X-Git-Url: https://git.exim.org/users/heiko/exim.git/blobdiff_plain/d1cebc7fe815c47a5e619d5de43bbf19707760ed..c039ce6150634eb51a120406b5b7784823430eb5:/test/runtest diff --git a/test/runtest b/test/runtest index d9aa97fa5..7fe0e5dae 100755 --- a/test/runtest +++ b/test/runtest @@ -14,6 +14,7 @@ ############################################################################### #use strict; +#use 5.010; use Errno; use FileHandle; use Socket; @@ -38,6 +39,7 @@ $gnutls_dh_bits_normal = 2236; $cf = "bin/cf -exact"; $cr = "\r"; $debug = 0; +$flavour = 'FOO'; $force_continue = 0; $force_update = 0; $log_failed_filename = "failed-summary.log"; @@ -45,7 +47,7 @@ $more = "less -XF"; $optargs = ""; $save_output = 0; $server_opts = ""; -$flavour = 'FOO'; +$valgrind = 0; $have_ipv4 = 1; $have_ipv6 = 1; @@ -81,13 +83,16 @@ $parm_port_d3 = 1227; # Additional for daemon $parm_port_d4 = 1228; # Additional for daemon # Manually set locale -$ENV{'LC_ALL'} = 'C'; +$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}; +my ($parm_configure_owner, $parm_configure_group); +my ($parm_ipv4, $parm_ipv6); +my $parm_hostname; ############################################################################### ############################################################################### @@ -348,7 +353,7 @@ $spid = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; # that are specific to certain file types, though there are also some of those # inline too. -while() +LINE: while() { RESET_AFTER_EXTRA_LINE_READ: # Custom munges @@ -426,7 +431,7 @@ RESET_AFTER_EXTRA_LINE_READ: # File descriptor numbers may vary s/^writing data block fd=\d+/writing data block fd=dddd/; - s/running as transport filter: write=\d+ read=\d+/running as transport filter: write=dddd read=dddd/; + s/(running as transport filter:) fd_write=\d+ fd_read=\d+/$1 fd_write=dddd fd_read=dddd/; # ======== Dumpdb output ======== @@ -652,6 +657,9 @@ RESET_AFTER_EXTRA_LINE_READ: s/waiting for children of \d+/waiting for children of pppp/; s/waiting for (\S+) \(\d+\)/waiting for $1 (pppp)/; + # The spool header file name varies with PID + s%^(Writing spool header file: .*/hdr).[0-9]{1,5}%$1.pppp%; + # ======== Port numbers ======== # Incoming port numbers may vary, but not in daemon startup line. @@ -1003,6 +1011,29 @@ RESET_AFTER_EXTRA_LINE_READ: while () { last if !/^\s/; } } + # 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; + + # SUPPORT_PROXY + next if /host in hosts_proxy\?/; + + # Experimental_International + next if / in smtputf8_advertise_hosts\? no \(option unset\)/; + + # Environment cleaning + next if /\w+ in keep_environment\? (yes|no)/; + + # Sizes vary with test hostname + 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/; + # 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 @@ -1024,20 +1055,6 @@ 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; - - # SUPPORT_PROXY - next if /host in hosts_proxy\?/; - - # 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. @@ -1052,6 +1069,7 @@ RESET_AFTER_EXTRA_LINE_READ: /^log selectors =/ || /^cwd=/ || /^Fixed never_users:/ || + /^Configure owner:/ || /^Size of off_t:/ ); @@ -1406,6 +1424,14 @@ $munges = 'sys_bindir' => { 'mainlog' => 's%/(usr/)?bin/%SYSBINDIR/%' }, + 'sync_check_data' => + { '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/' + }, }; @@ -1681,6 +1707,8 @@ my($commandnameref) = $_[3]; my($aux_info) = $_[4]; my($yield) = 1; +our %ENV = map { $_ => $ENV{$_} } grep { /^(?:USER|SHELL|PATH|TERM|EXIM_TEST_.*)$/ } keys %ENV; + if (/^(\d+)\s*$/) # Handle unusual return code { my($r) = $_[2]; @@ -1946,7 +1974,7 @@ if (/^sleep\s+(.*)$/) # Various Unix management commands are recognized if (/^(ln|ls|du|mkdir|mkfifo|touch|cp|cat)\s/ || - /^sudo (rmdir|rm|chown|chmod)\s/) + /^sudo\s(rmdir|rm|mv|chown|chmod)\s/) { run_system("$_ >>test-stdout 2>>test-stderr"); return 1; @@ -1967,6 +1995,7 @@ if (/^(ln|ls|du|mkdir|mkfifo|touch|cp|cat)\s/ || # command, triggered by $server_pid being non-zero. The server sends its output # to a different file. The variable $server_opts, if not empty, contains # options to disable IPv4 or IPv6 if necessary. +# This works because "server" swallows its stdin before waiting for a connection. if (/^server\s+(.*)$/) { @@ -2084,7 +2113,7 @@ if (/^client/ || /^(sudo\s+)?perl\b/) # not drop privilege when -C and -D options are present. To run the exim # command as root, we use sudo. -elsif (/^([A-Z_]+=\S+\s+)?(\d+)?\s*(sudo(?:\s+-u\s+(\w+))?\s+)?exim(_\S+)?\s+(.*)$/) +elsif (/^((?i:[A-Z\d_]+=\S+\s+)+)?(\d+)?\s*(sudo(?:\s+-u\s+(\w+))?\s+)?exim(_\S+)?\s+(.*)$/) { $args = $6; my($envset) = (defined $1)? $1 : ""; @@ -2145,7 +2174,10 @@ elsif (/^([A-Z_]+=\S+\s+)?(\d+)?\s*(sudo(?:\s+-u\s+(\w+))?\s+)?exim(_\S+)?\s+(.* $args =~ s/(?:^|\s)-d\S*// if $optargs =~ /(?:^|\s)-d/; - $cmd = "$envset$sudo$parm_cwd/eximdir/exim$special$optargs " . + my $opt_valgrind = $valgrind ? "valgrind --leak-check=yes --suppressions=$parm_cwd/aux-fixed/valgrind.supp " : ""; + + $cmd = "$envset$sudo$opt_valgrind" . + "$parm_cwd/eximdir/exim$special$optargs " . "-DEXIM_PATH=$parm_cwd/eximdir/exim$special " . "-C $parm_cwd/test-config $args " . ">>test-stdout 2>>test-stderr"; @@ -2315,7 +2347,7 @@ return $yield; # Ran command and waited ############################################################################### ############################################################################### -# Here beginneth the Main Program ... +# Here begins the Main Program ... ############################################################################### ############################################################################### @@ -2345,7 +2377,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; @@ -2354,7 +2386,7 @@ $more = "more" if system("which less >/dev/null 2>&1") != 0; ################################################## print "You need to have sudo access to root to run these tests. Checking ...\n"; -if (system("sudo date >/dev/null") != 0) +if (system('sudo true >/dev/null') != 0) { die "** Test for sudo failed: testing abandoned.\n"; } @@ -2400,6 +2432,7 @@ while (@ARGV > 0 && $ARGV[0] =~ /^-/) if ($arg eq "-NOIPV4") { $have_ipv4 = 0; next; } if ($arg eq "-NOIPV6") { $have_ipv6 = 0; next; } if ($arg eq "-KEEP") { $save_output = 1; next; } + if ($arg eq "-VALGRIND") { $valgrind = 1; next; } if ($arg =~ /^-FLAVOU?R$/) { $flavour = shift; next; } } $optargs .= " $arg"; @@ -2533,9 +2566,22 @@ open(EXIMINFO, "$parm_exim -d -C $parm_cwd/test-config -DDIR=$parm_cwd " . die "** Cannot run $parm_exim: $!\n"; while() { + if (my ($version) = /^Exim version (\S+)/) { + my $git = `git describe --dirty=-XX --match 'exim-4*'`; + if (defined $git and $? == 0) { + chomp $git; + $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" + if not $version eq $git; + } + } $parm_eximuser = $1 if /^exim_user = (.*)$/; $parm_eximgroup = $1 if /^exim_group = (.*)$/; $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/; } close(EXIMINFO); @@ -2587,6 +2633,14 @@ else die "Unable to check the TRUSTED_CONFIG_LIST, seems to be empty?\n"; } +die "CONFIGURE_OWNER ($parm_configure_owner) does not match the user invoking $0 ($>)\n" + if $parm_configure_owner != $>; + +die "CONFIGURE_GROUP ($parm_configure_group) does not match the group invoking $0 ($))\n" + if 0020 & (stat "$parm_cwd/test-config")[2] + and $parm_configure_group != $); + + open(EXIMINFO, "$parm_exim -d-all+transport -bV -C $parm_cwd/test-config -DDIR=$parm_cwd |") || die "** Cannot run $parm_exim: $!\n"; @@ -2985,38 +3039,29 @@ else # Find this host's IP addresses - there may be many, of course, but we keep # one of each type (IPv4 and IPv6). -$parm_ipv4 = ""; -$parm_ipv6 = ""; - -$local_ipv4 = ""; -$local_ipv6 = ""; - -open(IFCONFIG, "ifconfig -a|") || die "** Cannot run \"ifconfig\": $!\n"; -while (($parm_ipv4 eq "" || $parm_ipv6 eq "") && ($_ = )) +open(IFCONFIG, 'ip address|') # show *all*, addresses w/o label + or open(IFCONFIG, 'ifconfig -a|') # probably skips addresses w/o label + or die "** Cannot run 'ifconfig' or 'ip address': $!\n"; +while (not ($parm_ipv4 and $parm_ipv6) and defined($_ = )) { - my($ip); - if ($parm_ipv4 eq "" && - $_ =~ /^\s*inet(?:\saddr)?:?\s?(\d+\.\d+\.\d+\.\d+)\s/i) + if (not $parm_ipv4 and /^\s*inet(?:\saddr)?:?\s?(\d+\.\d+\.\d+\.\d+)(?:\/\d+)\s/i) { - $ip = $1; - next if ($ip =~ /^127\./ || $ip =~ /^10\./); - $parm_ipv4 = $ip; + next if $1 =~ /^(?:127|10)\./; + $parm_ipv4 = $1; } - if ($parm_ipv6 eq "" && - $_ =~ /^\s*inet6(?:\saddr)?:?\s?([abcdef\d:]+)/i) + if (not $parm_ipv6 and /^\s*inet6(?:\saddr)?:?\s?([abcdef\d:]+)(?:\/\d+)/i) { - $ip = $1; - next if ($ip eq "::1" || $ip =~ /^fe80/i); - $parm_ipv6 = $ip; + next if $1 eq '::1' or $1 =~ /^fe80/i; + $parm_ipv6 = $1; } } close(IFCONFIG); # Use private IP addresses if there are no public ones. -$parm_ipv4 = $local_ipv4 if ($parm_ipv4 eq ""); -$parm_ipv6 = $local_ipv6 if ($parm_ipv6 eq ""); +$parm_ipv4 = '172.10.10.1' if not defined $parm_ipv4; +$parm_ipv6 = 'fd0a:c2ea:abfa::1' if not defined $parm_ipv6; # If either type of IP address is missing, we need to set the value to # something other than empty, because that wrecks the substitutions. The value @@ -3026,7 +3071,7 @@ $parm_ipv6 = $local_ipv6 if ($parm_ipv6 eq ""); # of IPV4 or IPv6 can be simulated by command options, which force $have_ipv4 # and $have_ipv6 false. -if ($parm_ipv4 eq "") +if (not $parm_ipv4) { $have_ipv4 = 0; $parm_ipv4 = ""; @@ -3042,7 +3087,7 @@ else $parm_running{"IPv4"} = " "; } -if ($parm_ipv6 eq "") +if (not $parm_ipv6) { $have_ipv6 = 0; $parm_ipv6 = ""; @@ -3090,8 +3135,9 @@ if ($parm_ipv6 =~ /^[\da-f]/) # Find the host name, fully qualified. 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" if $parm_hostname eq ""; +$parm_hostname = "no.host.name.found" unless defined $parm_hostname and length $parm_hostname; print "Hostname is $parm_hostname\n"; if ($parm_hostname !~ /\./) @@ -3703,8 +3749,9 @@ foreach $test (@test_list) my($subtest_startline) = $lineno; - # Now run the command. The function returns 0 if exim was run and waited - # for, 1 if any other command was run and waited for, and 2 if a command + # Now run the command. The function returns 0 for an inline command, + # 1 if a non-exim command was run and waited for, 2 if an exim + # command was run and waited for, and 3 if a command # was run and not waited for (usually a daemon or server startup). my($commandname) = ""; @@ -3769,7 +3816,7 @@ $0 = "[runtest $testno]"; log_failure($log_failed_filename, $testno, "exit code unexpected") if (/^c$/i && $force_continue); if ($force_continue) { - print "stderr tail:\n"; + print "\nstderr tail:\n"; print "===================\n"; system("tail -20 test-stderr"); print "===================\n";