X-Git-Url: https://git.exim.org/users/heiko/exim.git/blobdiff_plain/05faa88b01df9ab61a0f41ffd94b815bf101b6a4..8d42c8364882bf2d743a5b876d6df741b6d67e40:/test/runtest diff --git a/test/runtest b/test/runtest index c6d9c729e..7fc658a20 100755 --- a/test/runtest +++ b/test/runtest @@ -14,11 +14,12 @@ ############################################################################### #use strict; -require Cwd; use Errno; use FileHandle; use Socket; use Time::Local; +use Cwd; +use File::Basename; # Start by initializing some global variables @@ -43,6 +44,7 @@ $more = "less -XF"; $optargs = ""; $save_output = 0; $server_opts = ""; +$flavour = 'FOO'; $have_ipv4 = 1; $have_ipv6 = 1; @@ -413,6 +415,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/; @@ -703,6 +706,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 +737,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)/; @@ -844,7 +850,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 ======== @@ -1011,6 +1016,9 @@ RESET_AFTER_EXTRA_LINE_READ: 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 +1035,8 @@ RESET_AFTER_EXTRA_LINE_READ: /^Fixed never_users:/ || /^Size of off_t:/ ); + + } next; @@ -1122,7 +1132,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)); @@ -1189,7 +1205,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 +1216,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 +1278,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 +1356,12 @@ $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/' }, + }; @@ -1342,7 +1379,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) @@ -2193,6 +2230,15 @@ return $yield; # Ran command and waited autoflush STDOUT 1; print "Exim tester $testversion\n"; +# extend the PATH with .../sbin +# we map all (.../bin) to (.../sbin:.../bin) +$ENV{PATH} = do { + my %seen = map { $_, 1 } split /:/, $ENV{PATH}; + join ':' => map { m{(.*)/bin$} + ? ( $seen{"$1/sbin"} ? () : ("$1/sbin"), $_) + : ($_) } + split /:/, $ENV{PATH}; +}; ################################################## # Some tests check created file modes # @@ -2230,9 +2276,10 @@ else ################################################## # If the first character of the first argument is '/', the argument is taken -# as the path to the binary. +# 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 && $ARGV[0] =~ m?^/?)? shift @ARGV : ""; +$parm_exim = (@ARGV > 0 && (-x $ARGV[0] or $ARGV[0] =~ m?^/?))? Cwd::abs_path(shift @ARGV) : ""; print "Exim binary is $parm_exim\n" if $parm_exim ne ""; @@ -2259,6 +2306,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 =~ /^-FLAVOU?R$/) { $flavour = shift; next; } } $optargs .= " $arg"; } @@ -2382,12 +2430,13 @@ symlink("$parm_cwd/confs/0000", "$parm_cwd/test-config") print("Probing with config file: $parm_cwd/test-config\n"); open(EXIMINFO, "$parm_exim -d -C $parm_cwd/test-config -DDIR=$parm_cwd " . - "-bP exim_user exim_group|") || + "-bP exim_user exim_group 2>&1|") || die "** Cannot run $parm_exim: $!\n"; while() { $parm_eximuser = $1 if /^exim_user = (.*)$/; $parm_eximgroup = $1 if /^exim_group = (.*)$/; + $parm_trusted_config_list = $1 if /^TRUSTED_CONFIG_LIST:.*?"(.*?)"$/; } close(EXIMINFO); @@ -2410,6 +2459,34 @@ if (defined $parm_eximgroup) else { $parm_exim_gid = getgrnam($parm_eximgroup); } } +# check the permissions on the TRUSTED_CONFIG_LIST +if (defined $parm_trusted_config_list) + { + die "TRUSTED_CONFIG_LIST: $parm_trusted_config_list: $!\n" + if not -f $parm_trusted_config_list; + + die "TRUSTED_CONFIG_LIST $parm_trusted_config_list must not be world writable!\n" + if 02 & (stat _)[2]; + + die sprintf "TRUSTED_CONFIG_LIST: $parm_trusted_config_list %d is group writable, but not owned by group '%s' or '%s'.\n", + (stat _)[1], + scalar(getgrgid 0), scalar(getgrgid $>) + if (020 & (stat _)[2]) and not ((stat _)[5] == $> or (stat _)[5] == 0); + + die sprintf "TRUSTED_CONFIG_LIST: $parm_trusted_config_list is not owned by user '%s' or '%s'.\n", + scalar(getpwuid 0), scalar(getpwuid $>) + if (not (-o _ or (stat _)[4] == 0)); + + open(TCL, $parm_trusted_config_list) or die "Can't open $parm_trusted_config_list: $!\n"; + my $test_config = getcwd() . '/test-config'; + die "Can't find '$test_config' in TRUSTED_CONFIG_LIST $parm_trusted_config_list." + if not grep { /^$test_config$/ } ; + } +else + { + die "Unable to check the TRUSTED_CONFIG_LIST, seems to be empty?\n"; + } + open(EXIMINFO, "$parm_exim -bV -C $parm_cwd/test-config -DDIR=$parm_cwd |") || die "** Cannot run $parm_exim: $!\n"; @@ -3057,7 +3134,7 @@ else # because the current binary does not support the right facilities, and also # those that are outside the numerical range selected. -print "\nTest range is $test_start to $test_end\n"; +print "\nTest range is $test_start to $test_end (flavour $flavour)\n"; print "Omitting \${dlfunc expansion tests (loadable module not present)\n" if $dlfunc_deleted; print "Omitting dbm tests (unable to copy exim_dbmbuild)\n" @@ -3163,7 +3240,7 @@ for ($i = 0; $i < @test_dirs; $i++) foreach $test (@testlist) { - next if $test !~ /^\d{4}$/; + next if $test !~ /^\d{4}(?:\.\d+)?$/; next if $test < $test_start || $test > $test_end; push @test_list, "$testdir/$test"; } @@ -3349,7 +3426,7 @@ foreach $test (@test_list) local($lineno) = 0; local($commandno) = 0; local($subtestno) = 0; - local($testno) = substr($test, -4); + (local $testno = $test) =~ s|.*/||; local($sortlog) = 0; my($gnutls) = 0; @@ -3405,6 +3482,7 @@ foreach $test (@test_list) $stdout_skip = 0; $rmfiltertest = 0; $is_ipv6test = 0; + $TEST_STATE->{munge} = ""; # Remove the associative arrays used to hold checked mail files and msglogs