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