X-Git-Url: https://git.exim.org/users/jgh/exim.git/blobdiff_plain/b057ad118a14ea2e8f9bc483eaf636e84b25c4be..dd7b74e90a96eaf109796d8f9499578571a1572c:/test/runtest diff --git a/test/runtest b/test/runtest index 62281656d..d97969cf3 100755 --- a/test/runtest +++ b/test/runtest @@ -17,15 +17,20 @@ #use strict; 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' => '####'); @@ -44,7 +49,10 @@ $gnutls_dh_bits_normal = 2236; $cf = "bin/cf -exact"; $cr = "\r"; $debug = 0; -$flavour = 'FOO'; +$flavour = do { + my $f = Exim::Runtest::flavour(); + (grep { $f eq $_ } Exim::Runtest::flavours()) ? $f : 'FOO'; +}; $force_continue = 0; $force_update = 0; $log_failed_filename = "failed-summary.log"; @@ -88,6 +96,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'; @@ -149,6 +161,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; } @@ -878,7 +891,7 @@ RESET_AFTER_EXTRA_LINE_READ: next if /^SSL info: SSLv2\/v3 write client hello A/; next if /^SSL info: SSLv3 read server key exchange A/; next if /SSL verify error: depth=0 error=certificate not trusted/; - s/SSL3_READ_BYTES/ssl3_read_bytes/; + s/SSL3_READ_BYTES/ssl3_read_bytes/i; # gnutls version variances next if /^Error in the pull function./; @@ -1045,6 +1058,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 @@ -1119,11 +1156,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 ; } @@ -1143,13 +1191,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"; } @@ -1196,10 +1244,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$/); } @@ -1218,9 +1265,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); } @@ -1338,10 +1385,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; @@ -1443,6 +1490,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 /' }, }; @@ -1555,16 +1605,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) { @@ -1639,11 +1689,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) { @@ -2408,7 +2458,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 ""; @@ -2475,55 +2525,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 "") @@ -2576,7 +2577,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; } } @@ -2585,7 +2592,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); @@ -2599,6 +2606,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"; } @@ -3135,8 +3143,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 !~ /\./) @@ -3579,7 +3594,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" : ; @@ -3669,16 +3689,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);