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) <noreply@anthropic.com>
This commit is contained in:
Michael 2026-04-25 01:57:40 +02:00
parent 1f59b384be
commit 625a2b72c7

View file

@ -18,8 +18,19 @@ MARKER="SMOKE_TEST_SERVER_$PORT"
pkill -f "$MARKER" 2>/dev/null || true pkill -f "$MARKER" 2>/dev/null || true
sleep 0.1 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" 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 " python3 -c "
import sys; sys.argv[0] = '$MARKER' import sys; sys.argv[0] = '$MARKER'
sys.path.insert(0, 'web') sys.path.insert(0, 'web')
@ -40,14 +51,17 @@ cleanup() {
} }
trap cleanup EXIT INT TERM 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 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 sleep 0.1
done done
# Wenn nicht erreichbar: Log ausgeben und fail # 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 "FAIL: Server nicht erreichbar auf Port $PORT"
echo "--- $LOG ---" echo "--- $LOG ---"
cat "$LOG" cat "$LOG"
@ -63,14 +77,26 @@ for p in "/" "/index.html" "/templates.json" \
"/templates/system/summarizer.json" \ "/templates/system/summarizer.json" \
"/templates/user/email_draft.md" \ "/templates/user/email_draft.md" \
"/templates/user/brainstorming.md"; do "/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" status="ok"
[ "$code" = "200" ] || { status="FAIL"; FAIL=1; } [ "$code" = "200" ] || { status="FAIL"; FAIL=1; }
printf '%-50s %s %s\n' "$p" "$code" "$status" printf '%-50s %s %s\n' "$p" "$code" "$status"
done 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 EXIT_CODE=$FAIL
if [ "$FAIL" -eq 0 ]; then 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 fi
exit $FAIL exit $FAIL