From 35d437b7cc19d5126736e4820dcb38cfff051200 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 13 Sep 2023 00:44:49 +0200 Subject: tests/shell: kill running child processes when aborting "run-tests.sh" When aborting "run-tests.sh", child processes were left running. Kill them. It's surprisingly complicated to get this somewhat right. Do it by enabling monitor mode for each test call, so that they run in separate process groups and we can kill the entire group. Note that we cannot just `kill -- -$$`, because it's not clear who is in this process group. Also, we don't want to kill the `tee` process which handles our logging. Signed-off-by: Thomas Haller Signed-off-by: Florian Westphal --- tests/shell/run-tests.sh | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/tests/shell/run-tests.sh b/tests/shell/run-tests.sh index f20a2bec..cf17302f 100755 --- a/tests/shell/run-tests.sh +++ b/tests/shell/run-tests.sh @@ -424,12 +424,29 @@ if [ ! -x "$DIFF" ] ; then DIFF=true fi +declare -A JOBS_PIDLIST + cleanup_on_exit() { + pids_search='' + for pid in "${!JOBS_PIDLIST[@]}" ; do + kill -- "-$pid" &>/dev/null + pids_search="$pids_search\\|\\<$pid\\>" + done + if [ -n "$pids_search" ] ; then + pids_search="${pids_search:2}" + for i in {1..100}; do + ps xh -o pgrp | grep -q "$pids_search" || break + sleep 0.01 + done + fi if [ "$NFT_TEST_KEEP_LOGS" != y -a -n "$NFT_TEST_TMPDIR" ] ; then rm -rf "$NFT_TEST_TMPDIR" fi } -trap cleanup_on_exit EXIT + +trap 'exit 130' SIGINT +trap 'exit 143' SIGTERM +trap 'rc=$?; cleanup_on_exit; exit $rc' EXIT NFT_TEST_TMPDIR="$(mktemp --tmpdir="$_TMPDIR" -d "nft-test.$(date '+%Y%m%d-%H%M%S.%3N').XXXXXX")" || msg_error "Failure to create temp directory in \"$_TMPDIR\"" @@ -628,7 +645,6 @@ print_test_result() { } declare -A JOBS_TEMPDIR -declare -A JOBS_PIDLIST job_start() { local testfile="$1" @@ -656,7 +672,8 @@ job_wait() while [ "$JOBS_N_RUNNING" -gt 0 -a "$JOBS_N_RUNNING" -ge "$num_jobs" ] ; do wait -n -p JOBCOMPLETED local rc_got="$?" - testfile2="${JOBS_PIDLIST[$JOBCOMPLETED]}" + local testfile2="${JOBS_PIDLIST[$JOBCOMPLETED]}" + unset JOBS_PIDLIST[$JOBCOMPLETED] print_test_result "${JOBS_TEMPDIR["$testfile2"]}" "$testfile2" "$rc_got" ((JOBS_N_RUNNING--)) check_kmemleak @@ -677,8 +694,12 @@ for testfile in "${TESTS[@]}" ; do chmod 755 "$NFT_TEST_TESTTMPDIR" JOBS_TEMPDIR["$testfile"]="$NFT_TEST_TESTTMPDIR" - job_start "$testfile" "$TESTIDX" & - JOBS_PIDLIST[$!]="$testfile" + [[ -o monitor ]] && set_old_state='set -m' || set_old_state='set +m' + set -m + ( job_start "$testfile" "$TESTIDX" ) & + pid=$! + eval "$set_old_state" + JOBS_PIDLIST[$pid]="$testfile" ((JOBS_N_RUNNING++)) done -- cgit v1.2.3