Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 40 additions & 40 deletions Runner/plans/video_pre-merge.yaml
Original file line number Diff line number Diff line change
@@ -1,55 +1,55 @@
metadata:
format: Lava-Test Test Definition 1.0
name: Video_V4L2_All
description: "Single YAML: pass TARGET, STACK, iris path and downstream FW; run.sh handles the rest"
name: Video_V4L2_With_Secrets
description: "Run Video V4L2 runner; use LAVA secrets for Wi-Fi; auto-args for kodiak vs lemans/monaco; run base & overlay"
maintainer:
- smuppand@qti.qualcomm.com
os:
- openembedded
scope:
- functional

run:
steps:
- cd Runner
- export REPO_ROOT="$PWD"

# --- Job-level inputs (set per device/job) ---
- export TARGET="${TARGET:-}" # e.g. Kodiak|LeMans|Monaco|Talos
- export STACK="${STACK:-both}" # base|overlay|auto|both or synonyms: upstream|downstream
- export IRIS_BIN="${IRIS_BIN:-}" # optional: /path/to/iris_v4l2_test
- export DOWNSTREAM_FW="${DOWNSTREAM_FW:-}" # optional: firmware blob for overlay

# Normalize STACK -> MODE (one-liner synonyms)
- export MODE_NORM="$(printf '%s' "$STACK" | tr '[:upper:]' '[:lower:]' | sed -e 's/^upstream$/base/' -e 's/^downstream$/overlay/')"
- |
case "$MODE_NORM" in base|overlay|auto|both) : ;; *) MODE_NORM="both" ;; esac
echo "TARGET=$TARGET STACK=$STACK MODE_NORM=$MODE_NORM"

# Build args for run.sh (match your CLI exactly)
- export TARGET="${TARGET:-}" # expected values: kodiak | lemans | monaco (case-insensitive)

# Read Wi-Fi credentials from LAVA-provided secrets (exported as env vars in the job)
- export SSID="${LAVA_WIFI_SSID:-}"
- export PASSWORD="${LAVA_WIFI_PASSWORD:-}"

# Build args for run.sh based on TARGET; always pass secrets; add downstream FW only for kodiak
- |
RPATH="$REPO_ROOT/suites/Multimedia/Video/Video_V4L2_Runner/run.sh"
RESFILE="$REPO_ROOT/suites/Multimedia/Video/Video_V4L2_Runner/Video_V4L2_Runner.res"
ARGS=""
[ -n "$TARGET" ] && ARGS="$ARGS --target \"$TARGET\""

if [ -n "$IRIS_BIN" ]; then
ARGS="$ARGS --iris-bin \"$IRIS_BIN\""
else
IB="$(command -v iris_v4l2_test 2>/dev/null || true)"
[ -n "$IB" ] && ARGS="$ARGS --iris-bin \"$IB\""
fi

[ -n "$DOWNSTREAM_FW" ] && ARGS="$ARGS --downstream-fw \"$DOWNSTREAM_FW\""

echo "ARGS=$ARGS"

# Single call: run.sh handles base/overlay/auto and 'both' via its reexec shim
- |
cd "$REPO_ROOT/suites/Multimedia/Video/Video_V4L2_Runner"
TL="$(printf '%s' "${TARGET:-}" | tr '[:upper:]' '[:lower:]')"
case "$TL" in
kodiak)
ARGS="$ARGS --platform kodiak --app /data/vendor/iris_test_app/iris_v4l2_test --ssid \"$SSID\" --password \"$PASSWORD\" --downstream-fw /data/vendor/iris_test_app/vpu20_p1_gen2.mbn"
;;
lemans)
ARGS="$ARGS --platform lemans --ssid \"$SSID\" --password \"$PASSWORD\"" --app /data/vendor/iris_test_app/iris_v4l2_test
;;
monaco)
ARGS="$ARGS --platform monaco --ssid \"$SSID\" --password \"$PASSWORD\"" --app /data/vendor/iris_test_app/iris_v4l2_test
;;
*)
# Unknown or not provided: still pass secrets; platform autodetect in run.sh
ARGS="$ARGS --ssid \"$SSID\" --password \"$PASSWORD\""
;;
esac
echo "TARGET=${TARGET:-unset} ARGS=$ARGS"

