Merge pull request #1067 from BobDickinson/cli-test-update
Fixed test failures induced by MCP SDK update
This commit is contained in:
commit
98f058765d
3 changed files with 41 additions and 20 deletions
|
|
@ -1,18 +1,30 @@
|
|||
import { expect } from "vitest";
|
||||
import type { CliResult } from "./cli-runner.js";
|
||||
|
||||
function formatCliOutput(result: CliResult): string {
|
||||
const out = result.stdout?.trim() || "(empty)";
|
||||
const err = result.stderr?.trim() || "(empty)";
|
||||
return `stdout: ${out}\nstderr: ${err}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that CLI command succeeded (exit code 0)
|
||||
*/
|
||||
export function expectCliSuccess(result: CliResult) {
|
||||
expect(result.exitCode).toBe(0);
|
||||
expect(
|
||||
result.exitCode,
|
||||
`CLI exited with code ${result.exitCode}. ${formatCliOutput(result)}`,
|
||||
).toBe(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that CLI command failed (non-zero exit code)
|
||||
*/
|
||||
export function expectCliFailure(result: CliResult) {
|
||||
expect(result.exitCode).not.toBe(0);
|
||||
expect(
|
||||
result.exitCode,
|
||||
`CLI unexpectedly exited with code ${result.exitCode}. ${formatCliOutput(result)}`,
|
||||
).not.toBe(0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import fs from "fs";
|
||||
import path from "path";
|
||||
import os from "os";
|
||||
import crypto from "crypto";
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import * as os from "os";
|
||||
import * as crypto from "crypto";
|
||||
import { getTestMcpServerCommand } from "./test-server-stdio.js";
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import type { Request, Response } from "express";
|
|||
import express from "express";
|
||||
import { createServer as createHttpServer, Server as HttpServer } from "http";
|
||||
import { createServer as createNetServer } from "net";
|
||||
import { randomUUID } from "crypto";
|
||||
import * as z from "zod/v4";
|
||||
import type { ServerConfig } from "./test-fixtures.js";
|
||||
|
||||
|
|
@ -187,22 +188,24 @@ export class TestServerHttp {
|
|||
}
|
||||
|
||||
/**
|
||||
* Start the server with the specified transport
|
||||
* Start the server with the specified transport.
|
||||
* When requestedPort is omitted, uses port 0 so the OS assigns a unique port (avoids EADDRINUSE when tests run in parallel).
|
||||
*/
|
||||
async start(
|
||||
transport: "http" | "sse",
|
||||
requestedPort?: number,
|
||||
): Promise<number> {
|
||||
const port = requestedPort
|
||||
? await findAvailablePort(requestedPort)
|
||||
: await findAvailablePort(transport === "http" ? 3001 : 3000);
|
||||
|
||||
this.url = `http://localhost:${port}`;
|
||||
const port =
|
||||
requestedPort !== undefined ? await findAvailablePort(requestedPort) : 0;
|
||||
|
||||
if (transport === "http") {
|
||||
return this.startHttp(port);
|
||||
const actualPort = await this.startHttp(port);
|
||||
this.url = `http://localhost:${actualPort}`;
|
||||
return actualPort;
|
||||
} else {
|
||||
return this.startSse(port);
|
||||
const actualPort = await this.startSse(port);
|
||||
this.url = `http://localhost:${actualPort}`;
|
||||
return actualPort;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -213,8 +216,10 @@ export class TestServerHttp {
|
|||
// Create HTTP server
|
||||
this.httpServer = createHttpServer(app);
|
||||
|
||||
// Create StreamableHTTP transport
|
||||
this.transport = new StreamableHTTPServerTransport({});
|
||||
// Create StreamableHTTP transport (stateful so it can handle multiple requests per session)
|
||||
this.transport = new StreamableHTTPServerTransport({
|
||||
sessionIdGenerator: () => randomUUID(),
|
||||
});
|
||||
|
||||
// Set up Express route to handle MCP requests
|
||||
app.post("/mcp", async (req: Request, res: Response) => {
|
||||
|
|
@ -292,10 +297,12 @@ export class TestServerHttp {
|
|||
// Connect transport to server
|
||||
await this.mcpServer.connect(this.transport);
|
||||
|
||||
// Start listening
|
||||
// Start listening (port 0 = OS assigns a unique port)
|
||||
return new Promise((resolve, reject) => {
|
||||
this.httpServer!.listen(port, () => {
|
||||
resolve(port);
|
||||
const assignedPort = (this.httpServer!.address() as { port: number })
|
||||
?.port;
|
||||
resolve(assignedPort ?? port);
|
||||
});
|
||||
this.httpServer!.on("error", reject);
|
||||
});
|
||||
|
|
@ -371,10 +378,12 @@ export class TestServerHttp {
|
|||
// Note: SSE transport is created per request, so we don't store a single instance
|
||||
this.transport = undefined;
|
||||
|
||||
// Start listening
|
||||
// Start listening (port 0 = OS assigns a unique port)
|
||||
return new Promise((resolve, reject) => {
|
||||
this.httpServer!.listen(port, () => {
|
||||
resolve(port);
|
||||
const assignedPort = (this.httpServer!.address() as { port: number })
|
||||
?.port;
|
||||
resolve(assignedPort ?? port);
|
||||
});
|
||||
this.httpServer!.on("error", reject);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue