mirror of
https://github.com/morluto/rea.git
synced 2026-11-15 11:13:21 +00:00
* fix(verifiers): release fixture roots only after their owners finish Several real-tool verifiers released a fixture root even when a cleanup that still used it had failed, so a surviving MCP server, session or descendant kept running against a deleted directory and the failure looked like ordinary cleanup. - scripts/lib/verifier-cleanup.mjs: new releaseAfter(dependents, release, retained) task. It attempts every dependent cleanup and releases the resource only if all succeed; otherwise it keeps the resource and reports it with the dependent failures. - verify-signal-recording: the root is released after the MCP client and transport close, and the host-limits read moves before the root is acquired so its failure cannot leak the root. - verify-recorded-crash: sessions, the sentinel and the process-lineage check must all succeed before the root is released. A transport close failure after a failed connect keeps the connect failure. - verify-wasm-artifact: both roots are released after the MCP client and transport close; the residue check and the two directories stay independent after that. - verify-native-ui: `open -W` exits only after the app exits, so the root is removed only once that exit is observed; otherwise it is retained and reported. Fixes #8561 Fixes #8562 Fixes #8564 Refs #8559 Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(verifiers): treat a signaled open as unproven fixture exit A terminated `open` launcher does not prove the LaunchServices app it started has exited, so only an `open -W` that exits on its own counts. Also clear the grace timer so a prompt exit does not hold the process for the rest of the grace period. Refs #8559 Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(verifiers): model open -W exiting after the fixture is signaled The native UI verifier now removes its root only after `open -W` exits on its own. The authored recording's `open` never exited when the fixture was signaled and had no signalCode, so the complete case waited out the grace period and kept the root. The double now behaves like `open -W`: it exits once the fixture process is signaled. Refs #8559 Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: gensokyo-dev <gensokyo-dev@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
58 lines
1.6 KiB
TypeScript
58 lines
1.6 KiB
TypeScript
import { expect, it } from "vitest";
|
|
import {
|
|
closeVerifierResources,
|
|
releaseAfter,
|
|
} from "../../../scripts/lib/verifier-cleanup.mjs";
|
|
|
|
it("releases a root only after every dependent cleanup succeeds", async () => {
|
|
const order: string[] = [];
|
|
await closeVerifierResources([
|
|
releaseAfter(
|
|
[
|
|
async () => {
|
|
order.push("client");
|
|
},
|
|
async () => {
|
|
order.push("transport");
|
|
},
|
|
],
|
|
async () => {
|
|
order.push("root");
|
|
},
|
|
"/fixture/root",
|
|
),
|
|
]);
|
|
expect(order).toEqual(["client", "transport", "root"]);
|
|
});
|
|
|
|
it("retains the root and reports every dependent failure", async () => {
|
|
const order: string[] = [];
|
|
const clientFailure = new Error("client close failed");
|
|
const failure = await closeVerifierResources([
|
|
releaseAfter(
|
|
[
|
|
async () => {
|
|
order.push("client");
|
|
throw clientFailure;
|
|
},
|
|
async () => {
|
|
order.push("transport");
|
|
},
|
|
],
|
|
async () => {
|
|
order.push("root");
|
|
},
|
|
"/fixture/root",
|
|
),
|
|
]).catch((cause: unknown) => cause);
|
|
// The later dependent is still attempted, but the root is not released.
|
|
expect(order).toEqual(["client", "transport"]);
|
|
expect(failure).toBeInstanceOf(AggregateError);
|
|
const [retention] = (failure as AggregateError).errors;
|
|
expect(retention).toBeInstanceOf(AggregateError);
|
|
expect((retention as AggregateError).errors).toEqual([
|
|
clientFailure,
|
|
new Error("Retained /fixture/root because a dependent cleanup failed."),
|
|
]);
|
|
});
|