summary refs log tree commit diff
diff options
context:
space:
mode:
authorThiago Jung Bauermann <bauermann@kolabnow.com>2022-06-14 00:32:23 -0300
committerLudovic Courtès <ludo@gnu.org>2022-06-17 15:31:33 +0200
commit861108ca6ab5f363a33fda12de579c140691d5d7 (patch)
treebe17db574ec5fa5407d9495506b9cfe9f8973ac2
parent37d5bd0b3158a8cb2995d340172c8105b9065885 (diff)
downloadguix-861108ca6ab5f363a33fda12de579c140691d5d7.tar.gz
gnu: public-inbox: Fixes to allow the testsuite to run
This patch makes the public-inbox testsuite pass. Some tests are skipped,
so the test coverage could likely be increased with more massaging.

Perhaps the most significant change is using tini to run the testsuite so
that the testsuite's sub-processes are reaped. The ‘check’ phase is based on
the one from the mutter package. Thanks to Maxim Cournoyer for pointing out
this solution.

* gnu/packages/patches/public-inbox-fix-spawn-test.patch: New file.
* gnu/local.mk (dist_patch_DATA): Add new patch.
* gnu/packages/mail.scm (public-inbox)[source]: Add new patch.
[arguments]<#:tests?>: Remove argument.
<#:imported-modules>: Add argument.
<#:modules>: Likewise.
<#:phases>{qualify-paths}: Substitute path for ‘/bin/cp’.
{pre-check}: Don't skip httpd-unix.t test.  Remove unnecessary path
substitutions for “env” and “/bin/sh”.
{check}: Replace with custom version that launches the tests under tini.
[native-inputs]: Add tini.

Signed-off-by: Ludovic Courtès <ludo@gnu.org>
-rw-r--r--gnu/local.mk1
-rw-r--r--gnu/packages/mail.scm60
-rw-r--r--gnu/packages/patches/public-inbox-fix-spawn-test.patch43
3 files changed, 91 insertions, 13 deletions
diff --git a/gnu/local.mk b/gnu/local.mk
index 576c1a3eb6..e38eb05205 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1651,6 +1651,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/psm-disable-memory-stats.patch		\
   %D%/packages/patches/psm-ldflags.patch			\
   %D%/packages/patches/psm-repro.patch				\
+  %D%/packages/patches/public-inbox-fix-spawn-test.patch	\
   %D%/packages/patches/pulseaudio-fix-mult-test.patch		\
   %D%/packages/patches/pulseaudio-longer-test-timeout.patch	\
   %D%/packages/patches/pulseview-qt515-compat.patch		\
diff --git a/gnu/packages/mail.scm b/gnu/packages/mail.scm
index 47a62b00de..5d2fbdeff5 100644
--- a/gnu/packages/mail.scm
+++ b/gnu/packages/mail.scm
@@ -88,6 +88,7 @@
   #:use-module (gnu packages django)
   #:use-module (gnu packages dns)
   #:use-module (gnu packages docbook)
+  #:use-module (gnu packages docker)
   #:use-module (gnu packages documentation)
   #:use-module (gnu packages emacs)
   #:use-module (gnu packages enchant)
@@ -4085,10 +4086,16 @@ Git and exports them in maildir format or to an MDA through a pipe.")
              (sha256
               (base32
                "0xni1l54v1z3p0zb52807maay0yqabp8jgf5iras5zmhgjyk3swz"))
