#!/usr/bin/env bats # Seam: scripts/homepage-status.py # Given a service config, the checker writes a valid status.json with the # correct state per service: an open port is up, a closed port is down, # a wip service is not probed and takes the state of its wip value # (wip-open / wip-closed). The output carries generated_at. load helpers setup() { CHECKER="$REPO_ROOT/scripts/homepage-status.py" TMP="$(mktemp -d)" UP_PORT=18899 DOWN_PORT=18900 # Hold a TCP listener on UP_PORT so a probe of it succeeds. python3 -c 'import socket,time; s=socket.socket(); s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1); s.bind(("127.0.0.1",'"$UP_PORT"')); s.listen(5); time.sleep(300)' & LISTENER_PID=$! sleep 0.5 } 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" } @test "checker: open port is up, closed port is down, wip is wip-open / wip-closed" { local svc="$TMP/services.json" out="$TMP/status.json" cat > "$svc" </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 } @test "the checker writes status.json world-readable so Caddy can serve it" { local svc="$TMP/services.json" out="$TMP/status.json" echo '[{"name":"x","category":"user","probe":"127.0.0.1:1","method":"tcp","wip":"closed"}]' > "$svc" python3 "$CHECKER" "$svc" "$out" [ "$(stat -c %a "$out")" = "644" ] }