Skip to content

Commit 5f0e933

Browse files
authored
Merge pull request qualcomm-linux#161 from smuppand/graphics
graphics: harden kmscube & weston-simple-egl tests (robust Wayland env, deterministic .res, CI-friendly logs)
2 parents d31f4c5 + 582574d commit 5f0e933

File tree

3 files changed

+474
-96
lines changed

3 files changed

+474
-96
lines changed

Runner/suites/Multimedia/Graphics/KMSCube/run.sh

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
33
# SPDX-License-Identifier: BSD-3-Clause-Clear
44

5-
# KMSCube Validator Script (Yocto-Compatible)
5+
# KMSCube Validator Script (Yocto-Compatible, POSIX sh)
6+
7+
# --- Robustly find and source init_env ---------------------------------------
68
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
79
INIT_ENV=""
810
SEARCH="$SCRIPT_DIR"
@@ -19,56 +21,101 @@ if [ -z "$INIT_ENV" ]; then
1921
exit 1
2022
fi
2123

24+
# Only source once (idempotent)
2225
if [ -z "$__INIT_ENV_LOADED" ]; then
2326
# shellcheck disable=SC1090
2427
. "$INIT_ENV"
2528
fi
2629

30+
# Always source functestlib.sh, using $TOOLS exported by init_env
2731
# shellcheck disable=SC1090,SC1091
2832
. "$TOOLS/functestlib.sh"
2933

34+
# --- Test metadata -----------------------------------------------------------
3035
TESTNAME="KMSCube"
31-
FRAME_COUNT=999
32-
EXPECTED_FRAMES=$((FRAME_COUNT - 1))
33-
test_path=$(find_test_case_by_name "$TESTNAME")
36+
FRAME_COUNT="${FRAME_COUNT:-999}" # allow override via env
37+
EXPECTED_MIN=$((FRAME_COUNT - 1)) # tolerate off-by-one under-reporting
38+
39+
# Ensure we run from the testcase directory so .res/logs land next to run.sh
40+
test_path="$(find_test_case_by_name "$TESTNAME")"
3441
cd "$test_path" || exit 1
42+
3543
RES_FILE="./$TESTNAME.res"
3644
LOG_FILE="./${TESTNAME}_run.log"
3745
rm -f "$RES_FILE" "$LOG_FILE"
3846

3947
log_info "-------------------------------------------------------------------"
4048
log_info "------------------- Starting $TESTNAME Testcase -------------------"
4149

42-
if check_dependencies "$TESTNAME"; then
43-
log_fail "$TESTNAME : kmscube binary not found"
44-
echo "$TESTNAME SKIP" > "$RES_FILE"
45-
exit 1
50+
# --- Dependencies ------------------------------------------------------------
51+
# Note: check_dependencies returns 0 when present, non-zero if missing.
52+
check_dependencies kmscube || {
53+
log_skip "$TESTNAME SKIP: missing dependencies: kmscube"
54+
echo "$TESTNAME SKIP" >"$RES_FILE"
55+
exit 0
56+
}
57+
KMSCUBE_BIN="$(command -v kmscube 2>/dev/null || true)"
58+
log_info "Using kmscube: ${KMSCUBE_BIN:-<not found>}"
59+
60+
# --- Basic DRM availability guard -------------------------------------------
61+
set -- /dev/dri/card* 2>/dev/null
62+
if [ ! -e "$1" ]; then
63+
log_skip "$TESTNAME SKIP: no /dev/dri/card* nodes"
64+
echo "$TESTNAME SKIP" >"$RES_FILE"
65+
exit 0
4666
fi
4767

68+
# --- If Weston is running, stop it so KMS has control ------------------------
4869
weston_was_running=0
4970
if weston_is_running; then
5071
weston_stop
5172
weston_was_running=1
5273
fi
5374

