All of lore.kernel.org
 help / color / mirror / Atom feed
From: Wander Lairson Costa <wander@redhat.com>
To: Clark Williams <williams@redhat.com>,
	John Kacur <jkacur@redhat.com>,
	linux-rt-users@vger.kernel.org
Cc: Juri Lelli <juri.lelli@redhat.com>,
	luffyluo@tencent.com, davidlt@rivosinc.com,
	Wander Lairson Costa <wander@redhat.com>
Subject: [[PATCH stalld] 24/33] tests: Introduce and adopt process helpers
Date: Wed, 20 May 2026 11:00:51 -0300	[thread overview]
Message-ID: <20260520140104.112142-25-wander@redhat.com> (raw)
In-Reply-To: <20260520140104.112142-1-wander@redhat.com>

Raw kill invocations scattered across the test suite obscure the
intent of the code. Using kill with signal zero acts as a liveness
check rather than signal delivery, while best-effort process cleanup
often requires ignoring errors.

This change introduces two dedicated helper functions to make these
patterns self-documenting. The process_alive function wraps the zero
signal check and preserves the exit code for use in conditionals and
loops. The send_signal function wraps standard signal delivery using
named signals like TERM or KILL, operating in a fire-and-forget
manner where failure is acceptable. These functions are kept separate
to distinguish predicates from cleanup actions, and both are exported
via export -f for availability in subshells.

Existing scripts including test_helpers.sh, test_boost_restoration.sh,
run_tests.sh, and test_starvation_detection.sh are updated to use
the new helpers in place of direct kill invocations.

Signed-off-by: Wander Lairson Costa <wander@redhat.com>
---
 tests/functional/test_boost_restoration.sh    |  2 +-
 tests/functional/test_starvation_detection.sh |  2 +-
 tests/helpers/test_helpers.sh                 | 60 +++++++++++--------
 tests/run_tests.sh                            |  6 +-
 4 files changed, 39 insertions(+), 31 deletions(-)

diff --git a/tests/functional/test_boost_restoration.sh b/tests/functional/test_boost_restoration.sh
index ddf3940..62c37b0 100755
--- a/tests/functional/test_boost_restoration.sh
+++ b/tests/functional/test_boost_restoration.sh
@@ -183,7 +183,7 @@ if wait_for_boost_detected "${STALLD_LOG}"; then
     sleep 1
 
     # Verify stalld is still running and didn't crash after task exit
-    assert_success "stalld handled task exit during boost gracefully" kill -0 ${STALLD_PID}
+    assert_success "stalld handled task exit during boost gracefully" process_alive ${STALLD_PID}
 
 else
     log "⚠ WARNING: No boost detected in this test run"
diff --git a/tests/functional/test_starvation_detection.sh b/tests/functional/test_starvation_detection.sh
index 17d7fe0..9362899 100755
--- a/tests/functional/test_starvation_detection.sh
+++ b/tests/functional/test_starvation_detection.sh
@@ -164,7 +164,7 @@ assert_log_contains --negate "${STALLD_LOG}" \
     "${BUSY_PID}.*starved" \
     "No false positive - progress-making task not reported as starved"
 
-kill ${BUSY_PID} 2>/dev/null
+send_signal TERM ${BUSY_PID}
 wait ${BUSY_PID} 2>/dev/null
 
 stop_stalld
