Files
rea/src/application/binaryDiagnostics/BinaryLayoutService.test.ts
T
morluto 3b698645a0 fix(evidence): retain completed observations on late cancellation
Validate completed reports before cancellation projection, retain valid
Evidence and captured command diagnostics, and convert raw cleanup partials
at their application owner. Record partial Evidence consistently across MCP
handlers. Keep page inspection separate from unfinished bundle analysis.

Refs #4261
2026-10-16 06:46:25 +08:00

170 lines
5.3 KiB
TypeScript

import { expect, it } from "vitest";
import { BinaryLayoutService } from "./BinaryLayoutService.js";
import {
binaryLayoutFixture,
BINARY_LAYOUT_TEST_PROVIDER,
} from "../../../tests/fixtures/binaryDiagnostics/layout.js";
import { AnalysisCapabilityUnavailableError } from "../../domain/analysisErrorCore.js";
import { parseEvidence } from "../../domain/evidence.js";
import { err, ok } from "../../domain/result.js";
it.each([
{ path: "relative.elf" },
{ path: "/selected.elf", approval: true },
{ path: 123 },
{},
])(
"rejects malformed selection before starting the provider: %j",
async (input) => {
const service = new BinaryLayoutService({
inspectAndClose(input, options) {
return this.inspect(input, options);
},
identity: BINARY_LAYOUT_TEST_PROVIDER,
inspect: () => {
throw new Error("must not run");
},
});
expect(await service.inspect(input)).toMatchObject({
ok: false,
error: { _tag: "AnalysisInputError" },
});
},
);
it("records the decoded layout once in its Evidence", async () => {
const layout = binaryLayoutFixture();
const service = new BinaryLayoutService({
inspectAndClose(input, options) {
return this.inspect(input, options);
},
identity: BINARY_LAYOUT_TEST_PROVIDER,
inspect: () => Promise.resolve(ok(layout)),
});
const result = await service.inspect({ path: layout.artifact.path });
if (!result.ok) throw result.error;
const evidence = parseEvidence(result.value);
expect(evidence.normalized_result).toEqual(layout);
expect(evidence.raw_result).toBeNull();
});
it("preserves a provider's actionable unsupported reason", async () => {
const failure = new AnalysisCapabilityUnavailableError(
"fixture-layout",
"inspect_binary_layout",
"ELF core belongs to recorded-crash analysis.",
);
const service = new BinaryLayoutService({
inspectAndClose(input, options) {
return this.inspect(input, options);
},
identity: BINARY_LAYOUT_TEST_PROVIDER,
inspect: () => Promise.resolve(err(failure)),
});
expect(await service.inspect({ path: "/source.elf" })).toEqual(err(failure));
});
it("cancels before invocation and after an acquired observation", async () => {
const controller = new AbortController();
const service = new BinaryLayoutService({
inspectAndClose(input, options) {
return this.inspect(input, options);
},
identity: BINARY_LAYOUT_TEST_PROVIDER,
inspect: () => {
controller.abort();
return Promise.resolve(ok(binaryLayoutFixture()));
},
});
const late = await service.inspect(
{ path: "/artifacts/source-owned.elf" },
{ signal: controller.signal },
);
expect(late).toMatchObject({
ok: false,
error: {
_tag: "AnalysisCancelledError",
capturedOutput: binaryLayoutFixture().diagnostics,
},
});
if (!late.ok) {
expect(parseEvidence(late.error.partialObservation)).toMatchObject({
operation: "inspect_binary_layout",
normalized_result: binaryLayoutFixture(),
});
}
const untouched = new BinaryLayoutService({
inspectAndClose(input, options) {
return this.inspect(input, options);
},
identity: BINARY_LAYOUT_TEST_PROVIDER,
inspect: () => {
throw new Error("must not run");
},
});
expect(
await untouched.inspect(
{ path: "/source.elf" },
{ signal: controller.signal },
),
).toMatchObject({ ok: false, error: { _tag: "AnalysisCancelledError" } });
});
it.each(["different-path", "invalid-digest", "outside-range"])(
"rejects provider evidence at the next boundary: %s",
async (problem) => {
const fixture = binaryLayoutFixture();
if (problem === "different-path") fixture.artifact.path = "/different.elf";
if (problem === "invalid-digest") fixture.artifact.sha256 = "unobserved";
if (problem === "outside-range")
fixture.segments.push({
index: 0,
type: "PT_LOAD",
offset: "0x80",
header_location: { offset: "0x0", bytes: "0x38" },
file_backing: "file",
file_size: "0x1",
memory_size: "0x1",
virtual_address: "0x20000000000001",
physical_address: "0x0",
alignment: "0x1",
flags: "0x5",
permissions: { read: true, write: false, execute: true },
});
const service = new BinaryLayoutService({
inspectAndClose(input, options) {
return this.inspect(input, options);
},
identity: BINARY_LAYOUT_TEST_PROVIDER,
inspect: () => Promise.resolve(ok(fixture)),
});
expect(
await service.inspect({ path: "/artifacts/source-owned.elf" }),
).toMatchObject({
ok: false,
error: {
_tag: "AnalysisOutputError",
capturedOutput: fixture.diagnostics,
},
});
const controller = new AbortController();
const lateInvalid = await new BinaryLayoutService({
inspectAndClose(input, options) {
return this.inspect(input, options);
},
identity: BINARY_LAYOUT_TEST_PROVIDER,
inspect: () => {
controller.abort();
return Promise.resolve(ok(fixture));
},
}).inspect(
{ path: "/artifacts/source-owned.elf" },
{ signal: controller.signal },
);
expect(lateInvalid).toMatchObject({
ok: false,
error: { _tag: "AnalysisOutputError" },
});
},
);