зеркало из https://github.com/microsoft/git.git
t7006: clean up SIGPIPE handling in trace2 tests
Comit c24b7f6736
(pager: test for exit code with and without SIGPIPE,
2021-02-02) introduced some tests that don't reliably generate SIGPIPE
where we expect it (i.e., when our pager doesn't read all of the output
from git-log).
There are two problems that somewhat cancel each other out.
First is that the output of git-log isn't very large (only around 800
bytes). So even if the pager doesn't read all of our output, it's racy
whether or not we'll actually get a SIGPIPE (we won't if we write all of
the output into the pipe buffer before the pager exits).
But we wrap git-log with test_terminal, which is supposed to propagate
the exit status of git-log. However, it doesn't always do so;
test_terminal will copy to stdout any lines that it got from our fake
pager, and it pipes to an empty command. So most of the time we are
seeing a SIGPIPE from test_terminal itself (though this is likewise
racy).
Let's try to make this more robust in two ways:
1. We'll put a commit with a huge message at the tip of history. Since
this is over a megabyte, it should fill the OS pipe buffer
completely, causing git-log to keep trying to write even after the
pager has exited.
2. We'll redirect the output of test_terminal to /dev/null. That means
it can never get SIGPIPE itself, and will always be giving us the
exit code from git-log.
These two changes reveal that one of the tests was looking for the wrong
behavior. If we try to start a pager that does not exist (according to
execve()), then the error propagates from start_command() back to the
pager code as an error, and we avoid redirecting git-log's stdout to the
broken pager entirely. Instead, it goes straight to the original stdout
(test_terminal's pty in this case), and we do not see a SIGPIPE at all.
So the test "git attempts to page to nonexisting pager command, gets
SIGPIPE" is checking the wrong outcome; it should be looking for a
successful exit (and was only confused by test_terminal's SIGPIPE).
There's a related test, "git discards nonexisting pager without
SIGPIPE", which sets the pager to a shell command which will read all
input and _then_ run a non-existing command. But that doesn't trigger
the same execve() behavior. We really do run the shell there and
redirect git-log's stdout to it. And the fact that the shell then exits
127 is not interesting. It is not different at that point than the
earlier test to check for "exit 1". So we can drop that test entirely.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
96bfb2d8ce
Коммит
f7991f01f2
|
@ -661,6 +661,13 @@ test_expect_success 'setup trace2' '
|
|||
export GIT_TRACE2_BRIEF
|
||||
'
|
||||
|
||||
test_expect_success 'setup large log output' '
|
||||
perl -e "
|
||||
print \"this is a long commit message\" x 50000
|
||||
" >commit-msg &&
|
||||
git commit --allow-empty -F commit-msg
|
||||
'
|
||||
|
||||
test_expect_success TTY 'git returns SIGPIPE on early pager exit' '
|
||||
test_when_finished "rm pager-used trace.normal" &&
|
||||
test_config core.pager ">pager-used; head -n 1; exit 0" &&
|
||||
|
@ -670,7 +677,7 @@ test_expect_success TTY 'git returns SIGPIPE on early pager exit' '
|
|||
|
||||
if test_have_prereq !MINGW
|
||||
then
|
||||
OUT=$( ((test_terminal git log; echo $? 1>&3) | :) 3>&1 ) &&
|
||||
OUT=$( ((test_terminal git log; echo $? 1>&3) >/dev/null) 3>&1 ) &&
|
||||
test_match_signal 13 "$OUT"
|
||||
else
|
||||
test_terminal git log
|
||||
|
@ -691,7 +698,7 @@ test_expect_success TTY 'git returns SIGPIPE on early pager non-zero exit' '
|
|||
|
||||
if test_have_prereq !MINGW
|
||||
then
|
||||
OUT=$( ((test_terminal git log; echo $? 1>&3) | :) 3>&1 ) &&
|
||||
OUT=$( ((test_terminal git log; echo $? 1>&3) >/dev/null) 3>&1 ) &&
|
||||
test_match_signal 13 "$OUT"
|
||||
else
|
||||
test_terminal git log
|
||||
|
@ -712,7 +719,7 @@ test_expect_success TTY 'git discards pager non-zero exit without SIGPIPE' '
|
|||
|
||||
if test_have_prereq !MINGW
|
||||
then
|
||||
OUT=$( ((test_terminal git log; echo $? 1>&3) | :) 3>&1 ) &&
|
||||
OUT=$( ((test_terminal git log; echo $? 1>&3) >/dev/null) 3>&1 ) &&
|
||||
test "$OUT" -eq 0
|
||||
else
|
||||
test_terminal git log
|
||||
|
@ -724,28 +731,7 @@ test_expect_success TTY 'git discards pager non-zero exit without SIGPIPE' '
|
|||
test_path_is_file pager-used
|
||||
'
|
||||
|
||||
test_expect_success TTY 'git discards nonexisting pager without SIGPIPE' '
|
||||
test_when_finished "rm pager-used trace.normal" &&
|
||||
test_config core.pager "wc >pager-used; does-not-exist" &&
|
||||
GIT_TRACE2="$(pwd)/trace.normal" &&
|
||||
export GIT_TRACE2 &&
|
||||
test_when_finished "unset GIT_TRACE2" &&
|
||||
|
||||
if test_have_prereq !MINGW
|
||||
then
|
||||
OUT=$( ((test_terminal git log; echo $? 1>&3) | :) 3>&1 ) &&
|
||||
test "$OUT" -eq 0
|
||||
else
|
||||
test_terminal git log
|
||||
fi &&
|
||||
|
||||
grep child_exit trace.normal >child-exits &&
|
||||
test_line_count = 1 child-exits &&
|
||||
grep " code:127 " child-exits &&
|
||||
test_path_is_file pager-used
|
||||
'
|
||||
|
||||
test_expect_success TTY 'git attempts to page to nonexisting pager command, gets SIGPIPE' '
|
||||
test_expect_success TTY 'git skips paging nonexisting command' '
|
||||
test_when_finished "rm trace.normal" &&
|
||||
test_config core.pager "does-not-exist" &&
|
||||
GIT_TRACE2="$(pwd)/trace.normal" &&
|
||||
|
@ -754,8 +740,8 @@ test_expect_success TTY 'git attempts to page to nonexisting pager command, gets
|
|||
|
||||
if test_have_prereq !MINGW
|
||||
then
|
||||
OUT=$( ((test_terminal git log; echo $? 1>&3) | :) 3>&1 ) &&
|
||||
test_match_signal 13 "$OUT"
|
||||
OUT=$( ((test_terminal git log; echo $? 1>&3) >/dev/null) 3>&1 ) &&
|
||||
test "$OUT" -eq 0
|
||||
else
|
||||
test_terminal git log
|
||||
fi &&
|
||||
|
@ -774,7 +760,7 @@ test_expect_success TTY 'git returns SIGPIPE on propagated signals from pager' '
|
|||
|
||||
if test_have_prereq !MINGW
|
||||
then
|
||||
OUT=$( ((test_terminal git log; echo $? 1>&3) | :) 3>&1 ) &&
|
||||
OUT=$( ((test_terminal git log; echo $? 1>&3) >/dev/null) 3>&1 ) &&
|
||||
test_match_signal 13 "$OUT"
|
||||
else
|
||||
test_terminal git log
|
||||
|
|
Загрузка…
Ссылка в новой задаче