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