]> git.ipfire.org Git - thirdparty/git.git/commitdiff
t1800: test SIGPIPE with parallel hooks
authorJeff King <peff@peff.net>
Fri, 10 Apr 2026 09:06:08 +0000 (12:06 +0300)
committerJunio C Hamano <gitster@pobox.com>
Fri, 10 Apr 2026 14:58:55 +0000 (07:58 -0700)
We recently fixed a bug in commit 2226ffaacd (run_processes_parallel():
fix order of sigpipe handling, 2026-04-08) where a hook that caused us
to get SIGPIPE would accidentally trigger the run_processes_parallel()
cleanup handler killing the child processes.

For a single hook, this meant killing the already-exited hook. This case
was triggered by our tests, but was only a problem on some platforms.

But if you have multiple hooks running in parallel, this causes a
problem everywhere, since one hook failing to read its input would take
down all hooks. Now that we have parallel hook support, we can add a
test for this case. It should pass already, due to the existing fix.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
t/t1800-hook.sh

index 41b2b2c746006633b4847b7fdcfaf9ed74b6f4c3..0132e772e472e27fe2dba2e431f61068f4317629 100755 (executable)
@@ -1190,4 +1190,42 @@ test_expect_success 'friendly-name matching unknown event warns' '
        test_grep "same as its event" err
 '
 
+test_expect_success 'hooks in parallel that do not read input' '
+       # Add this to our $PATH to avoid having to write the whole trash
+       # directory into our config options, which would require quoting.
+       mkdir bin &&
+       PATH=$PWD/bin:$PATH &&
+
+       write_script bin/hook-fast <<-\EOF &&
+       # This hook does not read its input, so the parent process
+       # may see SIGPIPE if it is not ignored. It should happen
+       # relatively quickly.
+       exit 0
+       EOF
+
+       write_script bin/hook-slow <<-\EOF &&
+       # This hook is slow, so we expect it to still be running
+       # when the other hook has exited (and the parent has a pipe error
+       # writing to it).
+       #
+       # So we want to be slow enough that we expect this to happen, but not
+       # so slow that the test takes forever. 1 second is probably enough
+       # in practice (and if it is occasionally not on a loaded system, we
+       # will err on the side of having the test pass).
+       sleep 1
+       exit 0
+       EOF
+
+       git init --bare parallel.git &&
+       git -C parallel.git config hook.fast.command "hook-fast" &&
+       git -C parallel.git config hook.fast.event pre-receive &&
+       git -C parallel.git config hook.fast.parallel true &&
+       git -C parallel.git config hook.slow.command "hook-slow" &&
+       git -C parallel.git config hook.slow.event pre-receive &&
+       git -C parallel.git config hook.slow.parallel true &&
+       git -C parallel.git config hook.jobs 2 &&
+
+       git push ./parallel.git "+refs/heads/*:refs/heads/*"
+'
+
 test_done