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
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ params:
DMESG_SCAN: 1 # Scan dmesg for errors after playback, default: 1
VERBOSE: 0 # Enable verbose logging, default: 0
EXTRACT_AUDIO_ASSETS: true # Download/extract audio assets if missing, default: true
ENABLE_NETWORK_DOWNLOAD: false # Enable network download of missing audio files, default: false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you still need SSID and PASSWORD if the network is enabled.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @mwasilew,

Thanks for the feedback. Fixed both issues:

  1. Made the commit title more descriptive
  2. SSID/PASSWORD: Added them back to the YAML params and run command - definitely needed for network download scenarios

Please review and let me know if any other changes are required.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good!

AUDIO_CLIPS_BASE_DIR: "" # Custom path to pre-staged audio clips (for CI), default: unset
SSID: "" # Wi-Fi SSID for network connection, default: unset
PASSWORD: "" # Wi-Fi password for network connection, default: unset
NET_PROBE_ROUTE_IP: "1.1.1.1" # IP used for route probing, default: 1.1.1.1
Expand All @@ -27,5 +29,5 @@ run:
steps:
- REPO_PATH=$PWD
- cd Runner/suites/Multimedia/Audio/AudioPlayback/
- ./run.sh --backend "${AUDIO_BACKEND}" --sink "${SINK_CHOICE}" --format "${FORMAT}" --durations "${DURATIONS}" --loops "${LOOPS}" --timeout "${TIMEOUT}" --strict "${STRICT}" --ssid "${SSID}" --password "${PASSWORD}" || true
- $REPO_PATH/Runner/utils/send-to-lava.sh AudioPlayback.res || true
- ./run.sh --backend "${AUDIO_BACKEND}" --sink "${SINK_CHOICE}" --formats "${FORMATS}" --durations "${DURATIONS}" --loops "${LOOPS}" --timeout "${TIMEOUT}" --strict "${STRICT}" --audio-clips-path "${AUDIO_CLIPS_BASE_DIR}" --ssid "${SSID}" --password "${PASSWORD}" || true
- $REPO_PATH/Runner/utils/send-to-lava.sh AudioPlayback.res || true
87 changes: 56 additions & 31 deletions Runner/suites/Multimedia/Audio/AudioPlayback/Read_me.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ This suite automates the validation of audio playback capabilities on Qualcomm L

- Supports **PipeWire** and **PulseAudio** backends
- 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
- Validates playback using multiple evidence sources:
- PipeWire/PulseAudio streaming state
Expand Down Expand Up @@ -91,6 +92,23 @@ SSID="MyNetwork" PASSWORD="MyPassword" ./run-test.sh AudioPlayback
# Override network probe targets (useful in restricted networks)
NET_PROBE_ROUTE_IP=192.168.1.1 NET_PING_HOST=192.168.1.254 ./run-test.sh AudioPlayback

# Run without network (requires local clips)
./run.sh

# Enable network download for missing clips
./run.sh --enable-network-download

# Provide WiFi credentials (auto-enables download)
./run.sh --ssid "MyNetwork" --password "MyPassword"

# Offline mode with local clips only
./run.sh --no-extract-assets

# CI workflow: Use pre-staged clips at custom location
./run.sh --audio-clips-path /tmp/ci-audio-staging/AudioClips

# CI workflow: Via environment variable
AUDIO_CLIPS_BASE_DIR="/tmp/ci-audio-staging/AudioClips" ./run-test.sh AudioPlayback

**Directly from Test Directory**
cd Runner/suites/Multimedia/Audio/AudioPlayback
Expand All @@ -112,38 +130,42 @@ cd Runner/suites/Multimedia/Audio/AudioPlayback


