Files
reverse-engineering-anything/tests/boundary/process/providerVerifierCleanup.test.ts
T
morluto 72ba1cd92b fix(verifiers): centralize failure and cleanup ownership
Own operation results and exact rejections in withVerifierCleanup, including
undefined, null and independent cleanup failures. Remove the optional-primary
cleanup contract and migrate every caller, preserving returns, annotations,
signal restoration and dependent cleanup order.

Make Frida/JEB reporters fail on reasonless rejections and retain JEB fixture
files while provider cleanup is incomplete. Own the nested packaged WASM
verifier and expose its composite process/root cleanup capability for retry.
Update runnable docs and isolated fixture dependencies.

Validation: 547 focused cases in 20 files, eight isolated boundary unit checks,
static/build/docs/discovery gates and duplication check (3.58%). Node process,
SDK and descriptor cleanup are exercised; provider and packaging results in
orchestration tests are simulated. Pack/install subprocess ownership remains
with the existing shared package runner outside the nested-command change.
2026-10-24 15:38:35 +08:00

179 lines
6.0 KiB
TypeScript

import {
copyFile,
mkdir,
readFile,
readdir,
writeFile,
} from "node:fs/promises";
import { join } from "node:path";
import { expect } from "vitest";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { processTest } from "../../support/process/processFixture.js";
type Provider = "frida" | "jeb";
type Primary = "undefined" | "null" | "success";
const cases = (["frida", "jeb"] as const).flatMap((provider) =>
[
{ primary: "undefined", closeFails: false },
{ primary: "null", closeFails: false },
{ primary: "undefined", closeFails: true },
{ primary: "success", closeFails: true },
].map(({ primary, closeFails }) => ({
provider,
primary: primary as Primary,
closeFails,
})),
);
/** Copy the actual script; substitute only the engine-facing module boundary. */
const verifierFixture = async (provider: Provider) => {
const root = await createTestTempDirectory("rea-provider-verifier-cleanup-");
const temporary = join(root, "temporary");
await mkdir(temporary);
await mkdir(join(root, "scripts", "lib"), { recursive: true });
await mkdir(join(root, "dist", "application", provider), { recursive: true });
await writeFile(join(root, "package.json"), '{"type":"module"}\n');
const script = join(root, "scripts", `verify-${provider}.mjs`);
await copyFile(
new URL(`../../../scripts/verify-${provider}.mjs`, import.meta.url),
script,
);
await copyFile(
new URL("../../../scripts/lib/verifier-cleanup.mjs", import.meta.url),
join(root, "scripts", "lib", "verifier-cleanup.mjs"),
);
const closeBody = `
await appendFile(process.env.REA_TEST_VERIFIER_CLOSE_LOG, "${provider}\\n");
if (process.env.REA_TEST_VERIFIER_CLOSE_FAIL === "1")
throw new Error("controlled ${provider} cleanup denial");
`;
const primaryBody = `
if (process.env.REA_TEST_VERIFIER_PRIMARY === "undefined") throw undefined;
if (process.env.REA_TEST_VERIFIER_PRIMARY === "null") throw null;
`;
if (provider === "frida") {
await mkdir(join(root, "dist", "frida"));
await mkdir(join(root, "dist", "contracts"));
await writeFile(
join(root, "dist", "frida", "FridaInstrumentationManager.js"),
`import { appendFile } from "node:fs/promises";
export class FridaInstrumentationManager {
async closeAll() { ${closeBody} }
}
`,
);
await writeFile(
join(
root,
"dist",
"application",
"frida",
"FridaInstrumentationService.js",
),
`export class FridaInstrumentationService {
async instrument() {
${primaryBody}
return { ok: true, value: {
cleanupError: null,
evidence: { normalized_result: {
pid: 77,
messages: [{ type: "send", payload: { rea_frida_verification: "ok", pid: 77 } }],
} },
} };
}
}
`,
);
await writeFile(
join(root, "dist", "contracts", "fridaRemoteAddress.js"),
"export const isValidFridaRemoteAddress = () => false;\n",
);
} else {
await mkdir(join(root, "dist", "composition"));
await writeFile(
join(root, "dist", "composition", "jeb.js"),
`import { appendFile } from "node:fs/promises";
export const createJebAnalysisProvider = () => ({
async close() { ${closeBody} },
});
`,
);
await writeFile(
join(root, "dist", "application", "jeb", "JebAnalysisService.js"),
`export class JebAnalysisService {
async execute(operation) {
${primaryBody}
const result = {
inspect_jeb_client: { engine: { version: "simulated", gui_client: false, endpoint: "simulated" } },
open_jeb_project: { input_files: [{ contents_sha256_hash: "${"a".repeat(64)}" }] },
list_jeb_units: { units: [{ id: "simulated-unit" }] },
decompile_jeb_item: { text: "simulated marker" },
}[operation];
if (result === undefined) throw new Error("Unexpected simulated operation: " + operation);
return { ok: true, value: { normalized_result: result } };
}
}
`,
);
}
return { root, script, temporary, closeLog: join(root, "close.log") };
};
// These are simulated provider outcomes exercising real verifier orchestration;
// they establish no Frida instrumentation or JEB engine behavior.
processTest.for(cases)(
"$provider verifier preserves primary=$primary with closeFails=$closeFails",
async ({ provider, primary, closeFails }, { processes }) => {
const fixture = await verifierFixture(provider);
const result = await processes.run(
process.execPath,
[
fixture.script,
...(provider === "jeb"
? ["--item-address", "simulated-item", "--marker", "simulated marker"]
: []),
],
{
cwd: fixture.root,
env: {
...process.env,
TMPDIR: fixture.temporary,
TEMP: fixture.temporary,
TMP: fixture.temporary,
REA_TEST_VERIFIER_PRIMARY: primary,
REA_TEST_VERIFIER_CLOSE_FAIL: closeFails ? "1" : "0",
REA_TEST_VERIFIER_CLOSE_LOG: fixture.closeLog,
},
timeoutMs: 10_000,
},
);
expect(result.signal, result.stderr).toBeNull();
expect(result.exitCode, result.stderr).toBe(1);
const reasons = [
...(primary === "success" ? [] : [primary]),
...(closeFails ? [`controlled ${provider} cleanup denial`] : []),
];
const label = provider === "frida" ? "Frida" : "JEB";
const retained = await readdir(fixture.temporary);
let retainedMessage = "";
if (provider === "jeb" && closeFails) {
expect(retained).toHaveLength(1);
const name = retained[0];
if (name === undefined) throw new Error("Missing retained JEB fixture");
expect(name).toMatch(/^rea-jeb-/u);
retainedMessage = `JEB fixture retained at ${join(fixture.temporary, name)}\n`;
} else expect(retained).toEqual([]);
expect(result.stderr).toBe(
`${retainedMessage}${label} real-provider verification failed: ${reasons.join("; ")}\n`,
);
expect(result.stdout).toBe("");
expect(await readFile(fixture.closeLog, "utf8")).toBe(`${provider}\n`);
},
);