From d56bebb4fe45b5e7a7756f72eca0ecb87bc067e4 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Thu, 24 Sep 2026 05:39:43 +0530 Subject: [PATCH 1/3] fastcv: add distro runtime package preparation Install missing FastCV runtime packages on Debian, Ubuntu, CentOS, and RHEL while preserving the image-provided Yocto path. Configure and verify the CentOS 10 Qualcomm RPM repositories and EPEL without upgrading installed packages. Signed-off-by: Srikanth Muppandam --- Runner/config/pkg_command_map.conf | 16 +++ Runner/utils/lib_fastcv.sh | 76 +++++++++++++ Runner/utils/lib_pkg_provider.sh | 173 ++++++++++++++++++++++++++++- 3 files changed, 264 insertions(+), 1 deletion(-) create mode 100755 Runner/utils/lib_fastcv.sh diff --git a/Runner/config/pkg_command_map.conf b/Runner/config/pkg_command_map.conf index 2f07ded7..4c0b2e73 100755 --- a/Runner/config/pkg_command_map.conf +++ b/Runner/config/pkg_command_map.conf @@ -241,6 +241,22 @@ opkg:Sensors:sns_test=qcom-sensors-api qcom-sensors-core qcom-sensors-registry q debian:package-set:fastrpc=fastrpc-support fastrpc-tests ubuntu:package-set:fastrpc=fastrpc-support fastrpc-tests +# --------------------------------------------------------------------------- +# Qualcomm FastCV runtime package set. +# +# FastCV tests recover these packages automatically on supported host distros. +# Yocto and other image-managed targets have no mapping and retain their +# image-provided FastCV stack. The fastcv_test module runner and matching data +# remain external fixtures and are not supplied by this package set. +# --------------------------------------------------------------------------- + +debian:package-set:fastcv-runtime=qcom-fastcv-binaries libfastcvopt-dev +ubuntu:package-set:fastcv-runtime=qcom-fastcv-binaries libfastcvopt-dev +centos:package-set:fastcv-rpm-prerequisites=epel-release +centos:package-set:fastcv-runtime=qcom-fastcv-binaries libfastcvopt-devel +rhel:package-set:fastcv-rpm-prerequisites=epel-release +rhel:package-set:fastcv-runtime=qcom-fastcv-binaries libfastcvopt-devel + # --------------------------------------------------------------------------- # Qualcomm MinkIPC runtime and test packages. # diff --git a/Runner/utils/lib_fastcv.sh b/Runner/utils/lib_fastcv.sh new file mode 100755 index 00000000..befbd7d7 --- /dev/null +++ b/Runner/utils/lib_fastcv.sh @@ -0,0 +1,76 @@ +#!/bin/sh +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause + +# fastcv_prepare_runtime_packages +# Ensure the FastCV runtime package set on supported host distributions. +# Inputs: none. Output: no machine-readable stdout contract. +# Returns: 0 when packages are ready, 1 when required recovery fails, and 2 +# when the target is an image-managed or otherwise unsupported distribution. +# Side effects: may configure Qualcomm RPM repositories on CentOS/RHEL and may +# install mapped packages through lib_pkg_provider.sh. Package-set upgrades are +# disabled for this operation and the prior policy is restored before return. +# Yocto remains unchanged. +fastcv_prepare_runtime_packages() { + fcprp_os_id="$(pkg_detect_os_id)" + + for fcprp_helper in \ + pkg_provider_init \ + pkg_ensure_host_distro_package_set_present \ + pkg_ensure_required_package_set_present \ + pkg_package_recovery_supported_os; do + if ! command -v "$fcprp_helper" >/dev/null 2>&1; then + log_error "FastCV package preparation helper is unavailable: $fcprp_helper" + return 1 + fi + done + + if ! pkg_package_recovery_supported_os "$fcprp_os_id"; then + log_info "[FASTCV-PACKAGES] action=image-provided os=$fcprp_os_id set=fastcv-runtime" + return 2 + fi + + if ! pkg_provider_init; then + log_error "FastCV package provider initialization failed" + return 1 + fi + + fcprp_previous_set_upgrade="$PKG_PACKAGE_SET_UPGRADE" + PKG_PACKAGE_SET_UPGRADE=0 + fcprp_rc=0 + + case "$fcprp_os_id" in + centos|rhel) + if ! command -v pkg_ensure_qualcomm_rpm_repository >/dev/null 2>&1; then + log_error "FastCV RPM repository preparation helper is unavailable" + fcprp_rc=1 + elif ! pkg_ensure_required_package_set_present \ + fastcv-rpm-prerequisites; then + log_error "FastCV EPEL repository prerequisite installation failed, os=$fcprp_os_id package=epel-release" + fcprp_rc=1 + elif ! command -v pkg_rpm_repository_enabled >/dev/null 2>&1; then + log_error "FastCV RPM repository verification helper is unavailable" + fcprp_rc=1 + elif ! pkg_rpm_repository_enabled epel; then + log_error "FastCV EPEL repository is not enabled after installing epel-release, os=$fcprp_os_id repository=epel" + fcprp_rc=1 + elif ! pkg_ensure_qualcomm_rpm_repository; then + fcprp_rc=1 + fi + ;; + esac + + if [ "$fcprp_rc" -eq 0 ] && + ! pkg_ensure_host_distro_package_set_present fastcv-runtime; then + fcprp_rc=1 + fi + + PKG_PACKAGE_SET_UPGRADE="$fcprp_previous_set_upgrade" + + if [ "$fcprp_rc" -ne 0 ]; then + return "$fcprp_rc" + fi + + log_info "[FASTCV-PACKAGES] action=ready os=$fcprp_os_id set=fastcv-runtime upgrades=disabled" + return 0 +} diff --git a/Runner/utils/lib_pkg_provider.sh b/Runner/utils/lib_pkg_provider.sh index 18918ea2..f3337b67 100755 --- a/Runner/utils/lib_pkg_provider.sh +++ b/Runner/utils/lib_pkg_provider.sh @@ -59,6 +59,9 @@ PKG_APT_AUTH_PASSWORD_FILE="/run/qcom-testkit/secrets/debusine_api_token" PKG_RPM_UPDATED_MARK="/tmp/qcom_testkit_rpm_updated" PKG_RPM_UPGRADED_MARK="/tmp/qcom_testkit_rpm_upgraded" PKG_RPM_BEST_EFFORT_CLEAN="1" +PKG_QCOM_RPM_REPO_FILE="${PKG_QCOM_RPM_REPO_FILE:-/etc/yum.repos.d/qualcomm-linux.repo}" +PKG_QCOM_RPM_AARCH64_BASEURL="${PKG_QCOM_RPM_AARCH64_BASEURL:-https://softwarecenter.qualcomm.com/nexus/rpm/centos/10/os/aarch64/}" +PKG_QCOM_RPM_NOARCH_BASEURL="${PKG_QCOM_RPM_NOARCH_BASEURL:-https://softwarecenter.qualcomm.com/nexus/rpm/centos/10/os/noarch/}" PKG_OPKG_UPDATED_MARK="/tmp/qcom_testkit_opkg_updated" @@ -526,7 +529,7 @@ pkg_package_recovery_supported_os() { recovery_os_id="$1" case "$recovery_os_id" in - debian|ubuntu|centos) + debian|ubuntu|centos|rhel) return 0 ;; *) @@ -1636,6 +1639,174 @@ pkg_rpm_tool() { return 1 } +# pkg_rpm_repository_enabled REPOSITORY_ID +# Check whether one exact RPM repository ID is enabled. +# Inputs: one repository ID containing letters, digits, `.`, `_`, or `-`, and +# not beginning with `-`. Output: no stdout contract. +# Returns: 0 when enabled, and 1 when the ID, RPM tool, or repository listing +# is unavailable. Side effects: invokes a read-only dnf/yum repository query. +pkg_rpm_repository_enabled() { + prre_repo_id="$1" + prre_tool="$(pkg_rpm_tool || true)" + + case "$prre_repo_id" in + ''|-*|*[!A-Za-z0-9._-]*) + return 1 + ;; + esac + [ -n "$prre_tool" ] || return 1 + + if ! prre_repo_list="$($prre_tool repolist enabled 2>/dev/null)"; then + return 1 + fi + + printf '%s\n' "$prre_repo_list" | + awk '{print $1}' | + grep -Fxq "$prre_repo_id" +} + +# pkg_ensure_qualcomm_rpm_repository +# Configure the Qualcomm CentOS 10 aarch64 and noarch RPM repositories. +# Inputs: none. Output: no machine-readable stdout contract. +# Returns: 0 when both repositories are already enabled or configured, and +# 1 when the RPM provider, privileges, architecture, OS version, or +# configuration fails. +# Side effects: may create PKG_QCOM_RPM_REPO_FILE and invalidate the RPM +# metadata-update marker. Existing repository definitions are not overwritten. +pkg_ensure_qualcomm_rpm_repository() { + qrr_os_id="$(pkg_detect_os_id)" + qrr_os_version="$(pkg_os_release_value VERSION_ID || true)" + qrr_provider="$(pkg_active_provider)" + qrr_arch="$(uname -m 2>/dev/null || true)" + qrr_tool="$(pkg_rpm_tool || true)" + + case "$qrr_os_id" in + centos|rhel) + ;; + *) + pkg_log_info "Qualcomm RPM repository setup is not applicable, os=$qrr_os_id" + return 0 + ;; + esac + + if [ "$qrr_provider" != "rpm" ] || [ -z "$qrr_tool" ]; then + pkg_log_fail "Qualcomm RPM repository setup requires dnf or yum, os=$qrr_os_id provider=$qrr_provider" + return 1 + fi + + if [ "$qrr_arch" != "aarch64" ]; then + pkg_log_fail "Qualcomm RPM repository is available only for aarch64 targets, architecture=${qrr_arch:-unknown}" + return 1 + fi + + if ! qrr_repo_list="$($qrr_tool repolist enabled 2>/dev/null)"; then + pkg_log_fail "Could not inspect enabled RPM repositories, tool=$qrr_tool" + return 1 + fi + qrr_aarch64_present=0 + qrr_noarch_present=0 + if printf '%s\n' "$qrr_repo_list" | + awk '{print $1}' | + grep -Fxq "qualcomm-linux-aarch64"; then + qrr_aarch64_present=1 + fi + if printf '%s\n' "$qrr_repo_list" | + awk '{print $1}' | + grep -Fxq "qualcomm-linux-noarch"; then + qrr_noarch_present=1 + fi + + if [ "$qrr_aarch64_present" -eq 1 ] && + [ "$qrr_noarch_present" -eq 1 ]; then + pkg_log_pass "Qualcomm RPM repositories are already configured" + return 0 + fi + + if [ "$qrr_aarch64_present" -ne "$qrr_noarch_present" ]; then + pkg_log_fail "Qualcomm RPM repository configuration is incomplete, aarch64=$qrr_aarch64_present noarch=$qrr_noarch_present" + return 1 + fi + + qrr_os_major=${qrr_os_version%%.*} + if [ "$qrr_os_major" != "10" ]; then + pkg_log_fail "Automatic Qualcomm RPM repository setup supports CentOS/RHEL major version 10, os=$qrr_os_id version=${qrr_os_version:-unknown}" + return 1 + fi + + if [ -e "$PKG_QCOM_RPM_REPO_FILE" ]; then + pkg_log_fail "Qualcomm RPM repository file already exists without both enabled repository IDs, path=$PKG_QCOM_RPM_REPO_FILE" + return 1 + fi + + if ! pkg_can_install; then + pkg_log_fail "Qualcomm RPM repository configuration requires root and package auto-install support" + return 1 + fi + + case "$PKG_QCOM_RPM_REPO_FILE" in + */*) + qrr_repo_dir=${PKG_QCOM_RPM_REPO_FILE%/*} + ;; + *) + qrr_repo_dir=. + ;; + esac + qrr_temp_file="$(mktemp "${TMPDIR:-/tmp}/qcom-linux-fastcv-repo.XXXXXX")" || { + pkg_log_fail "Could not allocate a temporary Qualcomm RPM repository file" + return 1 + } + + if ! mkdir -p "$qrr_repo_dir"; then + pkg_log_fail "Could not create RPM repository directory, path=$qrr_repo_dir" + rm -f "$qrr_temp_file" + return 1 + fi + + { + printf '%s\n' \ + '[qualcomm-linux-aarch64]' \ + 'name=Qualcomm Linux RPM Repository - CentOS Stream 10 (aarch64)' \ + "baseurl=$PKG_QCOM_RPM_AARCH64_BASEURL" \ + 'enabled=1' \ + 'gpgcheck=0' \ + 'priority=10' \ + '' \ + '[qualcomm-linux-noarch]' \ + 'name=Qualcomm Linux RPM Repository - CentOS Stream 10 (noarch)' \ + "baseurl=$PKG_QCOM_RPM_NOARCH_BASEURL" \ + 'enabled=1' \ + 'gpgcheck=0' \ + 'priority=10' + } >"$qrr_temp_file" + + if ! install -m 0644 "$qrr_temp_file" "$PKG_QCOM_RPM_REPO_FILE"; then + pkg_log_fail "Could not install Qualcomm RPM repository configuration, path=$PKG_QCOM_RPM_REPO_FILE" + rm -f "$qrr_temp_file" + return 1 + fi + rm -f "$qrr_temp_file" + rm -f "$PKG_RPM_UPDATED_MARK" 2>/dev/null || true + + if ! qrr_repo_list="$($qrr_tool repolist enabled 2>/dev/null)"; then + pkg_log_fail "Could not verify enabled Qualcomm RPM repositories, tool=$qrr_tool file=$PKG_QCOM_RPM_REPO_FILE" + rm -f "$PKG_QCOM_RPM_REPO_FILE" + return 1 + fi + if ! printf '%s\n' "$qrr_repo_list" | + awk '{print $1}' | + grep -Fxq "qualcomm-linux-aarch64" || + ! printf '%s\n' "$qrr_repo_list" | + awk '{print $1}' | + grep -Fxq "qualcomm-linux-noarch"; then + pkg_log_fail "Qualcomm RPM repository file was created but both repository IDs are not enabled, path=$PKG_QCOM_RPM_REPO_FILE" + rm -f "$PKG_QCOM_RPM_REPO_FILE" + return 1 + fi + + pkg_log_pass "Configured Qualcomm RPM repositories, file=$PKG_QCOM_RPM_REPO_FILE" + return 0 +} + # Refresh rpm metadata. pkg_rpm_update() { rpm_tool="$(pkg_rpm_tool || true)" From 5f5c0d547fbb3de029473bf2d34ccb83f389e806 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Thu, 24 Sep 2026 05:39:45 +0530 Subject: [PATCH 2/3] fastcv: add functional validation suites Add bounded module validation for a user-provided fastcv_test fixture and exact deinterleave validation for fastcv_simple_test64. Document package recovery, fixture requirements, defaults, result policy, and retained evidence. Signed-off-by: Srikanth Muppandam --- .../FastCV_Module_Functional_Validation.yaml | 40 + .../README.md | 297 +++++++ .../run.sh | 836 ++++++++++++++++++ ...FastCV_Simple_Deinterleave_Validation.yaml | 19 + .../README.md | 162 ++++ .../run.sh | 284 ++++++ 6 files changed, 1638 insertions(+) create mode 100755 Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation/FastCV_Module_Functional_Validation.yaml create mode 100644 Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation/README.md create mode 100755 Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation/run.sh create mode 100755 Runner/suites/Multimedia/FastCV/FastCV_Simple_Deinterleave_Validation/FastCV_Simple_Deinterleave_Validation.yaml create mode 100644 Runner/suites/Multimedia/FastCV/FastCV_Simple_Deinterleave_Validation/README.md create mode 100755 Runner/suites/Multimedia/FastCV/FastCV_Simple_Deinterleave_Validation/run.sh diff --git a/Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation/FastCV_Module_Functional_Validation.yaml b/Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation/FastCV_Module_Functional_Validation.yaml new file mode 100755 index 00000000..85230796 --- /dev/null +++ b/Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation/FastCV_Module_Functional_Validation.yaml @@ -0,0 +1,40 @@ +metadata: + name: FastCV_Module_Functional_Validation + format: "Lava-Test Test Definition 1.0" + description: "Run a user-sideloaded fastcv_test binary with its matching data folder and validate module results" + os: + - linux + scope: + - functional + - external-fixture + +params: + FASTCV_TEST_BINARY: "" + FASTCV_TEST_DATA_DIR: "" + FASTCV_TEST_TARGETS: "6" + FASTCV_TEST_MODULES: "COLORYUV,SCALE,ARITHM,BLUR,TRNS" + FASTCV_TEST_LOOPS: "10" + FASTCV_TEST_LEVEL: "10" + FASTCV_TEST_TIMEOUT: "300" + FASTCV_TEST_FUNCTION: "" + FASTCV_TEST_OPERATION_MODE: "" + FASTCV_TEST_OPERATION_TABLES_ONLY: "0" + FASTCV_TEST_SEED: "" + FASTCV_TEST_NO_BUFFER_POOL: "0" + FASTCV_TEST_PREALLOC_BYTES: "" + FASTCV_TEST_OPENCV: "0" + FASTCV_TEST_UNIT_ONLY: "0" + FASTCV_TEST_PROFILE_ONLY: "0" + FASTCV_TEST_EXHAUSTIVE: "0" + FASTCV_TEST_RESOLUTION: "" + FASTCV_TEST_QDSP_HEAP: "0" + FASTCV_TEST_ELEMENT_ALIGNMENT: "0" + FASTCV_TEST_CACHE_FLUSH: "0" + FASTCV_TEST_WITHOUT_OPERATION_MODE: "0" + +run: + steps: + - REPO_PATH=$PWD + - cd Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation + - ./run.sh --binary "${FASTCV_TEST_BINARY}" --data-dir "${FASTCV_TEST_DATA_DIR}" --targets "${FASTCV_TEST_TARGETS}" --modules "${FASTCV_TEST_MODULES}" --loops "${FASTCV_TEST_LOOPS}" --level "${FASTCV_TEST_LEVEL}" --timeout "${FASTCV_TEST_TIMEOUT}" --function "${FASTCV_TEST_FUNCTION}" --operation-mode "${FASTCV_TEST_OPERATION_MODE}" --operation-tables-only "${FASTCV_TEST_OPERATION_TABLES_ONLY}" --seed "${FASTCV_TEST_SEED}" --no-buffer-pool "${FASTCV_TEST_NO_BUFFER_POOL}" --prealloc-bytes "${FASTCV_TEST_PREALLOC_BYTES}" --opencv "${FASTCV_TEST_OPENCV}" --unit-only "${FASTCV_TEST_UNIT_ONLY}" --profile-only "${FASTCV_TEST_PROFILE_ONLY}" --exhaustive "${FASTCV_TEST_EXHAUSTIVE}" --resolution "${FASTCV_TEST_RESOLUTION}" --qdsp-heap "${FASTCV_TEST_QDSP_HEAP}" --element-alignment "${FASTCV_TEST_ELEMENT_ALIGNMENT}" --cache-flush "${FASTCV_TEST_CACHE_FLUSH}" --without-operation-mode "${FASTCV_TEST_WITHOUT_OPERATION_MODE}" || true + - $REPO_PATH/Runner/utils/send-to-lava.sh FastCV_Module_Functional_Validation.res diff --git a/Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation/README.md b/Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation/README.md new file mode 100644 index 00000000..9f0f9fa5 --- /dev/null +++ b/Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation/README.md @@ -0,0 +1,297 @@ +# FastCV Module Functional Validation + +This suite runs the Qualcomm `fastcv_test` module test using a binary and +matching data folder supplied by the user. These assets are not assumed to be +part of an installable package, root filesystem, or ramdisk. + +The suite does not discover `fastcv_test` from `PATH` or download test data. +The operator must sideload both fixture assets and provide their locations +explicitly. On supported general-purpose distributions, the suite installs +missing FastCV runtime packages before executing a valid fixture. + +## Required fixture + +Provide: + +- the path to the executable `fastcv_test` binary; and +- the directory containing the matching FastCV test data, including the + required `FastCVTestTable.csv` control file. + +Absolute paths are recommended because LAVA invokes the suite from its +repository directory. For example: + +```sh +./run.sh \ + --binary /var/fastcv/fastcv_test \ + --data-dir /var/fastcv/test_data_new +``` + +If neither path is supplied, the suite skips cleanly and prints the required +options. If only one path is supplied, the suite fails as an incomplete fixture +configuration. Invalid, unreadable, empty, or non-executable fixture paths also +fail once explicitly selected. + +The `fastcv_test` executable and test-data directory must come from the same +FastCV release. Warnings such as `Unknown function ... in FastCVTestTable.csv` +usually indicate that the binary and test data do not match. + +## Platform prerequisites + +On Yocto and other image-managed systems, the suite performs no package-manager +operations. The validation ramdisk or image must already contain the required +FastCV runtime libraries. + +On Debian and Ubuntu, the suite checks and installs these missing packages: + +```text +qcom-fastcv-binaries libfastcvopt-dev +``` + +On CentOS Stream 10 and compatible Red Hat Enterprise Linux 10 aarch64 systems, +the suite first installs `epel-release`, then ensures that these two Qualcomm +CentOS 10 repositories are enabled: + +```text +https://softwarecenter.qualcomm.com/nexus/rpm/centos/10/os/aarch64/ +https://softwarecenter.qualcomm.com/nexus/rpm/centos/10/os/noarch/ +``` + +When neither repository ID is already enabled, the suite creates +`/etc/yum.repos.d/qualcomm-linux.repo` with the +`qualcomm-linux-aarch64` and `qualcomm-linux-noarch` definitions from the RPM +image setup guide. It then checks and installs: + +```text +qcom-fastcv-binaries libfastcvopt-devel +``` + +No installed package is upgraded. Package recovery needs root privileges, +network access, and working distro repositories only when a required package +or repository is missing. An incomplete pre-existing Qualcomm repository +configuration fails rather than being overwritten. Package preparation failure +is reported as a suite failure. The RPM path also verifies that the `epel` +repository is enabled after installing `epel-release`. Automatic repository +creation is rejected on other CentOS or Red Hat major versions because the +configured repository URLs are specific to version 10. + +These packages provide the FastCV runtime dependencies, but they do not provide +the `fastcv_test` module runner or its matching test data. Sideload both fixture +assets separately, for example: + +```sh +install -d /var/fastcv +install -m 0755 ./fastcv_test /var/fastcv/fastcv_test +tar -xf ./test_data.tar.gz -C /var/fastcv +test -r /var/fastcv/test_data_new/FastCVTestTable.csv +``` + +Then run the suite. Runtime package recovery happens automatically: + +```sh +sudo ./run.sh \ + --binary /var/fastcv/fastcv_test \ + --data-dir /var/fastcv/test_data_new +``` + +`sudo` is needed only when the suite must add a repository or install a missing +package. LAVA target shells commonly already run as root. + +## Default coverage + +The default command is equivalent to: + +```sh +/var/fastcv/fastcv_test /var/fastcv/test_data_new -t 6 -l 10 -m COLORYUV +/var/fastcv/fastcv_test /var/fastcv/test_data_new -t 6 -l 10 -m SCALE +/var/fastcv/fastcv_test /var/fastcv/test_data_new -t 6 -l 10 -m ARITHM +/var/fastcv/fastcv_test /var/fastcv/test_data_new -t 6 -l 10 -m BLUR +/var/fastcv/fastcv_test /var/fastcv/test_data_new -t 6 -l 10 -m TRNS +``` + +This bounded default covers representative color conversion, scaling, +arithmetic, filtering, and transformation operations on CPU and VENUM. Each +module runs as a separate invocation and must report its exact module PASS plus +both overall FIT PASS markers. Any module or overall FIT FAIL marker fails the +suite. + +The complete native matrix remains available explicitly with `--targets 0 +--modules all`. That mode enables every backend reported by the binary and +walks its complete module table. It can take substantially longer, and the +suite replays the retained command output after the invocation completes or +reaches its configured timeout. + +Supported target selectors are: + +| Value | Target requested by `fastcv_test` | +| --- | --- | +| `0` | All targets available to the binary | +| `2` | CPU | +| `4` | VENUM | +| `6` | CPU and VENUM | +| `8` | DSP | + +Multiple targets may be supplied as a comma-separated list. Each target is a +separate bounded invocation. + +## Focused module coverage + +Use `--modules` with one module or a comma-separated module list. Each selected +module runs separately with `-m` and must report its exact module PASS marker. + +```sh +./run.sh \ + --binary /var/fastcv/fastcv_test \ + --data-dir /var/fastcv/test_data_new \ + --targets 6 \ + --loops 10 \ + --modules COLORYUV,SCALE,ARITHM,BLUR,TRNS +``` + +For example, the `SCALE` invocation must report all three markers: + +```text +FASTCV_TEST, SCALE=>PASS +FIT:(FeatureName=>FASTCV, Overall=>PASS) +FASTCV_PROFILE, FIT:(FeatureName=>FASTCV, Overall=>PASS) +``` + +Module names are validated as alphanumeric identifiers with `_`, `+`, or `-` +characters. The suite does not impose a static allowlist because the +sideloaded binary and data revision own the available module set. + +Run one focused module on CPU and VENUM: + +```sh +./run.sh \ + --binary /var/fastcv/fastcv_test \ + --data-dir /var/fastcv/test_data_new \ + --targets 6 \ + --loops 10 \ + --modules COLORYUV +``` + +Run one focused module on DSP: + +```sh +./run.sh \ + --binary /var/fastcv/fastcv_test \ + --data-dir /var/fastcv/test_data_new \ + --targets 8 \ + --loops 10 \ + --modules SCALE +``` + +Run the complete native target and module matrix only in a suitably sized +scheduled job: + +```sh +./run.sh \ + --binary /var/fastcv/fastcv_test \ + --data-dir /var/fastcv/test_data_new \ + --targets 0 \ + --modules all \ + --loops 10 \ + --level 10 \ + --timeout 1800 +``` + +## Options and precedence + +The wrapper exposes the options that are actually parsed by the supplied +`fastcvTest.cpp` Linux implementation: + +| Wrapper option | `fastcv_test` argument | Default and constraints | +| --- | --- | --- | +| `--binary PATH` | executable | Required external fixture path | +| `--data-dir DIR` | first positional argument | Required matching data directory | +| `--targets LIST` | `-t` | Comma-separated `0`, `2`, `4`, `6`, or `8`, default `6` | +| `--modules LIST` | `-m` | `all` or comma-separated modules, default `COLORYUV,SCALE,ARITHM,BLUR,TRNS` | +| `--loops COUNT` | `-l` | Positive integer, default `10` | +| `--level COUNT` | `-L` | Positive integer for all-module runs, default `10` | +| `--timeout SECONDS` | wrapper only | Positive per-invocation bound, default `300` | +| `--function NAME` | `-f` | Optional function, requires exactly one focused module | +| `--operation-mode N` | `-M` | Optional operation-mode bit value `0` through `8` | +| `--operation-tables-only 0\|1` | `-OPT` | Requires a nonzero operation mode | +| `--seed INTEGER` | `-s` | Optional RNG seed, a negative value requests a time-based seed | +| `--no-buffer-pool 0\|1` | `-nbp` | Use ordinary allocations instead of the internal buffer pool | +| `--prealloc-bytes N` | `-psb` | Positive scratch-buffer preallocation size | +| `--opencv 0\|1` | `-o` | Request OpenCV benchmark profiling when supported by the binary build | +| `--unit-only 0\|1` | `-U` | Disable performance profiling | +| `--profile-only 0\|1` | `-P` | Disable unit tests | +| `--exhaustive 0\|1` | `-E` | Enable exhaustive profiling-vector validation | +| `--resolution N` | `-S` | Profiling resolution index `0` through `7` | +| `--qdsp-heap 0\|1` | `-H` | Allocate QDSP test vectors from the ARM heap | +| `--element-alignment 0\|1` | `-AL` | Limit allocation alignment to element size | +| `--cache-flush 0\|1` | `-C` | Request cache flush/invalidate profiling, a no-op in the supplied non-Android source | +| `--without-operation-mode 0\|1` | `-TWOp` | Run the source's additional API checks without calling `fcvSetOperationMode` | + +`--unit-only` and `--profile-only` are mutually exclusive. +`--no-buffer-pool` cannot be combined with `--prealloc-bytes`, because the +source applies preallocation only when its internal buffer pool is enabled. +When `--without-operation-mode 1` is selected, the suite also requires the +source's exact success marker for that additional path. + +The supplied source rejects more than 14 total process arguments. The wrapper +counts the final argument vector and fails before execution when a requested +combination exceeds that source limit. This means all supported switches are +available, but they cannot all be enabled in one invocation. Split such +coverage across multiple suite executions. + +Environment equivalents use the names in the YAML parameters: +`FASTCV_TEST_BINARY`, `FASTCV_TEST_DATA_DIR`, `FASTCV_TEST_TARGETS`, +`FASTCV_TEST_MODULES`, `FASTCV_TEST_LOOPS`, `FASTCV_TEST_LEVEL`, +`FASTCV_TEST_TIMEOUT`, `FASTCV_TEST_FUNCTION`, +`FASTCV_TEST_OPERATION_MODE`, `FASTCV_TEST_OPERATION_TABLES_ONLY`, +`FASTCV_TEST_SEED`, `FASTCV_TEST_NO_BUFFER_POOL`, +`FASTCV_TEST_PREALLOC_BYTES`, `FASTCV_TEST_OPENCV`, +`FASTCV_TEST_UNIT_ONLY`, `FASTCV_TEST_PROFILE_ONLY`, +`FASTCV_TEST_EXHAUSTIVE`, `FASTCV_TEST_RESOLUTION`, +`FASTCV_TEST_QDSP_HEAP`, `FASTCV_TEST_ELEMENT_ALIGNMENT`, +`FASTCV_TEST_CACHE_FLUSH`, and `FASTCV_TEST_WITHOUT_OPERATION_MODE`. +CLI values take precedence. + +For example, a focused function run is: + +```sh +./run.sh \ + --binary /var/fastcv/fastcv_test \ + --data-dir /var/fastcv/test_data_new \ + --targets 6 \ + --modules SCALE \ + --function fcvScaleDownBy2u8 +``` + +The supplied source prints help for `-p`, `-e`, and `-DF`, but its argument +parser does not implement those switches. The wrapper intentionally does not +advertise them. `-AC` is compiled only for Android and is also outside this +Linux suite's interface. + +The full matrix size is the number of targets multiplied by the number of +focused modules. The suite rejects selections above 64 invocations to keep an +accidental selector expansion from consuming an unbounded CI job. Keep large +matrices in an appropriate scheduled job and divide them across executions. + +## Results + +- **PASS**: every requested invocation exits zero, reports the required module + and overall FIT PASS markers, reports the profile FIT marker unless unit-only + mode was requested, verifies selected function or without-operation-mode + markers when applicable, and reports no official FAIL marker. +- **FAIL**: the explicit fixture is incomplete or invalid, configuration is + malformed, required host-distribution package recovery fails, execution + fails or times out, a FAIL marker is present, or required PASS markers are + missing. +- **SKIP**: neither sideloaded asset path is provided. Kernel-log health is a + separate SKIP if a DSP-capable target was selected but logs are unavailable. + +## Evidence + +Each run stores evidence below: + +```text +results/FastCV_Module_Functional_Validation/run--/ +``` + +Evidence includes binary metadata, a complete data-file listing, normalized +target and module selections, one complete log per invocation, and one retained +FastRPC kernel-log snapshot when target `0` or `8` is selected. diff --git a/Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation/run.sh b/Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation/run.sh new file mode 100755 index 00000000..bce77a7c --- /dev/null +++ b/Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation/run.sh @@ -0,0 +1,836 @@ +#!/bin/sh +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause + +# ---------- Repo env + helpers ---------- +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 + +if [ -z "$INIT_ENV" ]; then + echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2 + exit 1 +fi + +# Only source once (idempotent) +# NOTE: We intentionally **do not export** any new vars. They stay local to this shell. +if [ -z "${__INIT_ENV_LOADED:-}" ]; then + # shellcheck disable=SC1090 + . "$INIT_ENV" + __INIT_ENV_LOADED=1 +fi + +# shellcheck disable=SC1090 +. "$INIT_ENV" +# shellcheck disable=SC1091 +. "$TOOLS/functestlib.sh" +# shellcheck disable=SC1091 +. "$TOOLS/lib_pkg_provider.sh" +# shellcheck disable=SC1091 +. "$TOOLS/lib_fastcv.sh" +TESTNAME="FastCV_Module_Functional_Validation" +RES_FILE="$SCRIPT_DIR/$TESTNAME.res" + +FASTCV_TEST_BINARY="${FASTCV_TEST_BINARY:-}" +FASTCV_TEST_DATA_DIR="${FASTCV_TEST_DATA_DIR:-}" +FASTCV_TEST_TARGETS="${FASTCV_TEST_TARGETS:-6}" +FASTCV_TEST_MODULES="${FASTCV_TEST_MODULES:-COLORYUV,SCALE,ARITHM,BLUR,TRNS}" +FASTCV_TEST_LOOPS="${FASTCV_TEST_LOOPS:-10}" +FASTCV_TEST_LEVEL="${FASTCV_TEST_LEVEL:-10}" +FASTCV_TEST_TIMEOUT="${FASTCV_TEST_TIMEOUT:-300}" +FASTCV_TEST_FUNCTION="${FASTCV_TEST_FUNCTION:-}" +FASTCV_TEST_OPERATION_MODE="${FASTCV_TEST_OPERATION_MODE:-}" +FASTCV_TEST_OPERATION_TABLES_ONLY="${FASTCV_TEST_OPERATION_TABLES_ONLY:-0}" +FASTCV_TEST_SEED="${FASTCV_TEST_SEED:-}" +FASTCV_TEST_NO_BUFFER_POOL="${FASTCV_TEST_NO_BUFFER_POOL:-0}" +FASTCV_TEST_PREALLOC_BYTES="${FASTCV_TEST_PREALLOC_BYTES:-}" +FASTCV_TEST_OPENCV="${FASTCV_TEST_OPENCV:-0}" +FASTCV_TEST_UNIT_ONLY="${FASTCV_TEST_UNIT_ONLY:-0}" +FASTCV_TEST_PROFILE_ONLY="${FASTCV_TEST_PROFILE_ONLY:-0}" +FASTCV_TEST_EXHAUSTIVE="${FASTCV_TEST_EXHAUSTIVE:-0}" +FASTCV_TEST_RESOLUTION="${FASTCV_TEST_RESOLUTION:-}" +FASTCV_TEST_QDSP_HEAP="${FASTCV_TEST_QDSP_HEAP:-0}" +FASTCV_TEST_ELEMENT_ALIGNMENT="${FASTCV_TEST_ELEMENT_ALIGNMENT:-0}" +FASTCV_TEST_CACHE_FLUSH="${FASTCV_TEST_CACHE_FLUSH:-0}" +FASTCV_TEST_WITHOUT_OPERATION_MODE="${FASTCV_TEST_WITHOUT_OPERATION_MODE:-0}" +FASTCV_TEST_MAX_CASES=64 +RESULT_DIR="$SCRIPT_DIR/results/$TESTNAME/run-$(date '+%Y%m%d-%H%M%S')-$$" +BINARY_REPORT="$RESULT_DIR/fastcv_test_binary.log" +DATA_REPORT="$RESULT_DIR/fastcv_test_data_files.log" +CONTROL_TABLE="" +TARGET_LIST="$RESULT_DIR/fastcv_targets.list" +MODULE_LIST="$RESULT_DIR/fastcv_modules.list" +DSP_TARGET_SELECTED=0 + +# usage +# Print required fixture paths and configurable fastcv_test arguments. +# Inputs: none. Output: help text on stdout. Returns: 0. Side effects: none. +usage() { + printf '%s\n' \ + "Usage: ./run.sh --binary PATH --data-dir DIR [options]" \ + " --binary PATH Sideloaded fastcv_test executable" \ + " --data-dir DIR Matching sideloaded FastCV data directory" \ + " --targets LIST Comma-separated 0,2,4,6,8, default: 6" \ + " --modules LIST all or comma-separated modules" \ + " default: COLORYUV,SCALE,ARITHM,BLUR,TRNS" \ + " --loops COUNT Value passed with -l, default: 10" \ + " --level COUNT Value passed with -L for all modules, default: 10" \ + " --timeout SECONDS Bound each invocation, default: 300" \ + " --function NAME Limit to one function, requires one focused module" \ + " --operation-mode N Value passed with -M, accepted: 0 through 8" \ + " --operation-tables-only 0|1 Pass -OPT" \ + " --seed INTEGER Value passed with -s, empty keeps binary default" \ + " --no-buffer-pool 0|1 Pass -nbp" \ + " --prealloc-bytes N Pass -psb N" \ + " --opencv 0|1 Pass -o" \ + " --unit-only 0|1 Pass -U" \ + " --profile-only 0|1 Pass -P" \ + " --exhaustive 0|1 Pass -E" \ + " --resolution N Pass -S, accepted: 0 through 7" \ + " --qdsp-heap 0|1 Pass -H" \ + " --element-alignment 0|1 Pass -AL" \ + " --cache-flush 0|1 Pass -C" \ + " --without-operation-mode 0|1 Pass -TWOp" \ + " -h, --help" \ + "The binary and data folder are external fixture assets and must be provided together." +} + +# parse_args ARG... +# Parse CLI values into the suite configuration globals. +# Inputs: command-line arguments. Output: no stdout. +# Returns: 0 on success, 2 for invalid input, or exits after help. +# Side effects: updates all FASTCV_TEST_* configuration globals. +parse_args() { + while [ "$#" -gt 0 ]; do + case "$1" in + --binary) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_BINARY="$2" + shift 2 + ;; + --data-dir) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_DATA_DIR="$2" + shift 2 + ;; + --targets) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_TARGETS="$2" + shift 2 + ;; + --modules) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_MODULES="$2" + shift 2 + ;; + --loops) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_LOOPS="$2" + shift 2 + ;; + --level) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_LEVEL="$2" + shift 2 + ;; + --timeout) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_TIMEOUT="$2" + shift 2 + ;; + --function) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_FUNCTION="$2" + shift 2 + ;; + --operation-mode) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_OPERATION_MODE="$2" + shift 2 + ;; + --operation-tables-only) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_OPERATION_TABLES_ONLY="$2" + shift 2 + ;; + --seed) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_SEED="$2" + shift 2 + ;; + --no-buffer-pool) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_NO_BUFFER_POOL="$2" + shift 2 + ;; + --prealloc-bytes) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_PREALLOC_BYTES="$2" + shift 2 + ;; + --opencv) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_OPENCV="$2" + shift 2 + ;; + --unit-only) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_UNIT_ONLY="$2" + shift 2 + ;; + --profile-only) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_PROFILE_ONLY="$2" + shift 2 + ;; + --exhaustive) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_EXHAUSTIVE="$2" + shift 2 + ;; + --resolution) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_RESOLUTION="$2" + shift 2 + ;; + --qdsp-heap) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_QDSP_HEAP="$2" + shift 2 + ;; + --element-alignment) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_ELEMENT_ALIGNMENT="$2" + shift 2 + ;; + --cache-flush) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_CACHE_FLUSH="$2" + shift 2 + ;; + --without-operation-mode) + [ "$#" -ge 2 ] || return 2 + FASTCV_TEST_WITHOUT_OPERATION_MODE="$2" + shift 2 + ;; + -h|--help) + usage + exit 0 + ;; + *) + log_error "Unknown argument: $1" + return 2 + ;; + esac + done +} + +# validate_boolean_option NAME VALUE +# Validate one wrapper boolean encoded as 0 or 1. +# Inputs: user-facing option name and value. Output: error log on invalid input. +# Returns: 0 for 0 or 1, and 1 otherwise. Side effects: none beyond logging. +validate_boolean_option() { + vbo_name="$1" + vbo_value="$2" + + case "$vbo_value" in + 0|1) + return 0 + ;; + *) + log_error "$vbo_name must be 0 or 1, observed=${vbo_value:-empty}" + return 1 + ;; + esac +} + +# prepare_target_list TARGETS OUTPUT_FILE +# Validate target selectors and write one deduplicated target per line. +# Inputs: comma-separated selectors and retained output path. +# Output: no stdout. Returns: 0 for valid selectors or 1 otherwise. +# Side effects: replaces OUTPUT_FILE and updates DSP_TARGET_SELECTED. +prepare_target_list() { + ptl_targets="$1" + ptl_output="$2" + ptl_raw="$ptl_output.raw" + ptl_error="" + DSP_TARGET_SELECTED=0 + + rm -f "$ptl_output" "$ptl_raw" + if ! printf '%s\n' "$ptl_targets" | tr ',' '\n' >"$ptl_raw"; then + return 1 + fi + + while IFS= read -r ptl_target; do + case "$ptl_target" in + 0|2|4|6|8) + ;; + *) + ptl_error="Invalid FastCV target selector: ${ptl_target:-empty}" + break + ;; + esac + if grep -Fxq "$ptl_target" "$ptl_output" 2>/dev/null; then + ptl_error="Duplicate FastCV target selector: $ptl_target" + break + fi + printf '%s\n' "$ptl_target" >>"$ptl_output" + case "$ptl_target" in + 0|8) + DSP_TARGET_SELECTED=1 + ;; + esac + done <"$ptl_raw" + rm -f "$ptl_raw" + + if [ -n "$ptl_error" ]; then + log_error "$ptl_error" + return 1 + fi + + [ -s "$ptl_output" ] +} + +# prepare_module_list MODULES OUTPUT_FILE +# Validate a module selector or normalize all-module mode to the ALL token. +# Inputs: all or a comma-separated module list, and retained output path. +# Output: no stdout. Returns: 0 for valid selectors or 1 otherwise. +# Side effects: replaces OUTPUT_FILE and its temporary raw selector file. +prepare_module_list() { + pml_modules="$1" + pml_output="$2" + pml_raw="$pml_output.raw" + pml_normalized=$(printf '%s\n' "$pml_modules" | tr '[:lower:]' '[:upper:]') + pml_error="" + + rm -f "$pml_output" "$pml_raw" + if [ "$pml_normalized" = "ALL" ]; then + printf 'ALL\n' >"$pml_output" + return 0 + fi + if ! printf '%s\n' "$pml_normalized" | tr ',' '\n' >"$pml_raw"; then + return 1 + fi + + while IFS= read -r pml_module; do + case "$pml_module" in + ''|*[!A-Z0-9_+-]*) + pml_error="Invalid FastCV module selector: ${pml_module:-empty}" + break + ;; + esac + if grep -Fxq "$pml_module" "$pml_output" 2>/dev/null; then + pml_error="Duplicate FastCV module selector: $pml_module" + break + fi + printf '%s\n' "$pml_module" >>"$pml_output" + done <"$pml_raw" + rm -f "$pml_raw" + + if [ -n "$pml_error" ]; then + log_error "$pml_error" + return 1 + fi + + [ -s "$pml_output" ] +} + +# run_fastcv_test_case TARGET MODULE +# Execute one bounded fastcv_test target/module selection and classify markers. +# Inputs: validated target value and ALL or one validated module name. +# Output: emits bounded diagnostics through the common logger. +# Returns: 0 for functional PASS or 1 for FAIL. +# Side effects: creates a retained command log and records one testcase result. +run_fastcv_test_case() { + rftc_target="$1" + rftc_module="$2" + case "$rftc_target" in + 0) + rftc_target_name="all" + ;; + 2) + rftc_target_name="cpu" + ;; + 4) + rftc_target_name="venum" + ;; + 6) + rftc_target_name="cpu-venum" + ;; + 8) + rftc_target_name="dsp" + ;; + esac + + rftc_module_label=$(printf '%s\n' "$rftc_module" | tr '[:upper:]' '[:lower:]') + rftc_log="$RESULT_DIR/fastcv_target-${rftc_target}_${rftc_target_name}_module-${rftc_module_label}.log" + rm -f "$rftc_log" + + set -- \ + "$FASTCV_TEST_BINARY" \ + "$FASTCV_TEST_DATA_DIR" \ + -t "$rftc_target" \ + -l "$FASTCV_TEST_LOOPS" + if [ "$rftc_module" = "ALL" ]; then + set -- "$@" -L "$FASTCV_TEST_LEVEL" + else + set -- "$@" -m "$rftc_module" + fi + + if [ -n "$FASTCV_TEST_FUNCTION" ]; then + set -- "$@" -f "$FASTCV_TEST_FUNCTION" + fi + if [ -n "$FASTCV_TEST_OPERATION_MODE" ]; then + set -- "$@" -M "$FASTCV_TEST_OPERATION_MODE" + fi + if [ "$FASTCV_TEST_OPERATION_TABLES_ONLY" -eq 1 ]; then + set -- "$@" -OPT + fi + if [ -n "$FASTCV_TEST_SEED" ]; then + set -- "$@" -s "$FASTCV_TEST_SEED" + fi + if [ "$FASTCV_TEST_NO_BUFFER_POOL" -eq 1 ]; then + set -- "$@" -nbp + fi + if [ -n "$FASTCV_TEST_PREALLOC_BYTES" ]; then + set -- "$@" -psb "$FASTCV_TEST_PREALLOC_BYTES" + fi + if [ "$FASTCV_TEST_OPENCV" -eq 1 ]; then + set -- "$@" -o + fi + if [ "$FASTCV_TEST_UNIT_ONLY" -eq 1 ]; then + set -- "$@" -U + fi + if [ "$FASTCV_TEST_PROFILE_ONLY" -eq 1 ]; then + set -- "$@" -P + fi + if [ "$FASTCV_TEST_EXHAUSTIVE" -eq 1 ]; then + set -- "$@" -E + fi + if [ -n "$FASTCV_TEST_RESOLUTION" ]; then + set -- "$@" -S "$FASTCV_TEST_RESOLUTION" + fi + if [ "$FASTCV_TEST_QDSP_HEAP" -eq 1 ]; then + set -- "$@" -H + fi + if [ "$FASTCV_TEST_ELEMENT_ALIGNMENT" -eq 1 ]; then + set -- "$@" -AL + fi + if [ "$FASTCV_TEST_CACHE_FLUSH" -eq 1 ]; then + set -- "$@" -C + fi + if [ "$FASTCV_TEST_WITHOUT_OPERATION_MODE" -eq 1 ]; then + set -- "$@" -TWOp + fi + + rftc_argc=$# + if [ "$rftc_argc" -gt 14 ]; then + test_result_record \ + "FAIL" \ + "fastcv_test argument selection exceeds the source limit, target=$rftc_target module=$rftc_module argc=$rftc_argc maximum=14" + return 1 + fi + + log_info "[FASTCV-CASE] phase=start target=$rftc_target target_name=$rftc_target_name module=$rftc_module loops=$FASTCV_TEST_LOOPS level=$FASTCV_TEST_LEVEL function=${FASTCV_TEST_FUNCTION:-all} operation_mode=${FASTCV_TEST_OPERATION_MODE:-default} operation_tables_only=$FASTCV_TEST_OPERATION_TABLES_ONLY seed=${FASTCV_TEST_SEED:-default} no_buffer_pool=$FASTCV_TEST_NO_BUFFER_POOL prealloc_bytes=${FASTCV_TEST_PREALLOC_BYTES:-none} opencv=$FASTCV_TEST_OPENCV unit_only=$FASTCV_TEST_UNIT_ONLY profile_only=$FASTCV_TEST_PROFILE_ONLY exhaustive=$FASTCV_TEST_EXHAUSTIVE resolution=${FASTCV_TEST_RESOLUTION:-default} qdsp_heap=$FASTCV_TEST_QDSP_HEAP element_alignment=$FASTCV_TEST_ELEMENT_ALIGNMENT cache_flush=$FASTCV_TEST_CACHE_FLUSH without_operation_mode=$FASTCV_TEST_WITHOUT_OPERATION_MODE argc=$rftc_argc timeout=${FASTCV_TEST_TIMEOUT}s" + run_with_timeout_log \ + "$FASTCV_TEST_TIMEOUT" \ + "$rftc_log" \ + "$@" + rftc_rc=$? + + log_file_with_label "FASTCV-TEST-$rftc_target-$rftc_module" "$rftc_log" 120 + rftc_failure_count=$(grep -E -c 'FASTCV_TEST, .*=>FAIL|FIT:\(FeatureName=>FASTCV, Overall=>FAIL\)' "$rftc_log" 2>/dev/null || true) + rftc_fit_count=$(grep -E -c '^FIT:\(FeatureName=>FASTCV, Overall=>PASS\)[[:space:]]*$' "$rftc_log" 2>/dev/null || true) + rftc_profile_count=$(grep -E -c '^FASTCV_PROFILE, FIT:\(FeatureName=>FASTCV, Overall=>PASS\)[[:space:]]*$' "$rftc_log" 2>/dev/null || true) + if [ "$FASTCV_TEST_WITHOUT_OPERATION_MODE" -eq 1 ]; then + rftc_without_mode_count=$(grep -F -c \ + 'Running fastCV API without calling setOperationMode is pass' \ + "$rftc_log" 2>/dev/null || true) + else + rftc_without_mode_count=0 + fi + if [ -n "$FASTCV_TEST_FUNCTION" ]; then + rftc_function_count=$(grep -F -c "Function chosen: $FASTCV_TEST_FUNCTION" "$rftc_log" 2>/dev/null || true) + else + rftc_function_count=0 + fi + if [ "$rftc_module" = "ALL" ]; then + rftc_module_count=$(grep -E -c '^FASTCV_TEST, [^=]+=>PASS[[:space:]]*$' "$rftc_log" 2>/dev/null || true) + else + rftc_module_count=$(grep -F -c "FASTCV_TEST, $rftc_module=>PASS" "$rftc_log" 2>/dev/null || true) + fi + rftc_output_bytes=$(wc -c <"$rftc_log" 2>/dev/null | tr -d '[:space:]') + + rftc_profile_required=1 + if [ "$FASTCV_TEST_UNIT_ONLY" -eq 1 ]; then + rftc_profile_required=0 + fi + rftc_marker_missing=0 + if [ "$rftc_module_count" -eq 0 ] || [ "$rftc_fit_count" -eq 0 ]; then + rftc_marker_missing=1 + fi + if [ "$rftc_profile_required" -eq 1 ] && [ "$rftc_profile_count" -eq 0 ]; then + rftc_marker_missing=1 + fi + if [ -n "$FASTCV_TEST_FUNCTION" ] && [ "$rftc_function_count" -eq 0 ]; then + rftc_marker_missing=1 + fi + if [ "$FASTCV_TEST_WITHOUT_OPERATION_MODE" -eq 1 ] && + [ "$rftc_without_mode_count" -eq 0 ]; then + rftc_marker_missing=1 + fi + + log_info "[FASTCV-CASE] phase=complete target=$rftc_target target_name=$rftc_target_name module=$rftc_module rc=$rftc_rc module_pass_markers=$rftc_module_count fit_pass_markers=$rftc_fit_count profile_pass_markers=$rftc_profile_count profile_required=$rftc_profile_required function_markers=$rftc_function_count without_operation_mode_markers=$rftc_without_mode_count failure_markers=$rftc_failure_count output_bytes=${rftc_output_bytes:-0} artifact=$rftc_log" + + if [ "$rftc_rc" -ne 0 ]; then + test_result_record \ + "FAIL" \ + "fastcv_test failed or exceeded the ${FASTCV_TEST_TIMEOUT}s bound, target=$rftc_target module=$rftc_module rc=$rftc_rc artifact=$rftc_log" + return 1 + fi + if [ "$rftc_failure_count" -gt 0 ]; then + test_result_record \ + "FAIL" \ + "fastcv_test reported an official FAIL marker, target=$rftc_target module=$rftc_module failure_markers=$rftc_failure_count artifact=$rftc_log" + return 1 + fi + if [ "$rftc_marker_missing" -eq 1 ]; then + test_result_record \ + "FAIL" \ + "fastcv_test omitted required PASS evidence, target=$rftc_target module=$rftc_module module_markers=$rftc_module_count fit_markers=$rftc_fit_count profile_markers=$rftc_profile_count profile_required=$rftc_profile_required function_markers=$rftc_function_count without_operation_mode_markers=$rftc_without_mode_count artifact=$rftc_log" + return 1 + fi + + test_result_record \ + "PASS" \ + "fastcv_test completed functional module validation, target=$rftc_target target_name=$rftc_target_name module=$rftc_module module_pass_markers=$rftc_module_count artifact=$rftc_log" + return 0 +} + +parse_args "$@" || { + usage >&2 + exit 2 +} + +test_result_init "$TESTNAME" "$RES_FILE" || exit 1 + +if ! mkdir -p "$RESULT_DIR"; then + test_result_finish \ + "FAIL" \ + "$TESTNAME FAIL: cannot create retained evidence directory $RESULT_DIR" +fi + +log_info "--------------------------------------------------------------------------" +log_info "Starting $TESTNAME" +log_info "Evidence directory: $RESULT_DIR" +log_info "FastCV module functional validation: running a user-sideloaded fastcv_test binary with its matching data folder" +log_info "[FASTCV-POLICY] applicability=explicit-external-fixture binary=${FASTCV_TEST_BINARY:-none} data_dir=${FASTCV_TEST_DATA_DIR:-none} targets=$FASTCV_TEST_TARGETS modules=$FASTCV_TEST_MODULES loops=$FASTCV_TEST_LOOPS level=$FASTCV_TEST_LEVEL timeout=${FASTCV_TEST_TIMEOUT}s max_cases=$FASTCV_TEST_MAX_CASES" +log_info "[FASTCV-OPTIONS] function=${FASTCV_TEST_FUNCTION:-all} operation_mode=${FASTCV_TEST_OPERATION_MODE:-default} operation_tables_only=$FASTCV_TEST_OPERATION_TABLES_ONLY seed=${FASTCV_TEST_SEED:-default} no_buffer_pool=$FASTCV_TEST_NO_BUFFER_POOL prealloc_bytes=${FASTCV_TEST_PREALLOC_BYTES:-none} opencv=$FASTCV_TEST_OPENCV unit_only=$FASTCV_TEST_UNIT_ONLY profile_only=$FASTCV_TEST_PROFILE_ONLY exhaustive=$FASTCV_TEST_EXHAUSTIVE resolution=${FASTCV_TEST_RESOLUTION:-default} qdsp_heap=$FASTCV_TEST_QDSP_HEAP element_alignment=$FASTCV_TEST_ELEMENT_ALIGNMENT cache_flush=$FASTCV_TEST_CACHE_FLUSH without_operation_mode=$FASTCV_TEST_WITHOUT_OPERATION_MODE" + +if [ -z "$FASTCV_TEST_BINARY" ] && [ -z "$FASTCV_TEST_DATA_DIR" ]; then + test_result_record \ + "SKIP" \ + "fastcv_test is a sideloaded fixture, provide both --binary PATH and --data-dir DIR" + test_result_finish +fi +if [ -z "$FASTCV_TEST_BINARY" ] || [ -z "$FASTCV_TEST_DATA_DIR" ]; then + test_result_record \ + "FAIL" \ + "FastCV fixture configuration is incomplete, binary=${FASTCV_TEST_BINARY:-missing} data_dir=${FASTCV_TEST_DATA_DIR:-missing}" + test_result_finish +fi + +case "$FASTCV_TEST_LOOPS" in + ''|*[!0-9]*|0) + test_result_record "FAIL" "FastCV loop count must be a positive integer, observed=${FASTCV_TEST_LOOPS:-empty}" + test_result_finish + ;; +esac +case "$FASTCV_TEST_LEVEL" in + ''|*[!0-9]*|0) + test_result_record "FAIL" "FastCV level must be a positive integer, observed=${FASTCV_TEST_LEVEL:-empty}" + test_result_finish + ;; +esac +case "$FASTCV_TEST_TIMEOUT" in + ''|*[!0-9]*|0) + test_result_record "FAIL" "FastCV timeout must be a positive integer, observed=${FASTCV_TEST_TIMEOUT:-empty}" + test_result_finish + ;; +esac + +if ! validate_boolean_option \ + "--operation-tables-only" \ + "$FASTCV_TEST_OPERATION_TABLES_ONLY" || + ! validate_boolean_option \ + "--no-buffer-pool" \ + "$FASTCV_TEST_NO_BUFFER_POOL" || + ! validate_boolean_option \ + "--opencv" \ + "$FASTCV_TEST_OPENCV" || + ! validate_boolean_option \ + "--unit-only" \ + "$FASTCV_TEST_UNIT_ONLY" || + ! validate_boolean_option \ + "--profile-only" \ + "$FASTCV_TEST_PROFILE_ONLY" || + ! validate_boolean_option \ + "--exhaustive" \ + "$FASTCV_TEST_EXHAUSTIVE" || + ! validate_boolean_option \ + "--qdsp-heap" \ + "$FASTCV_TEST_QDSP_HEAP" || + ! validate_boolean_option \ + "--element-alignment" \ + "$FASTCV_TEST_ELEMENT_ALIGNMENT" || + ! validate_boolean_option \ + "--cache-flush" \ + "$FASTCV_TEST_CACHE_FLUSH" || + ! validate_boolean_option \ + "--without-operation-mode" \ + "$FASTCV_TEST_WITHOUT_OPERATION_MODE"; then + test_result_record \ + "FAIL" \ + "FastCV boolean option validation failed" + test_result_finish +fi + +case "$FASTCV_TEST_FUNCTION" in + ''|*[!A-Za-z0-9_]*) + if [ -n "$FASTCV_TEST_FUNCTION" ]; then + test_result_record \ + "FAIL" \ + "FastCV function selector contains unsupported characters, function=$FASTCV_TEST_FUNCTION" + test_result_finish + fi + ;; +esac +case "$FASTCV_TEST_OPERATION_MODE" in + ''|0|1|2|3|4|5|6|7|8) + ;; + *) + test_result_record \ + "FAIL" \ + "FastCV operation mode must be empty or 0 through 8, observed=$FASTCV_TEST_OPERATION_MODE" + test_result_finish + ;; +esac +if [ "$FASTCV_TEST_OPERATION_TABLES_ONLY" -eq 1 ] && + { [ -z "$FASTCV_TEST_OPERATION_MODE" ] || + [ "$FASTCV_TEST_OPERATION_MODE" -eq 0 ]; }; then + test_result_record \ + "FAIL" \ + "FastCV operation-tables-only mode requires a nonzero --operation-mode" + test_result_finish +fi +case "$FASTCV_TEST_SEED" in + '') + ;; + -*) + seed_digits=${FASTCV_TEST_SEED#-} + case "$seed_digits" in + ''|*[!0-9]*) + test_result_record "FAIL" "FastCV seed must be an integer, observed=$FASTCV_TEST_SEED" + test_result_finish + ;; + esac + ;; + *[!0-9]*) + test_result_record "FAIL" "FastCV seed must be an integer, observed=$FASTCV_TEST_SEED" + test_result_finish + ;; +esac +case "$FASTCV_TEST_PREALLOC_BYTES" in + '') + ;; + *[!0-9]*|0) + test_result_record \ + "FAIL" \ + "FastCV preallocation size must be a positive integer, observed=$FASTCV_TEST_PREALLOC_BYTES" + test_result_finish + ;; +esac +case "$FASTCV_TEST_RESOLUTION" in + ''|0|1|2|3|4|5|6|7) + ;; + *) + test_result_record \ + "FAIL" \ + "FastCV resolution selector must be empty or 0 through 7, observed=$FASTCV_TEST_RESOLUTION" + test_result_finish + ;; +esac +if [ "$FASTCV_TEST_UNIT_ONLY" -eq 1 ] && + [ "$FASTCV_TEST_PROFILE_ONLY" -eq 1 ]; then + test_result_record \ + "FAIL" \ + "FastCV unit-only and profile-only modes cannot be enabled together" + test_result_finish +fi +if [ "$FASTCV_TEST_NO_BUFFER_POOL" -eq 1 ] && + [ -n "$FASTCV_TEST_PREALLOC_BYTES" ]; then + test_result_record \ + "FAIL" \ + "FastCV preallocated buffer bytes cannot be combined with no-buffer-pool mode" + test_result_finish +fi + +if [ ! -e "$FASTCV_TEST_BINARY" ]; then + test_result_record \ + "FAIL" \ + "Sideloaded fastcv_test binary does not exist, binary=$FASTCV_TEST_BINARY" + test_result_finish +fi +if [ ! -f "$FASTCV_TEST_BINARY" ]; then + test_result_record \ + "FAIL" \ + "Sideloaded fastcv_test binary path is not a regular file, binary=$FASTCV_TEST_BINARY" + test_result_finish +fi +if [ ! -x "$FASTCV_TEST_BINARY" ]; then + test_result_record \ + "FAIL" \ + "Sideloaded fastcv_test binary is not executable, binary=$FASTCV_TEST_BINARY" + test_result_finish +fi +if [ ! -d "$FASTCV_TEST_DATA_DIR" ]; then + test_result_record \ + "FAIL" \ + "Sideloaded FastCV data path is not a directory, data_dir=$FASTCV_TEST_DATA_DIR" + test_result_finish +fi +if [ ! -r "$FASTCV_TEST_DATA_DIR" ]; then + test_result_record \ + "FAIL" \ + "Sideloaded FastCV data directory is not readable, data_dir=$FASTCV_TEST_DATA_DIR" + test_result_finish +fi + +CONTROL_TABLE="$FASTCV_TEST_DATA_DIR/FastCVTestTable.csv" +if [ ! -r "$CONTROL_TABLE" ]; then + test_result_record \ + "FAIL" \ + "Sideloaded FastCV data directory is missing the readable FastCVTestTable.csv control file, expected=$CONTROL_TABLE" + test_result_finish +fi + +fastcv_prepare_runtime_packages +fastcv_package_rc=$? +case "$fastcv_package_rc" in + 0|2) + ;; + *) + test_result_record \ + "FAIL" \ + "FastCV runtime package preparation failed, os=$(pkg_detect_os_id) set=fastcv-runtime" + test_result_finish + ;; +esac + +if ! find "$FASTCV_TEST_DATA_DIR" -type f -print >"$DATA_REPORT" 2>/dev/null; then + test_result_record \ + "FAIL" \ + "Could not enumerate the sideloaded FastCV data directory, data_dir=$FASTCV_TEST_DATA_DIR artifact=$DATA_REPORT" + test_result_finish +fi +data_file_count=$(wc -l <"$DATA_REPORT" 2>/dev/null | tr -d '[:space:]') +if [ "${data_file_count:-0}" -eq 0 ]; then + test_result_record \ + "FAIL" \ + "Sideloaded FastCV data directory contains no files, data_dir=$FASTCV_TEST_DATA_DIR artifact=$DATA_REPORT" + test_result_finish +fi + +{ + printf 'binary=%s\n' "$FASTCV_TEST_BINARY" + printf 'architecture=%s\n' "$(uname -m 2>/dev/null || printf 'unknown')" + ls -l "$FASTCV_TEST_BINARY" 2>&1 +} >"$BINARY_REPORT" +log_info "[FASTCV-FIXTURE] binary=$FASTCV_TEST_BINARY executable=1 data_dir=$FASTCV_TEST_DATA_DIR control_table=$CONTROL_TABLE control_table_readable=1 data_files=$data_file_count binary_artifact=$BINARY_REPORT data_artifact=$DATA_REPORT" +log_file_with_label "FASTCV-BINARY" "$BINARY_REPORT" 10 +log_file_with_label "FASTCV-DATA" "$DATA_REPORT" 40 + +if ! prepare_target_list "$FASTCV_TEST_TARGETS" "$TARGET_LIST"; then + test_result_record \ + "FAIL" \ + "FastCV target selection is invalid, requested=${FASTCV_TEST_TARGETS:-empty} accepted=0,2,4,6,8 artifact=$TARGET_LIST" + test_result_finish +fi +if ! prepare_module_list "$FASTCV_TEST_MODULES" "$MODULE_LIST"; then + test_result_record \ + "FAIL" \ + "FastCV module selection is invalid, requested=${FASTCV_TEST_MODULES:-empty} artifact=$MODULE_LIST" + test_result_finish +fi +log_file_with_label "FASTCV-TARGET" "$TARGET_LIST" 10 +log_file_with_label "FASTCV-MODULE" "$MODULE_LIST" 80 + +if grep -Fxq "0" "$TARGET_LIST" 2>/dev/null && + grep -Fxq "ALL" "$MODULE_LIST" 2>/dev/null; then + log_warn "[FASTCV-SELECTION] mode=full-target-full-module runtime=potentially-long output=replayed-after-completion timeout=${FASTCV_TEST_TIMEOUT}s" +fi + +target_count=$(wc -l <"$TARGET_LIST" 2>/dev/null | tr -d '[:space:]') +module_count=$(wc -l <"$MODULE_LIST" 2>/dev/null | tr -d '[:space:]') +if [ -n "$FASTCV_TEST_FUNCTION" ]; then + selected_module=$(sed -n '1p' "$MODULE_LIST") + if [ "$module_count" -ne 1 ] || [ "$selected_module" = "ALL" ]; then + test_result_record \ + "FAIL" \ + "FastCV function selection requires exactly one focused module, function=$FASTCV_TEST_FUNCTION requested_modules=$FASTCV_TEST_MODULES normalized_modules=$module_count" + test_result_finish + fi +fi +case_count=$((target_count * module_count)) +if [ "$case_count" -gt "$FASTCV_TEST_MAX_CASES" ]; then + test_result_record \ + "FAIL" \ + "FastCV selection exceeds the bounded invocation limit, requested=$case_count maximum=$FASTCV_TEST_MAX_CASES targets=$target_count modules=$module_count" + test_result_finish +fi +log_info "[FASTCV-SELECTION] targets=$target_count modules=$module_count invocations=$case_count dsp_target_selected=$DSP_TARGET_SELECTED target_artifact=$TARGET_LIST module_artifact=$MODULE_LIST" + +while IFS= read -r fastcv_target; do + while IFS= read -r fastcv_module; do + run_fastcv_test_case "$fastcv_target" "$fastcv_module" || true + done <"$MODULE_LIST" +done <"$TARGET_LIST" + +if [ "$DSP_TARGET_SELECTED" -eq 1 ]; then + KERNEL_LOG_JOURNAL_FALLBACK=1 + export KERNEL_LOG_JOURNAL_FALLBACK + scan_dmesg_errors \ + "$RESULT_DIR/kernel" \ + "fastrpc|adsprpc|cdsprpc" \ + "not a crash|subsys-restart" + dmesg_rc=$? + + if [ "${DMESG_ACCESS_STATUS:-unknown}" != "available" ]; then + test_result_record \ + "SKIP" \ + "Kernel log access is unavailable for FastCV DSP health validation, status=${DMESG_ACCESS_STATUS:-unknown} provider=${DMESG_ACCESS_PROVIDER:-none} rc=${DMESG_ACCESS_RC:-unknown} artifact=${DMESG_ACCESS_LOG:-$RESULT_DIR/kernel/dmesg_access.log}" + elif [ "$dmesg_rc" -eq 0 ]; then + test_result_record \ + "FAIL" \ + "FastRPC-related kernel errors were found during FastCV DSP validation, artifact=$RESULT_DIR/kernel/dmesg_errors.log" + else + test_result_record \ + "PASS" \ + "No persistent FastRPC kernel errors were found during FastCV DSP validation" + fi +else + log_info "[FASTCV-KERNEL] action=not-required reason=no-dsp-capable-target-selected" +fi + +test_result_finish diff --git a/Runner/suites/Multimedia/FastCV/FastCV_Simple_Deinterleave_Validation/FastCV_Simple_Deinterleave_Validation.yaml b/Runner/suites/Multimedia/FastCV/FastCV_Simple_Deinterleave_Validation/FastCV_Simple_Deinterleave_Validation.yaml new file mode 100755 index 00000000..e82add5b --- /dev/null +++ b/Runner/suites/Multimedia/FastCV/FastCV_Simple_Deinterleave_Validation/FastCV_Simple_Deinterleave_Validation.yaml @@ -0,0 +1,19 @@ +metadata: + name: FastCV_Simple_Deinterleave_Validation + format: "Lava-Test Test Definition 1.0" + description: "Run fastcv_simple_test64 and validate its deinterleave data-integrity result" + os: + - linux + scope: + - functional + +params: + FASTCV_BINARY: "" + FASTCV_TIMEOUT: "60" + +run: + steps: + - REPO_PATH=$PWD + - cd Runner/suites/Multimedia/FastCV/FastCV_Simple_Deinterleave_Validation + - ./run.sh --binary "${FASTCV_BINARY}" --timeout "${FASTCV_TIMEOUT}" || true + - $REPO_PATH/Runner/utils/send-to-lava.sh FastCV_Simple_Deinterleave_Validation.res diff --git a/Runner/suites/Multimedia/FastCV/FastCV_Simple_Deinterleave_Validation/README.md b/Runner/suites/Multimedia/FastCV/FastCV_Simple_Deinterleave_Validation/README.md new file mode 100644 index 00000000..87e6e41f --- /dev/null +++ b/Runner/suites/Multimedia/FastCV/FastCV_Simple_Deinterleave_Validation/README.md @@ -0,0 +1,162 @@ +# FastCV Simple Deinterleave Validation + +This suite runs the image-provided `fastcv_simple_test64` utility as a bounded +FastCV functional regression. It validates the utility status and its exact +deinterleave data-integrity result instead of treating binary or library +presence as a functional pass. + +## Coverage + +The suite: + +- discovers `fastcv_simple_test64` using CLI, environment, then `PATH` + precedence; +- runs the utility with a configurable timeout; +- requires a zero process status; +- requires the exact `Results match, Deinterleave Test passed` marker; +- rejects the exact `Results mismatch, Deinterleave Test failed` marker; +- retains and replays bounded utility output; and +- captures one FastRPC-related kernel-log snapshot through + `scan_dmesg_errors`. + +The public meta-qcom 1.8.9 recipe packages this utility in `fastcv-apps` and +installs it as `/usr/bin/fastcv_simple_test64`. General-purpose distribution +package layouts can differ, so the suite verifies the installed executable +after runtime package preparation. + +The inspected 1.8.9 utility selects FastCV CPU performance mode. This suite +therefore proves FastCV API execution and deinterleave data integrity, but it +does **not** prove CDSP offload. CDSP validation requires a separate utility +that explicitly selects `FASTCV_OP_EXT_CDSP`, performs an operation, and +provides observable offload evidence. + +## Portability and prerequisites + +The suite is intended for Yocto, Debian, Ubuntu, CentOS, and Red Hat targets. + +On Yocto and other image-managed systems, the suite performs no package-manager +operations. The validation ramdisk or image must already contain the FastCV +libraries and `fastcv_simple_test64`. + +On Debian and Ubuntu, the suite checks and installs these missing packages: + +```text +qcom-fastcv-binaries libfastcvopt-dev +``` + +On CentOS Stream 10 and compatible Red Hat Enterprise Linux 10 aarch64 systems, +it first installs `epel-release`, then ensures that the Qualcomm CentOS 10 +`aarch64` and `noarch` repositories are enabled: + +```text +https://softwarecenter.qualcomm.com/nexus/rpm/centos/10/os/aarch64/ +https://softwarecenter.qualcomm.com/nexus/rpm/centos/10/os/noarch/ +``` + +When needed, their definitions are written to +`/etc/yum.repos.d/qualcomm-linux.repo`. The suite then checks and installs: + +```text +qcom-fastcv-binaries libfastcvopt-devel +``` + +No installed package is upgraded. Package recovery needs root privileges, +network access, and working distro repositories only when a required package +or repository is missing. An incomplete pre-existing Qualcomm repository +configuration fails rather than being overwritten. +The RPM path also verifies that the `epel` repository is enabled after +installing `epel-release`. Automatic repository creation is rejected on other +CentOS or Red Hat major versions because the configured repository URLs are +specific to version 10. + +After package preparation, the selected package split must provide +`fastcv_simple_test64` in `PATH`. The suite verifies this dynamically before +execution. To inspect it manually: + +```sh +command -v fastcv_simple_test64 +fastcv_simple_test64 +``` + +If the optional FastCV utility is absent from automatic discovery, the test +skips cleanly. An explicitly requested missing binary fails because the +override declares that binary as required. + +The `--binary` override must identify the packaged `fastcv_simple_test64` +deinterleave utility. It must not point to the separately sideloaded +`fastcv_test` module runner, which requires a test-data directory and exposes a +different CLI and result-marker contract. The suite detects that module CLI and +fails with an explicit wrong-binary diagnostic. + +A present utility that cannot execute, times out, exits nonzero, reports a +mismatch, or omits its success marker fails the functional check. + +## Usage + +Run with automatic discovery: + +```sh +./run.sh +``` + +On a supported general-purpose distribution, this command also performs the +automatic missing-package and repository preparation described above. +Use `sudo ./run.sh` when that preparation is needed and the current shell is +not already root. + +Select a utility explicitly: + +```sh +./run.sh --binary /usr/bin/fastcv_simple_test64 +``` + +The following is intentionally invalid because `fastcv_test` is the separate +module runner and requires its matching test-data directory: + +```sh +./run.sh --binary /var/fastcv/fastcv_test +``` + +Change the execution bound: + +```sh +./run.sh --timeout 90 +``` + +Environment equivalents are `FASTCV_BINARY` and `FASTCV_TIMEOUT`. CLI values +take precedence over environment values. An empty binary value keeps automatic +discovery enabled. + +## Results + +- **PASS**: the utility exits zero, reports at least one exact success marker, + and reports no exact mismatch marker. +- **FAIL**: required host-distribution package recovery fails, an explicitly + requested binary is absent, the discovered binary is not executable, + execution fails or exceeds the timeout, a mismatch is reported, or the + required success marker is absent. +- **SKIP**: automatic discovery finds no image-provided utility. Kernel-log + health is also a separate SKIP when the target does not expose readable + kernel logs. + +Kernel errors matched for FastRPC support are reported as a separate failure +and do not change the scope into a CDSP-offload claim. + +## Evidence + +Each run stores artifacts below: + +```text +results/FastCV_Simple_Deinterleave_Validation/run--/ +``` + +Artifacts include: + +- `fastcv_binary.log`: selected path, source, architecture, and file metadata; +- `fastcv_simple_test.log`: complete utility stdout and stderr; +- `kernel/dmesg_snapshot.log`: captured kernel log when access is available; +- `kernel/dmesg_errors.log`: filtered FastRPC-related errors; and +- `kernel/dmesg_access.log`: kernel-log provider and access diagnostics. + +Live stdout includes the selection source, bounded utility output, exit status, +marker counts, artifact paths, and final PASS, FAIL, or SKIP reasons. diff --git a/Runner/suites/Multimedia/FastCV/FastCV_Simple_Deinterleave_Validation/run.sh b/Runner/suites/Multimedia/FastCV/FastCV_Simple_Deinterleave_Validation/run.sh new file mode 100755 index 00000000..9ba90e25 --- /dev/null +++ b/Runner/suites/Multimedia/FastCV/FastCV_Simple_Deinterleave_Validation/run.sh @@ -0,0 +1,284 @@ +#!/bin/sh +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause + +# ---------- Repo env + helpers ---------- +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 + +if [ -z "$INIT_ENV" ]; then + echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2 + exit 1 +fi + +# Only source once (idempotent) +# NOTE: We intentionally **do not export** any new vars. They stay local to this shell. +if [ -z "${__INIT_ENV_LOADED:-}" ]; then + # shellcheck disable=SC1090 + . "$INIT_ENV" + __INIT_ENV_LOADED=1 +fi + +# shellcheck disable=SC1090 +. "$INIT_ENV" +# shellcheck disable=SC1091 +. "$TOOLS/functestlib.sh" +# shellcheck disable=SC1091 +. "$TOOLS/lib_pkg_provider.sh" +# shellcheck disable=SC1091 +. "$TOOLS/lib_fastcv.sh" +TESTNAME="FastCV_Simple_Deinterleave_Validation" +RES_FILE="$SCRIPT_DIR/$TESTNAME.res" + +FASTCV_BINARY="${FASTCV_BINARY:-}" +FASTCV_TIMEOUT="${FASTCV_TIMEOUT:-60}" +FASTCV_BINARY_SOURCE="dynamic-discovery" +RESULT_DIR="$SCRIPT_DIR/results/$TESTNAME/run-$(date '+%Y%m%d-%H%M%S')-$$" +RUN_LOG="$RESULT_DIR/fastcv_simple_test.log" +BINARY_REPORT="$RESULT_DIR/fastcv_binary.log" +SUCCESS_MARKER="Results match, Deinterleave Test passed" +FAILURE_MARKER="Results mismatch, Deinterleave Test failed" + +if [ -n "$FASTCV_BINARY" ]; then + FASTCV_BINARY_SOURCE="environment" +fi + +# usage +# Print FastCV CLI options and automatic binary-discovery behavior. +# Inputs: none. Output: help text on stdout. Returns: 0. Side effects: none. +usage() { + printf '%s\n' \ + "Usage: ./run.sh [options]" \ + " --binary PATH Override the FastCV utility path" \ + " --timeout SECONDS Bound the utility runtime, default: 60" \ + " -h, --help" \ + "Binary selection precedence is CLI, FASTCV_BINARY, then PATH." \ + "The packaged utility validates FastCV data integrity and does not prove CDSP offload." +} + +# parse_args ARG... +# Parse CLI overrides into the FastCV binary and timeout globals. +# Inputs: command-line arguments. Output: no stdout. +# Returns: 0 on success, 2 for invalid input, or exits after help. +# Side effects: updates FASTCV_BINARY, FASTCV_BINARY_SOURCE, and FASTCV_TIMEOUT. +parse_args() { + while [ "$#" -gt 0 ]; do + case "$1" in + --binary) + [ "$#" -ge 2 ] || return 2 + FASTCV_BINARY="$2" + if [ -n "$FASTCV_BINARY" ]; then + FASTCV_BINARY_SOURCE="cli" + else + FASTCV_BINARY_SOURCE="dynamic-discovery" + fi + shift 2 + ;; + --timeout) + [ "$#" -ge 2 ] || return 2 + FASTCV_TIMEOUT="$2" + shift 2 + ;; + -h|--help) + usage + exit 0 + ;; + *) + log_error "Unknown argument: $1" + return 2 + ;; + esac + done +} + +parse_args "$@" || { + usage >&2 + exit 2 +} + +test_result_init "$TESTNAME" "$RES_FILE" || exit 1 + +if ! mkdir -p "$RESULT_DIR"; then + test_result_finish \ + "FAIL" \ + "$TESTNAME FAIL: cannot create retained evidence directory $RESULT_DIR" +fi + +log_info "--------------------------------------------------------------------------" +log_info "Starting $TESTNAME" +log_info "Evidence directory: $RESULT_DIR" +log_info "FastCV simple deinterleave validation: running fastcv_simple_test64 with bounded execution and exact result-marker checks" +log_info "[FASTCV-POLICY] applicability=dynamic operation=deinterleave-data-integrity timeout=${FASTCV_TIMEOUT}s offload_claim=none" + +case "$FASTCV_TIMEOUT" in + ''|*[!0-9]*|0) + test_result_record \ + "FAIL" \ + "FastCV configuration is invalid, timeout must be a positive integer" + test_result_finish + ;; +esac + +fastcv_prepare_runtime_packages +fastcv_package_rc=$? +case "$fastcv_package_rc" in + 0|2) + ;; + *) + test_result_record \ + "FAIL" \ + "FastCV runtime package preparation failed, os=$(pkg_detect_os_id) set=fastcv-runtime" + test_result_finish + ;; +esac + +FASTCV_BINARY_PATH="" +if [ -n "$FASTCV_BINARY" ]; then + case "$FASTCV_BINARY" in + */*) + FASTCV_BINARY_PATH="$FASTCV_BINARY" + ;; + *) + FASTCV_BINARY_PATH=$(command -v "$FASTCV_BINARY" 2>/dev/null || true) + ;; + esac +else + FASTCV_BINARY_PATH=$(command -v fastcv_simple_test64 2>/dev/null || true) + if [ -n "$FASTCV_BINARY_PATH" ]; then + FASTCV_BINARY_SOURCE="path-discovery" + fi +fi + +if [ -z "$FASTCV_BINARY_PATH" ] || [ ! -e "$FASTCV_BINARY_PATH" ]; then + log_info "[FASTCV-DISCOVERY] selected=none source=$FASTCV_BINARY_SOURCE path_candidate=fastcv_simple_test64" + case "$FASTCV_BINARY_SOURCE" in + cli|environment) + test_result_record \ + "FAIL" \ + "Requested FastCV utility is not present, requested=${FASTCV_BINARY:-empty} source=$FASTCV_BINARY_SOURCE" + ;; + *) + test_result_record \ + "SKIP" \ + "FastCV utility fastcv_simple_test64 is not installed in PATH" + ;; + esac + test_result_finish +fi + +if [ ! -f "$FASTCV_BINARY_PATH" ]; then + log_info "[FASTCV-DISCOVERY] selected=$FASTCV_BINARY_PATH source=$FASTCV_BINARY_SOURCE regular_file=0" + test_result_record \ + "FAIL" \ + "FastCV utility path is not a regular file, binary=$FASTCV_BINARY_PATH source=$FASTCV_BINARY_SOURCE" + test_result_finish +fi + +if [ ! -x "$FASTCV_BINARY_PATH" ]; then + log_info "[FASTCV-DISCOVERY] selected=$FASTCV_BINARY_PATH source=$FASTCV_BINARY_SOURCE executable=0" + test_result_record \ + "FAIL" \ + "FastCV utility exists but is not executable, binary=$FASTCV_BINARY_PATH source=$FASTCV_BINARY_SOURCE" + test_result_finish +fi + +{ + printf 'binary=%s\n' "$FASTCV_BINARY_PATH" + printf 'source=%s\n' "$FASTCV_BINARY_SOURCE" + printf 'architecture=%s\n' "$(uname -m 2>/dev/null || printf 'unknown')" + ls -l "$FASTCV_BINARY_PATH" 2>&1 +} >"$BINARY_REPORT" + +log_info "[FASTCV-DISCOVERY] selected=$FASTCV_BINARY_PATH source=$FASTCV_BINARY_SOURCE executable=1 artifact=$BINARY_REPORT" +log_file_with_label "FASTCV-BINARY" "$BINARY_REPORT" 10 +log_info "[FASTCV-FUNCTIONAL] phase=start binary=$FASTCV_BINARY_PATH timeout=${FASTCV_TIMEOUT}s expected_marker=$SUCCESS_MARKER" + +run_with_timeout_log "$FASTCV_TIMEOUT" "$RUN_LOG" "$FASTCV_BINARY_PATH" +fastcv_rc=$? +log_file_with_label "FASTCV-OUTPUT" "$RUN_LOG" 80 + +success_count=$(grep -F -c "$SUCCESS_MARKER" "$RUN_LOG" 2>/dev/null || true) +failure_count=$(grep -F -c "$FAILURE_MARKER" "$RUN_LOG" 2>/dev/null || true) +module_cli_count=$(grep -E -c '^USAGE: .*test_data_directory' "$RUN_LOG" 2>/dev/null || true) +output_bytes=$(wc -c <"$RUN_LOG" 2>/dev/null | tr -d '[:space:]') + +case "$success_count" in + ''|*[!0-9]*) + success_count=0 + ;; +esac +case "$failure_count" in + ''|*[!0-9]*) + failure_count=0 + ;; +esac +case "$module_cli_count" in + ''|*[!0-9]*) + module_cli_count=0 + ;; +esac +case "$output_bytes" in + ''|*[!0-9]*) + output_bytes=0 + ;; +esac + +log_info "[FASTCV-FUNCTIONAL] phase=complete rc=$fastcv_rc success_markers=$success_count failure_markers=$failure_count module_cli_markers=$module_cli_count output_bytes=$output_bytes artifact=$RUN_LOG" + +if [ "$module_cli_count" -gt 0 ]; then + test_result_record \ + "FAIL" \ + "Selected executable exposes the fastcv_test module CLI instead of the packaged fastcv_simple_test64 deinterleave contract, binary=$FASTCV_BINARY_PATH artifact=$RUN_LOG" +elif [ "$fastcv_rc" -ne 0 ]; then + test_result_record \ + "FAIL" \ + "FastCV utility failed or exceeded the ${FASTCV_TIMEOUT}s execution bound, rc=$fastcv_rc artifact=$RUN_LOG" +elif [ "$failure_count" -gt 0 ]; then + test_result_record \ + "FAIL" \ + "FastCV utility reported a deinterleave data mismatch, failure_markers=$failure_count artifact=$RUN_LOG" +elif [ "$success_count" -eq 0 ]; then + test_result_record \ + "FAIL" \ + "FastCV utility exited successfully but did not report the required deinterleave success marker, artifact=$RUN_LOG" +else + test_result_record \ + "PASS" \ + "FastCV completed deinterleave data-integrity validation, success_markers=$success_count binary=$FASTCV_BINARY_PATH" +fi + +KERNEL_LOG_JOURNAL_FALLBACK=1 +export KERNEL_LOG_JOURNAL_FALLBACK +scan_dmesg_errors \ + "$RESULT_DIR/kernel" \ + "fastrpc|adsprpc|cdsprpc" \ + "not a crash|subsys-restart" +dmesg_rc=$? + +if [ "${DMESG_ACCESS_STATUS:-unknown}" != "available" ]; then + test_result_record \ + "SKIP" \ + "Kernel log access is unavailable for FastCV runtime health validation, status=${DMESG_ACCESS_STATUS:-unknown} provider=${DMESG_ACCESS_PROVIDER:-none} rc=${DMESG_ACCESS_RC:-unknown} artifact=${DMESG_ACCESS_LOG:-$RESULT_DIR/kernel/dmesg_access.log}" +elif [ "$dmesg_rc" -eq 0 ]; then + test_result_record \ + "FAIL" \ + "FastRPC-related kernel errors were found during FastCV validation, artifact=$RESULT_DIR/kernel/dmesg_errors.log" +else + test_result_record \ + "PASS" \ + "No persistent FastRPC kernel errors were found during FastCV validation" +fi + +test_result_finish From bcc9aa2b4f383dbd3b34b379061d74881266f200 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Thu, 24 Sep 2026 16:22:48 +0530 Subject: [PATCH 3/3] fastcv: accept profile-only functional output Some host-distribution fastcv_test builds emit function-level profiling PASS records and the final profile FIT result without the older module and plain FIT markers. Parse both supported dialects while requiring command success, positive function evidence, the profile summary, and no failure markers. Avoid RPM repository and network preparation when the complete FastCV package set is already installed, and document the resulting behavior. Signed-off-by: Srikanth Muppandam --- .../README.md | 31 +++++-- .../run.sh | 66 ++++++++------ Runner/utils/lib_fastcv.sh | 91 +++++++++++++++++++ 3 files changed, 151 insertions(+), 37 deletions(-) diff --git a/Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation/README.md b/Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation/README.md index 9f0f9fa5..1becbc73 100644 --- a/Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation/README.md +++ b/Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation/README.md @@ -72,7 +72,9 @@ configuration fails rather than being overwritten. Package preparation failure is reported as a suite failure. The RPM path also verifies that the `epel` repository is enabled after installing `epel-release`. Automatic repository creation is rejected on other CentOS or Red Hat major versions because the -configured repository URLs are specific to version 10. +configured repository URLs are specific to version 10. When the complete +FastCV package set is already installed, the suite skips repository setup and +package-manager network operations. These packages provide the FastCV runtime dependencies, but they do not provide the `fastcv_test` module runner or its matching test data. Sideload both fixture @@ -136,7 +138,9 @@ separate bounded invocation. ## Focused module coverage Use `--modules` with one module or a comma-separated module list. Each selected -module runs separately with `-m` and must report its exact module PASS marker. +module runs separately with `-m`. The runner accepts the two output dialects +observed from supported `fastcv_test` builds while retaining fail-closed +validation. ```sh ./run.sh \ @@ -147,7 +151,7 @@ module runs separately with `-m` and must report its exact module PASS marker. --modules COLORYUV,SCALE,ARITHM,BLUR,TRNS ``` -For example, the `SCALE` invocation must report all three markers: +The full output dialect reports all three summary markers: ```text FASTCV_TEST, SCALE=>PASS @@ -155,6 +159,18 @@ FIT:(FeatureName=>FASTCV, Overall=>PASS) FASTCV_PROFILE, FIT:(FeatureName=>FASTCV, Overall=>PASS) ``` +Some host-distribution builds emit only profiling records. For that dialect, +the runner requires at least one function-level profile PASS plus the final +profile FIT PASS: + +```text +FASTCV_PROFILE, fcvScaleDownBy2u8 :: PASS, ... +FASTCV_PROFILE, FIT:(FeatureName=>FASTCV, Overall=>PASS) +``` + +Both dialects also require exit status zero and no function, module, profile, +or FIT failure marker. A profile FIT summary by itself is not sufficient. + Module names are validated as alphanumeric identifiers with `_`, `+`, or `-` characters. The suite does not impose a static allowlist because the sideloaded binary and data revision own the available module set. @@ -273,10 +289,11 @@ matrices in an appropriate scheduled job and divide them across executions. ## Results -- **PASS**: every requested invocation exits zero, reports the required module - and overall FIT PASS markers, reports the profile FIT marker unless unit-only - mode was requested, verifies selected function or without-operation-mode - markers when applicable, and reports no official FAIL marker. +- **PASS**: every requested invocation exits zero and reports either the full + module/FIT marker set or function-level profiling PASS evidence with the + profile FIT summary. Unit-only mode requires the full non-profile marker set. + Selected function and without-operation-mode evidence is required when + applicable, and any official FAIL marker fails the invocation. - **FAIL**: the explicit fixture is incomplete or invalid, configuration is malformed, required host-distribution package recovery fails, execution fails or times out, a FAIL marker is present, or required PASS markers are diff --git a/Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation/run.sh b/Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation/run.sh index bce77a7c..824a22fc 100755 --- a/Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation/run.sh +++ b/Runner/suites/Multimedia/FastCV/FastCV_Module_Functional_Validation/run.sh @@ -384,8 +384,10 @@ run_fastcv_test_case() { -l "$FASTCV_TEST_LOOPS" if [ "$rftc_module" = "ALL" ]; then set -- "$@" -L "$FASTCV_TEST_LEVEL" + rftc_level_applied="$FASTCV_TEST_LEVEL" else set -- "$@" -m "$rftc_module" + rftc_level_applied="not-applied" fi if [ -n "$FASTCV_TEST_FUNCTION" ]; then @@ -442,7 +444,7 @@ run_fastcv_test_case() { return 1 fi - log_info "[FASTCV-CASE] phase=start target=$rftc_target target_name=$rftc_target_name module=$rftc_module loops=$FASTCV_TEST_LOOPS level=$FASTCV_TEST_LEVEL function=${FASTCV_TEST_FUNCTION:-all} operation_mode=${FASTCV_TEST_OPERATION_MODE:-default} operation_tables_only=$FASTCV_TEST_OPERATION_TABLES_ONLY seed=${FASTCV_TEST_SEED:-default} no_buffer_pool=$FASTCV_TEST_NO_BUFFER_POOL prealloc_bytes=${FASTCV_TEST_PREALLOC_BYTES:-none} opencv=$FASTCV_TEST_OPENCV unit_only=$FASTCV_TEST_UNIT_ONLY profile_only=$FASTCV_TEST_PROFILE_ONLY exhaustive=$FASTCV_TEST_EXHAUSTIVE resolution=${FASTCV_TEST_RESOLUTION:-default} qdsp_heap=$FASTCV_TEST_QDSP_HEAP element_alignment=$FASTCV_TEST_ELEMENT_ALIGNMENT cache_flush=$FASTCV_TEST_CACHE_FLUSH without_operation_mode=$FASTCV_TEST_WITHOUT_OPERATION_MODE argc=$rftc_argc timeout=${FASTCV_TEST_TIMEOUT}s" + log_info "[FASTCV-CASE] phase=start target=$rftc_target target_name=$rftc_target_name module=$rftc_module loops=$FASTCV_TEST_LOOPS level=$rftc_level_applied function=${FASTCV_TEST_FUNCTION:-all} operation_mode=${FASTCV_TEST_OPERATION_MODE:-default} operation_tables_only=$FASTCV_TEST_OPERATION_TABLES_ONLY seed=${FASTCV_TEST_SEED:-default} no_buffer_pool=$FASTCV_TEST_NO_BUFFER_POOL prealloc_bytes=${FASTCV_TEST_PREALLOC_BYTES:-none} opencv=$FASTCV_TEST_OPENCV unit_only=$FASTCV_TEST_UNIT_ONLY profile_only=$FASTCV_TEST_PROFILE_ONLY exhaustive=$FASTCV_TEST_EXHAUSTIVE resolution=${FASTCV_TEST_RESOLUTION:-default} qdsp_heap=$FASTCV_TEST_QDSP_HEAP element_alignment=$FASTCV_TEST_ELEMENT_ALIGNMENT cache_flush=$FASTCV_TEST_CACHE_FLUSH without_operation_mode=$FASTCV_TEST_WITHOUT_OPERATION_MODE argc=$rftc_argc timeout=${FASTCV_TEST_TIMEOUT}s" run_with_timeout_log \ "$FASTCV_TEST_TIMEOUT" \ "$rftc_log" \ @@ -450,38 +452,42 @@ run_fastcv_test_case() { rftc_rc=$? log_file_with_label "FASTCV-TEST-$rftc_target-$rftc_module" "$rftc_log" 120 - rftc_failure_count=$(grep -E -c 'FASTCV_TEST, .*=>FAIL|FIT:\(FeatureName=>FASTCV, Overall=>FAIL\)' "$rftc_log" 2>/dev/null || true) - rftc_fit_count=$(grep -E -c '^FIT:\(FeatureName=>FASTCV, Overall=>PASS\)[[:space:]]*$' "$rftc_log" 2>/dev/null || true) - rftc_profile_count=$(grep -E -c '^FASTCV_PROFILE, FIT:\(FeatureName=>FASTCV, Overall=>PASS\)[[:space:]]*$' "$rftc_log" 2>/dev/null || true) - if [ "$FASTCV_TEST_WITHOUT_OPERATION_MODE" -eq 1 ]; then - rftc_without_mode_count=$(grep -F -c \ - 'Running fastCV API without calling setOperationMode is pass' \ - "$rftc_log" 2>/dev/null || true) - else - rftc_without_mode_count=0 - fi - if [ -n "$FASTCV_TEST_FUNCTION" ]; then - rftc_function_count=$(grep -F -c "Function chosen: $FASTCV_TEST_FUNCTION" "$rftc_log" 2>/dev/null || true) - else - rftc_function_count=0 - fi - if [ "$rftc_module" = "ALL" ]; then - rftc_module_count=$(grep -E -c '^FASTCV_TEST, [^=]+=>PASS[[:space:]]*$' "$rftc_log" 2>/dev/null || true) - else - rftc_module_count=$(grep -F -c "FASTCV_TEST, $rftc_module=>PASS" "$rftc_log" 2>/dev/null || true) + if ! fastcv_collect_test_markers \ + "$rftc_log" \ + "$rftc_module" \ + "$FASTCV_TEST_FUNCTION" \ + "$FASTCV_TEST_WITHOUT_OPERATION_MODE"; then + test_result_record \ + "FAIL" \ + "Could not parse fastcv_test evidence, target=$rftc_target module=$rftc_module artifact=$rftc_log" + return 1 fi + rftc_failure_count="$FASTCV_MARKER_FAILURE_COUNT" + rftc_fit_count="$FASTCV_MARKER_FIT_COUNT" + rftc_profile_count="$FASTCV_MARKER_PROFILE_SUMMARY_COUNT" + rftc_profile_case_count="$FASTCV_MARKER_PROFILE_CASE_PASS_COUNT" + rftc_module_count="$FASTCV_MARKER_MODULE_COUNT" + rftc_function_count="$FASTCV_MARKER_FUNCTION_COUNT" + rftc_without_mode_count="$FASTCV_MARKER_WITHOUT_MODE_COUNT" rftc_output_bytes=$(wc -c <"$rftc_log" 2>/dev/null | tr -d '[:space:]') rftc_profile_required=1 if [ "$FASTCV_TEST_UNIT_ONLY" -eq 1 ]; then rftc_profile_required=0 fi - rftc_marker_missing=0 - if [ "$rftc_module_count" -eq 0 ] || [ "$rftc_fit_count" -eq 0 ]; then - rftc_marker_missing=1 - fi - if [ "$rftc_profile_required" -eq 1 ] && [ "$rftc_profile_count" -eq 0 ]; then - rftc_marker_missing=1 + rftc_marker_dialect="none" + rftc_marker_missing=1 + if [ "$rftc_module_count" -gt 0 ] && + [ "$rftc_fit_count" -gt 0 ] && + { [ "$rftc_profile_required" -eq 0 ] || + [ "$rftc_profile_count" -gt 0 ]; }; then + rftc_marker_dialect="test-and-profile" + rftc_marker_missing=0 + elif [ "$rftc_profile_required" -eq 1 ] && + [ "$rftc_profile_case_count" -gt 0 ] && + [ "$rftc_profile_count" -gt 0 ]; then + rftc_marker_dialect="profile-only" + rftc_marker_missing=0 fi if [ -n "$FASTCV_TEST_FUNCTION" ] && [ "$rftc_function_count" -eq 0 ]; then rftc_marker_missing=1 @@ -491,7 +497,7 @@ run_fastcv_test_case() { rftc_marker_missing=1 fi - log_info "[FASTCV-CASE] phase=complete target=$rftc_target target_name=$rftc_target_name module=$rftc_module rc=$rftc_rc module_pass_markers=$rftc_module_count fit_pass_markers=$rftc_fit_count profile_pass_markers=$rftc_profile_count profile_required=$rftc_profile_required function_markers=$rftc_function_count without_operation_mode_markers=$rftc_without_mode_count failure_markers=$rftc_failure_count output_bytes=${rftc_output_bytes:-0} artifact=$rftc_log" + log_info "[FASTCV-CASE] phase=complete target=$rftc_target target_name=$rftc_target_name module=$rftc_module rc=$rftc_rc marker_dialect=$rftc_marker_dialect module_pass_markers=$rftc_module_count fit_pass_markers=$rftc_fit_count profile_case_pass_markers=$rftc_profile_case_count profile_pass_markers=$rftc_profile_count profile_required=$rftc_profile_required function_markers=$rftc_function_count without_operation_mode_markers=$rftc_without_mode_count failure_markers=$rftc_failure_count output_bytes=${rftc_output_bytes:-0} artifact=$rftc_log" if [ "$rftc_rc" -ne 0 ]; then test_result_record \ @@ -508,13 +514,13 @@ run_fastcv_test_case() { if [ "$rftc_marker_missing" -eq 1 ]; then test_result_record \ "FAIL" \ - "fastcv_test omitted required PASS evidence, target=$rftc_target module=$rftc_module module_markers=$rftc_module_count fit_markers=$rftc_fit_count profile_markers=$rftc_profile_count profile_required=$rftc_profile_required function_markers=$rftc_function_count without_operation_mode_markers=$rftc_without_mode_count artifact=$rftc_log" + "fastcv_test omitted required PASS evidence, target=$rftc_target module=$rftc_module marker_dialect=$rftc_marker_dialect module_markers=$rftc_module_count fit_markers=$rftc_fit_count profile_case_markers=$rftc_profile_case_count profile_markers=$rftc_profile_count profile_required=$rftc_profile_required function_markers=$rftc_function_count without_operation_mode_markers=$rftc_without_mode_count artifact=$rftc_log" return 1 fi test_result_record \ "PASS" \ - "fastcv_test completed functional module validation, target=$rftc_target target_name=$rftc_target_name module=$rftc_module module_pass_markers=$rftc_module_count artifact=$rftc_log" + "fastcv_test completed functional module validation, target=$rftc_target target_name=$rftc_target_name module=$rftc_module marker_dialect=$rftc_marker_dialect module_pass_markers=$rftc_module_count profile_case_pass_markers=$rftc_profile_case_count artifact=$rftc_log" return 0 } @@ -759,7 +765,7 @@ fi } >"$BINARY_REPORT" log_info "[FASTCV-FIXTURE] binary=$FASTCV_TEST_BINARY executable=1 data_dir=$FASTCV_TEST_DATA_DIR control_table=$CONTROL_TABLE control_table_readable=1 data_files=$data_file_count binary_artifact=$BINARY_REPORT data_artifact=$DATA_REPORT" log_file_with_label "FASTCV-BINARY" "$BINARY_REPORT" 10 -log_file_with_label "FASTCV-DATA" "$DATA_REPORT" 40 +log_file_with_label "FASTCV-DATA" "$DATA_REPORT" 12 if ! prepare_target_list "$FASTCV_TEST_TARGETS" "$TARGET_LIST"; then test_result_record \ diff --git a/Runner/utils/lib_fastcv.sh b/Runner/utils/lib_fastcv.sh index befbd7d7..4b0375d2 100755 --- a/Runner/utils/lib_fastcv.sh +++ b/Runner/utils/lib_fastcv.sh @@ -2,6 +2,91 @@ # Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. # SPDX-License-Identifier: BSD-3-Clause +# fastcv_collect_test_markers LOG_FILE MODULE FUNCTION WITHOUT_OPERATION_MODE +# Classify success and failure markers emitted by supported fastcv_test builds. +# Inputs: a readable command log, the selected module, an optional function, +# and a 0/1 without-operation-mode flag. Output: no stdout. +# Returns: 0 after parsing or 1 when the log is unreadable. +# Side effects: updates FASTCV_MARKER_FAILURE_COUNT, FASTCV_MARKER_FIT_COUNT, +# FASTCV_MARKER_PROFILE_SUMMARY_COUNT, FASTCV_MARKER_PROFILE_CASE_PASS_COUNT, +# FASTCV_MARKER_MODULE_COUNT, FASTCV_MARKER_FUNCTION_COUNT, and +# FASTCV_MARKER_WITHOUT_MODE_COUNT for the caller. +fastcv_collect_test_markers() { + fcctm_log="$1" + fcctm_module="$2" + fcctm_function="$3" + fcctm_without_mode="$4" + + FASTCV_MARKER_FAILURE_COUNT=0 + FASTCV_MARKER_FIT_COUNT=0 + FASTCV_MARKER_PROFILE_SUMMARY_COUNT=0 + FASTCV_MARKER_PROFILE_CASE_PASS_COUNT=0 + FASTCV_MARKER_MODULE_COUNT=0 + FASTCV_MARKER_FUNCTION_COUNT=0 + FASTCV_MARKER_WITHOUT_MODE_COUNT=0 + fcctm_profile_function_count=0 + + [ -r "$fcctm_log" ] || return 1 + + # Exported result state for suite callers. + # shellcheck disable=SC2034 + FASTCV_MARKER_FAILURE_COUNT=$(grep -E -c \ + '(^FASTCV_TEST, .*=>FAIL[[:space:]]*$)|(^FASTCV_PROFILE, .* :: FAIL([,[:space:]]|$))|(^((FASTCV_PROFILE, )?FIT:\(FeatureName=>FASTCV, Overall=>FAIL\))[[:space:]]*$)' \ + "$fcctm_log" 2>/dev/null || true) + # Exported result state for suite callers. + # shellcheck disable=SC2034 + FASTCV_MARKER_FIT_COUNT=$(grep -E -c \ + '^FIT:\(FeatureName=>FASTCV, Overall=>PASS\)[[:space:]]*$' \ + "$fcctm_log" 2>/dev/null || true) + # Exported result state for suite callers. + # shellcheck disable=SC2034 + FASTCV_MARKER_PROFILE_SUMMARY_COUNT=$(grep -E -c \ + '^FASTCV_PROFILE, FIT:\(FeatureName=>FASTCV, Overall=>PASS\)[[:space:]]*$' \ + "$fcctm_log" 2>/dev/null || true) + # Exported result state for suite callers. + # shellcheck disable=SC2034 + FASTCV_MARKER_PROFILE_CASE_PASS_COUNT=$(grep -E -c \ + '^FASTCV_PROFILE, .+ :: PASS(,|[[:space:]]*$)' \ + "$fcctm_log" 2>/dev/null || true) + + if [ "$fcctm_module" = "ALL" ]; then + # Exported result state for suite callers. + # shellcheck disable=SC2034 + FASTCV_MARKER_MODULE_COUNT=$(grep -E -c \ + '^FASTCV_TEST, [^=]+=>PASS[[:space:]]*$' \ + "$fcctm_log" 2>/dev/null || true) + else + # Exported result state for suite callers. + # shellcheck disable=SC2034 + FASTCV_MARKER_MODULE_COUNT=$(grep -F -c \ + "FASTCV_TEST, $fcctm_module=>PASS" \ + "$fcctm_log" 2>/dev/null || true) + fi + + if [ -n "$fcctm_function" ]; then + FASTCV_MARKER_FUNCTION_COUNT=$(grep -E -c \ + "^Function chosen: ${fcctm_function}[[:space:]]*$" \ + "$fcctm_log" 2>/dev/null || true) + fcctm_profile_function_count=$(grep -E -c \ + "^FASTCV_PROFILE, $fcctm_function :: PASS(,|[[:space:]]*$)" \ + "$fcctm_log" 2>/dev/null || true) + FASTCV_MARKER_FUNCTION_COUNT=$(( + FASTCV_MARKER_FUNCTION_COUNT + + fcctm_profile_function_count + )) + fi + + if [ "$fcctm_without_mode" -eq 1 ]; then + # Exported result state for suite callers. + # shellcheck disable=SC2034 + FASTCV_MARKER_WITHOUT_MODE_COUNT=$(grep -F -c \ + 'Running fastCV API without calling setOperationMode is pass' \ + "$fcctm_log" 2>/dev/null || true) + fi + + return 0 +} + # fastcv_prepare_runtime_packages # Ensure the FastCV runtime package set on supported host distributions. # Inputs: none. Output: no machine-readable stdout contract. @@ -18,6 +103,7 @@ fastcv_prepare_runtime_packages() { pkg_provider_init \ pkg_ensure_host_distro_package_set_present \ pkg_ensure_required_package_set_present \ + pkg_verify_package_set_installed \ pkg_package_recovery_supported_os; do if ! command -v "$fcprp_helper" >/dev/null 2>&1; then log_error "FastCV package preparation helper is unavailable: $fcprp_helper" @@ -35,6 +121,11 @@ fastcv_prepare_runtime_packages() { return 1 fi + if pkg_verify_package_set_installed fastcv-runtime; then + log_info "[FASTCV-PACKAGES] action=already-ready os=$fcprp_os_id set=fastcv-runtime upgrades=disabled" + return 0 + fi + fcprp_previous_set_upgrade="$PKG_PACKAGE_SET_UPGRADE" PKG_PACKAGE_SET_UPGRADE=0 fcprp_rc=0