Files
rea/tests/boundary/native/pwntoolsArtifactCleanup.test.ts
gensokyo-dev e18594b247 refactor(composition): unify capability bindings and cleanup ownership (#8441)
Bind typed service creation, observed availability and retryable cleanup in one composition owner. Reuse selected CLI/MCP factories and canonical contract groups without copying provider operation inventories.

Closes #8429. Refs #740.

Validated paired real application workflows, actual local Codex CLI Terra/high use, complete Evidence and Unknown checkpoint parity, compiler-backed import boundaries, SDK schemas and final real mixed routing. Automated review findings were fixed at their producing owners. Existing exact-base CodeQL alerts are documented on the PR under the owner-authorized unrelated-check exception; no global alerts or security rules were changed.

Assisted-by: Suika (gensokyo-skills:suika-scatter-gather-planning)
2026-11-01 13:30:21 +08:00

433 lines
15 KiB
TypeScript

import { createHash } from "node:crypto";
import { mkdtemp, rm, writeFile, readFile, mkdir } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { expect, it, vi } from "vitest";
import { z } from "zod";
const closeState = vi.hoisted(() => ({
fail: false,
failOnce: false,
opened: 0,
closes: 0,
replyFail: false,
abort: undefined as AbortController | undefined,
inputAbort: undefined as AbortController | undefined,
}));
vi.mock("node:fs/promises", async (importOriginal) => {
const fs = await importOriginal<typeof import("node:fs/promises")>();
return {
...fs,
open: async (...args: Parameters<typeof fs.open>) => {
const handle = await fs.open(...args);
closeState.opened++;
const close = handle.close.bind(handle);
handle.close = async () => {
closeState.closes++;
if (String(args[0]).endsWith("selected.bin"))
closeState.inputAbort?.abort("selected-close-cancel");
if (String(args[0]).endsWith("reply.json")) {
closeState.abort?.abort("reply-close-cancel");
if (closeState.replyFail)
throw new Error("injected reply close failure");
}
if (closeState.fail || closeState.failOnce) {
closeState.failOnce = false;
throw new Error("injected stable artifact close failure");
}
return close();
};
return handle;
},
};
});
import { PwntoolsRecordedCrashProvider } from "../../../src/native/pwntools/PwntoolsRecordedCrashProvider.js";
import {
recordedCrashFixture,
recordedCrashFixtureBytes,
recordedCrashDebuggerFixture,
} from "../../fixtures/binaryDiagnostics/recordedCrash.js";
import { PwntoolsLayoutProvider } from "../../../src/native/pwntools/PwntoolsLayoutProvider.js";
import { PrivateRuntimeRoot } from "../../../src/process/PrivateRuntimeRoot.js";
import { prepareProcessOwnershipInspection } from "../../../src/process/ProcessOwnershipObservation.js";
import { spawnOwnedProviderProcess } from "../../../src/process/ProviderProcess.js";
import { binaryLayoutFixture } from "../../fixtures/binaryDiagnostics/layout.js";
import { PwntoolsDecoder } from "../../../src/native/pwntools/PwntoolsDecoder.js";
import { PWNTOOLS_PROVIDER_IDENTITY } from "../../../src/native/pwntools/PwntoolsProviderIdentity.js";
import { projectAnalysisError } from "../../../src/domain/analysisErrorProjection.js";
const makeDecoder = () =>
new PwntoolsDecoder(
{
identity: PWNTOOLS_PROVIDER_IDENTITY,
operation: "test_pwntools_artifact_read",
bridge: new URL("file:///unused-bridge.py"),
payloadSchema: z.string(),
project: () => {
throw new Error("input read should fail before decoder launch");
},
},
{ REA_PWNTOOLS_PYTHON: process.execPath },
undefined,
async () => {
throw new Error("runtime should not be created for failed input read");
},
);
const emulateSupportedHost = async (
run: () => Promise<void>,
): Promise<void> => {
const platform = Object.getOwnPropertyDescriptor(process, "platform");
const arch = Object.getOwnPropertyDescriptor(process, "arch");
Object.defineProperty(process, "platform", { ...platform, value: "linux" });
Object.defineProperty(process, "arch", { ...arch, value: "x64" });
try {
await run();
} finally {
if (platform !== undefined)
Object.defineProperty(process, "platform", platform);
if (arch !== undefined) Object.defineProperty(process, "arch", arch);
}
};
it("reports the read failure without stale incomplete-cleanup state when close retry succeeds", async () =>
emulateSupportedHost(async () => {
const root = await mkdtemp(join(tmpdir(), "rea-pwntools-close-retry-"));
const path = join(root, "selected.bin");
await writeFile(path, "selected evidence");
closeState.fail = false;
closeState.failOnce = true;
closeState.opened = 0;
closeState.closes = 0;
const decoder = makeDecoder();
try {
const result = await decoder.inspect({ path });
expect(result.ok).toBe(false);
if (result.ok) throw new Error("Injected close failure was not returned");
expect(result.error.partialObservation).toEqual({
kind: "file-snapshot-hash",
path,
bytes: 17,
sha256: createHash("sha256").update("selected evidence").digest("hex"),
});
expect(result.error.cleanupIncomplete).toBe(false);
expect(projectAnalysisError(result.error).code).not.toBe(
"cleanup_incomplete",
);
expect(result.error.cause).toMatchObject({
cleanup: {
resources: [path],
reason: expect.stringContaining(
"injected stable artifact close failure",
),
},
});
expect(closeState.closes).toBeGreaterThanOrEqual(2);
} finally {
closeState.fail = false;
closeState.failOnce = false;
await decoder.close();
await rm(root, { recursive: true, force: true });
}
}));
it("retains a persistent failed input descriptor and refuses the next acquisition", async () =>
emulateSupportedHost(async () => {
const root = await mkdtemp(join(tmpdir(), "rea-pwntools-held-close-"));
const path = join(root, "selected.bin");
await writeFile(path, "selected evidence");
closeState.fail = true;
closeState.failOnce = false;
closeState.opened = 0;
closeState.closes = 0;
const decoder = makeDecoder();
try {
const first = await decoder.inspect({ path });
expect(first.ok).toBe(false);
if (first.ok)
throw new Error("Persistent close failure was not returned");
expect(projectAnalysisError(first.error).code).toBe("cleanup_incomplete");
const openedAfterFailure = closeState.opened;
const retry = await decoder.inspect({ path });
expect(retry.ok).toBe(false);
if (retry.ok) throw new Error("Retained descriptor was not retried");
expect(projectAnalysisError(retry.error).code).toBe("cleanup_incomplete");
expect(closeState.opened).toBe(openedAfterFailure);
await expect(decoder.close()).rejects.toMatchObject({
cleanupIncomplete: true,
});
closeState.fail = false;
await decoder.close();
} finally {
closeState.fail = false;
closeState.failOnce = false;
try {
await decoder.close();
} catch {
// The test already asserts persistent cleanup failure before releasing it.
}
await rm(root, { recursive: true, force: true });
}
}));
it("retains selected target identity when cancellation arrives after its completed read", async () =>
emulateSupportedHost(async () => {
const root = await mkdtemp(join(tmpdir(), "rea-pwntools-input-cancel-"));
const path = join(root, "selected.bin");
await writeFile(path, "selected evidence");
closeState.inputAbort = new AbortController();
const decoder = makeDecoder();
try {
const result = await decoder.inspect(
{ path },
{ signal: closeState.inputAbort.signal },
);
expect(result.ok).toBe(false);
if (result.ok)
throw new Error("input finalization unexpectedly succeeded");
expect(projectAnalysisError(result.error).code).toBe("cancelled");
expect(result.error.cause).toBe("selected-close-cancel");
expect(result.error.partialObservation).toEqual({
kind: "file-snapshot-hash",
path,
bytes: 17,
sha256: createHash("sha256").update("selected evidence").digest("hex"),
});
} finally {
closeState.inputAbort = undefined;
await decoder.close();
await rm(root, { recursive: true, force: true });
}
}));
// Simulated decoder writes a reply; the selected object is never executed.
it("retains admitted layout through reply close failure and cancellation, then resolves cleanup", async () => {
await prepareProcessOwnershipInspection();
await emulateSupportedHost(async () => {
const root = await mkdtemp(join(tmpdir(), "rea-pwntools-reply-close-"));
const path = join(root, "selected.bin");
await writeFile(path, Buffer.alloc(128));
const runtime = await PrivateRuntimeRoot.create({
parent: root,
prefix: "worker-",
});
const {
artifact: _artifact,
diagnostics: _diagnostics,
...payload
} = binaryLayoutFixture(path);
closeState.replyFail = true;
closeState.abort = new AbortController();
const provider = new PwntoolsLayoutProvider(
{ REA_PWNTOOLS_PYTHON: process.execPath },
async (spawn) => {
const request = JSON.parse(
await readFile(join(runtime.path, "request.json"), "utf8"),
) as { reply_path: string };
return spawnOwnedProviderProcess({
...spawn,
arguments: [
"-e",
'require("node:fs").writeFileSync(process.argv[1], process.argv[2])',
request.reply_path,
JSON.stringify({
ok: true,
profile: PWNTOOLS_PROVIDER_IDENTITY.version,
value: payload,
}),
],
});
},
async () => runtime,
);
try {
const result = await provider.inspect(
{ path },
{ signal: closeState.abort.signal },
);
expect(result.ok).toBe(false);
if (result.ok)
throw new Error("reply finalization unexpectedly succeeded");
expect(result.error.cleanupIncomplete).toBe(true);
expect(result.error.partialObservation).toMatchObject({
artifact: { path, bytes: 128 },
});
expect(projectAnalysisError(result.error)).toMatchObject({
code: "cleanup_incomplete",
});
closeState.replyFail = false;
closeState.abort = undefined;
await provider.close();
expect(result.error.cleanupIncomplete).toBe(false);
expect(projectAnalysisError(result.error)).toMatchObject({
code: "cancelled",
});
} finally {
closeState.replyFail = false;
closeState.abort = undefined;
await provider.close();
await rm(root, { recursive: true, force: true });
}
});
});
it.each([
"normal",
"close",
"cancel",
"cancel-close",
"invalid-source",
"invalid-source-cancel",
"malformed-cancel",
"invalid-profile",
"malformed",
] as const)(
"admits base core facts before optional debugger enrichment: %s",
async (scenario) => {
await prepareProcessOwnershipInspection();
await emulateSupportedHost(async () => {
const root = await mkdtemp(join(tmpdir(), "rea-pwntools-core-reply-"));
const path = join(root, "selected.core");
const value = recordedCrashFixture(path);
await writeFile(path, recordedCrashFixtureBytes(value));
const runtime = await PrivateRuntimeRoot.create({
parent: root,
prefix: "worker-",
});
const plugin = join(root, "gdbinit.py");
const venv = join(root, "venv");
await writeFile(plugin, "# simulated debugger fixture");
await mkdir(venv);
const {
artifact: _artifact,
diagnostics: _diagnostics,
debugger: _debugger,
decoder_diagnostics: _decoderDiagnostics,
...payload
} = value;
if (scenario === "invalid-source" || scenario === "invalid-source-cancel")
payload.notes[0]!.owner_bytes_base64 =
Buffer.from("FAKE\0").toString("base64");
closeState.replyFail =
scenario !== "normal" &&
scenario !== "cancel" &&
scenario !== "invalid-source-cancel" &&
scenario !== "malformed-cancel";
closeState.abort =
scenario === "cancel-close" ||
scenario === "cancel" ||
scenario === "invalid-source-cancel" ||
scenario === "malformed-cancel"
? new AbortController()
: undefined;
let launches = 0;
const provider = new PwntoolsRecordedCrashProvider(
{
REA_PWNTOOLS_PYTHON: process.execPath,
REA_PWNDBG_GDB: process.execPath,
REA_PWNDBG_GDBINIT: plugin,
REA_PWNDBG_VENV_PATH: venv,
},
async (spawn) => {
launches++;
const request = JSON.parse(
await readFile(
join(spawn.cwd ?? runtime.path, "request.json"),
"utf8",
),
) as { reply_path: string };
const reply =
launches === 1
? {
ok: true,
profile:
scenario === "invalid-profile"
? "foreign-profile"
: PWNTOOLS_PROVIDER_IDENTITY.version,
value: payload,
}
: { ok: true, value: recordedCrashDebuggerFixture() };
return spawnOwnedProviderProcess({
...spawn,
arguments: [
"-e",
'require("node:fs").writeFileSync(process.argv[1], process.argv[2])',
request.reply_path,
scenario === "malformed" || scenario === "malformed-cancel"
? "{broken"
: JSON.stringify(reply),
],
});
},
async () => runtime,
);
try {
const result = await provider.inspect(
{ path, include_debugger_context: true },
closeState.abort === undefined
? undefined
: { signal: closeState.abort.signal },
);
expect(launches).toBe(scenario === "normal" ? 2 : 1);
if (scenario === "normal") {
expect(result.ok).toBe(true);
if (result.ok) expect(result.value.debugger.status).toBe("available");
} else {
expect(result.ok).toBe(false);
if (result.ok)
throw new Error("reply finalization unexpectedly succeeded");
if (
scenario === "close" ||
scenario === "cancel-close" ||
scenario === "cancel"
) {
expect(result.error.partialObservation).toMatchObject({
artifact: { path, bytes: value.artifact.bytes },
debugger: { status: "unavailable", requested: true },
});
} else expect(result.error.partialObservation).toBeUndefined();
closeState.replyFail = false;
closeState.abort = undefined;
await provider.close();
expect(result.error.cleanupIncomplete).toBe(false);
if (
scenario === "invalid-source" ||
scenario === "invalid-profile" ||
scenario === "malformed" ||
scenario === "invalid-source-cancel" ||
scenario === "malformed-cancel"
)
expect(projectAnalysisError(result.error).code).toBe(
"unreadable_output",
);
if (
scenario === "invalid-source-cancel" ||
scenario === "malformed-cancel"
) {
expect(projectAnalysisError(result.error)).toMatchObject({
code: "unreadable_output",
details: {
diagnostics: {
reply_finalization_error: { code: "cancelled" },
},
},
});
expect(
result.error.diagnostics?.reply_finalization_error,
).not.toHaveProperty("captured_output");
}
}
} finally {
closeState.replyFail = false;
closeState.abort = undefined;
await provider.close();
await rm(root, { recursive: true, force: true });
}
});
},
);