Files
rea/tests/boundary/mcp/largeBytePattern.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

78 lines
2.5 KiB
TypeScript

import { expect, it } from "vitest";
import type { CallToolResult } from "@modelcontextprotocol/server";
import { connectLocalToolsMcp } from "../../fixtures/localToolsMcp.js";
import { parseMcpToolError } from "../../fixtures/mcpToolError.js";
const LARGE_PATTERN_BYTES = 4 * 1024 * 1024;
const inputValidationError = (result: CallToolResult) => {
expect(result.isError).toBe(true);
const diagnostic = parseMcpToolError(result).error;
expect(diagnostic).toMatchObject({
code: "invalid_request",
recovery: {
kind: "inspect_input_contract",
operation: "search_bytes",
},
});
const text = JSON.stringify(diagnostic);
expect(text).not.toMatch(/RangeError|Maximum call stack/i);
return diagnostic;
};
it("validates large search_bytes inputs without breaking stdio MCP", async () => {
const { client, call } = await connectLocalToolsMcp();
const definition = (await client.listTools()).tools.find(
({ name }) => name === "search_bytes",
);
expect(definition?.inputSchema.properties?.pattern).toMatchObject({
type: "string",
});
expect(definition?.inputSchema.properties?.pattern).not.toHaveProperty(
"pattern",
);
expect(definition?.inputSchema.properties?.mask).toMatchObject({
type: "string",
});
expect(definition?.inputSchema.properties?.mask).not.toHaveProperty(
"pattern",
);
const initial = await call("search_bytes", { pattern: "aa" });
expect(parseMcpToolError(initial).error.code).toBe("target_unavailable");
const largePattern = "aa".repeat(LARGE_PATTERN_BYTES);
const largeSearch = await call("search_bytes", { pattern: largePattern });
expect(parseMcpToolError(largeSearch).error.code).toBe("target_unavailable");
const malformedPattern = `${largePattern.slice(0, -2)}a?`;
const malformed = inputValidationError(
await call("search_bytes", { pattern: malformedPattern }),
);
expect(malformed.details).toMatchObject({
issues: [{ path: ["pattern"], reason: "invalid_value" }],
});
const oversizedMask = inputValidationError(
await call("search_bytes", {
pattern: "aa",
mask: "ff".repeat(LARGE_PATTERN_BYTES),
}),
);
expect(oversizedMask.details).toMatchObject({
issues: [
{
path: ["mask"],
reason: "invalid_value",
message: "Mask length must equal pattern length",
},
],
});
const final = await call("search_bytes", { pattern: "aa" });
expect(parseMcpToolError(final).error.code).toBe("target_unavailable");
await client.ping();
});