Add bounded Panama recovery actions

This commit is contained in:
Gabriel Brown
2026-08-18 10:35:18 -04:00
parent d855a26bd9
commit 2cc109f5e1
6 changed files with 596 additions and 24 deletions
+83 -7
View File
@@ -75,15 +75,26 @@ fixture_dir="$(mktemp -d /tmp/panama-health.XXXXXX)"
helper="$fixture_dir/panama-doctor"
copy_bin="$fixture_dir/bin"
copy_file="$fixture_dir/copied-report.json"
repair_mode_file="$fixture_dir/repair-mode"
repair_log="$fixture_dir/repair.log"
notification_log="$fixture_dir/notifications.log"
printf 'success\n' >"$repair_mode_file"
printf '%s\n' \
'#!/usr/bin/env bash' \
'printf "%s\n" "$*" >>"$PANAMA_HEALTH_REPAIR_LOG"' \
'if [[ "$1" == "--json" ]]; then' \
' sleep 0.2' \
" printf '%s\\n' '$warning_snapshot'" \
' exit 0' \
'fi' \
'if [[ "$1" == "--repair" && "$2" == "panama.caffeine" && "$3" == "--json" ]]; then' \
' exit 0' \
' sleep 0.25' \
' case "$(cat "$PANAMA_HEALTH_REPAIR_MODE_FILE")" in' \
' success) printf "{\"schemaVersion\":1,\"checkId\":\"panama.caffeine\",\"accepted\":true,\"exitCode\":0,\"message\":\"Duplicate inhibitors were released.\"}\\n"; exit 0 ;;' \
' failed) printf "{\"schemaVersion\":1,\"checkId\":\"panama.caffeine\",\"accepted\":true,\"exitCode\":7,\"message\":\"Duplicate inhibitors could not be released.\"}\\n"; exit 7 ;;' \
' mismatch) printf "{\"schemaVersion\":1,\"checkId\":\"desktop.vicinae\",\"accepted\":true,\"exitCode\":0,\"message\":\"Wrong row.\"}\\n"; exit 0 ;;' \
' *) printf "not-json\\n"; exit 0 ;;' \
' esac' \
'fi' \
'exit 2' >"$helper"
chmod +x "$helper"
@@ -91,9 +102,16 @@ mkdir -p "$copy_bin"
printf '%s\n' \
'#!/usr/bin/env bash' \
'/usr/bin/cat > "$PANAMA_HEALTH_COPY_FILE"' >"$copy_bin/wl-copy"
chmod +x "$copy_bin/wl-copy"
printf '%s\n' \
'#!/usr/bin/env bash' \
'printf "%s\n" "$*" >>"$PANAMA_HEALTH_NOTIFICATION_LOG"' >"$copy_bin/notify-send"
chmod +x "$copy_bin/wl-copy" "$copy_bin/notify-send"
run() { PATH="$copy_bin:$PATH" PANAMA_HEALTH_HELPER="$helper" PANAMA_HEALTH_COPY_FILE="$copy_file" qs -p "$harness" "$@"; }
run() {
PATH="$copy_bin:$PATH" PANAMA_HEALTH_HELPER="$helper" PANAMA_HEALTH_COPY_FILE="$copy_file" \
PANAMA_HEALTH_REPAIR_MODE_FILE="$repair_mode_file" PANAMA_HEALTH_REPAIR_LOG="$repair_log" \
PANAMA_HEALTH_NOTIFICATION_LOG="$notification_log" qs -p "$harness" "$@"
}
harness_pid=""
cleanup() {
@@ -103,6 +121,8 @@ cleanup() {
trap cleanup EXIT
PATH="$copy_bin:$PATH" PANAMA_HEALTH_HELPER="$helper" PANAMA_HEALTH_COPY_FILE="$copy_file" \
PANAMA_HEALTH_REPAIR_MODE_FILE="$repair_mode_file" PANAMA_HEALTH_REPAIR_LOG="$repair_log" \
PANAMA_HEALTH_NOTIFICATION_LOG="$notification_log" \
qs -p "$harness" --daemonize >/dev/null
for _ in $(seq 1 40); do
run ipc show 2>/dev/null | rg -q '^target health-test$' && break
@@ -165,25 +185,81 @@ done
jq -e '.busy == false and .generation == ($before + 2) and .queuedRefresh == false' --argjson before "$before_generation" \
>/dev/null <<<"$state" || fail "queued refresh did not run exactly once: $state"
printf 'success\n' >"$repair_mode_file"
repair_generation="$(jq -r .generation <<<"$state")"
[[ "$(run ipc call health-test repair panama.caffeine)" == "true" ]] \
|| fail 'repairable check was refused'
run ipc call health-test queue >/dev/null
working_state="$(run ipc call health-test status)"
jq -e '.repairingId == "panama.caffeine" and .queuedRefresh == true
and (.checkStates[] | select(.id == "panama.caffeine") | .status) == "warning"' \
>/dev/null <<<"$working_state" || fail "repair did not retain the degraded row while working: $working_state"
for _ in $(seq 1 120); do
state="$(run ipc call health-test status)"
jq -e '.busy == false and .generation == ($before + 3)' --argjson before "$before_generation" \
jq -e '.busy == false and .generation == ($before + 1) and .queuedRefresh == false' --argjson before "$repair_generation" \
>/dev/null <<<"$state" && break
sleep 0.1
done
jq -e '.busy == false and .generation == ($before + 3)' --argjson before "$before_generation" \
>/dev/null <<<"$state" || fail "accepted repair did not trigger one rescan: $state"
jq -e '.busy == false and .generation == ($before + 1) and .queuedRefresh == false
and .lastRepair == {schemaVersion:1, checkId:"panama.caffeine", accepted:true, exitCode:0, message:"Duplicate inhibitors were released."}
and (.checkStates[] | select(.id == "panama.caffeine") | .status) == "warning"' \
--argjson before "$repair_generation" >/dev/null <<<"$state" \
|| fail "accepted repair was trusted before exactly one observed rescan: $state"
# A syntactically valid command failure remains inline for Settings and still
# receives exactly one observed rescan.
printf 'failed\n' >"$repair_mode_file"
failure_generation="$(jq -r .generation <<<"$state")"
[[ "$(run ipc call health-test repair panama.caffeine)" == "true" ]] \
|| fail 'second repairable check was refused'
for _ in $(seq 1 120); do
state="$(run ipc call health-test status)"
jq -e '.busy == false and .generation == ($before + 1)' --argjson before "$failure_generation" \
>/dev/null <<<"$state" && break
sleep 0.1
done
jq -e '.lastRepair.checkId == "panama.caffeine"
and .lastRepair.accepted == true and .lastRepair.exitCode == 7
and .lastRepair.message == "Duplicate inhibitors could not be released."
and .generation == ($before + 1)' --argjson before "$failure_generation" \
>/dev/null <<<"$state" || fail "known repair failure was not retained inline: $state"
[[ ! -e "$notification_log" || ! -s "$notification_log" ]] \
|| fail 'Settings-originated repair emitted an external notification'
# A malformed or mismatched helper response is contained and cannot masquerade
# as recovery; it also schedules only one scan.
printf 'mismatch\n' >"$repair_mode_file"
mismatch_generation="$(jq -r .generation <<<"$state")"
[[ "$(run ipc call health-test repair panama.caffeine)" == "true" ]] \
|| fail 'mismatch repair fixture was refused'
for _ in $(seq 1 120); do
state="$(run ipc call health-test status)"
jq -e '.busy == false and .generation == ($before + 1)' --argjson before "$mismatch_generation" \
>/dev/null <<<"$state" && break
sleep 0.1
done
jq -e '.lastRepair.checkId == "panama.caffeine" and .lastRepair.accepted == false
and .lastRepair.exitCode == 0 and .generation == ($before + 1)' \
--argjson before "$mismatch_generation" >/dev/null <<<"$state" \
|| fail "mismatched repair JSON escaped containment: $state"
[[ "$(run ipc call health-test repair unknown.check)" == "false" ]] \
|| fail 'unknown check started a repair'
[[ "$(run ipc call health-test repair integration.calendar)" == "false" ]] \
|| fail 'non-repairable check started a repair'
state="$(run ipc call health-test status)"
jq -e '.repairingId == "" and .generation == ($before + 3)' --argjson before "$before_generation" \
jq -e '.repairingId == "" and .generation == ($before + 1)' --argjson before "$mismatch_generation" \
>/dev/null <<<"$state" || fail "rejected repair altered process state: $state"
python3 - "$service" <<'PY' || fail 'external repair failure notification is not bounded'
import sys
source = open(sys.argv[1], encoding="utf-8").read()
assert 'if (failed && external && !failureNotification.running)' in source
assert '"notify-send", "-a", "Panama", "-i", "dialog-error-symbolic"' in source
assert '"Panama action failed", "The requested health repair could not be completed."' in source
PY
trap - EXIT
cleanup
printf 'health service contract: PASS\n'