mirror of
https://github.com/morluto/rea.git
synced 2026-10-26 17:35:11 +00:00
Route application and provider-environment harnesses through the shared MCP connection owner. Join accepted handshakes during shutdown, retain each failed close for retry, preserve primary and independent cleanup failures, and release provider files only after their session closes. Surface BinarySession close Result errors in production and artifact fixture teardown. Add real SDK and descriptor-boundary regressions for startup races, concurrent cleanup, mixed failures and recovery. Use a provider-free plist for descriptor ownership so installed deep engines cannot change the test outcome.
86 lines
2.6 KiB
TypeScript
86 lines
2.6 KiB
TypeScript
import type { Client } from "@modelcontextprotocol/client";
|
|
import { onTestFinished } from "vitest";
|
|
|
|
import { closeVerifierResources } from "../../scripts/lib/verifier-cleanup.mjs";
|
|
import { ok as resultOk } from "../../src/domain/result.js";
|
|
import { createTestBinarySession } from "./binarySession.js";
|
|
import type { BinarySession } from "../../src/application/binary/BinarySession.js";
|
|
import { observed } from "./analysisExecution.js";
|
|
import { createServer } from "../../src/server/createServer.js";
|
|
import {
|
|
createTestMcp,
|
|
type McpClientIdentity,
|
|
} from "../support/mcp/mcpFixture.js";
|
|
|
|
/** Owned MCP SDK session shared by application workflow scenarios. */
|
|
export interface ApplicationMcpHarness {
|
|
readonly client: Client;
|
|
readonly session: BinarySession;
|
|
readonly close: () => Promise<void>;
|
|
}
|
|
|
|
/** Connect application workflows through the production MCP registration. */
|
|
export async function createApplicationMcpHarness(
|
|
options: {
|
|
readonly session?: BinarySession;
|
|
readonly serverOptions?: Parameters<typeof createServer>[1];
|
|
readonly clientIdentity?: McpClientIdentity;
|
|
readonly registerCleanup?: (close: ApplicationMcpHarness["close"]) => void;
|
|
} = {},
|
|
): Promise<ApplicationMcpHarness> {
|
|
const session =
|
|
options.session ??
|
|
createTestBinarySession(() => ({
|
|
execute: () => Promise.resolve(observed(null)),
|
|
close: () => Promise.resolve(resultOk(null)),
|
|
}));
|
|
const mcp = createTestMcp();
|
|
let sessionClosed = false;
|
|
let closing: Promise<void> | undefined;
|
|
const close = (): Promise<void> => {
|
|
if (closing !== undefined) return closing;
|
|
const attempt = closeVerifierResources([
|
|
() => mcp.close(),
|
|
async () => {
|
|
if (sessionClosed) return;
|
|
const result = await session.close();
|
|
if (!result.ok) throw result.error;
|
|
sessionClosed = true;
|
|
},
|
|
]);
|
|
closing = attempt;
|
|
void attempt.catch(() => {
|
|
if (closing === attempt) closing = undefined;
|
|
});
|
|
return attempt;
|
|
};
|
|
onTestFinished(close);
|
|
|
|
try {
|
|
options.registerCleanup?.(close);
|
|
const server = createServer(
|
|
{ kind: "session", session },
|
|
options.serverOptions,
|
|
);
|
|
const client = await mcp.connect(
|
|
server,
|
|
options.clientIdentity ?? {
|
|
name: "application-workflow-test",
|
|
version: "1",
|
|
},
|
|
);
|
|
return { client, session, close };
|
|
} catch (cause) {
|
|
try {
|
|
await close();
|
|
} catch (cleanup) {
|
|
throw new AggregateError(
|
|
[cause, cleanup],
|
|
"Application MCP harness setup and cleanup failed",
|
|
{ cause },
|
|
);
|
|
}
|
|
throw cause;
|
|
}
|
|
}
|