feat: scripts/smoke_test.sh + AGENTS.md R4 verankert
Ein Aufruf startet den Server temporaer auf eigenem Port, prueft alle bekannten Endpunkte und raeumt sich selbst auf. Agenten muessen nichts ueber Hintergrund-Jobs, nohup oder Port-Cleanup wissen. - scripts/smoke_test.sh: trap-basierter Cleanup, setsid-unabhaengig via prozessgruppen-fremdem pkill-Fallback, eindeutiger Marker-Name in sys.argv[0], 20x100ms Wartezeit aufs Port-Binding. - AGENTS.md R4: verweist statt auf manuelle curl-Aufrufe auf ./scripts/smoke_test.sh; TL;DR und Einstiegs-Block aktualisiert. Verifiziert: exit 0, Port nach Durchlauf frei (kein Leak). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7b471abbf0
commit
3f35cff338
2 changed files with 84 additions and 3 deletions
11
AGENTS.md
11
AGENTS.md
|
|
@ -8,7 +8,7 @@ Diese Datei richtet sich an **Coding-Agenten (Claude, Codex u.ä.), die in diese
|
|||
|
||||
1. Erst lesen (Zeilen der Zielstelle nennen), dann ändern.
|
||||
2. Erst ausführen, dann berichten. Prosa ohne Tool-Call ≠ Ausführung.
|
||||
3. UI-/Server-Änderung → Server starten + `curl` → Ergebnis zitieren.
|
||||
3. UI-/Server-Änderung → `./scripts/smoke_test.sh` → Ausgabe zitieren.
|
||||
4. Nach Refactor: `grep -c <name>` = 1. Sonst nicht fertig.
|
||||
5. Doku beschreibt Code, nicht die Arbeit am Code.
|
||||
|
||||
|
|
@ -41,12 +41,16 @@ Für jede angekündigte Änderung muss **mindestens eines** dieser Artefakte vor
|
|||
Fehlen diese Belege, ist die Aufgabe nicht erledigt — die Tool-Aufrufe absetzen und erneut prüfen.
|
||||
|
||||
### R4 – UI-/Server-Änderungen gegen das laufende System prüfen
|
||||
Bei Änderungen an `web/serve.py` oder `web/index.html`: Server starten, betroffene Endpunkte per `curl` testen, und das Ergebnis im Bericht **zitieren**. Beispiel:
|
||||
Bei Änderungen an `web/serve.py` oder `web/index.html`: führe den Smoke-Test aus und zitiere die Ausgabe im Bericht:
|
||||
|
||||
```bash
|
||||
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8081/templates.json
|
||||
./scripts/smoke_test.sh
|
||||
```
|
||||
|
||||
Das Skript startet den Server temporär auf einem eigenen Port (Default 8082), prüft alle bekannten Endpunkte und räumt sich selbst auf. Du musst nichts über Hintergrund-Jobs, `&`, `nohup` oder Port-Cleanup wissen. Exit-Code 0 = alle 200; sonst 1.
|
||||
|
||||
Für Änderungen, die der Smoke-Test nicht abdeckt (neuer Endpunkt, geänderte Response, JSON-Edit-Flow im Browser), zusätzlich gezielten `curl`-Aufruf oder Browser-Check ergänzen.
|
||||
|
||||
„Sieht korrekt aus" ohne ausgeführten Test zählt nicht.
|
||||
|
||||
### R5 – Nichts in die Doku schreiben, was nicht existiert
|
||||
|
|
@ -66,6 +70,7 @@ Ein Commit = eine logische Änderung. Commit-Message im Stil der bestehenden His
|
|||
|
||||
```bash
|
||||
python3 web/serve.py # startet Server auf http://localhost:8081
|
||||
./scripts/smoke_test.sh # temporärer Server + Endpunkt-Check + Cleanup (fuer R4)
|
||||
./scripts/cleanup_server.sh # beendet hängende Instanzen
|
||||
python3 scripts/validate.py # validiert Template-Struktur
|
||||
```
|
||||
|
|
|
|||
76
scripts/smoke_test.sh
Executable file
76
scripts/smoke_test.sh
Executable file
|
|
@ -0,0 +1,76 @@
|
|||
#!/bin/bash
|
||||
# Startet web/serve.py temporaer, testet die wichtigsten Endpunkte,
|
||||
# raeumt den Prozess auch bei Abbruch auf. Ein einziger Aufruf; der
|
||||
# Agent muss nichts ueber Hintergrund-Jobs wissen.
|
||||
#
|
||||
# Nutzung: ./scripts/smoke_test.sh # Port 8082
|
||||
# ./scripts/smoke_test.sh 9000 # anderer Port
|
||||
# Exit-Code: 0 = alle Endpunkte 200, sonst 1.
|
||||
|
||||
set -u
|
||||
PORT="${1:-8082}"
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
LOG="/tmp/smoke.$PORT.log"
|
||||
EXIT_CODE=1
|
||||
MARKER="SMOKE_TEST_SERVER_$PORT"
|
||||
|
||||
# Vorherige Instanzen dieses Smoke-Tests beenden
|
||||
pkill -f "$MARKER" 2>/dev/null || true
|
||||
sleep 0.1
|
||||
|
||||
# Server im Hintergrund starten (exec → $! ist der Python-Prozess)
|
||||
cd "$ROOT"
|
||||
python3 -c "
|
||||
import sys; sys.argv[0] = '$MARKER'
|
||||
sys.path.insert(0, 'web')
|
||||
import http.server, socketserver
|
||||
from serve import Handler
|
||||
port = $PORT
|
||||
print(f'Serving on http://localhost:{port}', flush=True)
|
||||
with socketserver.TCPServer(('', port), Handler) as httpd:
|
||||
httpd.serve_forever()
|
||||
" > "$LOG" 2>&1 &
|
||||
PID=$!
|
||||
cleanup() {
|
||||
kill "$PID" 2>/dev/null || true
|
||||
wait "$PID" 2>/dev/null || true
|
||||
# Defensiv: falls der Kill-Signal den Python-Prozess nicht trifft
|
||||
pkill -f "$MARKER" 2>/dev/null || true
|
||||
exit "$EXIT_CODE"
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
# Auf Port-Binding warten (max. 2s)
|
||||
for i in $(seq 1 20); do
|
||||
if curl -sf -o /dev/null "http://localhost:$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
|
||||
echo "FAIL: Server nicht erreichbar auf Port $PORT"
|
||||
echo "--- $LOG ---"
|
||||
cat "$LOG"
|
||||
EXIT_CODE=1
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Endpunkte testen
|
||||
FAIL=0
|
||||
for p in "/" "/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"; do
|
||||
code=$(curl -s -o /dev/null -w '%{http_code}' "http://localhost:$PORT$p")
|
||||
status="ok"
|
||||
[ "$code" = "200" ] || { status="FAIL"; FAIL=1; }
|
||||
printf '%-50s %s %s\n' "$p" "$code" "$status"
|
||||
done
|
||||
|
||||
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 ---"
|
||||
fi
|
||||
exit $FAIL
|
||||
Loading…
Add table
Reference in a new issue