Add VDE switch management functions.
[jelmer/samba4-debian.git] / source / selftest / selftest.pl
index 03247a4f815c96b92d38c62813c59e115f499108..aa4423c7e2d551eb2068e6cacef2b3caebb1c085 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl
 # Bootstrap Samba and run a number of tests against it.
 #!/usr/bin/perl
 # Bootstrap Samba and run a number of tests against it.
-# Copyright (C) 2005-2007 Jelmer Vernooij <jelmer@samba.org>
+# Copyright (C) 2005-2008 Jelmer Vernooij <jelmer@samba.org>
 # Published under the GNU GPL, v3 or later.
 
 =pod
 # Published under the GNU GPL, v3 or later.
 
 =pod
@@ -13,7 +13,7 @@ selftest - Samba test runner
 
 selftest --help
 
 
 selftest --help
 
-selftest [--srcdir=DIR] [--builddir=DIR] [--target=samba4|samba3|win] [--socket-wrapper] [--quick] [--one] [--prefix=prefix] [--immediate] [--testlist=FILE] [TESTS]
+selftest [--srcdir=DIR] [--builddir=DIR] [--target=samba4|samba3|win|kvm] [--socket-wrapper] [--quick] [--exclude=FILE] [--include=FILE] [--one] [--prefix=prefix] [--immediate] [--testlist=FILE] [TESTS]
 
 =head1 DESCRIPTION
 
 
 =head1 DESCRIPTION
 
@@ -43,7 +43,7 @@ Change directory to run tests in. Default is 'st'.
 
 Show errors as soon as they happen rather than at the end of the test run.
                
 
 Show errors as soon as they happen rather than at the end of the test run.
                
-=item I<--target samba4|samba3|win>
+=item I<--target samba4|samba3|win|kvm>
 
 Specify test target against which to run. Default is 'samba4'.
 
 
 Specify test target against which to run. Default is 'samba4'.
 
@@ -67,17 +67,24 @@ these tests will be counted as successes, successes will be counted as failures.
 
 The format for the file is, one entry per line:
 
 
 The format for the file is, one entry per line:
 