diff --git a/tests/helpers/test_helpers.sh b/tests/helpers/test_helpers.sh
index c51361f..7159c19 100755
--- a/tests/helpers/test_helpers.sh
+++ b/tests/helpers/test_helpers.sh
@@ -119,7 +119,7 @@ test_section() {
 cleanup_scenario() {
 	for pid in "$@"; do
 		if [ -n "$pid" ]; then
-			kill -TERM "$pid" 2>/dev/null || true
+			send_signal TERM "$pid"
 			wait "$pid" 2>/dev/null || true
 		fi
 	done
@@ -356,11 +356,19 @@ assert_file_not_exists() {
 	fi
 }
 
+process_alive() {
+	kill -0 "$1" 2>/dev/null
+}
+
+send_signal() {
+	kill -"$1" "$2" 2>/dev/null || true
+}
+
 assert_process_running() {
 	local pid=$1
 	local message=${2:-"Process ${pid} should be running"}
 
-	if kill -0 ${pid} 2>/dev/null; then
+	if process_alive ${pid}; then
 		pass "${message}"
 	else
 		fail "${message}"
@@ -371,7 +379,7 @@ assert_process_not_running() {
 	local pid=$1
 	local message=${2:-"Process ${pid} should not be running"}
 
-	if ! kill -0 ${pid} 2>/dev/null; then
+	if ! process_alive ${pid}; then
 		pass "${message}"
 	else
 		fail "${message}"
@@ -476,7 +484,7 @@ start_stalld() {
 
 			# If pgrep didn't find it, fall back to the shell PID
 			if [ -z "${STALLD_PID}" ]; then
-				if kill -0 ${shell_pid} 2>/dev/null; then
+				if process_alive ${shell_pid}; then
 					STALLD_PID=${shell_pid}
 				fi
 			fi
@@ -488,11 +496,11 @@ start_stalld() {
 				sleep 0.5
 
 				# Check if shell_pid has exited (daemonization complete)
-				if ! kill -0 ${shell_pid} 2>/dev/null; then
+				if ! process_alive ${shell_pid}; then
 					# Shell process exited, daemon should be running
 					# Use pgrep -n to find the newest stalld process
 					STALLD_PID=$(pgrep -n -x stalld 2>/dev/null)
-					if [ -n "${STALLD_PID}" ] && kill -0 ${STALLD_PID} 2>/dev/null; then
+					if [ -n "${STALLD_PID}" ] && process_alive ${STALLD_PID}; then
 						break
 					fi
 				fi
@@ -514,7 +522,7 @@ start_stalld() {
 		return 1
 	fi
 
-	if ! kill -0 ${STALLD_PID} 2>/dev/null; then
+	if ! process_alive ${STALLD_PID}; then
 		echo -e "${RED}ERROR: stalld PID ${STALLD_PID} is not running${NC}"
 		return 1
 	fi
@@ -530,24 +538,24 @@ start_stalld() {
 # returning so callers do not need post-stop sleeps.
 stop_stalld() {
 	if [ -n "${STALLD_PID}" ]; then
-		if kill -0 ${STALLD_PID} 2>/dev/null; then
+		if process_alive ${STALLD_PID}; then
 			# Try graceful shutdown first (SIGTERM)
-			kill ${STALLD_PID} 2>/dev/null || true
+			send_signal TERM ${STALLD_PID}
 
 			# Poll for graceful exit (up to 5 seconds)
 			local timeout=5
 			local elapsed=0
-			while kill -0 ${STALLD_PID} 2>/dev/null && [ ${elapsed} -lt ${timeout} ]; do
+			while process_alive ${STALLD_PID} && [ ${elapsed} -lt ${timeout} ]; do
 				sleep 1
 				elapsed=$((elapsed + 1))
 			done
 
 			# Escalate to SIGKILL if still running
-			if kill -0 ${STALLD_PID} 2>/dev/null; then
-				kill -9 ${STALLD_PID} 2>/dev/null || true
+			if process_alive ${STALLD_PID}; then
+				send_signal KILL ${STALLD_PID}
 				# Poll for forced termination (up to 5 seconds)
 				elapsed=0
-				while kill -0 ${STALLD_PID} 2>/dev/null && [ ${elapsed} -lt ${timeout} ]; do
+				while process_alive ${STALLD_PID} && [ ${elapsed} -lt ${timeout} ]; do
 					sleep 1
 					elapsed=$((elapsed + 1))
 				done
@@ -565,14 +573,14 @@ kill_existing_stalld() {
 		echo "Killing existing stalld processes: ${pids}"
 		for pid in ${pids}; do
 			# Try graceful shutdown first
-			kill ${pid} 2>/dev/null || true
+			send_signal TERM ${pid}
 		done
 		sleep 0.5
 		# Force kill any remaining
 		pids=$(pgrep -x stalld 2>/dev/null)
 		if [ -n "${pids}" ]; then
 			for pid in ${pids}; do
-				kill -9 ${pid} 2>/dev/null || true
+				send_signal KILL ${pid}
 			done
 			sleep 0.2
 		fi
@@ -607,20 +615,20 @@ cleanup() {
 	for pid in "${CLEANUP_PIDS[@]}"; do
 		if [ -n "${pid}" ] && [ "${pid}" -gt 0 ] 2>/dev/null; then
 			# Check if process exists
-			if kill -0 ${pid} 2>/dev/null; then
-				kill ${pid} 2>/dev/null || true
+			if process_alive ${pid}; then
+				send_signal TERM ${pid}
 
 				local timeout=5
 				local elapsed=0
-				while kill -0 ${pid} 2>/dev/null && [ ${elapsed} -lt ${timeout} ]; do
+				while process_alive ${pid} && [ ${elapsed} -lt ${timeout} ]; do
 					sleep 1
 					elapsed=$((elapsed + 1))
 				done
 
-				if kill -0 ${pid} 2>/dev/null; then
-					kill -9 ${pid} 2>/dev/null || true
+				if process_alive ${pid}; then
+					send_signal KILL ${pid}
 					elapsed=0
-					while kill -0 ${pid} 2>/dev/null && [ ${elapsed} -lt ${timeout} ]; do
+					while process_alive ${pid} && [ ${elapsed} -lt ${timeout} ]; do
 						sleep 1
 						elapsed=$((elapsed + 1))
 					done
@@ -1285,7 +1293,7 @@ start_starvation_gen() {
 	local timeout=10
 	local elapsed=0
 	while [ $elapsed -lt $timeout ]; do
-		if ! kill -0 ${STARVE_PID} 2>/dev/null; then
+		if ! process_alive ${STARVE_PID}; then
 			echo -e "${RED}ERROR: starvation_gen exited prematurely${NC}"
 			echo "  Log contents:"
 			cat "${STARVE_LOG}"
@@ -1302,10 +1310,10 @@ start_starvation_gen() {
 	echo -e "${RED}ERROR: starvation_gen did not become ready within ${timeout}s${NC}"
 	echo "  Log contents:"
 	cat "${STARVE_LOG}"
-	kill ${STARVE_PID} 2>/dev/null
+	send_signal TERM ${STARVE_PID}
 	sleep 1
-	if kill -0 ${STARVE_PID} 2>/dev/null; then
-		kill -9 ${STARVE_PID} 2>/dev/null
+	if process_alive ${STARVE_PID}; then
+		send_signal KILL ${STARVE_PID}
 	fi
 	return 1
 }
@@ -1315,7 +1323,7 @@ export -f start_test end_test test_section cleanup_scenario find_starved_child
 export -f assert_starvation_detected assert_boost_detected assert_stalld_rejects assert_log_contains assert_success
 export -f pass fail assert_equals assert_contains assert_not_contains
 export -f assert_file_exists assert_file_not_exists
-export -f assert_process_running assert_process_not_running
+export -f process_alive send_signal assert_process_running assert_process_not_running
 export -f start_stalld stop_stalld kill_existing_stalld cleanup
 export -f wait_for_log_message wait_for_stalld_ready wait_for_starvation_detected wait_for_boost_detected wait_for_n_log_matches
 export -f get_thread_policy get_thread_priority
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index 63d0624..1fbb3f2 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -224,7 +224,7 @@ cleanup_runner() {
 		if [ -n "${pids}" ]; then
 			echo -e "${BLUE}Cleaning up remaining stalld processes: ${pids}${NC}"
 			for pid in ${pids}; do
-				kill -9 ${pid} 2>/dev/null || true
+				send_signal KILL ${pid}
 			done
 		fi
 
@@ -250,14 +250,14 @@ kill_existing_stalld_processes() {
 	if [ -n "${pids}" ]; then
 		echo -e "${BLUE}Killing existing stalld processes: ${pids}${NC}" | tee -a "${LOG_FILE}"
 		for pid in ${pids}; do
-			kill ${pid} 2>/dev/null || true
+			send_signal TERM ${pid}
 		done
 		sleep 0.5
 		# Force kill any remaining
 		pids=$(pgrep -x stalld 2>/dev/null)
 		if [ -n "${pids}" ]; then
 			for pid in ${pids}; do
-				kill -9 ${pid} 2>/dev/null || true
+				send_signal KILL ${pid}
 			done
 			sleep 0.2
 		fi
-- 
2.54.0


  parent reply	other threads:[~2026-05-20 14:02 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-20 14:00 [[PATCH stalld] 00/33] Test suite hardening, correctness fixes, and BPF optimization Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 01/33] stalld: Reject --force_fifo in single-threaded mode Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 02/33] tests: Introduce test_section() helper Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 03/33] tests: Introduce cleanup_scenario() helper Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 04/33] tests: Introduce starvation and boost asserts Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 05/33] tests: Introduce find_starved_child() helper Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 06/33] tests: Fix task exit timing in test_boost_restoration Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 07/33] tests: Consolidate and adopt init_functional_test() Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 08/33] tests: Introduce assert_stalld_rejects() helper Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 09/33] tests: Fix boost verification in runtime and duration tests Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 10/33] tests: Fix subshell swallowing test results Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 11/33] tests: Fix repeated log match finding same line Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 12/33] chore: Remove legacy test infrastructure and stale docs Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 13/33] tests: Add assertions to SCHED_OTHER restoration test Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 14/33] tests: Fix CPU selection grep substring matches Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 15/33] tests: Add idle CPU skipping assertion Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 16/33] tests: Remove redundant pkill from cleanup Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 17/33] tests: Introduce and adopt assert_log_contains() helper Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 18/33] tests: Remove weak, redundant, and assertion-free test blocks Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 19/33] tests: Introduce and adopt assert_success() helper Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 20/33] tests: Replace wait conditionals with asserts Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 21/33] tests: Remove if-wrappers around assert calls Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 22/33] tests: Abort immediately on test failure Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 23/33] tests: Remove dead code after making fail() fatal Wander Lairson Costa
2026-05-20 14:00 ` Wander Lairson Costa [this message]
2026-05-20 14:00 ` [[PATCH stalld] 25/33] tests: Extract wait_for_process_exit helper Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 26/33] tests: Reduce default wait timeouts Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 27/33] tests: Reduce starvation_gen durations Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 28/33] tests: Replace init sleeps in test_affinity Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 29/33] tests: Drop redundant sleeps in test_pidfile Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 30/33] tests: Remove redundant sleeps after start_stalld Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 31/33] tests: Reduce timing and replace sleeps with event waits Wander Lairson Costa
2026-05-20 14:00 ` [[PATCH stalld] 32/33] tests: Fix async-signal-unsafe handler Wander Lairson Costa
2026-05-20 14:01 ` [[PATCH stalld] 33/33] bpf: Replace linear task scan with hash map Wander Lairson Costa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260520140104.112142-25-wander@redhat.com \
    --to=wander@redhat.com \
    --cc=davidlt@rivosinc.com \
    --cc=jkacur@redhat.com \
    --cc=juri.lelli@redhat.com \
    --cc=linux-rt-users@vger.kernel.org \
    --cc=luffyluo@tencent.com \
    --cc=williams@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.