diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/Camera_NHX_Preview.yaml b/Runner/suites/Multimedia/Camera/Camera_NHX/Camera_NHX_Preview.yaml index acdb1cb1..179ea81e 100755 --- a/Runner/suites/Multimedia/Camera/Camera_NHX/Camera_NHX_Preview.yaml +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/Camera_NHX_Preview.yaml @@ -1,15 +1,19 @@ metadata: name: camera_nhx format: "Lava-Test Test Definition 1.0" - description: "Camera NHX preview validation" + description: "Camera NHX validation with selectable CAMX/NHX JSON config" os: - yocto scope: - functional +params: + NHX_JSON: "" + NHX_TARGET: "" + run: steps: - REPO_PATH=$PWD - cd Runner/suites/Multimedia/Camera/Camera_NHX - - ./run.sh || true + - ./run.sh --json "${NHX_JSON}" --target "${NHX_TARGET}" || true - $REPO_PATH/Runner/utils/send-to-lava.sh Camera_NHX.res diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/Kodiak/Prev_plus_Video_YUVNV12_MaxResolution_NHX.json b/Runner/suites/Multimedia/Camera/Camera_NHX/Kodiak/Prev_plus_Video_YUVNV12_MaxResolution_NHX.json new file mode 100755 index 00000000..17acd6d1 --- /dev/null +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/Kodiak/Prev_plus_Video_YUVNV12_MaxResolution_NHX.json @@ -0,0 +1,37 @@ +{ + "NativeHalX.OmniTest": { + "frames": 150, + "camera": 0, + "formats": [ + 35, + 34 + ], + "resolutions": [ + "max", + "max" + ], + "usage_flags": [ + 2304, + 65536 + ], + "data_spaces": [ + 65536, + 260 + ], + "directions": [ + "OUTPUT", + "OUTPUT" + ], + "stream_intervals": [ + 150, + 150 + ], + "num_streams": 2, + "request_types": [ + 1, + 3 + ], + "session_mode": 0, + "all_image_dump": true + } +} \ No newline at end of file diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/Kodiak/Preview_YUVNV12_MaxResolution_NHX.json b/Runner/suites/Multimedia/Camera/Camera_NHX/Kodiak/Preview_YUVNV12_MaxResolution_NHX.json new file mode 100755 index 00000000..ef47db31 --- /dev/null +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/Kodiak/Preview_YUVNV12_MaxResolution_NHX.json @@ -0,0 +1,30 @@ +{ + "NativeHalX.OmniTest": { + "frames" : 150, + "camera" : 0, + "formats": [ + 35 + ], + "resolutions": [ + "max" + ], + "usage_flags": [ + 2304 + ], + "data_spaces": [ + 65536 + ], + "directions": [ + "OUTPUT" + ], + "stream_intervals": [ + 150 + ], + "num_streams" : 1, + "request_types": [ + 1 + ], + "session_mode": 0, + "all_image_dump": true + } +} \ No newline at end of file diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/Kodiak/Snapshot_YUVNV12_MaxResolution_NHX.json b/Runner/suites/Multimedia/Camera/Camera_NHX/Kodiak/Snapshot_YUVNV12_MaxResolution_NHX.json new file mode 100755 index 00000000..d401d2b2 --- /dev/null +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/Kodiak/Snapshot_YUVNV12_MaxResolution_NHX.json @@ -0,0 +1,37 @@ +{ + "NativeHalX.OmniTest": { + "frames": 150, + "camera": 0, + "formats": [ + 35, + 33 + ], + "resolutions": [ + "max", + "max" + ], + "usage_flags": [ + 2304, + 3 + ], + "data_spaces": [ + 65536, + 146931712 + ], + "directions": [ + "OUTPUT", + "OUTPUT" + ], + "stream_intervals": [ + 150, + 5 + ], + "num_streams": 2, + "request_types": [ + 1, + 2 + ], + "session_mode": 0, + "all_image_dump": true + } +} \ No newline at end of file diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/Kodiak/Video_YUVNV12_MaxResolution_NHX.json b/Runner/suites/Multimedia/Camera/Camera_NHX/Kodiak/Video_YUVNV12_MaxResolution_NHX.json new file mode 100755 index 00000000..d831d46a --- /dev/null +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/Kodiak/Video_YUVNV12_MaxResolution_NHX.json @@ -0,0 +1,30 @@ +{ + "NativeHalX.OmniTest": { + "frames": 150, + "camera": 0, + "formats": [ + 34 + ], + "resolutions": [ + "max" + ], + "usage_flags": [ + 65536 + ], + "data_spaces": [ + 260 + ], + "directions": [ + "OUTPUT" + ], + "stream_intervals": [ + 150 + ], + "num_streams": 1, + "request_types": [ + 3 + ], + "session_mode": 0, + "all_image_dump": true + } +} \ No newline at end of file diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/Lemans/Prev_plus_Video_YUVNV12_MaxResolution_NHX.json b/Runner/suites/Multimedia/Camera/Camera_NHX/Lemans/Prev_plus_Video_YUVNV12_MaxResolution_NHX.json new file mode 100755 index 00000000..17acd6d1 --- /dev/null +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/Lemans/Prev_plus_Video_YUVNV12_MaxResolution_NHX.json @@ -0,0 +1,37 @@ +{ + "NativeHalX.OmniTest": { + "frames": 150, + "camera": 0, + "formats": [ + 35, + 34 + ], + "resolutions": [ + "max", + "max" + ], + "usage_flags": [ + 2304, + 65536 + ], + "data_spaces": [ + 65536, + 260 + ], + "directions": [ + "OUTPUT", + "OUTPUT" + ], + "stream_intervals": [ + 150, + 150 + ], + "num_streams": 2, + "request_types": [ + 1, + 3 + ], + "session_mode": 0, + "all_image_dump": true + } +} \ No newline at end of file diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/Lemans/Preview_YUVNV12_MaxResolution_NHX.json b/Runner/suites/Multimedia/Camera/Camera_NHX/Lemans/Preview_YUVNV12_MaxResolution_NHX.json new file mode 100755 index 00000000..ef47db31 --- /dev/null +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/Lemans/Preview_YUVNV12_MaxResolution_NHX.json @@ -0,0 +1,30 @@ +{ + "NativeHalX.OmniTest": { + "frames" : 150, + "camera" : 0, + "formats": [ + 35 + ], + "resolutions": [ + "max" + ], + "usage_flags": [ + 2304 + ], + "data_spaces": [ + 65536 + ], + "directions": [ + "OUTPUT" + ], + "stream_intervals": [ + 150 + ], + "num_streams" : 1, + "request_types": [ + 1 + ], + "session_mode": 0, + "all_image_dump": true + } +} \ No newline at end of file diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/Lemans/Video_YUVNV12_MaxResolution_NHX.json b/Runner/suites/Multimedia/Camera/Camera_NHX/Lemans/Video_YUVNV12_MaxResolution_NHX.json new file mode 100755 index 00000000..d831d46a --- /dev/null +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/Lemans/Video_YUVNV12_MaxResolution_NHX.json @@ -0,0 +1,30 @@ +{ + "NativeHalX.OmniTest": { + "frames": 150, + "camera": 0, + "formats": [ + 34 + ], + "resolutions": [ + "max" + ], + "usage_flags": [ + 65536 + ], + "data_spaces": [ + 260 + ], + "directions": [ + "OUTPUT" + ], + "stream_intervals": [ + 150 + ], + "num_streams": 1, + "request_types": [ + 3 + ], + "session_mode": 0, + "all_image_dump": true + } +} \ No newline at end of file diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/Monaco/Prev_plus_Video_YUVNV12_MaxResolution_NHX.json b/Runner/suites/Multimedia/Camera/Camera_NHX/Monaco/Prev_plus_Video_YUVNV12_MaxResolution_NHX.json new file mode 100755 index 00000000..17acd6d1 --- /dev/null +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/Monaco/Prev_plus_Video_YUVNV12_MaxResolution_NHX.json @@ -0,0 +1,37 @@ +{ + "NativeHalX.OmniTest": { + "frames": 150, + "camera": 0, + "formats": [ + 35, + 34 + ], + "resolutions": [ + "max", + "max" + ], + "usage_flags": [ + 2304, + 65536 + ], + "data_spaces": [ + 65536, + 260 + ], + "directions": [ + "OUTPUT", + "OUTPUT" + ], + "stream_intervals": [ + 150, + 150 + ], + "num_streams": 2, + "request_types": [ + 1, + 3 + ], + "session_mode": 0, + "all_image_dump": true + } +} \ No newline at end of file diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/Monaco/Preview_YUVNV12_MaxResolution_NHX.json b/Runner/suites/Multimedia/Camera/Camera_NHX/Monaco/Preview_YUVNV12_MaxResolution_NHX.json new file mode 100755 index 00000000..ef47db31 --- /dev/null +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/Monaco/Preview_YUVNV12_MaxResolution_NHX.json @@ -0,0 +1,30 @@ +{ + "NativeHalX.OmniTest": { + "frames" : 150, + "camera" : 0, + "formats": [ + 35 + ], + "resolutions": [ + "max" + ], + "usage_flags": [ + 2304 + ], + "data_spaces": [ + 65536 + ], + "directions": [ + "OUTPUT" + ], + "stream_intervals": [ + 150 + ], + "num_streams" : 1, + "request_types": [ + 1 + ], + "session_mode": 0, + "all_image_dump": true + } +} \ No newline at end of file diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/Monaco/Video_YUVNV12_MaxResolution_NHX.json b/Runner/suites/Multimedia/Camera/Camera_NHX/Monaco/Video_YUVNV12_MaxResolution_NHX.json new file mode 100755 index 00000000..d831d46a --- /dev/null +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/Monaco/Video_YUVNV12_MaxResolution_NHX.json @@ -0,0 +1,30 @@ +{ + "NativeHalX.OmniTest": { + "frames": 150, + "camera": 0, + "formats": [ + 34 + ], + "resolutions": [ + "max" + ], + "usage_flags": [ + 65536 + ], + "data_spaces": [ + 260 + ], + "directions": [ + "OUTPUT" + ], + "stream_intervals": [ + 150 + ], + "num_streams": 1, + "request_types": [ + 3 + ], + "session_mode": 0, + "all_image_dump": true + } +} \ No newline at end of file diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/README_Camera_NHX.md b/Runner/suites/Multimedia/Camera/Camera_NHX/README_Camera_NHX.md index 7f6b3d3a..2539b841 100644 --- a/Runner/suites/Multimedia/Camera/Camera_NHX/README_Camera_NHX.md +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/README_Camera_NHX.md @@ -1,6 +1,8 @@ # 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. +Camera NHX validation test for the Qualcomm CAMX proprietary camera stack. This test runs `nhx.sh`, collects generated image dumps, validates dumps (existence + non-zero size), and produces a PASS/FAIL `.res` file suitable for LAVA gating. + +The test supports the legacy/default NHX flow and optional target-specific JSON selection for preview, video, preview+video, and snapshot validation. --- @@ -10,6 +12,44 @@ Camera NHX validation test for Qualcomm CAMX proprietary camera stack. This test - Utilities: - `Runner/utils/functestlib.sh` - `Runner/utils/camera/lib_camera.sh` +- Target-specific NHX JSON configs: + - `Runner/suites/Multimedia/Camera/Camera_NHX/Kodiak/*.json` + - `Runner/suites/Multimedia/Camera/Camera_NHX/Lemans/*.json` + - `Runner/suites/Multimedia/Camera/Camera_NHX/Monaco/*.json` + - `Runner/suites/Multimedia/Camera/Camera_NHX/Talos/*.json` + +--- + +## Target JSON layout + +The test expects target-specific JSON files to be stored under the same directory as `run.sh`: + +```text +Camera_NHX/ + run.sh + README_Camera_NHX.md + Camera_NHX_Preview.yaml + Kodiak/ + Preview_YUVNV12_MaxResolution_NHX.json + Video_YUVNV12_MaxResolution_NHX.json + Prev_plus_Video_YUVNV12_MaxResolution_NHX.json + Snapshot_YUVNV12_MaxResolution_NHX.json + Lemans/ + Preview_YUVNV12_MaxResolution_NHX.json + Video_YUVNV12_MaxResolution_NHX.json + Prev_plus_Video_YUVNV12_MaxResolution_NHX.json + Monaco/ + Preview_YUVNV12_MaxResolution_NHX.json + Video_YUVNV12_MaxResolution_NHX.json + Prev_plus_Video_YUVNV12_MaxResolution_NHX.json + Talos/ + Preview_YUVNV12_MaxResolution_NHX.json + Video_YUVNV12_MaxResolution_NHX.json + Prev_plus_Video_YUVNV12_MaxResolution_NHX.json + Snapshot_YUVNV12_MaxResolution_NHX.json +``` + +Snapshot JSON files are currently expected only for targets where the files are present, such as `Kodiak` and `Talos`. Do not schedule snapshot for `Lemans` or `Monaco` unless the corresponding JSON files are added. --- @@ -22,37 +62,211 @@ Camera NHX validation test for Qualcomm CAMX proprietary camera stack. This test 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 +3. **CAMX proprietary prechecks** + - Device-tree presence checks for CAMX/camera patterns, including downstream CAMX-style nodes such as: + - `qcom,cam-sensor` + - `qcom,cam-gmsl-sensor` + - `qcom,cam-gmsl-deserializer` + - `qcom,eeprom` + - `qcom,cci` + - `qcom,csiphy` + - `qcom,cam-tpg1031` + - `qcom,camera` + - `fdtdump` scan for camera-related nodes through `lib_camera.sh` + - Camera kernel module detection and loaded-state validation + - ICP firmware presence check (`CAMERA_ICP`) + - `dmesg` scan for camera warnings/errors + - CAMX package presence check + - Sensor presence check is warn-only because NHX may still work depending on target/test config 4. **Runs NHX** - - Executes `nhx.sh` and captures all output to a timestamped log. + - Default mode runs `nhx.sh` with no argument, preserving the existing SoC-specific default behavior. + - Optional mode accepts one selected JSON via `--json` and optionally `--target`. + - The selected JSON is staged to the location expected by `/usr/bin/nhx.sh`. 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. + - Each dump file size is greater than `0` bytes + - Optionally generates checksums (`sha256sum`, `md5sum`, or `cksum`) and writes checksum files. 6. **Result decision** - - Parses `Final Report -> [X PASSED] [Y FAILED] [Z SKIPPED]` from the NHX log + - 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 + - Final Report is missing or unparseable + - NHX reports `FAILED > 0` + - No dumps are detected + - Any dump is missing or zero bytes - Dump checksum validation helper fails - Writes final result to: `Camera_NHX.res` --- +## NHX JSON selection + +### Default behavior + +```sh +./run.sh +``` + +This preserves the existing behavior and runs: + +```sh +nhx.sh +``` + +`nhx.sh` then selects the default JSON based on SoC ID: + +- Kodiak (`497`, `498`, `575`) -> `NHX.YUV_NV12_Prev_MaxRes` +- Lemans/Monaco (`534`, `606`, `667`, `674`, `675`, `676`) -> `NHX.YUV_NV12_Prev_MaxRes` +- Talos (`680`) -> `NHX.YUV_NV12_Prev_1920x1440` + +### Run one selected JSON + +Use `--json` to run exactly one selected JSON config: + +```sh +./run.sh --json Lemans/Prev_plus_Video_YUVNV12_MaxResolution_NHX.json +``` + +```sh +./run.sh --json Kodiak/Snapshot_YUVNV12_MaxResolution_NHX.json +``` + +```sh +./run.sh --json Talos/Video_YUVNV12_MaxResolution_NHX.json +``` + +### Run by filename with target + +When passing only a filename, use `--target` so the resolver can select the correct target folder: + +```sh +./run.sh --json Snapshot_YUVNV12_MaxResolution_NHX.json --target Kodiak +``` + +```sh +./run.sh --json Video_YUVNV12_MaxResolution_NHX.json --target Monaco +``` + +Supported target names: + +```text +Kodiak +Lemans +Monaco +Talos +``` + +### Environment variable style + +The same selection can be done through environment variables: + +```sh +NHX_JSON=Talos/Video_YUVNV12_MaxResolution_NHX.json ./run.sh +``` + +```sh +NHX_JSON=Snapshot_YUVNV12_MaxResolution_NHX.json NHX_TARGET=Talos ./run.sh +``` + +### Ambiguous filename handling + +Many JSON filenames exist under multiple target folders. For example: + +```sh +./run.sh --json Preview_YUVNV12_MaxResolution_NHX.json +``` + +is ambiguous because the same file can exist under `Kodiak`, `Lemans`, `Monaco`, and `Talos`. + +In that case, pass `--target`: + +```sh +./run.sh --json Preview_YUVNV12_MaxResolution_NHX.json --target Lemans +``` + +--- + +## How JSON staging works + +`/usr/bin/nhx.sh` does not accept an arbitrary absolute JSON path. It expects a JSON name and internally checks: + +```sh +/etc/camera/test/NHX/${JSON_FILE}.json +``` + +For this reason, when `--json` is used, `run.sh` resolves the source file from the test directory and stages it under: + +```text +/etc/camera/test/NHX//.json +``` + +Then it calls `nhx.sh` with the launcher argument without `.json`, for example: + +```sh +nhx.sh Lemans/Prev_plus_Video_YUVNV12_MaxResolution_NHX +``` + +This causes `nhx.sh` to load: + +```text +/etc/camera/test/NHX/Lemans/Prev_plus_Video_YUVNV12_MaxResolution_NHX.json +``` + +The run log and summary include: + +```text +NHX JSON requested +NHX target requested +NHX JSON resolved +NHX JSON argument +``` + +--- + +## Command usage + +```sh +./run.sh [--json JSON_FILE] [--target TARGET] [--help] +``` + +Options: + +```text +--json JSON_FILE NHX JSON file to pass to nhx.sh. + Can be absolute, relative to Camera_NHX/, or relative + to the target folder when --target is provided. + +--target TARGET Target folder name: Kodiak, Lemans, Monaco, Talos. + Used to resolve/stage --json under /etc/camera/test/NHX. + +--help Show usage. +``` + +Examples: + +```sh +./run.sh +``` + +```sh +./run.sh --json Lemans/Prev_plus_Video_YUVNV12_MaxResolution_NHX.json +``` + +```sh +./run.sh --json Snapshot_YUVNV12_MaxResolution_NHX.json --target Kodiak +``` + +```sh +NHX_JSON=Talos/Video_YUVNV12_MaxResolution_NHX.json ./run.sh +``` + +--- + ## Outputs Created under the test directory: @@ -60,12 +274,12 @@ Created under the test directory: - Logs: - `logs/Camera_NHX_.log` - `logs/dmesg_/dmesg_snapshot.log` - - `logs/dmesg_/dmesg_errors.log` (if any matches) + - `logs/dmesg_/dmesg_errors.log` when matches exist - 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) + - Dump list file, usually under `out/nhx_/` + - Checksum file(s), when checksum tool/helper is available - LAVA gating result: - `Camera_NHX.res` @@ -74,11 +288,13 @@ Created under the test directory: ## Dump directory -By default the test expects NHX dumps under: +By default, the test expects NHX dumps under: -- `/var/cache/camera/nativehaltest` +```text +/var/cache/camera/nativehaltest +``` -(Referenced in `run.sh` as `DUMP_DIR`.) +This is referenced in `run.sh` as `DUMP_DIR`. --- @@ -92,19 +308,26 @@ cd Runner/suites/Multimedia/Camera/Camera_NHX cat Camera_NHX.res ``` +Run a selected NHX config: + +```sh +./run.sh --json Lemans/Preview_YUVNV12_MaxResolution_NHX.json +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: +Default NHX preview flow: ```yaml metadata: - name: camera_nhx + name: camera_nhx_preview format: "Lava-Test Test Definition 1.0" - description: "Camera NHX validation" + description: "Camera NHX default validation" os: - linux scope: @@ -118,43 +341,130 @@ run: - $REPO_PATH/Runner/utils/send-to-lava.sh Camera_NHX.res ``` +Selected NHX config flow: + +```yaml +metadata: + name: camera_nhx_selected_config + format: "Lava-Test Test Definition 1.0" + description: "Camera NHX selected JSON validation" + os: + - linux + scope: + - functional + +params: + NHX_JSON: "Lemans/Prev_plus_Video_YUVNV12_MaxResolution_NHX.json" + +run: + steps: + - REPO_PATH=$PWD + - cd Runner/suites/Multimedia/Camera/Camera_NHX + - ./run.sh --json "${NHX_JSON}" || true + - $REPO_PATH/Runner/utils/send-to-lava.sh Camera_NHX.res +``` + +Selected filename plus target: + +```yaml +params: + NHX_JSON: "Snapshot_YUVNV12_MaxResolution_NHX.json" + NHX_TARGET: "Kodiak" + +run: + steps: + - REPO_PATH=$PWD + - cd Runner/suites/Multimedia/Camera/Camera_NHX + - ./run.sh --json "${NHX_JSON}" --target "${NHX_TARGET}" || 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) +### 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, when used + +### FAIL + +- Any PASS condition is not met +- NHX reports one or more failed cases +- Final Report is missing/unparseable +- No dumps are detected +- Any dump is missing or zero bytes +- Dump checksum validation helper fails -- **FAIL** - - Any PASS condition not met (including missing/zero dumps) +### SKIP -- **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) +- Missing CAMX prerequisites, such as DT patterns, camera module artifact/loaded state, ICP firmware, CAMX packages, or `nhx.sh` +- `fdtdump` is not available or camera node evidence is inconclusive +- Requested `--json` file is not found +- Requested JSON filename is ambiguous and `--target` was not supplied +- JSON staging under `/etc/camera/test/NHX` fails --- -## Notes / Troubleshooting +## Notes and 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. +If logs show `1970-01-01`, the device clock is not set. This is common on early boot images or minimal init environments. It does not affect functional correctness, but it can make log browsing confusing. + +### `nhx.sh` reports JSON file not found + +If you see a message similar to: + +```text +Warning: JSON file not found: /etc/camera/test/NHX/.json +``` + +check that: + +- `run.sh` logged a valid `NHX JSON resolved` +- `run.sh` logged a valid `NHX JSON argument` +- the selected JSON was staged under `/etc/camera/test/NHX` +- the argument passed to `nhx.sh` does not include an absolute `/tmp/...` path +- the argument passed to `nhx.sh` does not include the `.json` suffix + +Correct expected example: + +```text +NHX JSON argument: Lemans/Prev_plus_Video_YUVNV12_MaxResolution_NHX +``` + +### Camera_NHX SKIPs due to DT mismatch + +The test checks CAMX-related DT patterns. For downstream CAMX overlays, useful matches include: + +```text +qcom,cam-sensor +qcom,cam-gmsl-sensor +qcom,cam-gmsl-deserializer +qcom,eeprom +qcom,cci +qcom,csiphy +qcom,cam-tpg1031 +qcom,camera +``` + +If the test still SKIPs, inspect the saved logs and confirm the active DT overlay exposes camera/CAMX nodes. ### 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 `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. +The script scans dmesg and reports warnings, but does not fail only because camera warnings exist. Use the saved snapshot/errors logs to debug. -### CAMX bind graph not observed (SKIP) +### CAMX bind graph not observed -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. +If CAMX bind graph markers are not seen, the script logs a warning. This usually indicates CAMX stack did not fully initialize or relevant drivers/services did not come up. diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/Talos/Prev_plus_Video_YUVNV12_MaxResolution_NHX.json b/Runner/suites/Multimedia/Camera/Camera_NHX/Talos/Prev_plus_Video_YUVNV12_MaxResolution_NHX.json new file mode 100755 index 00000000..17acd6d1 --- /dev/null +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/Talos/Prev_plus_Video_YUVNV12_MaxResolution_NHX.json @@ -0,0 +1,37 @@ +{ + "NativeHalX.OmniTest": { + "frames": 150, + "camera": 0, + "formats": [ + 35, + 34 + ], + "resolutions": [ + "max", + "max" + ], + "usage_flags": [ + 2304, + 65536 + ], + "data_spaces": [ + 65536, + 260 + ], + "directions": [ + "OUTPUT", + "OUTPUT" + ], + "stream_intervals": [ + 150, + 150 + ], + "num_streams": 2, + "request_types": [ + 1, + 3 + ], + "session_mode": 0, + "all_image_dump": true + } +} \ No newline at end of file diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/Talos/Preview_YUVNV12_MaxResolution_NHX.json b/Runner/suites/Multimedia/Camera/Camera_NHX/Talos/Preview_YUVNV12_MaxResolution_NHX.json new file mode 100755 index 00000000..ef47db31 --- /dev/null +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/Talos/Preview_YUVNV12_MaxResolution_NHX.json @@ -0,0 +1,30 @@ +{ + "NativeHalX.OmniTest": { + "frames" : 150, + "camera" : 0, + "formats": [ + 35 + ], + "resolutions": [ + "max" + ], + "usage_flags": [ + 2304 + ], + "data_spaces": [ + 65536 + ], + "directions": [ + "OUTPUT" + ], + "stream_intervals": [ + 150 + ], + "num_streams" : 1, + "request_types": [ + 1 + ], + "session_mode": 0, + "all_image_dump": true + } +} \ No newline at end of file diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/Talos/Snapshot_YUVNV12_MaxResolution_NHX.json b/Runner/suites/Multimedia/Camera/Camera_NHX/Talos/Snapshot_YUVNV12_MaxResolution_NHX.json new file mode 100755 index 00000000..d401d2b2 --- /dev/null +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/Talos/Snapshot_YUVNV12_MaxResolution_NHX.json @@ -0,0 +1,37 @@ +{ + "NativeHalX.OmniTest": { + "frames": 150, + "camera": 0, + "formats": [ + 35, + 33 + ], + "resolutions": [ + "max", + "max" + ], + "usage_flags": [ + 2304, + 3 + ], + "data_spaces": [ + 65536, + 146931712 + ], + "directions": [ + "OUTPUT", + "OUTPUT" + ], + "stream_intervals": [ + 150, + 5 + ], + "num_streams": 2, + "request_types": [ + 1, + 2 + ], + "session_mode": 0, + "all_image_dump": true + } +} \ No newline at end of file diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/Talos/Video_YUVNV12_MaxResolution_NHX.json b/Runner/suites/Multimedia/Camera/Camera_NHX/Talos/Video_YUVNV12_MaxResolution_NHX.json new file mode 100755 index 00000000..d831d46a --- /dev/null +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/Talos/Video_YUVNV12_MaxResolution_NHX.json @@ -0,0 +1,30 @@ +{ + "NativeHalX.OmniTest": { + "frames": 150, + "camera": 0, + "formats": [ + 34 + ], + "resolutions": [ + "max" + ], + "usage_flags": [ + 65536 + ], + "data_spaces": [ + 260 + ], + "directions": [ + "OUTPUT" + ], + "stream_intervals": [ + 150 + ], + "num_streams": 1, + "request_types": [ + 3 + ], + "session_mode": 0, + "all_image_dump": true + } +} \ No newline at end of file diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/run.sh b/Runner/suites/Multimedia/Camera/Camera_NHX/run.sh index 2e421582..6150c529 100755 --- a/Runner/suites/Multimedia/Camera/Camera_NHX/run.sh +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/run.sh @@ -66,12 +66,17 @@ fi CAM_SERVER_PRESENT=0 CAM_SERVER_STOPPED_FOR_TEST=0 +NHX_JSON="${NHX_JSON:-}" +NHX_TARGET="${NHX_TARGET:-}" +NHX_JSON_RESOLVED="" +NHX_JSON_ARG="" + # shellcheck disable=SC2317 cleanup() { if [ "$CAM_SERVER_STOPPED_FOR_TEST" -eq 1 ] && [ "$CAM_SERVER_PRESENT" -eq 1 ]; then systemd_service_start_safe "cam-server" >/dev/null 2>&1 || true fi - + if [ -n "${MARKER:-}" ]; then rm -f "$MARKER" fi @@ -79,10 +84,72 @@ cleanup() { trap 'cleanup' EXIT INT TERM +usage() { + cat <&2 + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 + fi + NHX_JSON="$2" + shift 2 + ;; + --json=*) + NHX_JSON="${1#--json=}" + shift + ;; + --target) + if [ "$#" -lt 2 ]; then + echo "[ERROR] --target requires an argument" >&2 + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 + fi + NHX_TARGET="$2" + shift 2 + ;; + --target=*) + NHX_TARGET="${1#--target=}" + shift + ;; + -h|--help) + usage + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 + ;; + *) + echo "[ERROR] Unknown argument: $1" >&2 + usage >&2 + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 + ;; + esac +done + # ----------------------------------------------------------------------------- # Deps check # ----------------------------------------------------------------------------- -deps_list="date awk sed grep tee wc ls find stat rm tr head tail dmesg sort fdtdump mkfifo sha256sum md5sum cksum diff cp" +deps_list="date awk sed grep tee wc ls find stat rm tr head tail dmesg sort fdtdump mkfifo sha256sum md5sum cksum diff cp mkdir" if ! check_dependencies "$deps_list"; then log_skip "$TESTNAME SKIP missing one or more dependencies: $deps_list" echo "$TESTNAME SKIP" >"$RES_FILE" @@ -102,7 +169,7 @@ log_info "Checking CAMX proprietary prerequisites before running NHX" 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" +PATTERNS="qcom,cam-sensor qcom,cam-gmsl-sensor qcom,cam-gmsl-deserializer qcom,eeprom qcom,cci qcom,csiphy qcom,cam-tpg1031 qcom,camera qcom,cam camera_kt cam-req-mgr cam-cpas cam-jpeg cam-ife cam-icp camera0-thermal" found_any=0 missing_list="" @@ -322,28 +389,90 @@ fi # ----------------------------------------------------------------------------- : >"$MARKER" 2>/dev/null || touch "$MARKER" -log_info "Launching nhx.sh" +if [ -n "$NHX_JSON" ]; then + if ! command -v nhx_resolve_json_file >/dev/null 2>&1; then + log_skip "$TESTNAME SKIP nhx_resolve_json_file helper not available" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 + fi -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 ! command -v nhx_stage_json_for_launcher >/dev/null 2>&1; then + log_skip "$TESTNAME SKIP nhx_stage_json_for_launcher helper not available" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 + fi + + NHX_JSON_RESOLVED="$(nhx_resolve_json_file "$SCRIPT_DIR" "$NHX_JSON" "$NHX_TARGET" 2>/dev/null)" + nhx_resolve_rc=$? + + if [ "$nhx_resolve_rc" -eq 2 ]; then + log_skip "$TESTNAME SKIP requested NHX JSON matched multiple target folders; pass --target: $NHX_JSON" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 + fi + + if [ -z "$NHX_JSON_RESOLVED" ]; then + log_skip "$TESTNAME SKIP requested NHX JSON not found: $NHX_JSON target=${NHX_TARGET:-}" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 + fi - if ! mkfifo "$FIFO"; then - log_fail "$TESTNAME FAIL mkfifo failed" - echo "$TESTNAME FAIL" >"$RES_FILE" + NHX_JSON_ARG="$(nhx_stage_json_for_launcher "$SCRIPT_DIR" "$NHX_JSON_RESOLVED" "$NHX_TARGET" 2>/dev/null || true)" + + if [ -z "$NHX_JSON_ARG" ]; then + log_skip "$TESTNAME SKIP failed to stage NHX JSON for nhx.sh: $NHX_JSON_RESOLVED" + echo "$TESTNAME SKIP" >"$RES_FILE" exit 0 fi - ( tee "$RUN_LOG" <"$FIFO"; rm -f "$FIFO" 2>/dev/null || true ) & - TEEPID=$! + log_info "Launching nhx.sh with JSON source: $NHX_JSON_RESOLVED" + log_info "Launching nhx.sh with JSON argument: $NHX_JSON_ARG" + + if command -v run_cmd_live_to_log >/dev/null 2>&1; then + run_cmd_live_to_log "$RUN_LOG" nhx.sh "$NHX_JSON_ARG" + 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=$? + nhx.sh "$NHX_JSON_ARG" >"$FIFO" 2>&1 + NHX_RC=$? - wait "$TEEPID" 2>/dev/null || true + wait "$TEEPID" 2>/dev/null || true + fi +else + log_info "Launching nhx.sh with default SoC-specific JSON" + + 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 fi # ----------------------------------------------------------------------------- @@ -354,10 +483,10 @@ if [ "$CAM_SERVER_STOPPED_FOR_TEST" -eq 1 ]; then if systemd_service_start_safe "cam-server"; then CAM_SERVER_STOPPED_FOR_TEST=0 CAM_SERVER_TS_AFTER_START="$(date '+%Y-%m-%d %H:%M:%S')" - + log_info "cam-server status after start" systemd_service_status_log "cam-server AFTER start (status only)" "$RUN_LOG" "cam-server" || true - + log_info "cam-server stdout after start" systemd_service_stdout_since "cam-server AFTER start (stdout since start marker)" \ "$RUN_LOG" "$CAM_SERVER_TS_AFTER_START" "cam-server.service" || true @@ -367,6 +496,7 @@ if [ "$CAM_SERVER_STOPPED_FOR_TEST" -eq 1 ]; then else log_info "cam-server was not stopped for test, skipping restart" fi + # ----------------------------------------------------------------------------- # Dump validation # ----------------------------------------------------------------------------- @@ -422,6 +552,10 @@ TOTAL_BYTES=0 echo "$TESTNAME Summary" echo "Timestamp: $TS" echo "nhx.sh exit code: $NHX_RC" + echo "NHX JSON requested: ${NHX_JSON:-}" + echo "NHX target requested: ${NHX_TARGET:-}" + echo "NHX JSON resolved: ${NHX_JSON_RESOLVED:-}" + echo "NHX JSON argument: ${NHX_JSON_ARG:-}" echo "Dump directory: $DUMP_DIR" echo "Dump files detected: $DUMP_COUNT" echo "Log file: $RUN_LOG" diff --git a/Runner/utils/camera/lib_camera.sh b/Runner/utils/camera/lib_camera.sh index f350a15c..0c286200 100755 --- a/Runner/utils/camera/lib_camera.sh +++ b/Runner/utils/camera/lib_camera.sh @@ -539,8 +539,8 @@ camx_fdtdump_has_cam_nodes() { [ -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)" + | grep -Ei 'qcom,(cam|camera|cci|csiphy|eeprom)|camera@|cam-|cci[0-9]*@|csiphy[0-9]*@' \ + | grep -Ei 'qcom,cam|qcom,camera|qcom,cci|qcom,csiphy|qcom,eeprom|qcom,cam-tpg|qcom,cam-gmsl|qcom,cam-sensor|camera@|cam-req|cam-cpas|cam-jpeg|cam-ife|cam-icp|cam-sensor|camera0-thermal|cci[0-9]*@|csiphy[0-9]*@' || true)" [ -n "$out" ] || return 1 printf '%s\n' "$out" | head -n 20 @@ -559,6 +559,163 @@ nhx_pick_cksum_tool() { fi } +# Resolve one requested NHX JSON file. +# Usage: +# nhx_resolve_json_file "" "" "" +# +# base_dir: Camera_NHX testcase directory +# json: absolute path, path relative to base_dir, or filename +# target: optional target folder: Kodiak/Lemans/Monaco/Talos +# +# Prints resolved path on success. +nhx_resolve_json_file() { + base_dir="$1" + json="$2" + target="$3" + cand="" + found="" + dir="" + + [ -n "$base_dir" ] || return 1 + [ -n "$json" ] || return 1 + + case "$json" in + /*) + if [ -f "$json" ]; then + printf '%s\n' "$json" + return 0 + fi + ;; + */*) + cand="$base_dir/$json" + if [ -f "$cand" ]; then + printf '%s\n' "$cand" + return 0 + fi + + cand="$(pwd)/$json" + if [ -f "$cand" ]; then + printf '%s\n' "$cand" + return 0 + fi + ;; + *) + if [ -n "$target" ]; then + cand="$base_dir/$target/$json" + if [ -f "$cand" ]; then + printf '%s\n' "$cand" + return 0 + fi + fi + + cand="$base_dir/$json" + if [ -f "$cand" ]; then + printf '%s\n' "$cand" + return 0 + fi + + for dir in Kodiak Lemans Monaco Talos; do + cand="$base_dir/$dir/$json" + if [ -f "$cand" ]; then + if [ -n "$found" ]; then + return 2 + fi + found="$cand" + fi + done + + if [ -n "$found" ]; then + printf '%s\n' "$found" + return 0 + fi + ;; + esac + + return 1 +} + +# Stage resolved NHX JSON into the path expected by /usr/bin/nhx.sh. +# nhx.sh expects an argument without ".json" and internally looks under: +# /etc/camera/test/NHX/${JSON_FILE}.json +# +# Usage: +# nhx_stage_json_for_launcher "" "" "" +# +# Prints launcher argument, for example: +# Lemans/Prev_plus_Video_YUVNV12_MaxResolution_NHX +nhx_stage_json_for_launcher() { + base_dir="$1" + src_json="$2" + target="$3" + json_root="${NHX_JSON_ROOT:-/etc/camera/test/NHX}" + rel="" + first="" + base="" + name_no_ext="" + dst_dir="" + dst_json="" + + [ -n "$base_dir" ] || return 1 + [ -n "$src_json" ] || return 1 + [ -f "$src_json" ] || return 1 + + base="${src_json##*/}" + name_no_ext="${base%.json}" + + if [ "$name_no_ext" = "$base" ]; then + return 1 + fi + + if [ -z "$target" ]; then + case "$src_json" in + "$base_dir"/*) + rel="${src_json#"$base_dir"/}" + first="${rel%%/*}" + case "$first" in + Kodiak|Lemans|Monaco|Talos) + target="$first" + ;; + esac + ;; + esac + fi + + case "$target" in + Kodiak|Lemans|Monaco|Talos) + dst_dir="$json_root/$target" + dst_json="$dst_dir/$base" + + if ! mkdir -p "$dst_dir"; then + return 1 + fi + + if ! cp -f "$src_json" "$dst_json"; then + return 1 + fi + + printf '%s/%s\n' "$target" "$name_no_ext" + return 0 + ;; + "") + dst_dir="$json_root" + dst_json="$dst_dir/$base" + + if ! mkdir -p "$dst_dir"; then + return 1 + fi + + if ! cp -f "$src_json" "$dst_json"; then + return 1 + fi + + printf '%s\n' "$name_no_ext" + return 0 + ;; + esac + + return 1 +} + 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.