#!/usr/bin/env bash # Author: cirakg & claude ai # Summary: Run the debug app on each device in the headless simulator and check start-up time, memory, or the watchdog stress test. # # Usage: app-diag.sh perf|mem|watchdog DEVICE [DEVICE ...] # Output: build/diag/.log (console with DIAG and HARNESS lines) and # build/diag/-summary.json; verdict from tools/check_budgets.py. # watchdog: the stress build (source/util/StressTest.mc) on each # device, build/diag/watchdog-.log; it fails when the # simulator reports an error (such as "Watchdog Tripped"), the # test doesn't finish, or its last code (left on the screen) # doesn't decode. set -euo pipefail # shellcheck source=ciq-env.sh source "$(dirname "${BASH_SOURCE[0]}")/ciq-env.sh" kind="${1:?usage: app-diag.sh perf|mem|watchdog DEVICE [DEVICE ...]}" shift [[ "${kind}" == perf || "${kind}" == mem || "${kind}" == watchdog ]] || die "unknown kind '${kind}' (use perf, mem or watchdog)" (($# > 0)) || die "usage: app-diag.sh perf|mem|watchdog DEVICE [DEVICE ...]" ciq_require_sdk ciq_require_key # The stress test takes a few minutes per device (about 3,500 job steps at # 50 ms on the 512 KB watches). WATCHDOG_TIMEOUT_S=1200 STRESS_ITEMS=10 if [[ "${kind}" == watchdog ]]; then for device in "$@"; do build-app.sh stress "${device}" done ciq_start_display ciq_start_simulator mkdir -p "${BUILD_DIR}/diag" failed=0 for device in "$@"; do log="${BUILD_DIR}/diag/watchdog-${device}.log" log "watchdog stress test on ${device}" ciq_launch_app "${device}" "${log}" stress || log "no first frame on ${device}" for _ in $(seq 1 "${WATCHDOG_TIMEOUT_S}"); do grep -q "DIAG stress all done\|Error" "${log}" && break kill -0 "${CIQ_MONKEYDO_PID}" 2>/dev/null || break sleep 1 done # The last code stays on the screen; it must decode (on most watches # it was drawn from a bitmap). decoded=1 if grep -aq "DIAG stress all done" "${log}"; then sleep 1 python3 /work/tools/ui_flow.py --decode "OTPW stress" --device-dir "${CIQ_HOME}/Devices/${device}" \ --window "$(ciq_simulator_window)" --out "${BUILD_DIR}/diag/watchdog-${device}" >&2 || decoded=0 fi ciq_stop_app grep -a "DIAG stress" "${log}" | sed "s/^/[${device}] /" >&2 || true done_count="$(grep -ac "DIAG stress done name=" "${log}" || true)" if grep -aq "Error" "${log}"; then grep -a "Error" "${log}" | sed "s/^/[${device}] /" >&2 failed=1 elif ! grep -aq "DIAG stress all done" "${log}" || ((done_count != STRESS_ITEMS)); then log "${device}: the stress test did not finish (${done_count} of ${STRESS_ITEMS} items)" failed=1 elif ((decoded == 0)); then failed=1 fi done ((failed == 0)) || die "watchdog stress test failed; logs in build/diag/" log "watchdog stress test passed on: $*" exit 0 fi for device in "$@"; do build-app.sh debug "${device}" done ciq_start_display ciq_start_simulator out="${BUILD_DIR}/diag" mkdir -p "${out}" logs=() for device in "$@"; do log "starting the app on ${device}" ciq_launch_app "${device}" "${out}/${device}.log" || log "no first frame on ${device} within ${FIRST_FRAME_TIMEOUT_S} s" ciq_stop_app logs+=("${out}/${device}.log") done python3 /work/tools/check_budgets.py "${kind}" "${logs[@]}" --summary "${out}/${kind}-summary.json"