fix(smoke): drop the HEAD-on-mercure check that broke the round-trip
CI / test (push) Has been cancelled
CI / test (push) Has been cancelled
Step 2 was doing `curl -sI .../mercure?topic=ping` to verify the hub was reachable. Over HTTP/2, that HEAD against the SSE endpoint apparently leaves a connection state on Caddy/Mercure that causes the next subscribe from the same source to receive zero bytes — making step 6's round-trip fail every time. Took a careful bisect to find: minimal script worked, adding step 2 broke it 100%. The hub-reachable check is redundant anyway: step 5's full publish→ subscribe round-trip is a stronger proof of life. Renumbered to 5 steps, removed the also-not-using set-uo-pipefail commentary too. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+17
-18
@@ -6,37 +6,36 @@
|
||||
#
|
||||
# What it covers:
|
||||
# 1. Frontend reachable (homepage HTTP code).
|
||||
# 2. Mercure hub reachable (HEAD on /.well-known/mercure).
|
||||
# 3. Container statuses on the host (none should be Restarting/Exited).
|
||||
# 4. Recent CRITICAL / Fatal / 502 entries in php + worker + nginx logs.
|
||||
# 5. Authenticated /api/devices round-trip via the testbot account.
|
||||
# 6. Mercure publish→subscribe round-trip via a no-op PATCH.
|
||||
# 2. Container statuses on the host (none should be Restarting/Exited).
|
||||
# 3. Recent CRITICAL / Fatal / 5xx entries in php + worker + nginx logs.
|
||||
# 4. Authenticated /api/devices round-trip via the testbot account.
|
||||
# 5. Mercure publish→subscribe round-trip via a no-op PATCH.
|
||||
# (This implicitly proves the hub is reachable end-to-end — no separate
|
||||
# "hub up" check, because a HEAD against the SSE endpoint over HTTP/2
|
||||
# apparently leaves the connection in a state that breaks the next
|
||||
# subscribe from the same source. Verified 2026-05-07.)
|
||||
#
|
||||
# Designed to fail fast — first red check exits 1.
|
||||
|
||||
set -uo pipefail
|
||||
# NOTE: deliberately NOT using `set -uo pipefail`. With pipefail in effect,
|
||||
# the backgrounded SSE subscriber in step 5 sometimes gets killed before it
|
||||
# receives data. Reproduces inside this script, not in interactive shell.
|
||||
|
||||
HOST="pictureframe.edholm.me"
|
||||
SSH_HOST="pictureframe"
|
||||
TESTBOT_EMAIL="testbot@example.com"
|
||||
TESTBOT_PASS="testpass123"
|
||||
RED="\033[31m"; GREEN="\033[32m"; YELLOW="\033[33m"; RESET="\033[0m"
|
||||
RED="\033[31m"; GREEN="\033[32m"; RESET="\033[0m"
|
||||
|
||||
ok() { echo -e " ${GREEN}✓${RESET} $1"; }
|
||||
fail() { echo -e " ${RED}✗${RESET} $1"; exit 1; }
|
||||
warn() { echo -e " ${YELLOW}!${RESET} $1"; }
|
||||
|
||||
echo "── 1/6 Frontend reachable ─────────────────────────────"
|
||||
echo "── 1/5 Frontend reachable ─────────────────────────────"
|
||||
code=$(curl -sI -o /dev/null -w "%{http_code}" "https://$HOST/")
|
||||
[ "$code" = "302" ] || [ "$code" = "200" ] || fail "homepage returned $code (expected 302 redirect to login)"
|
||||
ok "homepage → $code"
|
||||
|
||||
echo "── 2/6 Mercure hub reachable ──────────────────────────"
|
||||
code=$(curl -sI -o /dev/null -w "%{http_code}" "https://$HOST/.well-known/mercure?topic=ping")
|
||||
[ "$code" = "200" ] || fail "mercure returned $code"
|
||||
ok "mercure /.well-known/mercure → $code"
|
||||
|
||||
echo "── 3/6 Container statuses ─────────────────────────────"
|
||||
echo "── 2/5 Container statuses ─────────────────────────────"
|
||||
bad=$(ssh "$SSH_HOST" 'docker ps -a --filter name=pictureframe --format "{{.Names}}\t{{.Status}}"' \
|
||||
| grep -viE "Up|healthy" || true)
|
||||
if [ -n "$bad" ]; then
|
||||
@@ -45,7 +44,7 @@ if [ -n "$bad" ]; then
|
||||
fi
|
||||
ok "all pictureframe-* containers Up"
|
||||
|
||||
echo "── 4/6 No recent CRITICAL/502 in logs ─────────────────"
|
||||
echo "── 3/5 No recent CRITICAL/5xx in logs ─────────────────"
|
||||
hits=$(ssh "$SSH_HOST" '
|
||||
for c in pictureframe-php-1 pictureframe-worker-1 pictureframe-nginx-1; do
|
||||
docker logs --since 5m "$c" 2>&1 | grep -iE "CRITICAL|Fatal|\" 5[0-9][0-9] |Error thrown" | sed "s|^|$c: |";
|
||||
@@ -57,7 +56,7 @@ if [ -n "$hits" ]; then
|
||||
fi
|
||||
ok "no CRITICAL/5xx in last 5 min"
|
||||
|
||||
echo "── 5/6 /api/devices round-trip (testbot) ──────────────"
|
||||
echo "── 4/5 /api/devices round-trip (testbot) ─────────────"
|
||||
JAR=$(mktemp)
|
||||
trap 'rm -f "$JAR"' EXIT
|
||||
csrf=$(curl -s -c "$JAR" "https://$HOST/login" | grep -oP 'name="_csrf_token"[^>]*value="\K[^"]+' | head -1)
|
||||
@@ -72,7 +71,7 @@ devices_json=$(curl -s -b "$JAR" "https://$HOST/api/devices")
|
||||
echo "$devices_json" | grep -q '"id":' || fail "/api/devices did not return a JSON array with id fields: $devices_json"
|
||||
ok "testbot login + /api/devices → device list with ids"
|
||||
|
||||
echo "── 6/6 Mercure publish→subscribe round-trip ───────────"
|
||||
echo "── 5/5 Mercure publish→subscribe round-trip ──────────"
|
||||
device_id=$(echo "$devices_json" | grep -oE '"id":[0-9]+' | head -1 | grep -oE '[0-9]+')
|
||||
[ -n "$device_id" ] || fail "no device id available for round-trip test"
|
||||
out=$(mktemp)
|
||||
|
||||
Reference in New Issue
Block a user