From 92fc4e48a0be7d8ee5d19c03829e83e0b463ad74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CAanchal?= Date: Thu, 22 Jan 2026 15:56:04 +0530 Subject: [PATCH 01/16] Add test script to validate USB HID MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The shell script verifies the enumeration of USB Human Interface Devices. Signed-off-by: “Aanchal --- Runner/suites/Kernel/Baseport/usb_hid/run.sh | 66 ++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 Runner/suites/Kernel/Baseport/usb_hid/run.sh diff --git a/Runner/suites/Kernel/Baseport/usb_hid/run.sh b/Runner/suites/Kernel/Baseport/usb_hid/run.sh new file mode 100644 index 00000000..da9effa6 --- /dev/null +++ b/Runner/suites/Kernel/Baseport/usb_hid/run.sh @@ -0,0 +1,66 @@ +#!/bin/sh + +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause-Clear + +# Validate USB HID device detection +# Requires at least one USB HID peripheral (keyboard/mouse, etc.) connected to a USB Host port. + +# Robustly find and source init_env +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +INIT_ENV="" +SEARCH="$SCRIPT_DIR" +while [ "$SEARCH" != "/" ]; do + if [ -f "$SEARCH/init_env" ]; then + INIT_ENV="$SEARCH/init_env" + break + fi + SEARCH=$(dirname "$SEARCH") +done + +if [ -z "$INIT_ENV" ]; then + echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2 + exit 1 +fi + +# Only source if not already loaded (idempotent) +if [ -z "$__INIT_ENV_LOADED" ]; then + # shellcheck disable=SC1090 + . "$INIT_ENV" +fi +# Always source functestlib.sh, using $TOOLS exported by init_env +# shellcheck disable=SC1090,SC1091 +. "$TOOLS/functestlib.sh" + +TESTNAME="usb_hid" +test_path=$(find_test_case_by_name "$TESTNAME") +cd "$test_path" || exit 1 +# shellcheck disable=SC2034 +res_file="./$TESTNAME.res" + +log_info "-----------------------------------------------------------------------------------------" +log_info "-------------------Starting $TESTNAME Testcase----------------------------" +log_info "=== Test Initialization ===" + +# Check if lsusb is installed +check_dependencies lsusb grep + +log_info "=== USB HID device Detection ===" +hid_iface_count="$(lsusb -v 2>/dev/null | grep -i 'Human Interface Device' | wc -l)" + +echo "lsusb -v HID descriptors:" +lsusb -v 2>/dev/null | grep -i 'Human Interface Device' || true + +echo "Number of HID interfaces found: $hid_iface_count" + +if [ "$hid_iface_count" -gt 0 ]; then + log_pass "$TESTNAME : Test Passed - USB HID interface(s) detected" + echo "$TESTNAME PASS" > "$res_file" + exit 0 +else + log_fail "$TESTNAME : Test Failed - No 'Human Interface Device' interface found" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi + +log_info "-------------------Completed $TESTNAME Testcase----------------------------" \ No newline at end of file From 5c78fe1c7387c08eeadcd11b8564a490af72ba75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CAanchal?= Date: Thu, 22 Jan 2026 16:00:57 +0530 Subject: [PATCH 02/16] Add documentation for Runner/../usb_hid/run.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added setup information and basic requirements. This informs the tester of the hardware setup requirement before starting test. Signed-off-by: “Aanchal --- .../suites/Kernel/Baseport/usb_hid/README.md | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 Runner/suites/Kernel/Baseport/usb_hid/README.md diff --git a/Runner/suites/Kernel/Baseport/usb_hid/README.md b/Runner/suites/Kernel/Baseport/usb_hid/README.md new file mode 100644 index 00000000..e632d3b1 --- /dev/null +++ b/Runner/suites/Kernel/Baseport/usb_hid/README.md @@ -0,0 +1,27 @@ +``` +Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +SPDX-License-Identifier: BSD-3-Clause-Clear +``` + +# USB HID Validation + +## Overview + +This shell script executes on the DUT (Device-Under-Test) and verifies enumeration of connected USB Human Interface Devices (HID). + +--- + +## Setup + +- Connect USB HID peripheral(s) to USB port(s) on DUT. +- Only applicable for USB ports that support Host Mode functionality. +- USB HID peripherals examples: Mouse, Keyboard, USB headset, etc. + +--- + +## License + +``` +Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +SPDX-License-Identifier: BSD-3-Clause-Clear +``` From 91cb3bb3509514a1ff045a4a20f5f060ebe27526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CAanchal?= Date: Thu, 22 Jan 2026 16:10:08 +0530 Subject: [PATCH 03/16] Add test definition for usb_hid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Individual test definition is meant to be used for debugging the test script running in LAVA. Signed-off-by: “Aanchal --- .../suites/Kernel/Baseport/usb_hid/usb_hid.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 Runner/suites/Kernel/Baseport/usb_hid/usb_hid.yaml diff --git a/Runner/suites/Kernel/Baseport/usb_hid/usb_hid.yaml b/Runner/suites/Kernel/Baseport/usb_hid/usb_hid.yaml new file mode 100644 index 00000000..7521de49 --- /dev/null +++ b/Runner/suites/Kernel/Baseport/usb_hid/usb_hid.yaml @@ -0,0 +1,16 @@ +metadata: + name: usb-hid + format: "Lava-Test Test Definition 1.0" + description: "This shell script executes on the DUT (Device-Under-Test) and verifies enumeration of connected USB Human Interface Devices (HID)." + os: + - linux + scope: + - functional + +run: + steps: + - REPO_PATH=$PWD + - cd Runner/suites/Kernel/Baseport/usb_hid + - ./run.sh || true + - $REPO_PATH/Runner/utils/send-to-lava.sh usb_hid.res || true + From 3acbc6708219cbfea3d9d1d624c619d84bebaaf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CAanchal?= Date: Thu, 22 Jan 2026 16:46:35 +0530 Subject: [PATCH 04/16] Fix: restore executable bits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: “Aanchal --- Runner/suites/Kernel/Baseport/usb_hid/run.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 Runner/suites/Kernel/Baseport/usb_hid/run.sh diff --git a/Runner/suites/Kernel/Baseport/usb_hid/run.sh b/Runner/suites/Kernel/Baseport/usb_hid/run.sh old mode 100644 new mode 100755 From ca2907d44f6f1c40df1ab4fbb47bb214d8ec8031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CAanchal?= Date: Thu, 22 Jan 2026 17:48:54 +0530 Subject: [PATCH 05/16] Add test script to validate USB MSD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The shell script verifies the enumeration of USB Mass Storage Devices. Signed-off-by: “Aanchal Chaurasia --- Runner/suites/Kernel/Baseport/usb_msd/run.sh | 67 ++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 Runner/suites/Kernel/Baseport/usb_msd/run.sh diff --git a/Runner/suites/Kernel/Baseport/usb_msd/run.sh b/Runner/suites/Kernel/Baseport/usb_msd/run.sh new file mode 100644 index 00000000..b91a25b0 --- /dev/null +++ b/Runner/suites/Kernel/Baseport/usb_msd/run.sh @@ -0,0 +1,67 @@ +#!/bin/sh + +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause-Clear + +# Validate USB Mass Storage device detection +# Requires at least one USB Mass Storage peripheral (USB flash drive, external HDD/SSD, etc.) connected to a USB Host port. + +# Robustly find and source init_env +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +INIT_ENV="" +SEARCH="$SCRIPT_DIR" +while [ "$SEARCH" != "/" ]; do + if [ -f "$SEARCH/init_env" ]; then + INIT_ENV="$SEARCH/init_env" + break + fi + SEARCH=$(dirname "$SEARCH") +done + +if [ -z "$INIT_ENV" ]; then + echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2 + exit 1 +fi + +# Only source if not already loaded (idempotent) +if [ -z "$__INIT_ENV_LOADED" ]; then + # shellcheck disable=SC1090 + . "$INIT_ENV" +fi +# Always source functestlib.sh, using $TOOLS exported by init_env +# shellcheck disable=SC1090,SC1091 +. "$TOOLS/functestlib.sh" + +TESTNAME="usb_msd" +test_path=$(find_test_case_by_name "$TESTNAME") +cd "$test_path" || exit 1 +# shellcheck disable=SC2034 +res_file="./$TESTNAME.res" + +log_info "-----------------------------------------------------------------------------------------" +log_info "-------------------Starting $TESTNAME Testcase----------------------------" +log_info "=== Test Initialization ===" + +# Check if lsusb is installed +check_dependencies lsusb grep + +log_info "=== USB Mass Storage device Detection ===" +# Count interfaces reported as Mass Storage by lsusb -v +msd_iface_count="$(lsusb -v 2>/dev/null | grep -i 'Mass Storage' | wc -l)" + +echo "lsusb -v Mass Storage descriptors:" +lsusb -v 2>/dev/null | grep -i 'Mass Storage' || true + +echo "Number of Mass Storage interfaces found: $msd_iface_count" + +if [ "$msd_iface_count" -gt 0 ]; then + log_pass "$TESTNAME : Test Passed - USB Mass Storage interface(s) detected" + echo "$TESTNAME PASS" > "$res_file" + exit 0 +else + log_fail "$TESTNAME : Test Failed - No 'Mass Storage' interface found" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi + +log_info "-------------------Completed $TESTNAME Testcase----------------------------" From 0f89e5f3ed7ff017c61bd6323857f9c2dfa02c47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CAanchal?= Date: Thu, 22 Jan 2026 17:52:50 +0530 Subject: [PATCH 06/16] Add documentation for Runner/../usb_msd/run.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added setup information and basic requirements. This informs the tester of the hardware setup requirement before starting test. Signed-off-by: “Aanchal Chaurasia --- .../suites/Kernel/Baseport/usb_msd/README.md | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 Runner/suites/Kernel/Baseport/usb_msd/README.md diff --git a/Runner/suites/Kernel/Baseport/usb_msd/README.md b/Runner/suites/Kernel/Baseport/usb_msd/README.md new file mode 100644 index 00000000..25436582 --- /dev/null +++ b/Runner/suites/Kernel/Baseport/usb_msd/README.md @@ -0,0 +1,27 @@ +``` +Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +SPDX-License-Identifier: BSD-3-Clause-Clear +``` + +# USB MSD Validation + +## Overview + +This shell script executes on the DUT (Device-Under-Test) and verifies enumeration of connected USB Mass Storage Devices (MSD). + +--- + +## Setup + +- Connect USB MSD peripheral(s) to USB port(s) on DUT. +- Only applicable for USB ports that support Host Mode functionality. +- USB MSD peripherals examples: USB flash drive, external HDD/SSD, etc. + +--- + +## License + +``` +Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +SPDX-License-Identifier: BSD-3-Clause-Clear +``` From 82ff904e18850ee02ecfe6d7fbe0ad582dba7bb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CAanchal?= Date: Thu, 22 Jan 2026 17:56:24 +0530 Subject: [PATCH 07/16] Add test definition for usb_msd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Individual test definition is meant to be used for debugging the test script running in LAVA. Signed-off-by: “Aanchal Chaurasia --- .../suites/Kernel/Baseport/usb_msd/usb_msd.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 Runner/suites/Kernel/Baseport/usb_msd/usb_msd.yaml diff --git a/Runner/suites/Kernel/Baseport/usb_msd/usb_msd.yaml b/Runner/suites/Kernel/Baseport/usb_msd/usb_msd.yaml new file mode 100644 index 00000000..56f443ab --- /dev/null +++ b/Runner/suites/Kernel/Baseport/usb_msd/usb_msd.yaml @@ -0,0 +1,17 @@ +metadata: + name: usb-msd + format: "Lava-Test Test Definition 1.0" + description: "This shell script executes on the DUT (Device-Under-Test) and verifies enumeration of connected USB Mass Storage Devices (MSD)." + os: + - linux + scope: + - functional + +run: + steps: + - REPO_PATH=$PWD + - cd Runner/suites/Kernel/Baseport/usb_msd + - chmod +x run.sh + - ./run.sh || true + - $REPO_PATH/Runner/utils/send-to-lava.sh usb_msd.res || true + From a6104aaccbb1f42fb823047ca1ae7ae7237abeaf Mon Sep 17 00:00:00 2001 From: Teja Swaroop Moida Date: Thu, 22 Jan 2026 19:35:58 +0530 Subject: [PATCH 08/16] Audio: Reduce AudioPlayback to 10 configs and fix YAML parameter conflicts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Optimized AudioPlayback test suite by reducing configurations from 20 to 10 and resolved YAML parameter conflicts causing LAVA execution failures. Changes: - AudioPlayback: Reduced from 20 to 10 test configurations - Renamed Config1-20 to playback_config1-10 for naming consistency - meta-ar-ci-premerge.yaml: Rebalanced to 5 playback + 5 record tests - Fixed YAML parameter conflicts in both AudioPlayback and AudioRecord - Updated documentation to reflect new configuration structure AudioPlayback reduction (20→10 configs): * Reduced clip configurations from 20 to 10 to optimize test suite size * Updated naming convention: Config1-20 → playback_config1-10 * Modified audio_common.sh to map new 10-clip configuration * Updated sample rate coverage: 8 KHz to 48 KHz * Updated Read_me.md with new configuration table and examples YAML parameter conflict resolution: * AudioPlayback.yaml: Removed --formats and --durations from run command * AudioRecord.yaml: Removed --durations from run command * Fixed "Cannot mix discovery parameters with legacy matrix parameters" error Pre-merge CI rebalancing: * AudioPlayback: 5 tests (playback_config1, 3, 5, 8, 10) * AudioRecord: 5 tests (record_config1, 3, 5, 7, 9) * Total remains 10 test cases with balanced 5+5 split * Uses pre-staged clips at /home/AudioClips/ * Unique result files prevent overwriting in parallel execution Test coverage: - AudioPlayback: 8-48 KHz, 8-32 bit, 1-8 channels - AudioRecord: 8-96 KHz, 1-6 channels - 10 diverse configurations ensure comprehensive audio validation Signed-off-by: Teja Swaroop Moida --- Runner/plans/meta-ar-ci-premerge.yaml | 56 ++--- .../Audio/AudioPlayback/AudioPlayback.yaml | 6 +- .../Multimedia/Audio/AudioPlayback/Read_me.md | 194 ++++++++++-------- .../Multimedia/Audio/AudioPlayback/run.sh | 31 ++- .../Audio/AudioRecord/AudioRecord.yaml | 2 +- Runner/utils/audio_common.sh | 96 +++++---- 6 files changed, 218 insertions(+), 167 deletions(-) diff --git a/Runner/plans/meta-ar-ci-premerge.yaml b/Runner/plans/meta-ar-ci-premerge.yaml index 6d2ee93c..82d0331b 100644 --- a/Runner/plans/meta-ar-ci-premerge.yaml +++ b/Runner/plans/meta-ar-ci-premerge.yaml @@ -13,49 +13,49 @@ run: steps: - cd Runner - # ========== AudioPlayback Test Cases (7 configs) ========== + # ========== AudioPlayback Test Cases (5 configs) ========== - # Playback Test 1: Config1 (16KHz, 16-bit, 2ch) - - $PWD/suites/Multimedia/Audio/AudioPlayback/run.sh --clip-name "Config1" --res-suffix "Config1" --audio-clips-path /home/AudioClips/ --no-extract-assets || true + # Playback Test 1: playback_config1 (8KHz, 8-bit, 1ch) + - $PWD/suites/Multimedia/Audio/AudioPlayback/run.sh --clip-name "playback_config1" --res-suffix "Config1" --audio-clips-path /home/AudioClips/ --no-extract-assets || true - $PWD/utils/send-to-lava.sh $PWD/suites/Multimedia/Audio/AudioPlayback/AudioPlayback_Config1.res || true - # Playback Test 2: Config7 (24KHz, 24-bit, 6ch) - - $PWD/suites/Multimedia/Audio/AudioPlayback/run.sh --clip-name "Config7" --res-suffix "Config7" --audio-clips-path /home/AudioClips/ --no-extract-assets || true - - $PWD/utils/send-to-lava.sh $PWD/suites/Multimedia/Audio/AudioPlayback/AudioPlayback_Config7.res || true + # Playback Test 2: playback_config3 (16KHz, 16-bit, 2ch) + - $PWD/suites/Multimedia/Audio/AudioPlayback/run.sh --clip-name "playback_config3" --res-suffix "Config3" --audio-clips-path /home/AudioClips/ --no-extract-assets || true + - $PWD/utils/send-to-lava.sh $PWD/suites/Multimedia/Audio/AudioPlayback/AudioPlayback_Config3.res || true - # Playback Test 3: Config13 (44.1KHz, 16-bit, 1ch) - - $PWD/suites/Multimedia/Audio/AudioPlayback/run.sh --clip-name "Config13" --res-suffix "Config13" --audio-clips-path /home/AudioClips/ --no-extract-assets || true - - $PWD/utils/send-to-lava.sh $PWD/suites/Multimedia/Audio/AudioPlayback/AudioPlayback_Config13.res || true - - # Playback Test 4: Config15 (48KHz, 8-bit, 2ch) - - $PWD/suites/Multimedia/Audio/AudioPlayback/run.sh --clip-name "Config15" --res-suffix "Config15" --audio-clips-path /home/AudioClips/ --no-extract-assets || true - - $PWD/utils/send-to-lava.sh $PWD/suites/Multimedia/Audio/AudioPlayback/AudioPlayback_Config15.res || true - - # Playback Test 5: Config18 (88.2KHz, 24-bit, 2ch) - - $PWD/suites/Multimedia/Audio/AudioPlayback/run.sh --clip-name "Config18" --res-suffix "Config18" --audio-clips-path /home/AudioClips/ --no-extract-assets || true - - $PWD/utils/send-to-lava.sh $PWD/suites/Multimedia/Audio/AudioPlayback/AudioPlayback_Config18.res || true + # Playback Test 3: playback_config5 (24KHz, 24-bit, 6ch) + - $PWD/suites/Multimedia/Audio/AudioPlayback/run.sh --clip-name "playback_config5" --res-suffix "Config5" --audio-clips-path /home/AudioClips/ --no-extract-assets || true + - $PWD/utils/send-to-lava.sh $PWD/suites/Multimedia/Audio/AudioPlayback/AudioPlayback_Config5.res || true - # Playback Test 6: Config20 (96KHz, 24-bit, 6ch) - - $PWD/suites/Multimedia/Audio/AudioPlayback/run.sh --clip-name "Config20" --res-suffix "Config20" --audio-clips-path /home/AudioClips/ --no-extract-assets || true - - $PWD/utils/send-to-lava.sh $PWD/suites/Multimedia/Audio/AudioPlayback/AudioPlayback_Config20.res || true + # Playback Test 4: playback_config8 (32KHz, 16-bit, 2ch) + - $PWD/suites/Multimedia/Audio/AudioPlayback/run.sh --clip-name "playback_config8" --res-suffix "Config8" --audio-clips-path /home/AudioClips/ --no-extract-assets || true + - $PWD/utils/send-to-lava.sh $PWD/suites/Multimedia/Audio/AudioPlayback/AudioPlayback_Config8.res || true - # Playback Test 7: Config5 (192KHz, 32-bit, 8ch) - - $PWD/suites/Multimedia/Audio/AudioPlayback/run.sh --clip-name "Config5" --res-suffix "Config5" --audio-clips-path /home/AudioClips/ --no-extract-assets || true - - $PWD/utils/send-to-lava.sh $PWD/suites/Multimedia/Audio/AudioPlayback/AudioPlayback_Config5.res || true + # Playback Test 5: playback_config10 (48KHz, 8-bit, 2ch) + - $PWD/suites/Multimedia/Audio/AudioPlayback/run.sh --clip-name "playback_config10" --res-suffix "Config10" --audio-clips-path /home/AudioClips/ --no-extract-assets || true + - $PWD/utils/send-to-lava.sh $PWD/suites/Multimedia/Audio/AudioPlayback/AudioPlayback_Config10.res || true - # ========== AudioRecord Test Cases (3 configs) ========== + # ========== AudioRecord Test Cases (5 configs) ========== # Record Test 1: record_config1 (8KHz, 1ch) - $PWD/suites/Multimedia/Audio/AudioRecord/run.sh --config-name "record_config1" --res-suffix "Config1" --record-seconds 10s || true - $PWD/utils/send-to-lava.sh $PWD/suites/Multimedia/Audio/AudioRecord/AudioRecord_Config1.res || true - # Record Test 2: record_config7 (48KHz, 2ch) + # Record Test 2: record_config3 (16KHz, 2ch) + - $PWD/suites/Multimedia/Audio/AudioRecord/run.sh --config-name "record_config3" --res-suffix "Config3" --record-seconds 10s || true + - $PWD/utils/send-to-lava.sh $PWD/suites/Multimedia/Audio/AudioRecord/AudioRecord_Config3.res || true + + # Record Test 3: record_config5 (32KHz, 2ch) + - $PWD/suites/Multimedia/Audio/AudioRecord/run.sh --config-name "record_config5" --res-suffix "Config5" --record-seconds 10s || true + - $PWD/utils/send-to-lava.sh $PWD/suites/Multimedia/Audio/AudioRecord/AudioRecord_Config5.res || true + + # Record Test 4: record_config7 (48KHz, 2ch) - $PWD/suites/Multimedia/Audio/AudioRecord/run.sh --config-name "record_config7" --res-suffix "Config7" --record-seconds 10s || true - $PWD/utils/send-to-lava.sh $PWD/suites/Multimedia/Audio/AudioRecord/AudioRecord_Config7.res || true - # Record Test 3: record_config10 (96KHz, 6ch) - - $PWD/suites/Multimedia/Audio/AudioRecord/run.sh --config-name "record_config10" --res-suffix "Config10" --record-seconds 10s || true - - $PWD/utils/send-to-lava.sh $PWD/suites/Multimedia/Audio/AudioRecord/AudioRecord_Config10.res || true + # Record Test 5: record_config9 (96KHz, 2ch) + - $PWD/suites/Multimedia/Audio/AudioRecord/run.sh --config-name "record_config9" --res-suffix "Config9" --record-seconds 10s || true + - $PWD/utils/send-to-lava.sh $PWD/suites/Multimedia/Audio/AudioRecord/AudioRecord_Config9.res || true # Parse and report results - $PWD/utils/result_parse.sh diff --git a/Runner/suites/Multimedia/Audio/AudioPlayback/AudioPlayback.yaml b/Runner/suites/Multimedia/Audio/AudioPlayback/AudioPlayback.yaml index ce472e89..c35263f3 100644 --- a/Runner/suites/Multimedia/Audio/AudioPlayback/AudioPlayback.yaml +++ b/Runner/suites/Multimedia/Audio/AudioPlayback/AudioPlayback.yaml @@ -10,7 +10,7 @@ metadata: params: AUDIO_BACKEND: "" # Selects backend: pipewire or pulseaudio, default: auto-detect SINK_CHOICE: "speakers" # Playback sink: speakers or null, default: speakers - CLIP_NAMES: "Config1" # Test specific clips (e.g., "Config1 Config2" or "play_48KHz_8b_2ch"), default: Config1 + CLIP_NAMES: "playback_config1" # Test specific clips (e.g., "playback_config1 playback_config2" or "play_48KHz_8b_2ch"), default: playback_config1 CLIP_FILTER: "" # Filter clips by pattern (e.g., "48KHz" or "16b" or "2ch"), default: unset FORMATS: "wav" # Audio formats: e.g. wav, default: wav DURATIONS: "short" # Playback durations: short, medium, long, default: short @@ -21,7 +21,7 @@ params: 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 - AUDIO_CLIPS_BASE_DIR: "" # Custom path to pre-staged audio clips (for CI), default: unset + AUDIO_CLIPS_BASE_DIR: "/home/AudioClips" # Custom path to pre-staged audio clips (for CI), default: /home/AudioClips 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 @@ -32,5 +32,5 @@ 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}" --formats "${FORMATS}" --durations "${DURATIONS}" --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}" --ssid "${SSID}" --password "${PASSWORD}" || true - $REPO_PATH/Runner/utils/send-to-lava.sh AudioPlayback${RES_SUFFIX:+_${RES_SUFFIX}}.res || true diff --git a/Runner/suites/Multimedia/Audio/AudioPlayback/Read_me.md b/Runner/suites/Multimedia/Audio/AudioPlayback/Read_me.md index 8931813b..1035578e 100644 --- a/Runner/suites/Multimedia/Audio/AudioPlayback/Read_me.md +++ b/Runner/suites/Multimedia/Audio/AudioPlayback/Read_me.md @@ -8,10 +8,10 @@ This suite automates the validation of audio playback capabilities on Qualcomm L ## Features - Supports **PipeWire** and **PulseAudio** backends -- **20-clip test coverage**: Comprehensive validation across diverse audio formats (sample rates: 8KHz-352.8KHz, bit depths: 8b-32b, channels: 1ch-8ch) +- **10-clip test coverage**: Comprehensive validation across diverse audio formats (sample rates: 8KHz-48KHz, bit depths: 8b-32b, channels: 1ch-8ch) - **Flexible clip selection**: - - Use generic config names (Config1-Config20) for easy selection - - Use descriptive names (e.g., play_48KHz_16b_2ch) for specific formats + - Use generic config names (playback_config1-playback_config10) for easy selection + - 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 - Plays audio clips with configurable format, duration, and loop count @@ -28,35 +28,25 @@ This suite automates the validation of audio playback capabilities on Qualcomm L ## Audio Clip Configurations -The test suite includes 20 diverse audio clip configurations covering various sample rates, bit depths, and channel configurations: - -Config Descriptive Name Sample Rate Bit Rate Channels -Config1 play_16KHz_16b_2ch 16 KHz 16-bit 2ch -Config2 play_176.4KHz_24b_1ch 176.4 KHz 24-bit 1ch -Config3 play_176.4KHz_32b_6ch 176.4 KHz 32-bit 6ch -Config4 play_192KHz_16b_6ch 192 KHz 16-bit 6ch -Config5 play_192KHz_32b_8ch 192 KHz 32-bit 8ch -Config6 play_22.050KHz_8b_1ch 22.05 KHz 8-bit 1ch -Config7 play_24KHz_24b_6ch 24 KHz 24-bit 6ch -Config8 play_24KHz_32b_8ch 24 KHz 32-bit 8ch -Config9 play_32KHz_16b_2ch 32 KHz 16-bit 2ch -Config10 play_32KHz_8b_8ch 32 KHz 8-bit 8ch -Config11 play_352.8KHz_32b_1ch 352.8 KHz 32-bit 1ch -Config12 play_384KHz_32b_2ch 384 KHz 32-bit 2ch -Config13 play_44.1KHz_16b_1ch 44.1 KHz 16-bit 1ch -Config14 play_44.1KHz_8b_6ch 44.1 KHz 8-bit 6ch -Config15 play_48KHz_8b_2ch 48 KHz 8-bit 2ch -Config16 play_48KHz_8b_8ch 48 KHz 8-bit 8ch -Config17 play_88.2KHz_16b_8ch 88.2 KHz 16-bit 8ch -Config18 play_88.2KHz_24b_2ch 88.2 KHz 24-bit 2ch -Config19 play_8KHz_8b_1ch 8 KHz 8-bit 1ch -Config20 play_96KHz_24b_6ch 96 KHz 24-bit 6ch +The test suite includes 10 diverse audio clip configurations covering various sample rates, bit depths, and channel configurations: + +Playback Config Descriptive Name Sample Rate Bit Rate Channels +playback_config1 play_16KHz_16b_2ch 16 KHz 16-bit 2ch +playback_config2 play_16KHz_8b_6ch 16 KHz 8-bit 6ch +playback_config3 play_22.050KHz_8b_1ch 22.05 KHz 8-bit 1ch +playback_config4 play_24KHz_24b_6ch 24 KHz 24-bit 6ch +playback_config5 play_24KHz_32b_1ch 24 KHz 32-bit 1ch +playback_config6 play_32KHz_16b_2ch 32 KHz 16-bit 2ch +playback_config7 play_32KHz_8b_8ch 32 KHz 8-bit 8ch +playback_config8 play_44.1KHz_16b_1ch 44.1 KHz 16-bit 1ch +playback_config9 play_48KHz_8b_2ch 48 KHz 8-bit 2ch +playback_config10 play_8KHz_8b_1ch 8 KHz 8-bit 1ch Coverage Summary: -- Sample Rates: 8 KHz, 16 KHz, 22.05 KHz, 24 KHz, 32 KHz, 44.1 KHz, 48 KHz, 88.2 KHz, 96 KHz, 176.4 KHz, 192 KHz, 352.8 KHz, 384 KHz +- Sample Rates: 8 KHz, 16 KHz, 22.05 KHz, 24 KHz, 32 KHz, 44.1 KHz, 48 KHz - Bit Depths: 8-bit, 16-bit, 24-bit, 32-bit - Channel Configurations: 1ch (Mono), 2ch (Stereo), 6ch (5.1 Surround), 8ch (7.1 Surround) -- Total Configurations: 20 unique audio format combinations +- Total Configurations: 10 unique audio format combinations ## Prerequisites @@ -151,21 +141,21 @@ AUDIO_CLIPS_BASE_DIR="/tmp/ci-audio-staging/AudioClips" ./run-test.sh AudioPlayb **Directly from Test Directory** cd Runner/suites/Multimedia/Audio/AudioPlayback -# Test all 20 clips (auto-discovery mode) +# Test all 10 clips (auto-discovery mode) ./run.sh --no-extract-assets -# Test specific clips using Config naming (Config1 to Config20) -./run.sh --no-extract-assets --clip-name "Config1" -./run.sh --no-extract-assets --clip-name "Config1 Config5 Config10" +# Test specific clips using playback_config naming (playback_config1 to playback_config10) +./run.sh --no-extract-assets --clip-name "playback_config1" +./run.sh --no-extract-assets --clip-name "playback_config1 playback_config5 playback_config10" # Test specific clips using descriptive names ./run.sh --no-extract-assets --clip-name "play_48KHz_8b_2ch" ./run.sh --no-extract-assets --clip-name "play_8KHz_8b_1ch" -./run.sh --no-extract-assets --clip-name "play_192KHz_32b_8ch" +./run.sh --no-extract-assets --clip-name "play_44.1KHz_16b_1ch" # Filter clips by sample rate ./run.sh --no-extract-assets --clip-filter "48KHz" -./run.sh --no-extract-assets --clip-filter "192KHz" +./run.sh --no-extract-assets --clip-filter "16KHz" # Filter clips by bit depth ./run.sh --no-extract-assets --clip-filter "16b" @@ -193,8 +183,8 @@ cd Runner/suites/Multimedia/Audio/AudioPlayback ./run.sh --junit results.xml --no-dmesg # CI/LAVA workflow: Generate unique result files for each test -./run.sh --clip-name "Config1" --res-suffix "Config1" --audio-clips-path /home/AudioClips/ --no-extract-assets -./run.sh --clip-name "Config7" --res-suffix "Config7" --audio-clips-path /home/AudioClips/ --no-extract-assets +./run.sh --clip-name "playback_config1" --res-suffix "Config1" --audio-clips-path /home/AudioClips/ --no-extract-assets +./run.sh --clip-name "playback_config7" --res-suffix "Config7" --audio-clips-path /home/AudioClips/ --no-extract-assets # This generates AudioPlayback_Config1.res and AudioPlayback_Config7.res (no overwriting) @@ -224,7 +214,7 @@ CLI Options Option Description --backend Select backend: pipewire or pulseaudio --sink Playback sink: speakers or null ---clip-name Test specific clips using Config1-Config20 or descriptive names (space-separated) +--clip-name Test specific clips using playback_config1-playback_config10 or descriptive names (space-separated) --clip-filter Filter clips by sample rate, bit rate, or channels (space-separated patterns) --formats Audio formats (space/comma separated): e.g. wav --durations Playback durations: short, medium, long @@ -244,77 +234,105 @@ Option Description Sample Output: -**Example 1: Testing specific clip using Config naming** +**Example 1: Testing specific clip using playback_config naming** ``` -sh-5.3# ./run.sh --no-extract-assets --clip-name "Config1" -[INFO] 2025-12-30 11:47:32 - ---------------- Starting AudioPlayback ---------------- -[INFO] 2025-12-30 11:47:32 - Platform Details: machine='Qualcomm Technologies, Inc. Robotics RB3gen2' target='Kodiak' kernel='6.18.0-00393-g27507852413b' arch='aarch64' -[INFO] 2025-12-30 11:47:32 - Args: backend=auto sink=speakers loops=1 timeout=0 formats='wav' durations='short' strict=0 dmesg=1 extract=false network_download=false clips_path=default -[INFO] 2025-12-30 11:47:32 - Using backend: pipewire -[INFO] 2025-12-30 11:47:32 - Routing to sink: id=52 name='Built-in Audio Speaker playback' choice=speakers -[INFO] 2025-12-30 11:47:32 - Using clip discovery mode -[INFO] 2025-12-30 11:47:32 - Discovered 1 clips to test -[INFO] 2025-12-30 11:47:32 - [play_16KHz_16b_2ch] Using clip: yesterday_16KHz_30s_16b_2ch.wav (1922036 bytes) -[INFO] 2025-12-30 11:47:32 - [play_16KHz_16b_2ch] loop 1/1 start=2025-12-30T11:47:32Z clip=yesterday_16KHz_30s_16b_2ch.wav backend=pipewire sink=speakers(52) -[INFO] 2025-12-30 11:47:32 - [play_16KHz_16b_2ch] exec: pw-play -v "AudioClips/yesterday_16KHz_30s_16b_2ch.wav" -[INFO] 2025-12-30 11:48:02 - [play_16KHz_16b_2ch] evidence: pw_streaming=1 pa_streaming=0 alsa_running=1 asoc_path_on=1 pw_log=1 -[PASS] 2025-12-30 11:48:02 - [play_16KHz_16b_2ch] loop 1 OK (rc=0, 30s) -[INFO] 2025-12-30 11:48:02 - Summary: total=1 pass=1 fail=0 skip=0 -[PASS] 2025-12-30 11:48:02 - AudioPlayback PASS +sh-5.3# ./run.sh --no-extract-assets --clip-name "playback_config1" +[INFO] 2026-01-22 17:46:33 - ---------------- Starting AudioPlayback ---------------- +[INFO] 2026-01-22 17:46:33 - Platform Details: machine='Qualcomm Technologies, Inc. Robotics RB3gen2' target='Kodiak' kernel='6.18.0-00393-g27507852413b' arch='aarch64' +[INFO] 2026-01-22 17:46:33 - Args: backend=auto sink=speakers loops=1 timeout=0 formats='wav' durations='short' strict=0 dmesg=1 extract=false network_download=false clips_path=default +[INFO] 2026-01-22 17:46:33 - Using backend: pipewire +[INFO] 2026-01-22 17:46:33 - Routing to sink: id=52 name='Built-in Audio Speaker playback' choice=speakers +[INFO] 2026-01-22 17:46:33 - Using clip discovery mode +[INFO] 2026-01-22 17:46:33 - Discovered 1 clips to test +[INFO] 2026-01-22 17:46:33 - [play_16KHz_16b_2ch] Using clip: yesterday_16KHz_30s_16b_2ch.wav (1922036 bytes) +[INFO] 2026-01-22 17:46:33 - [play_16KHz_16b_2ch] loop 1/1 start=2026-01-22T17:46:33Z clip=yesterday_16KHz_30s_16b_2ch.wav backend=pipewire sink=speakers(52) +[INFO] 2026-01-22 17:46:33 - [play_16KHz_16b_2ch] exec: pw-play -v "AudioClips/yesterday_16KHz_30s_16b_2ch.wav" +[INFO] 2026-01-22 17:47:04 - [play_16KHz_16b_2ch] evidence: pw_streaming=1 pa_streaming=0 alsa_running=1 asoc_path_on=1 pw_log=1 +[PASS] 2026-01-22 17:47:04 - [play_16KHz_16b_2ch] loop 1 OK (rc=0, 30s) +[INFO] 2026-01-22 17:47:04 - Summary: total=1 pass=1 fail=0 skip=0 +[PASS] 2026-01-22 17:47:04 - AudioPlayback PASS ``` **Example 2: Testing multiple clips** ``` -sh-5.3# ./run.sh --no-extract-assets --clip-name "Config1 Config2 Config3" -[INFO] 2025-12-30 11:48:13 - Using clip discovery mode -[INFO] 2025-12-30 11:48:13 - Discovered 3 clips to test -[INFO] 2025-12-30 11:48:13 - [play_16KHz_16b_2ch] Using clip: yesterday_16KHz_30s_16b_2ch.wav (1922036 bytes) -[PASS] 2025-12-30 11:48:43 - [play_16KHz_16b_2ch] loop 1 OK (rc=0, 30s) -[INFO] 2025-12-30 11:48:43 - [play_176.4KHz_24b_1ch] Using clip: yesterday_176.4KHz_30s_24b_1ch.wav (15892062 bytes) -[PASS] 2025-12-30 11:49:14 - [play_176.4KHz_24b_1ch] loop 1 OK (rc=0, 31s) -[INFO] 2025-12-30 11:49:14 - [play_176.4KHz_32b_6ch] Using clip: yesterday_176.4KHz_30s_32b_6ch.wav (127135484 bytes) -[PASS] 2025-12-30 11:49:44 - [play_176.4KHz_32b_6ch] loop 1 OK (rc=0, 30s) -[INFO] 2025-12-30 11:49:44 - Summary: total=3 pass=3 fail=0 skip=0 -[PASS] 2025-12-30 11:49:44 - AudioPlayback PASS +sh-5.3# ./run.sh --no-extract-assets --clip-name "playback_config1 playback_config3 playback_config5" +[INFO] 2026-01-22 17:42:30 - Using clip discovery mode +[INFO] 2026-01-22 17:42:30 - Discovered 3 clips to test +[INFO] 2026-01-22 17:42:30 - [play_16KHz_16b_2ch] Using clip: yesterday_16KHz_30s_16b_2ch.wav (1922036 bytes) +[PASS] 2026-01-22 17:43:00 - [play_16KHz_16b_2ch] loop 1 OK (rc=0, 30s) +[INFO] 2026-01-22 17:43:00 - [play_22.050KHz_8b_1ch] Using clip: yesterday_22.050KHz_30s_8b_1ch.wav (662284 bytes) +[PASS] 2026-01-22 17:43:30 - [play_22.050KHz_8b_1ch] loop 1 OK (rc=0, 30s) +[INFO] 2026-01-22 17:43:31 - [play_24KHz_32b_1ch] Using clip: yesterday_24KHz_30s_32b_1ch.wav (2883004 bytes) +[PASS] 2026-01-22 17:44:01 - [play_24KHz_32b_1ch] loop 1 OK (rc=0, 30s) +[INFO] 2026-01-22 17:44:01 - Summary: total=3 pass=3 fail=0 skip=0 +[PASS] 2026-01-22 17:44:01 - AudioPlayback PASS ``` **Example 3: Filtering clips by sample rate** ``` sh-5.3# ./run.sh --no-extract-assets --clip-filter "48KHz" -[INFO] 2025-12-30 12:00:08 - Using clip discovery mode -[INFO] 2025-12-30 12:00:08 - Discovered 2 clips to test -[INFO] 2025-12-30 12:00:08 - [play_48KHz_8b_2ch] Using clip: yesterday_48KHz_30s_8b_2ch.wav (2883002 bytes) -[PASS] 2025-12-30 12:00:38 - [play_48KHz_8b_2ch] loop 1 OK (rc=0, 30s) -[INFO] 2025-12-30 12:00:38 - [play_48KHz_8b_8ch] Using clip: yesterday_48KHz_30s_8b_8ch.wav (11531688 bytes) -[PASS] 2025-12-30 12:01:08 - [play_48KHz_8b_8ch] loop 1 OK (rc=0, 30s) -[INFO] 2025-12-30 12:01:08 - Summary: total=2 pass=2 fail=0 skip=0 -[PASS] 2025-12-30 12:01:08 - AudioPlayback PASS +[INFO] 2026-01-22 17:54:45 - Using clip discovery mode +[INFO] 2026-01-22 17:54:45 - Discovered 1 clips to test +[INFO] 2026-01-22 17:54:45 - [play_48KHz_8b_2ch] Using clip: yesterday_48KHz_30s_8b_2ch.wav (2883002 bytes) +[PASS] 2026-01-22 17:55:15 - [play_48KHz_8b_2ch] loop 1 OK (rc=0, 30s) +[INFO] 2026-01-22 17:55:15 - Summary: total=1 pass=1 fail=0 skip=0 +[PASS] 2026-01-22 17:55:15 - AudioPlayback PASS +``` + +**Example 4: Testing all 10 clips (auto-discovery mode)** +``` +sh-5.3# ./run.sh --no-extract-assets --timeout 5s +[INFO] 2026-01-22 17:51:32 - Auto-detected clip discovery mode (found clips in /home/AudioClips/) +[INFO] 2026-01-22 17:51:32 - Using clip discovery mode +[INFO] 2026-01-22 17:51:32 - Discovered 10 clips to test +[INFO] 2026-01-22 17:51:32 - [play_16KHz_16b_2ch] Using clip: yesterday_16KHz_30s_16b_2ch.wav (1922036 bytes) +[PASS] 2026-01-22 17:51:37 - [play_16KHz_16b_2ch] loop 1 OK (rc=0, 5s) +[INFO] 2026-01-22 17:51:37 - [play_16KHz_8b_6ch] Using clip: yesterday_16KHz_30s_8b_6ch.wav (2883002 bytes) +[PASS] 2026-01-22 17:51:43 - [play_16KHz_8b_6ch] loop 1 OK (rc=0, 5s) +[INFO] 2026-01-22 17:51:43 - [play_22.050KHz_8b_1ch] Using clip: yesterday_22.050KHz_30s_8b_1ch.wav (662284 bytes) +[PASS] 2026-01-22 17:51:48 - [play_22.050KHz_8b_1ch] loop 1 OK (rc=0, 5s) +[INFO] 2026-01-22 17:51:48 - [play_24KHz_24b_6ch] Using clip: yesterday_24KHz_30s_24b_6ch.wav (12973134 bytes) +[PASS] 2026-01-22 17:51:53 - [play_24KHz_24b_6ch] loop 1 OK (rc=0, 5s) +[INFO] 2026-01-22 17:51:53 - [play_24KHz_32b_1ch] Using clip: yesterday_24KHz_30s_32b_1ch.wav (2883004 bytes) +[PASS] 2026-01-22 17:51:58 - [play_24KHz_32b_1ch] loop 1 OK (rc=0, 5s) +[INFO] 2026-01-22 17:51:58 - [play_32KHz_16b_2ch] Using clip: yesterday_32KHz_30s_16b_2ch.wav (3843964 bytes) +[PASS] 2026-01-22 17:52:03 - [play_32KHz_16b_2ch] loop 1 OK (rc=0, 5s) +[INFO] 2026-01-22 17:52:03 - [play_32KHz_8b_8ch] Using clip: yesterday_32KHz_30s_8b_8ch.wav (7687832 bytes) +[PASS] 2026-01-22 17:52:09 - [play_32KHz_8b_8ch] loop 1 OK (rc=0, 5s) +[INFO] 2026-01-22 17:52:09 - [play_44.1KHz_16b_1ch] Using clip: yesterday_44.1KHz_30s_16b_1ch.wav (2648774 bytes) +[PASS] 2026-01-22 17:52:14 - [play_44.1KHz_16b_1ch] loop 1 OK (rc=0, 5s) +[INFO] 2026-01-22 17:52:14 - [play_48KHz_8b_2ch] Using clip: yesterday_48KHz_30s_8b_2ch.wav (2883002 bytes) +[PASS] 2026-01-22 17:52:19 - [play_48KHz_8b_2ch] loop 1 OK (rc=0, 5s) +[INFO] 2026-01-22 17:52:19 - [play_8KHz_8b_1ch] Using clip: yesterday_8KHz_30s_8b_1ch.wav (240362 bytes) +[PASS] 2026-01-22 17:52:24 - [play_8KHz_8b_1ch] loop 1 OK (rc=0, 5s) +[INFO] 2026-01-22 17:52:24 - Summary: total=10 pass=10 fail=0 skip=0 +[PASS] 2026-01-22 17:52:24 - AudioPlayback PASS ``` -**Example 4: Invalid config name (shows helpful error)** +**Example 5: Invalid config name (shows helpful error)** ``` -sh-5.3# ./run.sh --no-extract-assets --clip-name "Config0" -[INFO] 2025-12-30 11:59:52 - Using clip discovery mode -[SKIP] 2025-12-30 11:59:52 - AudioPlayback SKIP - Invalid clip/config name(s) provided. Available range: Config1 to Config20 +sh-5.3# ./run.sh --no-extract-assets --clip-name "playback_config99" +[INFO] 2026-01-22 17:59:52 - Using clip discovery mode +[SKIP] 2026-01-22 17:59:52 - AudioPlayback SKIP - Invalid clip/config name(s) provided. Available range: playback_config1 to playback_config10 ``` -**Example 5: CI/LAVA workflow with unique result files** +**Example 6: CI/LAVA workflow with unique result files** ``` -sh-5.3# ./run.sh --clip-name "Config1" --res-suffix "Config1" --audio-clips-path /home/AudioClips/ --no-extract-assets -[INFO] 2026-01-12 06:56:47 - Using unique result file: ./AudioPlayback_Config1.res -[INFO] 2026-01-12 06:56:47 - ---------------- Starting AudioPlayback ---------------- -[INFO] 2026-01-12 06:56:48 - Using clip discovery mode -[INFO] 2026-01-12 06:56:48 - Discovered 1 clips to test -[INFO] 2026-01-12 06:56:48 - [play_16KHz_16b_2ch] Clip duration: 30s (timeout threshold: 29s) -[PASS] 2026-01-12 06:57:18 - [play_16KHz_16b_2ch] loop 1 OK (rc=0, 30s) -[PASS] 2026-01-12 06:57:18 - AudioPlayback PASS +sh-5.3# ./run.sh --clip-name "playback_config1" --res-suffix "Config1" --audio-clips-path /home/AudioClips/ --no-extract-assets +[INFO] 2026-01-22 17:46:33 - Using unique result file: ./AudioPlayback_Config1.res +[INFO] 2026-01-22 17:46:33 - ---------------- Starting AudioPlayback ---------------- +[INFO] 2026-01-22 17:46:33 - Using clip discovery mode +[INFO] 2026-01-22 17:46:33 - Discovered 1 clips to test +[INFO] 2026-01-22 17:46:33 - [play_16KHz_16b_2ch] Clip duration: 30s (timeout threshold: 29s) +[PASS] 2026-01-22 17:47:04 - [play_16KHz_16b_2ch] loop 1 OK (rc=0, 30s) +[PASS] 2026-01-22 17:47:04 - AudioPlayback PASS sh-5.3# cat AudioPlayback_Config1.res AudioPlayback PASS -sh-5.3# ./run.sh --clip-name "Config7" --res-suffix "Config7" --audio-clips-path /home/AudioClips/ --no-extract-assets -[INFO] 2026-01-12 06:57:42 - Using unique result file: ./AudioPlayback_Config7.res -[PASS] 2026-01-12 06:58:13 - AudioPlayback PASS +sh-5.3# ./run.sh --clip-name "playback_config7" --res-suffix "Config7" --audio-clips-path /home/AudioClips/ --no-extract-assets +[INFO] 2026-01-22 17:48:34 - Using unique result file: ./AudioPlayback_Config7.res +[PASS] 2026-01-22 17:49:05 - AudioPlayback PASS sh-5.3# cat AudioPlayback_Config7.res AudioPlayback PASS diff --git a/Runner/suites/Multimedia/Audio/AudioPlayback/run.sh b/Runner/suites/Multimedia/Audio/AudioPlayback/run.sh index 757fcc12..05ff639b 100755 --- a/Runner/suites/Multimedia/Audio/AudioPlayback/run.sh +++ b/Runner/suites/Multimedia/Audio/AudioPlayback/run.sh @@ -113,7 +113,7 @@ Usage: $0 [options] --formats "wav" # Legacy matrix mode only --durations "short|short medium" # Legacy matrix mode only (not recommended for new tests) --clip-name "play_48KHz_16b_2ch" # Test specific clip(s) by name (space-separated) - # Also supports Config1, Config2, ..., Config20 + # Also supports playback_config1, playback_config2, ..., playback_config10 --clip-filter "48KHz" # Filter clips by pattern --res-suffix SUFFIX # Suffix for unique result file (e.g., "Config1") # Generates AudioPlayback_SUFFIX.res instead of AudioPlayback.res @@ -135,9 +135,9 @@ Testing Modes: - Use --clip-name or --clip-filter to select specific clips - Provides descriptive test case names based on audio format - Examples: - $0 --clip-name "Config1 Config7" + $0 --clip-name "playback_config1 playback_config7" $0 --clip-filter "48KHz" - $0 --clip-name "Config1" --res-suffix "Config1" # CI/LAVA use + $0 --clip-name "playback_config1" --res-suffix "Config1" # CI/LAVA use Legacy Matrix Mode: - Uses --formats and --durations to generate test matrix @@ -190,8 +190,16 @@ while [ $# -gt 0 ]; do shift 2 ;; --strict) - STRICT=1 - shift + case "$2" in + --*|"") + STRICT=1 + shift + ;; + *) + STRICT="$2" + shift 2 + ;; + esac ;; --no-dmesg) DMESG_SCAN=0 @@ -597,15 +605,24 @@ if [ "$USE_CLIP_DISCOVERY" = "true" ]; then log_info "[$case_name] loop $i/$LOOPS start=$iso clip=$clip_file backend=$AUDIO_BACKEND $loop_hdr" + # Determine effective timeout: use clip duration when TIMEOUT is disabled + effective_timeout="$TIMEOUT" + if [ "$TIMEOUT" = "0" ] || [ "$TIMEOUT" = "" ]; then + if [ "$clip_duration" -gt 0 ] 2>/dev/null; then + effective_timeout="$clip_duration" + log_info "[$case_name] Using clip duration as timeout: ${effective_timeout}s" + fi + fi + start_s="$(date +%s 2>/dev/null || echo 0)" if [ "$AUDIO_BACKEND" = "pipewire" ]; then log_info "[$case_name] exec: pw-play -v \"$clip_path\"" - audio_exec_with_timeout "$TIMEOUT" pw-play -v "$clip_path" >>"$logf" 2>&1 + audio_exec_with_timeout "$effective_timeout" pw-play -v "$clip_path" >>"$logf" 2>&1 rc=$? else log_info "[$case_name] exec: paplay --device=\"$SINK_NAME\" \"$clip_path\"" - audio_exec_with_timeout "$TIMEOUT" paplay --device="$SINK_NAME" "$clip_path" >>"$logf" 2>&1 + audio_exec_with_timeout "$effective_timeout" paplay --device="$SINK_NAME" "$clip_path" >>"$logf" 2>&1 rc=$? fi diff --git a/Runner/suites/Multimedia/Audio/AudioRecord/AudioRecord.yaml b/Runner/suites/Multimedia/Audio/AudioRecord/AudioRecord.yaml index 1dfb0b17..ff4b01e3 100644 --- a/Runner/suites/Multimedia/Audio/AudioRecord/AudioRecord.yaml +++ b/Runner/suites/Multimedia/Audio/AudioRecord/AudioRecord.yaml @@ -25,5 +25,5 @@ run: steps: - REPO_PATH=$PWD - cd Runner/suites/Multimedia/Audio/AudioRecord/ - - ./run.sh --backend "${AUDIO_BACKEND}" --source "${SOURCE_CHOICE}" --config-name "${CONFIG_NAMES}" --config-filter "${CONFIG_FILTER}" --durations "${DURATIONS}" --record-seconds "${RECORD_SECONDS}" --loops "${LOOPS}" --timeout "${TIMEOUT}" --strict "${STRICT}" --res-suffix "${RES_SUFFIX}" || true + - ./run.sh --backend "${AUDIO_BACKEND}" --source "${SOURCE_CHOICE}" --config-name "${CONFIG_NAMES}" --config-filter "${CONFIG_FILTER}" --record-seconds "${RECORD_SECONDS}" --loops "${LOOPS}" --timeout "${TIMEOUT}" --strict "${STRICT}" --res-suffix "${RES_SUFFIX}" || true - $REPO_PATH/Runner/utils/send-to-lava.sh AudioRecord${RES_SUFFIX:+_${RES_SUFFIX}}.res || true diff --git a/Runner/utils/audio_common.sh b/Runner/utils/audio_common.sh index 287007f1..e435417c 100755 --- a/Runner/utils/audio_common.sh +++ b/Runner/utils/audio_common.sh @@ -796,47 +796,55 @@ audio_check_clips_available() { # ---------- New Clip Discovery Functions (for 20-clip enhancement) ---------- # ---------- Config Mapping ---------- -# Provides stable, deterministic mapping from Config1-Config20 to specific +# Provides stable, deterministic mapping from playback_config1-playback_config10 to specific # audio format test cases. This ensures reproducible test coverage across # different systems and releases. # -# Config numbers map to specific sample rate, bit depth, and channel combinations: -# Config1 → 16 KHz, 16-bit, 2ch Config11 → 352.8 KHz, 32-bit, 1ch -# Config2 → 176.4 KHz, 24-bit, 1ch Config12 → 384 KHz, 32-bit, 2ch -# Config3 → 176.4 KHz, 32-bit, 6ch Config13 → 44.1 KHz, 16-bit, 1ch -# Config4 → 192 KHz, 16-bit, 6ch Config14 → 44.1 KHz, 8-bit, 6ch -# Config5 → 192 KHz, 32-bit, 8ch Config15 → 48 KHz, 8-bit, 2ch -# Config6 → 22.05 KHz, 8-bit, 1ch Config16 → 48 KHz, 8-bit, 8ch -# Config7 → 24 KHz, 24-bit, 6ch Config17 → 88.2 KHz, 16-bit, 8ch -# Config8 → 24 KHz, 32-bit, 8ch Config18 → 88.2 KHz, 24-bit, 2ch -# Config9 → 32 KHz, 16-bit, 2ch Config19 → 8 KHz, 8-bit, 1ch -# Config10 → 32 KHz, 8-bit, 8ch Config20 → 96 KHz, 24-bit, 6ch +# Playback config numbers map to specific sample rate, bit depth, and channel combinations: +# playback_config1 → 8 KHz, 8-bit, 1ch +# playback_config2 → 16 KHz, 8-bit, 6ch +# playback_config3 → 16 KHz, 16-bit, 2ch +# playback_config4 → 22.05 KHz, 8-bit, 1ch +# playback_config5 → 24 KHz, 24-bit, 6ch +# playback_config6 → 24 KHz, 32-bit, 1ch +# playback_config7 → 32 KHz, 8-bit, 8ch +# playback_config8 → 32 KHz, 16-bit, 2ch +# playback_config9 → 44.1 KHz, 16-bit, 1ch +# playback_config10 → 48 KHz, 8-bit, 2ch -# Translate Config number to test case name -# Returns descriptive test case name for given config number +# Translate playback_config name to test case name +# Returns descriptive test case name for given config map_config_to_testcase() { - config_num="$1" + config="$1" + + # Extract config number if using playback_config format + config_num="" + case "$config" in + playback_config*) + config_num="$(printf '%s' "$config" | sed -n 's/^playback_config\([0-9][0-9]*\)$/\1/p')" + ;; + Config*) + # For backward compatibility + config_num="$(printf '%s' "$config" | sed -n 's/^Config\([0-9][0-9]*\)$/\1/p')" + ;; + [0-9]*) + # Direct number input + config_num="$config" + ;; + esac + + # Map config number to test case name case "$config_num" in - 1) printf 'play_16KHz_16b_2ch\n' ;; - 2) printf 'play_176.4KHz_24b_1ch\n' ;; - 3) printf 'play_176.4KHz_32b_6ch\n' ;; - 4) printf 'play_192KHz_16b_6ch\n' ;; - 5) printf 'play_192KHz_32b_8ch\n' ;; - 6) printf 'play_22.05KHz_8b_1ch\n' ;; - 7) printf 'play_24KHz_24b_6ch\n' ;; - 8) printf 'play_24KHz_32b_8ch\n' ;; - 9) printf 'play_32KHz_16b_2ch\n' ;; - 10) printf 'play_32KHz_8b_8ch\n' ;; - 11) printf 'play_352.8KHz_32b_1ch\n' ;; - 12) printf 'play_384KHz_32b_2ch\n' ;; - 13) printf 'play_44.1KHz_16b_1ch\n' ;; - 14) printf 'play_44.1KHz_8b_6ch\n' ;; - 15) printf 'play_48KHz_8b_2ch\n' ;; - 16) printf 'play_48KHz_8b_8ch\n' ;; - 17) printf 'play_88.2KHz_16b_8ch\n' ;; - 18) printf 'play_88.2KHz_24b_2ch\n' ;; - 19) printf 'play_8KHz_8b_1ch\n' ;; - 20) printf 'play_96KHz_24b_6ch\n' ;; + 1) printf 'play_8KHz_8b_1ch\n' ;; + 2) printf 'play_16KHz_8b_6ch\n' ;; + 3) printf 'play_16KHz_16b_2ch\n' ;; + 4) printf 'play_22.05KHz_8b_1ch\n' ;; + 5) printf 'play_24KHz_24b_6ch\n' ;; + 6) printf 'play_24KHz_32b_1ch\n' ;; + 7) printf 'play_32KHz_8b_8ch\n' ;; + 8) printf 'play_32KHz_16b_2ch\n' ;; + 9) printf 'play_44.1KHz_16b_1ch\n' ;; + 10) printf 'play_48KHz_8b_2ch\n' ;; *) return 1 ;; esac return 0 @@ -960,7 +968,7 @@ resolve_clip_by_name() { } # Validate clip name against available clips -# Input: requested_name (e.g., play_48KHz_16b_2ch OR Config1), available_clips (list) +# Input: requested_name (e.g., play_48KHz_16b_2ch OR playback_config1), available_clips (list) # Output: matching clip filename to stdout # Logs error messages to stderr # Returns: 0=found, 1=not found @@ -968,9 +976,17 @@ validate_clip_name() { requested_name="$1" available_clips="$2" - # Check if requested_name is a generic config name (Config1, Config2, etc.) - # Support both "Config1" and "config1" (case-insensitive) - config_num="$(printf '%s' "$requested_name" | sed -n 's/^[Cc]onfig\([0-9][0-9]*\)$/\1/p')" + # Check if requested_name is a generic config name (playback_config1, Config1, etc.) + # Support both formats for backward compatibility + config_num="" + case "$requested_name" in + playback_config*) + config_num="$(printf '%s' "$requested_name" | sed -n 's/^playback_config\([0-9][0-9]*\)$/\1/p')" + ;; + [Cc]onfig*) + config_num="$(printf '%s' "$requested_name" | sed -n 's/^[Cc]onfig\([0-9][0-9]*\)$/\1/p')" + ;; + esac if [ -n "$config_num" ]; then # Generic config name - map to clip by index (1-based) @@ -1013,7 +1029,7 @@ validate_clip_name() { idx=$# # No match found - provide helpful error message with range - log_error "Wrong clip name: '$requested_name'. Available range: Config1 to Config$idx. Please check again." >&2 + log_error "Wrong clip name: '$requested_name'. Available range: playback_config1 to playback_config$idx. Please check again." >&2 return 1 } From 43995ae4bdef3a6579b06ddbd25cc967fec35320 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Tue, 27 Jan 2026 23:07:31 +0530 Subject: [PATCH 09/16] lib(functestlib): enhance check_dependencies and improve scan_dmesg_errors filtering/output Signed-off-by: Srikanth Muppandam --- Runner/utils/functestlib.sh | 96 +++++++++++++++++++++++++++---------- 1 file changed, 72 insertions(+), 24 deletions(-) diff --git a/Runner/utils/functestlib.sh b/Runner/utils/functestlib.sh index af503462..7ff9ddca 100755 --- a/Runner/utils/functestlib.sh +++ b/Runner/utils/functestlib.sh @@ -140,23 +140,37 @@ unload_kernel_module() { # --- Dependency check --- check_dependencies() { + # Support both: + # check_dependencies date awk sed + # check_dependencies "$deps" where deps="date awk sed" + if [ "$#" -eq 1 ]; then + # Split the single string into args + # shellcheck disable=SC2086 + set -- $1 + fi + missing=0 missing_cmds="" + for cmd in "$@"; do + [ -n "$cmd" ] || continue if ! command -v "$cmd" >/dev/null 2>&1; then log_warn "Required command '$cmd' not found in PATH." missing=1 missing_cmds="$missing_cmds $cmd" fi done + if [ "$missing" -ne 0 ]; then - testname="${TESTNAME:-}" - log_skip "${testname:-UnknownTest} SKIP: missing dependencies:$missing_cmds" - if [ -n "$testname" ]; then - echo "$testname SKIP" > "./$testname.res" + testname="${TESTNAME:-UnknownTest}" + log_skip "$testname SKIP missing dependencies$missing_cmds" + if [ -n "${TESTNAME:-}" ]; then + echo "$TESTNAME SKIP" > "./$TESTNAME.res" 2>/dev/null || true fi exit 0 fi + + return 0 } # --- Test case directory lookup --- @@ -3299,35 +3313,69 @@ detect_ufs_partition_block() { ############################################################################### scan_dmesg_errors() { prefix="$1" - module_regex="$2" # e.g. 'qcom_camss|camss|isp' + module_regex="$2" # e.g. 'qcom_camss|camss|isp|CAM-ICP|CAMERA_ICP' exclude_regex="${3:-"dummy regulator|supply [^ ]+ not found|using dummy regulator"}" - shift 3 - - mkdir -p "$prefix" - + success_regex="${4:-}" # OPTIONAL: require success evidence (e.g. FW download done successfully) + success_min_hits="${5:-1}" # OPTIONAL: minimum success hits required (default 1) + + shift 5 2>/dev/null || true + + mkdir -p "$prefix" 2>/dev/null || true + DMESG_SNAPSHOT="$prefix/dmesg_snapshot.log" DMESG_ERRORS="$prefix/dmesg_errors.log" - DATE_STAMP=$(date +%Y%m%d-%H%M%S) + DMESG_SUCCESS="$prefix/dmesg_success.log" + DATE_STAMP=$(date +%Y%m%d-%H%M%S 2>/dev/null || echo "unknown-date") DMESG_HISTORY="$prefix/dmesg_errors_$DATE_STAMP.log" - + # Error patterns (edit as needed for your test coverage) err_patterns='Unknown symbol|probe failed|fail(ed)?|error|timed out|not found|invalid|corrupt|abort|panic|oops|unhandled|can.t (start|init|open|allocate|find|register)' - - rm -f "$DMESG_SNAPSHOT" "$DMESG_ERRORS" - dmesg > "$DMESG_SNAPSHOT" 2>/dev/null - - # 1. Match lines with correct module and error pattern - # 2. Exclude lines with harmless patterns (using dummy regulator etc) - grep -iE "^\[[^]]+\][[:space:]]+($module_regex):.*($err_patterns)" "$DMESG_SNAPSHOT" \ - | grep -vEi "$exclude_regex" > "$DMESG_ERRORS" || true - - cp "$DMESG_ERRORS" "$DMESG_HISTORY" - + + rm -f "$DMESG_SNAPSHOT" "$DMESG_ERRORS" "$DMESG_SUCCESS" 2>/dev/null || true + dmesg > "$DMESG_SNAPSHOT" 2>/dev/null || true + + # Robust match: + # - First filter by module_regex (anywhere in line) + # - Then filter by err_patterns + # - Exclude benign patterns + # + # This works for both: + # [..] module: error ... + # and: + # [..] CAM_INFO: ... fail ... + # + # Note: module_regex should be tight enough to avoid false positives. + grep -iE "($module_regex)" "$DMESG_SNAPSHOT" 2>/dev/null \ + | grep -iE "($err_patterns)" 2>/dev/null \ + | grep -vEi "$exclude_regex" 2>/dev/null > "$DMESG_ERRORS" || true + + cp "$DMESG_ERRORS" "$DMESG_HISTORY" 2>/dev/null || true + if [ -s "$DMESG_ERRORS" ]; then - log_info "dmesg scan: found non-benign module errors in $DMESG_ERRORS (history: $DMESG_HISTORY)" + log_info "dmesg scan found non benign module errors in $DMESG_ERRORS (history: $DMESG_HISTORY)" return 0 fi - log_info "No relevant, non-benign errors for modules [$module_regex] in recent dmesg." + + # Optional success evidence check (no extra greps in run.sh) + if [ -n "$success_regex" ]; then + grep -iE "($success_regex)" "$DMESG_SNAPSHOT" 2>/dev/null > "$DMESG_SUCCESS" || true + + hits="$(wc -l < "$DMESG_SUCCESS" 2>/dev/null | awk '{print $1}')" + case "$hits" in ''|*[!0-9]*) hits=0 ;; esac + + case "$success_min_hits" in ''|*[!0-9]*) success_min_hits=1 ;; esac + + if [ "$hits" -lt "$success_min_hits" ]; then + log_info "dmesg scan found no required success evidence for modules [$module_regex] (need >=$success_min_hits hits). See $DMESG_SUCCESS" + return 2 + fi + + log_info "dmesg scan success evidence present in $DMESG_SUCCESS (hits=$hits)" + else + log_info "No relevant, non benign errors for modules [$module_regex] in recent dmesg." + fi + + # No errors return 1 } From b37db220c6ceb194c97140c09ae163a664383255 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Tue, 27 Jan 2026 23:07:50 +0530 Subject: [PATCH 10/16] camera(lib_camera): add CAMX/NHX helper utilities (DT/opkg/fw/dump+checksum validation) Signed-off-by: Srikanth Muppandam --- Runner/utils/camera/lib_camera.sh | 220 ++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) diff --git a/Runner/utils/camera/lib_camera.sh b/Runner/utils/camera/lib_camera.sh index 29bc3306..6955a4d1 100755 --- a/Runner/utils/camera/lib_camera.sh +++ b/Runner/utils/camera/lib_camera.sh @@ -416,3 +416,223 @@ libcam_scan_errors() { rm -f "$tmpf" return 0 } + +# Camera common helpers (Downstream CAMX/NHX) +# Keep generic helpers only. Policy and gating belongs in run.sh. + +# ----------------------------------------------------------------------------- +# SoC id helper +# ----------------------------------------------------------------------------- +# Return SoC id token used in firmware paths +# Prefer /sys/devices/soc0/soc_id. Normalize to lowercase and trim. +camx_read_soc_id() { + soc="" + + if [ -r /sys/devices/soc0/soc_id ]; then + soc="$(tr -d '\r\n[:space:]' /dev/null | tr '[:upper:]' '[:lower:]')" + fi + + [ -n "$soc" ] || return 1 + echo "$soc" + return 0 +} + +# ----------------------------------------------------------------------------- +# Firmware helpers +# ----------------------------------------------------------------------------- +# Find ICP camera firmware ELF (CAMERA_ICP_*.elf) +# Prints first match path on stdout. +camx_find_icp_firmware() { + soc="$(camx_read_soc_id 2>/dev/null || true)" + + # First try soc-specific canonical path + for root in /usr/lib/firmware /lib/firmware; do + if [ -n "$soc" ] && [ -d "$root/qcom/$soc" ]; then + p="$(find "$root/qcom/$soc" -maxdepth 1 -type f -name 'CAMERA_ICP_*.elf' 2>/dev/null | head -n 1)" + [ -n "$p" ] && echo "$p" && return 0 + fi + done + + # Fallback bounded search + for root in /usr/lib/firmware /lib/firmware; do + if [ -d "$root/qcom" ]; then + p="$(find "$root/qcom" -maxdepth 2 -type f -name 'CAMERA_ICP_*.elf' 2>/dev/null | head -n 1)" + [ -n "$p" ] && echo "$p" && return 0 + fi + done + + return 1 +} + +# ----------------------------------------------------------------------------- +# Package helpers (Yocto/QLI proprietary builds) +# ----------------------------------------------------------------------------- +camx_opkg_list_camx() { + command -v opkg >/dev/null 2>&1 || return 1 + out="$(opkg list-installed 2>/dev/null | grep -i '^camx' || true)" + [ -n "$out" ] || return 1 + printf '%s\n' "$out" + return 0 +} + +# ----------------------------------------------------------------------------- +# DT camera nodes sample using fdtdump +# ----------------------------------------------------------------------------- +camx_fdtdump_has_cam_nodes() { + command -v fdtdump >/dev/null 2>&1 || return 2 + [ -r /sys/firmware/fdt ] || return 1 + + out="$(fdtdump /sys/firmware/fdt 2>/dev/null \ + | grep -i 'cam' \ + | grep -Ei 'qcom,cam|qcom,camera|camera@|cam-req|cam-cpas|cam-jpeg|cam-ife|cam-icp|cam-sensor|camera0-thermal' || true)" + + [ -n "$out" ] || return 1 + printf '%s\n' "$out" | head -n 20 + return 0 +} + +# ---- NHX dump + checksum validation helpers (POSIX) ---- + +nhx_pick_cksum_tool() { + if command -v sha256sum >/dev/null 2>&1; then + echo "sha256sum" + elif command -v md5sum >/dev/null 2>&1; then + echo "md5sum" + else + echo "" + fi +} + +nhx_collect_new_dumps() { + # $1 = dump_dir, $2 = marker_file, $3 = output_list_file + # Collect NHX yuvs created after marker. Fallback to any *.yuv if none match. + ddir="$1" + marker="$2" + out="$3" + + : >"$out" + + # Prefer NHX-tagged files (matches your observed names) + find "$ddir" -maxdepth 1 -type f \ + \( -name '*NHX*.yuv' -o -name '*NHX*.raw' -o -name '*NHX*.bin' \) \ + -newer "$marker" 2>/dev/null | sort >"$out" + + if [ ! -s "$out" ]; then + # Fallback: any yuv created after marker + find "$ddir" -maxdepth 1 -type f -name '*.yuv' -newer "$marker" 2>/dev/null | sort >"$out" + fi +} + +nhx_validate_dumps_and_checksums() { + # $1 = dump_dir, $2 = marker_file, $3 = log_dir + ddir="$1" + marker="$2" + ldir="$3" + + list="$ldir/nhx_dumps.list" + sumfile="$ldir/nhx_checksums.txt" + prevsum="$ldir/nhx_checksums.prev.txt" + tool="$(nhx_pick_cksum_tool)" + + if [ ! -d "$ddir" ]; then + log_fail "DUMP_DIR does not exist: $ddir" + return 1 + fi + + if [ -z "$tool" ]; then + log_skip "No checksum tool found (sha256sum/md5sum). Skipping dump checksum validation." + return 0 + fi + + nhx_collect_new_dumps "$ddir" "$marker" "$list" + + if [ ! -s "$list" ]; then + log_fail "No NHX dump files found in $ddir (after marker). Dump/checksum validation not exercised." + return 1 + fi + + # Basic sanity: non-empty, not all identical checksum + : >"$sumfile" + first_sum="" + all_same="1" + count="0" + + while IFS= read -r f; do + [ -n "$f" ] || continue + + if [ ! -s "$f" ]; then + log_fail "Dump file is empty: $f" + return 1 + fi + + # Produce "HASH FILE" lines, same as sha256sum/md5sum + line="$($tool "$f" 2>/dev/null)" + if [ -z "$line" ]; then + log_fail "Checksum tool failed for: $f" + return 1 + fi + echo "$line" >>"$sumfile" + + cur_sum=$(echo "$line" | awk '{print $1}') + if [ -z "$first_sum" ]; then + first_sum="$cur_sum" + else + if [ "$cur_sum" != "$first_sum" ]; then + all_same="0" + fi + fi + + count=$((count + 1)) + done <"$list" + + log_info "Dump files detected: $count (list: $list)" + log_info "Checksums written: $sumfile (tool=$tool)" + + if [ "$count" -lt 1 ]; then + log_fail "Internal error: dump count computed as 0" + return 1 + fi + + if [ "$all_same" = "1" ] && [ "$count" -gt 1 ]; then + log_fail "All dump checksums are identical across $count files (suspicious: repeated/blank frames)" + return 1 + fi + + # Optional drift check: compare against previous run (same log dir) + if [ -f "$prevsum" ]; then + if ! diff -q "$prevsum" "$sumfile" >/dev/null 2>&1; then + log_warn "Dump checksums changed vs previous run ($prevsum). This may be expected; keeping as WARN." + else + log_info "Dump checksums match previous run ($prevsum)" + fi + fi + + # Save current as previous for next run + cp -f "$sumfile" "$prevsum" 2>/dev/null || true + + log_pass "NHX dump checksum validation exercised ($count files)" + return 0 +} + +# POSIX way to tee live output while preserving exit code +run_cmd_live_to_log() { + # $1 = logfile, $2... = command + logf="$1" + shift + + fifo="$logf.fifo.$$" + rm -f "$fifo" + mkfifo "$fifo" || return 1 + + # tee runs in background, command writes into fifo + tee -a "$logf" <"$fifo" & + teepid=$! + + "$@" >"$fifo" 2>&1 + rc=$? + + # close fifo and wait tee + rm -f "$fifo" + wait "$teepid" 2>/dev/null || true + return "$rc" +} From 43e3dcf14d2c3996ef5efa8bad06d889149be448 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Tue, 27 Jan 2026 23:08:13 +0530 Subject: [PATCH 11/16] camera(Camera_NHX): update run.sh to use lib_camera dump/checksum validation and deps via functestlib Signed-off-by: Srikanth Muppandam --- .../Multimedia/Camera/Camera_NHX/run.sh | 542 ++++++++++++++++++ 1 file changed, 542 insertions(+) create mode 100755 Runner/suites/Multimedia/Camera/Camera_NHX/run.sh diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/run.sh b/Runner/suites/Multimedia/Camera/Camera_NHX/run.sh new file mode 100755 index 00000000..5547249b --- /dev/null +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/run.sh @@ -0,0 +1,542 @@ +#!/bin/sh +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause-Clear +# +# Camera NHX validation + +TESTNAME="Camera_NHX" + +SCRIPT_DIR="$( + cd "$(dirname "$0")" || exit 1 + pwd +)" + +INIT_ENV="" +SEARCH="$SCRIPT_DIR" +while [ "$SEARCH" != "/" ]; do + if [ -f "$SEARCH/init_env" ]; then + INIT_ENV="$SEARCH/init_env" + break + fi + SEARCH=$(dirname "$SEARCH") +done + +RES_FILE="$SCRIPT_DIR/${TESTNAME}.res" + +if [ -z "${INIT_ENV:-}" ]; then + echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2 + echo "$TESTNAME SKIP" >"$RES_FILE" 2>/dev/null || true + exit 0 +fi + +if [ -z "${__INIT_ENV_LOADED:-}" ]; then + # shellcheck disable=SC1090 + . "$INIT_ENV" + __INIT_ENV_LOADED=1 +fi + +# shellcheck disable=SC1090,SC1091 +. "$TOOLS/functestlib.sh" + +# shellcheck disable=SC1090,SC1091 +. "$TOOLS/camera/lib_camera.sh" + +LOG_DIR="$SCRIPT_DIR/logs" +OUT_DIR="$SCRIPT_DIR/out" +DUMP_DIR="/var/cache/camera/nativehaltest" + +mkdir -p "$LOG_DIR" "$OUT_DIR" + +TS=$(date "+%Y%m%d_%H%M%S") +RUN_LOG="$LOG_DIR/${TESTNAME}_${TS}.log" +SUMMARY_TXT="$OUT_DIR/${TESTNAME}_summary_${TS}.txt" +DMESG_DIR="$LOG_DIR/dmesg_${TS}" + +# NHX helper output directory (IMPORTANT: lib_camera.sh expects a directory, not a file) +NHX_OUTDIR="$OUT_DIR/nhx_${TS}" + +# dump list & checksum artifacts (produced by dump validation helper) +DUMPS_LIST="$NHX_OUTDIR/nhx_dumps.list" +CHECKSUMS_TXT="$NHX_OUTDIR/nhx_checksums.txt" +CHECKSUMS_PREV="$OUT_DIR/${TESTNAME}_checksums.prev.txt" + +MARKER="$(mktemp "/tmp/${TESTNAME}.marker.XXXXXX" 2>/dev/null)" +if [ -z "$MARKER" ]; then + MARKER="/tmp/${TESTNAME}.marker.$$" + : >"$MARKER" 2>/dev/null || true +fi + +cleanup() { rm -f "$MARKER" 2>/dev/null || true; } +trap cleanup EXIT INT TERM + +# ----------------------------------------------------------------------------- +# Deps check (functestlib.sh provides check_dependencies) +# ----------------------------------------------------------------------------- +deps_list="date awk sed grep tee wc ls find stat rm tr head tail dmesg sort opkg fdtdump mkfifo sha256sum md5sum cksum diff cp" +if ! check_dependencies "$deps_list"; then + log_skip "$TESTNAME SKIP missing one or more dependencies: $deps_list" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 +fi + +if ! command -v nhx.sh >/dev/null 2>&1; then + log_skip "$TESTNAME SKIP nhx.sh not found in PATH" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 +fi + +# ----------------------------------------------------------------------------- +# CAMX prechecks +# Sequence: +# 1) DT check +# 2) fdtdump camera nodes sample +# 3) driver load checks +# 4) packages present +# 5) sensor presence warn-only +# ----------------------------------------------------------------------------- +log_info "Checking CAMX proprietary prerequisites before running NHX" + +# ----------------------------- +# 1) DT check +# ----------------------------- +log_info "DT check" + +PATTERNS="qcom,cam qcom,camera camera_kt cam-req-mgr cam-cpas cam-jpeg cam-ife cam-icp cam-sensor camera0-thermal" +found_any=0 +missing_list="" + +for pat in $PATTERNS; do + out="$(dt_confirm_node_or_compatible "$pat" 2>/dev/null || true)" + if [ -n "$out" ]; then + printf '%s\n' "$out" + found_any=1 + else + # Explicit append logic (reviewer-friendly; avoids &&/|| ambiguity) + if [ -n "$missing_list" ]; then + missing_list="$missing_list, $pat" + else + missing_list="$pat" + fi + fi +done + +if [ "$found_any" -ne 1 ]; then + log_skip "$TESTNAME SKIP missing DT patterns $missing_list" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 +fi + +# ----------------------------- +# 2) fdtdump camera nodes sample +# ----------------------------- +log_info "fdtdump camera nodes sample" + +FDT_MATCHES="$(camx_fdtdump_has_cam_nodes 2>/dev/null || true)" +rc=$? +if [ "$rc" -ne 0 ]; then + if [ "$rc" -eq 2 ]; then + log_skip "$TESTNAME SKIP fdtdump not available" + else + log_skip "$TESTNAME SKIP fdtdump did not show conclusive camera nodes" + fi + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 +fi + +printf '%s\n' "$FDT_MATCHES" | while IFS= read -r l; do + [ -n "$l" ] && log_info " $l" +done + +# ----------------------------- +# 3) driver load checks +# ----------------------------- +log_info "driver load checks" + +CAM_MOD="" + +if command -v lsmod >/dev/null 2>&1; then + CAM_MOD="$(lsmod 2>/dev/null | awk '{print $1}' \ + | grep -E '^(camera_qc|camera_qcm|camera_qcs)' \ + | head -n 1 || true)" +fi + +if [ -z "$CAM_MOD" ]; then + kver="$(uname -r 2>/dev/null || true)" + if [ -n "$kver" ] && [ -d "/lib/modules/$kver" ]; then + ko="$(find "/lib/modules/$kver" -type f \( -name 'camera_qc*.ko' -o -name 'camera_qcm*.ko' -o -name 'camera_qcs*.ko' \) \ + 2>/dev/null | head -n 1 || true)" + CAM_MOD="$(basename "${ko:-}" .ko)" + fi +fi + +if [ -z "$CAM_MOD" ]; then + log_skip "$TESTNAME SKIP could not determine camera module name" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 +fi + +CAM_KO="$(find_kernel_module "$CAM_MOD" 2>/dev/null || true)" +if [ -z "$CAM_KO" ] || [ ! -f "$CAM_KO" ]; then + log_skip "$TESTNAME SKIP camera module artifact not found ${CAM_MOD}.ko" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 +fi +log_info "Camera module artifact found $CAM_KO" + +if ! check_driver_loaded "$CAM_MOD" 2>/dev/null; then + log_skip "$TESTNAME SKIP camera module not loaded $CAM_MOD" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 +fi +log_info "Camera module is loaded $CAM_MOD" + +ICP_FW="$(camx_find_icp_firmware 2>/dev/null || true)" +if [ -z "$ICP_FW" ] || [ ! -f "$ICP_FW" ]; then + log_skip "$TESTNAME SKIP CAMERA_ICP firmware not found" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 +fi +log_info "ICP firmware found $ICP_FW" + +# dmesg collection and error scan +module_regex='CAM_(ERR|WARN|FATAL)' +exclude_regex='dummy regulator|supply [^ ]+ not found|using dummy regulator' + +scan_dmesg_errors "$DMESG_DIR" "$module_regex" "$exclude_regex" || true + +if [ -s "$DMESG_DIR/dmesg_errors.log" ]; then + log_warn "dmesg scan found camera warnings or errors in $DMESG_DIR/dmesg_errors.log" +else + log_info "dmesg scan did not find camera warnings or errors" +fi + +DM_SNAP="$DMESG_DIR/dmesg_snapshot.log" + +FW_BASENAME="$(basename "$ICP_FW" 2>/dev/null || echo "")" +FW_DL_OK=0 +FW_DONE_OK=0 + +if [ -n "$FW_BASENAME" ] && [ -r "$DM_SNAP" ]; then + if grep -F "CAM_INFO: CAM-ICP: cam_a5_download_fw" "$DM_SNAP" 2>/dev/null \ + | grep -F "$FW_BASENAME" >/dev/null 2>&1; then + FW_DL_OK=1 + fi + if grep -F "CAM_INFO: CAM-ICP: cam_icp_mgr_hw_open" "$DM_SNAP" 2>/dev/null \ + | grep -F "FW download done successfully" >/dev/null 2>&1; then + FW_DONE_OK=1 + fi +fi + +if [ "$FW_DL_OK" -eq 1 ] && [ "$FW_DONE_OK" -eq 1 ]; then + log_info "ICP firmware load markers found in dmesg" +else + log_warn "ICP firmware load markers missing in dmesg" + log_warn "FW download marker $FW_DL_OK" + log_warn "FW done marker $FW_DONE_OK" + log_warn "dmesg snapshot $DM_SNAP" +fi + +bind_cnt=0 +if [ -r "$DM_SNAP" ]; then + bind_cnt="$(grep -ciE 'cam_req_mgr.*bound|bound.*cam_req_mgr' "$DM_SNAP" 2>/dev/null || echo 0)" + case "$bind_cnt" in ''|*[!0-9]*) bind_cnt=0 ;; esac +fi + +if [ "$bind_cnt" -lt 5 ]; then + log_skip "$TESTNAME SKIP CAMX bind graph not observed" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 +fi +log_info "CAMX bind graph observed" + +# ----------------------------- +# 4) packages present +# ----------------------------- +log_info "packages present" + +CAMX_PKGS="$(camx_opkg_list_camx 2>/dev/null || true)" +if [ -z "$CAMX_PKGS" ]; then + log_skip "$TESTNAME SKIP CAMX packages not installed" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 +fi + +log_info "CAMX packages detected" +printf '%s\n' "$CAMX_PKGS" | while IFS= read -r l; do + [ -n "$l" ] && log_info " $l" +done + +# ----------------------------- +# 5) sensor presence warn-only +# ----------------------------- +log_info "sensor presence warn-only NHX may still work without cam sensors" + +SENSOR_COUNT="$(libcam_list_sensors_count 2>/dev/null || true)" +case "$SENSOR_COUNT" in ''|*[!0-9]*) SENSOR_COUNT=0 ;; esac +log_info "cam list detected $SENSOR_COUNT cameras" +if [ "$SENSOR_COUNT" -lt 1 ]; then + log_warn "No sensors reported by cam list continuing" +fi + +# ----------------------------------------------------------------------------- +# Pick checksum tool (prefer helper in lib_camera.sh) +# ----------------------------------------------------------------------------- +CKSUM_TOOL="" +if command -v nhx_pick_cksum_tool >/dev/null 2>&1; then + CKSUM_TOOL="$(nhx_pick_cksum_tool)" +else + if command -v sha256sum >/dev/null 2>&1; then + CKSUM_TOOL="sha256sum" + elif command -v md5sum >/dev/null 2>&1; then + CKSUM_TOOL="md5sum" + elif command -v cksum >/dev/null 2>&1; then + CKSUM_TOOL="cksum" + fi +fi + +log_info "$TESTNAME starting" +log_info "RUN_LOG=$RUN_LOG" +log_info "DUMP_DIR=$DUMP_DIR" +log_info "NHX_OUTDIR=$NHX_OUTDIR" +log_info "CKSUM_TOOL=${CKSUM_TOOL:-none}" + +# ----------------------------------------------------------------------------- +# Run NHX +# ----------------------------------------------------------------------------- +: >"$MARKER" 2>/dev/null || touch "$MARKER" + +log_info "Launching nhx.sh" + +if command -v run_cmd_live_to_log >/dev/null 2>&1; then + run_cmd_live_to_log "$RUN_LOG" nhx.sh + NHX_RC=$? +else + FIFO="/tmp/${TESTNAME}.fifo.$$" + rm -f "$FIFO" 2>/dev/null || true + + if ! mkfifo "$FIFO"; then + log_fail "$TESTNAME FAIL mkfifo failed" + echo "$TESTNAME FAIL" >"$RES_FILE" + exit 0 + fi + + ( tee "$RUN_LOG" <"$FIFO"; rm -f "$FIFO" 2>/dev/null || true ) & + TEEPID=$! + + nhx.sh >"$FIFO" 2>&1 + NHX_RC=$? + + wait "$TEEPID" 2>/dev/null || true +fi + +# ----------------------------------------------------------------------------- +# Dump validation (delegate to lib_camera.sh helper) +# IMPORTANT: helper expects an output DIRECTORY, not a file path. +# ----------------------------------------------------------------------------- +DUMP_VALIDATION_FAIL=0 + +# Ensure output directory exists regardless of helper/fallback +mkdir -p "$NHX_OUTDIR" 2>/dev/null || true + +if command -v nhx_validate_dumps_and_checksums >/dev/null 2>&1; then + # nhx_validate_dumps_and_checksums + if ! nhx_validate_dumps_and_checksums "$DUMP_DIR" "$MARKER" "$NHX_OUTDIR" "$CHECKSUMS_TXT" "$CHECKSUMS_PREV"; then + DUMP_VALIDATION_FAIL=1 + fi + + # If helper generated a different list name, keep our expected path working. + if [ ! -s "$DUMPS_LIST" ]; then + if [ -s "$NHX_OUTDIR/nhx_dumps.list" ]; then + DUMPS_LIST="$NHX_OUTDIR/nhx_dumps.list" + elif [ -s "$NHX_OUTDIR/dumps.list" ]; then + DUMPS_LIST="$NHX_OUTDIR/dumps.list" + elif [ -s "$NHX_OUTDIR/nhx_dump.list" ]; then + DUMPS_LIST="$NHX_OUTDIR/nhx_dump.list" + fi + fi +else + # fallback: old behavior + : >"$DUMPS_LIST" 2>/dev/null || true + + grep -F "Saving image to file:" "$RUN_LOG" \ + | sed 's/^.*Saving image to file:[[:space:]]*//' \ + | awk 'NF{print $0}' \ + | sort -u >"$DUMPS_LIST" 2>/dev/null || true + + DUMP_COUNT="$(wc -l <"$DUMPS_LIST" 2>/dev/null | awk '{print $1}')" + [ -n "$DUMP_COUNT" ] || DUMP_COUNT=0 + + if [ "$DUMP_COUNT" -eq 0 ]; then + log_info "No dump paths found in log scanning dump dir for new files" + if [ -d "$DUMP_DIR" ]; then + find "$DUMP_DIR" -type f -newer "$MARKER" 2>/dev/null | sort -u >"$DUMPS_LIST" + fi + fi +fi + +# ----------------------------------------------------------------------------- +# Compute dump count (based on DUMPS_LIST produced by helper/fallback) +# ----------------------------------------------------------------------------- +DUMP_COUNT="$(wc -l <"$DUMPS_LIST" 2>/dev/null | awk '{print $1}')" +[ -n "$DUMP_COUNT" ] || DUMP_COUNT=0 + +# ----------------------------------------------------------------------------- +# Validate dumps (summary-side size scan; checksum is already done by helper) +# ----------------------------------------------------------------------------- +ZERO_OR_MISSING=0 +TOTAL_BYTES=0 + +{ + echo "========================================" + echo "$TESTNAME Summary" + echo "Timestamp: $TS" + echo "nhx.sh exit code: $NHX_RC" + echo "Dump directory: $DUMP_DIR" + echo "Dump files detected: $DUMP_COUNT" + echo "Log file: $RUN_LOG" + echo "Checksum tool: ${CKSUM_TOOL:-none}" + echo "NHX outdir: $NHX_OUTDIR" + echo "Dump list: $DUMPS_LIST" + echo "Checksums: $CHECKSUMS_TXT" + echo "Prev checksums: $CHECKSUMS_PREV" + echo "Dump validation helper fail: $DUMP_VALIDATION_FAIL" + echo "========================================" + echo +} >"$SUMMARY_TXT" + +if [ "$DUMP_COUNT" -gt 0 ]; then + { + echo "Dump validation" + echo "----------------------------------------" + } >>"$SUMMARY_TXT" + + while IFS= read -r f; do + # Clear, reviewer-friendly empty-line skip + [ -z "$f" ] && continue + + if [ ! -f "$f" ]; then + ZERO_OR_MISSING=$((ZERO_OR_MISSING + 1)) + echo "MISSING: $f" >>"$SUMMARY_TXT" + continue + fi + + SZ="$(stat -c %s "$f" 2>/dev/null)" + if [ -z "$SZ" ]; then + SZ="$(wc -c <"$f" 2>/dev/null | awk '{print $1}')" + fi + [ -n "$SZ" ] || SZ=0 + + if [ "$SZ" -le 0 ]; then + ZERO_OR_MISSING=$((ZERO_OR_MISSING + 1)) + echo "ZERO-BYTES: $f size=$SZ" >>"$SUMMARY_TXT" + continue + fi + + TOTAL_BYTES=$((TOTAL_BYTES + SZ)) + echo "OK: $f size=$SZ" >>"$SUMMARY_TXT" + done <"$DUMPS_LIST" + + { + echo "----------------------------------------" + echo "Total dump bytes: $TOTAL_BYTES" + echo "Dump issues (missing/zero): $ZERO_OR_MISSING" + echo + } >>"$SUMMARY_TXT" +else + { + echo "Dump validation" + echo "----------------------------------------" + echo "No dump files detected" + echo "----------------------------------------" + echo + } >>"$SUMMARY_TXT" +fi + +# ----------------------------------------------------------------------------- +# Parse Final Report +# ----------------------------------------------------------------------------- +FINAL_LINE="$(grep -F "Final Report ->" "$RUN_LOG" | tail -n 1)" + +PASSED="" +FAILED="" +SKIPPED="" + +if [ -n "$FINAL_LINE" ]; then + PASSED="$(echo "$FINAL_LINE" | sed -n 's/.*\[\([0-9][0-9]*\) PASSED\].*/\1/p')" + FAILED="$(echo "$FINAL_LINE" | sed -n 's/.*\[\([0-9][0-9]*\) FAILED\].*/\1/p')" + SKIPPED="$(echo "$FINAL_LINE" | sed -n 's/.*\[\([0-9][0-9]*\) SKIPPED\].*/\1/p')" +fi + +{ + echo "Final Report parse" + echo "----------------------------------------" + echo "Final line: ${FINAL_LINE:-}" + echo "PASSED=$PASSED FAILED=$FAILED SKIPPED=$SKIPPED" + echo "----------------------------------------" +} >>"$SUMMARY_TXT" + +# ----------------------------------------------------------------------------- +# Decide PASS/FAIL +# ----------------------------------------------------------------------------- +RESULT="FAIL" +REASON="" + +if [ -z "$FINAL_LINE" ] || [ -z "$FAILED" ] || [ -z "$PASSED" ]; then + RESULT="FAIL" + REASON="Final Report not found or could not parse" +else + if [ "$FAILED" -gt 0 ]; then + RESULT="FAIL" + REASON="NHX reported FAILED=$FAILED" + else + RESULT="PASS" + REASON="NHX reported FAILED=0" + fi +fi + +if [ "$ZERO_OR_MISSING" -gt 0 ]; then + RESULT="FAIL" + if [ -n "$REASON" ]; then + REASON="$REASON dump issues=$ZERO_OR_MISSING" + else + REASON="dump issues=$ZERO_OR_MISSING" + fi +fi + +if [ "$DUMP_COUNT" -eq 0 ]; then + RESULT="FAIL" + if [ -n "$REASON" ]; then + REASON="$REASON no dumps detected" + else + REASON="no dumps detected" + fi +fi + +if [ "$DUMP_VALIDATION_FAIL" -ne 0 ]; then + RESULT="FAIL" + if [ -n "$REASON" ]; then + REASON="$REASON dump checksum validation failed" + else + REASON="dump checksum validation failed" + fi +fi + +log_info "========================================" +log_info "$TESTNAME final" +log_info "Final Report PASSED=${PASSED:-?} FAILED=${FAILED:-?} SKIPPED=${SKIPPED:-?}" +log_info "Dumps detected=$DUMP_COUNT issues=$ZERO_OR_MISSING total_bytes=$TOTAL_BYTES" +log_info "Dump validation helper fail=$DUMP_VALIDATION_FAIL" +log_info "Summary $SUMMARY_TXT" +log_info "Log $RUN_LOG" +log_info "Decision $RESULT $REASON" +log_info "========================================" + +if [ "$RESULT" = "PASS" ]; then + log_pass "$TESTNAME PASS $REASON" + echo "$TESTNAME PASS" >"$RES_FILE" +else + log_fail "$TESTNAME FAIL $REASON" + echo "$TESTNAME FAIL" >"$RES_FILE" +fi + +exit 0 From a1aded6683189387ab894a0d7bdbff2478a8af49 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Tue, 27 Jan 2026 23:08:36 +0530 Subject: [PATCH 12/16] lava(Camera_NHX): add Camera_NHX_Preview.yaml test definition Signed-off-by: Srikanth Muppandam --- .../Camera/Camera_NHX/Camera_NHX_Preview.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100755 Runner/suites/Multimedia/Camera/Camera_NHX/Camera_NHX_Preview.yaml diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/Camera_NHX_Preview.yaml b/Runner/suites/Multimedia/Camera/Camera_NHX/Camera_NHX_Preview.yaml new file mode 100755 index 00000000..acdb1cb1 --- /dev/null +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/Camera_NHX_Preview.yaml @@ -0,0 +1,15 @@ +metadata: + name: camera_nhx + format: "Lava-Test Test Definition 1.0" + description: "Camera NHX preview validation" + os: + - yocto + scope: + - functional + +run: + steps: + - REPO_PATH=$PWD + - cd Runner/suites/Multimedia/Camera/Camera_NHX + - ./run.sh || true + - $REPO_PATH/Runner/utils/send-to-lava.sh Camera_NHX.res From 492c7e530be4fa7f5e8ed88438d36eb1111b560a Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Tue, 27 Jan 2026 23:08:52 +0530 Subject: [PATCH 13/16] docs(Camera_NHX): add README.md for Camera_NHX Signed-off-by: Srikanth Muppandam --- .../Camera/Camera_NHX/README_Camera_NHX.md | 160 ++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 Runner/suites/Multimedia/Camera/Camera_NHX/README_Camera_NHX.md diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/README_Camera_NHX.md b/Runner/suites/Multimedia/Camera/Camera_NHX/README_Camera_NHX.md new file mode 100644 index 00000000..7f6b3d3a --- /dev/null +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/README_Camera_NHX.md @@ -0,0 +1,160 @@ +# Camera_NHX + +Camera NHX validation test for Qualcomm CAMX proprietary camera stack. This test runs `nhx.sh`, collects the generated image dumps, validates dumps (existence + non-zero size), and produces a PASS/FAIL `.res` file suitable for LAVA gating. + +--- + +## Location + +- Test script: `Runner/suites/Multimedia/Camera/Camera_NHX/run.sh` +- Utilities: + - `Runner/utils/functestlib.sh` + - `Runner/utils/camera/lib_camera.sh` + +--- + +## What this test does + +1. **Environment setup** + - Locates and sources `init_env` + - Sources `functestlib.sh` and `lib_camera.sh` + +2. **Dependency checks** + - Uses `check_dependencies` from `functestlib.sh` to ensure required commands exist. + +3. **CAMX proprietary prechecks (gate where required)** + - Device-tree presence checks for camera/CAMX patterns + - `fdtdump` scan for camera-related nodes (via helper) + - Camera kernel module detection + “loaded” validation + - ICP firmware presence check (CAMERA_ICP) + - `dmesg` scan for camera warnings/errors (warn-only) + - Gate on “bind graph observed” markers + +4. **Runs NHX** + - Executes `nhx.sh` and captures all output to a timestamped log. + +5. **Dump validation** + - Collects dump file list from NHX output and/or dump directory based on a marker timestamp. + - Validates: + - Dump list is non-empty + - Each dump file exists + - Each dump file size is **> 0 bytes** + - Optionally generates checksums (sha256sum/md5sum/cksum) and writes checksum files. + +6. **Result decision** + - Parses `Final Report -> [X PASSED] [Y FAILED] [Z SKIPPED]` from the NHX log + - FAIL if: + - Final Report missing/unparseable + - NHX reports FAILED > 0 + - No dumps detected + - Any dump missing/zero bytes + - Dump checksum validation helper fails + - Writes final result to: `Camera_NHX.res` + +--- + +## Outputs + +Created under the test directory: + +- Logs: + - `logs/Camera_NHX_.log` + - `logs/dmesg_/dmesg_snapshot.log` + - `logs/dmesg_/dmesg_errors.log` (if any matches) + +- Out files: + - `out/Camera_NHX_summary_.txt` + - Dump list file (path depends on `lib_camera.sh` helper output; typically under `out/`) + - Checksum file(s) (if enabled by helper/tool availability) + +- LAVA gating result: + - `Camera_NHX.res` + +--- + +## Dump directory + +By default the test expects NHX dumps under: + +- `/var/cache/camera/nativehaltest` + +(Referenced in `run.sh` as `DUMP_DIR`.) + +--- + +## How to run locally + +From the test folder: + +```sh +cd Runner/suites/Multimedia/Camera/Camera_NHX +./run.sh +cat Camera_NHX.res +``` + +This script is LAVA-friendly and exits `0` even on FAIL/SKIP; gating is via `.res`. + +--- + +## How to run in LAVA + +Example Lava-Test definition: + +```yaml +metadata: + name: camera_nhx + format: "Lava-Test Test Definition 1.0" + description: "Camera NHX validation" + os: + - linux + scope: + - functional + +run: + steps: + - REPO_PATH=$PWD + - cd Runner/suites/Multimedia/Camera/Camera_NHX + - ./run.sh || true + - $REPO_PATH/Runner/utils/send-to-lava.sh Camera_NHX.res +``` + +--- + +## PASS/FAIL/SKIP semantics + +- **PASS** + - NHX `Final Report` parsed successfully + - `FAILED=0` + - Dump list is non-empty + - All dump files exist and are **non-zero** + - Dump checksum validation helper did not fail (if used) + +- **FAIL** + - Any PASS condition not met (including missing/zero dumps) + +- **SKIP** + - Missing CAMX prerequisites (DT patterns, camera module artifact/loaded, ICP firmware, CAMX packages, etc.) + - `nhx.sh` not found in PATH + - `fdtdump` not available / inconclusive camera node evidence (as per helper return codes) + +--- + +## Notes / Troubleshooting + +### Timestamps show 1970-01-01 + +If logs show `1970-01-01`, the device clock is not set (common on early boot images or minimal init). This doesn’t affect functional correctness, but it can make log browsing confusing. Consider enabling NTP or setting RTC/time before running. + +### No dumps detected + +- Confirm NHX actually produced dumps and the dump path matches `DUMP_DIR` +- Check `logs/Camera_NHX_.log` for `Saving image to file:` lines +- Check permissions and free space under `/var/cache/camera/nativehaltest` + +### dmesg warnings + +The script scans dmesg and reports warnings, but does **not** SKIP just because camera warnings exist. Use the saved snapshot/errors logs to debug. + +### CAMX bind graph not observed (SKIP) + +If the bind graph markers are not seen enough times, the script SKIPs. This usually indicates CAMX stack did not fully initialize or relevant drivers/services didn’t come up. From 0c0b9b23d355b45a92368b84b45bc31b46dbd9ea Mon Sep 17 00:00:00 2001 From: Aanchal Chaurasia Date: Mon, 2 Feb 2026 01:44:35 +0530 Subject: [PATCH 14/16] Add test script to validate USB MSD The shell script verifies the enumeration of USB Mass Storage Devices. Signed-off-by: Aanchal Chaurasia --- Runner/suites/Kernel/Baseport/usb_msd/run.sh | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) mode change 100644 => 100755 Runner/suites/Kernel/Baseport/usb_msd/run.sh diff --git a/Runner/suites/Kernel/Baseport/usb_msd/run.sh b/Runner/suites/Kernel/Baseport/usb_msd/run.sh old mode 100644 new mode 100755 index b91a25b0..0f7a82d0 --- a/Runner/suites/Kernel/Baseport/usb_msd/run.sh +++ b/Runner/suites/Kernel/Baseport/usb_msd/run.sh @@ -27,6 +27,7 @@ fi if [ -z "$__INIT_ENV_LOADED" ]; then # shellcheck disable=SC1090 . "$INIT_ENV" + __INIT_ENV_LOADED=1 fi # Always source functestlib.sh, using $TOOLS exported by init_env # shellcheck disable=SC1090,SC1091 @@ -42,17 +43,16 @@ log_info "---------------------------------------------------------------------- log_info "-------------------Starting $TESTNAME Testcase----------------------------" log_info "=== Test Initialization ===" -# Check if lsusb is installed -check_dependencies lsusb grep +# Check if grep is installed, else skip test +deps_list="grep" +check_dependencies "$deps_list" +# Count interfaces with bInterfaceClass = 08 (MSD) under /sys/bus/usb/devices +msd_iface_count=0 log_info "=== USB Mass Storage device Detection ===" -# Count interfaces reported as Mass Storage by lsusb -v -msd_iface_count="$(lsusb -v 2>/dev/null | grep -i 'Mass Storage' | wc -l)" +msd_iface_count="$(cat /sys/bus/usb/devices/*/bInterfaceClass 2>/dev/null | grep -i '08' | wc -l)" -echo "lsusb -v Mass Storage descriptors:" -lsusb -v 2>/dev/null | grep -i 'Mass Storage' || true - -echo "Number of Mass Storage interfaces found: $msd_iface_count" +printf "Number of MSD interfaces found: $msd_iface_count" if [ "$msd_iface_count" -gt 0 ]; then log_pass "$TESTNAME : Test Passed - USB Mass Storage interface(s) detected" @@ -65,3 +65,5 @@ else fi log_info "-------------------Completed $TESTNAME Testcase----------------------------" +======= +log_info "-------------------Completed $TESTNAME Testcase----------------------------" \ No newline at end of file From 08e91ad37574b5d34f935e62e5ebe9965b1c1f2f Mon Sep 17 00:00:00 2001 From: Aanchal Chaurasia Date: Mon, 2 Feb 2026 01:47:00 +0530 Subject: [PATCH 15/16] Add documentation for Runner/../usb_msd/run.sh Added setup information and basic requirements. This informs the tester of the hardware setup requirement before starting test. Signed-off-by: Aanchal Chaurasia --- .../suites/Kernel/Baseport/usb_msd/README.md | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Runner/suites/Kernel/Baseport/usb_msd/README.md b/Runner/suites/Kernel/Baseport/usb_msd/README.md index 25436582..32da373b 100644 --- a/Runner/suites/Kernel/Baseport/usb_msd/README.md +++ b/Runner/suites/Kernel/Baseport/usb_msd/README.md @@ -19,9 +19,19 @@ This shell script executes on the DUT (Device-Under-Test) and verifies enumerati --- -## License +## Usage +### Instructions: +1. **Copy the test suite to the target device** using `scp` or any preferred method. +2. **Navigate to the test directory** on the target device. +3. **Run the test script** using the test runner or directly. -``` -Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. -SPDX-License-Identifier: BSD-3-Clause-Clear -``` +--- + +### Quick Example +```bash +git clone +cd +scp -r common Runner user@target_device_ip: +ssh user@target_device_ip +cd /Runner && ./run-test.sh usb_msd +``` \ No newline at end of file From 4956d55533bc3abd6b40b0bf570e5368a031bd8a Mon Sep 17 00:00:00 2001 From: Aanchal Chaurasia Date: Mon, 2 Feb 2026 01:47:53 +0530 Subject: [PATCH 16/16] Add test definition for usb_msd Individual test definition is meant to be used for debugging the test script running in LAVA. Signed-off-by: Aanchal Chaurasia --- Runner/suites/Kernel/Baseport/usb_msd/usb_msd.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Runner/suites/Kernel/Baseport/usb_msd/usb_msd.yaml b/Runner/suites/Kernel/Baseport/usb_msd/usb_msd.yaml index 56f443ab..f67e98d8 100644 --- a/Runner/suites/Kernel/Baseport/usb_msd/usb_msd.yaml +++ b/Runner/suites/Kernel/Baseport/usb_msd/usb_msd.yaml @@ -11,7 +11,5 @@ run: steps: - REPO_PATH=$PWD - cd Runner/suites/Kernel/Baseport/usb_msd - - chmod +x run.sh - ./run.sh || true - - $REPO_PATH/Runner/utils/send-to-lava.sh usb_msd.res || true - + - $REPO_PATH/Runner/utils/send-to-lava.sh usb_msd.res || true \ No newline at end of file