r25437: let the default env for 'make testenv' depend on the target
[ira/wip.git] / source4 / selftest / selftest.pl
1 #!/usr/bin/perl
2 # Bootstrap Samba and run a number of tests against it.
3 # Copyright (C) 2005-2007 Jelmer Vernooij <jelmer@samba.org>
4 # Published under the GNU GPL, v3 or later.
5
6 =pod
7
8 =head1 NAME
9
10 selftest - Samba test runner
11
12 =head1 SYNOPSIS
13
14 selftest --help
15
16 selftest [--srcdir=DIR] [--builddir=DIR] [--target=samba4|samba3|win] [--socket-wrapper] [--quick] [--one] [--prefix=prefix] [--immediate] [--testlist=FILE] [TESTS]
17
18 =head1 DESCRIPTION
19
20 A simple test runner. TESTS is a regular expression with tests to run.
21
22 =head1 OPTIONS
23
24 =over 4
25
26 =item I<--help>
27
28 Show list of available options.
29
30 =item I<--srcdir=DIR>
31
32 Source directory.
33
34 =item I<--builddir=DIR>
35
36 Build directory.
37
38 =item I<--prefix=DIR>
39
40 Change directory to run tests in. Default is 'st'.
41
42 =item I<--immediate>
43
44 Show errors as soon as they happen rather than at the end of the test run.
45                 
46 =item I<--target samba4|samba3|win>
47
48 Specify test target against which to run. Default is 'samba4'.
49
50 =item I<--quick>
51
52 Run only a limited number of tests. Intended to run in about 30 seconds on 
53 moderately recent systems.
54                 
55 =item I<--socket-wrapper>
56
57 Use socket wrapper library for communication with server. Only works 
58 when the server is running locally.
59
60 Will prevent TCP and UDP ports being opened on the local host but 
61 (transparently) redirects these calls to use unix domain sockets.
62
63 =item I<--expected-failures>
64
65 Specify a file containing a list of tests that are expected to fail. Failures for 
66 these tests will be counted as successes, successes will be counted as failures.
67
68 The format for the file is, one entry per line:
69
70 TESTSUITE-NAME/TEST-NAME
71
72 The reason for a test can also be specified, by adding a hash sign (#) and the reason 
73 after the test name.
74
75 =item I<--skip>
76
77 Specify a file containing a list of tests that should be skipped. Possible candidates are
78 tests that segfault the server, flip or don't end. The format of this file is the same as 
79 for the --expected-failures flag.
80
81 =item I<--one>
82
83 Abort as soon as one test fails.
84
85 =item I<--testlist>
86
87 Load a list of tests from the specified location.
88
89 =back
90
91 =head1 ENVIRONMENT
92
93 =over 4
94
95 =item I<SMBD_VALGRIND>
96
97 =item I<TORTURE_MAXTIME>
98
99 =item I<VALGRIND>
100
101 =item I<TLS_ENABLED>
102
103 =item I<srcdir>
104
105 =back
106
107 =head1 LICENSE
108
109 selftest is licensed under the GNU General Public License L<http://www.gnu.org/licenses/gpl.html>.
110
111 =head1 AUTHOR
112
113 Jelmer Vernooij
114
115 =cut
116
117 use strict;
118
119 use FindBin qw($RealBin $Script);
120 use File::Spec;
121 use Getopt::Long;
122 use POSIX;
123 use Cwd qw(abs_path);
124 use lib "$RealBin";
125 use Subunit qw(parse_results);
126 use env::Samba3;
127 use env::Samba4;
128 use env::Windows;
129 use SocketWrapper;
130
131 my $opt_help = 0;
132 my $opt_target = "samba4";
133 my $opt_quick = 0;
134 my $opt_socket_wrapper = 0;
135 my $opt_socket_wrapper_pcap = undef;
136 my $opt_socket_wrapper_keep_pcap = undef;
137 my $opt_one = 0;
138 my $opt_immediate = 0;
139 my $opt_expected_failures = undef;
140 my @opt_skip = ();
141 my $opt_verbose = 0;
142 my $opt_testenv = 0;
143 my $ldap = undef;
144 my $opt_analyse_cmd = undef;
145 my $opt_resetup_env = undef;
146 my $opt_bindir = undef;
147 my $opt_no_lazy_setup = undef;
148 my $opt_format = "plain";
149 my @opt_testlists = ();
150
151 my $srcdir = ".";
152 my $builddir = ".";
153 my $prefix = "./st";
154
155 my @expected_failures = ();
156 my @skips = ();
157
158 my $statistics = {
159         START_TIME => time(),
160
161         SUITES_FAIL => 0,
162         SUITES_OK => 0,
163         SUITES_SKIPPED => 0,
164
165         TESTS_UNEXPECTED_OK => 0,
166         TESTS_EXPECTED_OK => 0,
167         TESTS_UNEXPECTED_FAIL => 0,
168         TESTS_EXPECTED_FAIL => 0,
169         TESTS_ERROR => 0,
170         TESTS_SKIP => 0,
171 };
172
173 sub find_in_list($$)
174 {
175         my ($list, $fullname) = @_;
176
177         foreach (@$list) {
178                 if ($fullname =~ /$$_[0]/) {
179                          return ($$_[1]) if ($$_[1]);
180                          return "NO REASON SPECIFIED";
181                 }
182         }
183
184         return undef;
185 }
186
187 sub expecting_failure($)
188 {
189         my ($name) = @_;
190         return find_in_list(\@expected_failures, $name);
191 }
192
193 sub skip($)
194 {
195         my ($name) = @_;
196         return find_in_list(\@skips, $name);
197 }
198
199 sub getlog_env($);
200
201 sub setup_pcap($)
202 {
203         my ($state) = @_;
204
205         return unless ($opt_socket_wrapper_pcap);
206         return unless defined($ENV{SOCKET_WRAPPER_PCAP_DIR});
207
208         my $fname = sprintf("t%03u_%s", $state->{INDEX}, $state->{NAME});
209         $fname =~ s%[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\-]%_%g;
210
211         $state->{PCAP_FILE} = "$ENV{SOCKET_WRAPPER_PCAP_DIR}/$fname.pcap";
212
213         SocketWrapper::setup_pcap($state->{PCAP_FILE});
214 }
215
216 sub cleanup_pcap($$$)
217 {
218         my ($state, $expected_ret, $ret) = @_;
219
220         return unless ($opt_socket_wrapper_pcap);
221         return if ($opt_socket_wrapper_keep_pcap);
222         return unless ($expected_ret == $ret);
223         return unless defined($state->{PCAP_FILE});
224
225         unlink($state->{PCAP_FILE});
226         $state->{PCAP_FILE} = undef;
227 }
228
229 sub run_testsuite($$$$$$$)
230 {
231         my ($envname, $envvars, $name, $cmd, $i, $totalsuites, $msg_ops) = @_;
232         my $msg_state = {
233                 ENVNAME => $envname,
234                 ENVVARS => $envvars,
235                 NAME    => $name,
236                 CMD     => $cmd,
237                 INDEX   => $i,
238                 TOTAL   => $totalsuites,
239                 START_TIME      => time()
240         };
241
242         setup_pcap($msg_state);
243
244         open(RESULT, "$cmd 2>&1|");
245         $msg_ops->start_testsuite($msg_state);
246
247         my $expected_ret = parse_results(
248                 $msg_ops, $msg_state, $statistics, *RESULT, \&expecting_failure);
249
250         my $ret = close(RESULT);
251
252         cleanup_pcap($msg_state, $expected_ret, $ret);
253
254         $msg_ops->end_testsuite($msg_state, $expected_ret, $ret,
255                                                         getlog_env($msg_state->{ENVNAME}));
256
257         if (not $opt_socket_wrapper_keep_pcap and 
258                 defined($msg_state->{PCAP_FILE})) {
259                 $msg_ops->output_msg($msg_state, 
260                         "PCAP FILE: $msg_state->{PCAP_FILE}\n");
261         }
262
263         if ($ret != $expected_ret) {
264                 $statistics->{SUITES_FAIL}++;
265                 exit(1) if ($opt_one);
266         } else {
267                 $statistics->{SUITES_OK}++;
268         }
269
270         return ($ret == $expected_ret);
271 }
272
273 sub ShowHelp()
274 {
275         print "Samba test runner
276 Copyright (C) Jelmer Vernooij <jelmer\@samba.org>
277
278 Usage: $Script [OPTIONS] PREFIX
279
280 Generic options:
281  --help                     this help page
282  --target=samba4|samba3|win Samba version to target
283  --testlist=FILE                        file to read available tests from
284
285 Paths:
286  --prefix=DIR               prefix to run tests in [st]
287  --srcdir=DIR               source directory [.]
288  --builddir=DIR             output directory [.]
289
290 Target Specific:
291  --socket-wrapper-pcap          save traffic to pcap directories
292  --socket-wrapper-keep-pcap keep all pcap files, not just those for tests that 
293                             failed
294  --socket-wrapper           enable socket wrapper
295  --expected-failures=FILE   specify list of tests that is guaranteed to fail
296
297 Samba4 Specific:
298  --ldap=openldap|fedora-ds     back smbd onto specified ldap server
299
300 Samba3 Specific:
301  --bindir=PATH              path to binaries
302
303 Behaviour:
304  --quick                    run quick overall test
305  --one                      abort when the first test fails
306  --immediate                print test output for failed tests during run
307  --verbose                  be verbose
308  --analyse-cmd CMD          command to run after each test
309 ";
310         exit(0);
311 }
312
313 my $result = GetOptions (
314                 'help|h|?' => \$opt_help,
315                 'target=s' => \$opt_target,
316                 'prefix=s' => \$prefix,
317                 'socket-wrapper' => \$opt_socket_wrapper,
318                 'socket-wrapper-pcap' => \$opt_socket_wrapper_pcap,
319                 'socket-wrapper-keep-pcap' => \$opt_socket_wrapper_keep_pcap,
320                 'quick' => \$opt_quick,
321                 'one' => \$opt_one,
322                 'immediate' => \$opt_immediate,
323                 'expected-failures=s' => \$opt_expected_failures,
324                 'skip=s' => \@opt_skip,
325                 'srcdir=s' => \$srcdir,
326                 'builddir=s' => \$builddir,
327                 'verbose' => \$opt_verbose,
328                 'testenv' => \$opt_testenv,
329                 'ldap:s' => \$ldap,
330                 'analyse-cmd=s' => \$opt_analyse_cmd,
331                 'no-lazy-setup' => \$opt_no_lazy_setup,
332                 'resetup-environment' => \$opt_resetup_env,
333                 'bindir:s' => \$opt_bindir,
334                 'format=s' => \$opt_format,
335                 'testlist=s' => \@opt_testlists
336             );
337
338 exit(1) if (not $result);
339
340 ShowHelp() if ($opt_help);
341
342 my $tests = shift;
343
344 # quick hack to disable rpc validation when using valgrind - its way too slow
345 unless (defined($ENV{VALGRIND})) {
346         $ENV{VALIDATE} = "validate";
347         $ENV{MALLOC_CHECK_} = 2;
348 }
349
350 my $old_pwd = "$RealBin/..";
351
352 # Backwards compatibility:
353 if (defined($ENV{TEST_LDAP}) and $ENV{TEST_LDAP} eq "yes") {
354         if (defined($ENV{FEDORA_DS_PREFIX})) {
355                 $ldap = "fedora-ds";
356         } else {
357                 $ldap = "openldap";
358         }
359 }
360
361 my $torture_maxtime = ($ENV{TORTURE_MAXTIME} or 1200);
362 if ($ldap) {
363         # LDAP is slow
364         $torture_maxtime *= 2;
365 }
366
367 $prefix =~ s+//+/+;
368 $prefix =~ s+/./+/+;
369 $prefix =~ s+/$++;
370
371 die("using an empty prefix isn't allowed") unless $prefix ne "";
372
373 #Ensure we have the test prefix around
374 mkdir($prefix, 0777) unless -d $prefix;
375
376 my $prefix_abs = abs_path($prefix);
377 my $srcdir_abs = abs_path($srcdir);
378
379 die("using an empty absolute prefix isn't allowed") unless $prefix_abs ne "";
380 die("using '/' as absolute prefix isn't allowed") unless $prefix_abs ne "/";
381
382 $ENV{PREFIX} = $prefix;
383 $ENV{PREFIX_ABS} = $prefix_abs;
384 $ENV{SRCDIR} = $srcdir;
385 $ENV{SRCDIR_ABS} = $srcdir_abs;
386
387 my $tls_enabled = not $opt_quick;
388 if (defined($ENV{RUN_FROM_BUILD_FARM}) and 
389         ($ENV{RUN_FROM_BUILD_FARM} eq "yes")) {
390         $opt_format = "buildfarm";
391 }
392
393 $ENV{TLS_ENABLED} = ($tls_enabled?"yes":"no");
394 $ENV{LD_LDB_MODULE_PATH} = "$old_pwd/bin/modules/ldb";
395 $ENV{LD_SAMBA_MODULE_PATH} = "$old_pwd/bin/modules";
396 if (defined($ENV{LD_LIBRARY_PATH})) {
397         $ENV{LD_LIBRARY_PATH} = "$old_pwd/bin/shared:$ENV{LD_LIBRARY_PATH}";
398 } else {
399         $ENV{LD_LIBRARY_PATH} = "$old_pwd/bin/shared";
400 }
401 if (defined($ENV{PKG_CONFIG_PATH})) {
402         $ENV{PKG_CONFIG_PATH} = "$old_pwd/bin/pkgconfig:$ENV{PKG_CONFIG_PATH}";
403 } else { 
404         $ENV{PKG_CONFIG_PATH} = "$old_pwd/bin/pkgconfig";
405 }
406 # Required for smbscript:
407 $ENV{PATH} = "$old_pwd/bin:$old_pwd:$ENV{PATH}";
408
409
410 if ($opt_socket_wrapper_pcap) {
411         # Socket wrapper pcap implies socket wrapper
412         $opt_socket_wrapper = 1;
413 }
414
415 my $socket_wrapper_dir;
416 if ($opt_socket_wrapper) {
417         $socket_wrapper_dir = SocketWrapper::setup_dir("$prefix/w", $opt_socket_wrapper_pcap);
418         print "SOCKET_WRAPPER_DIR=$socket_wrapper_dir\n";
419 } else {
420         warn("Not using socket wrapper, but also not running as root. Will not be able to listen on proper ports") unless $< == 0;
421 }
422
423 my $target;
424 my $testenv_default = "none";
425
426 if ($opt_target eq "samba4") {
427         $testenv_default = "member";
428         $target = new Samba4($opt_bindir or "$srcdir/bin", $ldap, "$srcdir/setup");
429 } elsif ($opt_target eq "samba3") {
430         if ($opt_socket_wrapper and `$opt_bindir/smbd -b | grep SOCKET_WRAPPER` eq "") {
431                 die("You must include --enable-socket-wrapper when compiling Samba in order to execute 'make test'.  Exiting....");
432         }
433         $testenv_default = "dc";
434         $target = new Samba3($opt_bindir);
435 } elsif ($opt_target eq "win") {
436         die("Windows tests will not run with socket wrapper enabled.") 
437                 if ($opt_socket_wrapper);
438         $testenv_default = "dc";
439         $target = new Windows();
440 }
441
442 sub read_test_regexes($)
443 {
444         my ($name) = @_;
445         my @ret = ();
446         open(LF, "<$name") or die("unable to read $name: $!");
447         while (<LF>) { 
448                 chomp; 
449                 if (/^(.*?)([ \t]+)\#(.*)$/) {
450                         push (@ret, [$1, $3]);
451                 } else {
452                         s/^(.*?)([ \t]+)\#(.*)$//;
453                         push (@ret, [$_, undef]); 
454                 }
455         }
456         close(LF);
457         return @ret;
458 }
459
460 if (defined($opt_expected_failures)) {
461         @expected_failures = read_test_regexes($opt_expected_failures);
462 }
463
464 foreach (@opt_skip) {
465         push (@skips, read_test_regexes($_));
466 }
467
468 my $interfaces = join(',', ("127.0.0.6/8", 
469                             "127.0.0.7/8",
470                             "127.0.0.8/8",
471                             "127.0.0.9/8",
472                             "127.0.0.10/8",
473                             "127.0.0.11/8"));
474
475 my $conffile = "$prefix_abs/client/client.conf";
476
477 sub write_clientconf($$)
478 {
479         my ($conffile, $vars) = @_;
480
481         mkdir("$prefix/client", 0777) unless -d "$prefix/client";
482         
483         if ( -d "$prefix/client/private" ) {
484                 unlink <$prefix/client/private/*>;
485         } else {
486                 mkdir("$prefix/client/private", 0777);
487         }
488
489         open(CF, ">$conffile");
490         print CF "[global]\n";
491         if (defined($ENV{VALGRIND})) {
492                 print CF "\ticonv:native = true\n";
493         } else {
494                 print CF "\ticonv:native = false\n";
495         }
496         print CF "\tnetbios name = client\n";
497         if (defined($vars->{DOMAIN})) {
498                 print CF "\tworkgroup = $vars->{DOMAIN}\n";
499         }
500         if (defined($vars->{REALM})) {
501                 print CF "\trealm = $vars->{REALM}\n";
502         }
503         if (defined($vars->{NCALRPCDIR})) {
504                 print CF "\tncalrpc dir = $vars->{NCALRPCDIR}\n";
505         }
506         if (defined($vars->{PIDDIR})) {
507                 print CF "\tpid directory = $vars->{PIDDIR}\n";
508         }
509         if (defined($vars->{WINBINDD_SOCKET_DIR})) {
510                 print CF "\twinbindd socket directory = $vars->{WINBINDD_SOCKET_DIR}\n";
511         }
512         print CF "
513         private dir = $prefix_abs/client/private
514         js include = $srcdir_abs/scripting/libjs
515         name resolve order = bcast
516         interfaces = $interfaces
517         panic action = $srcdir_abs/script/gdb_backtrace \%PID\% \%PROG\%
518         max xmit = 32K
519         notify:inotify = false
520         ldb:nosync = true
521         system:anonymous = true
522         torture:basedir = $prefix_abs/client
523 #We don't want to pass our self-tests if the PAC code is wrong
524         gensec:require_pac = true
525 ";
526         close(CF);
527 }
528
529
530 my @torture_options = ();
531 push (@torture_options, "--configfile=$conffile");
532 # ensure any one smbtorture call doesn't run too long
533 push (@torture_options, "--maximum-runtime=$torture_maxtime");
534 push (@torture_options, "--target=$opt_target");
535 push (@torture_options, "--basedir=$prefix_abs");
536 push (@torture_options, "--option=torture:progress=no") if ($opt_format eq "buildfarm");
537 push (@torture_options, "--format=subunit");
538 push (@torture_options, "--option=torture:quick=yes") if ($opt_quick);
539
540 $ENV{TORTURE_OPTIONS} = join(' ', @torture_options);
541 print "OPTIONS $ENV{TORTURE_OPTIONS}\n";
542
543 my @todo = ();
544
545 my $testsdir = "$srcdir/selftest";
546 $ENV{SMB_CONF_PATH} = "$conffile";
547 $ENV{CONFIGURATION} = "--configfile=$conffile";
548
549 my %required_envs = ();
550
551 sub read_testlist($)
552 {
553         my ($filename) = @_;
554
555         my @ret = ();
556         open(IN, $filename) or die("Unable to open $filename: $!");
557
558         while (<IN>) {
559                 if ($_ eq "-- TEST --\n") {
560                         my $name = <IN>;
561                         $name =~ s/\n//g;
562                         my $env = <IN>;
563                         $env =~ s/\n//g;
564                         my $cmdline = <IN>;
565                         $cmdline =~ s/\n//g;
566                         if (not defined($tests) or $name =~ /$tests/) {
567                                 $required_envs{$env} = 1;
568                                 push (@ret, [$name, $env, $cmdline]);
569                         }
570                 } else {
571                         print;
572                 }
573         }
574         close(IN) or die("Error creating recipe");
575         return @ret;
576 }
577
578 if ($opt_quick) {
579         @todo = read_testlist("$testsdir/tests_quick.sh|");
580 } else {
581         @todo = read_testlist("$testsdir/tests_all.sh|");
582 }
583
584 foreach (@opt_testlists) {
585         push(@todo, read_testlist($_));
586 }
587
588 my $suitestotal = $#todo + 1;
589 my $i = 0;
590 $| = 1;
591
592 my %running_envs = ();
593
594 my @exported_envvars = (
595         # domain stuff
596         "DOMAIN",
597         "REALM",
598
599         # domain controller stuff
600         "DC_SERVER",
601         "DC_SERVER_IP",
602         "DC_NETBIOSNAME",
603         "DC_NETBIOSALIAS",
604
605         # server stuff
606         "SERVER",
607         "SERVER_IP",
608         "NETBIOSNAME",
609         "NETBIOSALIAS",
610
611         # user stuff
612         "USERNAME",
613         "PASSWORD",
614         "DC_USERNAME",
615         "DC_PASSWORD",
616
617         # misc stuff
618         "KRB5_CONFIG",
619         "WINBINDD_SOCKET_DIR"
620 );
621
622 $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub { 
623         my $signame = shift;
624         teardown_env($_) foreach(keys %running_envs);
625         die("Received signal $signame");
626 };
627
628 sub setup_env($)
629 {
630         my ($envname) = @_;
631
632         my $testenv_vars;
633         if ($envname eq "none") {
634                 $testenv_vars = {};
635         } elsif (defined($running_envs{$envname})) {
636                 $testenv_vars = $running_envs{$envname};
637                 if (not $target->check_env($testenv_vars)) {
638                         $testenv_vars = undef;
639                 }
640         } else {
641                 $testenv_vars = $target->setup_env($envname, $prefix);
642         }
643
644         return undef unless defined($testenv_vars);
645
646         $running_envs{$envname} = $testenv_vars;
647
648         SocketWrapper::set_default_iface(6);
649         write_clientconf($conffile, $testenv_vars);
650
651         foreach (@exported_envvars) {
652                 if (defined($testenv_vars->{$_})) {
653                         $ENV{$_} = $testenv_vars->{$_};
654                 } else {
655                         delete $ENV{$_};
656                 }
657         }
658
659         return $testenv_vars;
660 }
661
662 sub exported_envvars_str($)
663 {
664         my ($testenv_vars) = @_;
665         my $out = "";
666
667         foreach (@exported_envvars) {
668                 next unless defined($testenv_vars->{$_});
669                 $out .= $_."=".$testenv_vars->{$_}."\n";
670         }
671
672         return $out;
673 }
674
675 sub getlog_env($)
676 {
677         my ($envname) = @_;
678         return "" if ($envname eq "none");
679         return $target->getlog_env($running_envs{$envname});
680 }
681
682 sub check_env($)
683 {
684         my ($envname) = @_;
685         return 1 if ($envname eq "none");
686         return $target->check_env($running_envs{$envname});
687 }
688
689 sub teardown_env($)
690 {
691         my ($envname) = @_;
692         return if ($envname eq "none");
693         $target->teardown_env($running_envs{$envname});
694         delete $running_envs{$envname};
695 }
696
697 my $msg_ops;
698 if ($opt_format eq "buildfarm") {
699         require output::buildfarm;
700         $msg_ops = new output::buildfarm($statistics);
701 } elsif ($opt_format eq "plain") {
702         require output::plain;
703         $msg_ops = new output::plain($opt_verbose, $opt_immediate, $statistics);
704 } elsif ($opt_format eq "html") {
705         require output::html;
706         mkdir("test-results", 0777);
707         $msg_ops = new output::html("test-results", $statistics);
708 } else {
709         die("Invalid output format '$opt_format'");
710 }
711
712 if ($opt_no_lazy_setup) {
713         setup_env($_) foreach (keys %required_envs);
714 }
715
716 if ($opt_testenv) {
717         my $testenv_name = $ENV{SELFTEST_TESTENV};
718         $testenv_name = $testenv_default unless defined($testenv_name);
719
720         my $testenv_vars = setup_env($testenv_name);
721
722         $ENV{PIDDIR} = $testenv_vars->{PIDDIR};
723
724         my $envvarstr = exported_envvars_str($testenv_vars);
725
726         my $term = ($ENV{TERM} or "xterm");
727         system("$term -e 'echo -e \"
728 Welcome to the Samba4 Test environment '$testenv_name'
729
730 This matches the client environment used in make test
731 smbd is pid `cat \$PIDDIR/smbd.pid`
732
733 Some useful environment variables:
734 TORTURE_OPTIONS=\$TORTURE_OPTIONS
735 CONFIGURATION=\$CONFIGURATION
736
737 $envvarstr
738 \" && bash'");
739         teardown_env($testenv_name);
740 } else {
741         foreach (@todo) {
742                 $i++;
743                 my $cmd = $$_[2];
744                 $cmd =~ s/([\(\)])/\\$1/g;
745                 my $name = $$_[0];
746                 my $envname = $$_[1];
747                 
748                 my $skipreason = skip($name);
749                 if ($skipreason) {
750                         $msg_ops->skip_testsuite($envname, $name, $skipreason);
751                         $statistics->{SUITES_SKIPPED}++;
752                         next;
753                 }
754
755                 my $envvars = setup_env($envname);
756                 if (not defined($envvars)) {
757                         $statistics->{SUITES_SKIPPED}++;
758                         $msg_ops->missing_env($name, $envname);
759                         next;
760                 }
761
762                 run_testsuite($envname, $envvars, $name, $cmd, $i, $suitestotal, 
763                               $msg_ops);
764
765                 if (defined($opt_analyse_cmd)) {
766                         system("$opt_analyse_cmd \"$name\"");
767                 }
768
769                 teardown_env($envname) if ($opt_resetup_env);
770         }
771 }
772
773 print "\n";
774
775 teardown_env($_) foreach (keys %running_envs);
776
777 $target->stop();
778
779 $statistics->{END_TIME} = time();
780 my $duration = ($statistics->{END_TIME}-$statistics->{START_TIME});
781 $msg_ops->summary();
782 print "DURATION: $duration seconds\n";
783
784 my $failed = 0;
785
786 # if there were any valgrind failures, show them
787 foreach (<$prefix/valgrind.log*>) {
788         next unless (-s $_);
789         system("grep DWARF2.CFI.reader $_ > /dev/null");
790         if ($? >> 8 == 0) {
791             print "VALGRIND FAILURE\n";
792             $failed++;
793             system("cat $_");
794         }
795 }
796
797 if ($opt_format eq "buildfarm") {
798         print "TEST STATUS: $statistics->{SUITES_FAIL}\n";
799 }
800
801 exit $statistics->{SUITES_FAIL};