-             (file-name (git-file-name name version))))
+             (file-name (git-file-name name version))
+             (patches (search-patches "public-inbox-fix-spawn-test.patch"))))
     (build-system perl-build-system)
     (arguments
-     '(#:tests? #f
+     `(#:imported-modules (,@%perl-build-system-modules
+                           (guix build syscalls))
+       #:modules ((guix build perl-build-system)
+                  (guix build syscalls)
+                  (guix build utils)
+                  (ice-9 match))
        #:phases
        (modify-phases %standard-phases
          (add-before 'configure 'qualify-paths
@@ -4097,18 +4104,45 @@ Git and exports them in maildir format or to an MDA through a pipe.")
              (substitute* "lib/PublicInbox/Xapcmd.pm"
                (("'xapian-compact'")
                 (format #f "'~a'" (search-input-file inputs
-                                                     "/bin/xapian-compact"))))))
+                                                     "/bin/xapian-compact"))))
+             (substitute* "lib/PublicInbox/TestCommon.pm"
+               ;; This is only used for tests, but get it from ‘inputs’ so
+               ;; that cross builds won't hold a reference to a package built
+               ;; for another architecture.
+               (("/bin/cp") (search-input-file inputs "/bin/cp")))))
          (add-before 'check 'pre-check
            (lambda _
-             (substitute* "t/spawn.t"
-               (("\\['env'\\]") (string-append "['" (which "env") "']")))
-             (substitute* "t/ds-leak.t"
-               (("/bin/sh") (which "sh")))
-             (invoke "./certs/create-certs.perl")
-             ;; XXX: This test fails due to zombie process is not reaped by
-             ;; the builder.
-             (substitute* "t/httpd-unix.t"
-               (("^SKIP: \\{") "SKIP: { skip('Guix');"))))
+             (invoke "./certs/create-certs.perl")))
+         (replace 'check
+           (lambda* (#:key target
+                     (tests? (not target)) (test-flags '())
+                     #:allow-other-keys)
+             (if tests?
+                 (match (primitive-fork)
+                   (0                     ;child process
+                    ;; lei tests build UNIX domain sockets in the temporary
+                    ;; directory, but the path of those sockets can be at most
+                    ;; 108 chars and Guix' default value for the variables
+                    ;; below already use 47 chars. Use the shortest temporary
+                    ;; path possible to avoid hitting the limit.
+                    (setenv "TEMP" "/tmp")
+                    (setenv "TEMPDIR" "/tmp")
+                    (setenv "TMP" "/tmp")
+                    (setenv "TMPDIR" "/tmp")
+
+                    ;; Use tini so that signals are properly handled and
+                    ;; doubly-forked processes get reaped; otherwise,
+                    ;; lei-daemon is kept as a zombie and the testsuite
+                    ;; fails thinking that it didn't quit as it should.
+                    (set-child-subreaper!)
+                    (apply execlp "tini" "--"
+                           "make" "check" test-flags))
+                   (pid
+                    (match (waitpid pid)
+                      ((_ . status)
+                       (unless (zero? status)
+                         (error "`make check' exited with status" status))))))
+                 (format #t "test suite not run~%"))))
          (add-after 'install 'wrap-programs
            (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((out (assoc-ref outputs "out")))
@@ -4127,7 +4161,7 @@ Git and exports them in maildir format or to an MDA through a pipe.")
                 (find-files (string-append out "/bin")))))))))
     (native-inputs
      (list ;; For testing.
-           lsof openssl))
+           lsof openssl tini))
     (inputs
      (list bash-minimal
            curl
diff --git a/gnu/packages/patches/public-inbox-fix-spawn-test.patch b/gnu/packages/patches/public-inbox-fix-spawn-test.patch
new file mode 100644
index 0000000000..2739b1974d
--- /dev/null
+++ b/gnu/packages/patches/public-inbox-fix-spawn-test.patch
@@ -0,0 +1,43 @@
+From 5593489d9c3ce22b1942f35c7ebb0e06fcf2bfa8 Mon Sep 17 00:00:00 2001
+From: Thiago Jung Bauermann <bauermann@kolabnow.com>
+Date: Fri, 10 Jun 2022 12:39:18 -0300
+Subject: [PATCH] t/spawn: Find invalid PID to try to join its process group
+
+In the container used to build packages of the GNU Guix distribution, PID 1
+runs as the same user as the test so this spawn that should fail actually
+succeeds.
+
+Fix the problem by going through different PIDs and picking one that
+either doesn't exist or we aren't allowed to signal.
+---
+
+This patch is taken from the public-inbox repository and will appear in the
+release after v1.8.
+
+ t/spawn.t | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/t/spawn.t b/t/spawn.t
+index 6168c1f6171c..5fc99a2a101c 100644
+--- a/t/spawn.t
++++ b/t/spawn.t
+@@ -24,7 +24,18 @@ SKIP: {
+ 	is(waitpid($pid, 0), $pid, 'waitpid succeeds on spawned process');
+ 	is($?, 0, 'true exited successfully');
+ 	pipe(my ($r, $w)) or BAIL_OUT;
+-	$pid = eval { spawn(['true'], undef, { pgid => 1, 2 => $w }) };
++
++	# Find invalid PID to try to join its process group.
++	my $wrong_pgid = 1;
++	for (my $i=0x7fffffff; $i >= 2; $i--) {
++		if (kill(0, $i) == 0) {
++			$wrong_pgid = $i;
++			last;
++		}
++	}
++
++	# Test spawn behavior when it can't join the requested process group.
++	$pid = eval { spawn(['true'], undef, { pgid => $wrong_pgid, 2 => $w }) };
+ 	close $w;
+ 	my $err = do { local $/; <$r> };
+ 	# diag "$err ($@)";