Skip to content

Commit 8842577

Browse files
committed
chore: test
1 parent 25bad32 commit 8842577

1 file changed

Lines changed: 41 additions & 29 deletions

File tree

packages/agent-infra/mcp-hub/tests/server-startup-readiness.integration.test.ts

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ function createInMemoryFetch(
216216
};
217217
}
218218

219-
describe('Server Startup Readiness with Real Config', () => {
219+
describe('Server Startup Readiness - Race Condition Test', () => {
220220
let MCPHubCtor: MCPHubConstructor;
221221
let MCPServerEndpointCtor: MCPServerEndpointConstructor;
222222
const baseUrl = 'http://mcp.local/mcp';
@@ -228,64 +228,76 @@ describe('Server Startup Readiness with Real Config', () => {
228228
));
229229
});
230230

231-
it('should wait for all processes to be ready before accepting MCP connections (using examples/config.json)', async () => {
231+
it('should NOT return empty tools list when connecting during server initialization (BUG TEST)', async () => {
232232
// Use the REAL config file from examples/config.json
233233
const hub = new MCPHubCtor(configPath, { port: 3100 });
234234

235-
// Initialize hub - this loads config and starts all configured servers
236-
await hub.initialize();
237-
238-
// Verify that at least one server connected successfully
239-
const connections = Array.from(hub.connections.values());
240-
const connectedServers = connections.filter(
241-
(c) => c.status === 'connected',
242-
);
243-
244-
// At least one server from the config should be connected
245-
expect(connectedServers.length).toBeGreaterThan(0);
246-
247-
// Create the MCP endpoint AFTER hub initialization
235+
// Create the MCP endpoint IMMEDIATELY before starting initialization
236+
// This simulates the race condition: endpoint is ready but servers are not
248237
const endpoint = new MCPServerEndpointCtor(hub, { stateless: true });
249238
const fetchImpl = createInMemoryFetch(endpoint);
250239

251-
// Now attempt to connect to the MCP endpoint
240+
// Start hub initialization in the background (don't await yet)
241+
const initPromise = hub.initialize();
242+
243+
// Immediately try to connect to the MCP endpoint while servers are still initializing
244+
// This is where the bug occurs: endpoint accepts connection but servers aren't ready
252245
const transport = new StreamableHTTPClientTransport(new URL(baseUrl), {
253246
fetch: fetchImpl,
254247
});
255248
const client = new Client({
256-
name: 'readiness-test-client',
249+
name: 'race-condition-test-client',
257250
version: '1.0.0',
258251
});
259252

260253
try {
261254
await client.connect(transport);
262255

263-
// Request tools list - this is the key test
264-
const toolsResult = await client.request(
256+
// Request tools list IMMEDIATELY - this should expose the race condition
257+
// BUG: Without the fix, this returns empty list because servers aren't ready yet
258+
// FIX: With the fix, this should wait for servers to be ready or return all tools
259+
const toolsResultDuringInit = await client.request(
265260
{
266261
method: 'tools/list',
267262
params: {},
268263
},
269264
ListToolsResultSchema,
270265
);
271266

272-
// The bug was: when service starts and immediately connects to /mcp,
273-
// it returns empty list because processes aren't ready yet
274-
// After fix: tools list should contain tools from connected servers
275-
expect(toolsResult).toBeDefined();
276-
expect(toolsResult.tools).toBeDefined();
277-
expect(Array.isArray(toolsResult.tools)).toBe(true);
267+
console.log(
268+
`[DURING INIT] Received ${toolsResultDuringInit.tools.length} tools`,
269+
);
278270

279-
// With real MCP servers from examples/config.json, tools.length should be > 0
280-
expect(toolsResult.tools.length).toBeGreaterThan(0);
271+
// Wait for initialization to complete
272+
await initPromise;
273+
274+
// Now request tools list again after initialization is complete
275+
const toolsResultAfterInit = await client.request(
276+
{
277+
method: 'tools/list',
278+
params: {},
279+
},
280+
ListToolsResultSchema,
281+
);
281282

282283
console.log(
283-
`✓ Successfully received ${toolsResult.tools.length} tools from MCP servers`,
284+
`[AFTER INIT] Received ${toolsResultAfterInit.tools.length} tools`,
285+
);
286+
287+
// THE KEY ASSERTION: Tools list should NEVER be empty
288+
// This tests the bug: without the fix, toolsResultDuringInit.tools.length === 0
289+
// With the fix, it should always return tools (either by waiting or by being ready)
290+
expect(toolsResultDuringInit.tools.length).toBeGreaterThan(0);
291+
expect(toolsResultAfterInit.tools.length).toBeGreaterThan(0);
292+
293+
// Both requests should return the same number of tools
294+
expect(toolsResultDuringInit.tools.length).toBe(
295+
toolsResultAfterInit.tools.length,
284296
);
285297
} finally {
286298
await client.close();
287299
await endpoint.close();
288300
await hub.disconnectAll();
289301
}
290-
}, 60000); // Increased timeout for real server connections
302+
}, 60000);
291303
});

0 commit comments

Comments
 (0)