X-Git-Url: https://git.exim.org/users/heiko/exim.git/blobdiff_plain/1ef2730eb3d31c57a088b0491dfb5096f65b289a..0df394b5d5e6865094f601baf2a71f41d1d3ad95:/test/runtest?ds=sidebyside diff --git a/test/runtest b/test/runtest index 343630972..dc2cb5e7b 100755 --- a/test/runtest +++ b/test/runtest @@ -1,4 +1,6 @@ -#! /usr/bin/perl -w +#! /usr/bin/env perl +# We use env, because in some environments of our build farm +# the Perl 5.010 interpreter is only reachable via $PATH ############################################################################### # This is the controlling script for the "new" test suite for Exim. It should # @@ -14,14 +16,21 @@ ############################################################################### #use strict; -#use 5.010; +use 5.010; +use feature 'state'; # included in 5.010 +use warnings; + use Errno; use FileHandle; -use IO::Socket::INET; use Socket; use Time::Local; use Cwd; use File::Basename; +use FindBin qw'$Bin'; + +use lib "$Bin/lib"; +use Exim::Runtest; + use if $ENV{DEBUG} && $ENV{DEBUG} =~ /\bruntest\b/ => ('Smart::Comments' => '####'); @@ -84,6 +93,10 @@ $parm_port_d3 = 1227; # Additional for daemon $parm_port_d4 = 1228; # Additional for daemon my $dynamic_socket; # allocated later for PORT_DYNAMIC +# Find a suiteable group name for test (currently only 0001 +# uses a group name. A numeric group id would do +my $parm_mailgroup = Exim::Runtest::mailgroup('mail'); + # Manually set locale $ENV{LC_ALL} = 'C'; @@ -145,6 +158,7 @@ s?\bTESTNUM\b?$_[0]?g; s?(\b|_)V4NET([\._])?$1$parm_ipv4_test_net$2?g; s?\bV6NET:?$parm_ipv6_test_net:?g; s?\bPORT_DYNAMIC\b?$dynamic_socket->sockport()?eg; +s?\bMAILGROUP\b?$parm_mailgroup?g; } @@ -1041,6 +1055,30 @@ RESET_AFTER_EXTRA_LINE_READ: # Spool filesystem free space changes on different systems. s/^((?:spool|log) directory space =) -?\d+K (inodes =)\s*-?\d+/$1 nnnnnK $2 nnnnn/; + # Non-TLS builds have different expansions for received_header_text + if (s/(with \$received_protocol)\}\} \$\{if def:tls_cipher \{\(\$tls_cipher\)\n$/$1/) + { + $_ .= ; + s/\s+\}\}(?=\(Exim )/\}\} /; + } + if (/^ condition: def:tls_cipher$/) + { + ; ; ; ; ; ; + ; ; ; ; ; next; + } + + # Not all platforms build with DKIM enabled + next if /^PDKIM >> Body data for hash, canonicalized/; + + # Not all platforms support TCP Fast Open, and the compile omits the check + if (s/\S+ in hosts_try_fastopen\? no \(option unset\)\n$//) + { + $_ .= ; + s/ \.\.\. >>> / ... /; + } + + next if /^(ppppp )?setsockopt FASTOPEN: Protocol not available$/; + # When Exim is checking the size of directories for maildir, it uses # the check_dir_size() function to scan directories. Of course, the order # of the files that are obtained using readdir() varies from system to @@ -1115,11 +1153,22 @@ return $yield; # [2] if there is a C in the prompt and $force_continue is true # Returns: returns the answer -sub interact{ -print $_[0]; -if ($_[1]) { $_ = "u"; print "... update forced\n"; } - elsif ($_[2]) { $_ = "c"; print "... continue forced\n"; } - else { $_ = ; } +sub interact { + my ($prompt, $have_u, $have_c) = @_; + + print $prompt; + + if ($have_u) { + print "... update forced\n"; + return 'u'; + } + + if ($have_c) { + print "... continue forced\n"; + return 'c'; + } + + return lc ; } @@ -1139,13 +1188,13 @@ if ($_[1]) { $_ = "u"; print "... update forced\n"; } sub log_failure { - my $logfile = shift(); - my $testno = shift(); - my $detail = shift() || ''; - if ( open(my $fh, ">>", $logfile) ) { - print $fh "Test $testno $detail failed\n"; - close $fh; - } + my ($logfile, $testno, $detail) = @_; + + open(my $fh, '>>', $logfile) or return; + + print $fh "Test $testno " + . (defined $detail ? "$detail " : '') + . "failed\n"; } @@ -1192,10 +1241,9 @@ if (! -e $sf_current) for (;;) { - print "Continue, Show, or Quit? [Q] "; - $_ = $force_continue ? "c" : ; - tests_exit(1) if /^q?$/i; - log_failure($log_failed_filename, $testno, $rf) if (/^c$/i && $force_continue); + $_ = interact('Continue, Show, or Quit? [Q] ', undef, $force_continue); + tests_exit(1) if /^q?$/; + log_failure($log_failed_filename, $testno, $rf) if (/^c$/ && $force_continue); return 0 if /^c$/i; last if (/^s$/); } @@ -1214,9 +1262,9 @@ if (! -e $sf_current) print "\n"; for (;;) { - interact("Continue, Update & retry, Quit? [Q] ", $force_update, $force_continue); - tests_exit(1) if /^q?$/i; - log_failure($log_failed_filename, $testno, $rsf) if (/^c$/i && $force_continue); + $_ = interact('Continue, Update & retry, Quit? [Q] ', $force_update, $force_continue); + tests_exit(1) if /^q?$/; + log_failure($log_failed_filename, $testno, $rsf) if (/^c$/ && $force_continue); return 0 if /^c$/i; last if (/^u$/i); } @@ -1334,10 +1382,10 @@ if (-e $sf_current) print "\n"; for (;;) { - interact("Continue, Retry, Update current" - . ($sf_current ne $sf_flavour ? "/Save for flavour '$flavour'" : "") - . " & retry, Quit? [Q] ", $force_update, $force_continue); - tests_exit(1) if /^q?$/i; + $_ = interact('Continue, Retry, Update current' + . ($sf_current ne $sf_flavour ? "/Save for flavour '$flavour'" : '') + . ' & retry, Quit? [Q] ', $force_update, $force_continue); + tests_exit(1) if /^q?$/; log_failure($log_failed_filename, $testno, $sf_current) if (/^c$/i && $force_continue); return 0 if /^c$/i; return 1 if /^r$/i; @@ -1439,6 +1487,9 @@ $munges = { 'stdout' => 's/^\d\d:\d\d:\d\d\s+\d+ //; s/Process \d+ is ready for new message/Process pppp is ready for new message/' }, + + 'timeout_errno' => # actual errno differs Solaris vs. Linux + { 'mainlog' => 's/(host deferral .* errno) <\d+> /$1 /' }, }; @@ -1551,16 +1602,16 @@ if (! $message_skip) for (;;) { - interact("Continue, Update & retry, or Quit? [Q] ", $force_update, $force_continue); - tests_exit(1) if /^q?$/i; - log_failure($log_failed_filename, $testno, "missing email") if (/^c$/i && $force_continue); - last if /^c$/i; + $_ = interact('Continue, Update & retry, or Quit? [Q] ', $force_update, $force_continue); + tests_exit(1) if /^q?$/; + log_failure($log_failed_filename, $testno, "missing email") if (/^c$/ && $force_continue); + last if /^c$/; # For update, we not only have to unlink the file, but we must also # remove it from the @oldmails vector, as otherwise it will still be # checked for when we re-run the test. - if (/^u$/i) + if (/^u$/) { foreach $key (keys %expected_mails) { @@ -1635,11 +1686,11 @@ if (! $msglog_skip) for (;;) { - interact("Continue, Update, or Quit? [Q] ", $force_update, $force_continue); - tests_exit(1) if /^q?$/i; - log_failure($log_failed_filename, $testno, "missing msglog") if (/^c$/i && $force_continue); - last if /^c$/i; - if (/^u$/i) + $_ = interact('Continue, Update, or Quit? [Q] ', $force_update, $force_continue); + tests_exit(1) if /^q?$/; + log_failure($log_failed_filename, $testno, "missing msglog") if (/^c$/ && $force_continue); + last if /^c$/; + if (/^u$/) { foreach $key (keys %expected_msglogs) { @@ -2167,8 +2218,7 @@ elsif (/^((?i:[A-Z\d_]+=\S+\s+)+)?(\d+)?\s*(sudo(?:\s+-u\s+(\w+))?\s+)?exim(_\S+ # Done backwards just in case there are more than 9 - my($i); - for ($i = @msglist; $i > 0; $i--) { $args =~ s/\$msg$i/$msglist[$i-1]/g; } + for (my $i = @msglist; $i > 0; $i--) { $args =~ s/\$msg$i/$msglist[$i-1]/g; } if ( $args =~ /\$msg\d/ ) { tests_exit(-1, "Not enough messages in spool, for test $testno line $lineno\n") @@ -2360,9 +2410,9 @@ print "Exim tester $testversion\n"; # we map all (.../bin) to (.../sbin:.../bin) $ENV{PATH} = do { my %seen = map { $_, 1 } split /:/, $ENV{PATH}; - join ':' => map { m{(.*)/bin$} - ? ( $seen{"$1/sbin"} ? () : ("$1/sbin"), $_) - : ($_) } + join ':' => map { m{(.*)/bin$} + ? ( $seen{"$1/sbin"} ? () : ("$1/sbin"), $_) + : ($_) } split /:/, $ENV{PATH}; }; @@ -2405,7 +2455,7 @@ else # as the path to the binary. If the first argument does not start with a # '/' but exists in the file system, it's assumed to be the Exim binary. -$parm_exim = (@ARGV > 0 && (-x $ARGV[0] or $ARGV[0] =~ m?^/?))? Cwd::abs_path(shift @ARGV) : ""; +($parm_exim, @ARGV) = Exim::Runtest::exim_binary(@ARGV); print "Exim binary is $parm_exim\n" if $parm_exim ne ""; @@ -2472,55 +2522,6 @@ $parm_cwd = Cwd::getcwd(); # takes precedence; otherwise exim-snapshot takes precedence over any numbered # releases. -if ($parm_exim eq "") - { - my($use_srcdir) = ""; - - opendir DIR, ".." || die "** Failed to opendir \"..\": $!\n"; - while ($f = readdir(DIR)) - { - my($srcdir); - - # Try this directory if it is "exim4" or if it is exim-snapshot or exim-n.m - # possibly followed by -RCx where n.m is greater than any previously tried - # directory. Thus, we should choose the highest version of Exim that has - # been compiled. - - if ($f eq "exim4" || $f eq "exim-snapshot" || $f eq 'src') - { $srcdir = $f; } - else - { $srcdir = $f - if ($f =~ /^exim-\d+\.\d+(-RC\d+)?$/ && $f gt $use_srcdir); } - - # Look for a build directory with a binary in it. If we find a binary, - # accept this source directory. - - if ($srcdir) - { - opendir SRCDIR, "../$srcdir" || - die "** Failed to opendir \"$cwd/../$srcdir\": $!\n"; - while ($f = readdir(SRCDIR)) - { - if ($f =~ /^build-/ && -e "../$srcdir/$f/exim") - { - $use_srcdir = $srcdir; - $parm_exim = "$cwd/../$srcdir/$f/exim"; - $parm_exim =~ s'/[^/]+/\.\./'/'; - last; - } - } - closedir(SRCDIR); - } - - # If we have found "exim4" or "exim-snapshot", that takes precedence. - # Otherwise, continue to see if there's a later version. - - last if $use_srcdir eq "exim4" || $use_srcdir eq "exim-snapshot"; - } - closedir(DIR); - print "Exim binary found in $parm_exim\n" if $parm_exim ne ""; - } - # If $parm_exim is still empty, ask the caller if ($parm_exim eq "") @@ -2573,7 +2574,13 @@ while() $version =~ s/^\d+\K\./_/; $git =~ s/^exim-//i; $git =~ s/.*-\Kg([[:xdigit:]]+(?:-XX)?)/$1/; - print "\n*** Version mismatch (Exim: $version vs. GIT: $git). ***\n\n" + print <<___ + +*** Version mismatch +*** Exim binary: $version +*** Git : $git + +___ if not $version eq $git; } } @@ -2582,7 +2589,7 @@ while() $parm_trusted_config_list = $1 if /^TRUSTED_CONFIG_LIST:.*?"(.*?)"$/; ($parm_configure_owner, $parm_configure_group) = ($1, $2) if /^Configure owner:\s*(\d+):(\d+)/; - print "$_" if /wrong owner/; + print if /wrong owner/; } close(EXIMINFO); @@ -2596,6 +2603,7 @@ else print "Unable to extract exim_user from binary.\n"; print "Check if Exim refused to run; if so, consider:\n"; print " TRUSTED_CONFIG_LIST ALT_CONFIG_PREFIX WHITELIST_D_MACROS\n"; + print "If debug permission denied, are you in the exim group?\n"; die "Failing to get information from binary.\n"; } @@ -3132,8 +3140,15 @@ if ($parm_ipv6 =~ /^[\da-f]/) chomp($temp = `hostname`); die "'hostname' didn't return anything\n" unless defined $temp and length $temp; -$parm_hostname = (gethostbyname($temp))[0]; -$parm_hostname = "no.host.name.found" unless defined $parm_hostname and length $parm_hostname; +if ($temp =~ /\./) + { + $parm_hostname = $temp; + } +else + { + $parm_hostname = (gethostbyname($temp))[0]; + $parm_hostname = "no.host.name.found" unless defined $parm_hostname and length $parm_hostname; + } print "Hostname is $parm_hostname\n"; if ($parm_hostname !~ /\./) @@ -3576,7 +3591,12 @@ closedir(DIR); # contains ****. We open input from the terminal so that we can read responses # to prompts. -open(T, "/dev/tty") || tests_exit(-1, "Failed to open /dev/tty: $!"); +if (not $force_continue) { + # runtest needs to interact if we're not in continue + # mode. It does so by communicate to /dev/tty + open(T, "/dev/tty") or tests_exit(-1, "Failed to open /dev/tty: $!"); +} + print "\nPress RETURN to run the tests: "; $_ = $force_continue ? "c" : ; @@ -3666,16 +3686,7 @@ foreach $test (@test_list) if (/^no_stdout_check/) { $stdout_skip = 1; next; } if (/^rmfiltertest/) { $rmfiltertest = 1; next; } if (/^sortlog/) { $sortlog = 1; next; } - if (/\bPORT_DYNAMIC\b/) { - for (my $port = 1024; $port < 65000; $port++) { - $dynamic_socket = IO::Socket::INET->new( - LocalHost => '127.0.0.1', - LocalPort => $port, - Listen => 10, - ReuseAddr => 1, - ) and last; - } - } + if (/\bPORT_DYNAMIC\b/) { $dynamic_socket = Exim::Runtest::dynamic_socket(); next; } } # Reset to beginning of file for per test interpreting/processing seek(SCRIPT, 0, 0);