diff --git a/scripts/homepage-status.py b/scripts/homepage-status.py index 3e49f62..0bfdd87 100755 --- a/scripts/homepage-status.py +++ b/scripts/homepage-status.py @@ -11,6 +11,8 @@ import os import socket import sys import tempfile +import urllib.error +import urllib.request from datetime import datetime, timezone TIMEOUT = 5 # seconds, per probe (Q11 / Q40) @@ -18,6 +20,17 @@ TIMEOUT = 5 # seconds, per probe (Q11 / Q40) def probe(host, port, method="tcp"): """Return 'up' if the backend answers, else 'down'.""" + if method == "http": + try: + urllib.request.urlopen( + urllib.request.Request("http://%s:%d/" % (host, port)), + timeout=TIMEOUT, + ) + return "up" + except urllib.error.HTTPError: + return "up" # an HTTP response of any status means the backend is up + except Exception: + return "down" try: with socket.create_connection((host, port), timeout=TIMEOUT): return "up" diff --git a/tests/homepage_checker.bats b/tests/homepage_checker.bats index edf5090..cc461fb 100644 --- a/tests/homepage_checker.bats +++ b/tests/homepage_checker.bats @@ -19,6 +19,8 @@ setup() { teardown() { [ -n "${LISTENER_PID:-}" ] && kill "$LISTENER_PID" 2>/dev/null + [ -n "${RAW_PID:-}" ] && kill "$RAW_PID" 2>/dev/null + [ -n "${HTTP_PID:-}" ] && kill "$HTTP_PID" 2>/dev/null rm -rf "$TMP" } @@ -43,3 +45,46 @@ assert s["wip"] == "wip", s assert "generated_at" in d PY } + +@test "checker: http method — a non-HTTP listener is down, a real HTTP server is up" { + local svc="$TMP/services.json" out="$TMP/status.json" + local RAW_PORT=18903 HTTP_PORT=18904 + # A raw TCP listener that accepts connections but never speaks HTTP. + # Redirect its output so it cannot hold the test runner's stdout pipe open. + python3 - "$RAW_PORT" >/dev/null 2>&1 <<'PY' & +import socket, threading, time, sys +s = socket.socket() +s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) +s.bind(("127.0.0.1", int(sys.argv[1]))) +s.listen(5) +def hold(): + while True: + try: + c, _ = s.accept() + c.close() + except Exception: + break +threading.Thread(target=hold, daemon=True).start() +time.sleep(300) +PY + RAW_PID=$! + # A real HTTP server. + python3 -m http.server "$HTTP_PORT" --bind 127.0.0.1 >/dev/null 2>&1 & + HTTP_PID=$! + sleep 0.5 + cat > "$svc" </dev/null +}