Environment Variables:
Variable Description Default
AUDIO_BACKEND Selects backend: pipewire or pulseaudio auto-detect
SINK_CHOICE Playback sink: speakers or null speakers
FORMATS Audio formats: e.g. wav wav
DURATIONS Playback durations: short, medium, long short
LOOPS Number of playback loops 1
TIMEOUT Playback timeout per loop (e.g., 15s, 0=none) 0
STRICT Enable strict mode (fail on any error) 0
DMESG_SCAN Scan dmesg for errors after playback 1
VERBOSE Enable verbose logging 0
EXTRACT_AUDIO_ASSETS Download/extract audio assets if missing true
JUNIT_OUT Path to write JUnit XML output unset
SSID Wi-Fi SSID for network connection unset
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
Variable Description Default
AUDIO_BACKEND Selects backend: pipewire or pulseaudio auto-detect
SINK_CHOICE Playback sink: speakers or null speakers
FORMATS Audio formats: e.g. wav wav
DURATIONS Playback durations: short, medium, long short
LOOPS Number of playback loops 1
TIMEOUT Playback timeout per loop (e.g., 15s, 0=none) 0
STRICT Enable strict mode (fail on any error) 0
DMESG_SCAN Scan dmesg for errors after playback 1
VERBOSE Enable verbose logging 0
EXTRACT_AUDIO_ASSETS Download/extract audio assets if missing true
ENABLE_NETWORK_DOWNLOAD Enable network download of missing audio files false
AUDIO_CLIPS_BASE_DIR Custom path to pre-staged audio clips (CI use) unset
JUNIT_OUT Path to write JUnit XML output unset
SSID Wi-Fi SSID for network connection unset
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


CLI Options
Option Description
--backend Select backend: pipewire or pulseaudio
--sink Playback sink: speakers or null
--formats Audio formats (space/comma separated): e.g. wav
--durations Playback durations: short, medium, long
--loops Number of playback loops
--timeout Playback timeout per loop (e.g., 15s)
--strict Enable strict mode
--no-dmesg Disable dmesg scan
--no-extract-assets Disable asset extraction
--junit <file.xml> Write JUnit XML output
--verbose Enable verbose logging
--help Show usage instructions
Option Description
--backend Select backend: pipewire or pulseaudio
--sink Playback sink: speakers or null
--formats Audio formats (space/comma separated): e.g. wav
--durations Playback durations: short, medium, long
--loops Number of playback loops
--timeout Playback timeout per loop (e.g., 15s)
--strict Enable strict mode
--no-dmesg Disable dmesg scan
--no-extract-assets Disable asset extraction entirely (skips all asset operations)
--enable-network-download Enable network operations to download missing audio files (default: disabled)
--audio-clips-path <path> Custom location for audio clips (for CI with pre-staged clips)
--junit <file.xml> Write JUnit XML output
--verbose Enable verbose logging
--help Show usage instructions

