Files
reverse-engineering-anything/tests/process-global/verifierWorkspaceCleanup.test.ts
T
morluto 3ad2e214be fix(verifier): retain UF2 workspace until resource cleanup completes (#10096)
* fix(verifier): retain UF2 workspace until resource cleanup completes

* fix(verifiers): retain firmware workspace cleanup ownership
2026-11-11 18:53:02 +08:00

64 lines
2.4 KiB
TypeScript

import { access, mkdtemp, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { expect, it, vi } from "vitest";
it("preserves a pre-workspace failure and command cleanup failure", async () => {
const primary = new Error("tool lookup failed");
const cleanup = new Error("command cleanup failed");
const { withVerifierWorkspace } =
await import("../../scripts/lib/verifier-workspace.mjs");
const failure: unknown = await withVerifierWorkspace(
() => {
throw primary;
},
{ close: async () => Promise.reject(cleanup) },
() => undefined,
).catch((cause: unknown) => cause);
expect(failure).toBeInstanceOf(AggregateError);
expect((failure as AggregateError).cause).toBe(primary);
expect((failure as AggregateError).errors).toEqual([primary, cleanup]);
});
it("retains the parent lease when workspace removal fails after command close", async () => {
const root = await mkdtemp(join(tmpdir(), "rea-verifier-workspace-"));
const removal = new Error("controlled workspace removal failure");
await writeFile(join(root, "evidence"), "retained");
let denied = true;
vi.resetModules();
vi.doMock("node:fs/promises", async (importOriginal) => {
const actual = await importOriginal<typeof import("node:fs/promises")>();
return {
...actual,
rm: async (...args: Parameters<typeof rm>) => {
if (args[0] === root && denied) throw removal;
await actual.rm(...args);
},
};
});
try {
const { withVerifierWorkspace } =
await import("../../scripts/lib/verifier-workspace.mjs");
const failure: unknown = await withVerifierWorkspace(
() => "verified",
{ close: async () => undefined },
() => root,
).catch((cause: unknown) => cause);
expect(failure).toBeInstanceOf(Error);
const retained = failure as Error & {
cleanupLeases: { release(): Promise<void> }[];
};
expect((retained.cause as AggregateError).errors).toContain(removal);
expect(retained.cleanupLeases).toHaveLength(1);
await access(join(root, "evidence"));
await expect(retained.cleanupLeases[0]!.release()).rejects.toBe(removal);
denied = false;
await retained.cleanupLeases[0]!.release();
await expect(access(root)).rejects.toMatchObject({ code: "ENOENT" });
} finally {
vi.doUnmock("node:fs/promises");
vi.resetModules();
await rm(root, { recursive: true, force: true });
}
});