# Run base (upstream) then overlay (downstream)
# shellcheck disable=SC2086
sh -lc "$RPATH --stack base $ARGS" || true
"$REPO_ROOT/utils/send-to-lava.sh" "$RESFILE" || true

# shellcheck disable=SC2086
sh -lc "./run.sh $ARGS --mode \"$MODE_NORM\"" || true

# Report result (AUSanity style)
- "$REPO_ROOT/utils/send-to-lava.sh" "$REPO_ROOT/suites/Multimedia/Video/Video_V4L2_Runner/Video_V4L2_Runner.res" || true

# Optional roll-up (ignored if absent)
- "$REPO_ROOT/utils/result_parse.sh" || true
sh -lc "$RPATH --stack overlay $ARGS" || true
"$REPO_ROOT/utils/send-to-lava.sh" "$RESFILE" || true

# Optional roll-up (ignored if absent)
"$REPO_ROOT/utils/result_parse.sh" || true
52 changes: 49 additions & 3 deletions Runner/suites/Multimedia/Video/Video_V4L2_Runner/README_Video.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ The suite includes a **reboot-free video stack switcher** (upstream ↔ downstre
- **CLI parity**
`--stack both` is supported to run the suite twice in one invocation (BASE/upstream pass then OVERLAY/downstream pass).

- **NEW (opt‑in) custom module sources**
You can now point the runner at alternative module locations without disturbing the default flow. If you **do nothing**, behavior is unchanged.
- `--ko-dir DIR[:DIR2:...]` — search these dir(s) for `.ko*` files when resolving modules.
- `--ko-tree ROOT` — use `modprobe -d ROOT` (expects `ROOT/lib/modules/$(uname -r)`).
- `--ko-tar FILE.tar[.gz|.xz|.zst]` — unpack once under `/run/iris_mods/$KVER`; auto-derives a `--ko-tree` or `--ko-dir`.
- `--ko-prefer-custom` — prefer custom sources before the system tree.
- The loader now logs **path resolution** and **load method** lines, e.g.:
- `resolve-path: qcom_iris via KO_DIRS => /data/kos/qcom_iris.ko`
- `load-path: modprobe(system): qcom_iris` / `load-path: insmod: /tmp/qcom_iris.ko`

---

## Features
Expand All @@ -53,6 +63,7 @@ The suite includes a **reboot-free video stack switcher** (upstream ↔ downstre
- **Kodiak firmware live swap** with backup/restore helpers
- **udev refresh + prune** of stale device nodes
- **Waits/retries/sleeps** integrated across networking, downloads, module ops, and app launches (see next section)
- **(Opt‑in)** custom module sources with **non-exported** CLI flags (`--ko-*`); defaults remain untouched

---

Expand All @@ -68,8 +79,8 @@ These are **environment variables** (not user‑visible CLI flags) so your LAVA
| `VIDEO_APP_LAUNCH_SLEEP` | `1` | Sleep (seconds) right before launching `iris_v4l2_test` for each case. |
| `VIDEO_INTER_TEST_SLEEP` | `1` | Sleep (seconds) between cases to allow device/udev to settle. |

> Notes
> - If download **stalls** or the system clock is invalid for TLS, the runner re-checks network health and treats it as **offline** → decode cases **SKIP** (not FAIL).
> Notes
> - If download **stalls** or the system clock is invalid for TLS, the runner re-checks network health and treats it as **offline** → decode cases **SKIP** (not FAIL).
> - Module management includes small internal waits (e.g., `modprobe -r` retry after 200ms, 1s delays around remoteproc/module reloads). These are built‑in, no extra env required.

---
Expand Down Expand Up @@ -138,6 +149,12 @@ cd <target_path>/Runner
| `--stack auto|upstream|downstream|base|overlay|up|down|both` | Select target stack (use `both` for BASE→OVERLAY two-pass) |
| `--platform lemans|monaco|kodiak` | Force platform (else auto-detect) |
| `--downstream-fw PATH` | **Kodiak**: path to DS firmware (e.g. `vpu20_1v.mbn`) |
| `--ko-dir DIR[:DIR2:...]` | *(Opt‑in)* Additional directories to search for `.ko*` files during resolution |
| `--ko-tree ROOT` | *(Opt‑in)* Use `modprobe -d ROOT` (expects `ROOT/lib/modules/$(uname -r)`) |
| `--ko-tar FILE.tar[.gz|.xz|.zst]` | *(Opt‑in)* Unpack once into `/run/iris_mods/$KVER`; auto-derives `--ko-tree` or `--ko-dir` |
| `--ko-prefer-custom` | *(Opt‑in)* Prefer custom module sources (KO_DIRS/KO_TREE) before system |

> **Default remains unchanged.** If you omit all `--ko-*` flags, the runner uses the system module tree and `modinfo`/`modprobe` resolution only.

---

Expand Down Expand Up @@ -288,6 +305,34 @@ export VIDEO_INTER_TEST_SLEEP=3
./run.sh --stack upstream
```

### (Opt‑in) Use custom module sources
**Default behavior is unchanged.** Only use these when you want to test modules from a non-system location.

#### Use a prepared tree (modprobe -d)
```sh
./run.sh --ko-tree /opt/custom-kmods --stack upstream
```

#### Search one or more directories of loose .ko files
```sh
./run.sh --ko-dir /data/kos:/mnt/usb/venus_kos --stack downstream
```

#### Prefer custom before system
```sh
./run.sh --ko-dir /sdcard/kos --ko-prefer-custom --stack upstream
```

#### Unpack a tarball of modules and auto-wire paths
```sh
./run.sh --ko-tar /sdcard/iris_kmods_${KVER}.tar.xz --stack upstream
# The runner unpacks into /run/iris_mods/$KVER and derives --ko-tree or --ko-dir.
```

> While resolving and loading modules, the runner logs lines like:
> - `resolve-path: venus_core via KO_TREE => /run/iris_mods/6.9.0/lib/modules/6.9.0/venus_core.ko`
> - `load-path: insmod: /data/kos/qcom_iris.ko` or `load-path: modprobe(system): qcom_iris`

---

## Troubleshooting
Expand All @@ -304,4 +349,5 @@ export VIDEO_INTER_TEST_SLEEP=3
- **Download fails**
Ensure time is sane (TLS), network is reachable, and provide Wi‑Fi creds via env or `ssid_list.txt`. The downloader uses BusyBox‑compatible flags with retries and a final TLS‑lenient attempt if needed. When the network remains unreachable, the runner **SKIPs** decode cases.

---
---

139 changes: 139 additions & 0 deletions Runner/suites/Multimedia/Video/Video_V4L2_Runner/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ if [ -z "$INIT_ENV" ]; then
fi

# Only source once (idempotent)
# NOTE: We intentionally **do not export** any new vars. They stay local to this shell.
if [ -z "${__INIT_ENV_LOADED:-}" ]; then
# shellcheck disable=SC1090
. "$INIT_ENV"
Expand Down Expand Up @@ -62,6 +63,16 @@ if [ -z "${REPEAT_POLICY:-}" ]; then REPEAT_POLICY="all"; fi
JUNIT_OUT=""
VERBOSE="0"

# --- Stabilizers (opt-in) ---
RETRY_ON_FAIL="0" # extra attempts after a FAIL
POST_TEST_SLEEP="0" # settle time after each case

# --- Custom module source (opt-in; default is untouched) ---
KO_DIRS="" # colon-separated list of dirs that contain .ko files
KO_TREE="" # alt root that has lib/modules/$KVER
KO_TARBALL="" # optional tarball that we unpack once
KO_PREFER_CUSTOM="0" # 1 = try custom first; default 0 = system first

if [ -z "${VIDEO_STACK:-}" ]; then VIDEO_STACK="auto"; fi
if [ -z "${VIDEO_PLATFORM:-}" ]; then VIDEO_PLATFORM=""; fi
if [ -z "${VIDEO_FW_DS:-}" ]; then VIDEO_FW_DS=""; fi
Expand Down Expand Up @@ -94,8 +105,15 @@ Usage: $0 [--config path.json|/path/dir] [--dir DIR] [--pattern GLOB]
[--downstream-fw PATH] [--force]
[--app /path/to/iris_v4l2_test]
[--ssid SSID] [--password PASS]
[--ko-dir DIR[:DIR2:...]] # opt-in: search these dirs for .ko on failure
[--ko-tree ROOT] # opt-in: modprobe -d ROOT (expects lib/modules/\$(uname -r))
[--ko-tar FILE.tar[.gz|.xz]] # opt-in: unpack once under /run/iris_mods/\$KVER, set --ko-tree/--ko-dir accordingly
[--ko-prefer-custom] # opt-in: try custom sources before system
[--app-launch-sleep S] [--inter-test-sleep S]
[--log-flavor NAME] # internal: e.g. upstream or downstream (used by --stack both)
# --- Stabilizers ---
[--retry-on-fail N] # retry up to N times if a case ends FAIL
[--post-test-sleep S] # sleep S seconds after each case
EOF
}

Expand Down Expand Up @@ -190,6 +208,22 @@ while [ $# -gt 0 ]; do
shift
PASSWORD="$1"
;;
--ko-dir)
shift
KO_DIRS="$1"
;;
--ko-tree)
shift
KO_TREE="$1"
;;
--ko-tar)
shift
KO_TARBALL="$1"
;;
--ko-prefer-custom)
KO_PREFER_CUSTOM="1"
;;

--app-launch-sleep)
shift
APP_LAUNCH_SLEEP="$1"
Expand All @@ -202,6 +236,15 @@ while [ $# -gt 0 ]; do
shift
LOG_FLAVOR="$1"
;;
# --- Stabilizers ---
--retry-on-fail)
shift
RETRY_ON_FAIL="$1"
;;
--post-test-sleep)
shift
POST_TEST_SLEEP="$1"
;;
--help|-h)
usage
exit 0
Expand Down Expand Up @@ -234,6 +277,44 @@ export INTER_TEST_SLEEP
# --- EARLY dependency check (bail out fast) ---

# Ensure the app is executable if a path was provided but lacks +x

# --- Optional: unpack a custom module tarball **once** (no env exports) ---
KVER="$(uname -r 2>/dev/null || printf '%s' unknown)"
if [ -n "$KO_TARBALL" ] && [ -f "$KO_TARBALL" ]; then
DEST="/run/iris_mods/$KVER"
if [ ! -d "$DEST" ]; then
mkdir -p "$DEST" 2>/dev/null || true
case "$KO_TARBALL" in
*.tar|*.tar.gz|*.tgz|*.tar.xz|*.txz|*.tar.zst)
if command -v tar >/dev/null 2>&1; then
# best-effort; keep extraction bounded to DEST
tar -xf "$KO_TARBALL" -C "$DEST" 2>/dev/null || true
fi
;;
*)
# not a tar? treat as a directory if user passed one by mistake
:
;;
esac
fi
# decide whether the tar contained a full tree or loose .ko’s
if [ -d "$DEST/lib/modules/$KVER" ]; then
KO_TREE="$DEST"
else
# find first dir that has at least one .ko (bounded depth)
first_ko_dir="$(find "$DEST" -type f -name '*.ko*' -maxdepth 3 2>/dev/null | head -n1 | xargs -r dirname)"
if [ -n "$first_ko_dir" ]; then
if [ -n "$KO_DIRS" ]; then
KO_DIRS="$first_ko_dir:$KO_DIRS"
else
KO_DIRS="$first_ko_dir"
fi
fi
fi
# quiet summary (only if user opted-in)
log_info "Custom module source prepared (tree='${KO_TREE:-none}', dirs='${KO_DIRS:-none}', prefer_custom=$KO_PREFER_CUSTOM)"
fi

if [ -n "$VIDEO_APP" ] && [ -f "$VIDEO_APP" ] && [ ! -x "$VIDEO_APP" ]; then
chmod +x "$VIDEO_APP" 2>/dev/null || true
if [ ! -x "$VIDEO_APP" ]; then
Expand Down Expand Up @@ -497,6 +578,14 @@ if [ "${VIDEO_STACK}" = "both" ]; then
args="$args --inter-test-sleep $(printf %s "$INTER_TEST_SLEEP")"
fi

# --- Stabilizers passthrough ---
if [ -n "${RETRY_ON_FAIL:-}" ]; then
args="$args --retry-on-fail $(printf %s "$RETRY_ON_FAIL")"
fi
if [ -n "${POST_TEST_SLEEP:-}" ]; then
args="$args --post-test-sleep $(printf %s "$POST_TEST_SLEEP")"
fi

printf "%s" "$args"
}

Expand Down Expand Up @@ -564,6 +653,15 @@ log_info "APP=$VIDEO_APP"
if [ -n "$VIDEO_FW_DS" ]; then
log_info "Downstream FW override: $VIDEO_FW_DS"
fi
if [ -n "$KO_TREE$KO_DIRS$KO_TARBALL" ]; then
# print only when user actually provided custom sources
if [ -n "$KO_TREE" ]; then
log_info "Custom module tree (modprobe -d): $KO_TREE"
fi
if [ -n "$KO_DIRS" ]; then
log_info "Custom ko dir(s): $KO_DIRS (prefer_custom=$KO_PREFER_CUSTOM)"
fi
fi
if [ -n "$VIDEO_FW_BACKUP_DIR" ]; then
log_info "FW backup override: $VIDEO_FW_BACKUP_DIR"
fi
Expand Down Expand Up @@ -1019,6 +1117,38 @@ while IFS= read -r cfg; do
fi
fi

# (2) Retry on final failure (extra attempts outside REPEAT loop, before recording results)
if [ "$final" = "FAIL" ] && [ "$RETRY_ON_FAIL" -gt 0 ] 2>/dev/null; then
r=1
log_info "[$id] RETRY_ON_FAIL: up to $RETRY_ON_FAIL additional attempt(s)"
while [ "$r" -le "$RETRY_ON_FAIL" ]; do
# optional delay between retries, reuse REPEAT_DELAY for consistency
if [ "$REPEAT_DELAY" -gt 0 ] 2>/dev/null; then
sleep "$REPEAT_DELAY"
fi

log_info "[$id] retry attempt $r/$RETRY_ON_FAIL"
if video_run_once "$cfg" "$logf" "$TIMEOUT" "$SUCCESS_RE" "$LOGLEVEL"; then
pass_runs=$((pass_runs + 1))
final="PASS"
log_pass "[$id] RETRY succeeded — marking PASS"
break
else
# capture latest rc marker for visibility
rc_val="$(awk -F'=' '/^END-RUN rc=/{print $2}' "$logf" 2>/dev/null | tail -n1 | tr -d ' ')"
if [ -n "$rc_val" ]; then
case "$rc_val" in
139) log_warn "[$id] Retry exited rc=139 (SIGSEGV)." ;;
134) log_warn "[$id] Retry exited rc=134 (SIGABRT)." ;;
137) log_warn "[$id] Retry exited rc=137 (SIGKILL/OOM?)." ;;
*) : ;;
esac
fi
fi
r=$((r + 1))
done
fi

{
printf 'RESULT id=%s mode=%s pretty="%s" final=%s pass_runs=%s fail_runs=%s elapsed=%s\n' \
"$id" "$mode" "$pretty" "$final" "$pass_runs" "$fail_runs" "$elapsed"
Expand Down Expand Up @@ -1052,6 +1182,15 @@ while IFS= read -r cfg; do
fi
fi

# (6) Post-test settle sleep
case "$POST_TEST_SLEEP" in
''|*[!0-9]* )
:
;;
0) : ;;
*) log_info "Post-test sleep ${POST_TEST_SLEEP}s"; sleep "$POST_TEST_SLEEP" ;;
esac

if [ "$MAX" -gt 0 ] && [ "$total" -ge "$MAX" ]; then
log_info "Reached MAX=$MAX tests; stopping"
break
Expand Down
Loading
Loading