```

Expand Down Expand Up @@ -178,8 +200,10 @@ Diagnostic logs: dmesg snapshots, mixer dumps, playback logs per test case
- The script validates the presence of required tools before executing tests; missing tools result in SKIP.
- If any critical tool is missing, the script exits with an error message.
- Logs include dmesg snapshots, mixer dumps, and playback logs.
- Asset download requires network connectivity.
- Pass Wi-Fi credentials via SSID and PASSWORD environment variables to enable network access for asset downloads and playback validation.
- **Network operations are disabled by default**. Use `--enable-network-download` to download missing audio files.
- Pass Wi-Fi credentials via `--ssid` and `--password` CLI flags (or SSID/PASSWORD environment variables) to auto-enable network download.
- If audio clips are present locally, the test runs without any network operations (offline-capable).
- If clips are missing and network download is disabled, the test will SKIP with a helpful message.
- You can override default network probe targets using NET_PROBE_ROUTE_IP and NET_PING_HOST to avoid connectivity-related failures in restricted environments.
- Evidence-based PASS/FAIL logic ensures reliability even if backend quirks occur.

Expand All @@ -188,3 +212,4 @@ Diagnostic logs: dmesg snapshots, mixer dumps, playback logs per test case
SPDX-License-Identifier: BSD-3-Clause-Clear
(C) Qualcomm Technologies, Inc. and/or its subsidiaries.


114 changes: 79 additions & 35 deletions Runner/suites/Multimedia/Audio/AudioPlayback/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ STRICT="${STRICT:-0}"
DMESG_SCAN="${DMESG_SCAN:-1}"
VERBOSE=0
EXTRACT_AUDIO_ASSETS="${EXTRACT_AUDIO_ASSETS:-true}"
ENABLE_NETWORK_DOWNLOAD="${ENABLE_NETWORK_DOWNLOAD:-false}" # Default: no network operations
AUDIO_CLIPS_BASE_DIR="${AUDIO_CLIPS_BASE_DIR:-}" # Custom path for audio clips (CI use)

# Network bring-up knobs (match video behavior)
if [ -z "${NET_STABILIZE_SLEEP:-}" ]; then
Expand All @@ -88,6 +90,8 @@ Usage: $0 [options]
--durations "short|short medium|short medium long"
--loops N
--timeout SECS # set 0 to disable watchdog
--enable-network-download
--audio-clips-path PATH # Custom location for audio clips (CI use)
--strict
--no-dmesg
--no-extract-assets
Expand Down Expand Up @@ -136,6 +140,14 @@ while [ $# -gt 0 ]; do
EXTRACT_AUDIO_ASSETS=false
shift
;;
--enable-network-download)
ENABLE_NETWORK_DOWNLOAD=true
shift
;;
--audio-clips-path)
AUDIO_CLIPS_BASE_DIR="$2"
shift 2
;;
--ssid)
# shellcheck disable=SC2034
SSID="$2"
Expand All @@ -161,6 +173,12 @@ while [ $# -gt 0 ]; do
esac
done

# Auto-enable network download if WiFi credentials provided
if [ -n "$SSID" ] && [ -n "$PASSWORD" ]; then
log_info "WiFi credentials provided, auto-enabling network download"
ENABLE_NETWORK_DOWNLOAD=true
fi

# Ensure we run from the testcase dir
test_path="$(find_test_case_by_name "$TESTNAME" 2>/dev/null || echo "$SCRIPT_DIR")"
if ! cd "$test_path"; then
Expand All @@ -178,7 +196,13 @@ else
log_info "Platform Details: unknown"
fi

log_info "Args: backend=${AUDIO_BACKEND:-auto} sink=$SINK_CHOICE loops=$LOOPS timeout=$TIMEOUT formats='$FORMATS' durations='$DURATIONS' strict=$STRICT dmesg=$DMESG_SCAN extract=$EXTRACT_AUDIO_ASSETS"
# Export AUDIO_CLIPS_BASE_DIR for use by resolve_clip() in audio_common.sh
if [ -n "$AUDIO_CLIPS_BASE_DIR" ]; then
export AUDIO_CLIPS_BASE_DIR
log_info "Using custom audio clips path: $AUDIO_CLIPS_BASE_DIR"
fi

log_info "Args: backend=${AUDIO_BACKEND:-auto} sink=$SINK_CHOICE loops=$LOOPS timeout=$TIMEOUT formats='$FORMATS' durations='$DURATIONS' strict=$STRICT dmesg=$DMESG_SCAN extract=$EXTRACT_AUDIO_ASSETS network_download=$ENABLE_NETWORK_DOWNLOAD clips_path=${AUDIO_CLIPS_BASE_DIR:-default}"

# --- Rootfs minimum size check (mirror video policy) ---
if [ "$TOP_LEVEL_RUN" -eq 1 ]; then
Expand All @@ -187,25 +211,51 @@ else
log_info "Sub-run: skipping rootfs size check (already performed)."
fi

# --- Network preflight identical to video gating ---
# --- Smart network gating: only connect if needed ---
if [ "$TOP_LEVEL_RUN" -eq 1 ]; then
if [ "${EXTRACT_AUDIO_ASSETS}" = "true" ]; then
NET_RC="1"

if command -v check_network_status_rc >/dev/null 2>&1; then
check_network_status_rc
NET_RC="$?"
elif command -v check_network_status >/dev/null 2>&1; then
check_network_status >/dev/null 2>&1
NET_RC="$?"
fi

if [ "$NET_RC" -ne 0 ]; then
video_step "" "Bring network online (Wi-Fi credentials if provided)"
ensure_network_online || true
sleep "${NET_STABILIZE_SLEEP}"
# First check: Do we have all files we need?
if audio_check_clips_available "$FORMATS" "$DURATIONS"; then
log_info "All required audio clips present locally, skipping all network operations"
else
sleep "${NET_STABILIZE_SLEEP}"
# Files missing - check if network download is enabled
if [ "${ENABLE_NETWORK_DOWNLOAD}" = "true" ]; then
log_info "Audio clips missing, network download enabled - bringing network online"
# Now check network status and bring up if needed
NET_RC="1"
if command -v check_network_status_rc >/dev/null 2>&1; then
check_network_status_rc
NET_RC="$?"
elif command -v check_network_status >/dev/null 2>&1; then
check_network_status >/dev/null 2>&1
NET_RC="$?"
fi

if [ "$NET_RC" -ne 0 ]; then
video_step "" "Bring network online (Wi-Fi credentials if provided)"
ensure_network_online || true
sleep "${NET_STABILIZE_SLEEP}"
else
sleep "${NET_STABILIZE_SLEEP}"
fi

# Download and extract audio clips tarball
log_info "Downloading audio clips from: $AUDIO_TAR_URL"
if audio_fetch_assets_from_url "$AUDIO_TAR_URL"; then
log_info "Audio clips downloaded and extracted successfully"
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"
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"
exit 0
fi
fi
fi
else
Expand Down Expand Up @@ -323,28 +373,22 @@ for fmt in $FORMATS; do
continue
fi

# Check if clip is available (should have been downloaded at top level if needed)
if [ "${EXTRACT_AUDIO_ASSETS}" = "true" ]; then
if [ -f "$clip" ] && [ -s "$clip" ]; then
if [ -s "$clip" ]; then
CLIP_BYTES="$(wc -c < "$clip" 2>/dev/null || echo 0)"
log_info "[$case_name] Clip already present: $clip (${CLIP_BYTES} bytes) — skipping fetch/extract."
log_info "[$case_name] Using clip: $clip (${CLIP_BYTES} bytes)"
else
log_info "[$case_name] Preparing assets for clip: $clip (not found locally)"
log_info "[$case_name] Attempting fetch/extract from: $AUDIO_TAR_URL"

audio_ensure_clip_ready "$clip" "$AUDIO_TAR_URL"
rc=$?

if [ "$rc" -eq 0 ] && [ -f "$clip" ]; then
CLIP_BYTES="$(wc -c < "$clip" 2>/dev/null || echo 0)"
log_info "[$case_name] Clip ready: $clip (${CLIP_BYTES} bytes)"
fi

if [ "$rc" -eq 2 ] || [ "$rc" -eq 1 ]; then
log_skip "[$case_name] SKIP: Required clip missing and network unavailable or fetch failed."
echo "$case_name SKIP (clip missing)" >> "$LOGDIR/summary.txt"
skip=$((skip + 1))
continue
# Clip missing or empty - this shouldn't happen if top-level download succeeded
log_skip "[$case_name] SKIP: Clip not available: $clip"
if [ "${ENABLE_NETWORK_DOWNLOAD}" = "true" ]; then
log_info "[$case_name] Hint: Clip should have been downloaded at test startup"
else
log_info "[$case_name] Hint: Run with --enable-network-download to download clips"
fi
echo "$case_name SKIP (clip unavailable)" >> "$LOGDIR/summary.txt"
skip=$((skip + 1))
continue
fi
fi

Expand Down
22 changes: 21 additions & 1 deletion Runner/utils/audio_common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ check_audio_daemon() {

# ---------- Assets / clips ----------
resolve_clip() {
fmt="$1"; dur="$2"; base="AudioClips"
fmt="$1"; dur="$2"
base="${AUDIO_CLIPS_BASE_DIR:-AudioClips}"
case "$fmt:$dur" in
wav:short|wav:medium|wav:long) printf '%s\n' "$base/yesterday_48KHz.wav" ;;
*) printf '%s\n' "" ;;
Expand Down Expand Up @@ -735,3 +736,22 @@ alsa_pick_virtual_pcm() {
done
return 1
}


# Check if all required audio clips are available locally
# Usage: audio_check_clips_available "$FORMATS" "$DURATIONS"
# Returns: 0 if all clips present and non-empty, 1 if any clip missing or empty
audio_check_clips_available() {
formats="$1"
durations="$2"

for fmt in $formats; do
for dur in $durations; do
clip="$(resolve_clip "$fmt" "$dur")"
if [ -n "$clip" ] && [ ! -s "$clip" ]; then
return 1 # At least one clip missing or empty
fi
done
done
return 0 # All clips present and non-empty
}
Loading