diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-09-20 00:36:17 +0000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-09-20 00:36:17 +0000 |
| commit | 36a82d934366cc2ddbd92ee3885b1c547eeb8244 (patch) | |
| tree | 06b92cd5b00145ebb2f3faacb9fb1bacccf5fb27 /scripts/test-health-checks.sh | |
| parent | c58f7519936dc547ee2aec5bfbb1e477356656d9 (diff) | |
Fold the DB-ping health check in; delete the watchdog that never ran
scripts/health-watchdog.sh was written after the 2026-08-04 incident, where a
liveness stub stayed green for three days while every database-touching request
path was wedged. Its header says "Meant to run from cron every few minutes". It
was never scheduled — not in any unit, not in any crontab — so it has been dead
code since August, offering coverage it did not provide.
Its one real idea is worth keeping: /health pings the database and returns 503
when that fails, which the gateway route checks cannot see, because `/` answers
303 to the login page without going near the database.
check_app_health now does that poll (two attempts, five seconds apart, so a
single blip is not an outage), verify-deploy asserts it, and health-check
recovers from it by restarting the main service — the action the old watchdog
would have taken. The dead script is removed rather than left to imply cover.
Tests now 11, including a stub server returning 503 to prove a listening-but-
wedged app is caught.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018AwnALZL6bD4VBtATDVv3B
Diffstat (limited to 'scripts/test-health-checks.sh')
| -rwxr-xr-x | scripts/test-health-checks.sh | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/scripts/test-health-checks.sh b/scripts/test-health-checks.sh index fbe9e47..fa59d8b 100755 --- a/scripts/test-health-checks.sh +++ b/scripts/test-health-checks.sh @@ -121,6 +121,46 @@ else bad "subshell semantics" "array unexpectedly survived a subshell" fi +printf '=== check_app_health ===\n' + +# Unreachable app: must fail, not be mistaken for healthy. +APP_HEALTH_URL="http://127.0.0.1:9/health" +out=$(check_app_health); rc=$? +if [ $rc -ne 0 ] && printf '%s' "$out" | grep -q "app health"; then + ok "catches an unreachable app health endpoint" +else + bad "unreachable health endpoint" "rc=$rc out=$(printf '%s' "$out" | tr '\n' ' ')" +fi + +# A 503 is what /health returns when the database is unreachable — the app is +# listening and answering, so only this check can see it. +python3 - "$tmp/hport" <<'PY2' & +import http.server, socketserver, sys +class H(http.server.BaseHTTPRequestHandler): + def do_GET(self): + self.send_response(503); self.end_headers() + self.wfile.write(b"db unreachable") + def log_message(self, *a): pass +with socketserver.TCPServer(("127.0.0.1", 0), H) as s: + open(sys.argv[1], "w").write(str(s.server_address[1])) + s.serve_forever() +PY2 +hpid=$! +for _ in $(seq 1 50); do [ -s "$tmp/hport" ] && break; sleep 0.1; done +hport=$(cat "$tmp/hport" 2>/dev/null || echo "") +if [ -n "$hport" ]; then + APP_HEALTH_URL="http://127.0.0.1:${hport}/health" + out=$(check_app_health); rc=$? + if [ $rc -ne 0 ] && printf '%s' "$out" | grep -q "503"; then + ok "catches a listening app whose database ping fails (503)" + else + bad "503 db-ping detection" "rc=$rc out=$(printf '%s' "$out" | tr '\n' ' ')" + fi +else + bad "503 db-ping detection" "could not start stub server" +fi +kill "$hpid" 2>/dev/null; wait "$hpid" 2>/dev/null + printf '=== check_build_stamp ===\n' out=$(check_build_stamp "definitely-not-the-running-commit"); rc=$? |
