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