From a518204a63168a3f7b9319bc643dcc597d6757d1 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Thu, 12 Mar 2026 22:59:05 +0530 Subject: [PATCH 1/3] utils: fix file_size_bytes fallback ordering Prefer GNU stat output first, then fall back to BSD stat and wc -c. This avoids false zero-byte results on target images where the earlier ordering could return an incorrect numeric value before reaching a safe fallback. Signed-off-by: Srikanth Muppandam --- Runner/utils/functestlib.sh | 129 ++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/Runner/utils/functestlib.sh b/Runner/utils/functestlib.sh index de707d04..7483f056 100755 --- a/Runner/utils/functestlib.sh +++ b/Runner/utils/functestlib.sh @@ -3055,6 +3055,87 @@ check_systemd_services() { return 0 } +# Check whether a systemd service/unit exists on the target. +systemd_service_exists() { + svc="$1" + + if ! command -v systemctl >/dev/null 2>&1; then + return 1 + fi + + systemctl cat "$svc" >/dev/null 2>&1 +} + +# Check whether a systemd service/unit is currently active. +systemd_service_is_active() { + svc="$1" + + if ! command -v systemctl >/dev/null 2>&1; then + return 1 + fi + + systemctl is-active --quiet "$svc" +} + +# Start a systemd service/unit quietly. +systemd_service_start_safe() { + svc="$1" + + if ! command -v systemctl >/dev/null 2>&1; then + return 1 + fi + + systemctl start "$svc" >/dev/null 2>&1 +} + +# Stop a systemd service/unit quietly. +systemd_service_stop_safe() { + svc="$1" + + if ! command -v systemctl >/dev/null 2>&1; then + return 1 + fi + + systemctl stop "$svc" >/dev/null 2>&1 +} + +# Log status-only output for a systemd service/unit to the given logfile. +systemd_service_status_log() { + label="$1" + logfile="$2" + svc="$3" + + if ! command -v systemctl >/dev/null 2>&1; then + return 1 + fi + + { + echo "===== $label =====" + systemctl --no-pager --full --lines=0 status "$svc" 2>&1 + echo "==============================" + } | tee -a "$logfile" +} + +# Log stdout journal entries for a systemd service/unit since a given timestamp. +systemd_service_stdout_since() { + label="$1" + logfile="$2" + since_ts="$3" + svc="$4" + + if ! command -v journalctl >/dev/null 2>&1; then + return 1 + fi + + { + echo "===== $label =====" + journalctl --no-pager -q \ + _SYSTEMD_UNIT="$svc" \ + _TRANSPORT=stdout \ + --since "$since_ts" 2>&1 + echo "==============================" + } | tee -a "$logfile" +} # Ensure udhcpc default.script exists, create if missing ensure_udhcpc_script() { udhcpc_dir="/usr/share/udhcpc" @@ -4558,3 +4639,51 @@ get_pid() { log_info "Process '$process_name' not found." return 1 } + +# Returns the size of the given file in bytes using stat, with fallbacks for portability across systems. +# Prints 0 and returns failure if the file does not exist or the size cannot be determined reliably. +file_size_bytes() { + file_path="$1" + size="" + + [ -f "$file_path" ] || { + printf '%s\n' "0" + return 1 + } + + # Prefer GNU stat first. + size="$(stat -c %s "$file_path" 2>/dev/null || true)" + case "$size" in + ''|*[!0-9]*) + size="" + ;; + esac + + # Fall back to BSD stat only if GNU form did not work. + if [ -z "$size" ]; then + size="$(stat -f %z "$file_path" 2>/dev/null || true)" + case "$size" in + ''|*[!0-9]*) + size="" + ;; + esac + fi + + # Final portable fallback. + if [ -z "$size" ]; then + size="$(wc -c <"$file_path" 2>/dev/null | awk '{print $1}')" + case "$size" in + ''|*[!0-9]*) + size="" + ;; + esac + fi + + if [ -z "$size" ]; then + printf '%s\n' "0" + return 1 + fi + + printf '%s\n' "$size" + return 0 +} From 4dac1744559cdae53dc56260862424267257c560 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Thu, 12 Mar 2026 22:59:44 +0530 Subject: [PATCH 2/3] camera: add generic NHX and CAMX helper updates Update camera helpers to better support NHX validation across targets. Changes include: - board-aware camera module selection from DT data - generic CAMERA_ICP firmware discovery under /lib/firmware/qcom - package detection for both opkg and dnf/rpm based images - cam-server logging helpers for status and stdout capture - NHX dump size helper built on shared file size detection Signed-off-by: Srikanth Muppandam --- Runner/utils/camera/lib_camera.sh | 151 +++++++++++++++++++++++++----- 1 file changed, 129 insertions(+), 22 deletions(-) diff --git a/Runner/utils/camera/lib_camera.sh b/Runner/utils/camera/lib_camera.sh index 7897317a..f350a15c 100755 --- a/Runner/utils/camera/lib_camera.sh +++ b/Runner/utils/camera/lib_camera.sh @@ -442,36 +442,93 @@ camx_read_soc_id() { # Find ICP camera firmware ELF (CAMERA_ICP_*.elf) # Prints first match path on stdout. camx_find_icp_firmware() { - soc="$(camx_read_soc_id 2>/dev/null || true)" - - # First try soc-specific canonical path - for root in /usr/lib/firmware /lib/firmware; do - if [ -n "$soc" ] && [ -d "$root/qcom/$soc" ]; then - p="$(find "$root/qcom/$soc" -maxdepth 1 -type f -name 'CAMERA_ICP_*.elf' 2>/dev/null | head -n 1)" - [ -n "$p" ] && echo "$p" && return 0 - fi - done - - # Fallback bounded search - for root in /usr/lib/firmware /lib/firmware; do - if [ -d "$root/qcom" ]; then - p="$(find "$root/qcom" -maxdepth 2 -type f -name 'CAMERA_ICP_*.elf' 2>/dev/null | head -n 1)" - [ -n "$p" ] && echo "$p" && return 0 + token_list="" + token="" + cand="" + + if [ -r /proc/device-tree/compatible ]; then + token_list="$( + tr '\0' '\n' /dev/null \ + | tr '[:upper:]' '[:lower:]' \ + | sed -n 's#.*\(qcm[0-9][0-9]*\|qcs[0-9][0-9]*\|sa[0-9][0-9]*p\).*#\1#p' \ + | sort -u + )" + fi + + for token in $token_list; do + if [ -d "/lib/firmware/qcom/$token" ]; then + for cand in \ + "/lib/firmware/qcom/$token/CAMERA_ICP.mbn" \ + "/lib/firmware/qcom/$token/CAMERA_ICP.elf" + do + if [ -f "$cand" ]; then + printf '%s\n' "$cand" + return 0 + fi + done + + cand="$( + find "/lib/firmware/qcom/$token" -maxdepth 1 -type f \ + \( -name 'CAMERA_ICP*.mbn' -o -name 'CAMERA_ICP*.elf' \) \ + 2>/dev/null | sort | head -n 1 + )" + if [ -n "$cand" ] && [ -f "$cand" ]; then + printf '%s\n' "$cand" + return 0 + fi fi done - + + cand="$( + find /lib/firmware/qcom -type f \ + \( -name 'CAMERA_ICP.mbn' -o -name 'CAMERA_ICP.elf' -o -name 'CAMERA_ICP*.mbn' -o -name 'CAMERA_ICP*.elf' \) \ + 2>/dev/null | sort | head -n 1 + )" + if [ -n "$cand" ] && [ -f "$cand" ]; then + printf '%s\n' "$cand" + return 0 + fi + + cand="$( + find /lib/firmware -type f \ + \( -name 'CAMERA_ICP.mbn' -o -name 'CAMERA_ICP.elf' -o -name 'CAMERA_ICP*.mbn' -o -name 'CAMERA_ICP*.elf' \) \ + 2>/dev/null | sort | head -n 1 + )" + if [ -n "$cand" ] && [ -f "$cand" ]; then + printf '%s\n' "$cand" + return 0 + fi + return 1 } - # ----------------------------------------------------------------------------- # Package helpers (Yocto/QLI proprietary builds) # ----------------------------------------------------------------------------- camx_opkg_list_camx() { - command -v opkg >/dev/null 2>&1 || return 1 - out="$(opkg list-installed 2>/dev/null | grep -i '^camx' || true)" - [ -n "$out" ] || return 1 - printf '%s\n' "$out" - return 0 + out="" + + if command -v opkg >/dev/null 2>&1; then + out="$(opkg list-installed 2>/dev/null | grep -i '^camx' || true)" + [ -n "$out" ] || return 1 + printf '%s\n' "$out" + return 0 + fi + + if command -v dnf >/dev/null 2>&1; then + out="$(dnf list installed 2>/dev/null | grep -i '^camx' || true)" + [ -n "$out" ] || return 1 + printf '%s\n' "$out" + return 0 + fi + + if command -v rpm >/dev/null 2>&1; then + out="$(rpm -qa 2>/dev/null | grep -i '^camx' || true)" + [ -n "$out" ] || return 1 + printf '%s\n' "$out" + return 0 + fi + + return 1 } # ----------------------------------------------------------------------------- @@ -635,3 +692,53 @@ run_cmd_live_to_log() { wait "$teepid" 2>/dev/null || true return "$rc" } + +# ----------------------------------------------------------------------------- +# Pick board-specific camera module from DT compatible/model +# ----------------------------------------------------------------------------- +camx_pick_camera_module() { + compat_list="" + model_str="" + + if [ -r /proc/device-tree/compatible ]; then + compat_list="$(tr '\0' '\n' /dev/null | tr '[:upper:]' '[:lower:]')" + fi + + if [ -r /proc/device-tree/model ]; then + model_str="$(tr '[:upper:]' '[:lower:]' /dev/null)" + fi + + case "$compat_list +$model_str" in + *rb3gen2*|*qcm6490*|*qcs6490*) + printf '%s\n' "camera_qcm6490" + return 0 + ;; + *qcs9100-ride-sx*|*iq-9075-evk*|*qcs8300-ride-sx*|*iq-8275-evk*|*qcs9100*|*qcs8300*) + printf '%s\n' "camera_qcs9100" + return 0 + ;; + *qcs615-ride*|*iq-615-evk*|*qcs615*) + printf '%s\n' "camera_qcs615" + return 0 + ;; + esac + + return 1 +} + +# Get the size of the yuv file dump +nhx_dump_size_bytes() { + file_path="$1" + size="$(file_size_bytes "$file_path" 2>/dev/null || printf '%s\n' "0")" + + case "$size" in + ''|*[!0-9]*) + printf '%s\n' "0" + return 1 + ;; + esac + + printf '%s\n' "$size" + return 0 +} From 3a8e643faf74cd58bb9dd794c4641adf07cf0940 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Thu, 12 Mar 2026 23:00:01 +0530 Subject: [PATCH 3/3] camera: refine NHX validation flow and reuse common helpers Rework the Camera_NHX runner to use the updated shared helpers and make the validation flow more robust. Changes include: - use board-aware camera module selection - use generic CAMERA_ICP firmware lookup - support rpm/dnf based images through shared package detection - stop/start cam-server around nhx.sh and capture status/stdout logs - keep pre-NHX CAMX dmesg checks warn-only - reuse shared dump size handling during dump validation Signed-off-by: Srikanth Muppandam --- .../Multimedia/Camera/Camera_NHX/run.sh | 188 ++++++++++-------- 1 file changed, 109 insertions(+), 79 deletions(-) diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/run.sh b/Runner/suites/Multimedia/Camera/Camera_NHX/run.sh index 38ed33e8..2e421582 100755 --- a/Runner/suites/Multimedia/Camera/Camera_NHX/run.sh +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/run.sh @@ -1,6 +1,6 @@ #!/bin/sh # Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. -# SPDX-License-Identifier: BSD-3-Clause# +# SPDX-License-Identifier: BSD-3-Clause # Camera NHX validation TESTNAME="Camera_NHX" @@ -51,10 +51,8 @@ RUN_LOG="$LOG_DIR/${TESTNAME}_${TS}.log" SUMMARY_TXT="$OUT_DIR/${TESTNAME}_summary_${TS}.txt" DMESG_DIR="$LOG_DIR/dmesg_${TS}" -# NHX helper output directory (IMPORTANT: lib_camera.sh expects a directory, not a file) NHX_OUTDIR="$OUT_DIR/nhx_${TS}" -# dump list & checksum artifacts (produced by dump validation helper) DUMPS_LIST="$NHX_OUTDIR/nhx_dumps.list" CHECKSUMS_TXT="$NHX_OUTDIR/nhx_checksums.txt" CHECKSUMS_PREV="$OUT_DIR/${TESTNAME}_checksums.prev.txt" @@ -65,13 +63,26 @@ if [ -z "$MARKER" ]; then : >"$MARKER" 2>/dev/null || true fi -cleanup() { rm -f "$MARKER" 2>/dev/null || true; } -trap cleanup EXIT INT TERM +CAM_SERVER_PRESENT=0 +CAM_SERVER_STOPPED_FOR_TEST=0 + +# 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 +} + +trap 'cleanup' EXIT INT TERM # ----------------------------------------------------------------------------- -# Deps check (functestlib.sh provides check_dependencies) +# Deps check # ----------------------------------------------------------------------------- -deps_list="date awk sed grep tee wc ls find stat rm tr head tail dmesg sort opkg fdtdump mkfifo sha256sum md5sum cksum diff cp" +deps_list="date awk sed grep tee wc ls find stat rm tr head tail dmesg sort fdtdump mkfifo sha256sum md5sum cksum diff cp" if ! check_dependencies "$deps_list"; then log_skip "$TESTNAME SKIP missing one or more dependencies: $deps_list" echo "$TESTNAME SKIP" >"$RES_FILE" @@ -86,18 +97,9 @@ fi # ----------------------------------------------------------------------------- # CAMX prechecks -# Sequence: -# 1) DT check -# 2) fdtdump camera nodes sample -# 3) driver load checks -# 4) packages present -# 5) sensor presence warn-only # ----------------------------------------------------------------------------- log_info "Checking CAMX proprietary prerequisites before running NHX" -# ----------------------------- -# 1) DT check -# ----------------------------- log_info "DT check" PATTERNS="qcom,cam qcom,camera camera_kt cam-req-mgr cam-cpas cam-jpeg cam-ife cam-icp cam-sensor camera0-thermal" @@ -110,7 +112,6 @@ for pat in $PATTERNS; do printf '%s\n' "$out" found_any=1 else - # Explicit append logic (reviewer-friendly; avoids &&/|| ambiguity) if [ -n "$missing_list" ]; then missing_list="$missing_list, $pat" else @@ -125,12 +126,9 @@ if [ "$found_any" -ne 1 ]; then exit 0 fi -# ----------------------------- -# 2) fdtdump camera nodes sample -# ----------------------------- log_info "fdtdump camera nodes sample" -FDT_MATCHES="$(camx_fdtdump_has_cam_nodes 2>/dev/null || true)" +FDT_MATCHES="$(camx_fdtdump_has_cam_nodes 2>/dev/null)" rc=$? if [ "$rc" -ne 0 ]; then if [ "$rc" -eq 2 ]; then @@ -143,37 +141,31 @@ if [ "$rc" -ne 0 ]; then fi printf '%s\n' "$FDT_MATCHES" | while IFS= read -r l; do - [ -n "$l" ] && log_info " $l" + if [ -n "$l" ]; then + log_info " $l" + fi done -# ----------------------------- -# 3) driver load checks -# ----------------------------- log_info "driver load checks" CAM_MOD="" -if command -v lsmod >/dev/null 2>&1; then - CAM_MOD="$(lsmod 2>/dev/null | awk '{print $1}' \ - | grep -E '^(camera_qc|camera_qcm|camera_qcs)' \ - | head -n 1 || true)" +if command -v camx_pick_camera_module >/dev/null 2>&1; then + CAM_MOD="$(camx_pick_camera_module 2>/dev/null || true)" fi -if [ -z "$CAM_MOD" ]; then - kver="$(uname -r 2>/dev/null || true)" - if [ -n "$kver" ] && [ -d "/lib/modules/$kver" ]; then - ko="$(find "/lib/modules/$kver" -type f \( -name 'camera_qc*.ko' -o -name 'camera_qcm*.ko' -o -name 'camera_qcs*.ko' \) \ - 2>/dev/null | head -n 1 || true)" - CAM_MOD="$(basename "${ko:-}" .ko)" - fi +if [ -z "$CAM_MOD" ] && command -v lsmod >/dev/null 2>&1; then + CAM_MOD="$(lsmod 2>/dev/null | awk '{print $1}' | grep -E '^(camera_qc|camera_qcm|camera_qcs)' | head -n 1 || true)" fi if [ -z "$CAM_MOD" ]; then - log_skip "$TESTNAME SKIP could not determine camera module name" + log_skip "$TESTNAME SKIP could not determine board-specific camera module" echo "$TESTNAME SKIP" >"$RES_FILE" exit 0 fi +log_info "Board-specific camera module selected $CAM_MOD" + CAM_KO="$(find_kernel_module "$CAM_MOD" 2>/dev/null || true)" if [ -z "$CAM_KO" ] || [ ! -f "$CAM_KO" ]; then log_skip "$TESTNAME SKIP camera module artifact not found ${CAM_MOD}.ko" @@ -197,7 +189,6 @@ if [ -z "$ICP_FW" ] || [ ! -f "$ICP_FW" ]; then fi log_info "ICP firmware found $ICP_FW" -# dmesg collection and error scan module_regex='CAM_(ERR|WARN|FATAL)' exclude_regex='dummy regulator|supply [^ ]+ not found|using dummy regulator' @@ -216,12 +207,10 @@ FW_DL_OK=0 FW_DONE_OK=0 if [ -n "$FW_BASENAME" ] && [ -r "$DM_SNAP" ]; then - if grep -F "CAM_INFO: CAM-ICP: cam_a5_download_fw" "$DM_SNAP" 2>/dev/null \ - | grep -F "$FW_BASENAME" >/dev/null 2>&1; then + if grep -F "CAM_INFO: CAM-ICP: cam_a5_download_fw" "$DM_SNAP" 2>/dev/null | grep -F "$FW_BASENAME" >/dev/null 2>&1; then FW_DL_OK=1 fi - if grep -F "CAM_INFO: CAM-ICP: cam_icp_mgr_hw_open" "$DM_SNAP" 2>/dev/null \ - | grep -F "FW download done successfully" >/dev/null 2>&1; then + if grep -F "CAM_INFO: CAM-ICP: cam_icp_mgr_hw_open" "$DM_SNAP" 2>/dev/null | grep -F "FW download done successfully" >/dev/null 2>&1; then FW_DONE_OK=1 fi fi @@ -238,19 +227,17 @@ fi bind_cnt=0 if [ -r "$DM_SNAP" ]; then bind_cnt="$(grep -ciE 'cam_req_mgr.*bound|bound.*cam_req_mgr' "$DM_SNAP" 2>/dev/null || echo 0)" - case "$bind_cnt" in ''|*[!0-9]*) bind_cnt=0 ;; esac + case "$bind_cnt" in + ''|*[!0-9]*) bind_cnt=0 ;; + esac fi -if [ "$bind_cnt" -lt 5 ]; then - log_skip "$TESTNAME SKIP CAMX bind graph not observed" - echo "$TESTNAME SKIP" >"$RES_FILE" - exit 0 +if [ "$bind_cnt" -lt 1 ]; then + log_warn "CAMX bind graph not observed in pre-NHX dmesg snapshot" +else + log_info "CAMX bind graph observed in pre-NHX dmesg snapshot count=$bind_cnt" fi -log_info "CAMX bind graph observed" -# ----------------------------- -# 4) packages present -# ----------------------------- log_info "packages present" CAMX_PKGS="$(camx_opkg_list_camx 2>/dev/null || true)" @@ -262,24 +249,22 @@ fi log_info "CAMX packages detected" printf '%s\n' "$CAMX_PKGS" | while IFS= read -r l; do - [ -n "$l" ] && log_info " $l" + if [ -n "$l" ]; then + log_info " $l" + fi done -# ----------------------------- -# 5) sensor presence warn-only -# ----------------------------- log_info "sensor presence warn-only NHX may still work without cam sensors" SENSOR_COUNT="$(libcam_list_sensors_count 2>/dev/null || true)" -case "$SENSOR_COUNT" in ''|*[!0-9]*) SENSOR_COUNT=0 ;; esac +case "$SENSOR_COUNT" in + ''|*[!0-9]*) SENSOR_COUNT=0 ;; +esac log_info "cam list detected $SENSOR_COUNT cameras" if [ "$SENSOR_COUNT" -lt 1 ]; then log_warn "No sensors reported by cam list continuing" fi -# ----------------------------------------------------------------------------- -# Pick checksum tool (prefer helper in lib_camera.sh) -# ----------------------------------------------------------------------------- CKSUM_TOOL="" if command -v nhx_pick_cksum_tool >/dev/null 2>&1; then CKSUM_TOOL="$(nhx_pick_cksum_tool)" @@ -299,6 +284,39 @@ log_info "DUMP_DIR=$DUMP_DIR" log_info "NHX_OUTDIR=$NHX_OUTDIR" log_info "CKSUM_TOOL=${CKSUM_TOOL:-none}" +# ----------------------------------------------------------------------------- +# cam-server stop before NHX +# ----------------------------------------------------------------------------- +if systemd_service_exists "cam-server"; then + CAM_SERVER_PRESENT=1 + + CAM_SERVER_TS_BEFORE_STOP='5 minutes ago' + + log_info "cam-server status before stop" + systemd_service_status_log "cam-server BEFORE stop (status only)" "$RUN_LOG" "cam-server" || true + + log_info "cam-server stdout before stop" + systemd_service_stdout_since "cam-server BEFORE stop (stdout recent)" \ + "$RUN_LOG" "$CAM_SERVER_TS_BEFORE_STOP" "cam-server.service" || true + + log_info "Stopping cam-server before nhx.sh" + if systemd_service_stop_safe "cam-server"; then + CAM_SERVER_STOPPED_FOR_TEST=1 + CAM_SERVER_TS_AFTER_STOP="$(date '+%Y-%m-%d %H:%M:%S')" + + log_info "cam-server status after stop" + systemd_service_status_log "cam-server AFTER stop (status only)" "$RUN_LOG" "cam-server" || true + + log_info "cam-server stdout after stop" + systemd_service_stdout_since "cam-server AFTER stop (stdout since stop marker)" \ + "$RUN_LOG" "$CAM_SERVER_TS_AFTER_STOP" "cam-server.service" || true + else + log_warn "Failed to stop cam-server before nhx.sh" + fi +else + log_info "cam-server service not present, continuing" +fi + # ----------------------------------------------------------------------------- # Run NHX # ----------------------------------------------------------------------------- @@ -329,21 +347,38 @@ else fi # ----------------------------------------------------------------------------- -# Dump validation (delegate to lib_camera.sh helper) -# IMPORTANT: helper expects an output DIRECTORY, not a file path. +# cam-server start after NHX +# ----------------------------------------------------------------------------- +if [ "$CAM_SERVER_STOPPED_FOR_TEST" -eq 1 ]; then + log_info "Starting cam-server after nhx.sh" + 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 + else + log_warn "Failed to start cam-server after nhx.sh" + fi +else + log_info "cam-server was not stopped for test, skipping restart" +fi +# ----------------------------------------------------------------------------- +# Dump validation # ----------------------------------------------------------------------------- DUMP_VALIDATION_FAIL=0 -# Ensure output directory exists regardless of helper/fallback mkdir -p "$NHX_OUTDIR" 2>/dev/null || true if command -v nhx_validate_dumps_and_checksums >/dev/null 2>&1; then - # nhx_validate_dumps_and_checksums if ! nhx_validate_dumps_and_checksums "$DUMP_DIR" "$MARKER" "$NHX_OUTDIR" "$CHECKSUMS_TXT" "$CHECKSUMS_PREV"; then DUMP_VALIDATION_FAIL=1 fi - # If helper generated a different list name, keep our expected path working. if [ ! -s "$DUMPS_LIST" ]; then if [ -s "$NHX_OUTDIR/nhx_dumps.list" ]; then DUMPS_LIST="$NHX_OUTDIR/nhx_dumps.list" @@ -354,7 +389,6 @@ if command -v nhx_validate_dumps_and_checksums >/dev/null 2>&1; then fi fi else - # fallback: old behavior : >"$DUMPS_LIST" 2>/dev/null || true grep -F "Saving image to file:" "$RUN_LOG" \ @@ -363,7 +397,9 @@ else | sort -u >"$DUMPS_LIST" 2>/dev/null || true DUMP_COUNT="$(wc -l <"$DUMPS_LIST" 2>/dev/null | awk '{print $1}')" - [ -n "$DUMP_COUNT" ] || DUMP_COUNT=0 + if [ -z "$DUMP_COUNT" ]; then + DUMP_COUNT=0 + fi if [ "$DUMP_COUNT" -eq 0 ]; then log_info "No dump paths found in log scanning dump dir for new files" @@ -373,15 +409,11 @@ else fi fi -# ----------------------------------------------------------------------------- -# Compute dump count (based on DUMPS_LIST produced by helper/fallback) -# ----------------------------------------------------------------------------- DUMP_COUNT="$(wc -l <"$DUMPS_LIST" 2>/dev/null | awk '{print $1}')" -[ -n "$DUMP_COUNT" ] || DUMP_COUNT=0 +if [ -z "$DUMP_COUNT" ]; then + DUMP_COUNT=0 +fi -# ----------------------------------------------------------------------------- -# Validate dumps (summary-side size scan; checksum is already done by helper) -# ----------------------------------------------------------------------------- ZERO_OR_MISSING=0 TOTAL_BYTES=0 @@ -410,7 +442,6 @@ if [ "$DUMP_COUNT" -gt 0 ]; then } >>"$SUMMARY_TXT" while IFS= read -r f; do - # Clear, reviewer-friendly empty-line skip [ -z "$f" ] && continue if [ ! -f "$f" ]; then @@ -419,11 +450,10 @@ if [ "$DUMP_COUNT" -gt 0 ]; then continue fi - SZ="$(stat -c %s "$f" 2>/dev/null)" - if [ -z "$SZ" ]; then - SZ="$(wc -c <"$f" 2>/dev/null | awk '{print $1}')" - fi - [ -n "$SZ" ] || SZ=0 + SZ="$(nhx_dump_size_bytes "$f" 2>/dev/null || printf '%s\n' "0")" + case "$SZ" in + ''|*[!0-9]*) SZ=0 ;; + esac if [ "$SZ" -le 0 ]; then ZERO_OR_MISSING=$((ZERO_OR_MISSING + 1))