Skip to content

Commit fb611d4

Browse files
authored
Merge pull request #391 from githubnext/lpcox/test-serena2
fix: MCP session management in gateway tests
2 parents 035dd0f + e160c0c commit fb611d4

2 files changed

Lines changed: 97 additions & 20 deletions

File tree

run_containerized.sh

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -225,15 +225,25 @@ validate_log_directory_mount() {
225225
fi
226226
}
227227

228-
# Set DOCKER_API_VERSION based on architecture
228+
# Set DOCKER_API_VERSION based on architecture and Docker daemon requirements
229229
set_docker_api_version() {
230-
local arch=$(uname -m)
231-
if [ "$arch" = "arm64" ] || [ "$arch" = "aarch64" ]; then
232-
export DOCKER_API_VERSION=1.43
230+
# First, check what the Docker daemon requires as minimum API version
231+
local min_api=$(docker version --format '{{.Server.MinAPIVersion}}' 2>/dev/null || echo "")
232+
233+
if [ -n "$min_api" ]; then
234+
# Use the daemon's minimum API version to ensure compatibility
235+
export DOCKER_API_VERSION="$min_api"
236+
log_info "Set DOCKER_API_VERSION=$DOCKER_API_VERSION (daemon minimum)"
233237
else
234-
export DOCKER_API_VERSION=1.44
238+
# Fallback: set based on architecture
239+
local arch=$(uname -m)
240+
if [ "$arch" = "arm64" ] || [ "$arch" = "aarch64" ]; then
241+
export DOCKER_API_VERSION=1.44
242+
else
243+
export DOCKER_API_VERSION=1.44
244+
fi
245+
log_info "Set DOCKER_API_VERSION=$DOCKER_API_VERSION for $arch (fallback)"
235246
fi
236-
log_info "Set DOCKER_API_VERSION=$DOCKER_API_VERSION for $arch"
237247
}
238248

239249
# Detect host IP and configure host.docker.internal DNS mapping

test/serena-mcp-tests/test_serena_via_gateway.sh

Lines changed: 81 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,12 @@ fi
124124
# Test 3: Pull gateway container image
125125
log_section "Test 3: Gateway Container Image Availability"
126126
count_test
127-
log_info "Pulling gateway container image..."
128-
if docker pull "$GATEWAY_IMAGE" >/dev/null 2>&1; then
127+
# Check if image exists locally first
128+
if docker image inspect "$GATEWAY_IMAGE" >/dev/null 2>&1; then
129+
log_info "Using local gateway image (skipping pull)"
130+
log_success "Gateway container image is available"
131+
elif docker pull "$GATEWAY_IMAGE" >/dev/null 2>&1; then
132+
log_info "Pulling gateway container image..."
129133
log_success "Gateway container image is available"
130134
else
131135
log_error "Failed to pull gateway container image: $GATEWAY_IMAGE"
@@ -239,22 +243,63 @@ else
239243
exit 1
240244
fi
241245

