Skip to content

Commit 65cee87

Browse files
hyperpolymathclaude
andcommitted
feat: add e2e integration test script for live VeriSimDB + server probing
Tests the full pipeline: 1. VeriSimDB health check (port 8090) 2. Create test octad with all 8 modalities 3. Query octad back via REST + text search 4. Drift detection endpoint verification 5. Optional live game server TCP probe 6. Cleanup test data Accepts optional host:port argument for targeting specific servers. Gracefully skips live probe when no servers are reachable. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 20d733e commit 65cee87

1 file changed

Lines changed: 271 additions & 0 deletions

File tree

scripts/e2e-test.sh

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
#!/usr/bin/env bash
2+
# SPDX-License-Identifier: PMPL-1.0-or-later
3+
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath)
4+
#
5+
# e2e-test.sh — End-to-end integration test for Game Server Admin
6+
#
7+
# Tests the full pipeline:
8+
# 1. Verify VeriSimDB is running on port 8090
9+
# 2. Create a test octad via REST API
10+
# 3. Query it back via VQL
11+
# 4. Probe a real game server (if reachable)
12+
# 5. Store probe results as octad
13+
# 6. Verify drift detection responds
14+
# 7. Clean up test data
15+
#
16+
# Usage:
17+
# ./scripts/e2e-test.sh # Auto-detect servers
18+
# ./scripts/e2e-test.sh mc.example.com:25565 # Probe specific server
19+
#
20+
# Prerequisites:
21+
# - gsa-verisimdb container running on port 8090
22+
# - curl installed
23+
24+
set -euo pipefail
25+
26+
VERISIMDB_URL="${GSA_VERISIMDB_URL:-http://[::1]:8090}"
27+
TARGET_SERVER="${1:-}"
28+
PASSED=0
29+
FAILED=0
30+
TOTAL=0
31+
32+
# ── Helpers ──────────────────────────────────────────────────────────
33+
34+
pass() { ((PASSED++)); ((TOTAL++)); echo " PASS: $1"; }
35+
fail() { ((FAILED++)); ((TOTAL++)); echo " FAIL: $1"; }
36+
37+
check() {
38+
local desc="$1"
39+
shift
40+
if "$@" >/dev/null 2>&1; then
41+
pass "$desc"
42+
else
43+
fail "$desc"
44+
fi
45+
}
46+
47+
check_output() {
48+
local desc="$1"
49+
local expected="$2"
50+
shift 2
51+
local output
52+
output=$("$@" 2>/dev/null) || { fail "$desc (command failed)"; return; }
53+
if echo "$output" | grep -q "$expected"; then
54+
pass "$desc"
55+
else
56+
fail "$desc (expected '$expected' in output)"
57+
fi
58+
}
59+
60+
echo "═══════════════════════════════════════════════════════════════"
61+
echo " Game Server Admin — End-to-End Integration Test"
62+
echo "═══════════════════════════════════════════════════════════════"
63+
echo ""
64+
echo "VeriSimDB URL: $VERISIMDB_URL"
65+
echo "Target server: ${TARGET_SERVER:-auto-detect}"
66+
echo ""
67+
68+
# ── Step 1: VeriSimDB Health ─────────────────────────────────────────
69+
70+
echo "Step 1: VeriSimDB health check"
71+
check "VeriSimDB is reachable" curl -sf "${VERISIMDB_URL}/health"
72+
check_output "VeriSimDB returns ok" "ok" curl -sf "${VERISIMDB_URL}/health"
73+
74+
if [[ $FAILED -gt 0 ]]; then
75+
echo ""
76+
echo "ABORT: VeriSimDB not running. Start it with:"
77+
echo " systemctl --user start gsa-verisimdb"
78+
echo " # or: podman run -d --name gsa-verisimdb -p [::1]:8090:8090 gsa-verisimdb:latest"
79+
exit 1
80+
fi
81+
82+
# ── Step 2: Create Test Octad ────────────────────────────────────────
83+
84+
echo ""
85+
echo "Step 2: Create test octad"
86+
87+
TEST_OCTAD=$(cat <<'JSON'
88+
{
89+
"document": {
90+
"title": "e2e-test-server",
91+
"body": "Minecraft Java Edition test server for GSA e2e validation. Running version 1.21.4 with max-players=32 and difficulty=normal.",
92+
"fields": {"game_id": "minecraft-java", "test": "true"}
93+
},
94+
"semantic": {
95+
"types": ["https://gsa.hyperpolymath.dev/types/GameServer", "https://gsa.hyperpolymath.dev/types/GameServer/Minecraft"],
96+
"properties": {}
97+
},
98+
"graph": {
99+
"relationships": [["has-profile", "profile:minecraft-java"], ["in-cluster", "cluster:e2e-test"]]
100+
},
101+
"vector": {
102+
"embedding": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8],
103+
"model": "test-8dim"
104+
},
105+
"provenance": {
106+
"event_type": "created",
107+
"actor": "gsa-e2e-test",
108+
"description": "Created by e2e integration test"
109+
},
110+
"spatial": {
111+
"latitude": 51.5074,
112+
"longitude": -0.1278,
113+
"altitude": 0.0
114+
},
115+
"metadata": {
116+
"game_id": "minecraft-java",
117+
"host": "127.0.0.1",
118+
"port": "25565",
119+
"protocol": "minecraft-query",
120+
"status": "test"
121+
}
122+
}
123+
JSON
124+
)
125+
126+
CREATE_RESPONSE=$(curl -sf -X POST "${VERISIMDB_URL}/api/v1/octads" \
127+
-H "Content-Type: application/json" \
128+
-d "$TEST_OCTAD" 2>/dev/null) || { fail "Create octad (HTTP error)"; CREATE_RESPONSE=""; }
129+
130+
if [[ -n "$CREATE_RESPONSE" ]]; then
131+
OCTAD_ID=$(echo "$CREATE_RESPONSE" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
132+
if [[ -n "$OCTAD_ID" ]]; then
133+
pass "Create octad (id=$OCTAD_ID)"
134+
else
135+
# Try alternate JSON field names
136+
OCTAD_ID=$(echo "$CREATE_RESPONSE" | grep -o '"entity_id":"[^"]*"' | head -1 | cut -d'"' -f4)
137+
if [[ -n "$OCTAD_ID" ]]; then
138+
pass "Create octad (entity_id=$OCTAD_ID)"
139+
else
140+
fail "Create octad (no ID in response: ${CREATE_RESPONSE:0:200})"
141+
OCTAD_ID="e2e-test-fallback"
142+
fi
143+
fi
144+
else
145+
OCTAD_ID="e2e-test-fallback"
146+
fi
147+
148+
# ── Step 3: Query Octad Back ─────────────────────────────────────────
149+
150+
echo ""
151+
echo "Step 3: Query octad back"
152+
153+
if [[ "$OCTAD_ID" != "e2e-test-fallback" ]]; then
154+
check_output "GET octad by ID" "e2e-test-server" \
155+
curl -sf "${VERISIMDB_URL}/api/v1/octads/${OCTAD_ID}"
156+
fi
157+
158+
check_output "Text search for 'minecraft'" "minecraft" \
159+
curl -sf "${VERISIMDB_URL}/api/v1/search/text?q=minecraft&limit=5"
160+
161+
# ── Step 4: Drift Detection ──────────────────────────────────────────
162+
163+
echo ""
164+
echo "Step 4: Drift detection"
165+
166+
check "Drift status endpoint responds" curl -sf "${VERISIMDB_URL}/api/v1/drift/status"
167+
168+
if [[ "$OCTAD_ID" != "e2e-test-fallback" ]]; then
169+
# Entity-level drift check
170+
DRIFT_RESPONSE=$(curl -sf "${VERISIMDB_URL}/api/v1/drift/entity/${OCTAD_ID}" 2>/dev/null) || true
171+
if [[ -n "$DRIFT_RESPONSE" ]]; then
172+
pass "Entity drift check (id=$OCTAD_ID)"
173+
else
174+
fail "Entity drift check"
175+
fi
176+
fi
177+
178+
# ── Step 5: Live Server Probe (Optional) ─────────────────────────────
179+
180+
echo ""
181+
echo "Step 5: Live server probe"
182+
183+
if [[ -z "$TARGET_SERVER" ]]; then
184+
# Try common public Minecraft servers (best-effort)
185+
PROBE_TARGETS=(
186+
"127.0.0.1:25565"
187+
"127.0.0.1:19132"
188+
"127.0.0.1:2456"
189+
)
190+
for target in "${PROBE_TARGETS[@]}"; do
191+
host="${target%:*}"
192+
port="${target#*:}"
193+
if timeout 2 bash -c "echo >/dev/tcp/$host/$port" 2>/dev/null; then
194+
TARGET_SERVER="$target"
195+
echo " Found reachable server: $TARGET_SERVER"
196+
break
197+
fi
198+
done
199+
fi
200+
201+
if [[ -n "$TARGET_SERVER" ]]; then
202+
host="${TARGET_SERVER%:*}"
203+
port="${TARGET_SERVER#*:}"
204+
echo " Probing $TARGET_SERVER..."
205+
206+
# TCP connectivity check
207+
if timeout 3 bash -c "echo >/dev/tcp/$host/$port" 2>/dev/null; then
208+
pass "TCP connect to $TARGET_SERVER"
209+
210+
# Store probe result as octad
211+
PROBE_OCTAD=$(cat <<PROBEJSON
212+
{
213+
"document": {
214+
"title": "probe-${host}-${port}",
215+
"body": "Live probe result for ${host}:${port} from GSA e2e test",
216+
"fields": {"probe": "true", "host": "$host", "port": "$port"}
217+
},
218+
"metadata": {
219+
"game_id": "unknown",
220+
"host": "$host",
221+
"port": "$port",
222+
"protocol": "tcp-connect",
223+
"status": "reachable"
224+
},
225+
"provenance": {
226+
"event_type": "probed",
227+
"actor": "gsa-e2e-test",
228+
"description": "Live TCP probe from e2e test"
229+
}
230+
}
231+
PROBEJSON
232+
)
233+
PROBE_RESPONSE=$(curl -sf -X POST "${VERISIMDB_URL}/api/v1/octads" \
234+
-H "Content-Type: application/json" \
235+
-d "$PROBE_OCTAD" 2>/dev/null) || true
236+
237+
if [[ -n "$PROBE_RESPONSE" ]]; then
238+
pass "Store probe result in VeriSimDB"
239+
else
240+
fail "Store probe result in VeriSimDB"
241+
fi
242+
else
243+
fail "TCP connect to $TARGET_SERVER (unreachable)"
244+
fi
245+
else
246+
echo " No reachable game servers found (skipping live probe)"
247+
echo " To test with a specific server: $0 host:port"
248+
fi
249+
250+
# ── Step 6: Cleanup ──────────────────────────────────────────────────
251+
252+
echo ""
253+
echo "Step 6: Cleanup"
254+
255+
if [[ "$OCTAD_ID" != "e2e-test-fallback" ]]; then
256+
check "Delete test octad" curl -sf -X DELETE "${VERISIMDB_URL}/api/v1/octads/${OCTAD_ID}"
257+
fi
258+
259+
# ── Summary ──────────────────────────────────────────────────────────
260+
261+
echo ""
262+
echo "═══════════════════════════════════════════════════════════════"
263+
echo " Results: $PASSED passed, $FAILED failed, $TOTAL total"
264+
echo "═══════════════════════════════════════════════════════════════"
265+
266+
if [[ $FAILED -gt 0 ]]; then
267+
exit 1
268+
else
269+
echo " All tests passed!"
270+
exit 0
271+
fi

0 commit comments

Comments
 (0)