2 # Bootstrap Samba and run a number of tests against it.
3 # Copyright (C) 2005-2010 Jelmer Vernooij <jelmer@samba.org>
4 # Copyright (C) 2007-2009 Stefan Metzmacher <metze@samba.org>
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.
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.
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/>.
23 selftest - Samba test runner
29 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]
33 A simple test runner. TESTS is a regular expression with tests to run.
41 Show list of available options.
47 =item I<--builddir=DIR>
57 Change directory to run tests in. Default is 'st'.
59 =item I<--target samba4|samba3|win|kvm>
61 Specify test target against which to run. Default is 'samba4'.
65 Run only a limited number of tests. Intended to run in about 30 seconds on
66 moderately recent systems.
68 =item I<--socket-wrapper>
70 Use socket wrapper library for communication with server. Only works
71 when the server is running locally.
73 Will prevent TCP and UDP ports being opened on the local host but
74 (transparently) redirects these calls to use unix domain sockets.
78 Specify a file containing a list of tests that should be skipped. Possible
79 candidates are tests that segfault the server, flip or don't end.
83 Specify a file containing a list of tests that should be run. Same format
84 as the --exclude flag.
86 Not includes specified means all tests will be run.
90 Abort as soon as one test fails.
94 Load a list of tests from the specified location.
102 =item I<SMBD_VALGRIND>
104 =item I<TORTURE_MAXTIME>
116 selftest is licensed under the GNU General Public License L<http://www.gnu.org/licenses/gpl.html>.
126 use FindBin
qw($RealBin $Script);
128 use File::Temp qw(tempfile);
131 use Cwd
qw(abs_path);
138 Time
::HiRes
->import("time");
141 print "You don't have Time::Hires installed !\n";
145 my $opt_target = "samba4";
147 my $opt_socket_wrapper = 0;
148 my $opt_socket_wrapper_pcap = undef;
149 my $opt_socket_wrapper_keep_pcap = undef;
151 my @opt_exclude = ();
152 my @opt_include = ();
154 my $opt_image = undef;
157 my $opt_resetup_env = undef;
158 my $opt_bindir = undef;
159 my $opt_load_list = undef;
172 print STDERR
"Exiting early because of SIGPIPE.\n";
176 $SIG{PIPE
} = \
&pipe_handler
;
180 my ($list, $fullname) = @_;
183 if ($fullname =~ /$$_[0]/) {
184 return ($$_[1]) if ($$_[1]);
196 return find_in_list
(\
@excludes, $name);
205 return unless ($opt_socket_wrapper_pcap);
206 return unless defined($ENV{SOCKET_WRAPPER_PCAP_DIR
});
209 $fname =~ s
%[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\
-]%_%g;
211 my $pcap_file = "$ENV{SOCKET_WRAPPER_PCAP_DIR}/$fname.pcap";
213 SocketWrapper
::setup_pcap
($pcap_file);
220 my ($pcap_file, $exitcode) = @_;
222 return unless ($opt_socket_wrapper_pcap);
223 return if ($opt_socket_wrapper_keep_pcap);
224 return unless ($exitcode == 0);
225 return unless defined($pcap_file);
230 # expand strings from %ENV
231 sub expand_environment_strings
($)
234 # we use a reverse sort so we do the longer ones first
235 foreach my $k (sort { $b cmp $a } keys %ENV) {
236 $s =~ s/\$$k/$ENV{$k}/g;
241 sub run_testsuite
($$$$$)
243 my ($envname, $name, $cmd, $i, $totalsuites) = @_;
244 my $pcap_file = setup_pcap
($name);
246 Subunit
::start_testsuite
($name);
247 Subunit
::progress_push
();
248 Subunit
::report_time
(time());
250 Subunit
::report_time
(time());
251 Subunit
::progress_pop
();
254 Subunit
::progress_pop
();
255 Subunit
::end_testsuite
($name, "error", "Unable to run $cmd: $!");
258 Subunit
::end_testsuite
($name, "error",
259 sprintf("%s died with signal %d, %s coredump\n", $cmd, ($?
& 127), ($?
& 128) ?
'with' : 'without'));
263 my $exitcode = $?
>> 8;
265 my $envlog = getlog_env
($envname);
267 print "envlog: $envlog\n";
270 print "command: $cmd\n";
271 printf "expanded command: %s\n", expand_environment_strings
($cmd);
273 if ($exitcode == 0) {
274 Subunit
::end_testsuite
($name, "success");
276 Subunit
::end_testsuite
($name, "failure", "Exit code was $exitcode");
279 cleanup_pcap
($pcap_file, $exitcode);
281 if (not $opt_socket_wrapper_keep_pcap and defined($pcap_file)) {
282 print "PCAP FILE: $pcap_file\n";
285 if ($exitcode != 0) {
286 exit(1) if ($opt_one);
294 print "Samba test runner
295 Copyright (C) Jelmer Vernooij <jelmer\@samba.org>
296 Copyright (C) Stefan Metzmacher <metze\@samba.org>
298 Usage: $Script [OPTIONS] TESTNAME-REGEX
301 --help this help page
302 --target=samba[34]|win|kvm Samba version to target
303 --testlist=FILE file to read available tests from
306 --prefix=DIR prefix to run tests in [st]
307 --srcdir=DIR source directory [.]
308 --builddir=DIR output directory [.]
309 --exeext=EXT executable extention []
312 --socket-wrapper-pcap save traffic to pcap directories
313 --socket-wrapper-keep-pcap keep all pcap files, not just those for tests that
315 --socket-wrapper enable socket wrapper
316 --bindir=PATH path to target binaries
319 --ldap=openldap|fedora-ds back samba onto specified ldap server
322 --image=PATH path to KVM image
325 --quick run quick overall test
326 --one abort when the first test fails
328 --analyse-cmd CMD command to run after each test
333 my $result = GetOptions
(
334 'help|h|?' => \
$opt_help,
335 'target=s' => \
$opt_target,
336 'prefix=s' => \
$prefix,
337 'socket-wrapper' => \
$opt_socket_wrapper,
338 'socket-wrapper-pcap' => \
$opt_socket_wrapper_pcap,
339 'socket-wrapper-keep-pcap' => \
$opt_socket_wrapper_keep_pcap,
340 'quick' => \
$opt_quick,
342 'exclude=s' => \
@opt_exclude,
343 'include=s' => \
@opt_include,
344 'srcdir=s' => \
$srcdir,
345 'builddir=s' => \
$builddir,
346 'exeext=s' => \
$exeext,
347 'verbose' => \
$opt_verbose,
348 'testenv' => \
$opt_testenv,
350 'resetup-environment' => \
$opt_resetup_env,
351 'bindir:s' => \
$opt_bindir,
352 'image=s' => \
$opt_image,
353 'testlist=s' => \
@testlists,
354 'load-list=s' => \
$opt_load_list,
357 exit(1) if (not $result);
359 ShowHelp
() if ($opt_help);
361 # we want unbuffered output
366 # quick hack to disable rpc validation when using valgrind - its way too slow
367 unless (defined($ENV{VALGRIND
})) {
368 $ENV{VALIDATE
} = "validate";
369 $ENV{MALLOC_CHECK_
} = 2;
372 # make all our python scripts unbuffered
373 $ENV{PYTHONUNBUFFERED
} = 1;
375 my $bindir = ($opt_bindir or "$builddir/bin");
376 my $bindir_abs = abs_path
($bindir);
378 # Backwards compatibility:
379 if (defined($ENV{TEST_LDAP
}) and $ENV{TEST_LDAP
} eq "yes") {
380 if (defined($ENV{FEDORA_DS_ROOT
})) {
387 my $torture_maxtime = ($ENV{TORTURE_MAXTIME
} or 1200);
390 $torture_maxtime *= 2;
397 die("using an empty prefix isn't allowed") unless $prefix ne "";
399 #Ensure we have the test prefix around
400 mkdir($prefix, 0777) unless -d
$prefix;
402 my $prefix_abs = abs_path
($prefix);
403 my $tmpdir_abs = abs_path
("$prefix/tmp");
404 mkdir($tmpdir_abs, 0777) unless -d
$tmpdir_abs;
406 my $srcdir_abs = abs_path
($srcdir);
407 my $builddir_abs = abs_path
($builddir);
409 die("using an empty absolute prefix isn't allowed") unless $prefix_abs ne "";
410 die("using '/' as absolute prefix isn't allowed") unless $prefix_abs ne "/";
412 $ENV{PREFIX
} = $prefix;
413 $ENV{KRB5CCNAME
} = "$prefix/krb5ticket";
414 $ENV{PREFIX_ABS
} = $prefix_abs;
415 $ENV{SRCDIR
} = $srcdir;
416 $ENV{SRCDIR_ABS
} = $srcdir_abs;
417 $ENV{BUILDDIR
} = $builddir;
418 $ENV{BUILDDIR_ABS
} = $builddir_abs;
419 $ENV{EXEEXT
} = $exeext;
421 my $tls_enabled = not $opt_quick;
422 $ENV{TLS_ENABLED
} = ($tls_enabled?
"yes":"no");
423 $ENV{LDB_MODULES_PATH
} = "$bindir_abs/modules/ldb";
424 $ENV{LD_SAMBA_MODULE_PATH
} = "$bindir_abs/modules";
425 sub prefix_pathvar
($$)
427 my ($name, $newpath) = @_;
428 if (defined($ENV{$name})) {
429 $ENV{$name} = "$newpath:$ENV{$name}";
431 $ENV{$name} = $newpath;
434 prefix_pathvar
("PKG_CONFIG_PATH", "$bindir_abs/pkgconfig");
435 prefix_pathvar
("PYTHONPATH", "$bindir_abs/python");
437 if ($opt_socket_wrapper_keep_pcap) {
438 # Socket wrapper keep pcap implies socket wrapper pcap
439 $opt_socket_wrapper_pcap = 1;
442 if ($opt_socket_wrapper_pcap) {
443 # Socket wrapper pcap implies socket wrapper
444 $opt_socket_wrapper = 1;
447 my $socket_wrapper_dir;
448 if ($opt_socket_wrapper) {
449 $socket_wrapper_dir = SocketWrapper
::setup_dir
("$prefix_abs/w", $opt_socket_wrapper_pcap);
450 print "SOCKET_WRAPPER_DIR=$socket_wrapper_dir\n";
453 print "WARNING: Not using socket wrapper, but also not running as root. Will not be able to listen on proper ports\n";
458 my $testenv_default = "none";
460 if ($opt_target eq "samba4") {
461 $testenv_default = "all";
462 require target
::Samba4
;
463 $target = new Samba4
($bindir, $ldap, "$srcdir/setup", $exeext);
464 } elsif ($opt_target eq "samba3") {
465 if ($opt_socket_wrapper and `$bindir/smbd -b | grep SOCKET_WRAPPER` eq "") {
466 die("You must include --enable-socket-wrapper when compiling Samba in order to execute 'make test'. Exiting....");
468 $testenv_default = "member";
469 require target
::Samba3
;
470 $target = new Samba3
($bindir);
471 } elsif ($opt_target eq "win") {
472 die("Windows tests will not run with socket wrapper enabled.")
473 if ($opt_socket_wrapper);
474 $testenv_default = "dc";
475 require target
::Windows
;
476 $target = new Windows
();
477 } elsif ($opt_target eq "kvm") {
478 die("Kvm tests will not run with socket wrapper enabled.")
479 if ($opt_socket_wrapper);
481 die("No image specified") unless ($opt_image);
482 $target = new Kvm
($opt_image, undef);
486 # Start a Virtual Distributed Ethernet Switch
487 # Returns the pid of the switch.
489 sub start_vde_switch
($)
493 system("vde_switch --pidfile $path/vde.pid --sock $path/vde.sock --daemon");
495 open(PID
, "$path/vde.pid");
503 # Stop a Virtual Distributed Ethernet Switch
504 sub stop_vde_switch
($)
510 sub read_test_regexes
($)
514 open(LF
, "<$name") or die("unable to read $name: $!");
518 if (/^(.*?)([ \t]+)\#([\t ]*)(.*?)$/) {
519 push (@ret, [$1, $4]);
521 s/^(.*?)([ \t]+)\#([\t ]*)(.*?)$//;
522 push (@ret, [$_, undef]);
529 foreach (@opt_exclude) {
530 push (@excludes, read_test_regexes
($_));
533 foreach (@opt_include) {
534 push (@includes, read_test_regexes
($_));
537 my $interfaces = join(',', ("127.0.0.11/8",
544 my $clientdir = "$prefix_abs/client";
546 my $conffile = "$clientdir/client.conf";
547 $ENV{SMB_CONF_PATH
} = $conffile;
549 sub write_clientconf
($$$)
551 my ($conffile, $clientdir, $vars) = @_;
553 mkdir("$clientdir", 0777) unless -d
"$clientdir";
555 if ( -d
"$clientdir/private" ) {
556 unlink <$clientdir/private/*>;
558 mkdir("$clientdir/private", 0777);
561 if ( -d
"$clientdir/lockdir" ) {
562 unlink <$clientdir/lockdir/*>;
564 mkdir("$clientdir/lockdir", 0777);
567 if ( -d
"$clientdir/ncalrpcdir" ) {
568 unlink <$clientdir/ncalrpcdir/*>;
570 mkdir("$clientdir/ncalrpcdir", 0777);
573 open(CF
, ">$conffile");
574 print CF
"[global]\n";
575 if (defined($ENV{VALGRIND
})) {
576 print CF
"\ticonv:native = true\n";
578 print CF
"\ticonv:native = false\n";
580 print CF
"\tnetbios name = client\n";
581 if (defined($vars->{DOMAIN
})) {
582 print CF
"\tworkgroup = $vars->{DOMAIN}\n";
584 if (defined($vars->{REALM
})) {
585 print CF
"\trealm = $vars->{REALM}\n";
587 if ($opt_socket_wrapper) {
588 print CF
"\tinterfaces = $interfaces\n";
591 private dir = $clientdir/private
592 lock dir = $clientdir/lockdir
593 ncalrpc dir = $clientdir/ncalrpcdir
594 name resolve order = bcast file
595 panic action = $RealBin/gdb_backtrace \%PID\% \%PROG\%
597 notify:inotify = false
599 system:anonymous = true
600 client lanman auth = Yes
602 torture:basedir = $clientdir
603 #We don't want to pass our self-tests if the PAC code is wrong
604 gensec:require_pac = true
605 modules dir = $ENV{LD_SAMBA_MODULE_PATH}
606 setup directory = ./setup
607 resolv:host file = $prefix_abs/dns_host_file
608 #We don't want to run 'speed' tests for very long
609 torture:timelimit = 1
616 my $testsdir = "$srcdir/selftest";
618 sub should_run_test
($)
624 for (my $i=0; $i <= $#tests; $i++) {
625 if ($name =~ /$tests[$i]/i) {
637 open(IN
, $filename) or die("Unable to open $filename: $!");
640 if (/-- TEST(-LOADLIST|-IDLIST|) --\n/) {
641 my $supports_loadlist = (defined($1) and $1 eq "-LOADLIST");
642 my $supports_idlist = (defined($1) and $1 eq "-IDLIST");
649 if (should_run_test
($name) == 1) {
650 push (@ret, [$name, $env, $cmdline, $supports_loadlist, $supports_idlist]);
656 close(IN
) or die("Error creating recipe");
660 if ($#testlists == -1) {
661 die("No testlists specified");
664 $ENV{SELFTEST_PREFIX
} = "$prefix_abs";
665 $ENV{SELFTEST_TMPDIR
} = "$tmpdir_abs";
666 if ($opt_socket_wrapper) {
667 $ENV{SELFTEST_INTERFACES
} = $interfaces;
669 $ENV{SELFTEST_INTERFACES
} = "";
672 $ENV{SELFTEST_VERBOSE
} = "1";
674 $ENV{SELFTEST_VERBOSE
} = "";
677 $ENV{SELFTEST_QUICK
} = "1";
679 $ENV{SELFTEST_QUICK
} = "";
681 $ENV{SELFTEST_TARGET
} = $opt_target;
682 $ENV{SELFTEST_MAXTIME
} = $torture_maxtime;
685 foreach my $fn (@testlists) {
686 foreach (read_testlist
($fn)) {
688 next if (@includes and not defined(find_in_list
(\
@includes, $name)));
689 push (@available, $_);
693 my $restricted = undef;
694 my $restricted_used = {};
696 if ($opt_load_list) {
698 open(LOAD_LIST
, "<$opt_load_list") or die("Unable to open $opt_load_list");
699 while (<LOAD_LIST
>) {
701 push (@
$restricted, $_);
706 my $individual_tests = undef;
707 $individual_tests = {};
709 foreach my $testsuite (@available) {
710 my $name = $$testsuite[0];
711 my $skipreason = skip
($name);
712 if (defined($restricted)) {
713 # Find the testsuite for this test
715 foreach my $r (@
$restricted) {
717 $individual_tests->{$name} = [];
719 $restricted_used->{$r} = 1;
720 } elsif (substr($r, 0, length($name)+1) eq "$name.") {
721 push(@
{$individual_tests->{$name}}, $r);
723 $restricted_used->{$r} = 1;
727 if (defined($skipreason)) {
728 Subunit
::skip_testsuite
($name, $skipreason);
730 push(@todo, $testsuite);
733 } elsif (defined($skipreason)) {
734 Subunit
::skip_testsuite
($name, $skipreason);
736 push(@todo, $testsuite);
740 if (defined($restricted)) {
741 foreach (@
$restricted) {
742 unless (defined($restricted_used->{$_})) {
743 print "No test or testsuite found matching $_\n";
746 } elsif ($#todo == -1) {
747 print STDERR
"No tests to run\n";
751 my $suitestotal = $#todo + 1;
753 Subunit
::progress
($suitestotal);
754 Subunit
::report_time
(time());
759 my %running_envs = ();
761 sub get_running_env
($)
769 return $running_envs{$envname};
772 my @exported_envvars = (
777 # domain controller stuff
786 "MEMBER_NETBIOSNAME",
787 "MEMBER_NETBIOSALIAS",
789 # rpc proxy controller stuff
791 "RPC_PROXY_SERVER_IP",
792 "RPC_PROXY_NETBIOSNAME",
793 "RPC_PROXY_NETBIOSALIAS",
795 # domain controller stuff for Vampired DC
797 "VAMPIRE_DC_SERVER_IP",
798 "VAMPIRE_DC_NETBIOSNAME",
799 "VAMPIRE_DC_NETBIOSALIAS",
816 "WINBINDD_SOCKET_DIR",
817 "WINBINDD_PRIV_PIPE_DIR",
821 $SIG{INT
} = $SIG{QUIT
} = $SIG{TERM
} = sub {
823 teardown_env
($_) foreach(keys %running_envs);
824 die("Received signal $signame");
829 my ($name, $prefix) = @_;
831 my $testenv_vars = undef;
837 $option =~ s/^[^:]*//;
840 $option = "client" if $option eq "";
842 if ($envname eq "none") {
844 } elsif (defined(get_running_env
($envname))) {
845 $testenv_vars = get_running_env
($envname);
846 if (not $target->check_env($testenv_vars)) {
847 print $target->getlog_env($testenv_vars);
848 $testenv_vars = undef;
851 $testenv_vars = $target->setup_env($envname, $prefix);
854 return undef unless defined($testenv_vars);
856 $running_envs{$envname} = $testenv_vars;
858 if ($option eq "local") {
859 SocketWrapper
::set_default_iface
($testenv_vars->{SOCKET_WRAPPER_DEFAULT_IFACE
});
860 $ENV{SMB_CONF_PATH
} = $testenv_vars->{SERVERCONFFILE
};
861 } elsif ($option eq "client") {
862 SocketWrapper
::set_default_iface
(11);
863 write_clientconf
($conffile, $clientdir, $testenv_vars);
864 $ENV{SMB_CONF_PATH
} = $conffile;
866 die("Unknown option[$option] for envname[$envname]");
869 foreach (@exported_envvars) {
870 if (defined($testenv_vars->{$_})) {
871 $ENV{$_} = $testenv_vars->{$_};
877 return $testenv_vars;
880 sub exported_envvars_str
($)
882 my ($testenv_vars) = @_;
885 foreach (@exported_envvars) {
886 next unless defined($testenv_vars->{$_});
887 $out .= $_."=".$testenv_vars->{$_}."\n";
896 return "" if ($envname eq "none");
897 return $target->getlog_env(get_running_env
($envname));
903 return 1 if ($envname eq "none");
904 return $target->check_env(get_running_env
($envname));
910 return if ($envname eq "none");
911 $target->teardown_env(get_running_env
($envname));
912 delete $running_envs{$envname};
915 # This 'global' file needs to be empty when we start
916 unlink("$prefix_abs/dns_host_file");
919 my $testenv_name = $ENV{SELFTEST_TESTENV
};
920 $testenv_name = $testenv_default unless defined($testenv_name);
922 my $testenv_vars = setup_env
($testenv_name, $prefix);
924 die("Unable to setup environment $testenv_name") unless ($testenv_vars);
926 $ENV{PIDDIR
} = $testenv_vars->{PIDDIR
};
927 $ENV{ENVNAME
} = $testenv_name;
929 my $envvarstr = exported_envvars_str
($testenv_vars);
931 my $term = ($ENV{TERMINAL
} or "xterm -e");
932 system("$term 'echo -e \"
933 Welcome to the Samba4 Test environment '$testenv_name'
935 This matches the client environment used in make test
936 server is pid `cat \$PIDDIR/samba.pid`
938 Some useful environment variables:
939 TORTURE_OPTIONS=\$TORTURE_OPTIONS
940 SMB_CONF_PATH=\$SMB_CONF_PATH
943 \" && LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH} bash'");
944 teardown_env
($testenv_name);
950 my $envname = $$_[1];
952 my $envvars = setup_env
($envname, $prefix);
953 if (not defined($envvars)) {
954 Subunit
::start_testsuite
($name);
955 Subunit
::end_testsuite
($name, "error",
956 "unable to set up environment $envname - exiting");
961 # Generate a file with the individual tests to run, if the
962 # test runner for this test suite supports it.
963 if ($individual_tests and $individual_tests->{$name}) {
965 my ($fh, $listid_file) = tempfile
(UNLINK
=> 0);
966 foreach my $test (@
{$individual_tests->{$name}}) {
967 print $fh substr($test, length($name)+1) . "\n";
969 $cmd =~ s/\$LOADLIST/--load-list=$listid_file/g;
971 $cmd =~ s/\s+[^\s]+\s*$//;
972 $cmd .= " " . join(' ', @
{$individual_tests->{$name}});
976 run_testsuite
($envname, $name, $cmd, $i, $suitestotal);
978 teardown_env
($envname) if ($opt_resetup_env);
984 teardown_env
($_) foreach (keys %running_envs);
988 # if there were any valgrind failures, show them
989 foreach (<$prefix/valgrind
.log*>) {
991 print "VALGRIND FAILURE\n";