54-
log_info "Running kmscube test with --count=$FRAME_COUNT..."
55-
if kmscube --count="$FRAME_COUNT" > "$LOG_FILE" 2>&1; then
56-
if grep -q "Rendered $EXPECTED_FRAMES frames" "$LOG_FILE"; then
57-
log_pass "$TESTNAME : Test Passed"
58-
echo "$TESTNAME PASS" > "$RES_FILE"
59-
else
60-
log_fail "$TESTNAME : Expected output not found (Rendered $EXPECTED_FRAMES frames)"
61-
echo "$TESTNAME FAIL" > "$RES_FILE"
62-
exit 1
75+
# --- Execute kmscube ---------------------------------------------------------
76+
log_info "Running kmscube with --count=${FRAME_COUNT} ..."
77+
if kmscube --count="${FRAME_COUNT}" >"$LOG_FILE" 2>&1; then :; else
78+
rc=$?
79+
log_fail "$TESTNAME : Execution failed (rc=$rc) — see $LOG_FILE"
80+
echo "$TESTNAME FAIL" >"$RES_FILE"
81+
if [ "$weston_was_running" -eq 1 ]; then
82+
log_info "Restarting Weston after failure"
83+
weston_start
6384
fi
85+
exit 1
86+
fi
87+
88+
# --- Parse 'Rendered N frames' (case-insensitive), use the last N -----------
89+
FRAMES_RENDERED="$(
90+
awk 'BEGIN{IGNORECASE=1}
91+
/Rendered[[:space:]][0-9]+[[:space:]]+frames/{
92+
# capture the numeric token on that line; remember the last match
93+
for(i=1;i<=NF;i++) if ($i ~ /^[0-9]+$/) n=$i
94+
last=n
95+
}
96+
END{if (last!="") print last}' "$LOG_FILE"
97+
)"
98+
[ -n "$FRAMES_RENDERED" ] || FRAMES_RENDERED=0
99+
[ "$EXPECTED_MIN" -lt 0 ] && EXPECTED_MIN=0
100+
log_info "kmscube reported: Rendered ${FRAMES_RENDERED} frames (requested ${FRAME_COUNT}, min acceptable ${EXPECTED_MIN})"
101+
102+
# --- Verdict -----------------------------------------------------------------
103+
if [ "$FRAMES_RENDERED" -ge "$EXPECTED_MIN" ]; then
104+
log_pass "$TESTNAME : PASS"
105+
echo "$TESTNAME PASS" >"$RES_FILE"
64106
else
65-
log_fail "$TESTNAME : Execution failed (non-zero exit code)"
66-
echo "$TESTNAME FAIL" > "$RES_FILE"
107+
log_fail "$TESTNAME : FAIL (rendered ${FRAMES_RENDERED} < ${EXPECTED_MIN})"
108+
echo "$TESTNAME FAIL" >"$RES_FILE"
109+
if [ "$weston_was_running" -eq 1 ]; then
110+
log_info "Restarting Weston after failure"
111+
weston_start
112+
fi
67113
exit 1
68114
fi
69115

116+
# --- Restore Weston if we stopped it -----------------------------------------
70117
if [ "$weston_was_running" -eq 1 ]; then
71-
log_info "weston realuching after $TESTNAME completion"
118+
log_info "Restarting Weston after $TESTNAME completion"
72119
weston_start
73120
fi
74121

Lines changed: 163 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,198 @@
11
#!/bin/sh
2+
# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
23
# SPDX-License-Identifier: BSD-3-Clause-Clear
3-
# Description: Script to test the 'weston-simple-egl' Wayland client for 30 seconds and log the result.
4+
# Validate weston-simple-egl runs under a working Wayland session.
5+
# - Robust Wayland env resolution (adopts socket & fixes XDG_RUNTIME_DIR perms)
6+
# - CI-friendly logs and PASS/FAIL semantics
7+
# - Optional FPS parsing if build prints it (lenient if not present)
48

