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