Fix bug 1224.
[exim.git] / test / runtest
index 2af47eb62281788b19bb4acd5a21474cddea1070..ab87ab30e7df3a9da52b168c9a4bea35716a2df6 100755 (executable)
@@ -1,7 +1,5 @@
 #! /usr/bin/perl -w
 
 #! /usr/bin/perl -w
 
-# $Cambridge: exim/test/runtest,v 1.32 2009/11/19 18:51:11 nm4 Exp $
-
 ###############################################################################
 # This is the controlling script for the "new" test suite for Exim. It should #
 # be possible to export this suite for running on a wide variety of hosts, in #
 ###############################################################################
 # This is the controlling script for the "new" test suite for Exim. It should #
 # be possible to export this suite for running on a wide variety of hosts, in #
@@ -23,9 +21,9 @@ use Socket;
 
 # Start by initializing some global variables
 
 
 # Start by initializing some global variables
 
-$testversion = "4.70 (14-Oct-09)";
+$testversion = "4.72 (02-Jun-10)";
 
 
-$cf = "bin/cf";
+$cf = "bin/cf -exact";
 $cr = "\r";
 $debug = 0;
 $force_update = 0;
 $cr = "\r";
 $debug = 0;
 $force_update = 0;
@@ -299,6 +297,7 @@ $spid = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
 
 while(<IN>)
   {
 
 while(<IN>)
   {
+RESET_AFTER_EXTRA_LINE_READ:
   # Check for "*** truncated ***"
   $yield = 1 if /\*\*\* truncated \*\*\*/;
 
   # Check for "*** truncated ***"
   $yield = 1 if /\*\*\* truncated \*\*\*/;
 
@@ -312,7 +311,8 @@ while(<IN>)
   s?\Q$parm_cwd\E?TESTSUITE?g;
 
   # Replace the Exim version number (may appear in various places)
   s?\Q$parm_cwd\E?TESTSUITE?g;
 
   # Replace the Exim version number (may appear in various places)
-  s/Exim \d+\.\d+[\w-]*/Exim x.yz/i;
+  # patchexim should have fixed this for us
+  #s/(Exim) \d+\.\d+[\w_-]*/$1 x.yz/i;
 
   # Replace Exim message ids by a unique series
   s/((?:[^\W_]{6}-){2}[^\W_]{2})
 
   # Replace Exim message ids by a unique series
   s/((?:[^\W_]{6}-){2}[^\W_]{2})
@@ -441,7 +441,7 @@ while(<IN>)
     \d{4}-\d\d-\d\d\s\d\d:\d\d:\d\d/Exim statistics from <time> to <time>/x;
 
 
     \d{4}-\d\d-\d\d\s\d\d:\d\d:\d\d/Exim statistics from <time> to <time>/x;
 
 
-  # ======== Caller's login, uid, gid, home ========
+  # ======== Caller's login, uid, gid, home, gecos ========
 
   s/\Q$parm_caller_home\E/CALLER_HOME/g;   # NOTE: these must be done
   s/\b\Q$parm_caller\E\b/CALLER/g;         #       in this order!
 
   s/\Q$parm_caller_home\E/CALLER_HOME/g;   # NOTE: these must be done
   s/\b\Q$parm_caller\E\b/CALLER/g;         #       in this order!
@@ -453,6 +453,8 @@ while(<IN>)
   s/\buid=$parm_caller_uid\b/uid=CALLER_UID/g;
   s/\bgid=$parm_caller_gid\b/gid=CALLER_GID/g;
 
   s/\buid=$parm_caller_uid\b/uid=CALLER_UID/g;
   s/\bgid=$parm_caller_gid\b/gid=CALLER_GID/g;
 
+  s/\bname=$parm_caller_gecos\b/name=CALLER_GECOS/g;
+
   # When looking at spool files with -Mvh, we will find not only the caller
   # login, but also the uid and gid. It seems that $) in some Perls gives all
   # the auxiliary gids as well, so don't bother checking for that.
   # When looking at spool files with -Mvh, we will find not only the caller
   # login, but also the uid and gid. It seems that $) in some Perls gives all
   # the auxiliary gids as well, so don't bother checking for that.
@@ -548,6 +550,9 @@ while(<IN>)
   # The amount of space between "host" and the address in verification output
   # depends on the length of the host name. We therefore reduce it to one space
   # for all of them.
   # The amount of space between "host" and the address in verification output
   # depends on the length of the host name. We therefore reduce it to one space
   # for all of them.
+  # 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
 
   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+)/  host $1 $2/;
   s/^\s+(host\s\S+\s\S+)\s+(port=.*)/  host $1 $2/;
@@ -555,9 +560,10 @@ while(<IN>)
   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;
   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;
-  s/\b\Q$parm_ipv6\E\b/ip6:ip6:ip6:ip6:ip6:ip6:ip6:ip6/g;
+  s/(^|\W)\K\Q$parm_ipv6\E/ip6:ip6:ip6:ip6:ip6:ip6:ip6:ip6/g;
   s/\b\Q$parm_ipv4r\E\b/ip4-reverse/g;
   s/\b\Q$parm_ipv4r\E\b/ip4-reverse/g;
-  s/\b\Q$parm_ipv6r\E\b/ip6-reverse/g;
+  s/(^|\W)\K\Q$parm_ipv6r\E/ip6-reverse/g;
+  s/^(\s+host\s\S+\s+\[\S+\]) +$/$1 /;
 
 
   # ======== Test network IP addresses ========
 
 
   # ======== Test network IP addresses ========
@@ -587,7 +593,12 @@ while(<IN>)
 
   # ======== Output from ls ========
   # Different operating systems use different spacing on long output
 
   # ======== Output from ls ========
   # Different operating systems use different spacing on long output
-  s/ +/ /g if /^[-rwd]{10} /;
+  #s/ +/ /g if /^[-rwd]{10} /;
+  # (Bug 1226) SUSv3 allows a trailing printable char for modified access method control.
+  # Handle only the Gnu and MacOS space, dot, plus and at-sign.  A full [[:graph:]]
+  # unfortunately matches a non-ls linefull of dashes.
+  # Allow the case where we've already picked out the file protection bits.
+  s/^([-d](?:[-r][-w][-SsTtx]){3})[.+@]?( +|$)/\1 /;
 
 
   # ======== Message sizes =========
 
 
   # ======== Message sizes =========
@@ -676,6 +687,9 @@ while(<IN>)
   s/^\d\d\d(?=[PFS*])/ddd/;
 
 
   s/^\d\d\d(?=[PFS*])/ddd/;
 
 
+  # Lookups have a char which depends on the number of lookup types compiled in.
+  s%(?<!lsearch)[0-?]TESTSUITE/aux-fixed/%0TESTSUITE/aux-fixed/%g;
+
   # ==========================================================
   # Some munging is specific to the specific file types
 
   # ==========================================================
   # Some munging is specific to the specific file types
 
@@ -727,6 +741,42 @@ while(<IN>)
     next if /GnuTLS compile-time version: \d+[\.\d]+$/;
     next if /GnuTLS runtime version: \d+[\.\d]+$/;
 
     next if /GnuTLS compile-time version: \d+[\.\d]+$/;
     next if /GnuTLS runtime version: \d+[\.\d]+$/;
 
+    # drop openssl version strings
+    next if /OpenSSL compile-time version: OpenSSL \d+[\.\da-z]+/;
+    next if /OpenSSL runtime version: OpenSSL \d+[\.\da-z]+/;
+
+    # drop lookups
+    next if /^Lookups \(built-in\):/;
+    next if /^Loading lookup modules from/;
+    next if /^Loaded \d+ lookup modules/;
+    next if /^Total \d+ lookups/;
+
+    # drop compiler information
+    next if /^Compiler:/;
+
+    # and the ugly bit
+    # different libraries will have different numbers (possibly 0) of follow-up
+    # lines, indenting with more data
+    if (/^Library version:/) {
+      while (1) {
+       $_ = <IN>;
+       next if /^\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:/;
+
+    # 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
+    # be the case
+    next if /^changing group to \d+ failed: Operation not permitted/;
+
+    # We invoke Exim with -D, so we hit this new messag as of Exim 4.73:
+    next if /^macros_trusted overridden to true by whitelisting/;
+
     # We have to omit the localhost ::1 address so that all is well in
     # the IPv4-only case.
 
     # We have to omit the localhost ::1 address so that all is well in
     # the IPv4-only case.
 
@@ -1822,6 +1872,13 @@ autoflush STDOUT 1;
 print "Exim tester $testversion\n";
 
 
 print "Exim tester $testversion\n";
 
 
+##################################################
+#      Some tests check created file modes       #
+##################################################
+
+umask 022;
+
+
 ##################################################
 #       Check for the "less" command             #
 ##################################################
 ##################################################
 #       Check for the "less" command             #
 ##################################################
@@ -1993,7 +2050,13 @@ if ($parm_exim eq "")
 #          Find what is in the binary            #
 ##################################################
 
 #          Find what is in the binary            #
 ##################################################
 
-open(EXIMINFO, "$parm_exim -C confs/0000 -DDIR=$parm_cwd " .
+# deal with TRUSTED_CONFIG_LIST restrictions
+unlink("$parm_cwd/test-config") if -e "$parm_cwd/test-config";
+symlink("$parm_cwd/confs/0000", "$parm_cwd/test-config")
+  or die "Unable to link initial config into place: $!\n";
+
+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|") ||
   die "** Cannot run $parm_exim: $!\n";
 while(<EXIMINFO>)
                "-bP exim_user exim_group|") ||
   die "** Cannot run $parm_exim: $!\n";
 while(<EXIMINFO>)
@@ -2008,6 +2071,13 @@ if (defined $parm_eximuser)
   if ($parm_eximuser =~ /^\d+$/) { $parm_exim_uid = $parm_eximuser; }
     else { $parm_exim_uid = getpwnam($parm_eximuser); }
   }
   if ($parm_eximuser =~ /^\d+$/) { $parm_exim_uid = $parm_eximuser; }
     else { $parm_exim_uid = getpwnam($parm_eximuser); }
   }
+else
+  {
+  print "Unable to extract exim_user from binary.\n";
+  print "Check if Exim refused to run; if so, consider:\n";
+  print "  TRUSTED_CONFIG_LIST ALT_CONFIG_PREFIX WHITELIST_D_MACROS\n";
+  die "Failing to get information from binary.\n";
+  }
 
 if (defined $parm_eximgroup)
   {
 
 if (defined $parm_eximgroup)
   {
@@ -2015,7 +2085,7 @@ if (defined $parm_eximgroup)
     else { $parm_exim_gid = getgrnam($parm_eximgroup); }
   }
 
     else { $parm_exim_gid = getgrnam($parm_eximgroup); }
   }
 
-open(EXIMINFO, "$parm_exim -bV -C confs/0000 -DDIR=$parm_cwd |") ||
+open(EXIMINFO, "$parm_exim -bV -C $parm_cwd/test-config -DDIR=$parm_cwd |") ||
   die "** Cannot run $parm_exim: $!\n";
 
 print "-" x 78, "\n";
   die "** Cannot run $parm_exim: $!\n";
 
 print "-" x 78, "\n";
@@ -2028,7 +2098,10 @@ while (<EXIMINFO>)
 
   elsif (/^Size of off_t: (\d+)/)
     {
 
   elsif (/^Size of off_t: (\d+)/)
     {
+    print;
     $have_largefiles = 1 if $1 > 4;
     $have_largefiles = 1 if $1 > 4;
+    die "** Size of off_t > 32 which seems improbable, not running tests\n"
+        if ($1 > 32);
     }
 
   elsif (/^Support for: (.*)/)
     }
 
   elsif (/^Support for: (.*)/)
@@ -2039,7 +2112,7 @@ while (<EXIMINFO>)
     %parm_support = @temp;
     }
 
     %parm_support = @temp;
     }
 