5-
# Robustly find and source init_env
9+
# ---------- Source init_env and functestlib ----------
610
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
711
INIT_ENV=""
812
SEARCH="$SCRIPT_DIR"
913
while [ "$SEARCH" != "/" ]; do
10-
if [ -f "$SEARCH/init_env" ]; then
11-
INIT_ENV="$SEARCH/init_env"
12-
break
13-
fi
14-
SEARCH=$(dirname "$SEARCH")
14+
if [ -f "$SEARCH/init_env" ]; then INIT_ENV="$SEARCH/init_env"; break; fi
15+
SEARCH=$(dirname "$SEARCH")
1516
done
16-
1717
if [ -z "$INIT_ENV" ]; then
18-
echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2
19-
exit 1
18+
echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2
19+
exit 1
2020
fi
21-
22-
# Only source if not already loaded (idempotent)
2321
if [ -z "$__INIT_ENV_LOADED" ]; then
24-
# shellcheck disable=SC1090
25-
. "$INIT_ENV"
22+
# shellcheck disable=SC1090
23+
. "$INIT_ENV"
2624
fi
27-
28-
# Always source functestlib.sh, using $TOOLS exported by init_env
2925
# shellcheck disable=SC1090,SC1091
3026
. "$TOOLS/functestlib.sh"
3127

3228
TESTNAME="weston-simple-egl"
29+
# Tunables (env override)
30+
DURATION="${DURATION:-30s}" # how long to run the client
31+
STOP_GRACE="${STOP_GRACE:-3s}" # grace period on stop
32+
EXPECT_FPS="${EXPECT_FPS:-60}" # nominal refresh (used for logging)
33+
FPS_TOL_PCT="${FPS_TOL_PCT:-10}" # +/- tolerance %
34+
REQUIRE_FPS="${REQUIRE_FPS:-0}" # 1=require FPS lines & threshold; 0=best effort
3335

34-
test_path=$(find_test_case_by_name "$TESTNAME")
36+
test_path="$(find_test_case_by_name "$TESTNAME" 2>/dev/null || echo "$SCRIPT_DIR")"
3537
cd "$test_path" || exit 1
3638
RES_FILE="./$TESTNAME.res"
3739
LOG_FILE="./${TESTNAME}_run.log"
3840
rm -f "$RES_FILE" "$LOG_FILE"
3941

4042
log_info "--------------------------------------------------------------------------"
4143
log_info "------------------- Starting $TESTNAME Testcase --------------------------"
44+
# FIX #1: Use ASCII '+/-' and keep it in a normal string
45+
log_info "Config: DURATION=$DURATION STOP_GRACE=$STOP_GRACE EXPECT_FPS=${EXPECT_FPS}+/-${FPS_TOL_PCT}% REQUIRE_FPS=$REQUIRE_FPS"
46+
47+
# Dependencies
48+
check_dependencies weston-simple-egl || {
49+
log_fail "$TESTNAME : weston-simple-egl binary not found in PATH"
50+
echo "$TESTNAME SKIP" > "$RES_FILE"
51+
exit 0
52+
}
53+
BIN="$(command -v weston-simple-egl 2>/dev/null || true)"
54+
log_info "Using weston-simple-egl: ${BIN:-<none>}"
55+
56+
# Resolve Wayland socket:
57+
# 1) If current env points to a real socket, use it.
58+
sock=""
59+
if [ -n "$XDG_RUNTIME_DIR" ] && [ -n "$WAYLAND_DISPLAY" ] && [ -e "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" ]; then
60+
sock="$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY"
61+
fi
4262