-TESTSUITE-NAME/TEST-NAME
+TESTSUITE-NAME.TEST-NAME
 
 The reason for a test can also be specified, by adding a hash sign (#) and the reason 
 after the test name.
 
 
 The reason for a test can also be specified, by adding a hash sign (#) and the reason 
 after the test name.
 
-=item I<--skip>
+=item I<--exclude>
 
 
-Specify a file containing a list of tests that should be skipped. Possible candidates are
-tests that segfault the server, flip or don't end. The format of this file is the same as 
+Specify a file containing a list of tests that should be skipped. Possible 
+candidates are tests that segfault the server, flip or don't end. The format of this file is the same as 
 for the --expected-failures flag.
 
 for the --expected-failures flag.
 
+=item I<--include>
+
+Specify a file containing a list of tests that should be run. Same format 
+as the --exclude flag.
+
+Not includes specified means all tests will be run.
+
 =item I<--one>
 
 Abort as soon as one test fails.
 =item I<--one>
 
 Abort as soon as one test fails.
@@ -123,9 +130,6 @@ use POSIX;
 use Cwd qw(abs_path);
 use lib "$RealBin";
 use Subunit qw(parse_results);
 use Cwd qw(abs_path);
 use lib "$RealBin";
 use Subunit qw(parse_results);
-use env::Samba3;
-use env::Samba4;
-use env::Windows;
 use SocketWrapper;
 
 my $opt_help = 0;
 use SocketWrapper;
 
 my $opt_help = 0;
@@ -137,8 +141,10 @@ my $opt_socket_wrapper_keep_pcap = undef;
 my $opt_one = 0;
 my $opt_immediate = 0;
 my $opt_expected_failures = undef;
 my $opt_one = 0;
 my $opt_immediate = 0;
 my $opt_expected_failures = undef;
-my $opt_skip = undef;
+my @opt_exclude = ();
+my @opt_include = ();
 my $opt_verbose = 0;
 my $opt_verbose = 0;
+my $opt_image = undef;
 my $opt_testenv = 0;
 my $ldap = undef;
 my $opt_analyse_cmd = undef;
 my $opt_testenv = 0;
 my $ldap = undef;
 my $opt_analyse_cmd = undef;
@@ -146,21 +152,18 @@ my $opt_resetup_env = undef;
 my $opt_bindir = undef;
 my $opt_no_lazy_setup = undef;
 my $opt_format = "plain";
 my $opt_bindir = undef;
 my $opt_no_lazy_setup = undef;
 my $opt_format = "plain";
-my @opt_testlists = ();
+my @testlists = ();
 
 my $srcdir = ".";
 my $builddir = ".";
 my $prefix = "./st";
 
 my @expected_failures = ();
 
 my $srcdir = ".";
 my $builddir = ".";
 my $prefix = "./st";
 
 my @expected_failures = ();
-my @skips = ();
+my @includes = ();
+my @excludes = ();
 
 my $statistics = {
 
 my $statistics = {
-       START_TIME => time(),
-
        SUITES_FAIL => 0,
        SUITES_FAIL => 0,
-       SUITES_OK => 0,
-       SUITES_SKIPPED => 0,
 
        TESTS_UNEXPECTED_OK => 0,
        TESTS_EXPECTED_OK => 0,
 
        TESTS_UNEXPECTED_OK => 0,
        TESTS_EXPECTED_OK => 0,
@@ -193,77 +196,77 @@ sub expecting_failure($)
 sub skip($)
 {
        my ($name) = @_;
 sub skip($)
 {
        my ($name) = @_;
-       return find_in_list(\@skips, $name);
+
+       return find_in_list(\@excludes, $name);
 }
 
 sub getlog_env($);
 
 sub setup_pcap($)
 {
 }
 
 sub getlog_env($);
 
 sub setup_pcap($)
 {
-       my ($state) = @_;
+       my ($state, $name) = @_;
 
        return unless ($opt_socket_wrapper_pcap);
        return unless defined($ENV{SOCKET_WRAPPER_PCAP_DIR});
 
 
        return unless ($opt_socket_wrapper_pcap);
        return unless defined($ENV{SOCKET_WRAPPER_PCAP_DIR});
 
-       my $fname = sprintf("t%03u_%s", $state->{INDEX}, $state->{NAME});
+       my $fname = $name;
        $fname =~ s%[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\-]%_%g;
 
        $fname =~ s%[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\-]%_%g;
 
-       $state->{PCAP_FILE} = "$ENV{SOCKET_WRAPPER_PCAP_DIR}/$fname.pcap";
+       my $pcap_file = "$ENV{SOCKET_WRAPPER_PCAP_DIR}/$fname.pcap";
 
 
-       SocketWrapper::setup_pcap($state->{PCAP_FILE});
+       SocketWrapper::setup_pcap($pcap_file);
+
+       return $pcap_file;
 }
 
 sub cleanup_pcap($$$)
 {
 }
 
 sub cleanup_pcap($$$)
 {
-       my ($state, $expected_ret, $ret) = @_;
+       my ($pcap_file, $expected_ret, $ret) = @_;
 
        return unless ($opt_socket_wrapper_pcap);
        return if ($opt_socket_wrapper_keep_pcap);
        return unless ($expected_ret == $ret);
 
        return unless ($opt_socket_wrapper_pcap);
        return if ($opt_socket_wrapper_keep_pcap);
        return unless ($expected_ret == $ret);
-       return unless defined($state->{PCAP_FILE});
+       return unless defined($pcap_file);
 
 
-       unlink($state->{PCAP_FILE});
-       $state->{PCAP_FILE} = undef;
+       unlink($pcap_file);
 }
 
 sub run_testsuite($$$$$$)
 {
        my ($envname, $name, $cmd, $i, $totalsuites, $msg_ops) = @_;
 }
 
 sub run_testsuite($$$$$$)
 {
        my ($envname, $name, $cmd, $i, $totalsuites, $msg_ops) = @_;
-       my $msg_state = {
-               ENVNAME => $envname,
-               NAME    => $name,
-               CMD     => $cmd,
-               INDEX   => $i,
-               TOTAL   => $totalsuites,
-               START_TIME      => time()
-       };
+       my $pcap_file = setup_pcap($name);
 
 
-       setup_pcap($msg_state);
+       $msg_ops->start_test([], $name);
 
        open(RESULT, "$cmd 2>&1|");
 
        open(RESULT, "$cmd 2>&1|");
-       $msg_ops->start_testsuite($msg_state);
-
        my $expected_ret = parse_results(
        my $expected_ret = parse_results(
-               $msg_ops, $msg_state, $statistics, *RESULT, \&expecting_failure);
+               $msg_ops, $statistics, *RESULT, \&expecting_failure, [$name]);
+
+       my $envlog = getlog_env($envname);
+       $msg_ops->output_msg("ENVLOG: $envlog\n") if ($envlog ne "");
+
+       $msg_ops->output_msg("CMD: $cmd\n");
 
        my $ret = close(RESULT);
 
        my $ret = close(RESULT);
+       $ret = 0 unless $ret == 1;
 
 
-       cleanup_pcap($msg_state, $expected_ret, $ret);
+       if ($ret == 1) {
+               $msg_ops->end_test([], $name, "success", $expected_ret != $ret, undef);
+       } else {
+               $msg_ops->end_test([], $name, "failure", $expected_ret != $ret, 
+                                              "Returned $ret");
+       }
 
 
-       $msg_ops->end_testsuite($msg_state, $expected_ret, $ret,
-                                                       getlog_env($msg_state->{ENVNAME}));
+       cleanup_pcap($pcap_file, $expected_ret, $ret);
 
        if (not $opt_socket_wrapper_keep_pcap and 
 
        if (not $opt_socket_wrapper_keep_pcap and 
-               defined($msg_state->{PCAP_FILE})) {
-               $msg_ops->output_msg($msg_state, 
-                       "PCAP FILE: $msg_state->{PCAP_FILE}\n");
+               defined($pcap_file)) {
+               $msg_ops->output_msg("PCAP FILE: $pcap_file\n");
        }
 
        if ($ret != $expected_ret) {
                $statistics->{SUITES_FAIL}++;
                exit(1) if ($opt_one);
        }
 
        if ($ret != $expected_ret) {
                $statistics->{SUITES_FAIL}++;
                exit(1) if ($opt_one);
-       } else {
-               $statistics->{SUITES_OK}++;
        }
 
        return ($ret == $expected_ret);
        }
 
        return ($ret == $expected_ret);
@@ -278,7 +281,7 @@ Usage: $Script [OPTIONS] PREFIX
 
 Generic options:
  --help                     this help page
 
 Generic options:
  --help                     this help page
- --target=samba4|samba3|win Samba version to target
+ --target=samba[34]|win|kvm Samba version to target
  --testlist=FILE                       file to read available tests from
 
 Paths:
  --testlist=FILE                       file to read available tests from
 
 Paths:
@@ -287,7 +290,7 @@ Paths:
  --builddir=DIR             output directory [.]
 
 Target Specific:
  --builddir=DIR             output directory [.]
 
 Target Specific:
- --socket-wrapper-pcap=DIR     save traffic to pcap directories
+ --socket-wrapper-pcap         save traffic to pcap directories
  --socket-wrapper-keep-pcap keep all pcap files, not just those for tests that 
                             failed
  --socket-wrapper           enable socket wrapper
  --socket-wrapper-keep-pcap keep all pcap files, not just those for tests that 
                             failed
  --socket-wrapper           enable socket wrapper
@@ -299,6 +302,9 @@ Samba4 Specific:
 Samba3 Specific:
  --bindir=PATH              path to binaries
 
 Samba3 Specific:
  --bindir=PATH              path to binaries
 
+Kvm Specific:
+ --image=PATH               path to KVM image
+
 Behaviour:
  --quick                    run quick overall test
  --one                      abort when the first test fails
 Behaviour:
  --quick                    run quick overall test
  --one                      abort when the first test fails
@@ -320,7 +326,8 @@ my $result = GetOptions (
                'one' => \$opt_one,
                'immediate' => \$opt_immediate,
                'expected-failures=s' => \$opt_expected_failures,
                'one' => \$opt_one,
                'immediate' => \$opt_immediate,
                'expected-failures=s' => \$opt_expected_failures,
-               'skip=s' => \$opt_skip,
+               'exclude=s' => \@opt_exclude,
+               'include=s' => \@opt_include,
                'srcdir=s' => \$srcdir,
                'builddir=s' => \$builddir,
                'verbose' => \$opt_verbose,
                'srcdir=s' => \$srcdir,
                'builddir=s' => \$builddir,
                'verbose' => \$opt_verbose,
@@ -331,7 +338,8 @@ my $result = GetOptions (
                'resetup-environment' => \$opt_resetup_env,
                'bindir:s' => \$opt_bindir,
                'format=s' => \$opt_format,
                'resetup-environment' => \$opt_resetup_env,
                'bindir:s' => \$opt_bindir,
                'format=s' => \$opt_format,
-               'testlist=s' => \@opt_testlists
+               'image=s' => \$opt_image,
+               'testlist=s' => \@testlists
            );
 
 exit(1) if (not $result);
            );
 
 exit(1) if (not $result);
@@ -350,7 +358,7 @@ my $old_pwd = "$RealBin/..";
 
 # Backwards compatibility:
 if (defined($ENV{TEST_LDAP}) and $ENV{TEST_LDAP} eq "yes") {
 
 # Backwards compatibility:
 if (defined($ENV{TEST_LDAP}) and $ENV{TEST_LDAP} eq "yes") {
-       if (defined($ENV{FEDORA_DS_PREFIX})) {
+       if (defined($ENV{FEDORA_DS_ROOT})) {
                $ldap = "fedora-ds";
        } else {
                $ldap = "openldap";
                $ldap = "fedora-ds";
        } else {
                $ldap = "openldap";
@@ -379,24 +387,20 @@ die("using an empty absolute prefix isn't allowed") unless $prefix_abs ne "";
 die("using '/' as absolute prefix isn't allowed") unless $prefix_abs ne "/";
 
 $ENV{PREFIX} = $prefix;
 die("using '/' as absolute prefix isn't allowed") unless $prefix_abs ne "/";
 
 $ENV{PREFIX} = $prefix;
+$ENV{KRB5CCNAME} = "$prefix/krb5ticket";
 $ENV{PREFIX_ABS} = $prefix_abs;
 $ENV{SRCDIR} = $srcdir;
 $ENV{SRCDIR_ABS} = $srcdir_abs;
 
 $ENV{PREFIX_ABS} = $prefix_abs;
 $ENV{SRCDIR} = $srcdir;
 $ENV{SRCDIR_ABS} = $srcdir_abs;
 
-my $tls_enabled = not $opt_quick;
 if (defined($ENV{RUN_FROM_BUILD_FARM}) and 
        ($ENV{RUN_FROM_BUILD_FARM} eq "yes")) {
        $opt_format = "buildfarm";
 }
 
 if (defined($ENV{RUN_FROM_BUILD_FARM}) and 
        ($ENV{RUN_FROM_BUILD_FARM} eq "yes")) {
        $opt_format = "buildfarm";
 }
 
+my $tls_enabled = not $opt_quick;
 $ENV{TLS_ENABLED} = ($tls_enabled?"yes":"no");
 $ENV{TLS_ENABLED} = ($tls_enabled?"yes":"no");
-$ENV{LD_LDB_MODULE_PATH} = "$old_pwd/bin/modules/ldb";
+$ENV{LDB_MODULES_PATH} = "$old_pwd/bin/modules/ldb";
 $ENV{LD_SAMBA_MODULE_PATH} = "$old_pwd/bin/modules";
 $ENV{LD_SAMBA_MODULE_PATH} = "$old_pwd/bin/modules";
-if (defined($ENV{LD_LIBRARY_PATH})) {
-       $ENV{LD_LIBRARY_PATH} = "$old_pwd/bin/shared:$ENV{LD_LIBRARY_PATH}";
-} else {
-       $ENV{LD_LIBRARY_PATH} = "$old_pwd/bin/shared";
-}
 if (defined($ENV{PKG_CONFIG_PATH})) {
        $ENV{PKG_CONFIG_PATH} = "$old_pwd/bin/pkgconfig:$ENV{PKG_CONFIG_PATH}";
 } else { 
 if (defined($ENV{PKG_CONFIG_PATH})) {
        $ENV{PKG_CONFIG_PATH} = "$old_pwd/bin/pkgconfig:$ENV{PKG_CONFIG_PATH}";
 } else { 
@@ -405,6 +409,10 @@ if (defined($ENV{PKG_CONFIG_PATH})) {
 # Required for smbscript:
 $ENV{PATH} = "$old_pwd/bin:$old_pwd:$ENV{PATH}";
 
 # Required for smbscript:
 $ENV{PATH} = "$old_pwd/bin:$old_pwd:$ENV{PATH}";
 
+if ($opt_socket_wrapper_keep_pcap) {
+       # Socket wrapper keep pcap implies socket wrapper pcap
+       $opt_socket_wrapper_pcap = 1;
+}
 
 if ($opt_socket_wrapper_pcap) {
        # Socket wrapper pcap implies socket wrapper
 
 if ($opt_socket_wrapper_pcap) {
        # Socket wrapper pcap implies socket wrapper
@@ -420,19 +428,56 @@ if ($opt_socket_wrapper) {
 }
 
 my $target;
 }
 
 my $target;
+my $testenv_default = "none";
 
 if ($opt_target eq "samba4") {
 
 if ($opt_target eq "samba4") {
+       $testenv_default = "member";
+       require target::Samba4;
        $target = new Samba4($opt_bindir or "$srcdir/bin", $ldap, "$srcdir/setup");
 } elsif ($opt_target eq "samba3") {
        if ($opt_socket_wrapper and `$opt_bindir/smbd -b | grep SOCKET_WRAPPER` eq "") {
                die("You must include --enable-socket-wrapper when compiling Samba in order to execute 'make test'.  Exiting....");
        }
        $target = new Samba4($opt_bindir or "$srcdir/bin", $ldap, "$srcdir/setup");
 } elsif ($opt_target eq "samba3") {
        if ($opt_socket_wrapper and `$opt_bindir/smbd -b | grep SOCKET_WRAPPER` eq "") {
                die("You must include --enable-socket-wrapper when compiling Samba in order to execute 'make test'.  Exiting....");
        }
-
+       $testenv_default = "dc";
+       require target::Samba3;
        $target = new Samba3($opt_bindir);
 } elsif ($opt_target eq "win") {
        die("Windows tests will not run with socket wrapper enabled.") 
                if ($opt_socket_wrapper);
        $target = new Samba3($opt_bindir);
 } elsif ($opt_target eq "win") {
        die("Windows tests will not run with socket wrapper enabled.") 
                if ($opt_socket_wrapper);
+       $testenv_default = "dc";
+       require target::Windows;
        $target = new Windows();
        $target = new Windows();
+} elsif ($opt_target eq "kvm") {
+       die("Kvm tests will not run with socket wrapper enabled.") 
+               if ($opt_socket_wrapper);
+       require target::Kvm;
+       die("No image specified") unless ($opt_image);
+       $target = new Kvm($opt_image, undef);
+}
+
+#
+# Start a Virtual Distributed Ethernet Switch
+# Returns the pid of the switch.
+#
+sub start_vde_switch($)
+{
+       my ($path) = @_;
+
+       system("vde_switch --pidfile $path/vde.pid --sock $path/vde.sock --daemon");
+
+       open(PID, "$path/vde.pid");
+       <PID> =~ /([0-9]+)/;
+       my $pid = $1;
+       close(PID);
+
+       return $pid;
+}
+
+# Stop a Virtual Distributed Ethernet Switch
+sub stop_vde_switch($)
+{
+       my ($pid) = @_;
+       kill 9, $pid;
 }
 
 sub read_test_regexes($)
 }
 
 sub read_test_regexes($)
@@ -442,10 +487,10 @@ sub read_test_regexes($)
        open(LF, "<$name") or die("unable to read $name: $!");
        while (<LF>) { 
                chomp; 
        open(LF, "<$name") or die("unable to read $name: $!");
        while (<LF>) { 
                chomp; 
-               if (/^(.*?)([ \t]+)\#(.*)$/) {
-                       push (@ret, [$1, $3]);
+               if (/^(.*?)([ \t]+)\#([\t ]*)(.*?)$/) {
+                       push (@ret, [$1, $4]);
                } else {
                } else {
-                       s/^(.*?)([ \t]+)\#(.*)$//;
+                       s/^(.*?)([ \t]+)\#([\t ]*)(.*?)$//;
                        push (@ret, [$_, undef]); 
                }
        }
                        push (@ret, [$_, undef]); 
                }
        }
@@ -457,8 +502,16 @@ if (defined($opt_expected_failures)) {
        @expected_failures = read_test_regexes($opt_expected_failures);
 }
 
        @expected_failures = read_test_regexes($opt_expected_failures);
 }
 
-if (defined($opt_skip)) {
-       @skips = read_test_regexes($opt_skip);
+foreach (@opt_exclude) {
+       push (@excludes, read_test_regexes($_));
+}
+
+if ($opt_quick) {
+       push (@includes, read_test_regexes("samba4-quick"));
+}
+
+foreach (@opt_include) {
+       push (@includes, read_test_regexes($_));
 }
 
 my $interfaces = join(',', ("127.0.0.6/8", 
 }
 
 my $interfaces = join(',', ("127.0.0.6/8", 
@@ -505,11 +558,13 @@ sub write_clientconf($$)
        if (defined($vars->{WINBINDD_SOCKET_DIR})) {
                print CF "\twinbindd socket directory = $vars->{WINBINDD_SOCKET_DIR}\n";
        }
        if (defined($vars->{WINBINDD_SOCKET_DIR})) {
                print CF "\twinbindd socket directory = $vars->{WINBINDD_SOCKET_DIR}\n";
        }
+       if ($opt_socket_wrapper) {
+               print CF "\tinterfaces = $interfaces\n";
+       }
        print CF "
        private dir = $prefix_abs/client/private
        js include = $srcdir_abs/scripting/libjs
        name resolve order = bcast
        print CF "
        private dir = $prefix_abs/client/private
        js include = $srcdir_abs/scripting/libjs
        name resolve order = bcast
-       interfaces = $interfaces
        panic action = $srcdir_abs/script/gdb_backtrace \%PID\% \%PROG\%
        max xmit = 32K
        notify:inotify = false
        panic action = $srcdir_abs/script/gdb_backtrace \%PID\% \%PROG\%
        max xmit = 32K
        notify:inotify = false
@@ -518,17 +573,17 @@ sub write_clientconf($$)
        torture:basedir = $prefix_abs/client
 #We don't want to pass our self-tests if the PAC code is wrong
        gensec:require_pac = true
        torture:basedir = $prefix_abs/client
 #We don't want to pass our self-tests if the PAC code is wrong
        gensec:require_pac = true
+       modules dir = $ENV{LD_SAMBA_MODULE_PATH}
 ";
        close(CF);
 }
 
 ";
        close(CF);
 }
 
-
 my @torture_options = ();
 push (@torture_options, "--configfile=$conffile");
 # ensure any one smbtorture call doesn't run too long
 push (@torture_options, "--maximum-runtime=$torture_maxtime");
 push (@torture_options, "--target=$opt_target");
 my @torture_options = ();
 push (@torture_options, "--configfile=$conffile");
 # ensure any one smbtorture call doesn't run too long
 push (@torture_options, "--maximum-runtime=$torture_maxtime");
 push (@torture_options, "--target=$opt_target");
-push (@torture_options, "--basedir=$prefix");
+push (@torture_options, "--basedir=$prefix_abs");
 push (@torture_options, "--option=torture:progress=no") if ($opt_format eq "buildfarm");
 push (@torture_options, "--format=subunit");
 push (@torture_options, "--option=torture:quick=yes") if ($opt_quick);
 push (@torture_options, "--option=torture:progress=no") if ($opt_format eq "buildfarm");
 push (@torture_options, "--format=subunit");
 push (@torture_options, "--option=torture:quick=yes") if ($opt_quick);
@@ -571,16 +626,50 @@ sub read_testlist($)
        return @ret;
 }
 
        return @ret;
 }
 
-if ($opt_quick) {
-       @todo = read_testlist("$testsdir/tests_quick.sh|");
+if ($#testlists == -1) {
+       die("No testlists specified");
+}
+
+my @available = ();
+foreach my $fn (@testlists) {
+       foreach (read_testlist($fn)) {
+               my $name = $$_[0];
+               next if (@includes and not find_in_list(\@includes, $name));
+               push (@available, $_);
+       }
+}
+
+my $msg_ops;
+if ($opt_format eq "buildfarm") {
+       require output::buildfarm;
+       $msg_ops = new output::buildfarm($statistics);
+} elsif ($opt_format eq "plain") {
+       require output::plain;
+       $msg_ops = new output::plain("$prefix/summary", $opt_verbose, $opt_immediate, $statistics, $#available+1);
+} elsif ($opt_format eq "html") {
+       require output::html;
+       mkdir("test-results", 0777);
+       $msg_ops = new output::html("test-results", $statistics);
 } else {
 } else {
-       @todo = read_testlist("$testsdir/tests_all.sh|");
+       die("Invalid output format '$opt_format'");
 }
 
 }
 
-foreach (@opt_testlists) {
-       push(@todo, read_testlist($_));
+
+foreach (@available) {
+       my $name = $$_[0];
+       my $skipreason = skip($name);
+       if ($skipreason) {
+               $msg_ops->skip_testsuite($name, $skipreason);
+       } else {
+               push(@todo, $_); 
+       }
 }
 
 }
 
+if ($#todo == -1) {
+       print STDERR "No tests to run\n";
+       exit(1);
+       }
+
 my $suitestotal = $#todo + 1;
 my $i = 0;
 $| = 1;
 my $suitestotal = $#todo + 1;
 my $i = 0;
 $| = 1;
@@ -612,9 +701,16 @@ my @exported_envvars = (
 
        # misc stuff
        "KRB5_CONFIG",
 
        # misc stuff
        "KRB5_CONFIG",
-       "WINBINDD_SOCKET_DIR"
+       "WINBINDD_SOCKET_DIR",
+       "WINBINDD_PRIV_PIPE_DIR"
 );
 
 );
 
+$SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub { 
+       my $signame = shift;
+       teardown_env($_) foreach(keys %running_envs);
+       die("Received signal $signame");
+};
+
 sub setup_env($)
 {
        my ($envname) = @_;
 sub setup_env($)
 {
        my ($envname) = @_;
@@ -633,6 +729,8 @@ sub setup_env($)
 
        return undef unless defined($testenv_vars);
 
 
        return undef unless defined($testenv_vars);
 
+       $running_envs{$envname} = $testenv_vars;
+
        SocketWrapper::set_default_iface(6);
        write_clientconf($conffile, $testenv_vars);
 
        SocketWrapper::set_default_iface(6);
        write_clientconf($conffile, $testenv_vars);
 
@@ -644,7 +742,6 @@ sub setup_env($)
                }
        }
 
                }
        }
 
-       $running_envs{$envname} = $testenv_vars;
        return $testenv_vars;
 }
 
        return $testenv_vars;
 }
 
@@ -683,28 +780,13 @@ sub teardown_env($)
        delete $running_envs{$envname};
 }
 
        delete $running_envs{$envname};
 }
 
-my $msg_ops;
-if ($opt_format eq "buildfarm") {
-       require output::buildfarm;
-       $msg_ops = new output::buildfarm();
-} elsif ($opt_format eq "plain") {
-       require output::plain;
-       $msg_ops = new output::plain($opt_verbose, $opt_immediate, $statistics);
-} elsif ($opt_format eq "html") {
-       require output::html;
-       mkdir("test-results", 0777);
-       $msg_ops = new output::html("test-results", $statistics);
-} else {
-       die("Invalid output format '$opt_format'");
-}
-
 if ($opt_no_lazy_setup) {
        setup_env($_) foreach (keys %required_envs);
 }
 
 if ($opt_testenv) {
        my $testenv_name = $ENV{SELFTEST_TESTENV};
 if ($opt_no_lazy_setup) {
        setup_env($_) foreach (keys %required_envs);
 }
 
 if ($opt_testenv) {
        my $testenv_name = $ENV{SELFTEST_TESTENV};
-       $testenv_name = "member" unless defined($testenv_name);
+       $testenv_name = $testenv_default unless defined($testenv_name);
 
        my $testenv_vars = setup_env($testenv_name);
 
 
        my $testenv_vars = setup_env($testenv_name);
 
@@ -724,7 +806,7 @@ TORTURE_OPTIONS=\$TORTURE_OPTIONS
 CONFIGURATION=\$CONFIGURATION
 
 $envvarstr
 CONFIGURATION=\$CONFIGURATION
 
 $envvarstr
-\" && bash'");
+\" && LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH} bash'");
        teardown_env($testenv_name);
 } else {
        foreach (@todo) {
        teardown_env($testenv_name);
 } else {
        foreach (@todo) {
@@ -734,21 +816,14 @@ $envvarstr
                my $name = $$_[0];
                my $envname = $$_[1];
                
                my $name = $$_[0];
                my $envname = $$_[1];
                
-               my $skipreason = skip($name);
-               if ($skipreason) {
-                       $msg_ops->skip_testsuite($envname, $name, $skipreason);
-                       $statistics->{SUITES_SKIPPED}++;
-                       next;
-               }
-
                my $envvars = setup_env($envname);
                if (not defined($envvars)) {
                my $envvars = setup_env($envname);
                if (not defined($envvars)) {
-                       $statistics->{SUITES_SKIPPED}++;
-                       $msg_ops->missing_env($name, $envname);
+                       $msg_ops->skip_testsuite($name, "unable to set up environment $envname");
                        next;
                }
 
                        next;
                }
 
-               run_testsuite($envname, $name, $cmd, $i, $suitestotal, $msg_ops);
+               run_testsuite($envname, $name, $cmd, $i, $suitestotal, 
+                             $msg_ops);
 
                if (defined($opt_analyse_cmd)) {
                        system("$opt_analyse_cmd \"$name\"");
 
                if (defined($opt_analyse_cmd)) {
                        system("$opt_analyse_cmd \"$name\"");
@@ -764,10 +839,7 @@ teardown_env($_) foreach (keys %running_envs);
 
 $target->stop();
 
 
 $target->stop();
 
-$statistics->{END_TIME} = time();
-my $duration = ($statistics->{END_TIME}-$statistics->{START_TIME});
 $msg_ops->summary();
 $msg_ops->summary();
-print "DURATION: $duration seconds\n";
 
 my $failed = 0;
 
 
 my $failed = 0;