[02/11] t/lib-git-daemon: make sure to kill the 'git-daemon' process
diff mbox series

Message ID 20190313122419.2210-3-szeder.dev@gmail.com
State New
Headers show
Series
  • tests: introduce 'test_atexit'
Related show

Commit Message

SZEDER Gábor March 13, 2019, 12:24 p.m. UTC
After 'start_git_daemon' starts 'git daemon' (note the space in the
middle) in the background, it saves the background process' PID, so
the daemon can be stopped at the end of the test script.  However,
'git-daemon' is not a builtin but a dashed external command, which
means that the dashless 'git daemon' executes the dashed 'git-daemon'
command, and, consequently, the PID recorded is not the PID of the
"real" daemon process, but that of the main 'git' wrapper.  Now, if a
test script involving 'git daemon' is interrupted by ctrl-C, then only
the main 'git' process is stopped, but the real daemon process tends
to survive somehow, and keeps on running in the background
indefinitely, keeping the daemon's port to itself, and thus preventing
subsequent runs of the same test script.

Work this around by running 'git daemon' with the '--pidfile=...'
option to save the PID of the real daemon process, and kill that
process in 'stop_git_daemon' as well.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
---
 t/lib-git-daemon.sh | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Comments

Junio C Hamano March 14, 2019, 2:35 a.m. UTC | #1
SZEDER Gábor <szeder.dev@gmail.com> writes:

> After 'start_git_daemon' starts 'git daemon' (note the space in the
> middle) in the background, it saves the background process' PID, so
> the daemon can be stopped at the end of the test script.  However,
> 'git-daemon' is not a builtin but a dashed external command, which
> means that the dashless 'git daemon' executes the dashed 'git-daemon'
> command, and, consequently, the PID recorded is not the PID of the
> "real" daemon process, but that of the main 'git' wrapper.

Hmph.  execv_dashed_external() does not quite execv() but uses
run_command() and waits, which is the source of this issue.  It
feels almost possible to work it around by actually exec'ing,
though.

	/*
	 * If we fail because the command is not found, it is
	 * OK to return. Otherwise, we just pass along the status code,
	 * or our usual generic code if we were not even able to exec
	 * the program.
	 */
	status = run_command(&cmd);
	if (status >= 0)
		exit(status);
	else if (errno != ENOENT)
		exit(128);

would become

	... prepare args from cmd ...
	execv(...);
	if (errno != ENOENT)
		exit(128);

and if exec succeeds, the whole process will exit with the status of
dashed command, failing to exec for reasons other than ENOENT will
exit with 128 and ENOENT will continue returning.

> Now, if a
> test script involving 'git daemon' is interrupted by ctrl-C, then only
> the main 'git' process is stopped, but the real daemon process tends
> to survive somehow, and keeps on running in the background
> indefinitely, keeping the daemon's port to itself, and thus preventing
> subsequent runs of the same test script.
>
> Work this around by running 'git daemon' with the '--pidfile=...'
> option to save the PID of the real daemon process, and kill that
> process in 'stop_git_daemon' as well.

OK, so for the purpose of waiting and monitoring, we still use the
pid of the git potty that is running and waiting for the daemon, but
we'll send another signal to kill the daemon off.  Makes sense.

Patch
diff mbox series

diff --git a/t/lib-git-daemon.sh b/t/lib-git-daemon.sh
index 79db3b7ae5..6dab8766e7 100644
--- a/t/lib-git-daemon.sh
+++ b/t/lib-git-daemon.sh
@@ -31,6 +31,7 @@  fi
 test_set_port LIB_GIT_DAEMON_PORT
 
 GIT_DAEMON_PID=
+GIT_DAEMON_PIDFILE="$PWD"/daemon.pid
 GIT_DAEMON_DOCUMENT_ROOT_PATH="$PWD"/repo
 GIT_DAEMON_HOST_PORT=127.0.0.1:$LIB_GIT_DAEMON_PORT
 GIT_DAEMON_URL=git://$GIT_DAEMON_HOST_PORT
@@ -49,7 +50,7 @@  start_git_daemon() {
 	mkfifo git_daemon_output
 	${LIB_GIT_DAEMON_COMMAND:-git daemon} \
 		--listen=127.0.0.1 --port="$LIB_GIT_DAEMON_PORT" \
-		--reuseaddr --verbose \
+		--reuseaddr --verbose --pid-file="$GIT_DAEMON_PIDFILE" \
 		--base-path="$GIT_DAEMON_DOCUMENT_ROOT_PATH" \
 		"$@" "$GIT_DAEMON_DOCUMENT_ROOT_PATH" \
 		>&3 2>git_daemon_output &
@@ -88,8 +89,9 @@  stop_git_daemon() {
 	then
 		error "git daemon exited with status: $ret"
 	fi
+	kill "$(cat "$GIT_DAEMON_PIDFILE")" 2>/dev/null
 	GIT_DAEMON_PID=
-	rm -f git_daemon_output
+	rm -f git_daemon_output "$GIT_DAEMON_PIDFILE"
 }
 
 # A stripped-down version of a netcat client, that connects to a "host:port"