43-
# Only start if not already running
44-
if ! weston_is_running; then
63+
# 2) Otherwise, scan common locations.
64+
if [ -z "$sock" ]; then
65+
for s in $(find_wayland_sockets); do
66+
if [ -e "$s" ]; then sock="$s"; break; fi
67+
done
68+
fi
69+
70+
# 3) If still no socket, try to start Weston and wait a bit.
71+
if [ -z "$sock" ]; then
72+
if weston_is_running; then
73+
log_warn "Weston running but no Wayland socket visible; attempting to continue."
74+
else
4575
log_info "Weston not running. Attempting to start..."
4676
weston_start
77+
fi
78+
# Wait for socket to appear (up to ~5s)
79+
n=0
80+
while [ $n -lt 5 ] && [ -z "$sock" ]; do
81+
for s in $(find_wayland_sockets); do
82+
if [ -e "$s" ]; then sock="$s"; break; fi
83+
done
84+
[ -n "$sock" ] && break
85+
sleep 1
86+
n=$((n+1))
87+
done
4788
fi
4889

49-
if check_dependencies weston-simple-egl; then
50-
log_fail "$TESTNAME : weston-simple-egl binary not found"
51-
echo "$TESTNAME SKIP" > "$RES_FILE"
52-
exit 1
90+
if [ -z "$sock" ]; then
91+
log_fail "$TESTNAME : FAIL (no Wayland socket found after attempting to start Weston)"
92+
echo "$TESTNAME FAIL" > "$RES_FILE"
93+
exit 1
94+
fi
95+
96+
# Adopt env and fix runtime dir perms (done inside helper(s))
97+
adopt_wayland_env_from_socket "$sock"
98+
99+
# FIX #2: Avoid duplicate prints — helpers can log the chosen socket/env once.
100+
# If your helpers are quiet instead, uncomment the two lines below:
101+
# log_info "Selected Wayland socket: $sock"
102+
# log_info "Wayland env: XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR WAYLAND_DISPLAY=$WAYLAND_DISPLAY"
103+
104+
if wayland_connection_ok; then
105+
log_info "Wayland connection test: OK (wayland-info/env)"
106+
else
107+
log_fail "$TESTNAME : FAIL (Wayland connection test failed)"
108+
print_path_meta "$XDG_RUNTIME_DIR" | sed 's/^/[DBG] /'
109+
stat "$XDG_RUNTIME_DIR" 2>/dev/null | sed 's/^/[DBG] /' || true
110+
echo "$TESTNAME FAIL" > "$RES_FILE"
111+
exit 1
53112
fi
54113

