Skip to content

Commit 69d01e7

Browse files
authored
Merge pull request #311 from smuppand/audio_pd
Harden DSP_AudioPD adsprpcd validation and add PID helper utilities
2 parents 3147945 + e286204 commit 69d01e7

File tree

2 files changed

+220
-55
lines changed

2 files changed

+220
-55
lines changed

Runner/suites/Multimedia/DSP_AudioPD/run.sh

Lines changed: 125 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
44
# SPDX-License-Identifier: BSD-3-Clause
5+
6+
TESTNAME="DSP_AudioPD"
7+
58
# Robustly find and source init_env
69
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
710
INIT_ENV=""
@@ -14,71 +17,160 @@ while [ "$SEARCH" != "/" ]; do
1417
SEARCH=$(dirname "$SEARCH")
1518
done
1619

20+
RES_FALLBACK="$SCRIPT_DIR/${TESTNAME}.res"
21+
1722
if [ -z "$INIT_ENV" ]; then
1823
echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2
19-
exit 1
24+
echo "$TESTNAME SKIP" >"$RES_FALLBACK" 2>/dev/null || true
25+
exit 0
2026
fi
2127

2228
# Only source if not already loaded (idempotent)
23-
if [ -z "$__INIT_ENV_LOADED" ]; then
29+
if [ -z "${__INIT_ENV_LOADED:-}" ]; then
2430
# shellcheck disable=SC1090
2531
. "$INIT_ENV"
32+
export __INIT_ENV_LOADED=1
2633
fi
34+
2735
# Always source functestlib.sh, using $TOOLS exported by init_env
2836
# shellcheck disable=SC1090,SC1091
2937
. "$TOOLS/functestlib.sh"
3038

31-
TESTNAME="DSP_AudioPD"
3239
test_path=$(find_test_case_by_name "$TESTNAME")
33-
cd "$test_path" || exit 1
40+
if [ -z "$test_path" ] || [ ! -d "$test_path" ]; then
41+
log_skip "$TESTNAME SKIP - test path not found"
42+
echo "$TESTNAME SKIP" >"$RES_FALLBACK" 2>/dev/null || true
43+
exit 0
44+
fi
45+
46+
if ! cd "$test_path"; then
47+
log_skip "$TESTNAME SKIP - cannot cd into $test_path"
48+
echo "$TESTNAME SKIP" >"$RES_FALLBACK" 2>/dev/null || true
49+
exit 0
50+
fi
51+
3452
# shellcheck disable=SC2034
3553
res_file="./$TESTNAME.res"
3654

3755
log_info "-----------------------------------------------------------------------------------------"
3856
log_info "-------------------Starting $TESTNAME Testcase----------------------------"
3957
log_info "=== Test Initialization ==="
4058

41-
log_info "Checking if dependency binary is available"
42-
check_dependencies adsprpcd
59+
# Dependencies (single call; log list; SKIP if missing)
60+
deps_list="adsprpcd tr awk grep sleep"
61+
log_info "Checking dependencies: ""$deps_list"""
62+
if ! check_dependencies "$deps_list"; then
63+
log_skip "$TESTNAME SKIP - missing one or more dependencies: $deps_list"
64+
echo "$TESTNAME SKIP" >"$res_file"
65+
exit 0
66+
fi
67+
68+
STARTED_BY_TEST=0
69+
PID=""
70+
71+
check_adsprpcd_wait_state() {
72+
pid="$1"
73+
pid=$(sanitize_pid "$pid")
4374

44-
if is_process_running "adsprpcd"; then
75+
case "$pid" in
76+
''|*[!0-9]*)
77+
return 1
78+
;;
79+
esac
80+
81+
# Prefer /proc/<pid>/wchan (more commonly available)
82+
if [ -r "/proc/$pid/wchan" ]; then
83+
wchan=$(tr -d '\r\n' <"/proc/$pid/wchan" 2>/dev/null)
84+
85+
# Accept suffixes like ".constprop.0"
86+
case "$wchan" in
87+
do_sys_poll*|ep_poll*|do_epoll_wait*|poll_schedule_timeout*)
88+
log_info "adsprpcd PID $pid wchan='$wchan' (accepted)"
89+
return 0
90+
;;
91+
*)
92+
log_info "adsprpcd PID $pid wchan='$wchan' (not in expected set)"
93+
return 1
94+
;;
95+
esac
96+
fi
97+
98+
# Fallback: /proc/<pid>/stack (may be missing depending on kernel config)
99+
if [ -r "/proc/$pid/stack" ]; then
100+
if grep -qE "(do_sys_poll|ep_poll|do_epoll_wait|poll_schedule_timeout)" "/proc/$pid/stack" 2>/dev/null; then
101+
log_info "adsprpcd PID $pid stack contains expected wait symbol"
102+
return 0
103+
fi
104+
log_info "adsprpcd PID $pid stack does not contain expected wait symbols"
105+
return 1
106+
fi
107+
108+
# Neither interface is available -> SKIP
109+
log_skip "Kernel does not expose /proc/$pid/(wchan|stack); cannot validate adsprpcd wait state"
110+
echo "$TESTNAME SKIP" >"$res_file"
111+
return 2
112+
}
113+
114+
if is_process_running "adsprpcd"; then
45115
log_info "adsprpcd is running"
46-
PID=$(get_pid "adsprpcd")
116+
PID=$(get_one_pid_by_name "adsprpcd" 2>/dev/null || true)
117+
PID=$(sanitize_pid "$PID")
47118
else
48119
log_info "adsprpcd is not running"
49120
log_info "Manually starting adsprpcd daemon"
50-
adsprpcd &
51-
PID=$!
121+
adsprpcd >/dev/null 2>&1 &
122+
PID=$(sanitize_pid "$!")
123+
STARTED_BY_TEST=1
124+
125+
# adsprpcd might daemonize/fork; if $! isn't alive, discover PID by name
126+
if [ -n "$PID" ] && ! wait_pid_alive "$PID" 2; then
127+
PID=""
128+
fi
129+
if [ -z "$PID" ]; then
130+
PID=$(get_one_pid_by_name "adsprpcd" 2>/dev/null || true)
131+
PID=$(sanitize_pid "$PID")
132+
fi
52133
fi
134+
53135
log_info "PID is $PID"
54-
sleep 5
55136

