Skip to content

Commit b680129

Browse files
committed
Fix soak test: route queries through MCP server (not CLI) for real metrics
1 parent dbd543a commit b680129

File tree

1 file changed

+70
-28
lines changed

1 file changed

+70
-28
lines changed

scripts/soak-test.sh

Lines changed: 70 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,37 @@ git -C "$SOAK_PROJECT" -c user.email=test@test -c user.name=test commit -q -m "i
9999

100100
# ── Helper: run CLI tool call and record latency ─────────────────
101101

102-
cli_call() {
102+
# Query ID counter
103+
QUERY_ID=1
104+
105+
# Send a JSON-RPC tool call to the running server via its stdin pipe.
106+
# Reads response from server stdout. Records latency.
107+
mcp_call() {
103108
local tool="$1"
104109
local args="$2"
110+
local id=$QUERY_ID
111+
QUERY_ID=$((QUERY_ID + 1))
112+
113+
local req="{\"jsonrpc\":\"2.0\",\"id\":$id,\"method\":\"tools/call\",\"params\":{\"name\":\"$tool\",\"arguments\":$args}}"
105114
local t0
106115
t0=$(python3 -c "import time; print(int(time.time()*1000))")
107-
"$BINARY" cli "$tool" "$args" > /dev/null 2>&1
108-
local rc=$?
109-
local t1
110-
t1=$(python3 -c "import time; print(int(time.time()*1000))")
111-
local dur=$((t1 - t0))
112-
echo "$(date +%s),$tool,$dur,$rc" >> "$LATENCY_CSV"
116+
117+
# Send request to server stdin
118+
echo "$req" >&3
119+
120+
# Read response (wait up to 30s)
121+
local resp=""
122+
if read -t 30 resp <&4 2>/dev/null; then
123+
local t1
124+
t1=$(python3 -c "import time; print(int(time.time()*1000))")
125+
local dur=$((t1 - t0))
126+
echo "$(date +%s),$tool,$dur,0" >> "$LATENCY_CSV"
127+
else
128+
local t1
129+
t1=$(python3 -c "import time; print(int(time.time()*1000))")
130+
local dur=$((t1 - t0))
131+
echo "$(date +%s),$tool,$dur,1" >> "$LATENCY_CSV"
132+
fi
113133
}
114134

115135
# ── Helper: collect diagnostics snapshot ─────────────────────────
@@ -131,23 +151,35 @@ collect_snapshot() {
131151
# ── Phase 1: Start MCP server with diagnostics ──────────────────
132152

133153
echo "--- Phase 1: start server ---"
134-
# Keep stdin open with a sleeping process — kill it to send EOF
135-
sleep 999999 | CBM_DIAGNOSTICS=1 "$BINARY" > /dev/null 2>"$RESULTS_DIR/server-stderr.log" &
154+
# Bidirectional pipes: fd3 = server stdin (write), fd4 = server stdout (read)
155+
SERVER_IN=$(mktemp -u).in
156+
SERVER_OUT=$(mktemp -u).out
157+
mkfifo "$SERVER_IN" "$SERVER_OUT"
158+
159+
CBM_DIAGNOSTICS=1 "$BINARY" < "$SERVER_IN" > "$SERVER_OUT" 2>"$RESULTS_DIR/server-stderr.log" &
136160
SERVER_PID=$!
137-
SLEEP_PID=$(jobs -p | head -1)
161+
162+
# Open fds AFTER server starts (otherwise fifo blocks)
163+
exec 3>"$SERVER_IN" # write to server stdin
164+
exec 4<"$SERVER_OUT" # read from server stdout
138165
sleep 3
139166

140167
if ! kill -0 "$SERVER_PID" 2>/dev/null; then
141168
echo "FAIL: server did not start"
142-
kill "$SLEEP_PID" 2>/dev/null || true
169+
exec 3>&- 4<&-
170+
rm -f "$SERVER_IN" "$SERVER_OUT"
143171
exit 1
144172
fi
145173
echo "OK: server running (pid=$SERVER_PID)"
146174

175+
# Send initialize handshake
176+
echo '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"capabilities":{}}}' >&3
177+
read -t 10 INIT_RESP <&4 || true
178+
147179
# ── Phase 2: Initial index ───────────────────────────────────────
148180

149181
echo "--- Phase 2: initial index ---"
150-
cli_call index_repository "{\"repo_path\":\"$SOAK_PROJECT\"}"
182+
mcp_call index_repository "{\"repo_path\":\"$SOAK_PROJECT\"}"
151183
sleep 6 # wait for diagnostics write
152184
collect_snapshot
153185

@@ -172,8 +204,8 @@ while [ "$(date +%s)" -lt "$END_TIME" ]; do
172204
CYCLE=$((CYCLE + 1))
173205

174206
# Queries every 2 seconds
175-
cli_call search_graph "{\"project\":\"$PROJ_NAME\",\"name_pattern\":\".*compute.*\"}"
176-
cli_call trace_call_path "{\"project\":\"$PROJ_NAME\",\"function_name\":\"compute\",\"direction\":\"both\"}"
207+
mcp_call search_graph "{\"project\":\"$PROJ_NAME\",\"name_pattern\":\".*compute.*\"}"
208+
mcp_call trace_call_path "{\"project\":\"$PROJ_NAME\",\"function_name\":\"compute\",\"direction\":\"both\"}"
177209

178210
# File mutation every 2 minutes
179211
if [ $((NOW - LAST_MUTATE)) -ge 120 ]; then
@@ -185,7 +217,7 @@ while [ "$(date +%s)" -lt "$END_TIME" ]; do
185217

186218
# Full reindex every 5 minutes
187219
if [ $((NOW - LAST_REINDEX)) -ge 300 ]; then
188-
cli_call index_repository "{\"repo_path\":\"$SOAK_PROJECT\"}"
220+
mcp_call index_repository "{\"repo_path\":\"$SOAK_PROJECT\"}"
189221
LAST_REINDEX=$NOW
190222
fi
191223

@@ -212,32 +244,42 @@ echo "OK: idle CPU=${IDLE_CPU}%"
212244
if [ "$SKIP_CRASH" != "--skip-crash-test" ]; then
213245
echo "--- Phase 5: crash recovery ---"
214246

215-
# Start a reindex then kill -9
216-
cli_call index_repository "{\"repo_path\":\"$SOAK_PROJECT\"}" &
217-
INDEX_PID=$!
218-
sleep 1
219-
kill -9 "$INDEX_PID" 2>/dev/null || true
220-
wait "$INDEX_PID" 2>/dev/null || true
247+
# Kill server mid-operation, restart, verify clean index
248+
mcp_call index_repository "{\"repo_path\":\"$SOAK_PROJECT\"}"
249+
kill -9 "$SERVER_PID" 2>/dev/null || true
250+
wait "$SERVER_PID" 2>/dev/null || true
251+
exec 3>&- 4<&-
252+
253+
# Restart server
254+
CBM_DIAGNOSTICS=1 "$BINARY" < "$SERVER_IN" > "$SERVER_OUT" 2>>"$RESULTS_DIR/server-stderr.log" &
255+
SERVER_PID=$!
256+
exec 3>"$SERVER_IN"
257+
exec 4<"$SERVER_OUT"
258+
sleep 3
221259

222-
# Verify the server is still alive (kill was on CLI, not server)
223260
if kill -0 "$SERVER_PID" 2>/dev/null; then
224-
echo "OK: server survived crash test"
261+
echo "OK: server restarted after kill -9"
262+
echo '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"capabilities":{}}}' >&3
263+
read -t 10 INIT_RESP <&4 || true
225264

226-
# Verify clean re-index after crash
227-
cli_call index_repository "{\"repo_path\":\"$SOAK_PROJECT\"}"
228-
echo "OK: clean re-index after crash"
265+
# Verify clean re-index works
266+
mcp_call index_repository "{\"repo_path\":\"$SOAK_PROJECT\"}"
267+
echo "OK: clean re-index after crash recovery"
229268
else
230-
echo "FAIL: server died during crash test"
269+
echo "FAIL: server did not restart after kill -9"
270+
PASS=false
231271
fi
232272
fi
233273

234274
# ── Phase 6: Shutdown + analysis ─────────────────────────────────
235275

236276
echo "--- Phase 6: shutdown + analysis ---"
237-
kill "$SLEEP_PID" 2>/dev/null || true # close stdin → EOF → server exits
277+
exec 3>&- # close server stdin → EOF → clean exit
238278
sleep 2
279+
exec 4<&- # close stdout reader
239280
kill "$SERVER_PID" 2>/dev/null || true
240281
wait "$SERVER_PID" 2>/dev/null || true
282+
rm -f "$SERVER_IN" "$SERVER_OUT"
241283

242284
# Final diagnostics (written by thread before exit)
243285
FINAL_DIAG="/tmp/cbm-diagnostics-${SERVER_PID}.json"

0 commit comments

Comments
 (0)