X-Git-Url: https://git.exim.org/users/jgh/exim.git/blobdiff_plain/a713f76692228165883d92875fbad3bfb89c001e..6440616152c46002c71a3a6413adeeb0fe435db0:/test/runtest diff --git a/test/runtest b/test/runtest index 13070647f..d9db2ccc8 100755 --- a/test/runtest +++ b/test/runtest @@ -64,7 +64,7 @@ my $force_continue = 0; my $force_update = 0; my $log_failed_filename = 'failed-summary.log'; my $log_summary_filename = 'run-summary.log'; -my $more = 'less -XF'; +my @more = qw'less -XF'; my $optargs = ''; my $save_output = 0; my $server_opts = ''; @@ -552,15 +552,19 @@ RESET_AFTER_EXTRA_LINE_READ: # the older (comment) style, keeping only the Auth element # (discarding kex, cipher, mac). For TLS 1.3 there is no kex # element (and no _WITH); insert a spurious "RSA". + # Also in $tls_X_cipher_std reporting. - s/^\s+by .+ with .+ \K tls TLS_.*?([^_]+)_WITH.+$/(TLS1.x:ke-$1-AES256-SHAnnn:xxx)/; - s/^\s+by .+ with .+ \K tls TLS_.+$/(TLS1.x:ke-RSA-AES256-SHAnnn:xxx)/; + s/^\s+by \S+ with .+ \K \(TLS1(?:\.[0-3])?\) tls TLS_.*?([^_]+)_WITH.+$/(TLS1.x:ke-$1-AES256-SHAnnn:xxx)/; + s/^\s+by \S+ with .+ \K \(TLS1(?:\.[0-3])?\) tls TLS_.+$/(TLS1.x:ke-RSA-AES256-SHAnnn:xxx)/; + + s/ cipher_ TLS_.*?([^_]+)_WITH.+$/ cipher_ TLS1.x:ke_$1_WITH_ci_mac/; + s/ cipher_ TLS_.*$/ cipher_ TLS1.x:ke_RSA_WITH_ci_mac/; # Test machines might have various different TLS library versions supporting # different protocols; can't rely upon TLS 1.2's AES256-GCM-SHA384, so we # treat the standard algorithms the same. # - # TLSversion : KeyExchange? - Authentication/Signature - C_iph_er - MAC : ??? + # TLSversion : KeyExchange? - Authentication/Signature - C_iph_er - MAC : bits # # So far, have seen: # TLSv1:AES128-GCM-SHA256:128 @@ -578,7 +582,7 @@ RESET_AFTER_EXTRA_LINE_READ: # # Retain the authentication algorith field as we want to test that. - s/( (?: (?:\b|\s) [\(=] ) | \s )TLSv1(\.[123])?:/$1TLS1.x:/xg; + s/( (?: (?:\b|\s) [\(=] ) | \s )TLS1(\.[123])?:/$1TLS1.x:/xg; s/(?PSK)_)?((?RSA|ECDSA)_)? (SECP(256|521)R1|X25519))?__?)? # key-exchange ((?RSA|ECDSA)((_PSS_RSAE)?_SHA(512|256))?__?)? # authentication + (?WITH_)? # stdname-with AES_(256|128)_(CBC|GCM) # cipher (__?AEAD)? # pseudo-MAC (__?SHA(1|256|384))? # PRF @@ -644,10 +649,15 @@ RESET_AFTER_EXTRA_LINE_READ: /"TLS1.x:ke-" . (defined($+{psk}) ? $+{psk} : "") . (defined($+{auth}) ? $+{auth} : "") + . (defined($+{with}) ? $+{with} : "") . "-AES256-SHAnnn:xxx"/gex; s/TLS1.2:RSA__CAMELLIA_256_GCM(_SHA384)?:256/TLS1.2:RSA_CAMELLIA_256_GCM-SHAnnn:256/g; s/\b(ECDHE-(RSA|ECDSA)-AES256-SHA|DHE-RSA-AES256-SHA256)\b/ke-$2-AES256-SHAnnn/g; + # Separate reporting of TLS version + s/ver: TLS1(\.[0-3])?$/ver: TLS1.x/; + s/ \(TLS1(\.[0-3])?\) / (TLS1.x) /; + # GnuTLS library error message changes s/(No certificate was found|Certificate is required)/The peer did not send any certificate/g; #(dodgy test?) s/\(certificate verification failed\): invalid/\(gnutls_handshake\): The peer did not send any certificate./g; @@ -790,6 +800,12 @@ RESET_AFTER_EXTRA_LINE_READ: # Also, the length of space at the end of the host line is dependent # on the length of the longest line, so strip it also on otherwise # un-rewritten lines like localhost + # + # host 127.0.0.1 [127.0.0.1] + # host 10.0.0.1 [10.0.0.1]- + # + # host 127.0.0.1 [127.0.0.1]-- + # host 169.16.16.16 [169.16.16.10] s/^\s+host\s(\S+)\s+(\S+)/ host $1 $2/; s/^\s+(host\s\S+\s\S+)\s+(port=.*)/ host $1 $2/; @@ -801,7 +817,7 @@ RESET_AFTER_EXTRA_LINE_READ: s/(^|\W)\K\Q$parm_ipv6_stripped\E/ip6:ip6:ip6:ip6:ip6:ip6:ip6:ip6/g; s/\b\Q$parm_ipv4r\E\b/ip4-reverse/g; s/(^|\W)\K\Q$parm_ipv6r\E/ip6-reverse/g; - s/^(\s+host\s\S+\s+\[\S+\]) +$/$1 /; + s/^\s+host\s\S+\s+\[\S+\]\K +$//; # strip, not collapse the trailing whitespace # ======== Test network IP addresses ======== @@ -877,7 +893,7 @@ RESET_AFTER_EXTRA_LINE_READ: # The sizes of filter files may vary because of the substitution of local # filenames, logins, etc. - s/^\d+(?= bytes read from )/ssss/; + s/^\d+(?= (\(tainted\) )?bytes read from )/ssss/; # ======== OpenSSL error messages ======== @@ -917,14 +933,17 @@ RESET_AFTER_EXTRA_LINE_READ: last if !defined $_; + # SRS timestamps and signatures vary by hostname and from run to run + + s/SRS0=....=..=[^=]+=[^@]+\@test.ex/SRS0=ZZZZ=YY=the.local.host.name=CALLER\@test.ex/; + + # ======== Output from the "fd" program about open descriptors ======== # The statuses seem to be different on different operating systems, but # at least we'll still be checking the number of open fd's. s/max fd = \d+/max fd = dddd/; - s/status=0 RDONLY/STATUS/g; - s/status=1 WRONLY/STATUS/g; - s/status=2 RDWR/STATUS/g; + s/status=[0-9a-f]+ (?:RDONLY|WRONLY|RDWR)/STATUS/g; # ======== Contents of spool files ======== @@ -1024,6 +1043,7 @@ RESET_AFTER_EXTRA_LINE_READ: s/(?<=^>>>>>>>>>>>>>>>> Exim pid=)\d+(?= terminating)/pppp/; s/^(proxy-proc \w{5}-pid) \d+$/$1 pppp/; + s/^(?:\s*\d+ )(exec .* -oPX)$/pppp $1/; # IP address lookups use gethostbyname() when IPv6 is not supported, # and gethostbyname2() or getipnodebyname() when it is. @@ -1041,6 +1061,9 @@ RESET_AFTER_EXTRA_LINE_READ: next if /OpenSSL compile-time version: OpenSSL \d+[\.\da-z]+/; next if /OpenSSL runtime version: OpenSSL \d+[\.\da-z]+/; + # this is timing-dependent + next if /^OpenSSL: creating STEK$/; + # drop lookups next if /^Lookups \(built-in\):/; next if /^Loading lookup modules from/; @@ -1175,6 +1198,9 @@ RESET_AFTER_EXTRA_LINE_READ: # Platform-dependent error strings s/Operation timed out/Connection timed out/; + # Platform differences on disconnect + s/unexpected disconnection while reading SMTP command from \[127.0.0.1\] \K\(error: Connection reset by peer\) //; + # Platform-dependent resolver option bits s/^ (?:writing|update) neg-cache entry for [^,]+-\K[0-9a-f]+, ttl/xxxx, ttl/; @@ -1238,11 +1264,12 @@ RESET_AFTER_EXTRA_LINE_READ: next if /^DKIM \[[^[]+\] (Header hash|b) computed:/; # Not all platforms support TCP Fast Open, and the compile omits the check - if (s/\S+ in hosts_try_fastopen\? (no \(option unset\)|yes \(matched "\*"\))\n$//) + if (s/\S+ in hosts_try_fastopen\? (no \(option unset\)|no \(end of list\)|yes \(matched "\*"\))\n$//) { + chomp; $_ .= ; s/ \.\.\. >>> / ... /; - if (s/ non-TFO mode connection attempt to 224.0.0.0, 0 data\b$//) { $_ .= ; } + if (s/ non-TFO mode connection attempt to 224.0.0.0, 0 data\b$//) { chomp; $_ .= ; } s/Address family not supported by protocol family/Network Error/; s/Network is unreachable/Network Error/; } @@ -1294,6 +1321,13 @@ RESET_AFTER_EXTRA_LINE_READ: # Platform differences in errno strings s/ SMTP\(Operation timed out\)< $f; } } @@ -1622,26 +1661,25 @@ if (-e $sf_current) } } - open(MUNGED, '>', $mf) || tests_exit(-1, "Failed to open $mf: $!"); - for ($i = 0; $i < @munged; $i++) - { print MUNGED $munged[$i]; } - close(MUNGED); + open(my $fh, '>', $mf) or tests_exit(-1, "Failed to open $mf: $!"); + print $fh @munged; } # Deal with log sorting if ($sortfile) { - my(@munged, $i, $j); - open(MUNGED, $mf) || tests_exit(-1, "Failed to open $mf: $!"); - @munged = ; - close(MUNGED); + my @munged = do { + open(my $fh, '<', $mf) or tests_exit(-1, "Failed to open $mf: $!"); + <$fh>; + }; - for ($i = 0; $i < @munged; $i++) + for (my $i = 0; $i < @munged; $i++) { if ($munged[$i] =~ /^[-\d]{10}\s[:\d]{8}\s[-A-Za-z\d]{16}\s[-=*]>/) { + my $j; for ($j = $i + 1; $j < @munged; $j++) { last if $munged[$j] !~ @@ -1653,11 +1691,9 @@ if (-e $sf_current) } } - open(MUNGED, ">$mf") || tests_exit(-1, "Failed to open $mf: $!"); - print MUNGED "**NOTE: The delivery lines in this file have been sorted.\n"; - for ($i = 0; $i < @munged; $i++) - { print MUNGED $munged[$i]; } - close(MUNGED); + open(my $fh, '>', $mf) or tests_exit(-1, "Failed to open $mf: $!"); + print $fh "**NOTE: The delivery lines in this file have been sorted.\n"; + print $fh @munged; } # Do the comparison @@ -1667,7 +1703,7 @@ if (-e $sf_current) # Handle comparison failure print "** Comparison of $mf with $sf_current failed"; - system("$more test-cf"); + system @more => 'test-cf'; print "\n"; for (;;) @@ -1698,8 +1734,7 @@ else # if we deal with a flavour file, we can't delete it, because next time the generic # file would be used again if ($sf_current eq $sf_flavour) { - open(FOO, ">$sf_current"); - close(FOO); + open(my $fh, '>', $sf_current); } else { tests_exit(-1, "Failed to unlink $sf_current") if !unlink($sf_current); @@ -1762,13 +1797,10 @@ $munges = s! DN="[^,"]*\K,!/!; ', 'rejectlog' => 's/ X=TLS\S+ / X=TLS_proto_and_cipher /', - 'mail' => 's/^\s+by .+ with .+ \K tls TLS_.+$/(TLS_proto_and_cipher)/; - s/ \(TLS[^)]*\)/ (TLS_proto_and_cipher)/; - ', }, 'debug_pid' => - { 'stderr' => 's/(^\s{0,4}|(?<=Process )|(?<=child ))\d{1,5}/ppppp/g' }, + { 'stderr' => 's/(^\s{0,4}|(?<=Process )|(?<=child ))\d+/ppppp/g' }, 'optional_dsn_info' => { 'mail' => '/^(X-(Remote-MTA-(smtp-greeting|helo-response)|Exim-Diagnostic|(body|message)-linecount):|Remote-MTA: X-ip;)/' @@ -1802,7 +1834,7 @@ $munges = }, 'timeout_errno' => # actual errno differs Solaris vs. Linux - { 'mainlog' => 's/(host deferral .* errno) <\d+> /$1 /' }, + { 'mainlog' => 's/((?:host|message) deferral .* errno) <\d+> /$1 /' }, 'peer_terminated_conn' => # actual error differs FreedBSD vs. Linux { 'stderr' => 's/^( SMTP\()Connection reset by peer(\)<<)$/$1closed$2/' }, @@ -2164,34 +2196,37 @@ if (/^dbmbuild\s+(\S+)\s+(\S+)/) if (/^dump\s+(\S+)/) { - my($which) = $1; - my(@temp); + my $which = $1; print ">> ./eximdir/exim_dumpdb $parm_cwd/spool $which\n" if $debug; - open(IN, "./eximdir/exim_dumpdb $parm_cwd/spool $which |"); - open(OUT, ">>test-stdout"); - print OUT "+++++++++++++++++++++++++++\n"; + open(my $in, "-|", './eximdir/exim_dumpdb', "$parm_cwd/spool", $which) or die "Can't run exim_dumpdb: $!"; + open(my $out, ">>test-stdout"); + print $out "+++++++++++++++++++++++++++\n"; if ($which eq "retry") { - $/ = "\n "; - @temp = ; - $/ = "\n"; - - @temp = sort { - my($aa) = split(' ', $a); - my($bb) = split(' ', $b); - return $aa cmp $bb; - } @temp; - + # the sort key is the first part of the retry db dump line, but for + # sorting we (temporarly) replace the own hosts ipv4 with a munged + # version, which matches the munging that is done later + # Why? We must ensure sure, that 127.0.0.1 always sorts first + # map-sort-map: Schwartz's transformation + # test 0099 + my @temp = map { $_->[1] } + 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; + [ $k, $_ ] + } + do { local $/ = "\n "; <$in> }; foreach $item (@temp) { $item =~ s/^\s*(.*)\n(.*)\n?\s*$/$1\n$2/m; - print OUT " $item\n"; + print $out " $item\n"; } } else { - @temp = ; + my @temp = <$in>; if ($which eq "callout") { @temp = sort { @@ -2200,11 +2235,9 @@ if (/^dump\s+(\S+)/) return $aa cmp $bb; } @temp; } - print OUT @temp; + print $out @temp; } - - close(IN); - close(OUT); + close($in); # close it explicitly, otherwise $? does not get set return 1; } @@ -2789,7 +2822,7 @@ umask 022; # Check for the "less" command # ################################################## -$more = 'more' if system('which less >/dev/null 2>&1') != 0; +@more = 'more' if system('which less >/dev/null 2>&1') != 0; @@ -2814,7 +2847,7 @@ Getopt::Long::Configure qw(no_getopt_compat); GetOptions( 'debug' => sub { $debug = 1; $cr = "\n" }, 'diff' => sub { $cf = 'diff -u' }, - 'continue' => sub { $force_continue = 1; $more = 'cat' }, + 'continue' => sub { $force_continue = 1; @more = 'cat' }, 'update' => \$force_update, 'ipv4!' => \$have_ipv4, 'ipv6!' => \$have_ipv6, @@ -3439,7 +3472,7 @@ while (not ($parm_ipv4 and $parm_ipv6) and defined($_ = )) { if (/^(?:[0-9]+: )?([a-z0-9]+): /) { $ifname = $1; } - if (not $parm_ipv4 and /^\s*inet(?:\saddr)?:?\s?(\d+\.\d+\.\d+\.\d+)(?:\/\d+)?\s/i) + if (not $parm_ipv4 and /^\s*inet(?:\saddr(?:ess))?:?\s*(\d+\.\d+\.\d+\.\d+)(?:\/\d+)?\s/i) { # It would be nice to be able to vary the /16 used for manyhome; we could take # an option to runtest used here - but we'd also have to pass it on to fakens. @@ -3448,7 +3481,8 @@ while (not ($parm_ipv4 and $parm_ipv6) and defined($_ = )) $parm_ipv4 = $1; } - if (not $parm_ipv6 and /^\s*inet6(?:\saddr)?:?\s?([abcdef\d:]+)(?:%[^ \/]+)?(?:\/\d+)?/i) + if ( (not $parm_ipv6 or $parm_ipv6 =~ /%/) + and /^\s*inet6(?:\saddr(?:ess))?:?\s*([abcdef\d:]+)(?:%[^ \/]+)?(?:\/\d+)?/i) { next if $1 eq '::' or $1 eq '::1' or $1 =~ /^ff00/i or $1 =~ /^fe80::1/i; $parm_ipv6 = $1; @@ -3817,6 +3851,10 @@ DIR: for (my $i = 0; $i < @test_dirs; $i++) } unlink("$parm_cwd/test-config"); } + elsif (/^ipv6-non-linklocal/) + { + if ($parm_ipv6 =~ /%/) { $wantthis = 0; last; } + } else { tests_exit(-1, "Unknown line in \"scripts/$testdir/REQUIRES\": \"$_\""); @@ -3957,7 +3995,7 @@ if ($have_ipv4 && $parm_ipv4 ne "127.0.0.1") tests_exit(-1, "Failed to open $parm_cwd/dnszones/db.ip4.$components[0]: $!"); print OUT "$components[3].$components[2].$components[1] PTR $parm_hostname.\n\n"; close(OUT); - } + } else { open(OUT, ">$parm_cwd/dnszones/db.ip4.$components[0]") || @@ -4309,11 +4347,11 @@ foreach $test (@test_list) last if /^[rc]$/i; if (/^e$/i) { - system("$more test-stderr"); + system @more => 'test-stderr'; } elsif (/^o$/i) { - system("$more test-stdout"); + system @more => 'test-stdout'; } }