X-Git-Url: http://git.samba.org/?p=samba.git;a=blobdiff_plain;f=selftest%2Fselftest.pl;h=c56f31f3762b901556d34d19171d82062b9c5acc;hp=cf79c8344166708dcd623d8e803d8d154d48a07c;hb=6b3404ad95998351127a5d1b181a2825827c7bd5;hpb=955076530425b2c37c7ad545f9a596e8daca0321 diff --git a/selftest/selftest.pl b/selftest/selftest.pl index cf79c834416..c56f31f3762 100755 --- a/selftest/selftest.pl +++ b/selftest/selftest.pl @@ -1,6 +1,6 @@ #!/usr/bin/perl # Bootstrap Samba and run a number of tests against it. -# Copyright (C) 2005-2009 Jelmer Vernooij +# Copyright (C) 2005-2010 Jelmer Vernooij # Copyright (C) 2007-2009 Stefan Metzmacher # This program is free software; you can redistribute it and/or modify @@ -26,7 +26,7 @@ selftest - Samba test runner selftest --help -selftest [--srcdir=DIR] [--builddir=DIR] [--exeext=EXT][--target=samba4|samba3|win|kvm] [--socket-wrapper] [--quick] [--exclude=FILE] [--include=FILE] [--one] [--prefix=prefix] [--testlist=FILE] [TESTS] +selftest [--srcdir=DIR] [--bindir=DIR] [--exeext=EXT][--target=samba|samba3|win] [--socket-wrapper] [--quick] [--exclude=FILE] [--include=FILE] [--one] [--prefix=prefix] [--testlist=FILE] [TESTS] =head1 DESCRIPTION @@ -44,9 +44,9 @@ Show list of available options. Source directory. -=item I<--builddir=DIR> +=item I<--bindir=DIR> -Build directory. +Built binaries directory. =item I<--exeext=EXT> @@ -56,7 +56,7 @@ Executable extention Change directory to run tests in. Default is 'st'. -=item I<--target samba4|samba3|win|kvm> +=item I<--target samba|samba3|win> Specify test target against which to run. Default is 'samba4'. @@ -130,12 +130,19 @@ use Getopt::Long; use POSIX; use Cwd qw(abs_path); use lib "$RealBin"; -use Subunit qw(parse_results); -use Subunit::Filter; +use Subunit; use SocketWrapper; +eval { +require Time::HiRes; +Time::HiRes->import("time"); +}; +if ($@) { + print "You don't have Time::Hires installed !\n"; +} + my $opt_help = 0; -my $opt_target = "samba4"; +my $opt_target = "samba"; my $opt_quick = 0; my $opt_socket_wrapper = 0; my $opt_socket_wrapper_pcap = undef; @@ -144,24 +151,30 @@ my $opt_one = 0; my @opt_exclude = (); my @opt_include = (); my $opt_verbose = 0; -my $opt_image = undef; my $opt_testenv = 0; +my $opt_list = 0; my $ldap = undef; -my $opt_analyse_cmd = undef; my $opt_resetup_env = undef; -my $opt_bindir = undef; -my $opt_no_lazy_setup = undef; +my $opt_binary_mapping = ""; my $opt_load_list = undef; my @testlists = (); my $srcdir = "."; -my $builddir = "."; +my $bindir = "./bin"; my $exeext = ""; my $prefix = "./st"; my @includes = (); my @excludes = (); +sub pipe_handler { + my $sig = shift @_; + print STDERR "Exiting early because of SIGPIPE.\n"; + exit(1); +} + +$SIG{PIPE} = \&pipe_handler; + sub find_in_list($$) { my ($list, $fullname) = @_; @@ -233,38 +246,22 @@ sub run_testsuite($$$$$) Subunit::start_testsuite($name); Subunit::progress_push(); Subunit::report_time(time()); + system($cmd); + Subunit::report_time(time()); + Subunit::progress_pop(); - open(RESULTS, "$cmd 2>&1|"); - my $statistics = { - TESTS_UNEXPECTED_OK => 0, - TESTS_EXPECTED_OK => 0, - TESTS_UNEXPECTED_FAIL => 0, - TESTS_EXPECTED_FAIL => 0, - TESTS_ERROR => 0, - TESTS_SKIP => 0, - }; - - my $msg_ops = new Subunit::Filter("$name\.", []); - - parse_results($msg_ops, $statistics, *RESULTS); - - my $ret = 0; - - unless (close(RESULTS)) { - if ($!) { - Subunit::progress_pop(); - Subunit::end_testsuite($name, "error", "Unable to run $cmd: $!"); - return 0; - } else { - $ret = $?; - } - } - - if ($ret & 127) { + if ($? == -1) { Subunit::progress_pop(); - Subunit::end_testsuite($name, "error", sprintf("Testsuite died with signal %d, %s coredump", ($ret & 127), ($ret & 128) ? "with": "without")); - return 0; + Subunit::end_testsuite($name, "error", "Unable to run $cmd: $!"); + exit(1); + } elsif ($? & 127) { + Subunit::end_testsuite($name, "error", + sprintf("%s died with signal %d, %s coredump\n", $cmd, ($? & 127), ($? & 128) ? 'with' : 'without')); + exit(1); } + + my $exitcode = $? >> 8; + my $envlog = getlog_env($envname); if ($envlog ne "") { print "envlog: $envlog\n"; @@ -273,10 +270,6 @@ sub run_testsuite($$$$$) print "command: $cmd\n"; printf "expanded command: %s\n", expand_environment_strings($cmd); - my $exitcode = $ret >> 8; - - Subunit::report_time(time()); - Subunit::progress_pop(); if ($exitcode == 0) { Subunit::end_testsuite($name, "success"); } else { @@ -306,33 +299,30 @@ Usage: $Script [OPTIONS] TESTNAME-REGEX Generic options: --help this help page - --target=samba[34]|win|kvm Samba version to target - --testlist=FILE file to read available tests from + --target=samba[3]|win Samba version to target + --testlist=FILE file to read available tests from Paths: --prefix=DIR prefix to run tests in [st] --srcdir=DIR source directory [.] - --builddir=DIR output directory [.] + --bindir=DIR binaries directory [./bin] --exeext=EXT executable extention [] Target Specific: - --socket-wrapper-pcap 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 - --bindir=PATH path to target binaries Samba4 Specific: --ldap=openldap|fedora-ds back samba onto specified ldap server -Kvm Specific: - --image=PATH path to KVM image - Behaviour: --quick run quick overall test --one abort when the first test fails --verbose be verbose - --analyse-cmd CMD command to run after each test + --testenv run a shell in the requested test environment + --list list available tests "; exit(0); } @@ -349,24 +339,24 @@ my $result = GetOptions ( 'exclude=s' => \@opt_exclude, 'include=s' => \@opt_include, 'srcdir=s' => \$srcdir, - 'builddir=s' => \$builddir, + 'bindir=s' => \$bindir, 'exeext=s' => \$exeext, 'verbose' => \$opt_verbose, 'testenv' => \$opt_testenv, + 'list' => \$opt_list, 'ldap:s' => \$ldap, - 'analyse-cmd=s' => \$opt_analyse_cmd, - 'no-lazy-setup' => \$opt_no_lazy_setup, 'resetup-environment' => \$opt_resetup_env, - 'bindir:s' => \$opt_bindir, - 'image=s' => \$opt_image, 'testlist=s' => \@testlists, 'load-list=s' => \$opt_load_list, + 'binary-mapping=s' => \$opt_binary_mapping ); exit(1) if (not $result); ShowHelp() if ($opt_help); +die("--list and --testenv are mutually exclusive") if ($opt_list and $opt_testenv); + # we want unbuffered output $| = 1; @@ -381,7 +371,6 @@ unless (defined($ENV{VALGRIND})) { # make all our python scripts unbuffered $ENV{PYTHONUNBUFFERED} = 1; -my $bindir = ($opt_bindir or "$builddir/bin"); my $bindir_abs = abs_path($bindir); # Backwards compatibility: @@ -405,12 +394,20 @@ $prefix =~ s+/$++; die("using an empty prefix isn't allowed") unless $prefix ne ""; -#Ensure we have the test prefix around -mkdir($prefix, 0777) unless -d $prefix; +# Ensure we have the test prefix around. +# +# We need restrictive +# permissions on this as some subdirectories in this tree will have +# wider permissions (ie 0777) and this would allow other users on the +# host to subvert the test process. +mkdir($prefix, 0700) unless -d $prefix; +chmod 0700, $prefix; my $prefix_abs = abs_path($prefix); +my $tmpdir_abs = abs_path("$prefix/tmp"); +mkdir($tmpdir_abs, 0777) unless -d $tmpdir_abs; + my $srcdir_abs = abs_path($srcdir); -my $builddir_abs = abs_path($builddir); 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 "/"; @@ -420,14 +417,12 @@ $ENV{KRB5CCNAME} = "$prefix/krb5ticket"; $ENV{PREFIX_ABS} = $prefix_abs; $ENV{SRCDIR} = $srcdir; $ENV{SRCDIR_ABS} = $srcdir_abs; -$ENV{BUILDDIR} = $builddir; -$ENV{BUILDDIR_ABS} = $builddir_abs; +$ENV{BINDIR} = $bindir_abs; $ENV{EXEEXT} = $exeext; my $tls_enabled = not $opt_quick; $ENV{TLS_ENABLED} = ($tls_enabled?"yes":"no"); -$ENV{LDB_MODULES_PATH} = "$bindir_abs/modules/ldb"; -$ENV{LD_SAMBA_MODULE_PATH} = "$bindir_abs/modules"; + sub prefix_pathvar($$) { my ($name, $newpath) = @_; @@ -454,38 +449,57 @@ my $socket_wrapper_dir; if ($opt_socket_wrapper) { $socket_wrapper_dir = SocketWrapper::setup_dir("$prefix_abs/w", $opt_socket_wrapper_pcap); print "SOCKET_WRAPPER_DIR=$socket_wrapper_dir\n"; -} else { +} elsif (not $opt_list) { unless ($< == 0) { - print "WARNING: Not using socket wrapper, but also not running as root. Will not be able to listen on proper ports\n"; + warn("not using socket wrapper, but also not running as root. Will not be able to listen on proper ports"); } } my $target; my $testenv_default = "none"; -if ($opt_target eq "samba4") { - $testenv_default = "all"; - require target::Samba4; - $target = new Samba4($bindir, $ldap, "$srcdir/setup", $exeext); -} elsif ($opt_target eq "samba3") { - if ($opt_socket_wrapper and `$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 = "member"; - require target::Samba3; - $target = new Samba3($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(); -} 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); +my %binary_mapping = (); +if ($opt_binary_mapping) { + my @binmapping_list = split(/,/, $opt_binary_mapping); + foreach my $mapping (@binmapping_list) { + my ($bin, $map) = split(/\:/, $mapping); + $binary_mapping{$bin} = $map; + } +} + +$ENV{BINARY_MAPPING} = $opt_binary_mapping; + +# After this many seconds, the server will self-terminate. All tests +# must terminate in this time, and testenv will only stay alive this +# long + +my $server_maxtime = 7500; +if (defined($ENV{SMBD_MAXTIME}) and $ENV{SMBD_MAXTIME} ne "") { + $server_maxtime = $ENV{SMBD_MAXTIME}; +} + +unless ($opt_list) { + if ($opt_target eq "samba") { + if ($opt_socket_wrapper and `$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::Samba; + $target = new Samba($bindir, \%binary_mapping, $ldap, $srcdir, $exeext, $server_maxtime); + } elsif ($opt_target eq "samba3") { + if ($opt_socket_wrapper and `$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 = "member"; + require target::Samba3; + $target = new Samba3($bindir, \%binary_mapping, $srcdir_abs, $exeext, $server_maxtime); + } 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(); + } } # @@ -547,40 +561,58 @@ my $interfaces = join(',', ("127.0.0.11/8", "127.0.0.15/8", "127.0.0.16/8")); -my $conffile = "$prefix_abs/client/client.conf"; +my $clientdir = "$prefix_abs/client"; + +my $conffile = "$clientdir/client.conf"; $ENV{SMB_CONF_PATH} = $conffile; -sub write_clientconf($$) +sub write_clientconf($$$) { - my ($conffile, $vars) = @_; + my ($conffile, $clientdir, $vars) = @_; - mkdir("$prefix/client", 0777) unless -d "$prefix/client"; + mkdir("$clientdir", 0777) unless -d "$clientdir"; - if ( -d "$prefix/client/private" ) { - unlink <$prefix/client/private/*>; + if ( -d "$clientdir/private" ) { + unlink <$clientdir/private/*>; } else { - mkdir("$prefix/client/private", 0777); + mkdir("$clientdir/private", 0777); } - if ( -d "$prefix/client/lockdir" ) { - unlink <$prefix/client/lockdir/*>; + if ( -d "$clientdir/lockdir" ) { + unlink <$clientdir/lockdir/*>; } else { - mkdir("$prefix/client/lockdir", 0777); + mkdir("$clientdir/lockdir", 0777); } - if ( -d "$prefix_abs/client/ncalrpcdir" ) { - unlink <$prefix/client/ncalrpcdir/*>; + if ( -d "$clientdir/statedir" ) { + unlink <$clientdir/statedir/*>; } else { - mkdir("$prefix/client/ncalrpcdir", 0777); + mkdir("$clientdir/statedir", 0777); } - open(CF, ">$conffile"); - print CF "[global]\n"; - if (defined($ENV{VALGRIND})) { - print CF "\ticonv:native = true\n"; + if ( -d "$clientdir/cachedir" ) { + unlink <$clientdir/cachedir/*>; } else { - print CF "\ticonv:native = false\n"; + mkdir("$clientdir/cachedir", 0777); + } + + # this is ugly, but the ncalrpcdir needs exactly 0755 + # otherwise tests fail. + my $mask = umask; + umask 0022; + if ( -d "$clientdir/ncalrpcdir/np" ) { + unlink <$clientdir/ncalrpcdir/np/*>; + rmdir "$clientdir/ncalrpcdir/np"; + } + if ( -d "$clientdir/ncalrpcdir" ) { + unlink <$clientdir/ncalrpcdir/*>; + rmdir "$clientdir/ncalrpcdir"; } + mkdir("$clientdir/ncalrpcdir", 0755); + umask $mask; + + open(CF, ">$conffile"); + print CF "[global]\n"; print CF "\tnetbios name = client\n"; if (defined($vars->{DOMAIN})) { print CF "\tworkgroup = $vars->{DOMAIN}\n"; @@ -592,33 +624,31 @@ sub write_clientconf($$) print CF "\tinterfaces = $interfaces\n"; } print CF " - private dir = $prefix_abs/client/private - lock dir = $prefix_abs/client/lockdir - ncalrpc dir = $prefix_abs/client/ncalrpcdir - name resolve order = bcast file - panic action = $RealBin/gdb_backtrace \%PID\% \%PROG\% + private dir = $clientdir/private + lock dir = $clientdir/lockdir + state directory = $clientdir/statedir + cache directory = $clientdir/cachedir + ncalrpc dir = $clientdir/ncalrpcdir + name resolve order = file bcast + panic action = $RealBin/gdb_backtrace \%d max xmit = 32K notify:inotify = false ldb:nosync = true system:anonymous = true client lanman auth = Yes log level = 1 - torture:basedir = $prefix_abs/client + torture:basedir = $clientdir #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} - setup directory = ./setup resolv:host file = $prefix_abs/dns_host_file +#We don't want to run 'speed' tests for very long + torture:timelimit = 1 "; close(CF); } my @todo = (); -my $testsdir = "$srcdir/selftest"; - -my %required_envs = (); - sub should_run_test($) { my $name = shift; @@ -641,8 +671,9 @@ sub read_testlist($) open(IN, $filename) or die("Unable to open $filename: $!"); while () { - if (/-- TEST(-LOADLIST)? --\n/) { + if (/-- TEST(-LOADLIST|-IDLIST|) --\n/) { my $supports_loadlist = (defined($1) and $1 eq "-LOADLIST"); + my $supports_idlist = (defined($1) and $1 eq "-IDLIST"); my $name = ; $name =~ s/\n//g; my $env = ; @@ -650,8 +681,7 @@ sub read_testlist($) my $cmdline = ; $cmdline =~ s/\n//g; if (should_run_test($name) == 1) { - $required_envs{$env} = 1; - push (@ret, [$name, $env, $cmdline, $supports_loadlist]); + push (@ret, [$name, $env, $cmdline, $supports_loadlist, $supports_idlist]); } } else { print; @@ -666,6 +696,8 @@ if ($#testlists == -1) { } $ENV{SELFTEST_PREFIX} = "$prefix_abs"; +$ENV{SELFTEST_TMPDIR} = "$tmpdir_abs"; +$ENV{TEST_DATA_PREFIX} = "$tmpdir_abs"; if ($opt_socket_wrapper) { $ENV{SELFTEST_INTERFACES} = $interfaces; } else { @@ -681,7 +713,6 @@ if ($opt_quick) { } else { $ENV{SELFTEST_QUICK} = ""; } -$ENV{SELFTEST_TARGET} = $opt_target; $ENV{SELFTEST_MAXTIME} = $torture_maxtime; my @available = (); @@ -694,53 +725,74 @@ foreach my $fn (@testlists) { } my $restricted = undef; +my $restricted_used = {}; if ($opt_load_list) { $restricted = []; open(LOAD_LIST, "<$opt_load_list") or die("Unable to open $opt_load_list"); - while () { - chomp; + while () { + chomp; push (@$restricted, $_); } close(LOAD_LIST); } -Subunit::progress($#available+1); -Subunit::report_time(time()); - my $individual_tests = undef; $individual_tests = {}; foreach my $testsuite (@available) { my $name = $$testsuite[0]; my $skipreason = skip($name); - if (defined($skipreason)) { - Subunit::skip_testsuite($name, $skipreason); - } elsif (defined($restricted)) { + if (defined($restricted)) { # Find the testsuite for this test - my $match = 0; + my $match = undef; foreach my $r (@$restricted) { if ($r eq $name) { $individual_tests->{$name} = []; - $match = 1; - } - if ($r =~ /^$name\.(.*)$/) { - push(@{$individual_tests->{$name}}, $1); - $match = 1; + $match = $r; + $restricted_used->{$r} = 1; + } elsif (substr($r, 0, length($name)+1) eq "$name.") { + push(@{$individual_tests->{$name}}, $r); + $match = $r; + $restricted_used->{$r} = 1; + } + } + if ($match) { + if (defined($skipreason)) { + if (not $opt_list) { + Subunit::skip_testsuite($name, $skipreason); + } + } else { + push(@todo, $testsuite); } } - push(@todo, $testsuite) if ($match); + } elsif (defined($skipreason)) { + if (not $opt_list) { + Subunit::skip_testsuite($name, $skipreason); + } } else { - push(@todo, $testsuite); + push(@todo, $testsuite); } } -if ($#todo == -1) { +if (defined($restricted)) { + foreach (@$restricted) { + unless (defined($restricted_used->{$_})) { + print "No test or testsuite found matching $_\n"; + } + } +} elsif ($#todo == -1) { print STDERR "No tests to run\n"; exit(1); - } +} my $suitestotal = $#todo + 1; + +unless ($opt_list) { + Subunit::progress($suitestotal); + Subunit::report_time(time()); +} + my $i = 0; $| = 1; @@ -803,6 +855,7 @@ my @exported_envvars = ( "KRB5_CONFIG", "WINBINDD_SOCKET_DIR", "WINBINDD_PRIV_PIPE_DIR", + "NMBD_SOCKET_DIR", "LOCAL_PATH" ); @@ -812,9 +865,9 @@ $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub { die("Received signal $signame"); }; -sub setup_env($) +sub setup_env($$) { - my ($name) = @_; + my ($name, $prefix) = @_; my $testenv_vars = undef; @@ -831,14 +884,21 @@ sub setup_env($) $testenv_vars = {}; } elsif (defined(get_running_env($envname))) { $testenv_vars = get_running_env($envname); - if (not $target->check_env($testenv_vars)) { - print $target->getlog_env($testenv_vars); + if (not $testenv_vars->{target}->check_env($testenv_vars)) { + print $testenv_vars->{target}->getlog_env($testenv_vars); $testenv_vars = undef; } } else { $testenv_vars = $target->setup_env($envname, $prefix); + if (defined($testenv_vars) && not defined($testenv_vars->{target})) { + $testenv_vars->{target} = $target; + } + if (not defined($testenv_vars)) { + warn("$opt_target can't provide environment '$envname'"); + } } + return undef unless defined($testenv_vars); $running_envs{$envname} = $testenv_vars; @@ -848,7 +908,7 @@ sub setup_env($) $ENV{SMB_CONF_PATH} = $testenv_vars->{SERVERCONFFILE}; } elsif ($option eq "client") { SocketWrapper::set_default_iface(11); - write_clientconf($conffile, $testenv_vars); + write_clientconf($conffile, $clientdir, $testenv_vars); $ENV{SMB_CONF_PATH} = $conffile; } else { die("Unknown option[$option] for envname[$envname]"); @@ -882,43 +942,45 @@ sub getlog_env($) { my ($envname) = @_; return "" if ($envname eq "none"); - return $target->getlog_env(get_running_env($envname)); + my $env = get_running_env($envname); + return $env->{target}->getlog_env($env); } sub check_env($) { my ($envname) = @_; return 1 if ($envname eq "none"); - return $target->check_env(get_running_env($envname)); + my $env = get_running_env($envname); + return $env->{target}->check_env($env); } sub teardown_env($) { my ($envname) = @_; return if ($envname eq "none"); - $target->teardown_env(get_running_env($envname)); + my $env = get_running_env($envname); + $env->{target}->teardown_env($env); delete $running_envs{$envname}; } # This 'global' file needs to be empty when we start unlink("$prefix_abs/dns_host_file"); -if ($opt_no_lazy_setup) { - setup_env($_) foreach (keys %required_envs); -} - if ($opt_testenv) { my $testenv_name = $ENV{SELFTEST_TESTENV}; $testenv_name = $testenv_default unless defined($testenv_name); - my $testenv_vars = setup_env($testenv_name); + my $testenv_vars = setup_env($testenv_name, $prefix); + + die("Unable to setup environment $testenv_name") unless ($testenv_vars); $ENV{PIDDIR} = $testenv_vars->{PIDDIR}; + $ENV{ENVNAME} = $testenv_name; my $envvarstr = exported_envvars_str($testenv_vars); - my $term = ($ENV{TERMINAL} or "xterm"); - system("$term -e 'echo -e \" + my $term = ($ENV{TERMINAL} or "xterm -e"); + system("$term 'echo -e \" Welcome to the Samba4 Test environment '$testenv_name' This matches the client environment used in make test @@ -931,37 +993,63 @@ SMB_CONF_PATH=\$SMB_CONF_PATH $envvarstr \" && LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH} bash'"); teardown_env($testenv_name); +} elsif ($opt_list) { + foreach (@todo) { + my $cmd = $$_[2]; + my $name = $$_[0]; + my $envname = $$_[1]; + + unless($cmd =~ /\$LISTOPT/) { + warn("Unable to list tests in $name"); + next; + } + + $cmd =~ s/\$LISTOPT/--list/g; + + system($cmd); + + if ($? == -1) { + die("Unable to run $cmd: $!"); + } elsif ($? & 127) { + die(snprintf("%s died with signal %d, %s coredump\n", $cmd, ($? & 127), ($? & 128) ? 'with' : 'without')); + } + + my $exitcode = $? >> 8; + if ($exitcode != 0) { + die("$cmd exited with exit code $exitcode"); + } + } } else { foreach (@todo) { $i++; my $cmd = $$_[2]; - $cmd =~ s/([\(\)])/\\$1/g; my $name = $$_[0]; my $envname = $$_[1]; - - my $envvars = setup_env($envname); + + my $envvars = setup_env($envname, $prefix); if (not defined($envvars)) { - Subunit::skip_testsuite($name, - "unable to set up environment $envname"); + Subunit::start_testsuite($name); + Subunit::end_testsuite($name, "error", + "unable to set up environment $envname - exiting"); next; } # Generate a file with the individual tests to run, if the # test runner for this test suite supports it. - if ($$_[3] and $individual_tests and $individual_tests->{$name}) { - my ($fh, $listid_file) = tempfile(UNLINK => 0); - foreach (@{$individual_tests->{$name}}) { - print $fh "$_\n"; + if ($individual_tests and $individual_tests->{$name}) { + if ($$_[3]) { + my ($fh, $listid_file) = tempfile(UNLINK => 0); + foreach my $test (@{$individual_tests->{$name}}) { + print $fh substr($test, length($name)+1) . "\n"; + } + $cmd =~ s/\$LOADLIST/--load-list=$listid_file/g; + } elsif ($$_[4]) { + $cmd =~ s/\s+[^\s]+\s*$//; + $cmd .= " " . join(' ', @{$individual_tests->{$name}}); } - $cmd .= " --load-list=$listid_file"; } - run_testsuite($envname, $name, $cmd, $i, $suitestotal, - ); - - if (defined($opt_analyse_cmd)) { - system("$opt_analyse_cmd \"$name\""); - } + run_testsuite($envname, $name, $cmd, $i, $suitestotal); teardown_env($envname) if ($opt_resetup_env); }