From 9627c201c751ef6c2c48ab2f7cbdf96156ab9251 Mon Sep 17 00:00:00 2001 From: Affaan Mustafa Date: Wed, 29 Apr 2026 22:57:18 -0400 Subject: [PATCH] test: harden mcp health http probe fixture --- tests/hooks/mcp-health-check.test.js | 44 +++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/tests/hooks/mcp-health-check.test.js b/tests/hooks/mcp-health-check.test.js index c6c50232..118b8706 100644 --- a/tests/hooks/mcp-health-check.test.js +++ b/tests/hooks/mcp-health-check.test.js @@ -54,6 +54,18 @@ function readState(statePath) { return JSON.parse(fs.readFileSync(statePath, 'utf8')); } +function readOptionalFile(filePath) { + return fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : ''; +} + +function hookFailureDetails(result, statePath) { + return [ + `exit=${result.code}`, + `stderr=${result.stderr.trim() || ''}`, + `state=${readOptionalFile(statePath)}` + ].join('; '); +} + function createCommandConfig(scriptPath) { return { command: process.execPath, @@ -132,7 +144,15 @@ function waitForHttpReady(urlString, timeoutMs = 5000) { const attempt = () => { const req = client.request(urlString, { method: 'GET' }, res => { res.resume(); - resolve(); + res.once('end', resolve); + res.once('error', error => { + if (Date.now() >= deadline) { + reject(new Error(`Timed out waiting for ${urlString}: ${error.message}`)); + return; + } + + setTimeout(attempt, 25); + }); }); req.setTimeout(250, () => { @@ -835,26 +855,30 @@ async function runTests() { writeConfig(configPath, { mcpServers: { - github: { + http400: { type: 'http', url: `http://127.0.0.1:${port}/mcp` } } }); - const input = { tool_name: 'mcp__github__search_repositories', tool_input: {} }; + const input = { tool_name: 'mcp__http400__search_repositories', tool_input: {} }; const result = runHook(input, { CLAUDE_HOOK_EVENT_NAME: 'PreToolUse', ECC_MCP_CONFIG_PATH: configPath, ECC_MCP_HEALTH_STATE_PATH: statePath, - ECC_MCP_HEALTH_TIMEOUT_MS: '500' + ECC_MCP_HEALTH_TIMEOUT_MS: '2000' }); - assert.strictEqual(result.code, 0, `Expected HTTP 400 probe to be treated as healthy, got ${result.code}`); + assert.strictEqual( + result.code, + 0, + `Expected HTTP 400 probe to be treated as healthy: ${hookFailureDetails(result, statePath)}` + ); assert.strictEqual(result.stdout.trim(), JSON.stringify(input), 'Expected original JSON on stdout'); const state = readState(statePath); - assert.strictEqual(state.servers.github.status, 'healthy', 'Expected HTTP MCP server to be marked healthy'); + assert.strictEqual(state.servers.http400.status, 'healthy', 'Expected HTTP MCP server to be marked healthy'); } finally { serverProcess.kill('SIGTERM'); cleanupTempDir(tempDir); @@ -910,10 +934,14 @@ async function runTests() { CLAUDE_HOOK_EVENT_NAME: 'PreToolUse', ECC_MCP_CONFIG_PATH: configPath, ECC_MCP_HEALTH_STATE_PATH: statePath, - ECC_MCP_HEALTH_TIMEOUT_MS: '500' + ECC_MCP_HEALTH_TIMEOUT_MS: '2000' }); - assert.strictEqual(result.code, 0, `Expected HTTP 401 probe to be treated as healthy, got ${result.code}`); + assert.strictEqual( + result.code, + 0, + `Expected HTTP 401 probe to be treated as healthy: ${hookFailureDetails(result, statePath)}` + ); assert.strictEqual(result.stdout.trim(), JSON.stringify(input), 'Expected original JSON on stdout'); const state = readState(statePath);