mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 18:07:06 +01:00
Location/curfew goes to daemon_location.sh, the derived state files to daemon_state.sh, the app layer to daemon_apps.sh. All 23 functions moved verbatim -- nothing restructured, which matters more here than anywhere else in this session. focus_daemon.sh has five `while IFS= read -r pkg; do ... done <file` loops and EVERY body calls pm. Piping any of them in lets pm inherit and drain the loop's stdin, so it would process one package instead of all of them -- measured elsewhere in this repo as 1 of 54. That audit ran BEFORE the extraction, not after coverage came back short, and all five moved untouched with a note above them saying why. CURRENT_MODE and _CURFEW_TICK_CACHED are each written in both the entry script and a library, so both stay declared with main, same call as NET_BUILT in the curfew split. 110 assertions and 33 mutations, all killed. Two survived the first run and both were defects in my own tests: the whitelist and sysprotect exactness checks used a SUPERSTRING of a listed entry, which fails under grep -qF and grep -qxF alike and so proved nothing about which was in use. Two subjects are NOT at 100%, and the numbers are reported as measured: daemon_state.sh 67/67 = 100.00% daemon_location.sh 26/40 = 65.00% daemon_apps.sh 71/76 = 93.42% Both shortfalls are kcov attribution failures, shown to be artifacts rather than gaps. daemon_location.sh's missing lines are all inside the embedded awk Haversine; mutating the Earth radius and dropping the longitude term both fail the suite, and an isolated probe shows a one-line awk measuring 100% where the identical multi-line one measures 0%. Collapsing the formula to satisfy the tool would cost the readability of the only real mathematics in the repo, so it stays. daemon_apps.sh's five are the trailing `done <file` of the very loops described above. That is the same artifact piping fixed in curfew_net.sh, and it is exactly what must NOT be done here. Redirecting two of them from /dev/null fails the suite, so the lines run; all three are pinned in the mutation spec instead. Over-cap count 19 -> 18. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
229 lines
7.7 KiB
Bash
Executable File
229 lines
7.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# lib/tests/daemon_cases_location.sh — assertions for daemon_location.sh: the
|
|
# GPS fix, the Haversine distance, and the night-curfew window.
|
|
#
|
|
# Sourced by test_daemon_libs.sh after daemon_libs_harness.sh, which owns the
|
|
# stubs, the subjects and the PASS/FAIL counters this file adds to.
|
|
#
|
|
# The curfew window wraps past midnight (2300 -> 0500), which is the case a
|
|
# naive start<=now<end comparison gets exactly backwards: it would report
|
|
# curfew during the whole day and never at night.
|
|
set -euo pipefail
|
|
|
|
# --- get_location -----------------------------------------------------------
|
|
|
|
_reset_dev
|
|
_t_eq "" "$(get_location)" "location is empty when dumpsys reports no fix"
|
|
|
|
printf 'last location=Location[fused 52.2297,21.0122 hAcc=12]\n' >"${DEV}/dumpsys_out"
|
|
_t_eq "52.2297,21.0122" "$(get_location)" "location extracts a fused coordinate pair"
|
|
|
|
# Several fixes in one dump: the first is the freshest and the only one used.
|
|
printf 'Location[fused 52.2297,21.0122]\nLocation[gps 50.0000,19.0000]\n' >"${DEV}/dumpsys_out"
|
|
_t_eq "52.2297,21.0122" "$(get_location)" "location takes only the first fix"
|
|
|
|
# Too few decimal places is not a real fix and must not be matched, or the
|
|
# daemon would compute a distance from a truncated coordinate.
|
|
printf 'Location[fused 52.22,21.01]\n' >"${DEV}/dumpsys_out"
|
|
_t_eq "" "$(get_location)" "location ignores coordinates with too little precision"
|
|
|
|
printf 'Location[fused -33.8688,151.2093]\n' >"${DEV}/dumpsys_out"
|
|
_t_eq "-33.8688,151.2093" "$(get_location)" "location handles southern/negative coordinates"
|
|
|
|
# --- calc_distance ----------------------------------------------------------
|
|
|
|
_t_eq "0" "$(calc_distance 52.2297 21.0122 52.2297 21.0122)" \
|
|
"distance from a point to itself is zero"
|
|
|
|
# Warsaw to Krakow is ~252 km. A wrong radius or a degrees/radians slip shows
|
|
# up here as an answer off by orders of magnitude, not a rounding difference.
|
|
km="$(( $(calc_distance 52.2297 21.0122 50.0647 19.9450) / 1000 ))"
|
|
if [[ "${km}" -ge 245 && "${km}" -le 260 ]]; then
|
|
_t_pass "distance Warsaw-Krakow is ~252 km (got ${km} km)"
|
|
else
|
|
_t_fail "distance Warsaw-Krakow should be ~252 km, got ${km} km"
|
|
fi
|
|
|
|
# One degree of latitude is ~111 km anywhere on the globe.
|
|
deg="$(calc_distance 0 0 1 0)"
|
|
if [[ "${deg}" -ge 110000 && "${deg}" -le 112000 ]]; then
|
|
_t_pass "one degree of latitude is ~111 km (got ${deg} m)"
|
|
else
|
|
_t_fail "one degree of latitude should be ~111 km, got ${deg} m"
|
|
fi
|
|
|
|
# Symmetry: the distance cannot depend on which point is called home.
|
|
_t_eq "$(calc_distance 52.2297 21.0122 50.0647 19.9450)" \
|
|
"$(calc_distance 50.0647 19.9450 52.2297 21.0122)" \
|
|
"distance is symmetric"
|
|
|
|
# A short hop must still register, since the geofence threshold is ~100 m.
|
|
near="$(calc_distance 52.2297 21.0122 52.2306 21.0122)"
|
|
if [[ "${near}" -ge 80 && "${near}" -le 120 ]]; then
|
|
_t_pass "a 0.0009 degree step is ~100 m (got ${near} m)"
|
|
else
|
|
_t_fail "a 0.0009 degree step should be ~100 m, got ${near} m"
|
|
fi
|
|
|
|
# --- _dec -------------------------------------------------------------------
|
|
|
|
# Zero-padded times must not be read as octal: "0830" as octal is invalid and
|
|
# would abort the comparison, stranding the daemon on the wrong app list.
|
|
_t_eq "830" "$(_dec 0830)" "_dec strips the leading zero from 0830"
|
|
_t_eq "500" "$(_dec 0500)" "_dec strips the leading zero from 0500"
|
|
_t_eq "0" "$(_dec 0000)" "_dec keeps a single digit for midnight"
|
|
_t_eq "2300" "$(_dec 2300)" "_dec leaves an unpadded time alone"
|
|
_t_eq "9" "$(_dec 0009)" "_dec strips several leading zeros"
|
|
|
|
# --- is_curfew_now, wrapping window (2300 -> 0500) --------------------------
|
|
|
|
_reset_dev
|
|
NIGHT_CURFEW_START="2300"
|
|
NIGHT_CURFEW_END="0500"
|
|
|
|
for t in 2300 2359 0000 0430; do
|
|
_set_now "${t}"
|
|
if is_curfew_now; then
|
|
_t_pass "curfew is open at ${t} inside the wrapping window"
|
|
else
|
|
_t_fail "curfew should be open at ${t}"
|
|
fi
|
|
done
|
|
|
|
for t in 0500 1200 2259; do
|
|
_set_now "${t}"
|
|
if ! is_curfew_now; then
|
|
_t_pass "curfew is closed at ${t} outside the wrapping window"
|
|
else
|
|
_t_fail "curfew should be closed at ${t}"
|
|
fi
|
|
done
|
|
|
|
# --- is_curfew_now, non-wrapping window -------------------------------------
|
|
|
|
NIGHT_CURFEW_START="0900"
|
|
NIGHT_CURFEW_END="1700"
|
|
|
|
_set_now "1200"
|
|
if is_curfew_now; then
|
|
_t_pass "curfew is open midway through a same-day window"
|
|
else
|
|
_t_fail "curfew should be open at 1200 for a 0900-1700 window"
|
|
fi
|
|
|
|
_set_now "0900"
|
|
if is_curfew_now; then
|
|
_t_pass "a same-day window includes its start minute"
|
|
else
|
|
_t_fail "0900 should be inside a 0900-1700 window"
|
|
fi
|
|
|
|
# The end is exclusive, or two adjacent windows would both claim the boundary.
|
|
_set_now "1700"
|
|
if ! is_curfew_now; then
|
|
_t_pass "a same-day window excludes its end minute"
|
|
else
|
|
_t_fail "1700 should be outside a 0900-1700 window"
|
|
fi
|
|
|
|
_set_now "0800"
|
|
if ! is_curfew_now; then
|
|
_t_pass "curfew is closed before a same-day window opens"
|
|
else
|
|
_t_fail "0800 should be outside a 0900-1700 window"
|
|
fi
|
|
|
|
NIGHT_CURFEW_START="2300"
|
|
NIGHT_CURFEW_END="0500"
|
|
# Read back so the reset has a reader in this file (SC2034); the subject is
|
|
# what actually consumes it, but each file is linted standalone.
|
|
_t_eq "2300-0500" "${NIGHT_CURFEW_START}-${NIGHT_CURFEW_END}" \
|
|
"the wrapping window is restored for the remaining cases"
|
|
|
|
# A broken clock must fail OPEN — to the day list, not the strict one.
|
|
_set_now "not-a-time"
|
|
if ! is_curfew_now; then
|
|
_t_pass "a malformed clock reads as no curfew rather than permanent curfew"
|
|
else
|
|
_t_fail "a malformed clock must not enable the curfew"
|
|
fi
|
|
|
|
_set_now ""
|
|
if ! is_curfew_now; then
|
|
_t_pass "an empty clock reading reads as no curfew"
|
|
else
|
|
_t_fail "an empty clock must not enable the curfew"
|
|
fi
|
|
|
|
# --- curfew_active ----------------------------------------------------------
|
|
|
|
_reset_dev
|
|
_set_now "0000"
|
|
if curfew_active; then
|
|
_t_pass "curfew is active inside the window when enabled"
|
|
else
|
|
_t_fail "curfew should be active at 0000 when enabled"
|
|
fi
|
|
|
|
_reset_dev
|
|
_set_now "1200"
|
|
if ! curfew_active; then
|
|
_t_pass "curfew is inactive outside the window"
|
|
else
|
|
_t_fail "curfew should be inactive at 1200"
|
|
fi
|
|
|
|
# The force file is the test hook: it opens curfew regardless of the clock.
|
|
_reset_dev
|
|
_set_now "1200"
|
|
touch "${CURFEW_FORCE_FILE}"
|
|
if curfew_active; then
|
|
_t_pass "the force file opens curfew outside the window"
|
|
else
|
|
_t_fail "the force file should open curfew regardless of the clock"
|
|
fi
|
|
|
|
# The override must beat the force file, or there is no way out.
|
|
_reset_dev
|
|
touch "${CURFEW_OVERRIDE_FILE}"
|
|
_set_now "0000"
|
|
if ! curfew_active; then
|
|
_t_pass "the override file closes curfew even when forced"
|
|
else
|
|
_t_fail "the override must take precedence over the force file"
|
|
fi
|
|
rm -f "${CURFEW_OVERRIDE_FILE}" "${CURFEW_FORCE_FILE}"
|
|
|
|
_reset_dev
|
|
NIGHT_CURFEW_ENABLED=0
|
|
_set_now "0000"
|
|
if ! curfew_active; then
|
|
_t_pass "curfew is inactive while the feature is disabled"
|
|
else
|
|
_t_fail "curfew must be inactive when NIGHT_CURFEW_ENABLED is 0"
|
|
fi
|
|
NIGHT_CURFEW_ENABLED=1
|
|
_t_eq "1" "${NIGHT_CURFEW_ENABLED}" \
|
|
"the curfew is re-enabled for the memo cases"
|
|
|
|
# The memo exists to stop is_curfew_now forking `date` once per package in
|
|
# the sweep. Proven by moving the clock and requiring the answer not to move.
|
|
_reset_dev
|
|
_set_now "0000"
|
|
curfew_active
|
|
_set_now "1200"
|
|
if curfew_active; then
|
|
_t_pass "curfew_active answers from the per-tick memo, not the clock"
|
|
else
|
|
_t_fail "the memo should hold within a tick even as the clock moves"
|
|
fi
|
|
|
|
# Clearing the memo is what main does each tick; the answer must then follow
|
|
# the clock again, or a curfew could never end.
|
|
_CURFEW_TICK_CACHED=""
|
|
if ! curfew_active; then
|
|
_t_pass "clearing the memo lets the answer follow the clock again"
|
|
else
|
|
_t_fail "a cleared memo must be recomputed"
|
|
fi
|