r25110: Show environment variables in HTML output.
[ira/wip.git] / source / 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 = undef;
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=DIR      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
425 if ($opt_target eq "samba4") {
426         $target = new Samba4($opt_bindir or "$srcdir/bin", $ldap, "$srcdir/setup");
427 } elsif ($opt_target eq "samba3") {
428         if ($opt_socket_wrapper and `$opt_bindir/smbd -b | grep SOCKET_WRAPPER` eq "") {
429                 die("You must include --enable-socket-wrapper when compiling Samba in order to execute 'make test'.  Exiting....");
430         }
431
432         $target = new Samba3($opt_bindir);
433 } elsif ($opt_target eq "win") {
434         die("Windows tests will not run with socket wrapper enabled.") 
435                 if ($opt_socket_wrapper);
436         $target = new Windows();
437 }
438
439 sub read_test_regexes($)
440 {
441         my ($name) = @_;
442         my @ret = ();
443         open(LF, "<$name") or die("unable to read $name: $!");
444         while (<LF>) { 
445                 chomp; 
446                 if (/^(.*?)([ \t]+)\#(.*)$/) {
447                         push (@ret, [$1, $3]);
448                 } else {
449                         s/^(.*?)([ \t]+)\#(.*)$//;
450                         push (@ret, [$_, undef]); 
451                 }
452         }
453         close(LF);
454         return @ret;
455 }
456
457 if (defined($opt_expected_failures)) {
458         @expected_failures = read_test_regexes($opt_expected_failures);
459 }
460
461 if (defined($opt_skip)) {
462         @skips = read_test_regexes($opt_skip);
463 }
464
465 my $interfaces = join(',', ("127.0.0.6/8", 
466                             "127.0.0.7/8",
467                             "127.0.0.8/8",
468                             "127.0.0.9/8",
469                             "127.0.0.10/8",
470                             "127.0.0.11/8"));
471
472 my $conffile = "$prefix_abs/client/client.conf";
473
474 sub write_clientconf($$)
475 {
476         my ($conffile, $vars) = @_;
477
478         mkdir("$prefix/client", 0777) unless -d "$prefix/client";
479         
480         if ( -d "$prefix/client/private" ) {
481                 unlink <$prefix/client/private/*>;
482         } else {
483                 mkdir("$prefix/client/private", 0777);
484         }
485
486         open(CF, ">$conffile");
487         print CF "[global]\n";
488         if (defined($ENV{VALGRIND})) {
489                 print CF "\ticonv:native = true\n";
490         } else {
491                 print CF "\ticonv:native = false\n";
492         }
493         print CF "\tnetbios name = client\n";
494         if (defined($vars->{DOMAIN})) {
495                 print CF "\tworkgroup = $vars->{DOMAIN}\n";
496         }
497         if (defined($vars->{REALM})) {
498                 print CF "\trealm = $vars->{REALM}\n";
499         }
500         if (defined($vars->{NCALRPCDIR})) {
501                 print CF "\tncalrpc dir = $vars->{NCALRPCDIR}\n";
502         }
503         if (defined($vars->{PIDDIR})) {
504                 print CF "\tpid directory = $vars->{PIDDIR}\n";
505         }
506         if (defined($vars->{WINBINDD_SOCKET_DIR})) {
507                 print CF "\twinbindd socket directory = $vars->{WINBINDD_SOCKET_DIR}\n";
508         }
509         print CF "
510         private dir = $prefix_abs/client/private
511         js include = $srcdir_abs/scripting/libjs
512         name resolve order = bcast
513         interfaces = $interfaces
514         panic action = $srcdir_abs/script/gdb_backtrace \%PID\% \%PROG\%
515         max xmit = 32K
516         notify:inotify = false
517         ldb:nosync = true
518         system:anonymous = true
519         torture:basedir = $prefix_abs/client
520 #We don't want to pass our self-tests if the PAC code is wrong
521         gensec:require_pac = true
522 ";
523         close(CF);
524 }
525
526
527 my @torture_options = ();
528 push (@torture_options, "--configfile=$conffile");
529 # ensure any one smbtorture call doesn't run too long
530 push (@torture_options, "--maximum-runtime=$torture_maxtime");
531 push (@torture_options, "--target=$opt_target");
532 push (@torture_options, "--basedir=$prefix_abs");
533 push (@torture_options, "--option=torture:progress=no") if ($opt_format eq "buildfarm");
534 push (@torture_options, "--format=subunit");
535 push (@torture_options, "--option=torture:quick=yes") if ($opt_quick);
536
537 $ENV{TORTURE_OPTIONS} = join(' ', @torture_options);
538 print "OPTIONS $ENV{TORTURE_OPTIONS}\n";
539
540 my @todo = ();
541
542 my $testsdir = "$srcdir/selftest";
543 $ENV{SMB_CONF_PATH} = "$conffile";
544 $ENV{CONFIGURATION} = "--configfile=$conffile";
545
546 my %required_envs = ();
547
548 sub read_testlist($)
549 {
550         my ($filename) = @_;
551
552         my @ret = ();
553         open(IN, $filename) or die("Unable to open $filename: $!");
554
555         while (<IN>) {
556                 if ($_ eq "-- TEST --\n") {
557                         my $name = <IN>;
558                         $name =~ s/\n//g;
559                         my $env = <IN>;
560                         $env =~ s/\n//g;
561                         my $cmdline = <IN>;
562                         $cmdline =~ s/\n//g;
563                         if (not defined($tests) or $name =~ /$tests/) {
564                                 $required_envs{$env} = 1;
565                                 push (@ret, [$name, $env, $cmdline]);
566                         }
567                 } else {
568                         print;
569                 }
570         }
571         close(IN) or die("Error creating recipe");
572         return @ret;
573 }
574
575 if ($opt_quick) {
576         @todo = read_testlist("$testsdir/tests_quick.sh|");
577 } else {
578         @todo = read_testlist("$testsdir/tests_all.sh|");
579 }
580
581 foreach (@opt_testlists) {
582         push(@todo, read_testlist($_));
583 }
584
585 my $suitestotal = $#todo + 1;
586 my $i = 0;
587 $| = 1;
588
589 my %running_envs = ();
590
591 my @exported_envvars = (
592         # domain stuff
593         "DOMAIN",
594         "REALM",
595
596         # domain controller stuff
597         "DC_SERVER",
598         "DC_SERVER_IP",
599         "DC_NETBIOSNAME",
600         "DC_NETBIOSALIAS",
601
602         # server stuff
603         "SERVER",
604         "SERVER_IP",
605         "NETBIOSNAME",
606         "NETBIOSALIAS",
607
608         # user stuff
609         "USERNAME",
610         "PASSWORD",
611         "DC_USERNAME",
612         "DC_PASSWORD",
613
614         # misc stuff
615         "KRB5_CONFIG",
616         "WINBINDD_SOCKET_DIR"
617 );
618
619 $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub { 
620         my $signame = shift;
621         teardown_env($_) foreach(keys %running_envs);
622         die("Received signal $signame");
623 };
624
625 sub setup_env($)
626 {
627         my ($envname) = @_;
628
629         my $testenv_vars;
630         if ($envname eq "none") {
631                 $testenv_vars = {};
632         } elsif (defined($running_envs{$envname})) {
633                 $testenv_vars = $running_envs{$envname};
634                 if (not $target->check_env($testenv_vars)) {
635                         $testenv_vars = undef;
636                 }
637         } else {
638                 $testenv_vars = $target->setup_env($envname, $prefix);
639         }
640
641         return undef unless defined($testenv_vars);
642
643         $running_envs{$envname} = $testenv_vars;
644
645         SocketWrapper::set_default_iface(6);
646         write_clientconf($conffile, $testenv_vars);
647
648         foreach (@exported_envvars) {
649                 if (defined($testenv_vars->{$_})) {
650                         $ENV{$_} = $testenv_vars->{$_};
651                 } else {
652                         delete $ENV{$_};
653                 }
654         }
655
656         return $testenv_vars;
657 }
658
659 sub exported_envvars_str($)
660 {
661         my ($testenv_vars) = @_;
662         my $out = "";
663
664         foreach (@exported_envvars) {
665                 next unless defined($testenv_vars->{$_});
666                 $out .= $_."=".$testenv_vars->{$_}."\n";
667         }
668
669         return $out;
670 }
671
672 sub getlog_env($)
673 {
674         my ($envname) = @_;
675         return "" if ($envname eq "none");
676         return $target->getlog_env($running_envs{$envname});
677 }
678
679 sub check_env($)
680 {
681         my ($envname) = @_;
682         return 1 if ($envname eq "none");
683         return $target->check_env($running_envs{$envname});
684 }
685
686 sub teardown_env($)
687 {
688         my ($envname) = @_;
689         return if ($envname eq "none");
690         $target->teardown_env($running_envs{$envname});
691         delete $running_envs{$envname};
692 }
693
694 my $msg_ops;
695 if ($opt_format eq "buildfarm") {
696         require output::buildfarm;
697         $msg_ops = new output::buildfarm();
698 } elsif ($opt_format eq "plain") {
699         require output::plain;
700         $msg_ops = new output::plain($opt_verbose, $opt_immediate, $statistics);
701 } elsif ($opt_format eq "html") {
702         require output::html;
703         mkdir("test-results", 0777);
704         $msg_ops = new output::html("test-results", $statistics);
705 } else {
706         die("Invalid output format '$opt_format'");
707 }
708
709 if ($opt_no_lazy_setup) {
710         setup_env($_) foreach (keys %required_envs);
711 }
712
713 if ($opt_testenv) {
714         my $testenv_name = $ENV{SELFTEST_TESTENV};
715         $testenv_name = "member" unless defined($testenv_name);
716
717         my $testenv_vars = setup_env($testenv_name);
718
719         $ENV{PIDDIR} = $testenv_vars->{PIDDIR};
720
721         my $envvarstr = exported_envvars_str($testenv_vars);
722
723         my $term = ($ENV{TERM} or "xterm");
724         system("$term -e 'echo -e \"
725 Welcome to the Samba4 Test environment '$testenv_name'
726
727 This matches the client environment used in make test
728 smbd is pid `cat \$PIDDIR/smbd.pid`
729
730 Some useful environment variables:
731 TORTURE_OPTIONS=\$TORTURE_OPTIONS
732 CONFIGURATION=\$CONFIGURATION
733
734 $envvarstr
735 \" && bash'");
736         teardown_env($testenv_name);
737 } else {
738         foreach (@todo) {
739                 $i++;
740                 my $cmd = $$_[2];
741                 $cmd =~ s/([\(\)])/\\$1/g;
742                 my $name = $$_[0];
743                 my $envname = $$_[1];
744                 
745                 my $skipreason = skip($name);
746                 if ($skipreason) {
747                         $msg_ops->skip_testsuite($envname, $name, $skipreason);
748                         $statistics->{SUITES_SKIPPED}++;
749                         next;
750                 }
751
752                 my $envvars = setup_env($envname);
753                 if (not defined($envvars)) {
754                         $statistics->{SUITES_SKIPPED}++;
755                         $msg_ops->missing_env($name, $envname);
756                         next;
757                 }
758
759                 run_testsuite($envname, $envvars, $name, $cmd, $i, $suitestotal, 
760                               $msg_ops);
761
762                 if (defined($opt_analyse_cmd)) {
763                         system("$opt_analyse_cmd \"$name\"");
764                 }
765
766                 teardown_env($envname) if ($opt_resetup_env);
767         }
768 }
769
770 print "\n";
771
772 teardown_env($_) foreach (keys %running_envs);
773
774 $target->stop();
775
776 $statistics->{END_TIME} = time();
777 my $duration = ($statistics->{END_TIME}-$statistics->{START_TIME});
778 $msg_ops->summary();
779 print "DURATION: $duration seconds\n";
780
781 my $failed = 0;
782
783 # if there were any valgrind failures, show them
784 foreach (<$prefix/valgrind.log*>) {
785         next unless (-s $_);
786         system("grep DWARF2.CFI.reader $_ > /dev/null");
787         if ($? >> 8 == 0) {
788             print "VALGRIND FAILURE\n";
789             $failed++;
790             system("cat $_");
791         }
792 }
793
794 if ($opt_format eq "buildfarm") {
795         print "TEST STATUS: $statistics->{SUITES_FAIL}\n";
796 }
797
798 exit $statistics->{SUITES_FAIL};