aboutsummaryrefslogtreecommitdiff
path: root/docker
diff options
context:
space:
mode:
Diffstat (limited to 'docker')
-rwxr-xr-xdocker/scripts/app-diag.sh63
-rwxr-xr-xdocker/scripts/build-app.sh16
-rwxr-xr-xdocker/scripts/screenshots.sh33
3 files changed, 99 insertions, 13 deletions
diff --git a/docker/scripts/app-diag.sh b/docker/scripts/app-diag.sh
index 804d68a..025fd49 100755
--- a/docker/scripts/app-diag.sh
+++ b/docker/scripts/app-diag.sh
@@ -1,21 +1,74 @@
#!/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 or memory budgets.
+# 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 DEVICE [DEVICE ...]
+# Usage: app-diag.sh perf|mem|watchdog DEVICE [DEVICE ...]
# Output: build/diag/<DEVICE>.log (console with DIAG and HARNESS lines) and
# build/diag/<perf|mem>-summary.json; verdict from tools/check_budgets.py.
+# watchdog: the stress build (source/util/StressTest.mc) on each
+# device, build/diag/watchdog-<DEVICE>.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 DEVICE [DEVICE ...]}"
+kind="${1:?usage: app-diag.sh perf|mem|watchdog DEVICE [DEVICE ...]}"
shift
-[[ "${kind}" == perf || "${kind}" == mem ]] || die "unknown kind '${kind}' (use perf or mem)"
-(($# > 0)) || die "usage: app-diag.sh perf|mem DEVICE [DEVICE ...]"
+[[ "${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
diff --git a/docker/scripts/build-app.sh b/docker/scripts/build-app.sh
index 1a7d59a..5ead272 100755
--- a/docker/scripts/build-app.sh
+++ b/docker/scripts/build-app.sh
@@ -1,21 +1,22 @@
#!/usr/bin/env bash
# Author: cirakg & claude ai
-# Summary: Compile the watch app for one device: debug, release, unit-test or UI-test build.
+# Summary: Compile the watch app for one device: debug, release, unit-test, UI-test or watchdog stress build.
#
-# Usage: build-app.sh debug|release|test|uitest DEVICE
+# Usage: build-app.sh debug|release|test|uitest|stress DEVICE
# Output: build/<mode>/<DEVICE>.prg, and the compiler log next to it.
#
# Policy (README section 17.7): strict type checking (-l 3), and any compiler
# warning fails the build. UI-test builds add uitest.jungle (fixed clock,
-# fake entries; see source/util/TestMode.mc). Test builds add test.jungle, so test code never
-# reaches debug or release builds; release builds (-r) also drop every
+# fake entries; see source/util/TestMode.mc), stress builds stress.jungle (the
+# watchdog stress test, source/util/StressTest.mc). Test builds add
+# test.jungle, so test code never reaches debug or release builds; release builds (-r) also drop every
# (:debug) declaration, such as the diagnostics in source/util/Diag.mc.
set -euo pipefail
# shellcheck source=ciq-env.sh
source "$(dirname "${BASH_SOURCE[0]}")/ciq-env.sh"
-mode="${1:?usage: build-app.sh debug|release|test|uitest DEVICE}"
-device="${2:?usage: build-app.sh debug|release|test|uitest DEVICE}"
+mode="${1:?usage: build-app.sh debug|release|test|uitest|stress DEVICE}"
+device="${2:?usage: build-app.sh debug|release|test|uitest|stress DEVICE}"
ciq_require_sdk
ciq_require_key
@@ -29,11 +30,12 @@ case "${mode}" in
debug) ;;
release) args+=(-r) ;;
uitest) jungles="${jungles};/work/uitest.jungle" ;;
+ stress) jungles="${jungles};/work/stress.jungle" ;;
test)
jungles="${jungles};/work/test.jungle"
args+=(-t)
;;
- *) die "unknown build mode '${mode}' (use debug, release, test or uitest)" ;;
+ *) die "unknown build mode '${mode}' (use debug, release, test, uitest or stress)" ;;
esac
out_dir="${BUILD_DIR}/${mode}"
diff --git a/docker/scripts/screenshots.sh b/docker/scripts/screenshots.sh
index 414af52..91477c4 100755
--- a/docker/scripts/screenshots.sh
+++ b/docker/scripts/screenshots.sh
@@ -9,7 +9,9 @@
#
# Uses the UI-test build (uitest.jungle): fake entries, PIN 123456 and a
# frozen clock, so every screenshot is reproducible. tools/ui_flow.py
-# drives the app and checks the screens.
+# drives the app and checks the screens. Then the app is launched again and
+# its glance, which now shows the favourite's code (the first run sealed it),
+# is checked as glance_code.png.
set -euo pipefail
# shellcheck source=ciq-env.sh
source "$(dirname "${BASH_SOURCE[0]}")/ciq-env.sh"
@@ -26,6 +28,34 @@ ciq_start_display
ciq_start_simulator
out="${BUILD_DIR}/screenshots"
+
+# A new launch starts in the glance; screenshot it before anything opens the app.
+shoot_glance() {
+ local device="$1" glance_log="${out}/$1/glance.log"
+ : >"${glance_log}"
+ monkeydo "${BUILD_DIR}/uitest/${device}.prg" "${device}" >>"${glance_log}" 2>&1 &
+ CIQ_MONKEYDO_PID=$!
+ local shown=0
+ for _ in $(seq 1 600); do
+ if grep -q "DIAG shown glance_code" "${glance_log}"; then
+ shown=1
+ break
+ fi
+ sleep 0.05
+ done
+ if ((shown == 0)); then
+ ciq_stop_app
+ log "${device}: the glance with the favourite's code didn't appear; see ${glance_log}"
+ return 1
+ fi
+ sleep 1
+ local status=0
+ python3 /work/tools/ui_flow.py --shot glance_code --device-dir "${CIQ_HOME}/Devices/${device}" \
+ --window "$(ciq_simulator_window)" --out "${out}/${device}" --golden "/work/test/golden/${device}" \
+ "${approve[@]}" || status=1
+ ciq_stop_app
+ return "${status}"
+}
mkdir -p "${out}"
approve=()
[[ "${APPROVE:-0}" == 1 ]] && approve=(--approve)
@@ -43,6 +73,7 @@ for device in "$@"; do
--window "$(ciq_simulator_window)" --out "${out}/${device}" --golden "/work/test/golden/${device}" \
"${approve[@]}" || failed=1
ciq_stop_app
+ shoot_glance "${device}" || failed=1
done
((failed == 0)) || die "screenshot checks failed; see build/screenshots/"