Skip to content

Commit 0d9b0d7

Browse files
szedergitster
authored andcommitted
t9300-fast-import: don't hang if background fast-import exits too early
The five tests checking 'git fast-import's checkpoint handling in 't9300-fast-import.sh', all with the prefix "V:" in their test description, can hang indefinitely if 'git fast-import' unexpectedly dies early in any of these tests. These five tests run 'git fast-import' in the background, while feeding instructions to its standard input through a fifo (fd 8) from a background subshell, and reading and verifying its standard output through another fifo (fd 9) in the test script's main shell process. This "reading and verifying" is basically a 'while read ...' shell loop iterating until 'git fast-import' outputs the expected line, ignoring any other output. This doesn't work very well when 'git fast-import' dies before printing that particular line, because the 'read' builtin doesn't get EOF after the death of 'git fast-import', as their input and output are not connected directly but through a fifo. Consequently, that 'read' hangs waiting for the next line from the already dead 'git fast-import', leaving the test script and in turn the whole test suite hanging. Avoid this hang by checking whether the background 'git fast-import' process exited unexpectedly early, and interrupt the 'while read' loop if it did. We have to jump through some hoops to achive that, though: - Start the background 'git fast-import' in another background subshell, which then: - prints the PID of that 'git fast-import' process to the fifo, to be read by the main shell process, so it will know which process to kill when the test is finished. - waits until that 'git fast-import' process exits. If it does exit, then report its exit code, and write a message to the fifo used for 'git fast-import's standard output, thus un-block the 'read' builtin in the main shell process. - Modify that 'while read' loop to break the loop upon seeing that message, and fail the test in the usual way. - Once the test is finished kill that background subshell as well, and do so before killing the background 'git fast-import'. Otherwise the background 'git fast-import' and subshell processes would die racily, and if 'git fast-import' were to die sooner, then we might get some undesired and potentially confusing messages in the test's output. Signed-off-by: SZEDER Gábor <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 21f5762 commit 0d9b0d7

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

t/t9300-fast-import.sh

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3164,12 +3164,21 @@ background_import_then_checkpoint () {
31643164
exec 9<>V.output
31653165
rm V.output
31663166

3167-
git fast-import $options <&8 >&9 &
3168-
fi_pid=$!
3167+
(
3168+
git fast-import $options <&8 >&9 &
3169+
echo $! >&9
3170+
wait $!
3171+
echo >&2 "background fast-import terminated too early with exit code $?"
3172+
# Un-block the read loop in the main shell process.
3173+
echo >&9 UNEXPECTED
3174+
) &
3175+
sh_pid=$!
3176+
read fi_pid <&9
31693177
# We don't mind if fast-import has already died by the time the test
31703178
# ends.
31713179
test_when_finished "
31723180
exec 8>&-; exec 9>&-;
3181+
kill $sh_pid && wait $sh_pid
31733182
kill $fi_pid && wait $fi_pid
31743183
true"
31753184

@@ -3190,6 +3199,9 @@ background_import_then_checkpoint () {
31903199
then
31913200
error=0
31923201
break
3202+
elif test "$output" = "UNEXPECTED"
3203+
then
3204+
break
31933205
fi
31943206
# otherwise ignore cruft
31953207
echo >&2 "cruft: $output"

0 commit comments

Comments
 (0)