X-Git-Url: https://git.exim.org/users/heiko/exim.git/blobdiff_plain/50dc740948ba43eaeb6d33757bc83beff33f2a64..28a169c6cdc03bfab1240724eae05ec061d22b20:/test/runtest?ds=sidebyside diff --git a/test/runtest b/test/runtest index 49964af2a..fcc7a972e 100755 --- a/test/runtest +++ b/test/runtest @@ -14,11 +14,13 @@ ############################################################################### #use strict; -require Cwd; use Errno; use FileHandle; use Socket; use Time::Local; +use Cwd; +use File::Basename; +use if $ENV{DEBUG} && $ENV{DEBUG} =~ /\bruntest\b/ => ('Smart::Comments' => '####'); # Start by initializing some global variables @@ -43,6 +45,7 @@ $more = "less -XF"; $optargs = ""; $save_output = 0; $server_opts = ""; +$flavour = 'FOO'; $have_ipv4 = 1; $have_ipv6 = 1; @@ -80,6 +83,10 @@ $parm_port_d4 = 1228; # Additional for daemon # Manually set locale $ENV{'LC_ALL'} = 'C'; +# In some environments USER does not exists, but we +# need it for some test(s) +$ENV{USER} = getpwuid($>) + if not exists $ENV{USER}; ############################################################################### @@ -320,6 +327,8 @@ my($extra) = $_[1]; my($yield) = 0; my(@saved) = (); +local $_; + open(IN, "$file") || tests_exit(-1, "Failed to open $file: $!"); my($is_log) = $file =~ /log/; @@ -413,6 +422,7 @@ RESET_AFTER_EXTRA_LINE_READ: # Random local part in callout cache testing s/myhost.test.ex-\d+-testing/myhost.test.ex-dddddddd-testing/; + s/the.local.host.name-\d+-testing/the.local.host.name-dddddddd-testing/; # File descriptor numbers may vary s/^writing data block fd=\d+/writing data block fd=dddd/; @@ -670,6 +680,7 @@ RESET_AFTER_EXTRA_LINE_READ: s/^\s+host\s(\S+)\s+(\S+)/ host $1 $2/; s/^\s+(host\s\S+\s\S+)\s+(port=.*)/ host $1 $2/; s/^\s+(host\s\S+\s\S+)\s+(?=MX=)/ $1 /; + s/^\s+host\s.*?\K\s+(ad=\S+)/ $1/; s/host\s\Q$parm_ipv4\E\s\[\Q$parm_ipv4\E\]/host ipv4.ipv4.ipv4.ipv4 [ipv4.ipv4.ipv4.ipv4]/; s/host\s\Q$parm_ipv6\E\s\[\Q$parm_ipv6\E\]/host ip6:ip6:ip6:ip6:ip6:ip6:ip6:ip6 [ip6:ip6:ip6:ip6:ip6:ip6:ip6:ip6]/; s/\b\Q$parm_ipv4\E\b/ip4.ip4.ip4.ip4/g; @@ -703,6 +714,9 @@ RESET_AFTER_EXTRA_LINE_READ: # ======== Other error numbers ======== s/errno=\d+/errno=dd/g; + # ======== System Error Messages ====== + # depending on the underlaying file system the error message seems to differ + s/(?: is not a regular file)|(?: has too many links \(\d+\))/ not a regular file or too many links/; # ======== Output from ls ======== # Different operating systems use different spacing on long output @@ -731,8 +745,8 @@ RESET_AFTER_EXTRA_LINE_READ: s/this message = \d+\b/this message = sss/; s/Size of headers = \d+/Size of headers = sss/; s/sum=(?!0)\d+/sum=dddd/; - s/(?<=sum=dddd )count=(?!0)\d+\b/count=dd/; - s/(?<=sum=0 )count=(?!0)\d+\b/count=dd/; + s/(?<=sum=dddd )count=\d+\b/count=dd/; + s/(?<=sum=0 )count=\d+\b/count=dd/; s/,S is \d+\b/,S is ddddd/; s/\+0100,\d+;/+0100,ddd;/; s/\(\d+ bytes written\)/(ddd bytes written)/; @@ -809,7 +823,7 @@ RESET_AFTER_EXTRA_LINE_READ: # ========================================================== # MIME boundaries in RFC3461 DSN messages - s/\d{8,10}-eximdsn-\d{7,10}/NNNNNNNNNN-eximdsn-MMMMMMMMMM/; + s/\d{8,10}-eximdsn-\d+/NNNNNNNNNN-eximdsn-MMMMMMMMMM/; # ========================================================== # Some munging is specific to the specific file types @@ -844,7 +858,6 @@ RESET_AFTER_EXTRA_LINE_READ: next if /^SSL info: unknown state/; next if /^SSL info: SSLv2\/v3 write client hello A/; next if /^SSL info: SSLv3 read server key exchange A/; - } # ======== stderr ======== @@ -862,7 +875,7 @@ RESET_AFTER_EXTRA_LINE_READ: # IP address lookups use gethostbyname() when IPv6 is not supported, # and gethostbyname2() or getipnodebyname() when it is. - s/\bgethostbyname2?|\bgetipnodebyname/get[host|ipnode]byname[2]/; + s/\b(gethostbyname2?|\bgetipnodebyname)(\(af=inet\))?/get[host|ipnode]byname[2]/; # drop gnutls version strings next if /GnuTLS compile-time version: \d+[\.\d]+$/; @@ -1006,11 +1019,17 @@ RESET_AFTER_EXTRA_LINE_READ: @saved = (); } + # remote port numbers vary + s/(Connection request from 127.0.0.1 port) \d{1,5}/$1 sssss/; + # Skip hosts_require_dane checks when the options # are unset, because dane ain't always there. next if /in\shosts_require_dane\?\sno\s\(option\sunset\)/x; + # Experimental_International + next if / in smtputf8_advertise_hosts\? no \(option unset\)/; + # Skip some lines that Exim puts out at the start of debugging output # because they will be different in different binaries. @@ -1027,6 +1046,8 @@ RESET_AFTER_EXTRA_LINE_READ: /^Fixed never_users:/ || /^Size of off_t:/ ); + + } next; @@ -1059,7 +1080,7 @@ return $yield; # Arguments: [0] the prompt string # [1] if there is a U in the prompt and $force_update is true # [2] if there is a C in the prompt and $force_continue is true -# Returns: nothing (it sets $_) +# Returns: returns the answer sub interact{ print $_[0]; @@ -1122,7 +1143,13 @@ my($rf,$rsf,$mf,$sf,$sortfile,$extra) = @_; # If there is no saved file, the raw files must either not exist, or be # empty. The test ! -s is TRUE if the file does not exist or is empty. -if (! -e $sf) +# we check if there is a flavour specific file, but we remember +# the original file name as "generic" +$sf_generic = $sf; +$sf_flavour = "$sf_generic.$flavour"; +$sf_current = -e $sf_flavour ? $sf_flavour : $sf_generic; + +if (! -e $sf_current) { return 0 if (! -s $rf && (! defined $rsf || ! -s $rsf)); @@ -1162,6 +1189,8 @@ if (! -e $sf) } } +#### $_ + # Control reaches here if either (a) there is a saved file ($sf), or (b) there # was a request to create a saved file. First, create the munged file from any # data that does exist. @@ -1189,7 +1218,7 @@ close(MUNGED); # a result of parallel deliveries. We load the munged file and sort sequences # of delivery lines. -if (-e $sf) +if (-e $sf_current) { # Deal with truncated text items @@ -1200,7 +1229,7 @@ if (-e $sf) open(MUNGED, "$mf") || tests_exit(-1, "Failed to open $mf: $!"); @munged = ; close(MUNGED); - open(SAVED, "$sf") || tests_exit(-1, "Failed to open $sf: $!"); + open(SAVED, $sf_current) || tests_exit(-1, "Failed to open $sf_current: $!"); @saved = ; close(SAVED); @@ -1262,31 +1291,46 @@ if (-e $sf) # Do the comparison - return 0 if (system("$cf '$mf' '$sf' >test-cf") == 0); + return 0 if (system("$cf '$mf' '$sf_current' >test-cf") == 0); # Handle comparison failure - print "** Comparison of $mf with $sf failed"; + print "** Comparison of $mf with $sf_current failed"; system("$more test-cf"); print "\n"; for (;;) { - interact("Continue, Retry, Update & retry, Quit? [Q] ", $force_update, $force_continue); + 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; - log_failure($log_failed_filename, $testno, $sf) if (/^c$/i && $force_continue); + log_failure($log_failed_filename, $testno, $sf_current) if (/^c$/i && $force_continue); return 0 if /^c$/i; return 1 if /^r$/i; - last if (/^u$/i); + last if (/^[us]$/i); } } # Update or delete the saved file, and give the appropriate return code. if (-s $mf) - { tests_exit(-1, "Failed to cp $mf $sf") if system("cp '$mf' '$sf'") != 0; } + { + my $sf = /^u/i ? $sf_current : $sf_flavour; + tests_exit(-1, "Failed to cp $mf $sf") if system("cp '$mf' '$sf'") != 0; + } else - { tests_exit(-1, "Failed to unlink $sf") if !unlink($sf); } + { + # 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); + } + else { + tests_exit(-1, "Failed to unlink $sf_current") if !unlink($sf_current); + } + } return 1; } @@ -1325,6 +1369,21 @@ $munges = 'optional_cert_hostnames' => { 'stderr' => '/in tls_verify_cert_hostnames\? no/' }, + 'loopback' => + { 'stdout' => 's/[[](127\.0\.0\.1|::1)]/[IP_LOOPBACK_ADDR]/' }, + + 'scanfile_size' => + { 'stdout' => 's/(Content-length:) \d\d\d/$1 ddd/' }, + + 'delay_1500' => + { 'stderr' => 's/(1[5-9]|23\d)\d\d msec/ssss msec/' }, + + 'tls_anycipher' => + { 'mainlog' => 's/ X=TLS\S+ / X=TLS_proto_and_cipher /' }, + + 'debug_pid' => + { 'stderr' => 's/(^\s{0,4}|(?<=Process )|(?<=child ))\d{1,5}/ppppp/g' }, + }; @@ -1342,7 +1401,7 @@ $munges = # [4] TRUE if this is a log file whose deliveries must be sorted # [5] an optional custom munge command # -# Arguments: Optionally, name of a custom munge to run. +# Arguments: Optionally, name of a single custom munge to run. # Returns: 0 if the output compared equal # 1 if re-run needed (files may have been updated) @@ -1889,7 +1948,8 @@ if (/^(ln|ls|du|mkdir|mkfifo|touch|cp|cat)\s/ || if (/^server\s+(.*)$/) { - $cmd = "./bin/server $server_opts $1 >>test-stdout-server"; + $pidfile = "$parm_cwd/aux-var/server-daemon.pid"; + $cmd = "./bin/server $server_opts -oP $pidfile $1 >>test-stdout-server"; print ">> $cmd\n" if ($debug); $server_pid = open SERVERCMD, "|$cmd" || tests_exit(-1, "Failed to run $cmd"); SERVERCMD->autoflush(1); @@ -1903,10 +1963,9 @@ if (/^server\s+(.*)$/) print SERVERCMD "++++\n"; # Send end to server; can't send EOF yet # because close() waits for the process. - # This gives the server time to get started; otherwise the next + # Interlock the server startup; otherwise the next # process may not find it there when it expects it. - - select(undef, undef, undef, 0.5); + while (! stat("$pidfile") ) { select(undef, undef, undef, 0.3); } return 3; } @@ -2082,6 +2141,7 @@ elsif (/^([A-Z_]+=\S+\s+)?(\d+)?\s*(sudo\s+)?exim(_\S+)?\s+(.*)$/) if ($cmd =~ /\s-DSERVER=server\s/ && $cmd !~ /\s-DNOTDAEMON\s/) { + $pidfile = "$parm_cwd/spool/exim-daemon.pid"; if ($debug) { printf ">> daemon: $cmd\n"; } run_system("sudo mkdir spool/log 2>/dev/null"); run_system("sudo chown $parm_eximuser:$parm_eximgroup spool/log"); @@ -2092,12 +2152,23 @@ elsif (/^([A-Z_]+=\S+\s+)?(\d+)?\s*(sudo\s+)?exim(_\S+)?\s+(.*)$/) # file is written to the spool directory, in case the Exim binary was # built with PID_FILE_PATH pointing somewhere else. - $cmd =~ s!\s-bd\s! -bdf -oP $parm_cwd/spool/exim-daemon.pid !; + if ($cmd =~ /\s-oP\s/) + { + ($pidfile = $cmd) =~ s/^.*-oP ([^ ]+).*$/$1/; + $cmd =~ s!\s-bd\s! -bdf !; + } + else + { + $pidfile = "$parm_cwd/spool/exim-daemon.pid"; + $cmd =~ s!\s-bd\s! -bdf -oP $pidfile !; + } print ">> |${cmd}-server\n" if ($debug); open DAEMONCMD, "|${cmd}-server" || tests_exit(-1, "Failed to run $cmd"); DAEMONCMD->autoflush(1); while (