242-
# Function to send MCP request via gateway
243-
send_mcp_request() {
246+
# Session ID for MCP Streamable HTTP transport
247+
# Stored in a file to survive subshell boundaries
248+
MCP_SESSION_FILE="$TEMP_DIR/mcp_session_id.txt"
249+
echo "" > "$MCP_SESSION_FILE"
250+
251+
# Response file for avoiding subshell variable scope issues
252+
MCP_RESPONSE_FILE="$TEMP_DIR/mcp_response.txt"
253+
254+
# Function to get the current session ID
255+
get_session_id() {
256+
cat "$MCP_SESSION_FILE" 2>/dev/null || echo ""
257+
}
258+
259+
# Function to send MCP request and capture session ID
260+
# This writes response to MCP_RESPONSE_FILE and updates session ID file
261+
send_mcp_request_direct() {
244262
local request="$1"
245263
local endpoint="http://localhost:$GATEWAY_PORT/mcp/serena"
264+
local headers_file="$TEMP_DIR/response_headers.txt"
265+
local session_id=$(get_session_id)
266+
267+
# Run curl and save response to file
268+
if [ -n "$session_id" ]; then
269+
curl -s -X POST "$endpoint" \
270+
-H "Content-Type: application/json" \
271+
-H "Accept: application/json, text/event-stream" \
272+
-H "Authorization: $GATEWAY_API_KEY" \
273+
-H "Mcp-Session-Id: $session_id" \
274+
-D "$headers_file" \
275+
-d "$request" > "$MCP_RESPONSE_FILE" 2>/dev/null || echo '{"error": "request failed"}' > "$MCP_RESPONSE_FILE"
276+
else
277+
curl -s -X POST "$endpoint" \
278+
-H "Content-Type: application/json" \
279+
-H "Accept: application/json, text/event-stream" \
280+
-H "Authorization: $GATEWAY_API_KEY" \
281+
-D "$headers_file" \
282+
-d "$request" > "$MCP_RESPONSE_FILE" 2>/dev/null || echo '{"error": "request failed"}' > "$MCP_RESPONSE_FILE"
283+
fi
246284

247-
curl -s -X POST "$endpoint" \
248-
-H "Content-Type: application/json" \
249-
-H "Accept: application/json, text/event-stream" \
250-
-H "Authorization: $GATEWAY_API_KEY" \
251-
-d "$request" 2>/dev/null || echo '{"error": "request failed"}'
285+
# Capture session ID from response headers and save to file
286+
if [ -f "$headers_file" ]; then
287+
local new_session_id=$(grep -i "^mcp-session-id:" "$headers_file" | sed 's/^[Mm]cp-[Ss]ession-[Ii]d: *//;s/\r$//' | head -1)
288+
if [ -n "$new_session_id" ]; then
289+
echo "$new_session_id" > "$MCP_SESSION_FILE"
290+
fi
291+
fi
252292
}
253293

254-
# Function to send MCP request and parse response (handles SSE)
255-
send_and_parse_mcp_request() {
256-
local request="$1"
257-
local raw_response=$(send_mcp_request "$request")
294+
# Function to send MCP request and get the raw response
295+
# Call send_mcp_request_direct first, then use get_mcp_response
296+
get_mcp_response() {
297+
cat "$MCP_RESPONSE_FILE"
298+
}
299+
300+
# Function to get parsed JSON from SSE response
301+
get_mcp_response_json() {
302+
local raw_response=$(cat "$MCP_RESPONSE_FILE")
258303

259304
# Check if response is SSE format
260305
if echo "$raw_response" | grep -q "^event: message"; then
@@ -266,21 +311,43 @@ send_and_parse_mcp_request() {
266311
fi
267312
}
268313

314+
# Legacy function for backward compatibility
315+
send_mcp_request() {
316+
local request="$1"
317+
send_mcp_request_direct "$request"
318+
get_mcp_response
319+
}
320+
321+
# Legacy function for backward compatibility - parses SSE response
322+
# NOTE: Session ID is now persisted to file, so it survives subshell usage
323+
send_and_parse_mcp_request() {
324+
local request="$1"
325+
send_mcp_request_direct "$request"
326+
get_mcp_response_json
327+
}
328+
269329
# Test 6: MCP Protocol - Initialize
270330
log_section "Test 6: MCP Protocol Initialize (via Gateway)"
271331
count_test
272332
log_info "Sending MCP initialize request through gateway..."
273333

274334
INIT_REQUEST='{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test-client","version":"1.0.0"}}}'
275335

336+
# Send request - session ID will be captured and saved to file
276337
INIT_JSON=$(send_and_parse_mcp_request "$INIT_REQUEST")
277338

278339
echo "$INIT_JSON" > "$RESULTS_DIR/initialize_response.json"
279340

341+
MCP_SESSION_ID=$(get_session_id)
280342
if echo "$INIT_JSON" | grep -q '"jsonrpc"'; then
281343
if echo "$INIT_JSON" | grep -q '"result"'; then
282344
log_success "MCP initialize succeeded through gateway"
283345
log_info "Response saved to: $RESULTS_DIR/initialize_response.json"
346+
if [ -n "$MCP_SESSION_ID" ]; then
347+
log_info "MCP Session ID: $MCP_SESSION_ID"
348+
else
349+
log_warning "No MCP Session ID captured - subsequent requests may fail"
350+
fi
284351
else
285352
log_error "MCP initialize returned error through gateway"
286353
echo "$INIT_JSON" | head -5
@@ -293,7 +360,7 @@ fi
293360
# Send initialized notification to complete handshake
294361
log_info "Sending initialized notification to complete MCP handshake..."
295362
INITIALIZED_NOTIF='{"jsonrpc":"2.0","method":"notifications/initialized"}'
296-
send_mcp_request "$INITIALIZED_NOTIF" >/dev/null 2>&1
363+
send_mcp_request_direct "$INITIALIZED_NOTIF"
297364

298365
# Give the server a moment to process the notification
299366
sleep 1

0 commit comments

Comments
 (0)