git p4 test: clean up the p4d cleanup functions

Confusingly, the 'git p4' tests used two cleanup functions:

  - 'kill_p4d' was run in the last test before 'test_done', and it not
    only killed 'p4d', but it killed the watchdog process, and cleaned
    up after 'p4d' as well by removing all directories used by the P4
    daemon and client.

    This cleanup is not necessary right before 'test_done', because
    the whole trash directory is about to get removed anyway, but it
    is necessary in 't9801-git-p4-branch.sh', which uses 'kill_p4d' to
    stop 'p4d' before re-starting it in the middle of the test script.

  - 'cleanup' was run in the trap on EXIT, and it killed 'p4d', but,
    it didn't kill the watchdog process, and, contrarily to its name,
    didn't perform any cleanup whatsoever.

Make it clearer what's going on by renaming and simplifying the
cleanup functions, so in the end we'll have:

  - 'stop_p4d_and_watchdog' replaces 'cleanup' as it will try to live
    up to its name and stop both the 'p4d' and the watchdog processes,
    and as the sole function registered with 'test_atexit' it will be
    responsible for no leaving any stray processes behind after 'git p4'
    tests were finished or interrupted.

  - 'stop_and_cleanup_p4d' replaces 'kill_p4d' as it will stop 'p4d'
    (and the watchdog) and remove all directories used by the P4
    daemon and cliean, so it can be used mid-script to stop and then
    re-start 'p4d'.

Note that while 'cleanup' sent a single SIGKILL to 'p4d', 'kill_p4d'
was quite brutal, as it first sent SIGTERM to the daemon repeatedly,
either until its pid disappeared or until a given timeout was up, and
then it sent SIGKILL repeatedly, for good measure.  This is overkill
(pardon the pun): a single SIGKILL should be able to take down any
process in a sensible state, and if a process were to somehow end up
stuck in the dreaded uninterruptible sleep state then even repeated
SIGKILLs won't bring immediate help.  So ditch all the repeated
SIGTERM/SIGKILL parts, and use a single SIGKILL to stop 'p4d', and
make sure that there are no races between asynchron signal delivery
and subsequent restart of 'p4d' by waiting for it to die.

With this change the 'retry_until_fail' helper has no callers left,
remove it.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
SZEDER Gábor 2019-03-13 13:24:16 +01:00 committed by Junio C Hamano
parent 99e37c2560
commit 07353d9042
2 changed files with 12 additions and 28 deletions

View file

@ -67,12 +67,8 @@ cli="$TRASH_DIRECTORY/cli"
git="$TRASH_DIRECTORY/git" git="$TRASH_DIRECTORY/git"
pidfile="$TRASH_DIRECTORY/p4d.pid" pidfile="$TRASH_DIRECTORY/p4d.pid"
# Sometimes "prove" seems to hang on exit because p4d is still running stop_p4d_and_watchdog () {
cleanup () { kill -9 $p4d_pid $watchdog_pid
if test -f "$pidfile"
then
kill -9 $(cat "$pidfile") 2>/dev/null && exit 255
fi
} }
# git p4 submit generates a temp file, which will # git p4 submit generates a temp file, which will
@ -87,7 +83,7 @@ start_p4d () {
# Don't register and then run the same atexit handlers several times. # Don't register and then run the same atexit handlers several times.
if test -z "$registered_stop_p4d_atexit_handler" if test -z "$registered_stop_p4d_atexit_handler"
then then
test_atexit 'kill_p4d; cleanup' test_atexit 'stop_p4d_and_watchdog'
registered_stop_p4d_atexit_handler=AlreadyDone registered_stop_p4d_atexit_handler=AlreadyDone
fi fi
@ -100,6 +96,7 @@ start_p4d () {
echo $! >"$pidfile" echo $! >"$pidfile"
} }
) && ) &&
p4d_pid=$(cat "$pidfile")
# This gives p4d a long time to start up, as it can be # This gives p4d a long time to start up, as it can be
# quite slow depending on the machine. Set this environment # quite slow depending on the machine. Set this environment
@ -107,14 +104,13 @@ start_p4d () {
# an automated test setup. If the p4d process dies, that # an automated test setup. If the p4d process dies, that
# will be caught with the "kill -0" check below. # will be caught with the "kill -0" check below.
i=${P4D_START_PATIENCE:-300} i=${P4D_START_PATIENCE:-300}
pid=$(cat "$pidfile")
timeout=$(($(time_in_seconds) + $P4D_TIMEOUT)) timeout=$(($(time_in_seconds) + $P4D_TIMEOUT))
while true while true
do do
if test $(time_in_seconds) -gt $timeout if test $(time_in_seconds) -gt $timeout
then then
kill -9 $pid kill -9 $p4d_pid
exit 1 exit 1
fi fi
sleep 1 sleep 1
@ -131,7 +127,7 @@ start_p4d () {
break break
fi fi
# fail if p4d died # fail if p4d died
kill -0 $pid 2>/dev/null || break kill -0 $p4d_pid 2>/dev/null || break
echo waiting for p4d to start echo waiting for p4d to start
sleep 1 sleep 1
i=$(( $i - 1 )) i=$(( $i - 1 ))
@ -178,22 +174,10 @@ retry_until_success () {
done done
} }
retry_until_fail () { stop_and_cleanup_p4d () {
timeout=$(($(time_in_seconds) + $RETRY_TIMEOUT)) kill -9 $p4d_pid $watchdog_pid
until ! "$@" 2>/dev/null || test $(time_in_seconds) -gt $timeout wait $p4d_pid
do rm -rf "$db" "$cli" "$pidfile"
sleep 1
done
}
kill_p4d () {
pid=$(cat "$pidfile")
retry_until_fail kill $pid
retry_until_fail kill -9 $pid
# complain if it would not die
test_must_fail kill $pid >/dev/null 2>&1 &&
rm -rf "$db" "$cli" "$pidfile" &&
retry_until_fail kill -9 $watchdog_pid
} }
cleanup_git () { cleanup_git () {

View file

@ -151,7 +151,7 @@ test_expect_success 'import depot, branch detection, branchList branch definitio
' '
test_expect_success 'restart p4d' ' test_expect_success 'restart p4d' '
kill_p4d && stop_and_cleanup_p4d &&
start_p4d start_p4d
' '
@ -505,7 +505,7 @@ test_expect_success 'use-client-spec detect-branches skips files in branches' '
' '
test_expect_success 'restart p4d' ' test_expect_success 'restart p4d' '
kill_p4d && stop_and_cleanup_p4d &&
start_p4d start_p4d
' '