2 # Bootstrap Samba and run a number of tests against it.
3 # Copyright (C) 2005-2007 Jelmer Vernooij <jelmer@samba.org>
4 # Published under the GNU GPL, v3 or later.
10 selftest - Samba test runner
16 selftest [--srcdir=DIR] [--builddir=DIR] [--target=samba4|samba3|win] [--socket-wrapper] [--quick] [--one] [--prefix=prefix] [--immediate] [TESTS]
20 A simple test runner. TESTS is a regular expression with tests to run.
28 Show list of available options.
34 =item I<--builddir=DIR>
40 Change directory to run tests in. Default is 'st'.
44 Show errors as soon as they happen rather than at the end of the test run.
46 =item I<--target samba4|samba3|win>
48 Specify test target against which to run. Default is 'samba4'.
52 Run only a limited number of tests. Intended to run in about 30 seconds on
53 moderately recent systems.
55 =item I<--socket-wrapper>
57 Use socket wrapper library for communication with server. Only works
58 when the server is running locally.
60 Will prevent TCP and UDP ports being opened on the local host but
61 (transparently) redirects these calls to use unix domain sockets.
63 =item I<--expected-failures>
65 Specify a file containing a list of tests that are expected to fail. Failures for
66 these tests will be counted as successes, successes will be counted as failures.
68 The format for the file is, one entry per line:
70 TESTSUITE-NAME/TEST-NAME
74 Abort as soon as one test fails.
82 =item I<SMBD_VALGRIND>
84 =item I<TORTURE_MAXTIME>
98 selftest is licensed under the GNU General Public License L<http://www.gnu.org/licenses/gpl.html>.
109 use FindBin qw($RealBin $Script);
119 my $opt_target = "samba4";
121 my $opt_socket_wrapper = 0;
122 my $opt_socket_wrapper_pcap = undef;
124 my $opt_immediate = 0;
125 my $opt_expected_failures = undef;
132 my $suitesfailed = [];
134 my @expected_failures = ();
140 TESTS_UNEXPECTED_OK => 0,
141 TESTS_EXPECTED_OK => 0,
142 TESTS_UNEXPECTED_FAIL => 0,
143 TESTS_EXPECTED_FAIL => 0,
147 sub expecting_failure($)
149 my $fullname = shift;
151 foreach (@expected_failures) {
152 return 1 if $fullname =~ /^$_$/;
158 sub run_test_buildfarm($$$$)
160 my ($name, $cmd, $i, $suitestotal) = @_;
161 print "--==--==--==--==--==--==--==--==--==--==--\n";
162 print "Running test $name (level 0 stdout)\n";
163 print "--==--==--==--==--==--==--==--==--==--==--\n";
166 my $expected_ret = 1;
168 open(RESULT, "$cmd|");
171 if (/^test: (.+)\n/) {
172 $open_tests->{$1} = 1;
173 } elsif (/^(success|failure|skip|error): (.*?)( \[)?\n/) {
175 if ($1 eq "success") {
176 delete $open_tests->{$2};
177 if (expecting_failure("$name/$2")) {
178 $statistics->{TESTS_UNEXPECTED_OK}++;
180 $statistics->{TESTS_EXPECTED_OK}++;
182 } elsif ($1 eq "failure") {
183 delete $open_tests->{$2};
184 if (expecting_failure("$name/$2")) {
185 $statistics->{TESTS_EXPECTED_FAIL}++;
188 $statistics->{TESTS_UNEXPECTED_FAIL}++;
190 } elsif ($1 eq "skip") {
191 delete $open_tests->{$2};
192 } elsif ($1 eq "error") {
193 $statistics->{TESTS_ERROR}++;
194 delete $open_tests->{$2};
198 print "COMMAND: $cmd\n";
199 foreach (keys %$open_tests) {
200 print "$_ was started but never finished!\n";
201 $statistics->{TESTS_ERROR}++;
203 my $ret = close(RESULT);
205 print "==========================================\n";
206 if ($ret == $expected_ret) {
207 print "TEST PASSED: $name\n";
209 print "TEST FAILED: $name (status $ret)\n";
211 print "==========================================\n";
214 my $test_output = {};
215 sub run_test_plain($$$$)
217 my ($name, $cmd, $i, $totalsuites) = @_;
219 if ($#$suitesfailed+1 > 0) { $err = ", ".($#$suitesfailed+1)." errors"; }
220 printf "[$i/$totalsuites in " . (time() - $start)."s$err] $name\n";
221 open(RESULT, "$cmd 2>&1|");
222 my $expected_ret = 1;
224 $test_output->{$name} = "";
226 $test_output->{$name}.=$_;
227 print if ($opt_verbose);
228 if (/^test: (.+)\n/) {
229 $open_tests->{$1} = 1;
230 } elsif (/^(success|failure|skip|error): (.*?)( \[)?\n/) {
232 if ($1 eq "success") {
233 delete $open_tests->{$2};
234 if (expecting_failure("$name/$2")) {
235 $statistics->{TESTS_UNEXPECTED_OK}++;
237 $statistics->{TESTS_EXPECTED_OK}++;
239 } elsif ($1 eq "failure") {
240 delete $open_tests->{$2};
241 if (expecting_failure("$name/$2")) {
242 $statistics->{TESTS_EXPECTED_FAIL}++;
245 $statistics->{TESTS_UNEXPECTED_FAIL}++;
247 } elsif ($1 eq "skip") {
248 delete $open_tests->{$2};
249 } elsif ($1 eq "error") {
250 $statistics->{TESTS_ERROR}++;
251 delete $open_tests->{$2};
255 $test_output->{$name}.="COMMAND: $cmd\n";
256 foreach (keys %$open_tests) {
257 $test_output->{$name}.="$_ was started but never finished!\n";
258 $statistics->{TESTS_ERROR}++;
260 my $ret = close(RESULT);
261 if ($ret != $expected_ret and ($opt_immediate or $opt_one) and not $opt_verbose) {
262 print "$test_output->{$name}\n";
264 if ($ret != $expected_ret) {
265 push(@$suitesfailed, $name);
266 $statistics->{SUITES_FAIL}++;
267 exit(1) if ($opt_one);
269 $statistics->{SUITES_OK}++;
275 print "Samba test runner
276 Copyright (C) Jelmer Vernooij <jelmer\@samba.org>
278 Usage: $Script [OPTIONS] PREFIX
281 --help this help page
284 --prefix=DIR prefix to run tests in [st]
285 --srcdir=DIR source directory [.]
286 --builddir=DIR output directory [.]
289 --target=samba4|samba3|win Samba version to target
290 --socket-wrapper-pcap=FILE save traffic to pcap file
291 --socket-wrapper enable socket wrapper
292 --expected-failures=FILE specify list of tests that is guaranteed to fail
295 --quick run quick overall test
296 --one abort when the first test fails
297 --immediate print test output for failed tests during run
303 my $result = GetOptions (
304 'help|h|?' => \$opt_help,
305 'target=s' => \$opt_target,
306 'prefix=s' => \$prefix,
307 'socket-wrapper' => \$opt_socket_wrapper,
308 'socket-wrapper-pcap=s' => \$opt_socket_wrapper_pcap,
309 'quick' => \$opt_quick,
311 'immediate' => \$opt_immediate,
312 'expected-failures=s' => \$opt_expected_failures,
313 'srcdir=s' => \$srcdir,
314 'builddir=s' => \$builddir,
315 'verbose' => \$opt_verbose
318 exit(1) if (not $result);
320 ShowHelp() if ($opt_help);
324 my $torture_maxtime = $ENV{TORTURE_MAXTIME};
325 unless (defined($torture_maxtime)) {
326 $torture_maxtime = 1200;
329 # quick hack to disable rpc validation when using valgrind - its way too slow
330 unless (defined($ENV{VALGRIND})) {
331 $ENV{VALIDATE} = "validate";
334 my $old_pwd = "$RealBin/../..";
335 my $ldap = (defined($ENV{TEST_LDAP}) and ($ENV{TEST_LDAP} eq "yes"))?1:0;
338 $ENV{PREFIX} = $prefix;
340 $ENV{SRCDIR} = $srcdir;
342 my $bindir = "$srcdir/bin";
343 my $setupdir = "$srcdir/setup";
344 my $testsdir = "$srcdir/script/tests";
346 my $tls_enabled = not $opt_quick;
347 my $from_build_farm = (defined($ENV{RUN_FROM_BUILD_FARM}) and
348 ($ENV{RUN_FROM_BUILD_FARM} eq "yes"));
350 $ENV{TLS_ENABLED} = ($tls_enabled?"yes":"no");
351 $ENV{LD_LDB_MODULE_PATH} = "$old_pwd/bin/modules/ldb";
352 $ENV{LD_SAMBA_MODULE_PATH} = "$old_pwd/bin/modules";
353 if (defined($ENV{LD_LIBRARY_PATH})) {
354 $ENV{LD_LIBRARY_PATH} = "$old_pwd/bin/shared:$ENV{LD_LIBRARY_PATH}";
356 $ENV{LD_LIBRARY_PATH} = "$old_pwd/bin/shared";
358 $ENV{PKG_CONFIG_PATH} = "$old_pwd/bin/pkgconfig:$ENV{PKG_CONFIG_PATH}";
359 $ENV{PATH} = "$old_pwd/bin:$ENV{PATH}";
361 my @torture_options = ();
363 my $testenv_vars = {};
365 if ($opt_target eq "samba4") {
366 $testenv_vars = Samba4::provision($prefix);
367 } elsif ($opt_target eq "win") {
368 die ("Windows tests will not run without root privileges.")
369 if (`whoami` ne "root");
371 die("Windows tests will not run with socket wrapper enabled.")
372 if ($opt_socket_wrapper);
374 die("Windows tests will not run quickly.") if ($opt_quick);
376 die("Environment variable WINTESTCONF has not been defined.\n".
377 "Windows tests will not run unconfigured.") if (not defined($ENV{WINTESTCONF}));
379 die ("$ENV{WINTESTCONF} could not be read.") if (! -r $ENV{WINTESTCONF});
381 $ENV{WINTEST_DIR}="$ENV{SRCDIR}/script/tests/win";
382 } elsif ($opt_target eq "none") {
384 die("unknown target `$opt_target'");
387 foreach (keys %$testenv_vars) { $ENV{$_} = $testenv_vars->{$_}; }
389 if ($opt_socket_wrapper_pcap) {
390 $ENV{SOCKET_WRAPPER_PCAP_FILE} = $opt_socket_wrapper_pcap;
391 # Socket wrapper pcap implies socket wrapper
392 $opt_socket_wrapper = 1;
395 my $socket_wrapper_dir;
396 if ($opt_socket_wrapper)
398 $socket_wrapper_dir = SocketWrapper::setup_dir("$prefix/w");
399 print "SOCKET_WRAPPER_DIR=$socket_wrapper_dir\n";
402 # Start slapd before smbd
404 Samba4::slapd_start($ENV{SLAPD_CONF}, $ENV{LDAPI_ESCAPE}) or die("couldn't start slapd");
406 print "LDAP PROVISIONING...";
407 Samba4::provision_ldap($bindir, $setupdir);
410 $torture_maxtime *= 2;
413 if (defined($opt_expected_failures)) {
414 open(KNOWN, "<$opt_expected_failures") or die("unable to read known failures file: $!");
418 push (@expected_failures, $_); }
422 my $test_fifo = "$prefix/smbd_test.fifo";
424 $ENV{SMBD_TEST_FIFO} = $test_fifo;
425 $ENV{SMBD_TEST_LOG} = "$prefix/smbd_test.log";
427 SocketWrapper::set_default_iface(1);
429 if (defined($ENV{SMBD_MAX_TIME})) {
430 $max_time = $ENV{SMBD_MAX_TIME};
432 Samba4::smbd_check_or_start($bindir, $test_fifo, $ENV{SMBD_TEST_LOG},
433 $socket_wrapper_dir, $max_time, $ENV{CONFFILE});
435 SocketWrapper::set_default_iface(6);
437 my $interfaces = join(',', ("127.0.0.6/8",
444 push (@torture_options, "--option=interfaces=$interfaces");
445 push (@torture_options, $ENV{CONFIGURATION});
446 # ensure any one smbtorture call doesn't run too long
447 push (@torture_options, "--maximum-runtime=$torture_maxtime");
448 push (@torture_options, "--target=$opt_target");
449 push (@torture_options, "--option=torture:progress=no") if ($from_build_farm);
450 push (@torture_options, "--format=subunit");
451 push (@torture_options, "--option=torture:quick=yes") if ($opt_quick);
453 $ENV{TORTURE_OPTIONS} = join(' ', @torture_options);
454 print "OPTIONS $ENV{TORTURE_OPTIONS}\n";
456 open(DATA, ">$test_fifo");
460 if ($opt_target eq "win") {
461 system("$testsdir/test_win.sh");
464 open(IN, "$testsdir/tests_quick.sh|");
466 open(IN, "$testsdir/tests_all.sh|");
469 if ($_ eq "-- TEST --\n") {
474 push (@todo, [$name, $cmdline])
475 if (not defined($tests) or $name =~ /$tests/);
480 close(IN) or die("Error creating recipe");
483 Samba4::wait_for_start();
485 # start off with 0 failures
488 my $suitestotal = $#todo + 1;
497 $cmd =~ s/([\(\)])/\\$1/g;
499 if ($from_build_farm) {
500 run_test_buildfarm($name, $cmd, $i, $suitestotal);
502 run_test_plain($name, $cmd, $i, $suitestotal);
512 my $failed = $? >> 8;
514 if (-f "$ENV{PIDDIR}/smbd.pid" ) {
515 open(IN, "<$ENV{PIDDIR}/smbd.pid") or die("unable to open smbd pid file");
520 Samba4::slapd_stop() if ($ldap);
523 my $duration = ($end-$start);
524 my $numfailed = $#$suitesfailed+1;
525 if ($numfailed == 0) {
526 my $ok = $statistics->{TESTS_EXPECTED_OK} + $statistics->{TESTS_EXPECTED_FAIL};
527 print "ALL OK ($ok tests in $statistics->{SUITES_OK} testsuites)\n";
530 unless ($from_build_farm) {
531 if (not $opt_immediate and not $opt_verbose) {
532 foreach (@$suitesfailed) {
533 print "===============================================================================\n";
535 print $test_output->{$_};
540 print "FAILED ($statistics->{TESTS_UNEXPECTED_FAIL} failures and $statistics->{TESTS_ERROR} errors in $statistics->{SUITES_FAIL} testsuites)\n";
543 ************************
544 *** TESTSUITE FAILED ***
545 ************************
550 print "DURATION: $duration seconds\n";
552 # if there were any valgrind failures, show them
553 foreach (<$prefix/valgrind.log*>) {
555 system("grep DWARF2.CFI.reader $_ > /dev/null");
557 print "VALGRIND FAILURE\n";