diff --git a/scripts/glasspane-stress-test.sh b/scripts/glasspane-stress-test.sh new file mode 100755 index 0000000..879d4a4 --- /dev/null +++ b/scripts/glasspane-stress-test.sh @@ -0,0 +1,79 @@ +#!/bin/sh +# Glasspane stress test — concurrent agent spawn + state tracking. +# Requires: colibri-daemon running, python3.11, root (for nc to socket) +set -eu + +SOCKET="${COLIBRI_SOCKET:-/var/run/colibri/colibri.sock}" +PASS=0 +FAIL=0 +NC="mdo -u root nc -U $SOCKET -w 5" + +assert_pane_count() { + _desc="$1"; _expected="$2" + _json=$(printf '{"cmd":"glasspane-snapshot"}\n' | timeout 5 $NC 2>/dev/null | tail -1) + _count=$(echo "$_json" | python3.11 -c "import json,sys;print(len(json.load(sys.stdin)['data']['panes']))" 2>/dev/null || echo "0") + if [ "$_count" -ge "$_expected" ]; then + echo " PASS: $_desc → $_count panes" + PASS=$((PASS + 1)) + else + echo " FAIL: $_desc (expected >= $_expected, got $_count)" + FAIL=$((FAIL + 1)) + fi +} + +assert_states_contain() { + _desc="$1"; shift + _json=$(printf '{"cmd":"glasspane-snapshot"}\n' | timeout 5 $NC 2>/dev/null | tail -1) + _states=$(echo "$_json" | python3.11 -c "import json,sys;d=json.load(sys.stdin)['data'];print(','.join(p['state'] for p in d['panes']))" 2>/dev/null || echo "ERROR") + for _exp in "$@"; do + case "$_states" in + *"$_exp"*) + echo " PASS: $_desc → $_states" + PASS=$((PASS + 1)) + return + ;; + esac + done + echo " FAIL: $_desc (expected one of: $*, got $_states)" + FAIL=$((FAIL + 1)) +} + +echo "=== Glasspane Stress Test ===" +echo "Socket: $SOCKET" +echo "" + +# 1. Concurrent multi-spawn — spawn 3 smoke agents at once +echo "--- Concurrent spawn (3 agents) ---" +for _ in 1 2 3; do + printf '{"cmd":"spawn-agent","provider":"local","model":"/usr/local/bin/colibri-smoke-agent"}\n' | timeout 5 $NC >/dev/null 2>&1 & +done +wait +sleep 2 +assert_pane_count "3 concurrent spawns" 3 +assert_states_contain "All agents done" "done" + +# 2. State transitions: working → done +echo "" +echo "--- State transitions ---" +cat > /tmp/gst-working.sh << 'AGENT' +#!/bin/sh +echo '{"type":"turn_start"}' +sleep 3 +echo '{"type":"turn_end"}' +AGENT +chmod +x /tmp/gst-working.sh + +timeout 5 sh -c "printf '{\"cmd\":\"spawn-agent\",\"provider\":\"local\",\"model\":\"/tmp/gst-working.sh\"}\n' | $NC" >/dev/null 2>&1 & +SPAWN_PID=$! +sleep 1 +assert_states_contain "Agent working mid-execution" "working" +wait $SPAWN_PID 2>/dev/null || true +sleep 3 +assert_states_contain "Agent finished → done" "done" +rm -f /tmp/gst-working.sh + +echo "" +echo "=== Results: $PASS passed, $FAIL failed ===" +[ "$FAIL" -eq 0 ] && echo "✅ Glasspane state machine OK" && exit 0 +echo "❌ Glasspane test failures" +exit 1