Merge commit 'release-4-0-0alpha1' into v4-0-test
[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 = ();
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         $ret = 0 unless $ret == 1;
252
253         cleanup_pcap($msg_state, $expected_ret, $ret);
254
255         $msg_ops->end_testsuite($msg_state, $expected_ret, $ret,
256                                                         getlog_env($msg_state->{ENVNAME}));
257
258         if (not $opt_socket_wrapper_keep_pcap and 
259                 defined($msg_state->{PCAP_FILE})) {
260                 $msg_ops->output_msg($msg_state, 
261                         "PCAP FILE: $msg_state->{PCAP_FILE}\n");
262         }
263
264         if ($ret != $expected_ret) {
265                 $statistics->{SUITES_FAIL}++;
266                 exit(1) if ($opt_one);
267         } else {
268                 $statistics->{SUITES_OK}++;
269         }
270
271         return ($ret == $expected_ret);
272 }
273
274 sub ShowHelp()
275 {
276         print "Samba test runner
277 Copyright (C) Jelmer Vernooij <jelmer\@samba.org>
278
279 Usage: $Script [OPTIONS] PREFIX
280
281 Generic options:
282  --help                     this help page
283  --target=samba4|samba3|win Samba version to target
284  --testlist=FILE                        file to read available tests from
285
286 Paths:
287  --prefix=DIR               prefix to run tests in [st]
288  --srcdir=DIR               source directory [.]
289  --builddir=DIR             output directory [.]
290
291 Target Specific:
292  --socket-wrapper-pcap          save traffic to pcap directories
293  --socket-wrapper-keep-pcap keep all pcap files, not just those for tests that 
294                             failed
295  --socket-wrapper           enable socket wrapper
296  --expected-failures=FILE   specify list of tests that is guaranteed to fail
297
298 Samba4 Specific:
299  --ldap=openldap|fedora-ds     back smbd onto specified ldap server
300
301 Samba3 Specific:
302  --bindir=PATH              path to binaries
303
304 Behaviour:
305  --quick                    run quick overall test
306  --one                      abort when the first test fails
307  --immediate                print test output for failed tests during run
308  --verbose                  be verbose
309  --analyse-cmd CMD          command to run after each test
310 ";
311         exit(0);
312 }
313
314 my $result = GetOptions (
315                 'help|h|?' => \$opt_help,
316                 'target=s' => \$opt_target,
317                 'prefix=s' => \$prefix,
318                 'socket-wrapper' => \$opt_socket_wrapper,
319                 'socket-wrapper-pcap' => \$opt_socket_wrapper_pcap,
320                 'socket-wrapper-keep-pcap' => \$opt_socket_wrapper_keep_pcap,
321                 'quick' => \$opt_quick,
322                 'one' => \$opt_one,
323                 'immediate' => \$opt_immediate,
324                 'expected-failures=s' => \$opt_expected_failures,
325                 'skip=s' => \@opt_skip,
326                 'srcdir=s' => \$srcdir,
327                 'builddir=s' => \$builddir,
328                 'verbose' => \$opt_verbose,
329                 'testenv' => \$opt_testenv,
330                 'ldap:s' => \$ldap,
331                 'analyse-cmd=s' => \$opt_analyse_cmd,
332                 'no-lazy-setup' => \$opt_no_lazy_setup,
333                 'resetup-environment' => \$opt_resetup_env,
334                 'bindir:s' => \$opt_bindir,
335                 'format=s' => \$opt_format,
336                 'testlist=s' => \@opt_testlists
337             );
338
339 exit(1) if (not $result);
340
341 ShowHelp() if ($opt_help);
342
343 my $tests = shift;
344
345 # quick hack to disable rpc validation when using valgrind - its way too slow
346 unless (defined($ENV{VALGRIND})) {
347         $ENV{VALIDATE} = "validate";
348         $ENV{MALLOC_CHECK_} = 2;
349 }
350
351 my $old_pwd = "$RealBin/..";
352
353 # Backwards compatibility:
354 if (defined($ENV{TEST_LDAP}) and $ENV{TEST_LDAP} eq "yes") {
355         if (defined($ENV{FEDORA_DS_PREFIX})) {
356                 $ldap = "fedora-ds";
357         } else {
358                 $ldap = "openldap";
359         }
360 }
361
362 my $torture_maxtime = ($ENV{TORTURE_MAXTIME} or 1200);
363 if ($ldap) {
364         # LDAP is slow
365         $torture_maxtime *= 2;
366 }
367
368 $prefix =~ s+//+/+;
369 $prefix =~ s+/./+/+;
370 $prefix =~ s+/$++;
371
372 die("using an empty prefix isn't allowed") unless $prefix ne "";
373
374 #Ensure we have the test prefix around
375 mkdir($prefix, 0777) unless -d $prefix;
376
377 my $prefix_abs = abs_path($prefix);
378 my $srcdir_abs = abs_path($srcdir);
379
380 die("using an empty absolute prefix isn't allowed") unless $prefix_abs ne "";
381 die("using '/' as absolute prefix isn't allowed") unless $prefix_abs ne "/";
382
383 $ENV{PREFIX} = $prefix;
384 $ENV{PREFIX_ABS} = $prefix_abs;
385 $ENV{SRCDIR} = $srcdir;
386 $ENV{SRCDIR_ABS} = $srcdir_abs;
387
388 if (defined($ENV{RUN_FROM_BUILD_FARM}) and 
389         ($ENV{RUN_FROM_BUILD_FARM} eq "yes")) {
390         $opt_format = "buildfarm";
391 }
392
393 my $tls_enabled = not $opt_quick;
394 $ENV{TLS_ENABLED} = ($tls_enabled?"yes":"no");
395 $ENV{LD_LDB_MODULE_PATH} = "$old_pwd/bin/modules/ldb";
396 $ENV{LD_SAMBA_MODULE_PATH} = "$old_pwd/bin/modules";
397 if (defined($ENV{LD_LIBRARY_PATH})) {
398         $ENV{LD_LIBRARY_PATH} = "$old_pwd/bin/shared:$ENV{LD_LIBRARY_PATH}";
399 } else {
400         $ENV{LD_LIBRARY_PATH} = "$old_pwd/bin/shared";
401 }
402 if (defined($ENV{PKG_CONFIG_PATH})) {
403         $ENV{PKG_CONFIG_PATH} = "$old_pwd/bin/pkgconfig:$ENV{PKG_CONFIG_PATH}";
404 } else { 
405         $ENV{PKG_CONFIG_PATH} = "$old_pwd/bin/pkgconfig";
406 }
407 # Required for smbscript:
408 $ENV{PATH} = "$old_pwd/bin:$old_pwd:$ENV{PATH}";
409
410
411 if ($opt_socket_wrapper_pcap) {
412         # Socket wrapper pcap implies socket wrapper
413         $opt_socket_wrapper = 1;
414 }
415
416 my $socket_wrapper_dir;
417 if ($opt_socket_wrapper) {
418         $socket_wrapper_dir = SocketWrapper::setup_dir("$prefix/w", $opt_socket_wrapper_pcap);
419         print "SOCKET_WRAPPER_DIR=$socket_wrapper_dir\n";
420 } else {
421         warn("Not using socket wrapper, but also not running as root. Will not be able to listen on proper ports") unless $< == 0;
422 }
423
424 my $target;
425 my $testenv_default = "none";
426
427 if ($opt_target eq "samba4") {
428         $testenv_default = "member";
429         $target = new Samba4($opt_bindir or "$srcdir/bin", $ldap, "$srcdir/setup");
430 } elsif ($opt_target eq "samba3") {
431         if ($opt_socket_wrapper and `$opt_bindir/smbd -b | grep SOCKET_WRAPPER` eq "") {
432                 die("You must include --enable-socket-wrapper when compiling Samba in order to execute 'make test'.  Exiting....");
433         }
434         $testenv_default = "dc";
435         $target = new Samba3($opt_bindir);
436 } elsif ($opt_target eq "win") {
437         die("Windows tests will not run with socket wrapper enabled.") 
438                 if ($opt_socket_wrapper);
439         $testenv_default = "dc";
440         $target = new Windows();
441 }
442
443 sub read_test_regexes($)
444 {
445         my ($name) = @_;
446         my @ret = ();
447         open(LF, "<$name") or die("unable to read $name: $!");
448         while (<LF>) { 
449                 chomp; 
450                 if (/^(.*?)([ \t]+)\#(.*)$/) {
451                         push (@ret, [$1, $3]);
452                 } else {
453                         s/^(.*?)([ \t]+)\#(.*)$//;
454                         push (@ret, [$_, undef]); 
455                 }
456         }
457         close(LF);
458         return @ret;
459 }
460
461 if (defined($opt_expected_failures)) {
462         @expected_failures = read_test_regexes($opt_expected_failures);
463 }
464
465 foreach (@opt_skip) {
466         push (@skips, read_test_regexes($_));
467 }
468
469 my $interfaces = join(',', ("127.0.0.6/8", 
470                             "127.0.0.7/8",
471                             "127.0.0.8/8",
472                             "127.0.0.9/8",
473                             "127.0.0.10/8",
474                             "127.0.0.11/8"));
475
476 my $conffile = "$prefix_abs/client/client.conf";
477
478 sub write_clientconf($$)
479 {
480         my ($conffile, $vars) = @_;
481
482         mkdir("$prefix/client", 0777) unless -d "$prefix/client";
483         
484         if ( -d "$prefix/client/private" ) {
485                 unlink <$prefix/client/private/*>;
486         } else {
487                 mkdir("$prefix/client/private", 0777);
488         }
489
490         open(CF, ">$conffile");
491         print CF "[global]\n";
492         if (defined($ENV{VALGRIND})) {
493                 print CF "\ticonv:native = true\n";
494         } else {
495                 print CF "\ticonv:native = false\n";
496         }
497         print CF "\tnetbios name = client\n";
498         if (defined($vars->{DOMAIN})) {
499                 print CF "\tworkgroup = $vars->{DOMAIN}\n";
500         }
501         if (defined($vars->{REALM})) {
502                 print CF "\trealm = $vars->{REALM}\n";
503         }
504         if (defined($vars->{NCALRPCDIR})) {
505                 print CF "\tncalrpc dir = $vars->{NCALRPCDIR}\n";
506         }
507         if (defined($vars->{PIDDIR})) {
508                 print CF "\tpid directory = $vars->{PIDDIR}\n";
509         }
510         if (defined($vars->{WINBINDD_SOCKET_DIR})) {
511                 print CF "\twinbindd socket directory = $vars->{WINBINDD_SOCKET_DIR}\n";
512         }
513         print CF "
514         private dir = $prefix_abs/client/private
515         js include = $srcdir_abs/scripting/libjs
516         name resolve order = bcast
517         interfaces = $interfaces
518         panic action = $srcdir_abs/script/gdb_backtrace \%PID\% \%PROG\%
519         max xmit = 32K
520         notify:inotify = false
521         ldb:nosync = true
522         system:anonymous = true
523         torture:basedir = $prefix_abs/client
524 #We don't want to pass our self-tests if the PAC code is wrong
525         gensec:require_pac = true
526 ";
527         close(CF);
528 }
529
530
531 my @torture_options = ();
532 push (@torture_options, "--configfile=$conffile");
533 # ensure any one smbtorture call doesn't run too long
534 push (@torture_options, "--maximum-runtime=$torture_maxtime");
535 push (@torture_options, "--target=$opt_target");
536 push (@torture_options, "--basedir=$prefix_abs");
537 push (@torture_options, "--option=torture:progress=no") if ($opt_format eq "buildfarm");
538 push (@torture_options, "--format=subunit");
539 push (@torture_options, "--option=torture:quick=yes") if ($opt_quick);
540
541 $ENV{TORTURE_OPTIONS} = join(' ', @torture_options);
542 print "OPTIONS $ENV{TORTURE_OPTIONS}\n";
543
544 my @todo = ();
545
546 my $testsdir = "$srcdir/selftest";
547 $ENV{SMB_CONF_PATH} = "$conffile";
548 $ENV{CONFIGURATION} = "--configfile=$conffile";
549
550 my %required_envs = ();
551
552 sub read_testlist($)
553 {
554         my ($filename) = @_;
555
556         my @ret = ();
557         open(IN, $filename) or die("Unable to open $filename: $!");
558
559         while (<IN>) {
560                 if ($_ eq "-- TEST --\n") {
561                         my $name = <IN>;
562                         $name =~ s/\n//g;
563                         my $env = <IN>;
564                         $env =~ s/\n//g;
565                         my $cmdline = <IN>;
566                         $cmdline =~ s/\n//g;
567                         if (not defined($tests) or $name =~ /$tests/) {
568                                 $required_envs{$env} = 1;
569                                 push (@ret, [$name, $env, $cmdline]);
570                         }
571                 } else {
572                         print;
573                 }
574         }
575         close(IN) or die("Error creating recipe");
576         return @ret;
577 }
578
579 if ($opt_quick) {
580         @todo = read_testlist("$testsdir/tests_quick.sh|");
581 } else {
582         @todo = read_testlist("$testsdir/tests_all.sh|");
583 }
584
585 foreach (@opt_testlists) {
586         push(@todo, read_testlist($_));
587 }
588
589 if ($#todo == -1) {
590         print STDERR "No tests to run\n";
591         exit(1);
592         }
593
594 my $suitestotal = $#todo + 1;
595 my $i = 0;
596 $| = 1;
597
598 my %running_envs = ();
599
600 my @exported_envvars = (
601         # domain stuff
602         "DOMAIN",
603         "REALM",
604
605         # domain controller stuff
606         "DC_SERVER",
607         "DC_SERVER_IP",
608         "DC_NETBIOSNAME",
609         "DC_NETBIOSALIAS",
610
611         # server stuff
612         "SERVER",
613         "SERVER_IP",
614         "NETBIOSNAME",
615         "NETBIOSALIAS",
616
617         # user stuff
618         "USERNAME",
619         "PASSWORD",
620         "DC_USERNAME",
621         "DC_PASSWORD",
622
623         # misc stuff
624         "KRB5_CONFIG",
625         "WINBINDD_SOCKET_DIR",
626         "WINBINDD_PRIV_PIPE_DIR"
627 );
628
629 $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub { 
630         my $signame = shift;
631         teardown_env($_) foreach(keys %running_envs);
632         die("Received signal $signame");
633 };
634
635 sub setup_env($)
636 {
637         my ($envname) = @_;
638
639         my $testenv_vars;
640         if ($envname eq "none") {
641                 $testenv_vars = {};
642         } elsif (defined($running_envs{$envname})) {
643                 $testenv_vars = $running_envs{$envname};
644                 if (not $target->check_env($testenv_vars)) {
645                         $testenv_vars = undef;
646                 }
647         } else {
648                 $testenv_vars = $target->setup_env($envname, $prefix);
649         }
650
651         return undef unless defined($testenv_vars);
652
653         $running_envs{$envname} = $testenv_vars;
654
655         SocketWrapper::set_default_iface(6);
656         write_clientconf($conffile, $testenv_vars);
657
658         foreach (@exported_envvars) {
659                 if (defined($testenv_vars->{$_})) {
660                         $ENV{$_} = $testenv_vars->{$_};
661                 } else {
662                         delete $ENV{$_};
663                 }
664         }
665
666         return $testenv_vars;
667 }
668
669 sub exported_envvars_str($)
670 {
671         my ($testenv_vars) = @_;
672         my $out = "";
673
674         foreach (@exported_envvars) {
675                 next unless defined($testenv_vars->{$_});
676                 $out .= $_."=".$testenv_vars->{$_}."\n";
677         }
678
679         return $out;
680 }
681
682 sub getlog_env($)
683 {
684         my ($envname) = @_;
685         return "" if ($envname eq "none");
686         return $target->getlog_env($running_envs{$envname});
687 }
688
689 sub check_env($)
690 {
691         my ($envname) = @_;
692         return 1 if ($envname eq "none");
693         return $target->check_env($running_envs{$envname});
694 }
695
696 sub teardown_env($)
697 {
698         my ($envname) = @_;
699         return if ($envname eq "none");
700         $target->teardown_env($running_envs{$envname});
701         delete $running_envs{$envname};
702 }
703
704 my $msg_ops;
705 if ($opt_format eq "buildfarm") {
706         require output::buildfarm;
707         $msg_ops = new output::buildfarm($statistics);
708 } elsif ($opt_format eq "plain") {
709         require output::plain;
710         $msg_ops = new output::plain($opt_verbose, $opt_immediate, $statistics);
711 } elsif ($opt_format eq "html") {
712         require output::html;
713         mkdir("test-results", 0777);
714         $msg_ops = new output::html("test-results", $statistics);
715 } else {
716         die("Invalid output format '$opt_format'");
717 }
718
719 if ($opt_no_lazy_setup) {
720         setup_env($_) foreach (keys %required_envs);
721 }
722
723 if ($opt_testenv) {
724         my $testenv_name = $ENV{SELFTEST_TESTENV};
725         $testenv_name = $testenv_default unless defined($testenv_name);
726
727         my $testenv_vars = setup_env($testenv_name);
728
729         $ENV{PIDDIR} = $testenv_vars->{PIDDIR};
730
731         my $envvarstr = exported_envvars_str($testenv_vars);
732
733         my $term = ($ENV{TERM} or "xterm");
734         system("$term -e 'echo -e \"
735 Welcome to the Samba4 Test environment '$testenv_name'
736
737 This matches the client environment used in make test
738 smbd is pid `cat \$PIDDIR/smbd.pid`
739
740 Some useful environment variables:
741 TORTURE_OPTIONS=\$TORTURE_OPTIONS
742 CONFIGURATION=\$CONFIGURATION
743
744 $envvarstr
745 \" && bash'");
746         teardown_env($testenv_name);
747 } else {
748         foreach (@todo) {
749                 $i++;
750                 my $cmd = $$_[2];
751                 $cmd =~ s/([\(\)])/\\$1/g;
752                 my $name = $$_[0];
753                 my $envname = $$_[1];
754                 
755                 my $skipreason = skip($name);
756                 if ($skipreason) {
757                         $msg_ops->skip_testsuite($envname, $name, $skipreason);
758                         $statistics->{SUITES_SKIPPED}++;
759                         next;
760                 }
761
762                 my $envvars = setup_env($envname);
763                 if (not defined($envvars)) {
764                         $statistics->{SUITES_SKIPPED}++;
765                         $msg_ops->missing_env($name, $envname);
766                         next;
767                 }
768
769                 run_testsuite($envname, $envvars, $name, $cmd, $i, $suitestotal, 
770                               $msg_ops);
771
772                 if (defined($opt_analyse_cmd)) {
773                         system("$opt_analyse_cmd \"$name\"");
774                 }
775
776                 teardown_env($envname) if ($opt_resetup_env);
777         }
778 }
779
780 print "\n";
781
782 teardown_env($_) foreach (keys %running_envs);
783
784 $target->stop();
785
786 $statistics->{END_TIME} = time();
787 my $duration = ($statistics->{END_TIME}-$statistics->{START_TIME});
788 $msg_ops->summary();
789 print "DURATION: $duration seconds\n";
790
791 my $failed = 0;
792
793 # if there were any valgrind failures, show them
794 foreach (<$prefix/valgrind.log*>) {
795         next unless (-s $_);
796         system("grep DWARF2.CFI.reader $_ > /dev/null");
797         if ($? >> 8 == 0) {
798             print "VALGRIND FAILURE\n";
799             $failed++;
800             system("cat $_");
801         }
802 }
803
804 if ($opt_format eq "buildfarm") {
805         print "TEST STATUS: $statistics->{SUITES_FAIL}\n";
806 }
807
808 exit $statistics->{SUITES_FAIL};