56-
if [ -z "$PID" ]; then
57-
log_info "Failed to start the binary"
58-
exit 1
59-
else
60-
log_info "Binary is running successfully"
61-
fi
137+
if [ -z "$PID" ] || ! wait_pid_alive "$PID" 10; then
138+
log_fail "Failed to start adsprpcd or PID did not become alive"
139+
echo "$TESTNAME FAIL" >"$res_file"
62140

63-
check_stack_trace() {
64-
pid=$1
65-
if grep -q "do_sys_poll" < "/proc/$pid/stack" 2>/dev/null; then
66-
return 0
67-
else
68-
return 1
141+
# Kill only if we started it and PID is valid
142+
if [ "$STARTED_BY_TEST" -eq 1 ]; then
143+
PID_CLEAN=$(sanitize_pid "$PID")
144+
if [ -n "$PID_CLEAN" ]; then
145+
kill_process "$PID_CLEAN" || true
146+
fi
69147
fi
70-
}
148+
exit 0
149+
fi
71150

72-
# Print overall test result
73-
if check_stack_trace "$PID"; then
151+
# Evaluate
152+
check_adsprpcd_wait_state "$PID"
153+
rc=$?
154+
155+
if [ "$rc" -eq 0 ]; then
74156
log_pass "$TESTNAME : Test Passed"
75-
echo "$TESTNAME PASS" > "$res_file"
76-
kill_process "$PID"
77-
exit 0
157+
echo "$TESTNAME PASS" >"$res_file"
158+
elif [ "$rc" -eq 2 ]; then
159+
# SKIP already written by the function
160+
:
78161
else
79162
log_fail "$TESTNAME : Test Failed"
80-
echo "$TESTNAME FAIL" > "$res_file"
81-
kill_process "$PID"
82-
exit 1
163+
echo "$TESTNAME FAIL" >"$res_file"
83164
fi
84-
log_info "-------------------Completed $TESTNAME Testcase----------------------------"
165+
166+
log_info "-------------------Completed $TESTNAME Testcase----------------------------"
167+
168+
# Kill only if we started it
169+
if [ "$STARTED_BY_TEST" -eq 1 ]; then
170+
PID_CLEAN=$(sanitize_pid "$PID")
171+
if [ -n "$PID_CLEAN" ]; then
172+
kill_process "$PID_CLEAN" || true
173+
fi
174+
fi
175+
176+
exit 0

Runner/utils/functestlib.sh

Lines changed: 95 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4334,42 +4334,110 @@ ensure_network_online() {
43344334
return 1
43354335
}
43364336

