From 48155d189aaf2ac8d4ddabf909fcae44e9321e13 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 4 Mar 2012 05:00:55 +0100 Subject: selftest: More work on conversion to Python. --- selftest/selftest.py | 1288 +++++++++++++++++++------------------------------- 1 file changed, 482 insertions(+), 806 deletions(-) (limited to 'selftest/selftest.py') diff --git a/selftest/selftest.py b/selftest/selftest.py index 3b211b3dff..3c65660c7a 100755 --- a/selftest/selftest.py +++ b/selftest/selftest.py @@ -16,33 +16,44 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import os import sys import signal - -opt_help = 0; -opt_target = "samba"; -opt_quick = 0; -opt_socket_wrapper = 0; -opt_socket_wrapper_pcap = undef; -opt_socket_wrapper_keep_pcap = undef; -opt_one = 0; -opt_exclude = (); -opt_include = (); -opt_verbose = 0; -opt_testenv = 0; -opt_list = 0; -ldap = undef; -opt_resetup_env = undef; -opt_binary_mapping = ""; -opt_load_list = undef; -testlists = (); - -srcdir = "."; -bindir = "./bin"; -prefix = "./st"; - -includes = (); -excludes = (); +import warnings + +import optparse + +includes = () +excludes = () + +def read_excludes(fn): + excludes.extend(read_test_regexes(fn)) + +def read_includes(fn): + includes.extend(read_test_regexes(fn)) + +parser = optparse.OptionParser("TEST-REGEXES") +parser.add_option("--target", type="choice", choices=["samba", "samba3"], default="samba", help="Samba version to target") +parser.add_option("--quick", help="run quick overall test") +parser.add_option("--verbose", help="be verbose") +parser.add_option("--list", help="list available tests") +parser.add_option("--socket-wrapper", help="enable socket wrapper") +parser.add_option("--socket-wrapper-pcap", help="save traffic to pcap directories", type="str") +parser.add_option("--socket-wrapper-keep-pcap", help="keep all pcap files, not just those for tests that failed") +parser.add_option("--one", help="abort when the first test fails") +parser.add_option("--exclude", action="callback", help="Add file to exclude files", callback=read_excludes) +parser.add_option("--include", action="callback", help="Add file to include files", callback=read_includes) +parser.add_option("--testenv", help="run a shell in the requested test environment") +parser.add_option("--resetup-environment", help="Re-setup environment") +parser.add_option("--binary-mapping", help="Map binaries to use", type=str) +parser.add_option("--load-list", help="Load list of tests to load from a file", type=str) +parser.add_option("--prefix", help="prefix to run tests in", type=str, default="./st") +parser.add_option("--srcdir", type=str, default=".", help="source directory") +parser.add_option("--bindir", type=str, default="./bin", help="binaries directory") +parser.add_option("--testlist", type=str, action="append", help="file to read available tests from") +parser.add_option("--ldap", help="back samba onto specified ldap server", choices=["openldap", "fedora-ds"], type=str) + +opts, args = parser.parse_args() def pipe_handler(sig): sys.stderr.write("Exiting early because of SIGPIPE.\n") @@ -50,222 +61,127 @@ def pipe_handler(sig): signal.signal(signal.SIGPIPE, pipe_handler) -sub find_in_list($$) -{ - my ($list, $fullname) = @_; - - foreach (@$list) { - if ($fullname =~ /$$_[0]/) { - return ($$_[1]) if ($$_[1]); - return ""; - } - } - - return undef; -} - -sub skip($) -{ - my ($name) = @_; +def skip(name): + return find_in_list(excludes, name) - return find_in_list(\@excludes, $name); -} +def setup_pcap(name): + if (not opts.socket_wrapper_pcap or + not os.environ.get("SOCKET_WRAPPER_PCAP_DIR"): + return -sub getlog_env($); + fname = name + fname =~ s%[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\-]%_%g; -sub setup_pcap($) -{ - my ($name) = @_; + pcap_file = os.path.join(os.environ["SOCKET_WRAPPER_PCAP_DIR"], "%s.pcap" % + fname) - return unless ($opt_socket_wrapper_pcap); - return unless defined($ENV{SOCKET_WRAPPER_PCAP_DIR}); + socket_wrapper.setup_pcap(pcap_file) + return pcap_file - my $fname = $name; - $fname =~ s%[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\-]%_%g; - my $pcap_file = "$ENV{SOCKET_WRAPPER_PCAP_DIR}/$fname.pcap"; +def cleanup_pcap(pcap_file, exit_code): + if not opts.socket_wrapper_pcap: + return + if opts.socket_wrapper_keep_pcap: + return + if exitcode == 0: + return + if pcap_file is None: + return - SocketWrapper::setup_pcap($pcap_file); + os.unlink(pcap_file) - return $pcap_file; -} - -sub cleanup_pcap($$) -{ - my ($pcap_file, $exitcode) = @_; - - return unless ($opt_socket_wrapper_pcap); - return if ($opt_socket_wrapper_keep_pcap); - return unless ($exitcode == 0); - return unless defined($pcap_file); - - unlink($pcap_file); -} # expand strings from %ENV -sub expand_environment_strings($) -{ - my $s = shift; +def expand_environment_strings(s): # we use a reverse sort so we do the longer ones first foreach my $k (sort { $b cmp $a } keys %ENV) { $s =~ s/\$$k/$ENV{$k}/g; } return $s; -} -sub run_testsuite($$$$$) -{ - my ($envname, $name, $cmd, $i, $totalsuites) = @_; - my $pcap_file = setup_pcap($name); - Subunit::start_testsuite($name); +def run_testsuite(envname, name, cmd, i, totalsuites): + pcap_file = setup_pcap(name) + + Subunit::start_testsuite(name); Subunit::progress_push(); Subunit::report_time(time()); - system($cmd); + os.system(cmd) Subunit::report_time(time()); Subunit::progress_pop(); if ($? == -1) { Subunit::progress_pop(); - Subunit::end_testsuite($name, "error", "Unable to run $cmd: $!"); + Subunit::end_testsuite(name, "error", "Unable to run $cmd: $!"); exit(1); } elsif ($? & 127) { - Subunit::end_testsuite($name, "error", + 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"; - } + envlog = env_manager.getlog_env(envname) + if envlog != "": + sys.stdout.write("envlog: %s\n" % envlog) - print "command: $cmd\n"; - printf "expanded command: %s\n", expand_environment_strings($cmd); + sys.stdout.write("command: %s\n" % cmd) + sys.stdout.write("expanded command: %s\n" % expand_environment_strings(cmd)) - if ($exitcode == 0) { - Subunit::end_testsuite($name, "success"); - } else { - Subunit::end_testsuite($name, "failure", "Exit code was $exitcode"); - } + if exitcode == 0: + Subunit::end_testsuite(name, "success") + else: + Subunit::end_testsuite(name, "failure", "Exit code was %d" % exitcode) - cleanup_pcap($pcap_file, $exitcode); + cleanup_pcap(pcap_file, exitcode) - if (not $opt_socket_wrapper_keep_pcap and defined($pcap_file)) { - print "PCAP FILE: $pcap_file\n"; - } + if not opts.socket_wrapper_keep_pcap and pcap_file is not None: + sys.stdout.write("PCAP FILE: %s\n" % pcap_file) - if ($exitcode != 0) { - exit(1) if ($opt_one); - } + if exitcode != 0 and opts.one: + sys.exit(1) - return $exitcode; -} - -sub ShowHelp() -{ - print "Samba test runner -Copyright (C) Jelmer Vernooij -Copyright (C) Stefan Metzmacher - -Usage: $Script [OPTIONS] TESTNAME-REGEX - -Generic options: - --help this help page - --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 [.] - --bindir=DIR binaries directory [./bin] - -Target Specific: - --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 - -Samba4 Specific: - --ldap=openldap|fedora-ds back samba onto specified ldap server - -Behaviour: - --quick run quick overall test - --one abort when the first test fails - --verbose be verbose - --testenv run a shell in the requested test environment - --list list available tests -"; - exit(0); -} - -my $result = GetOptions ( - 'help|h|?' => \$opt_help, - 'target=s' => \$opt_target, - 'prefix=s' => \$prefix, - 'socket-wrapper' => \$opt_socket_wrapper, - 'socket-wrapper-pcap' => \$opt_socket_wrapper_pcap, - 'socket-wrapper-keep-pcap' => \$opt_socket_wrapper_keep_pcap, - 'quick' => \$opt_quick, - 'one' => \$opt_one, - 'exclude=s' => \@opt_exclude, - 'include=s' => \@opt_include, - 'srcdir=s' => \$srcdir, - 'bindir=s' => \$bindir, - 'verbose' => \$opt_verbose, - 'testenv' => \$opt_testenv, - 'list' => \$opt_list, - 'ldap:s' => \$ldap, - 'resetup-environment' => \$opt_resetup_env, - '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); + return exitcode + +if opts.list and opts.testenv: + sys.stderr.write("--list and --testenv are mutually exclusive\n") + sys.exit(1) # we want unbuffered output $| = 1; -my @tests = @ARGV; +tests = args # quick hack to disable rpc validation when using valgrind - its way too slow -unless (defined($ENV{VALGRIND})) { - $ENV{VALIDATE} = "validate"; - $ENV{MALLOC_CHECK_} = 2; -} +if not os.environ.get("VALGRIND"): + os.environ"VALIDATE"] = "validate" + os.environ["MALLOC_CHECK_"] = 2 # make all our python scripts unbuffered -$ENV{PYTHONUNBUFFERED} = 1; +os.environ["PYTHONUNBUFFERED"] = "1" -my $bindir_abs = abs_path($bindir); +bindir_abs = os.path.abspath(bindir) # Backwards compatibility: -if (defined($ENV{TEST_LDAP}) and $ENV{TEST_LDAP} eq "yes") { - if (defined($ENV{FEDORA_DS_ROOT})) { - $ldap = "fedora-ds"; - } else { - $ldap = "openldap"; - } -} +if os.environ.get("TEST_LDAP") == "yes": + if os.environ.get("FEDORA_DS_ROOT"): + ldap = "fedora-ds" + else: + ldap = "openldap" -my $torture_maxtime = ($ENV{TORTURE_MAXTIME} or 1200); -if ($ldap) { - # LDAP is slow - $torture_maxtime *= 2; -} +torture_maxtime = int(os.getenv("TORTURE_MAXTIME", "1200")) +if ldap: + # LDAP is slow + torture_maxtime *= 2 $prefix =~ s+//+/+; $prefix =~ s+/./+/+; $prefix =~ s+/$++; -die("using an empty prefix isn't allowed") unless $prefix ne ""; +if prefix == "": + raise Exception("using an empty prefix isn't allowed") # Ensure we have the test prefix around. # @@ -273,582 +189,352 @@ die("using an empty prefix isn't allowed") unless $prefix ne ""; # 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); - -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; -$ENV{KRB5CCNAME} = "$prefix/krb5ticket"; -$ENV{PREFIX_ABS} = $prefix_abs; -$ENV{SRCDIR} = $srcdir; -$ENV{SRCDIR_ABS} = $srcdir_abs; -$ENV{BINDIR} = $bindir_abs; - -my $tls_enabled = not $opt_quick; -$ENV{TLS_ENABLED} = ($tls_enabled?"yes":"no"); - -sub prefix_pathvar($$) -{ - my ($name, $newpath) = @_; - if (defined($ENV{$name})) { - $ENV{$name} = "$newpath:$ENV{$name}"; - } else { - $ENV{$name} = $newpath; - } -} -prefix_pathvar("PKG_CONFIG_PATH", "$bindir_abs/pkgconfig"); -prefix_pathvar("PYTHONPATH", "$bindir_abs/python"); - -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 - $opt_socket_wrapper = 1; -} - -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"; -} elsif (not $opt_list) { - unless ($< == 0) { - 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"; - -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; +if not os.path.isdir(prefix): + os.mkdir(prefix, 0700) +else: + os.chmod(prefix, 0700) + +prefix_abs = os.path.abspath(prefix) +tmpdir_abs = os.path.abspath(os.path.join(prefix, "tmp")) +if not os.path.isdir(tmpdir_abs): + os.mkdir(tmpdir_abs, 0777) + +srcdir_abs = os.path.abspath(srcdir) + +if prefix_abs == "": + raise Exception("using an empty absolute prefix isn't allowed") +if prefix_abs == "/": + raise Exception("using '/' as absolute prefix isn't allowed") + +os.environ["PREFIX"] = prefix +os.environ["KRB5CCNAME"] = os.path.join(prefix, "krb5ticket") +os.environ["PREFIX_ABS"] = prefix_abs +os.environ["SRCDIR"] = srcdir +os.environ["SRCDIR_ABS"] = srcdir_abs +os.environ["BINDIR"] = bindir_abs + +tls_enabled = not opts.quick +if tls_enabled: + os.environ["TLS_ENABLED"] = "yes" +else: + os.environ["TLS_ENABLED"] = "no" + +def prefix_pathvar(name, newpath): + if name in os.environ: + os.environ[name] = "%s:%s" % (newpath, os.environ[name]) + else: + .environ[name] = newpath +prefix_pathvar("PKG_CONFIG_PATH", os.path.join(bindir_abs, "pkgconfig")) +prefix_pathvar("PYTHONPATH", os.path.join(bindir_abs, "python")) + +if opts.socket_wrapper_keep_pcap: + # Socket wrapper keep pcap implies socket wrapper pcap + opts.socket_wrapper_pcap = True + +if opts.socket_wrapper_pcap: + # Socket wrapper pcap implies socket wrapper + opts.socket_wrapper = True + +if opts.socket_wrapper: + socket_wrapper_dir = socket_wrapper.setup_dir(os.path.join(prefix_abs, "w"), opts.socket_wrapper_pcap) + sys.stdout.write("SOCKET_WRAPPER_DIR=%s\n" % socket_wrapper_dir) +elif not opts.list: + if sys.getuid() != 0: + warnings.warn("not using socket wrapper, but also not running as root. Will not be able to listen on proper ports") + +testenv_default = "none" + +if opts.binary_mapping: + binary_mapping = dict([l.split(":") for l in opts.binary_mapping.split(",")]) +else: + binary_mapping = {} + +os.environ["BINARY_MAPPING"] = opts.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, $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, $server_maxtime); - } -} - -# -# 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"); - =~ /([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($) -{ - my ($name) = @_; - my @ret = (); - open(LF, "<$name") or die("unable to read $name: $!"); - while () { - chomp; - next if (/^#/); - if (/^(.*?)([ \t]+)\#([\t ]*)(.*?)$/) { - push (@ret, [$1, $4]); - } else { - s/^(.*?)([ \t]+)\#([\t ]*)(.*?)$//; - push (@ret, [$_, undef]); - } - } - close(LF); - return @ret; -} - -foreach (@opt_exclude) { - push (@excludes, read_test_regexes($_)); -} - -foreach (@opt_include) { - push (@includes, read_test_regexes($_)); -} - -my $interfaces = join(',', ("127.0.0.11/8", - "127.0.0.12/8", - "127.0.0.13/8", - "127.0.0.14/8", - "127.0.0.15/8", - "127.0.0.16/8")); - -my $clientdir = "$prefix_abs/client"; - -my $conffile = "$clientdir/client.conf"; -$ENV{SMB_CONF_PATH} = $conffile; - -sub write_clientconf($$$) -{ - my ($conffile, $clientdir, $vars) = @_; - - mkdir("$clientdir", 0777) unless -d "$clientdir"; - - if ( -d "$clientdir/private" ) { - unlink <$clientdir/private/*>; - } else { - mkdir("$clientdir/private", 0777); - } - - if ( -d "$clientdir/lockdir" ) { - unlink <$clientdir/lockdir/*>; - } else { - mkdir("$clientdir/lockdir", 0777); - } - - if ( -d "$clientdir/statedir" ) { - unlink <$clientdir/statedir/*>; - } else { - mkdir("$clientdir/statedir", 0777); - } - - if ( -d "$clientdir/cachedir" ) { - unlink <$clientdir/cachedir/*>; - } else { - mkdir("$clientdir/cachedir", 0777); - } +server_maxtime = 7500 +if os.environ.get("SMBD_MAXTIME", ""): + server_maxtime = int(os.environ["SMBD_MAXTIME"]) + +if not opts.list: + if opts.target == "samba": + if opts.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, $server_maxtime) + elif opts.target == "samba3": + if opts.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, $server_maxtime) + +interfaces = ",".join([ + "127.0.0.11/8", + "127.0.0.12/8", + "127.0.0.13/8", + "127.0.0.14/8", + "127.0.0.15/8", + "127.0.0.16/8"]) + +clientdir = os.path.join(prefix_abs, "client") + +conffile = os.path.join(clientdir, "client.conf") +os.environ["SMB_CONF_PATH"] = conffile + +def write_clientconf(conffile, clientdir, vars): + if not os.path.isdir(clientdir): + os.mkdir(clientdir, 0777) + + for n in ["private", "lockdir", "statedir", "cachedir"]: + p = os.path.join(clientdir, n) + shutil.rmtree(p) + os.mkdir(p, 0777) + + # this is ugly, but the ncalrpcdir needs exactly 0755 + # otherwise tests fail. + mask = os.umask(0022) + + for n in ["ncalrpcdir", "ncalrpcdir/np"]: + p = os.path.join(clientdir, n) + shutil.rmtree(p) + os.mkdir(p, 0777) + os.umask(mask) + + settings = { + "netbios name": "client", + "private dir": os.path.join(clientdir, "private"), + "lock dir": os.path.join(clientdir, "lockdir"), + "state directory": os.path.join(clientdir, "statedir"), + "cache directory": os.path.join(clientdir, "cachedir"), + "ncalrpc dir": os.path.join(clientdir, "ncalrpcdir"), + "name resolve order": "file bcast", + "panic action": os.path.join(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": clientdir, + #We don't want to pass our self-tests if the PAC code is wrong + "gensec:require_pac": "true", + "resolv:host file": os.path.join(prefix_abs, "dns_host_file"), + #We don't want to run 'speed' tests for very long + "torture:timelimit": "1", + } + + if "DOMAIN" in vars: + settings["workgroup"] = vars["DOMAIN"] + if "REALM" in vars: + settings["realm"] = vars["REALM"] + if opts.socket_wrapper: + settings["interfaces"] = interfaces + + f = open(conffile, 'w') + try: + f.write("[global]\n") + for item in settings.iteritems(): + f.write("\t%s = %s\n" % item) + finally: + f.close() + +todo = [] + +if testlists == []: + sys.stderr.write("No testlists specified\n") + sys.exit(1) - # 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"; - } - if (defined($vars->{REALM})) { - print CF "\trealm = $vars->{REALM}\n"; - } - if ($opt_socket_wrapper) { - print CF "\tinterfaces = $interfaces\n"; - } - print CF " - 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 = $clientdir -#We don't want to pass our self-tests if the PAC code is wrong - gensec:require_pac = true - 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 = (); - -sub should_run_test($) -{ - my $name = shift; - if ($#tests == -1) { - return 1; - } - for (my $i=0; $i <= $#tests; $i++) { - if ($name =~ /$tests[$i]/i) { - return 1; - } - } - return 0; -} - -sub read_testlist($) -{ - my ($filename) = @_; - - my @ret = (); - open(IN, $filename) or die("Unable to open $filename: $!"); - - while () { - 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 = ; - $env =~ s/\n//g; - my $cmdline = ; - $cmdline =~ s/\n//g; - if (should_run_test($name) == 1) { - push (@ret, [$name, $env, $cmdline, $supports_loadlist, $supports_idlist]); - } - } else { - print; - } - } - close(IN) or die("Error creating recipe"); - return @ret; -} - -if ($#testlists == -1) { - die("No testlists specified"); -} - -$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 { - $ENV{SELFTEST_INTERFACES} = ""; -} -if ($opt_verbose) { - $ENV{SELFTEST_VERBOSE} = "1"; -} else { - $ENV{SELFTEST_VERBOSE} = ""; -} -if ($opt_quick) { - $ENV{SELFTEST_QUICK} = "1"; -} else { - $ENV{SELFTEST_QUICK} = ""; -} -$ENV{SELFTEST_MAXTIME} = $torture_maxtime; - -my @available = (); -foreach my $fn (@testlists) { - foreach (read_testlist($fn)) { - my $name = $$_[0]; - next if (@includes and not defined(find_in_list(\@includes, $name))); - push (@available, $_); - } -} +os.environ["SELFTEST_PREFIX"] = prefix_abs +os.environ["SELFTEST_TMPDIR"] = tmpdir_abs +os.environ["TEST_DATA_PREFIX"] = tmpdir_abs +if opts.socket_wrapper: + os.environ["SELFTEST_INTERFACES"] = interfaces +else: + os.environ["SELFTEST_INTERFACES"] = "" +if opts.verbose: + os.environ["SELFTEST_VERBOSE"] = "1" +else: + os.environ["SELFTEST_VERBOSE"] = "" +if opts.quick: + os.environ["SELFTEST_QUICK"] = "1" +else: + os.environ["SELFTEST_QUICK"] = "" +os.environ["SELFTEST_MAXTIME"] = str(torture_maxtime) + +available = [] +for fn in testlists: + for testsuite in read_testlist(fn): + if not should_run_test(tests, testsuite): + continue + name = testsuite[0] + if includes is not None and find_in_list(includes, name) is not None: + continue + available.append(testsuite) + +if opts.load_list: + individual_tests = {} + restricted = [] + f = open(opts.load_list, 'r') + try: + restricted_mgr = RestrictedTestManager(read_restricted_test_list(f)) + finally: + f.close() +else: + restricted_mgr = None + individual_tests = None + + +for testsuite in available: + name = testsuite[0] + skipreason = skip(name) + if restricted_mgr is not None: + match = restricted_mgr.should_run_testsuite(name) + if match == []: + continue + else: + match = None + if skipreason is not None: + if not opts.list: + Subunit::skip_testsuite(name, skipreason) + else: + todo.append(testsuite + (match,)) + +if restricted_mgr is not None: + for name in restricted_mgr.iter_unused(): + sys.stdout.write("No test or testsuite found matching %s\n" % name) +if todo == []: + sys.stderr.write("No tests to run\n") + sys.exit(1) -my $restricted = undef; -my $restricted_used = {}; +suitestotal = len(todo) -if ($opt_load_list) { - $restricted = []; - open(LOAD_LIST, "<$opt_load_list") or die("Unable to open $opt_load_list"); - while () { - chomp; - push (@$restricted, $_); - } - close(LOAD_LIST); -} - -my $individual_tests = undef; -$individual_tests = {}; - -foreach my $testsuite (@available) { - my $name = $$testsuite[0]; - my $skipreason = skip($name); - if (defined($restricted)) { - # Find the testsuite for this test - my $match = undef; - foreach my $r (@$restricted) { - if ($r eq $name) { - $individual_tests->{$name} = []; - $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); - } - } - } elsif (defined($skipreason)) { - if (not $opt_list) { - Subunit::skip_testsuite($name, $skipreason); - } - } else { - push(@todo, $testsuite); - } -} +if not opts.list: + Subunit::progress($suitestotal) + Subunit::report_time(time()) -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); -} +i = 0 +$| = 1; -my $suitestotal = $#todo + 1; +exported_envvars = [ + # domain stuff + "DOMAIN", + "REALM", + + # domain controller stuff + "DC_SERVER", + "DC_SERVER_IP", + "DC_NETBIOSNAME", + "DC_NETBIOSALIAS", + + # domain member + "MEMBER_SERVER", + "MEMBER_SERVER_IP", + "MEMBER_NETBIOSNAME", + "MEMBER_NETBIOSALIAS", + + # rpc proxy controller stuff + "RPC_PROXY_SERVER", + "RPC_PROXY_SERVER_IP", + "RPC_PROXY_NETBIOSNAME", + "RPC_PROXY_NETBIOSALIAS", + + # domain controller stuff for Vampired DC + "VAMPIRE_DC_SERVER", + "VAMPIRE_DC_SERVER_IP", + "VAMPIRE_DC_NETBIOSNAME", + "VAMPIRE_DC_NETBIOSALIAS", + + # server stuff + "SERVER", + "SERVER_IP", + "NETBIOSNAME", + "NETBIOSALIAS", + + # user stuff + "USERNAME", + "USERID", + "PASSWORD", + "DC_USERNAME", + "DC_PASSWORD", + + # misc stuff + "KRB5_CONFIG", + "WINBINDD_SOCKET_DIR", + "WINBINDD_PRIV_PIPE_DIR", + "NMBD_SOCKET_DIR", + "LOCAL_PATH" +] + +def handle_sigdie(signame): + env_manager.teardown_all() + sys.stderr.write("Received signal %s" % signame) + sys.exit(1) -unless ($opt_list) { - Subunit::progress($suitestotal); - Subunit::report_time(time()); -} +signal.signal(signal.SIGINT, handle_sigdie) +signal.signal(signal.SIGQUIT, handle_sigdie) +signal.signal(signal.SIGTERM, handle_sigdie) -my $i = 0; -$| = 1; +def exported_envvars_str(testenv_vars): + out = "" -my %running_envs = (); - -sub get_running_env($) -{ - my ($name) = @_; - - my $envname = $name; - - $envname =~ s/:.*//; - - return $running_envs{$envname}; -} - -my @exported_envvars = ( - # domain stuff - "DOMAIN", - "REALM", - - # domain controller stuff - "DC_SERVER", - "DC_SERVER_IP", - "DC_NETBIOSNAME", - "DC_NETBIOSALIAS", - - # domain member - "MEMBER_SERVER", - "MEMBER_SERVER_IP", - "MEMBER_NETBIOSNAME", - "MEMBER_NETBIOSALIAS", - - # rpc proxy controller stuff - "RPC_PROXY_SERVER", - "RPC_PROXY_SERVER_IP", - "RPC_PROXY_NETBIOSNAME", - "RPC_PROXY_NETBIOSALIAS", - - # domain controller stuff for Vampired DC - "VAMPIRE_DC_SERVER", - "VAMPIRE_DC_SERVER_IP", - "VAMPIRE_DC_NETBIOSNAME", - "VAMPIRE_DC_NETBIOSALIAS", - - # server stuff - "SERVER", - "SERVER_IP", - "NETBIOSNAME", - "NETBIOSALIAS", - - # user stuff - "USERNAME", - "USERID", - "PASSWORD", - "DC_USERNAME", - "DC_PASSWORD", - - # misc stuff - "KRB5_CONFIG", - "WINBINDD_SOCKET_DIR", - "WINBINDD_PRIV_PIPE_DIR", - "NMBD_SOCKET_DIR", - "LOCAL_PATH" -); - -$SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub { - my $signame = shift; - teardown_env($_) foreach(keys %running_envs); - die("Received signal $signame"); -}; - -sub setup_env($$) -{ - my ($name, $prefix) = @_; - - my $testenv_vars = undef; - - my $envname = $name; - my $option = $name; - - $envname =~ s/:.*//; - $option =~ s/^[^:]*//; - $option =~ s/^://; - - $option = "client" if $option eq ""; - - if ($envname eq "none") { - $testenv_vars = {}; - } elsif (defined(get_running_env($envname))) { - $testenv_vars = get_running_env($envname); - 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) and $testenv_vars eq "UNKNOWN") { - return $testenv_vars; - } elsif (defined($testenv_vars) && not defined($testenv_vars->{target})) { - $testenv_vars->{target} = $target; - } - if (not defined($testenv_vars)) { - warn("$opt_target can't start up known environment '$envname'"); - } - } + for n in exported_envvars: + if not n in testenv_vars: + continue + out += "%s=%s\n" % (n, testenv_vars[n]) - - return undef unless defined($testenv_vars); + return out - $running_envs{$envname} = $testenv_vars; - if ($option eq "local") { - SocketWrapper::set_default_iface($testenv_vars->{SOCKET_WRAPPER_DEFAULT_IFACE}); - $ENV{SMB_CONF_PATH} = $testenv_vars->{SERVERCONFFILE}; - } elsif ($option eq "client") { - SocketWrapper::set_default_iface(11); - write_clientconf($conffile, $clientdir, $testenv_vars); - $ENV{SMB_CONF_PATH} = $conffile; - } else { - die("Unknown option[$option] for envname[$envname]"); - } +def switch_env(name, prefix): + if ":" in name: + (envname, option) = name.split(":", 1) + else: + envname = name + option = "client" - foreach (@exported_envvars) { - if (defined($testenv_vars->{$_})) { - $ENV{$_} = $testenv_vars->{$_}; - } else { - delete $ENV{$_}; - } - } + env = env_manager.setup_env(envname, prefix) - return $testenv_vars; -} + testenv_vars = env.get_vars() -sub exported_envvars_str($) -{ - my ($testenv_vars) = @_; - my $out = ""; + if option == "local": + socket_wrapper.set_default_iface(testenv_vars["SOCKET_WRAPPER_DEFAULT_IFACE"]) + os.environ["SMB_CONF_PATH"] = testenv_vars["SERVERCONFFILE"] + elif option == "client": + socket_wrapper.set_default_iface(11) + write_clientconf(conffile, clientdir, testenv_vars) + os.environ["SMB_CONF_PATH"] = conffile + else: + raise Exception("Unknown option[%s] for envname[%s]" % (option, + envname)) - foreach (@exported_envvars) { - next unless defined($testenv_vars->{$_}); - $out .= $_."=".$testenv_vars->{$_}."\n"; - } + for name in exported_envvars: + if name in testenv_vars: + os.environ[name] = testenv_vars[name] + else: + del os.environ[name] - return $out; -} - -sub getlog_env($) -{ - my ($envname) = @_; - return "" if ($envname eq "none"); - my $env = get_running_env($envname); - return $env->{target}->getlog_env($env); -} - -sub check_env($) -{ - my ($envname) = @_; - return 1 if ($envname eq "none"); - my $env = get_running_env($envname); - return $env->{target}->check_env($env); -} - -sub teardown_env($) -{ - my ($envname) = @_; - return if ($envname eq "none"); - my $env = get_running_env($envname); - $env->{target}->teardown_env($env); - delete $running_envs{$envname}; -} + return testenv_vars # This 'global' file needs to be empty when we start -unlink("$prefix_abs/dns_host_file"); - -if ($opt_testenv) { - my $testenv_name = $ENV{SELFTEST_TESTENV}; - $testenv_name = $testenv_default unless defined($testenv_name); +os.unlink(os.path.join(prefix_abs, "dns_host_file")) - my $testenv_vars = setup_env($testenv_name, $prefix); +if opts.testenv: + testenv_name = os.environ.get("SELFTEST_TESTENV", testenv_default) - die("Unable to setup environment $testenv_name") unless ($testenv_vars); + testenv_vars = switch_env(testenv_name, prefix) - $ENV{PIDDIR} = $testenv_vars->{PIDDIR}; - $ENV{ENVNAME} = $testenv_name; + os.environ["PIDDIR"] = testenv_vars["PIDDIR"] + os.environ["ENVNAME"] = testenv_name - my $envvarstr = exported_envvars_str($testenv_vars); + envvarstr = exported_envvars_str(testenv_vars) - my $term = ($ENV{TERMINAL} or "xterm -e"); - system("$term 'echo -e \" + term = os.environ.get("TERMINAL", "xterm -e") + os.system("$term 'echo -e \" Welcome to the Samba4 Test environment '$testenv_name' This matches the client environment used in make test @@ -860,85 +546,75 @@ 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; - } + env_manager.teardown_env(testenv_name) +elif opts.list: + for (name, envname, cmd, supports_loadfile, supports_idlist, subtests) in todo: + if not "$LISTOPT" in cmd: + warnings.warn("Unable to list tests in %s" % name) + continue - $cmd =~ s/\$LISTOPT/--list/g; + cmd = cmd.replace("$LISTOPT", "--list") - system($cmd); + os.system(cmd) - if ($? == -1) { + 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]; - my $name = $$_[0]; - my $envname = $$_[1]; - - my $envvars = setup_env($envname, $prefix); - if (not defined($envvars)) { - Subunit::start_testsuite($name); - Subunit::end_testsuite($name, "error", - "unable to set up environment $envname - exiting"); - next; - } elsif ($envvars eq "UNKNOWN") { - Subunit::start_testsuite($name); - Subunit::end_testsuite($name, "skip", - "environment $envname is unknown in this test backend - skipping"); - next; - } - - # Generate a file with the individual tests to run, if the - # test runner for this test suite supports it. - 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}}); - } - } - - run_testsuite($envname, $name, $cmd, $i, $suitestotal); - - teardown_env($envname) if ($opt_resetup_env); - } -} - -print "\n"; - -teardown_env($_) foreach (keys %running_envs); - -my $failed = 0; + my $exitcode = $? >> 8; + if exitcode != 0: + sys.stderr.write("%s exited with exit code %s\n" % (cmd, exitcode)) + sys.exit(1) +else: + for (name, envname, cmd, supports_loadfile, supports_idlist, subtests) in todo: + try: + envvars = switch_env(envname, prefix) + except Exception: + Subunit::start_testsuite(name); + Subunit::end_testsuite(name, "error", + "unable to set up environment %s" % envname); + continue + if envvars is None: + Subunit::start_testsuite(name); + Subunit::end_testsuite(name, "skip", + "environment is unknown in this test backend - skipping" % envname) + continue + + # Generate a file with the individual tests to run, if the + # test runner for this test suite supports it. + if subtests is not None: + if supports_loadfile: + (fd, listid_file) = tempfile.mkstemp() + # FIXME: Remove tempfile afterwards + f = os.fdopen(fd) + try: + for test in subtests: + f.write(test+"\n") + finally: + f.close() + cmd = cmd.replace("$LOADLIST", "--load-list=%s" % listid_file) + elif supports_idlist: + cmd += " ".join(subtests) + + run_testsuite(envname, name, cmd, i, suitestotal) + + if opts.resetup_env: + env_manager.teardown_env(envname) + +sys.stdout.write("\n") + +env_manager.teardown_all() # if there were any valgrind failures, show them -foreach (<$prefix/valgrind.log*>) { - next unless (-s $_); - print "VALGRIND FAILURE\n"; - $failed++; - system("cat $_"); -} -exit 0; +for fn in os.listdir(prefix): + if fn.startswith("valgrind.log"): + sys.stdout.write("VALGRIND FAILURE\n") + f = open(os.path.join(prefix, fn), 'r') + try: + sys.stdout.write(f.read()) + finally: + f.close() + +sys.exit(0) -- cgit