diff --git a/Runner/suites/Multimedia/Audio/AudioPlayback/AudioPlayback.yaml b/Runner/suites/Multimedia/Audio/AudioPlayback/AudioPlayback.yaml index 357fdd7f..7e3dfe64 100644 --- a/Runner/suites/Multimedia/Audio/AudioPlayback/AudioPlayback.yaml +++ b/Runner/suites/Multimedia/Audio/AudioPlayback/AudioPlayback.yaml @@ -27,10 +27,11 @@ params: NET_PROBE_ROUTE_IP: "1.1.1.1" # IP used for route probing, default: 1.1.1.1 NET_PING_HOST: "8.8.8.8" # Host used for ping reachability check, default: 8.8.8.8 RES_SUFFIX: "" # Suffix for unique result file and log directory (e.g., "Config1" generates AudioPlayback_Config1.res and results/AudioPlayback_Config1/), default: unset + LAVA_TESTCASE_ID: "AudioPlayback" # Unique testcase ID written into the .res file for LAVA, default: AudioPlayback run: steps: - REPO_PATH=$PWD - cd Runner/suites/Multimedia/Audio/AudioPlayback/ - - ./run.sh --backend "${AUDIO_BACKEND}" --sink "${SINK_CHOICE}" --clip-name "${CLIP_NAMES}" --clip-filter "${CLIP_FILTER}" --loops "${LOOPS}" --timeout "${TIMEOUT}" --strict "${STRICT}" --audio-clips-path "${AUDIO_CLIPS_BASE_DIR}" --res-suffix "${RES_SUFFIX}" --ssid "${SSID}" --password "${PASSWORD}" || true + - ./run.sh --backend "${AUDIO_BACKEND}" --sink "${SINK_CHOICE}" --clip-name "${CLIP_NAMES}" --clip-filter "${CLIP_FILTER}" --loops "${LOOPS}" --timeout "${TIMEOUT}" --strict "${STRICT}" --audio-clips-path "${AUDIO_CLIPS_BASE_DIR}" --res-suffix "${RES_SUFFIX}" --lava-testcase-id "${LAVA_TESTCASE_ID}" --ssid "${SSID}" --password "${PASSWORD}" || true - $REPO_PATH/Runner/utils/send-to-lava.sh AudioPlayback${RES_SUFFIX:+_${RES_SUFFIX}}.res diff --git a/Runner/suites/Multimedia/Audio/AudioPlayback/Read_me.md b/Runner/suites/Multimedia/Audio/AudioPlayback/Read_me.md index d97c3f8c..9cbf64b0 100644 --- a/Runner/suites/Multimedia/Audio/AudioPlayback/Read_me.md +++ b/Runner/suites/Multimedia/Audio/AudioPlayback/Read_me.md @@ -14,6 +14,10 @@ This suite automates the validation of audio playback capabilities on Qualcomm L - Use descriptive names (e.g., play_48KHz_8b_2ch) for specific formats - Auto-discovery mode tests all available clips - **Clip filtering**: Filter tests by sample rate, bit rate, or channel configuration +- **CI/LAVA integration**: + - Unique result file suffixes prevent file collisions in parallel test runs + - Unique testcase IDs prevent LAVA testcase ID collisions + - Enables running multiple AudioPlayback configurations simultaneously in CI - Plays audio clips with configurable format, duration, and loop count - **Network operations are optional**: By default, no network connection is attempted. Use `--enable-network-download` to enable downloading missing audio files - Automatically downloads and extracts audio assets if missing @@ -226,6 +230,7 @@ PASSWORD Wi-Fi password for network connection unset NET_PROBE_ROUTE_IP IP used for route probing (default: 1.1.1.1) 1.1.1.1 NET_PING_HOST Host used for ping reachability check 8.8.8.8 RES_SUFFIX Suffix for unique result file and log directory unset +LAVA_TESTCASE_ID Unique testcase ID written into the .res file for LAVA AudioPlayback CLI Options @@ -244,6 +249,7 @@ Option Description --enable-network-download Enable network operations to download missing audio files (default: disabled) --audio-clips-path Custom location for audio clips (for CI with pre-staged clips) --res-suffix Suffix for unique result file and log directory (e.g., "Config01" generates AudioPlayback_Config01.res and results/AudioPlayback_Config01/) +--lava-testcase-id Unique testcase ID written into the .res file for LAVA (e.g., "AudioPlayback_Config01") --junit Write JUnit XML output --verbose Enable verbose logging --help Show usage instructions @@ -361,6 +367,31 @@ AudioPlayback_Config01.res AudioPlayback_Config07.res ``` +**Example 7: CI/LAVA workflow with unique testcase IDs (prevents LAVA collisions)** +``` +# Using --lava-testcase-id ensures unique testcase IDs in LAVA results +# This prevents testcase ID collisions when running multiple AudioPlayback configs in parallel + +sh-5.3# ./run.sh --clip-name "playback_config1" --res-suffix "Config01" --lava-testcase-id "AudioPlayback_Config01" --audio-clips-path /home/AudioClips/ --no-extract-assets +[INFO] 2026-01-22 18:10:15 - Using unique result file: ./AudioPlayback_Config01.res +[PASS] 2026-01-22 18:10:45 - AudioPlayback PASS + +sh-5.3# cat AudioPlayback_Config01.res +AudioPlayback_Config01 PASS + +sh-5.3# ./run.sh --clip-name "playback_config7" --res-suffix "Config07" --lava-testcase-id "AudioPlayback_Config07" --audio-clips-path /home/AudioClips/ --no-extract-assets +[INFO] 2026-01-22 18:11:30 - Using unique result file: ./AudioPlayback_Config07.res +[PASS] 2026-01-22 18:12:00 - AudioPlayback PASS + +sh-5.3# cat AudioPlayback_Config07.res +AudioPlayback_Config07 PASS + +# LAVA will receive unique testcase IDs: +# - AudioPlayback_Config01 PASS +# - AudioPlayback_Config07 PASS +# No testcase ID collisions! +``` + Results: - Results are stored in: results/AudioPlayback/ (or results/AudioPlayback_/ when using --res-suffix) - Summary result file: AudioPlayback.res (or AudioPlayback_.res when using --res-suffix) diff --git a/Runner/suites/Multimedia/Audio/AudioPlayback/run.sh b/Runner/suites/Multimedia/Audio/AudioPlayback/run.sh index 83fafa9b..0f91871c 100755 --- a/Runner/suites/Multimedia/Audio/AudioPlayback/run.sh +++ b/Runner/suites/Multimedia/Audio/AudioPlayback/run.sh @@ -46,17 +46,20 @@ if [ -d /run/systemd/system ] && command -v systemctl >/dev/null 2>&1; then fi TESTNAME="AudioPlayback" +RESULT_TESTNAME="$TESTNAME" RES_SUFFIX="" # Optional suffix for unique result files (e.g., "Config1") # RES_FILE will be set after parsing command-line arguments -# Pre-parse --res-suffix for early failure handling -# This ensures unique result files even if setup fails in parallel CI runs +# Pre-parse --res-suffix and --lava-testcase-id for early failure handling +# This ensures unique result files and unique testcase IDs even if setup fails in parallel CI runs prev_arg="" for arg in "$@"; do case "$prev_arg" in --res-suffix) RES_SUFFIX="$arg" - break + ;; + --lava-testcase-id) + RESULT_TESTNAME="$arg" ;; esac prev_arg="$arg" @@ -183,6 +186,10 @@ while [ $# -gt 0 ]; do RES_SUFFIX="$2" shift 2 ;; + --lava-testcase-id) + RESULT_TESTNAME="$2" + shift 2 + ;; --loops) LOOPS="$2" shift 2 @@ -306,7 +313,7 @@ trap 'audio_cleanup_started_daemons' EXIT HUP INT TERM if { [ -n "$CLIP_NAMES" ] || [ -n "$CLIP_FILTER" ]; } && { [ -n "$FORMATS" ] || [ -n "$DURATIONS" ]; }; then log_error "Cannot mix clip discovery parameters (--clip-name, --clip-filter) with legacy matrix parameters (--formats, --durations)" log_error "Please use either clip discovery mode OR legacy matrix mode, not both" - echo "$TESTNAME SKIP" > "$RES_FILE" + echo "$RESULT_TESTNAME SKIP" > "$RES_FILE" exit 0 fi @@ -368,7 +375,7 @@ fi test_path="$(find_test_case_by_name "$TESTNAME" 2>/dev/null || echo "$SCRIPT_DIR")" if ! cd "$test_path"; then log_error "cd failed: $test_path" - echo "$TESTNAME FAIL" >"$RES_FILE" + echo "$RESULT_TESTNAME FAIL" >"$RES_FILE" exit 1 fi @@ -443,14 +450,14 @@ if [ "$TOP_LEVEL_RUN" -eq 1 ]; then else log_error "Failed to download or extract audio clips from: $AUDIO_TAR_URL" log_skip "$TESTNAME SKIP - Audio clips download failed" - echo "$TESTNAME SKIP" >"$RES_FILE" + echo "$RESULT_TESTNAME SKIP" >"$RES_FILE" exit 0 fi else log_skip "$TESTNAME SKIP - Required audio clips not found locally and network download disabled" log_info "To download audio clips, run with: --enable-network-download" log_info "Or manually download from: $AUDIO_TAR_URL" - echo "$TESTNAME SKIP" >"$RES_FILE" + echo "$RESULT_TESTNAME SKIP" >"$RES_FILE" exit 0 fi fi @@ -488,13 +495,13 @@ if [ -z "$AUDIO_BACKEND" ]; then log_info "Using backend: alsa (direct minimal-build fallback)" else log_skip "$TESTNAME SKIP - no audio backend running" - echo "$TESTNAME SKIP" >"$RES_FILE" + echo "$RESULT_TESTNAME SKIP" >"$RES_FILE" exit 0 fi fi else log_skip "$TESTNAME SKIP - no audio backend running" - echo "$TESTNAME SKIP" >"$RES_FILE" + echo "$RESULT_TESTNAME SKIP" >"$RES_FILE" exit 0 fi fi @@ -558,7 +565,7 @@ fi if [ "$backend_ok" -ne 1 ]; then log_skip "$TESTNAME SKIP - backend not available: $AUDIO_BACKEND" - echo "$TESTNAME SKIP" >"$RES_FILE" + echo "$RESULT_TESTNAME SKIP" >"$RES_FILE" exit 0 fi @@ -573,7 +580,7 @@ case "$AUDIO_BACKEND" in export AUDIO_SYSTEMD_MANAGED else log_skip "$TESTNAME SKIP - missing PipeWire playback utility" - echo "$TESTNAME SKIP" >"$RES_FILE" + echo "$RESULT_TESTNAME SKIP" >"$RES_FILE" exit 0 fi fi @@ -587,7 +594,7 @@ case "$AUDIO_BACKEND" in export AUDIO_SYSTEMD_MANAGED else log_skip "$TESTNAME SKIP - missing PulseAudio playback utility" - echo "$TESTNAME SKIP" >"$RES_FILE" + echo "$RESULT_TESTNAME SKIP" >"$RES_FILE" exit 0 fi fi @@ -595,13 +602,13 @@ case "$AUDIO_BACKEND" in alsa) if ! check_dependencies aplay; then log_skip "$TESTNAME SKIP - missing ALSA playback utility" - echo "$TESTNAME SKIP" >"$RES_FILE" + echo "$RESULT_TESTNAME SKIP" >"$RES_FILE" exit 0 fi ;; *) log_skip "$TESTNAME SKIP - unsupported backend: $AUDIO_BACKEND" - echo "$TESTNAME SKIP" >"$RES_FILE" + echo "$RESULT_TESTNAME SKIP" >"$RES_FILE" exit 0 ;; esac @@ -624,7 +631,7 @@ if [ "$AUDIO_BACKEND" = "pipewire" ]; then export AUDIO_SYSTEMD_MANAGED else log_skip "$TESTNAME SKIP - PipeWire control-plane not responsive" - echo "$TESTNAME SKIP" > "$RES_FILE" + echo "$RESULT_TESTNAME SKIP" > "$RES_FILE" exit 0 fi fi @@ -647,7 +654,7 @@ elif [ "$AUDIO_BACKEND" = "pulseaudio" ]; then export AUDIO_SYSTEMD_MANAGED else log_skip "$TESTNAME SKIP - PulseAudio control-plane not responsive" - echo "$TESTNAME SKIP" > "$RES_FILE" + echo "$RESULT_TESTNAME SKIP" > "$RES_FILE" exit 0 fi fi @@ -684,7 +691,7 @@ esac if [ -z "$SINK_ID" ]; then log_skip "$TESTNAME SKIP - requested sink '$SINK_CHOICE' not found for $AUDIO_BACKEND" - echo "$TESTNAME SKIP" >"$RES_FILE" + echo "$RESULT_TESTNAME SKIP" >"$RES_FILE" exit 0 fi @@ -742,13 +749,13 @@ if [ "$USE_CLIP_DISCOVERY" = "true" ]; then if [ -n "$CLIP_NAMES" ] || [ -n "$CLIP_FILTER" ]; then CLIPS_TO_TEST="$(discover_and_filter_clips "$CLIP_NAMES" "$CLIP_FILTER")" || { log_skip "$TESTNAME SKIP - Invalid clip/config name(s) provided" - echo "$TESTNAME SKIP" > "$RES_FILE" + echo "$RESULT_TESTNAME SKIP" > "$RES_FILE" exit 0 } else CLIPS_TO_TEST="$(discover_audio_clips)" || { log_skip "$TESTNAME SKIP - No audio clips found in $clips_dir" - echo "$TESTNAME SKIP" > "$RES_FILE" + echo "$RESULT_TESTNAME SKIP" > "$RES_FILE" exit 0 } fi @@ -1059,23 +1066,23 @@ log_info "Summary: total=$total pass=$pass fail=$fail skip=$skip" if [ "$total" -eq 0 ] && [ "$pass" -eq 0 ] && [ "$fail" -eq 0 ]; then log_skip "$TESTNAME SKIP - no runnable playback testcases" - echo "$TESTNAME SKIP" > "$RES_FILE" + echo "$RESULT_TESTNAME SKIP" > "$RES_FILE" exit 0 fi # --- Proper exit codes: PASS=0, FAIL=1, SKIP-only=0 --- if [ "$pass" -eq 0 ] && [ "$fail" -eq 0 ] && [ "$skip" -gt 0 ]; then log_skip "$TESTNAME SKIP" - echo "$TESTNAME SKIP" > "$RES_FILE" + echo "$RESULT_TESTNAME SKIP" > "$RES_FILE" exit 0 fi if [ "$suite_rc" -eq 0 ]; then log_pass "$TESTNAME PASS" - echo "$TESTNAME PASS" > "$RES_FILE" + echo "$RESULT_TESTNAME PASS" > "$RES_FILE" exit 0 fi log_fail "$TESTNAME FAIL" -echo "$TESTNAME FAIL" > "$RES_FILE" +echo "$RESULT_TESTNAME FAIL" > "$RES_FILE" exit 1