From 625a2b72c75e1148497c19eb22479a0875c5fb0e Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 25 Apr 2026 01:57:40 +0200 Subject: [PATCH] fix: smoke_test - Pre-Compile-Gate, Connect-Timeout, JSON-Inhalts-Check Drei Maskierungs-Bugs: kaputtes serve.py liess curl auf localhost auf einen unbenutzten Port unter WSL2 ~2 min pro Iteration haengen (Polling-Loop bis 40 min); status-only-Tests sahen ein zerschossenes templates.json nicht. - python3 -m py_compile vor Server-Start: Syntax-Fehler scheitern in <100ms mit klarer Meldung statt nach 22s Timeout-Polling. - 127.0.0.1 + --connect-timeout 1 ersetzt localhost-Polling: umgeht Resolver/IPv6-Falle, kappt jeden Versuch nach 1s. - Endpoint-curls bekommen --max-time 5: ein einzelner haengender Endpunkt killt nicht mehr die Suite. - Inhalts-Gate prueft nach den 8 HTTP-Checks, dass /templates.json parsable JSON ist - Pseudo-Fix-Schutz (kaputtes Manifest = HTTP 200 + JSON.parse stirbt im Frontend). Co-Authored-By: Claude Opus 4.7 (1M context) --- scripts/smoke_test.sh | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/scripts/smoke_test.sh b/scripts/smoke_test.sh index 0f28977..f17d920 100755 --- a/scripts/smoke_test.sh +++ b/scripts/smoke_test.sh @@ -18,8 +18,19 @@ MARKER="SMOKE_TEST_SERVER_$PORT" pkill -f "$MARKER" 2>/dev/null || true sleep 0.1 -# Server im Hintergrund starten (exec → $! ist der Python-Prozess) +# Pre-Check: serve.py muss sich kompilieren lassen. Sonst stirbt der +# Server beim Import und das Polling unten wartet umsonst — wir wollen +# in <100ms mit klarer Fehlermeldung scheitern, nicht in 22s mit +# "Server nicht erreichbar". cd "$ROOT" +if ! python3 -m py_compile web/serve.py 2> "$LOG"; then + echo "FAIL: web/serve.py hat Syntax-/Indent-Fehler" + echo "--- $LOG ---" + cat "$LOG" + exit 1 +fi + +# Server im Hintergrund starten (exec → $! ist der Python-Prozess) python3 -c " import sys; sys.argv[0] = '$MARKER' sys.path.insert(0, 'web') @@ -40,14 +51,17 @@ cleanup() { } trap cleanup EXIT INT TERM -# Auf Port-Binding warten (max. 2s) +# Auf Port-Binding warten (max. 2s). +# 127.0.0.1 statt localhost umgeht den Resolver — sonst kann unter +# WSL2/IPv6 ein TCP-SYN auf einen unbenutzten Port minutenlang ohne +# RST hängen. --connect-timeout 1 ist Defense-in-Depth. for i in $(seq 1 20); do - if curl -sf -o /dev/null "http://localhost:$PORT/"; then break; fi + if curl -sf --connect-timeout 1 -o /dev/null "http://127.0.0.1:$PORT/"; then break; fi sleep 0.1 done # Wenn nicht erreichbar: Log ausgeben und fail -if ! curl -sf -o /dev/null "http://localhost:$PORT/"; then +if ! curl -sf --connect-timeout 1 -o /dev/null "http://127.0.0.1:$PORT/"; then echo "FAIL: Server nicht erreichbar auf Port $PORT" echo "--- $LOG ---" cat "$LOG" @@ -63,14 +77,26 @@ for p in "/" "/index.html" "/templates.json" \ "/templates/system/summarizer.json" \ "/templates/user/email_draft.md" \ "/templates/user/brainstorming.md"; do - code=$(curl -s -o /dev/null -w '%{http_code}' "http://localhost:$PORT$p") + code=$(curl -s --max-time 5 -o /dev/null -w '%{http_code}' "http://127.0.0.1:$PORT$p") status="ok" [ "$code" = "200" ] || { status="FAIL"; FAIL=1; } printf '%-50s %s %s\n' "$p" "$code" "$status" done +# Inhalts-Gate: templates.json muss valides JSON sein. Ohne diese +# Pruefung kann ein "Fix" das Manifest zerschiessen, der Server liefert +# es weiterhin mit HTTP 200 aus, das Frontend stirbt aber beim +# JSON.parse. Status-only-Tests sehen das nicht. +if [ "$FAIL" -eq 0 ]; then + if ! curl -s --max-time 5 "http://127.0.0.1:$PORT/templates.json" \ + | python3 -c 'import json,sys; json.load(sys.stdin)' 2>/dev/null; then + echo "FAIL: /templates.json ist kein gueltiges JSON" + FAIL=1 + fi +fi + EXIT_CODE=$FAIL if [ "$FAIL" -eq 0 ]; then - echo "--- alle $( (echo "/" "/index.html" "/templates.json" "/templates/system/commit_analysis.json" "/templates/system/code_reviewer.json" "/templates/system/summarizer.json" "/templates/user/email_draft.md" "/templates/user/brainstorming.md") | wc -w ) Endpunkte OK ---" + echo "--- alle 8 Endpunkte OK + templates.json valide ---" fi exit $FAIL