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