Files
rea/tests/boundary/mcp/reverseEngineeringEnvironmentMcp.test.ts
morluto 60149282fc test: strengthen integration oracles and verification (#8295)
* test: strengthen integration oracles and verification

* test: bound lifecycle gates and strengthen workflow checks

* test: verify complete paged and extracted results

* test: preserve bytecode and cancellation evidence

* test: strengthen retained evidence and fixture cleanup

* test: require cross-projection bridge identities

* test: retain fixture owners through cleanup failures

* test: verify graph examples and project selectors

* test: tighten provider and lifecycle regressions

* test: consolidate hex coverage and bound cutter cleanup

* test: bound subprocess output waits and strengthen graph checks

* test: check mcp recovery and preserve cleanup owners

* test: verify structured mcp argument failures

* test: preserve artifact cleanup and gdb limit evidence

* test: preserve evidence identities and bound provider gates

* test: retain browser and comparison cleanup owners

* test: bound startup and strengthen fixture oracles

* test: bound lifecycle gates and verify recovered evidence

* test: verify public outcomes and lifecycle ownership

* test: assert precise evidence and release lifecycle gates

* test: verify selected facts and bound cleanup waits

* test: check retained evidence and decoded records

* test: verify final reports and retain cleanup ownership

* test: bound reviewed startup gates and retain cleanup

* test: verify PE errors and preserve MCP cleanup

* test: preserve MCP fixture cleanup ownership

* test: release provider gates before late startup
2026-11-01 00:15:28 +08:00

122 lines
4.2 KiB
TypeScript

import { chmod, mkdtemp, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import type { Client } from "@modelcontextprotocol/client";
import { expect, it } from "vitest";
import { createProviderEnvironmentMcpHarness } from "../../support/reverseDebuggerMcpTestHelpers.js";
const writeProvider = async (path: string, output: string): Promise<void> => {
await writeFile(
path,
`#!${process.execPath}\nprocess.stdout.write('${output}');\n`,
);
await chmod(path, 0o755);
};
const connectProviderClient = (options: {
readonly directory: string;
readonly clientName: string;
readonly configuredProvider: string;
readonly providerEnvironment?: { REA_RIZIN_COMMAND: string };
}) =>
createProviderEnvironmentMcpHarness({
directory: options.directory,
clientName: options.clientName,
serverOptions: {
environment: { REA_RIZIN_COMMAND: options.configuredProvider },
...(options.providerEnvironment === undefined
? {}
: { providerEnvironment: options.providerEnvironment }),
},
});
const executeRizinCommand = async (
client: Client,
artifact: string,
): Promise<Awaited<ReturnType<Client["callTool"]>>> => {
const response = await client.callTool({
name: "execute_rizin_command",
arguments: { path: artifact, command: "iI" },
});
expect(response.isError).not.toBe(true);
return response;
};
it("uses the captured server environment to resolve reverse-engineering providers", async () => {
const directory = await mkdtemp(join(tmpdir(), "rea-provider-environment-"));
const provider = join(directory, "selected-rizin");
const artifact = join(directory, "fixture.bin");
await writeFile(artifact, "fixture");
await writeProvider(provider, "captured-environment-provider");
const { client } = await connectProviderClient({
directory,
clientName: "reverse-provider-environment",
configuredProvider: provider,
});
const response = await executeRizinCommand(client, artifact);
expect(response.structuredContent).toMatchObject({
raw_result: { stdout: "captured-environment-provider" },
});
});
it("prefers an explicit provider environment over the captured server environment", async () => {
const directory = await mkdtemp(join(tmpdir(), "rea-provider-override-"));
const configured = join(directory, "captured-rizin");
const override = join(directory, "override-rizin");
const artifact = join(directory, "fixture.bin");
await writeFile(artifact, "fixture");
for (const [path, output] of [
[configured, "captured"],
[override, "explicit-override"],
] as const) {
await writeProvider(path, output);
}
const { client } = await connectProviderClient({
directory,
clientName: "reverse-provider-override",
configuredProvider: configured,
providerEnvironment: { REA_RIZIN_COMMAND: override },
});
const response = await executeRizinCommand(client, artifact);
expect(response.structuredContent).toMatchObject({
raw_result: { stdout: "explicit-override" },
});
expect(JSON.stringify(response.structuredContent)).not.toContain(
'"captured"',
);
});
it("snapshots an explicit provider environment when the server is created", async () => {
const directory = await mkdtemp(join(tmpdir(), "rea-provider-snapshot-"));
const configured = join(directory, "captured-rizin");
const override = join(directory, "explicit-rizin");
const artifact = join(directory, "fixture.bin");
await writeFile(artifact, "fixture");
for (const [path, output] of [
[configured, "captured"],
[override, "explicit-snapshot"],
] as const) {
await writeProvider(path, output);
}
const providerEnvironment = { REA_RIZIN_COMMAND: override };
const { client } = await connectProviderClient({
directory,
clientName: "reverse-provider-snapshot",
configuredProvider: configured,
providerEnvironment,
});
providerEnvironment.REA_RIZIN_COMMAND = configured;
const response = await executeRizinCommand(client, artifact);
expect(response.structuredContent).toMatchObject({
raw_result: { stdout: "explicit-snapshot" },
});
expect(JSON.stringify(response.structuredContent)).not.toContain(
'"captured"',
);
});