X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/996a98d33f790a1e6af927c02318649feec6061b..80dceaeced16838c894429d5c15d8699ddec5542:/test/runtest diff --git a/test/runtest b/test/runtest index 1e604e1cd..2ac6198eb 100755 --- a/test/runtest +++ b/test/runtest @@ -29,10 +29,11 @@ use File::Basename; use Pod::Usage; use Getopt::Long; use FindBin qw'$RealBin'; +use File::Copy; use lib "$RealBin/lib"; use Exim::Runtest; -use Exim::Utils qw(uniq numerically); +use Exim::Utils qw(uniq numerically cp); use if $ENV{DEBUG} && scalar($ENV{DEBUG} =~ /\bruntest\b/) => 'Smart::Comments' => '####'; use if $ENV{DEBUG} && scalar($ENV{DEBUG} =~ /\bruntest\b/) => 'Data::Dumper'; @@ -368,6 +369,10 @@ my($is_mail) = $file =~ /mail/; $date = "\\d{2}-\\w{3}-\\d{4}\\s\\d{2}:\\d{2}:\\d{2}"; +# Debug time & pid + +$time_pid = "(?:\\d{2}:\\d{2}:\\d{2}\\s+\\d+\\s)"; + # Pattern for matching pids at start of stderr lines; initially something # that won't match. @@ -407,7 +412,7 @@ RESET_AFTER_EXTRA_LINE_READ: #s/Exim \K\d+[._]\d+[\w_-]*/x.yz/i; # Replace Exim message ids by a unique series - s/((?:[^\W_]{6}-){2}[^\W_]{2}) + s/(\d[^\W_]{5}-[^\W_]{6}-[^\W_]{2}) /new_value($1, "10Hm%s-0005vi-00", \$next_msgid)/egx; # The names of lock files appear in some error and debug messages @@ -598,11 +603,13 @@ RESET_AFTER_EXTRA_LINE_READ: # LibreSSL # TLSv1:AES256-GCM-SHA384:256 # TLSv1:ECDHE-RSA-CHACHA20-POLY1305:256 + # TLS1.3:AEAD-AES256-GCM-SHA384:256 # # ECDHE-RSA-CHACHA20-POLY1305 # AES256-GCM-SHA384 s/(?>/; next if /SSL verify error: depth=0 error=certificate not trusted/; + # OpenSSL 3.0.0 + s/TLS error \(D-H param setting .* error:\K.*dh key too small/xxxxxxxx:SSL routines::dh key too small/; + # ======== Maildir things ======== # timestamp output in maildir processing s/(timestamp=|\(timestamp_only\): )\d+/$1ddddddd/g; @@ -955,6 +964,9 @@ RESET_AFTER_EXTRA_LINE_READ: # MIME boundaries in RFC3461 DSN messages s/\d{8,10}-eximdsn-\d+/NNNNNNNNNN-eximdsn-MMMMMMMMMM/; + # Cyrus SASL library version differences (rejectlog) + s/Cyrus SASL permanent failure: \Kuser not found$/generic failure/; + # ========================================================== # Some munging is specific to the specific file types @@ -1007,7 +1019,8 @@ RESET_AFTER_EXTRA_LINE_READ: s/conversion: german.xn--strae-oqa.de/conversion: german.straße.de/; # subsecond timstamp info in reported header-files - s/^(-received_time_usec \.)\d{6}$/$1uuuuuu/; + s/^-received_time_usec \.\K\d{6}$/uuuuuu/; + s/^-received_time_complete \K\d+\.\d{6}$/tttt.uuuuuu/; # Postgres server takes varible time to shut down; lives in various places s/^waiting for server to shut down\.+ done$/waiting for server to shut down.... done/; @@ -1019,6 +1032,9 @@ RESET_AFTER_EXTRA_LINE_READ: # ARC is not always supported by the build next if /^arc_sign =/; + # LIMITS is not always supported by the build + next if /^limits_advertise_hosts =/; + # TLS resumption is not always supported by the build next if /^tls_resumption_hosts =/; next if /^-tls_resumption/; @@ -1090,11 +1106,20 @@ RESET_AFTER_EXTRA_LINE_READ: next if /^GnuTLS<2>: added \d+ protocols, \d+ ciphersuites, \d+ sig algos and \d+ groups into priority list$/; next if /^GnuTLS<2>: (Disabling X.509 extensions|signing structure using RSA-SHA256)/; next if /^GnuTLS.*(wrap_nettle_mpi_print|gnutls_subject_alt_names_get|get_alt_name)/; + next if /^GnuTLS<[23]>: (p11|ASSERT: pkcs11.c|Initializing needed PKCS #11 modules)/; + next if /^GnuTLS<2>: Intel (AES|GCM) accelerator was detected/; + next if /^Added \d{3} certificate authorities/; + next if /^TLS: not preloading CRL for server/; + next if /^GnuTLS<3>: ASSERT: extensions.c\[_gnutls_get_extension/; + next if /^GnuTLS<3>: ASSERT: \.\.\/\.\.\/\.\.\/lib\/x509\//; + next if /^GnuTLS<2>: Initializing PKCS #11 modules/; + # only kevent platforms (FreeBSD, OpenBSD) say this next if /^watch dir/; next if /^watch file .*\/usr\/local/; next if /^watch file .*\/etc\/ssl/; + next if /^closing watch fd:/; # TLS preload # there happen in different orders for OpenSSL/GnuTLS/noTLS @@ -1103,28 +1128,28 @@ RESET_AFTER_EXTRA_LINE_READ: next if /^TLS: not preloading server certs$/; # drop lookups - next if /^Lookups \(built-in\):/; - next if /^Loading lookup modules from/; - next if /^Loaded \d+ lookup modules/; - next if /^Total \d+ lookups/; + next if /^$time_pid?(?: Lookups\ \(built-in\): + | Loading\ lookup\ modules\ from + | Loaded\ \d+\ lookup\ modules + | Total\ \d+\ lookups)/x; # drop compiler information - next if /^Compiler:/; + next if /^$time_pid?Compiler:/; # and the ugly bit # different libraries will have different numbers (possibly 0) of follow-up # lines, indenting with more data - if (/^Library version:/) { + if (/^$time_pid?Library version:/) { while (1) { $_ = ; - next if /^\s/; + next if /^$time_pid?\s/; goto RESET_AFTER_EXTRA_LINE_READ; } } # drop other build-time controls emitted for debugging - next if /^WHITELIST_D_MACROS:/; - next if /^TRUSTED_CONFIG_LIST:/; + next if /^$time_pid?WHITELIST_D_MACROS:/; + next if /^$time_pid?TRUSTED_CONFIG_LIST:/; # As of Exim 4.74, we log when a setgid fails; because we invoke Exim # with -be, privileges will have been dropped, so this will always @@ -1153,6 +1178,8 @@ RESET_AFTER_EXTRA_LINE_READ: # drop pdkim debugging header next if /^DKIM( <<<<<<<<<<<<<<<<<<<<<<<<<<<<<+|: no signatures)$/; + # Some platforms have TIOCOUTome do not + next if /\d+ bytes remain in socket output buffer$/; # Various other IPv6 lines must be omitted too next if /using host_fake_gethostbyname for \S+ \(IPv6\)/; @@ -1168,14 +1195,16 @@ RESET_AFTER_EXTRA_LINE_READ: next; } - # Non-TLS bulds have a different Recieved: header expansion - s/^((.*)\t}}}}by \$primary_hostname \$\{if def:received_protocol \{with \$received_protocol }})\(Exim \$version_number\)$/$1\${if def:tls_in_cipher_std { tls \$tls_in_cipher_std\n$2\t}}(Exim \$version_number)/; - s/^((\s*).*considering: with \$received_protocol }})\(Exim \$version_number\)$/$1\${if def:tls_in_cipher_std { tls \$tls_in_cipher_std\n$2\t}}(Exim \$version_number)/; - if (/condition: def:tls_in_cipher_std$/) + # Non-TLS builds have a different default Recieved: header expansion + s/^((.*)\t}}}}by \$primary_hostname \$\{if def:received_protocol \{with \$received_protocol }})\(Exim \$version_number\)$/$1\${if def:tls_in_ver { (\$tls_in_ver)}}\${if def:tls_in_cipher_std { tls \$tls_in_cipher_std\n$2\t}}(Exim \$version_number)/; + s/^((\s*).*considering: with \$received_protocol }})\(Exim \$version_number\)$/$1\${if def:tls_in_ver { (\$tls_in_ver)}}\${if def:tls_in_cipher_std { tls \$tls_in_cipher_std\n$2\t}}(Exim \$version_number)/; + if (/condition: def:tls_in_ver$/) { $_= ; $_= ; $_= ; $_= ; $_= ; $_= ; $_= ; $_= ; - $_= ; $_= ; $_= ; next; + $_= ; $_= ; $_= ; $_= ; + $_= ; $_= ; $_= ; $_= ; + $_= ; $_= ; $_= ; $_= ; $_= ; next; } @@ -1267,6 +1296,9 @@ RESET_AFTER_EXTRA_LINE_READ: $_ = $line . $_; } + # Different builds will have different lookup types included + s/^\s*search_type \K\d+ \((\w+)\) quoting -1 \(none\)$/NN ($1) quoting -1 (none)/; + # DISABLE_OCSP next if /in hosts_requ(est|ire)_ocsp\? (no|yes)/; @@ -1282,6 +1314,9 @@ RESET_AFTER_EXTRA_LINE_READ: # Experimental_REQUIRETLS next if / in tls_advertise_requiretls?\? no \(end of list\)/; + # Experimental_LIMITS + next if / in limits_advertise_hosts?\? no \(matched "!\*"\)/; + # TCP Fast Open next if /^(ppppp )?setsockopt FASTOPEN: Network Error/; @@ -1289,7 +1324,7 @@ RESET_AFTER_EXTRA_LINE_READ: next if /\w+ in keep_environment\? (yes|no)/; # Sizes vary with test hostname - s/^cmd buf flush \d+ bytes$/cmd buf flush ddd bytes/; + s/^cmd buf flush \d+ bytes/cmd buf flush ddd bytes/; # Spool filesystem free space changes on different systems. s/^((?:spool|log) directory space =) -?\d+K (inodes =)\s*-?\d+/$1 nnnnnK $2 nnnnn/; @@ -1384,8 +1419,13 @@ RESET_AFTER_EXTRA_LINE_READ: s/^errno = \d+$/errno = EEE/; s/^writing error \d+: /writing error EEE: /; - # Some platforms have to flip to slow-mode taint-checking - next if /switching to slow-mode taint checking/; + # Time-only, in debug output + # we have to handle double lines from the DBOPEN, hence placed down here and /mg + s/^\d\d:\d\d:\d\d\s+/01:01:01 /mg; + + # pid in debug lines + s/^(\d\d:\d\d:\d\d)(\s+\d+\s)/"$1 " . new_value($2, "%s", \$next_pid) . " "/mgxe; + s/(?>/; + s/\(gnutls_handshake\): No common application protocol could be negotiated./(SSL_accept): error: <>/; } # ======== mail ======== @@ -1789,7 +1837,7 @@ if (-e $sf_current) if (-s $mf) { my $sf = /^u/i ? $sf_current : $sf_flavour; - tests_exit(-1, "Failed to cp $mf $sf") if system("cp '$mf' '$sf'") != 0; + copy($mf, $sf) or tests_exit(-1, "Failed to copy $mf $sf"); } else { @@ -1890,11 +1938,6 @@ $munges = { 'mainlog' => 's/^(.* SMTP protocol synchronization error .* next input=.{8}).*$/$1/', 'rejectlog' => 's/^(.* SMTP protocol synchronization error .* next input=.{8}).*$/$1/'}, - 'debuglog_stdout' => - { '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|message) deferral .* errno) <\d+> /$1 /' }, @@ -1995,7 +2038,7 @@ if (! $message_skip) foreach $mail (@mails) { - next if $mail eq "test-mail/oncelog"; + next if $mail =~ /^test-mail\/oncelog(.(dir|pag|db))?$/; $saved_mail = substr($mail, 10); # Remove "test-mail/" $saved_mail =~ s/^$parm_caller(\/|$)/CALLER/; # Convert caller name @@ -2152,7 +2195,7 @@ if ($debug) $prcmd =~ s/; /;\n>> /; print ">> $prcmd\n"; } -system("$cmd"); +system($cmd); } @@ -2276,7 +2319,7 @@ if (/^dump\s+(\S+)/) sort { $a->[0] cmp $b->[0] } #map { [ (split)[0] =~ s/\Q$parm_ipv4/ip4.ip4.ip4.ip4/gr, $_ ] } # this is too modern for 5.10.1 map { - (my $k = (split)[0]) =~ s/\Q$parm_ipv4/ip4.ip4.ip4.ip4/g; + (my $k = (split)[0]) =~ s/\Q$parm_ipv4\E/ip4.ip4.ip4.ip4/g; [ $k, $_ ] } do { local $/ = "\n "; <$in> }; @@ -2297,6 +2340,16 @@ if (/^dump\s+(\S+)/) return $aa cmp $bb; } @temp; } + elsif ($which eq "seen") + { + @temp = sort { + (my $aa = $a) =~ s/^([\d.]+)/$1/; + (my $bb = $b) =~ s/^([\d.]+)/$1/; + $aa =~ s/\Q$parm_ipv4\E/ip4.ip4.ip4.ip4/; + $bb =~ s/\Q$parm_ipv4\E/ip4.ip4.ip4.ip4/; + return $aa cmp $bb; + } @temp; + } print $out @temp; } close($in); # close it explicitly, otherwise $? does not get set @@ -2935,6 +2988,7 @@ GetOptions( 'valgrind' => \$valgrind, 'range=s{2}' => \my @range_wanted, 'test=i@' => \my @tests_wanted, + 'fail-any!' => \my $fail_any, 'flavor|flavour=s' => \$flavour, 'help' => sub { pod2usage(-exit => 0) }, 'man' => sub { @@ -3043,7 +3097,7 @@ my $eximinfo = "$parm_exim -d -C $parm_cwd/test-config -DDIR=$parm_cwd -bP exim_ chomp(my @eximinfo = `$eximinfo 2>&1`); die "$0: Can't run $eximinfo\n" if $? == -1; -warn 'Got ' . $?>>8 . " from $eximinfo\n" if $?; +warn 'Got ' . ($?>>8) . " from $eximinfo\n" if $?; foreach (@eximinfo) { if (my ($version) = /^Exim version (\S+)/) { @@ -3738,37 +3792,16 @@ system("sudo cp eximdir/exim eximdir/exim_exim;" . ($parm_exim_dir) = $parm_exim =~ m?^(.*)/exim?; $dbm_build_deleted = 0; -if (defined $parm_lookups{dbm} && - system("cp $parm_exim_dir/exim_dbmbuild eximdir") != 0) +if (defined $parm_lookups{dbm} && not cp("$parm_exim_dir/exim_dbmbuild", "eximdir/exim_dbmbuild")) { delete $parm_lookups{dbm}; $dbm_build_deleted = 1; } -if (system("cp $parm_exim_dir/exim_dumpdb eximdir") != 0) - { - tests_exit(-1, "Failed to make a copy of exim_dumpdb: $!"); - } - -if (system("cp $parm_exim_dir/exim_lock eximdir") != 0) - { - tests_exit(-1, "Failed to make a copy of exim_lock: $!"); - } - -if (system("cp $parm_exim_dir/exinext eximdir") != 0) - { - tests_exit(-1, "Failed to make a copy of exinext: $!"); - } - -if (system("cp $parm_exim_dir/exigrep eximdir") != 0) - { - tests_exit(-1, "Failed to make a copy of exigrep: $!"); - } - -if (system("cp $parm_exim_dir/eximstats eximdir") != 0) - { - tests_exit(-1, "Failed to make a copy of eximstats: $!"); - } +foreach my $tool (qw(exim_dumpdb exim_lock exinext exigrep eximstats)) { + cp("$parm_exim_dir/$tool" => "eximdir/$tool") + or tests_exit(-1, "Failed to make a copy of $tool: $!"); +} # Collect some version information print '-' x 78, "\n"; @@ -4161,6 +4194,7 @@ if (not $force_continue) { } +my $failures = 0; foreach $test (@test_list) { state $lasttestdir = ''; @@ -4207,15 +4241,15 @@ foreach $test (@test_list) # the test-mail directory for appendfile deliveries. system "sudo /bin/rm -rf spool test-*"; - system "mkdir test-mail 2>/dev/null"; + mkdir "test-mail"; # A privileged Exim will normally make its own spool directory, but some of # the tests run in unprivileged modes that don't always work if the spool # directory isn't already there. What is more, we want anybody to be able # to read it in order to find the daemon's pid. - system "mkdir spool; " . - "sudo chown $parm_eximuser:$parm_eximgroup spool; " . + mkdir "spool"; + system "sudo chown $parm_eximuser:$parm_eximgroup spool; " . "sudo chmod 0755 spool"; # Empty the cache that keeps track of things like message id mappings, and @@ -4394,10 +4428,12 @@ foreach $test (@test_list) print "\nshow stdErr, show stdOut, Retry, Continue (without file comparison), or Quit? [Q] "; $_ = $force_continue ? "c" : ; tests_exit(1) if /^q?$/i; - if (/^c$/ && $force_continue) { - log_failure($log_failed_filename, $testno, "exit code unexpected"); - log_test($log_summary_filename, $testno, 'F') - } + if (/^c$/ && $force_continue) + { + log_failure($log_failed_filename, $testno, "exit code unexpected"); + log_test($log_summary_filename, $testno, 'F'); + $failures++; + } if ($force_continue) { print "\nstdout tail:\n"; @@ -4450,7 +4486,7 @@ foreach $test (@test_list) { if (($? & 0xff) == 0) { printf("Server return code %d for test %d starting line %d", $?/256, - $testno, $subtest_startline); } + $testno, $subtest_startline); } elsif (($? & 0xff00) == 0) { printf("Server killed by signal %d", $? & 255); } else @@ -4461,10 +4497,12 @@ foreach $test (@test_list) print "\nShow server stdout, Retry, Continue, or Quit? [Q] "; $_ = $force_continue ? "c" : ; tests_exit(1) if /^q?$/i; - if (/^c$/ && $force_continue) { - log_failure($log_failed_filename, $testno, "exit code unexpected"); - log_test($log_summary_filename, $testno, 'F') - } + if (/^c$/ && $force_continue) + { + log_failure($log_failed_filename, $testno, "exit code unexpected"); + log_test($log_summary_filename, $testno, 'F'); + $failures++; + } print "... continue forced\n" if $force_continue; last if /^[rc]$/i; @@ -4499,7 +4537,14 @@ foreach $test (@test_list) { sleep 1 if $slow; my $rc = check_output($TEST_STATE->{munge}); - log_test($log_summary_filename, $testno, 'P') if ($rc == 0); + if ($rc == 0) + { + log_test($log_summary_filename, $testno, 'P'); + } + else + { + $failures++; + } if ($rc < 2) { print (" Script completed\n"); @@ -4518,7 +4563,7 @@ foreach $test (@test_list) ################################################## tests_exit(-1, "No runnable tests selected") if not @test_list; -tests_exit(0); +tests_exit($fail_any ? $failures : 0); __END__