selftest: don't export $CONFIGURATION anymore only $SMB_CONF_PATH
[samba.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 $old_pwd = "$RealBin/..";
369
370 # Backwards compatibility:
371 if (defined($ENV{TEST_LDAP}) and $ENV{TEST_LDAP} eq "yes") {
372         if (defined($ENV{FEDORA_DS_ROOT})) {
373                 $ldap = "fedora-ds";
374         } else {
375                 $ldap = "openldap";
376         }
377 }
378
379 my $torture_maxtime = ($ENV{TORTURE_MAXTIME} or 1200);
380 if ($ldap) {
381         # LDAP is slow
382         $torture_maxtime *= 2;
383 }
384
385 $prefix =~ s+//+/+;
386 $prefix =~ s+/./+/+;
387 $prefix =~ s+/$++;
388
389 die("using an empty prefix isn't allowed") unless $prefix ne "";
390
391 #Ensure we have the test prefix around
392 mkdir($prefix, 0777) unless -d $prefix;
393
394 my $prefix_abs = abs_path($prefix);
395 my $srcdir_abs = abs_path($srcdir);
396
397 die("using an empty absolute prefix isn't allowed") unless $prefix_abs ne "";
398 die("using '/' as absolute prefix isn't allowed") unless $prefix_abs ne "/";
399
400 $ENV{PREFIX} = $prefix;
401 $ENV{KRB5CCNAME} = "$prefix/krb5ticket";
402 $ENV{PREFIX_ABS} = $prefix_abs;
403 $ENV{SRCDIR} = $srcdir;
404 $ENV{SRCDIR_ABS} = $srcdir_abs;
405
406 if (defined($ENV{RUN_FROM_BUILD_FARM}) and 
407         ($ENV{RUN_FROM_BUILD_FARM} eq "yes")) {
408         $opt_format = "buildfarm";
409 }
410
411 my $tls_enabled = not $opt_quick;
412 $ENV{TLS_ENABLED} = ($tls_enabled?"yes":"no");
413 $ENV{LDB_MODULES_PATH} = "$old_pwd/source4/bin/modules/ldb";
414 $ENV{LD_SAMBA_MODULE_PATH} = "$old_pwd/source4/bin/modules";
415 sub prefix_pathvar($$)
416 {
417         my ($name, $newpath) = @_;
418         if (defined($ENV{$name})) {
419                 $ENV{$name} = "$newpath:$ENV{$name}";
420         } else {
421                 $ENV{$name} = $newpath;
422         }
423 }
424 prefix_pathvar("PKG_CONFIG_PATH", "$old_pwd/source4/bin/pkgconfig");
425 prefix_pathvar("PYTHONPATH", "$old_pwd/source4/bin/python");
426
427 if ($opt_socket_wrapper_keep_pcap) {
428         # Socket wrapper keep pcap implies socket wrapper pcap
429         $opt_socket_wrapper_pcap = 1;
430 }
431
432 if ($opt_socket_wrapper_pcap) {
433         # Socket wrapper pcap implies socket wrapper
434         $opt_socket_wrapper = 1;
435 }
436
437 my $socket_wrapper_dir;
438 if ($opt_socket_wrapper) {
439         $socket_wrapper_dir = SocketWrapper::setup_dir("$prefix/w", $opt_socket_wrapper_pcap);
440         print "SOCKET_WRAPPER_DIR=$socket_wrapper_dir\n";
441 } else {
442          unless ($< == 0) { 
443                  print "WARNING: Not using socket wrapper, but also not running as root. Will not be able to listen on proper ports\n";
444          }
445 }
446
447 my $target;
448 my $testenv_default = "none";
449
450 if ($opt_target eq "samba4") {
451         $testenv_default = "member";
452         require target::Samba4;
453         $target = new Samba4($opt_bindir or "$builddir/bin",
454                              $ldap, "$srcdir/setup", $exeext);
455 } elsif ($opt_target eq "samba3") {
456         my $bindir = ($opt_bindir or "$builddir/bin");
457         if ($opt_socket_wrapper and `$bindir/smbd -b | grep SOCKET_WRAPPER` eq "") {
458                 die("You must include --enable-socket-wrapper when compiling Samba in order to execute 'make test'.  Exiting....");
459         }
460         $testenv_default = "member";
461         require target::Samba3;
462         $target = new Samba3($bindir);
463 } elsif ($opt_target eq "win") {
464         die("Windows tests will not run with socket wrapper enabled.") 
465                 if ($opt_socket_wrapper);
466         $testenv_default = "dc";
467         require target::Windows;
468         $target = new Windows();
469 } elsif ($opt_target eq "kvm") {
470         die("Kvm tests will not run with socket wrapper enabled.") 
471                 if ($opt_socket_wrapper);
472         require target::Kvm;
473         die("No image specified") unless ($opt_image);
474         $target = new Kvm($opt_image, undef);
475 }
476
477 #
478 # Start a Virtual Distributed Ethernet Switch
479 # Returns the pid of the switch.
480 #
481 sub start_vde_switch($)
482 {
483         my ($path) = @_;
484
485         system("vde_switch --pidfile $path/vde.pid --sock $path/vde.sock --daemon");
486
487         open(PID, "$path/vde.pid");
488         <PID> =~ /([0-9]+)/;
489         my $pid = $1;
490         close(PID);
491
492         return $pid;
493 }
494
495 # Stop a Virtual Distributed Ethernet Switch
496 sub stop_vde_switch($)
497 {
498         my ($pid) = @_;
499         kill 9, $pid;
500 }
501
502 sub read_test_regexes($)
503 {
504         my ($name) = @_;
505         my @ret = ();
506         open(LF, "<$name") or die("unable to read $name: $!");
507         while (<LF>) { 
508                 chomp; 
509                 next if (/^#/);
510                 if (/^(.*?)([ \t]+)\#([\t ]*)(.*?)$/) {
511                         push (@ret, [$1, $4]);
512                 } else {
513                         s/^(.*?)([ \t]+)\#([\t ]*)(.*?)$//;
514                         push (@ret, [$_, undef]); 
515                 }
516         }
517         close(LF);
518         return @ret;
519 }
520
521 if (defined($opt_expected_failures)) {
522         @expected_failures = read_test_regexes($opt_expected_failures);
523 }
524
525 foreach (@opt_exclude) {
526         push (@excludes, read_test_regexes($_));
527 }
528
529 foreach (@opt_include) {
530         push (@includes, read_test_regexes($_));
531 }
532
533 my $interfaces = join(',', ("127.0.0.6/8", 
534                             "127.0.0.7/8",
535                             "127.0.0.8/8",
536                             "127.0.0.9/8",
537                             "127.0.0.10/8",
538                             "127.0.0.11/8"));
539
540 my $conffile = "$prefix_abs/client/client.conf";
541 $ENV{SMB_CONF_PATH} = $conffile;
542
543 sub write_clientconf($$)
544 {
545         my ($conffile, $vars) = @_;
546
547         mkdir("$prefix/client", 0777) unless -d "$prefix/client";
548         
549         if ( -d "$prefix/client/private" ) {
550                 unlink <$prefix/client/private/*>;
551         } else {
552                 mkdir("$prefix/client/private", 0777);
553         }
554
555         if ( -d "$prefix/client/lock" ) {
556                 unlink <$prefix/client/lockdir/*>;
557         } else {
558                 mkdir("$prefix/client/lockdir", 0777);
559         }
560
561         open(CF, ">$conffile");
562         print CF "[global]\n";
563         if (defined($ENV{VALGRIND})) {
564                 print CF "\ticonv:native = true\n";
565         } else {
566                 print CF "\ticonv:native = false\n";
567         }
568         print CF "\tnetbios name = client\n";
569         if (defined($vars->{DOMAIN})) {
570                 print CF "\tworkgroup = $vars->{DOMAIN}\n";
571         }
572         if (defined($vars->{REALM})) {
573                 print CF "\trealm = $vars->{REALM}\n";
574         }
575         if ($opt_socket_wrapper) {
576                 print CF "\tinterfaces = $interfaces\n";
577         }
578         print CF "
579         private dir = $prefix_abs/client/private
580         lock dir = $prefix_abs/client/lockdir
581         name resolve order = bcast
582         panic action = $RealBin/gdb_backtrace \%PID\% \%PROG\%
583         max xmit = 32K
584         notify:inotify = false
585         ldb:nosync = true
586         system:anonymous = true
587         client lanman auth = Yes
588         torture:basedir = $prefix_abs/client
589 #We don't want to pass our self-tests if the PAC code is wrong
590         gensec:require_pac = true
591         modules dir = $ENV{LD_SAMBA_MODULE_PATH}
592 ";
593         close(CF);
594 }
595
596 my @todo = ();
597
598 my $testsdir = "$srcdir/selftest";
599
600 my %required_envs = ();
601
602 sub read_testlist($)
603 {
604         my ($filename) = @_;
605
606         my @ret = ();
607         open(IN, $filename) or die("Unable to open $filename: $!");
608
609         while (<IN>) {
610                 if ($_ eq "-- TEST --\n") {
611                         my $name = <IN>;
612                         $name =~ s/\n//g;
613                         my $env = <IN>;
614                         $env =~ s/\n//g;
615                         my $cmdline = <IN>;
616                         $cmdline =~ s/\n//g;
617                         if (not defined($tests) or $name =~ /$tests/) {
618                                 $required_envs{$env} = 1;
619                                 push (@ret, [$name, $env, $cmdline]);
620                         }
621                 } else {
622                         print;
623                 }
624         }
625         close(IN) or die("Error creating recipe");
626         return @ret;
627 }
628
629 if ($#testlists == -1) {
630         die("No testlists specified");
631 }
632
633 $ENV{SELFTEST_PREFIX} = "$prefix_abs";
634 if ($opt_socket_wrapper) {
635         $ENV{SELFTEST_INTERFACES} = $interfaces;
636 } else {
637         $ENV{SELFTEST_INTERFACES} = "";
638 }
639 if ($opt_verbose) {
640         $ENV{SELFTEST_VERBOSE} = "1";
641 } else {
642         $ENV{SELFTEST_VERBOSE} = "";
643 }
644 if ($opt_quick) {
645         $ENV{SELFTEST_QUICK} = "1";
646 } else {
647         $ENV{SELFTEST_QUICK} = "";
648 }
649 $ENV{SELFTEST_TARGET} = $opt_target;
650 $ENV{SELFTEST_MAXTIME} = $torture_maxtime;
651
652 my @available = ();
653 foreach my $fn (@testlists) {
654         foreach (read_testlist($fn)) {
655                 my $name = $$_[0];
656                 next if (@includes and not find_in_list(\@includes, $name));
657                 push (@available, $_);
658         }
659 }
660
661 my $msg_ops;
662 if ($opt_format eq "buildfarm") {
663         require output::buildfarm;
664         $msg_ops = new output::buildfarm($statistics);
665 } elsif ($opt_format eq "plain") {
666         require output::plain;
667         $msg_ops = new output::plain("$prefix/summary", $opt_verbose, $opt_immediate, $statistics, $#available+1);
668 } elsif ($opt_format eq "html") {
669         require output::html;
670         mkdir("test-results", 0777);
671         $msg_ops = new output::html("test-results", $statistics);
672 } else {
673         die("Invalid output format '$opt_format'");
674 }
675
676
677 foreach (@available) {
678         my $name = $$_[0];
679         my $skipreason = skip($name);
680         if ($skipreason) {
681                 $msg_ops->skip_testsuite($name, $skipreason);
682         } else {
683                 push(@todo, $_); 
684         }
685 }
686
687 if ($#todo == -1) {
688         print STDERR "No tests to run\n";
689         exit(1);
690         }
691
692 my $suitestotal = $#todo + 1;
693 my $i = 0;
694 $| = 1;
695
696 my %running_envs = ();
697
698 sub get_running_env($)
699 {
700         my ($name) = @_;
701
702         my $envname = $name;
703
704         $envname =~ s/:.*//;
705
706         return $running_envs{$envname};
707 }
708
709 my @exported_envvars = (
710         # domain stuff
711         "DOMAIN",
712         "REALM",
713
714         # domain controller stuff
715         "DC_SERVER",
716         "DC_SERVER_IP",
717         "DC_NETBIOSNAME",
718         "DC_NETBIOSALIAS",
719
720         # server stuff
721         "SERVER",
722         "SERVER_IP",
723         "NETBIOSNAME",
724         "NETBIOSALIAS",
725
726         # user stuff
727         "USERNAME",
728         "PASSWORD",
729         "DC_USERNAME",
730         "DC_PASSWORD",
731
732         # misc stuff
733         "KRB5_CONFIG",
734         "WINBINDD_SOCKET_DIR",
735         "WINBINDD_PRIV_PIPE_DIR"
736 );
737
738 $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub { 
739         my $signame = shift;
740         teardown_env($_) foreach(keys %running_envs);
741         die("Received signal $signame");
742 };
743
744 sub setup_env($)
745 {
746         my ($name) = @_;
747
748         my $testenv_vars = undef;
749
750         my $envname = $name;
751         my $option = $name;
752
753         $envname =~ s/:.*//;
754         $option =~ s/^[^:]*//;
755         $option =~ s/^://;
756
757         $option = "client" if $option eq "";
758
759         if ($envname eq "none") {
760                 $testenv_vars = {};
761         } elsif (defined(get_running_env($envname))) {
762                 $testenv_vars = get_running_env($envname);
763                 if (not $target->check_env($testenv_vars)) {
764                         $testenv_vars = undef;
765                 }
766         } else {
767                 $testenv_vars = $target->setup_env($envname, $prefix);
768         }
769
770         return undef unless defined($testenv_vars);
771
772         $running_envs{$envname} = $testenv_vars;
773
774         if ($option eq "local") {
775                 SocketWrapper::set_default_iface($testenv_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
776                 $ENV{SMB_CONF_PATH} = $testenv_vars->{SERVERCONFFILE};
777         } elsif ($option eq "client") {
778                 SocketWrapper::set_default_iface(6);
779                 write_clientconf($conffile, $testenv_vars);
780                 $ENV{SMB_CONF_PATH} = $conffile;
781         } else {
782                 die("Unknown option[$option] for envname[$envname]");
783         }
784
785         foreach (@exported_envvars) {
786                 if (defined($testenv_vars->{$_})) {
787                         $ENV{$_} = $testenv_vars->{$_};
788                 } else {
789                         delete $ENV{$_};
790                 }
791         }
792
793         return $testenv_vars;
794 }
795
796 sub exported_envvars_str($)
797 {
798         my ($testenv_vars) = @_;
799         my $out = "";
800
801         foreach (@exported_envvars) {
802                 next unless defined($testenv_vars->{$_});
803                 $out .= $_."=".$testenv_vars->{$_}."\n";
804         }
805
806         return $out;
807 }
808
809 sub getlog_env($)
810 {
811         my ($envname) = @_;
812         return "" if ($envname eq "none");
813         return $target->getlog_env(get_running_env($envname));
814 }
815
816 sub check_env($)
817 {
818         my ($envname) = @_;
819         return 1 if ($envname eq "none");
820         return $target->check_env(get_running_env($envname));
821 }
822
823 sub teardown_env($)
824 {
825         my ($envname) = @_;
826         return if ($envname eq "none");
827         $target->teardown_env(get_running_env($envname));
828         delete $running_envs{$envname};
829 }
830
831 if ($opt_no_lazy_setup) {
832         setup_env($_) foreach (keys %required_envs);
833 }
834
835 if ($opt_testenv) {
836         my $testenv_name = $ENV{SELFTEST_TESTENV};
837         $testenv_name = $testenv_default unless defined($testenv_name);
838
839         my $testenv_vars = setup_env($testenv_name);
840
841         $ENV{PIDDIR} = $testenv_vars->{PIDDIR};
842
843         my $envvarstr = exported_envvars_str($testenv_vars);
844
845         my $term = ($ENV{TERM} or "xterm");
846         system("$term -e 'echo -e \"
847 Welcome to the Samba4 Test environment '$testenv_name'
848
849 This matches the client environment used in make test
850 server is pid `cat \$PIDDIR/samba.pid`
851
852 Some useful environment variables:
853 TORTURE_OPTIONS=\$TORTURE_OPTIONS
854 SMB_CONF_PATH=\$SMB_CONF_PATH
855
856 $envvarstr
857 \" && LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH} bash'");
858         teardown_env($testenv_name);
859 } else {
860         foreach (@todo) {
861                 $i++;
862                 my $cmd = $$_[2];
863                 $cmd =~ s/([\(\)])/\\$1/g;
864                 my $name = $$_[0];
865                 my $envname = $$_[1];
866                 
867                 my $envvars = setup_env($envname);
868                 if (not defined($envvars)) {
869                         $msg_ops->skip_testsuite($name, "unable to set up environment $envname");
870                         next;
871                 }
872
873                 run_testsuite($envname, $name, $cmd, $i, $suitestotal, 
874                               $msg_ops);
875
876                 if (defined($opt_analyse_cmd)) {
877                         system("$opt_analyse_cmd \"$name\"");
878                 }
879
880                 teardown_env($envname) if ($opt_resetup_env);
881         }
882 }
883
884 print "\n";
885
886 teardown_env($_) foreach (keys %running_envs);
887
888 $target->stop();
889
890 $msg_ops->summary();
891
892 my $failed = 0;
893
894 # if there were any valgrind failures, show them
895 foreach (<$prefix/valgrind.log*>) {
896         next unless (-s $_);
897         system("grep DWARF2.CFI.reader $_ > /dev/null");
898         if ($? >> 8 == 0) {
899             print "VALGRIND FAILURE\n";
900             $failed++;
901             system("cat $_");
902         }
903 }
904
905 if ($opt_format eq "buildfarm") {
906         print "TEST STATUS: $statistics->{SUITES_FAIL}\n";
907 }
908
909 exit $statistics->{SUITES_FAIL};