Files
reverse-engineering-anything/src/application/binary/LazyAnalysisProvider.test.ts
T
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

141 lines
3.9 KiB
TypeScript

import { expect, it } from "vitest";
import { withVerifierCleanup } from "../../../scripts/lib/verifier-cleanup.mjs";
import { awaitAcknowledgement } from "../../../tests/fixtures/lifecycleAcknowledgement.js";
import { parseBinaryTarget } from "../BinaryTargetResolver.js";
import type {
AnalysisProvider,
ProviderIdentity,
} from "../AnalysisProvider.js";
import { createAnalysisExecution } from "../AnalysisProvider.js";
import { LazyAnalysisProvider } from "./LazyAnalysisProvider.js";
import { ok as resultOk } from "../../domain/result.js";
const identity: ProviderIdentity = {
id: "test-provider",
name: "Test provider",
version: "1",
};
const providerWithClient = (
onCreate: () => void = () => undefined,
): AnalysisProvider => ({
identity: () => identity,
capabilities: () => [],
createClient: () => {
onCreate();
return {
execute: async () => resultOk(createAnalysisExecution(null, identity)),
close: async () => resultOk(null),
};
},
});
const target = async () => {
const parsed = await parseBinaryTarget(process.execPath);
if (!parsed.ok) throw parsed.error;
return parsed.value;
};
it("returns a tagged provider error when lazy loading fails", async () => {
const provider = new LazyAnalysisProvider({
identity,
capabilities: [],
load: async () => {
throw new Error("provider module unavailable");
},
});
const result = await provider
.createClient(await target())
.execute("health", {});
expect(result).toMatchObject({
ok: false,
error: {
_tag: "ProviderAdapterError",
providerId: "test-provider",
operation: "health",
},
});
});
it("joins a cancelled unabortable module load and refuses late client acquisition", async () => {
let finishLoading!: (provider: AnalysisProvider) => void;
let enter!: () => void;
let creates = 0;
const entered = new Promise<void>((resolve) => {
enter = resolve;
});
const loading = new Promise<AnalysisProvider>((resolve) => {
finishLoading = resolve;
});
const provider = new LazyAnalysisProvider({
identity,
capabilities: [],
load: () => {
enter();
return loading;
},
});
const controller = new AbortController();
const reason = { request: "cancel during import" };
const client = provider.createClient(await target());
let settled = false;
const pending = client
.execute("health", {}, { signal: controller.signal })
.then((value) => {
settled = true;
return value;
});
await withVerifierCleanup(async () => {
await awaitAcknowledgement(entered, pending, "provider module load");
controller.abort(reason);
await new Promise<void>((resolve) => setImmediate(resolve));
expect(settled).toBe(false);
finishLoading(
providerWithClient(() => {
creates++;
}),
);
const result = await pending;
expect(result).toMatchObject({
ok: false,
error: { _tag: "AnalysisCancelledError", operation: "health" },
});
if (result.ok) throw new Error("Cancellation unexpectedly succeeded");
expect(result.error.cause).toBe(reason);
expect(creates).toBe(0);
expect(await client.close()).toEqual(resultOk(null));
}, [
() => controller.abort(),
() => finishLoading(providerWithClient()),
async () => {
await pending;
},
async () => {
const closed = await client.close();
if (!closed.ok) throw closed.error;
},
]);
});
it("reports that a lazy client was closed before its first operation", async () => {
const provider = new LazyAnalysisProvider({
identity,
capabilities: [],
load: async () => providerWithClient(),
});
const client = provider.createClient(await target());
await client.close();
expect(await client.execute("health", {})).toMatchObject({
ok: false,
error: {
_tag: "ProviderAdapterError",
operation: "health",
diagnostics: { reason: "client_closed" },
},
});
});