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