55-
XDG_RUNTIME_DIR="/dev/socket/weston"
56-
WAYLAND_DISPLAY="wayland-1"
57-
export XDG_RUNTIME_DIR WAYLAND_DISPLAY
58-
59-
mkdir -p "$XDG_RUNTIME_DIR"
60-
chmod 0700 "$XDG_RUNTIME_DIR"
61-
log_info "Running weston-simple-egl for 30 seconds..."
62-
script -q -c "weston-simple-egl" "$LOG_FILE" 2>/dev/null &
63-
EGL_PID=$!
64-
sleep 30
65-
kill "$EGL_PID" 2>/dev/null
66-
wait "$EGL_PID" 2>/dev/null
67-
68-
count=$(grep -i -o "5 seconds" "$LOG_FILE" | wc -l)
69-
if [ "$count" -ge 5 ]; then
70-
log_pass "$TESTNAME : Test Passed"
114+
# Try to enable FPS prints if supported by the client build (best effort).
115+
export SIMPLE_EGL_FPS=1
116+
export WESTON_SIMPLE_EGL_FPS=1
117+
118+
# Run the client for DURATION with a stopwatch for CI logs.
119+
log_info "Running weston-simple-egl for $DURATION ..."
120+
start_ts="$(date +%s 2>/dev/null || echo 0)"
121+
if command -v run_with_timeout >/dev/null 2>&1; then
122+
run_with_timeout "$DURATION" weston-simple-egl >"$LOG_FILE" 2>&1
123+
rc=$?
124+
else
125+
if command -v timeout >/dev/null 2>&1; then
126+
timeout "$DURATION" weston-simple-egl >"$LOG_FILE" 2>&1
127+
rc=$?
128+
else
129+
# Last resort: background and sleep.
130+
sh -c 'weston-simple-egl' >"$LOG_FILE" 2>&1 &
131+
pid=$!
132+
# DURATION like "30s" → "30"
133+
dur_s="$(printf '%s' "$DURATION" | sed -n 's/^\([0-9][0-9]*\)s$/\1/p')"
134+
[ -z "$dur_s" ] && dur_s="$DURATION"
135+
sleep "$dur_s"
136+
kill "$pid" 2>/dev/null || true
137+
wait "$pid" 2>/dev/null || true
138+
rc=143
139+
fi
140+
fi
141+
end_ts="$(date +%s 2>/dev/null || echo 0)"
142+
elapsed=$(( end_ts - start_ts ))
143+
[ "$elapsed" -lt 0 ] && elapsed=0
144+
145+
# FPS parsing (best effort)
146+
fps="-"
147+
fps_line="$(grep -E '([Ff][Pp][Ss]|frames per second|^fps:)' "$LOG_FILE" 2>/dev/null | tail -n 1)"
148+
if [ -n "$fps_line" ]; then
149+
# Extract last numeric token (integer or float)
150+
fps="$(printf '%s\n' "$fps_line" | awk '{
151+
for (i=NF;i>=1;i--) if ($i ~ /^[0-9]+(\.[0-9]+)?$/) {print $i; exit}
152+
}')"
153+
[ -z "$fps" ] && fps="-"
154+
fi
155+
156+
# CI debugging summary
157+
log_info "Result summary: rc=$rc elapsed=${elapsed}s fps=${fps} (expected ~${EXPECT_FPS}+/-${FPS_TOL_PCT}%)"
158+
# Quick duration gate: must have run at least (DURATION-1) seconds to be considered OK.
159+
dur_s="$(printf '%s' "$DURATION" | sed -n 's/^\([0-9][0-9]*\)s$/\1/p')"
160+
[ -z "$dur_s" ] && dur_s="$DURATION"
161+
min_ok=$(( dur_s - 1 ))
162+
[ "$min_ok" -lt 0 ] && min_ok=0
163+
164+
final="PASS"
165+
166+
if [ "$elapsed" -lt "$min_ok" ]; then
167+
final="FAIL"
168+
log_fail "$TESTNAME : FAIL (exited after ${elapsed}s; expected ~${dur_s}s) — rc=$rc"
169+
fi
170+
171+
# Optional FPS gate
172+
if [ "$final" = "PASS" ] && [ "$REQUIRE_FPS" -eq 1 ]; then
173+
if [ "$fps" = "-" ]; then
174+
final="FAIL"
175+
log_fail "$TESTNAME : FAIL (no FPS lines found but REQUIRE_FPS=1)"
176+
else
177+
# Integer-only tolerance check (portable)
178+
lo=$(( (EXPECT_FPS * (100 - FPS_TOL_PCT)) / 100 ))
179+
hi=$(( (EXPECT_FPS * (100 + FPS_TOL_PCT)) / 100 ))
180+
fps_int="$(printf '%s' "$fps" | cut -d. -f1)"
181+
if [ "$fps_int" -lt "$lo" ] || [ "$fps_int" -gt "$hi" ]; then
182+
final="FAIL"
183+
log_fail "$TESTNAME : FAIL (fps=$fps outside ${lo}-${hi})"
184+
fi
185+
fi
186+
fi
187+
188+
case "$final" in
189+
PASS)
190+
log_pass "$TESTNAME : PASS"
71191
echo "$TESTNAME PASS" > "$RES_FILE"
72192
exit 0
73-
else
74-
log_fail "$TESTNAME : Test Failed"
193+
;;
194+
*)
75195
echo "$TESTNAME FAIL" > "$RES_FILE"
76196
exit 1
77-
fi
78-
79-
log_info "------------------- Completed $TESTNAME Testcase ------------------------"
80-
exit 0
197+
;;
198+
esac

0 commit comments

Comments
 (0)