TODO... selftest: add Samba34 target
[metze/samba/wip.git] / selftest / selftest.pl
1 #!/usr/bin/perl
2 # Bootstrap Samba and run a number of tests against it.
3 # Copyright (C) 2005-2008 Jelmer Vernooij <jelmer@samba.org>
4 # Copyright (C) 2007-2009 Stefan Metzmacher <metze@samba.org>
5 # Published under the GNU GPL, v3 or later.
6
7 =pod
8
9 =head1 NAME
10
11 selftest - Samba test runner
12
13 =head1 SYNOPSIS
14
15 selftest --help
16
17 selftest [--srcdir=DIR] [--builddir=DIR] [--exeext=EXT][--target=samba4|samba3|win|kvm] [--socket-wrapper] [--quick] [--exclude=FILE] [--include=FILE] [--one] [--prefix=prefix] [--immediate] [--testlist=FILE] [TESTS]
18
19 =head1 DESCRIPTION
20
21 A simple test runner. TESTS is a regular expression with tests to run.
22
23 =head1 OPTIONS
24
25 =over 4
26
27 =item I<--help>
28
29 Show list of available options.
30
31 =item I<--srcdir=DIR>
32
33 Source directory.
34
35 =item I<--builddir=DIR>
36
37 Build directory.
38
39 =item I<--exeext=EXT>
40
41 Executable extention
42
43 =item I<--prefix=DIR>
44
45 Change directory to run tests in. Default is 'st'.
46
47 =item I<--immediate>
48
49 Show errors as soon as they happen rather than at the end of the test run.
50                 
51 =item I<--target samba4|samba3|win|kvm>
52
53 Specify test target against which to run. Default is 'samba4'.
54
55 =item I<--quick>
56
57 Run only a limited number of tests. Intended to run in about 30 seconds on 
58 moderately recent systems.
59                 
60 =item I<--socket-wrapper>
61
62 Use socket wrapper library for communication with server. Only works 
63 when the server is running locally.
64
65 Will prevent TCP and UDP ports being opened on the local host but 
66 (transparently) redirects these calls to use unix domain sockets.
67
68 =item I<--expected-failures>
69
70 Specify a file containing a list of tests that are expected to fail. Failures for 
71 these tests will be counted as successes, successes will be counted as failures.
72
73 The format for the file is, one entry per line:
74
75 TESTSUITE-NAME.TEST-NAME
76
77 The reason for a test can also be specified, by adding a hash sign (#) and the reason 
78 after the test name.
79
80 =item I<--exclude>
81
82 Specify a file containing a list of tests that should be skipped. Possible 
83 candidates are tests that segfault the server, flip or don't end. The format of this file is the same as 
84 for the --expected-failures flag.
85
86 =item I<--include>
87
88 Specify a file containing a list of tests that should be run. Same format 
89 as the --exclude flag.
90
91 Not includes specified means all tests will be run.
92
93 =item I<--one>
94
95 Abort as soon as one test fails.
96
97 =item I<--testlist>
98
99 Load a list of tests from the specified location.
100
101 =back
102
103 =head1 ENVIRONMENT
104
105 =over 4
106
107 =item I<SMBD_VALGRIND>
108
109 =item I<TORTURE_MAXTIME>
110
111 =item I<VALGRIND>
112
113 =item I<TLS_ENABLED>
114
115 =item I<srcdir>
116
117 =back
118
119 =head1 LICENSE
120
121 selftest is licensed under the GNU General Public License L<http://www.gnu.org/licenses/gpl.html>.
122
123 =head1 AUTHOR
124
125 Jelmer Vernooij
126
127 =cut
128
129 use strict;
130
131 use FindBin qw($RealBin $Script);
132 use File::Spec;
133 use Getopt::Long;
134 use POSIX;
135 use Cwd qw(abs_path);
136 use lib "$RealBin";
137 use Subunit qw(parse_results);
138 use SocketWrapper;
139
140 my $opt_help = 0;
141 my $opt_target = "samba4";
142 my $opt_quick = 0;
143 my $opt_socket_wrapper = 0;
144 my $opt_socket_wrapper_pcap = undef;
145 my $opt_socket_wrapper_keep_pcap = undef;
146 my $opt_one = 0;
147 my $opt_immediate = 0;
148 my $opt_expected_failures = undef;
149 my @opt_exclude = ();
150 my @opt_include = ();
151 my $opt_verbose = 0;
152 my $opt_image = undef;
153 my $opt_testenv = 0;
154 my $ldap = undef;
155 my $opt_analyse_cmd = undef;
156 my $opt_resetup_env = undef;
157 my $opt_bindir = undef;
158 my $opt_no_lazy_setup = undef;
159 my $opt_format = "plain";
160 my @testlists = ();
161
162 my $srcdir = ".";
163 my $builddir = ".";
164 my $exeext = "";
165 my $prefix = "./st";
166
167 my @expected_failures = ();
168 my @includes = ();
169 my @excludes = ();
170
171 my $statistics = {
172         SUITES_FAIL => 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 ($name) = @_;
214
215         return unless ($opt_socket_wrapper_pcap);
216         return unless defined($ENV{SOCKET_WRAPPER_PCAP_DIR});
217
218         my $fname = $name;
219         $fname =~ s%[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\-]%_%g;
220
221         my $pcap_file = "$ENV{SOCKET_WRAPPER_PCAP_DIR}/$fname.pcap";
222
223         SocketWrapper::setup_pcap($pcap_file);
224
225         return $pcap_file;
226 }
227
228 sub cleanup_pcap($$$)
229 {
230         my ($pcap_file, $expected_ret, $ret) = @_;
231
232         return unless ($opt_socket_wrapper_pcap);
233         return if ($opt_socket_wrapper_keep_pcap);
234         return unless ($expected_ret == $ret);
235         return unless defined($pcap_file);
236
237         unlink($pcap_file);
238 }
239
240 sub run_testsuite($$$$$$)
241 {
242         my ($envname, $name, $cmd, $i, $totalsuites, $msg_ops) = @_;
243         my $pcap_file = setup_pcap($name);
244
245         $msg_ops->start_test([], $name);
246
247         unless (open(RESULT, "$cmd 2>&1|")) {
248                 $statistics->{TESTS_ERROR}++;
249                 $msg_ops->end_test([], $name, "error", 1, "Unable to run $cmd: $!");
250                 $statistics->{SUITES_FAIL}++;
251                 return 0;
252         }
253
254         my $expected_ret = parse_results(
255                 $msg_ops, $statistics, *RESULT, \&expecting_failure, [$name]);
256
257         my $envlog = getlog_env($envname);
258         $msg_ops->output_msg("ENVLOG: $envlog\n") if ($envlog ne "");
259
260         $msg_ops->output_msg("CMD: $cmd\n");
261
262         my $ret = close(RESULT);
263         $ret = 0 unless $ret == 1;
264
265         my $exitcode = $? >> 8;
266
267         if ($ret == 1) {
268                 $msg_ops->end_test([], $name, "success", $expected_ret != $ret, undef); 
269         } else {
270                 $msg_ops->end_test([], $name, "failure", $expected_ret != $ret, "Exit code was $exitcode");
271         }
272
273         cleanup_pcap($pcap_file, $expected_ret, $ret);
274
275         if (not $opt_socket_wrapper_keep_pcap and defined($pcap_file)) {
276                 $msg_ops->output_msg("PCAP FILE: $pcap_file\n");
277         }
278
279         if ($ret != $expected_ret) {
280                 $statistics->{SUITES_FAIL}++;
281                 exit(1) if ($opt_one);
282         }
283
284         return ($ret == $expected_ret);
285 }
286
287 sub ShowHelp()
288 {
289         print "Samba test runner
290 Copyright (C) Jelmer Vernooij <jelmer\@samba.org>
291 Copyright (C) Stefan Metzmacher <metze\@samba.org>
292
293 Usage: $Script [OPTIONS] TESTNAME-REGEX
294
295 Generic options:
296  --help                     this help page
297  --target=samba[34]|win|kvm Samba version to target
298  --testlist=FILE            file to read available tests from
299
300 Paths:
301  --prefix=DIR               prefix to run tests in [st]
302  --srcdir=DIR               source directory [.]
303  --builddir=DIR             output directory [.]
304  --exeext=EXT               executable extention []
305
306 Target Specific:
307  --socket-wrapper-pcap      save traffic to pcap directories
308  --socket-wrapper-keep-pcap keep all pcap files, not just those for tests that 
309                             failed
310  --socket-wrapper           enable socket wrapper
311  --bindir=PATH              path to target binaries
312  --expected-failures=FILE   specify list of tests that is guaranteed to fail
313
314 Samba4 Specific:
315  --ldap=openldap|fedora-ds  back samba onto specified ldap server
316
317 Kvm Specific:
318  --image=PATH               path to KVM image
319
320 Behaviour:
321  --quick                    run quick overall test
322  --one                      abort when the first test fails
323  --immediate                print test output for failed tests during run
324  --verbose                  be verbose
325  --analyse-cmd CMD          command to run after each test
326 ";
327         exit(0);
328 }
329
330 my $result = GetOptions (
331                 'help|h|?' => \$opt_help,
332                 'target=s' => \$opt_target,
333                 'prefix=s' => \$prefix,
334                 'socket-wrapper' => \$opt_socket_wrapper,
335                 'socket-wrapper-pcap' => \$opt_socket_wrapper_pcap,
336                 'socket-wrapper-keep-pcap' => \$opt_socket_wrapper_keep_pcap,
337                 'quick' => \$opt_quick,
338                 'one' => \$opt_one,
339                 'immediate' => \$opt_immediate,
340                 'expected-failures=s' => \$opt_expected_failures,
341                 'exclude=s' => \@opt_exclude,
342                 'include=s' => \@opt_include,
343                 'srcdir=s' => \$srcdir,
344                 'builddir=s' => \$builddir,
345                 'exeext=s' => \$exeext,
346                 'verbose' => \$opt_verbose,
347                 'testenv' => \$opt_testenv,
348                 'ldap:s' => \$ldap,
349                 'analyse-cmd=s' => \$opt_analyse_cmd,
350                 'no-lazy-setup' => \$opt_no_lazy_setup,
351                 'resetup-environment' => \$opt_resetup_env,
352                 'bindir:s' => \$opt_bindir,
353                 'format=s' => \$opt_format,
354                 'image=s' => \$opt_image,
355                 'testlist=s' => \@testlists
356             );
357
358 exit(1) if (not $result);
359
360 ShowHelp() if ($opt_help);
361
362 my $tests = shift;
363
364 # quick hack to disable rpc validation when using valgrind - its way too slow
365 unless (defined($ENV{VALGRIND})) {
366         $ENV{VALIDATE} = "validate";
367         $ENV{MALLOC_CHECK_} = 2;
368 }
369
370 my $bindir = ($opt_bindir or "$builddir/bin");
371 my $bindir_abs = abs_path($bindir);
372
373 # Backwards compatibility:
374 if (defined($ENV{TEST_LDAP}) and $ENV{TEST_LDAP} eq "yes") {
375         if (defined($ENV{FEDORA_DS_ROOT})) {
376                 $ldap = "fedora-ds";
377         } else {
378                 $ldap = "openldap";
379         }
380 }
381
382 my $torture_maxtime = ($ENV{TORTURE_MAXTIME} or 1200);
383 if ($ldap) {
384         # LDAP is slow
385         $torture_maxtime *= 2;
386 }
387
388 $prefix =~ s+//+/+;
389 $prefix =~ s+/./+/+;
390 $prefix =~ s+/$++;
391
392 die("using an empty prefix isn't allowed") unless $prefix ne "";
393
394 #Ensure we have the test prefix around
395 mkdir($prefix, 0777) unless -d $prefix;
396
397 my $prefix_abs = abs_path($prefix);
398 my $srcdir_abs = abs_path($srcdir);
399 my $builddir_abs = abs_path($builddir);
400
401 die("using an empty absolute prefix isn't allowed") unless $prefix_abs ne "";
402 die("using '/' as absolute prefix isn't allowed") unless $prefix_abs ne "/";
403
404 $ENV{PREFIX} = $prefix;
405 $ENV{KRB5CCNAME} = "$prefix/krb5ticket";
406 $ENV{PREFIX_ABS} = $prefix_abs;
407 $ENV{SRCDIR} = $srcdir;
408 $ENV{SRCDIR_ABS} = $srcdir_abs;
409 $ENV{BUILDDIR} = $builddir;
410 $ENV{BUILDDIR_ABS} = $builddir_abs;
411 $ENV{EXEEXT} = $exeext;
412
413 if (defined($ENV{RUN_FROM_BUILD_FARM}) and 
414         ($ENV{RUN_FROM_BUILD_FARM} eq "yes")) {
415         $opt_format = "buildfarm";
416 }
417
418 my $tls_enabled = not $opt_quick;
419 $ENV{TLS_ENABLED} = ($tls_enabled?"yes":"no");
420 $ENV{LDB_MODULES_PATH} = "$bindir_abs/modules/ldb";
421 $ENV{LD_SAMBA_MODULE_PATH} = "$bindir_abs/modules";
422 sub prefix_pathvar($$)
423 {
424         my ($name, $newpath) = @_;
425         if (defined($ENV{$name})) {
426                 $ENV{$name} = "$newpath:$ENV{$name}";
427         } else {
428                 $ENV{$name} = $newpath;
429         }
430 }
431 prefix_pathvar("PKG_CONFIG_PATH", "$bindir_abs/pkgconfig");
432 prefix_pathvar("PYTHONPATH", "$bindir_abs/python");
433
434 if ($opt_socket_wrapper_keep_pcap) {
435         # Socket wrapper keep pcap implies socket wrapper pcap
436         $opt_socket_wrapper_pcap = 1;
437 }
438
439 if ($opt_socket_wrapper_pcap) {
440         # Socket wrapper pcap implies socket wrapper
441         $opt_socket_wrapper = 1;
442 }
443
444 my $socket_wrapper_dir;
445 if ($opt_socket_wrapper) {
446         $socket_wrapper_dir = SocketWrapper::setup_dir("$prefix/w", $opt_socket_wrapper_pcap);
447         print "SOCKET_WRAPPER_DIR=$socket_wrapper_dir\n";
448 } else {
449          unless ($< == 0) { 
450                  print "WARNING: Not using socket wrapper, but also not running as root. Will not be able to listen on proper ports\n";
451          }
452 }
453
454 my $target;
455 my $testenv_default = "none";
456
457 if ($opt_target eq "samba4") {
458         $testenv_default = "member";
459         require target::Samba4;
460         $target = new Samba4($bindir, $ldap, "$srcdir/setup", $exeext);
461 } elsif ($opt_target eq "samba3") {
462         if ($opt_socket_wrapper and `$bindir/smbd -b | grep SOCKET_WRAPPER` eq "") {
463                 die("You must include --enable-socket-wrapper when compiling Samba in order to execute 'make test'.  Exiting....");
464         }
465         $testenv_default = "member";
466         require target::Samba3;
467         $target = new Samba3($bindir);
468 } elsif ($opt_target eq "samba34") {
469         if ($opt_socket_wrapper and `$bindir/smbd -b | grep SOCKET_WRAPPER` eq "") {
470                 die("You must include --enable-socket-wrapper when compiling Samba in order to execute 'make test'.  Exiting....");
471         }
472         $testenv_default = "franky_dc";
473         require target::Samba34;
474         $target = new Samba34($bindir);
475 } elsif ($opt_target eq "win") {
476         die("Windows tests will not run with socket wrapper enabled.") 
477                 if ($opt_socket_wrapper);
478         $testenv_default = "dc";
479         require target::Windows;
480         $target = new Windows();
481 } elsif ($opt_target eq "kvm") {
482         die("Kvm tests will not run with socket wrapper enabled.") 
483                 if ($opt_socket_wrapper);
484         require target::Kvm;
485         die("No image specified") unless ($opt_image);
486         $target = new Kvm($opt_image, undef);
487 }
488
489 #
490 # Start a Virtual Distributed Ethernet Switch
491 # Returns the pid of the switch.
492 #
493 sub start_vde_switch($)
494 {
495         my ($path) = @_;
496
497         system("vde_switch --pidfile $path/vde.pid --sock $path/vde.sock --daemon");
498
499         open(PID, "$path/vde.pid");
500         <PID> =~ /([0-9]+)/;
501         my $pid = $1;
502         close(PID);
503
504         return $pid;
505 }
506
507 # Stop a Virtual Distributed Ethernet Switch
508 sub stop_vde_switch($)
509 {
510         my ($pid) = @_;
511         kill 9, $pid;
512 }
513
514 sub read_test_regexes($)
515 {
516         my ($name) = @_;
517         my @ret = ();
518         open(LF, "<$name") or die("unable to read $name: $!");
519         while (<LF>) { 
520                 chomp; 
521                 next if (/^#/);
522                 if (/^(.*?)([ \t]+)\#([\t ]*)(.*?)$/) {
523                         push (@ret, [$1, $4]);
524                 } else {
525                         s/^(.*?)([ \t]+)\#([\t ]*)(.*?)$//;
526                         push (@ret, [$_, undef]); 
527                 }
528         }
529         close(LF);
530         return @ret;
531 }
532
533 if (defined($opt_expected_failures)) {
534         @expected_failures = read_test_regexes($opt_expected_failures);
535 }
536
537 foreach (@opt_exclude) {
538         push (@excludes, read_test_regexes($_));
539 }
540
541 foreach (@opt_include) {
542         push (@includes, read_test_regexes($_));
543 }
544
545 my $interfaces = join(',', ("127.0.0.6/8", 
546                             "127.0.0.7/8",
547                             "127.0.0.8/8",
548                             "127.0.0.9/8",
549                             "127.0.0.10/8",
550                             "127.0.0.11/8"));
551
552 my $conffile = "$prefix_abs/client/client.conf";
553 $ENV{SMB_CONF_PATH} = $conffile;
554
555 sub write_clientconf($$)
556 {
557         my ($conffile, $vars) = @_;
558
559         mkdir("$prefix/client", 0777) unless -d "$prefix/client";
560         
561         if ( -d "$prefix/client/private" ) {
562                 unlink <$prefix/client/private/*>;
563         } else {
564                 mkdir("$prefix/client/private", 0777);
565         }
566
567         if ( -d "$prefix/client/lock" ) {
568                 unlink <$prefix/client/lockdir/*>;
569         } else {
570                 mkdir("$prefix/client/lockdir", 0777);
571         }
572
573         open(CF, ">$conffile");
574         print CF "[global]\n";
575         if (defined($ENV{VALGRIND})) {
576                 print CF "\ticonv:native = true\n";
577         } else {
578                 print CF "\ticonv:native = false\n";
579         }
580         print CF "\tnetbios name = client\n";
581         if (defined($vars->{DOMAIN})) {
582                 print CF "\tworkgroup = $vars->{DOMAIN}\n";
583         }
584         if (defined($vars->{REALM})) {
585                 print CF "\trealm = $vars->{REALM}\n";
586         }
587         if ($opt_socket_wrapper) {
588                 print CF "\tinterfaces = $interfaces\n";
589         }
590         print CF "
591         private dir = $prefix_abs/client/private
592         lock dir = $prefix_abs/client/lockdir
593         name resolve order = bcast
594         panic action = $RealBin/gdb_backtrace \%PID\% \%PROG\%
595         max xmit = 32K
596         notify:inotify = false
597         ldb:nosync = true
598         system:anonymous = true
599         client lanman auth = Yes
600         torture:basedir = $prefix_abs/client
601 #We don't want to pass our self-tests if the PAC code is wrong
602         gensec:require_pac = true
603         modules dir = $ENV{LD_SAMBA_MODULE_PATH}
604 ";
605         close(CF);
606 }
607
608 my @todo = ();
609
610 my $testsdir = "$srcdir/selftest";
611
612 my %required_envs = ();
613
614 sub read_testlist($)
615 {
616         my ($filename) = @_;
617
618         my @ret = ();
619         open(IN, $filename) or die("Unable to open $filename: $!");
620
621         while (<IN>) {
622                 if ($_ eq "-- TEST --\n") {
623                         my $name = <IN>;
624                         $name =~ s/\n//g;
625                         my $env = <IN>;
626                         $env =~ s/\n//g;
627                         my $cmdline = <IN>;
628                         $cmdline =~ s/\n//g;
629                         if (not defined($tests) or $name =~ /$tests/) {
630                                 $required_envs{$env} = 1;
631                                 push (@ret, [$name, $env, $cmdline]);
632                         }
633                 } else {
634                         print;
635                 }
636         }
637         close(IN) or die("Error creating recipe");
638         return @ret;
639 }
640
641 if ($#testlists == -1) {
642         die("No testlists specified");
643 }
644
645 $ENV{SELFTEST_PREFIX} = "$prefix_abs";
646 if ($opt_socket_wrapper) {
647         $ENV{SELFTEST_INTERFACES} = $interfaces;
648 } else {
649         $ENV{SELFTEST_INTERFACES} = "";
650 }
651 if ($opt_verbose) {
652         $ENV{SELFTEST_VERBOSE} = "1";
653 } else {
654         $ENV{SELFTEST_VERBOSE} = "";
655 }
656 if ($opt_quick) {
657         $ENV{SELFTEST_QUICK} = "1";
658 } else {
659         $ENV{SELFTEST_QUICK} = "";
660 }
661 $ENV{SELFTEST_TARGET} = $opt_target;
662 $ENV{SELFTEST_MAXTIME} = $torture_maxtime;
663
664 my @available = ();
665 foreach my $fn (@testlists) {
666         foreach (read_testlist($fn)) {
667                 my $name = $$_[0];
668                 next if (@includes and not find_in_list(\@includes, $name));
669                 push (@available, $_);
670         }
671 }
672
673 my $msg_ops;
674 if ($opt_format eq "buildfarm") {
675         require output::buildfarm;
676         $msg_ops = new output::buildfarm($statistics);
677 } elsif ($opt_format eq "plain") {
678         require output::plain;
679         $msg_ops = new output::plain("$prefix/summary", $opt_verbose, $opt_immediate, $statistics, $#available+1);
680 } elsif ($opt_format eq "html") {
681         require output::html;
682         mkdir("test-results", 0777);
683         $msg_ops = new output::html("test-results", $statistics);
684 } else {
685         die("Invalid output format '$opt_format'");
686 }
687
688
689 foreach (@available) {
690         my $name = $$_[0];
691         my $skipreason = skip($name);
692         if ($skipreason) {
693                 $msg_ops->skip_testsuite($name, $skipreason);
694         } else {
695                 push(@todo, $_); 
696         }
697 }
698
699 if ($#todo == -1) {
700         print STDERR "No tests to run\n";
701         exit(1);
702         }
703
704 my $suitestotal = $#todo + 1;
705 my $i = 0;
706 $| = 1;
707
708 my %running_envs = ();
709
710 sub get_running_env($)
711 {
712         my ($name) = @_;
713
714         my $envname = $name;
715
716         $envname =~ s/:.*//;
717
718         return $running_envs{$envname};
719 }
720
721 my @exported_envvars = (
722         # domain stuff
723         "DOMAIN",
724         "REALM",
725
726         # domain controller stuff
727         "DC_SERVER",
728         "DC_SERVER_IP",
729         "DC_NETBIOSNAME",
730         "DC_NETBIOSALIAS",
731
732         # server stuff
733         "SERVER",
734         "SERVER_IP",
735         "NETBIOSNAME",
736         "NETBIOSALIAS",
737
738         # user stuff
739         "USERNAME",
740         "PASSWORD",
741         "DC_USERNAME",
742         "DC_PASSWORD",
743
744         # misc stuff
745         "KRB5_CONFIG",
746         "WINBINDD_SOCKET_DIR",
747         "WINBINDD_PRIV_PIPE_DIR"
748 );
749
750 $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub { 
751         my $signame = shift;
752         teardown_env($_) foreach(keys %running_envs);
753         die("Received signal $signame");
754 };
755
756 sub setup_env($)
757 {
758         my ($name) = @_;
759
760         my $testenv_vars = undef;
761
762         my $envname = $name;
763         my $option = $name;
764
765         $envname =~ s/:.*//;
766         $option =~ s/^[^:]*//;
767         $option =~ s/^://;
768
769         $option = "client" if $option eq "";
770
771         if ($envname eq "none") {
772                 $testenv_vars = {};
773         } elsif (defined(get_running_env($envname))) {
774                 $testenv_vars = get_running_env($envname);
775                 if (not $target->check_env($testenv_vars)) {
776                         $testenv_vars = undef;
777                 }
778         } else {
779                 $testenv_vars = $target->setup_env($envname, $prefix);
780         }
781
782         return undef unless defined($testenv_vars);
783
784         $running_envs{$envname} = $testenv_vars;
785
786         if ($option eq "local") {
787                 SocketWrapper::set_default_iface($testenv_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
788                 $ENV{SMB_CONF_PATH} = $testenv_vars->{SERVERCONFFILE};
789         } elsif ($option eq "client") {
790                 SocketWrapper::set_default_iface(6);
791                 write_clientconf($conffile, $testenv_vars);
792                 $ENV{SMB_CONF_PATH} = $conffile;
793         } else {
794                 die("Unknown option[$option] for envname[$envname]");
795         }
796
797         foreach (@exported_envvars) {
798                 if (defined($testenv_vars->{$_})) {
799                         $ENV{$_} = $testenv_vars->{$_};
800                 } else {
801                         delete $ENV{$_};
802                 }
803         }
804
805         return $testenv_vars;
806 }
807
808 sub exported_envvars_str($)
809 {
810         my ($testenv_vars) = @_;
811         my $out = "";
812
813         foreach (@exported_envvars) {
814                 next unless defined($testenv_vars->{$_});
815                 $out .= $_."=".$testenv_vars->{$_}."\n";
816         }
817
818         return $out;
819 }
820
821 sub getlog_env($)
822 {
823         my ($envname) = @_;
824         return "" if ($envname eq "none");
825         return $target->getlog_env(get_running_env($envname));
826 }
827
828 sub check_env($)
829 {
830         my ($envname) = @_;
831         return 1 if ($envname eq "none");
832         return $target->check_env(get_running_env($envname));
833 }
834
835 sub teardown_env($)
836 {
837         my ($envname) = @_;
838         return if ($envname eq "none");
839         $target->teardown_env(get_running_env($envname));
840         delete $running_envs{$envname};
841 }
842
843 if ($opt_no_lazy_setup) {
844         setup_env($_) foreach (keys %required_envs);
845 }
846
847 if ($opt_testenv) {
848         my $testenv_name = $ENV{SELFTEST_TESTENV};
849         $testenv_name = $testenv_default unless defined($testenv_name);
850
851         my $testenv_vars = setup_env($testenv_name);
852
853         $ENV{PIDDIR} = $testenv_vars->{PIDDIR};
854
855         my $envvarstr = exported_envvars_str($testenv_vars);
856
857         my $term = ($ENV{TERM} or "xterm");
858         system("$term -e 'echo -e \"
859 Welcome to the Samba4 Test environment '$testenv_name'
860
861 This matches the client environment used in make test
862 server is pid `cat \$PIDDIR/samba.pid`
863
864 Some useful environment variables:
865 TORTURE_OPTIONS=\$TORTURE_OPTIONS
866 SMB_CONF_PATH=\$SMB_CONF_PATH
867
868 $envvarstr
869 \" && LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH} bash'");
870         teardown_env($testenv_name);
871 } else {
872         foreach (@todo) {
873                 $i++;
874                 my $cmd = $$_[2];
875                 $cmd =~ s/([\(\)])/\\$1/g;
876                 my $name = $$_[0];
877                 my $envname = $$_[1];
878                 
879                 my $envvars = setup_env($envname);
880                 if (not defined($envvars)) {
881                         $msg_ops->skip_testsuite($name, "unable to set up environment $envname");
882                         next;
883                 }
884
885                 run_testsuite($envname, $name, $cmd, $i, $suitestotal, 
886                               $msg_ops);
887
888                 if (defined($opt_analyse_cmd)) {
889                         system("$opt_analyse_cmd \"$name\"");
890                 }
891
892                 teardown_env($envname) if ($opt_resetup_env);
893         }
894 }
895
896 print "\n";
897
898 teardown_env($_) foreach (keys %running_envs);
899
900 $target->stop();
901
902 $msg_ops->summary();
903
904 my $failed = 0;
905
906 # if there were any valgrind failures, show them
907 foreach (<$prefix/valgrind.log*>) {
908         next unless (-s $_);
909         system("grep DWARF2.CFI.reader $_ > /dev/null");
910         if ($? >> 8 == 0) {
911             print "VALGRIND FAILURE\n";
912             $failed++;
913             system("cat $_");
914         }
915 }
916
917 if ($opt_format eq "buildfarm") {
918         print "TEST STATUS: $statistics->{SUITES_FAIL}\n";
919 }
920
921 exit $statistics->{SUITES_FAIL};