-  elsif (/^Lookups: (.*)/)
+  elsif (/^Lookups \(built-in\): (.*)/)
     {
     print;
     @temp = split /(\s+)/, $1;
     {
     print;
     @temp = split /(\s+)/, $1;
@@ -2089,6 +2162,7 @@ while (<EXIMINFO>)
 close(EXIMINFO);
 print "-" x 78, "\n";
 
 close(EXIMINFO);
 print "-" x 78, "\n";
 
+unlink("$parm_cwd/test-config");
 
 ##################################################
 #    Check for SpamAssassin and ClamAV           #
 
 ##################################################
 #    Check for SpamAssassin and ClamAV           #
@@ -2359,18 +2433,23 @@ if (defined $parm_support{'Expand_dlfunc'} && !-e "bin/loaded")
 # Find the caller of this program.
 
 ($parm_caller,$pwpw,$parm_caller_uid,$parm_caller_gid,$pwquota,$pwcomm,
 # Find the caller of this program.
 
 ($parm_caller,$pwpw,$parm_caller_uid,$parm_caller_gid,$pwquota,$pwcomm,
- $pwgecos, $parm_caller_home) = getpwuid($>);
+ $parm_caller_gecos, $parm_caller_home) = getpwuid($>);
 
 $pwpw = $pwpw;       # Kill Perl warnings
 $pwquota = $pwquota;
 $pwcomm = $pwcomm;
 
 $pwpw = $pwpw;       # Kill Perl warnings
 $pwquota = $pwquota;
 $pwcomm = $pwcomm;
-$pwgecos = $pwgecos;
 
 $parm_caller_group = getgrgid($parm_caller_gid);
 
 print "Program caller is $parm_caller, whose group is $parm_caller_group\n";
 print "Home directory is $parm_caller_home\n";
 
 
 $parm_caller_group = getgrgid($parm_caller_gid);
 
 print "Program caller is $parm_caller, whose group is $parm_caller_group\n";
 print "Home directory is $parm_caller_home\n";
 
+unless (defined $parm_eximgroup)
+  {
+  print "Unable to derive \$parm_eximgroup.\n";
+  die "** ABANDONING.\n";
+  }
+
 print "You need to be in the Exim group to run these tests. Checking ...";
 
 if (`groups` =~ /\b\Q$parm_eximgroup\E\b/)
 print "You need to be in the Exim group to run these tests. Checking ...";
 
 if (`groups` =~ /\b\Q$parm_eximgroup\E\b/)
@@ -2609,6 +2688,12 @@ if (system("cp $parm_exim_dir/eximstats eximdir") != 0)
 
 print "Exim user is $parm_eximuser ($parm_exim_uid)\n";
 print "Exim group is $parm_eximgroup ($parm_exim_gid)\n";
 
 print "Exim user is $parm_eximuser ($parm_exim_uid)\n";
 print "Exim group is $parm_eximgroup ($parm_exim_gid)\n";
+
+if ($parm_caller_uid eq $parm_exim_uid) {
+  tests_exit(-1, "Exim user ($parm_eximuser,$parm_exim_uid) cannot be "
+                ."the same as caller ($parm_caller,$parm_caller_uid)");
+}
+
 print "The Exim user needs access to the test suite directory. Checking ...";
 
 if (($rc = system("sudo bin/checkaccess $parm_cwd/eximdir/exim $parm_eximuser $parm_eximgroup")) != 0)
 print "The Exim user needs access to the test suite directory. Checking ...";
 
 if (($rc = system("sudo bin/checkaccess $parm_cwd/eximdir/exim $parm_eximuser $parm_eximgroup")) != 0)
@@ -3182,4 +3267,4 @@ tests_exit(-1, "No runnable tests selected") if @test_list == 0;
 tests_exit(0);
 
 # End of runtest script
 tests_exit(0);
 
 # End of runtest script
-
+# vim: set sw=2 :