4337+
# Return the first numeric token found in input (helps when tools return multi-PID / noisy output)
4338+
sanitize_pid() {
4339+
# Return first numeric token from input (single PID) or empty
4340+
printf '%s' "$1" \
4341+
| tr -d '\r' \
4342+
| tr -c '0-9 \n' ' ' \
4343+
| awk '{print $1; exit}'
4344+
}
4345+
4346+
# Get a single PID (first match) for a given process name.
4347+
# Prefer pgrep, then get_pid, then a ps fallback.
4348+
get_one_pid_by_name() {
4349+
name="$1"
4350+
[ -z "$name" ] && return 1
4351+
4352+
pid=""
4353+
4354+
# Prefer pgrep
4355+
if command -v pgrep >/dev/null 2>&1; then
4356+
pid=$(pgrep -x "$name" 2>/dev/null | awk 'NR==1{print; exit}')
4357+
pid=$(sanitize_pid "$pid")
4358+
[ -n "$pid" ] && { printf '%s\n' "$pid"; return 0; }
4359+
fi
4360+
4361+
# Fallback to get_pid (should already return first PID after your update)
4362+
if command -v get_pid >/dev/null 2>&1; then
4363+
pid=$(get_pid "$name" 2>/dev/null)
4364+
pid=$(sanitize_pid "$pid")
4365+
[ -n "$pid" ] && { printf '%s\n' "$pid"; return 0; }
4366+
fi
4367+
4368+
# Final fallback: ps
4369+
pid=$(ps -e 2>/dev/null | awk -v n="$name" '$NF==n {print $1; exit}')
4370+
pid=$(sanitize_pid "$pid")
4371+
[ -n "$pid" ] && { printf '%s\n' "$pid"; return 0; }
4372+
4373+
return 1
4374+
}
4375+
4376+
# Wait until PID is alive (kill -0 succeeds) or timeout seconds elapse.
4377+
wait_pid_alive() {
4378+
pid="$1"
4379+
timeout="${2:-10}"
4380+
4381+
pid=$(sanitize_pid "$pid")
4382+
case "$pid" in
4383+
''|*[!0-9]*)
4384+
return 1
4385+
;;
4386+
esac
4387+
4388+
i=0
4389+
while [ "$i" -lt "$timeout" ]; do
4390+
if kill -0 "$pid" 2>/dev/null; then
4391+
return 0
4392+
fi
4393+
sleep 1
4394+
i=$((i + 1))
4395+
done
4396+
return 1
4397+
}
4398+
4399+
# Kill process for the given PID
43374400
kill_process() {
43384401
PID="$1"
43394402
KILL_TERM_GRACE="${KILL_TERM_GRACE:-5}"
43404403
KILL_KILL_GRACE="${KILL_KILL_GRACE:-5}"
43414404
SELF_PID="$$"
4342-
4405+
4406+
case "$PID" in
4407+
''|*[!0-9]*)
4408+
log_warn "Refusing to kill non-numeric PID '$PID'"
4409+
return 1
4410+
;;
4411+
esac
4412+
43434413
# Safety checks
43444414
if [ "$PID" -eq 1 ] || [ "$PID" -eq "$SELF_PID" ]; then
43454415
log_warn "Refusing to kill PID $PID (init or self)"
43464416
return 1
43474417
fi
4348-
4349-
# Check if process exists
4418+
43504419
if ! kill -0 "$PID" 2>/dev/null; then
43514420
log_info "Process $PID not running"
43524421
return 0
43534422
fi
4354-
4423+
43554424
log_info "Sending SIGTERM to PID $PID"
43564425
kill -TERM "$PID" 2>/dev/null
43574426
sleep "$KILL_TERM_GRACE"
4358-
4427+
43594428
if kill -0 "$PID" 2>/dev/null; then
43604429
log_info "Sending SIGKILL to PID $PID"
43614430
kill -KILL "$PID" 2>/dev/null
43624431
sleep "$KILL_KILL_GRACE"
43634432
fi
4364-
4365-
# Final check
4433+
43664434
if kill -0 "$PID" 2>/dev/null; then
43674435
log_warn "Failed to kill process $PID"
43684436
return 1
4369-
else
4370-
log_info "Process $PID terminated successfully"
4371-
return 0
43724437
fi
4438+
4439+
log_info "Process $PID terminated successfully"
4440+
return 0
43734441
}
43744442

43754443
is_process_running() {
@@ -4426,20 +4494,25 @@ get_pid() {
44264494
log_info "Usage: get_pid <process_name>"
44274495
return 1
44284496
fi
4429-
4497+
44304498
process_name="$1"
4431-
4432-
# Try multiple ps variants for compatibility
4433-
pid=$(ps -e | awk -v name="$process_name" '$NF == name { print $1 }')
4434-
[ -z "$pid" ] && pid=$(ps -A | awk -v name="$process_name" '$NF == name { print $1 }')
4435-
[ -z "$pid" ] && pid=$(ps -aux | awk -v name="$process_name" '$11 == name { print $2 }')
4436-
[ -z "$pid" ] && pid=$(ps -ef | awk -v name="$process_name" '$NF == name { print $2 }')
4437-
4499+
pid=""
4500+
4501+
# Prefer pgrep if available (fast + clean)
4502+
if command -v pgrep >/dev/null 2>&1; then
4503+
pid=$(pgrep -x "$process_name" 2>/dev/null | awk 'NR==1 {print; exit}')
4504+
fi
4505+
4506+
# POSIX fallback: ps
4507+
if [ -z "$pid" ]; then
4508+
pid=$(ps -e 2>/dev/null | awk -v name="$process_name" '$NF == name { print $1; exit }')
4509+
fi
4510+
44384511
if [ -n "$pid" ]; then
4439-
echo "$pid"
4512+
printf '%s\n' "$pid"
44404513
return 0
4441-
else
4442-
log_info "Process '$process_name' not found."
4443-
return 1
44444514
fi
4515+
4516+
log_info "Process '$process_name' not found."
4517+
return 1
44454518
}

0 commit comments

Comments
 (0)