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

117 lines
4.0 KiB
TypeScript

import { expect, it, vi } from "vitest";
import { awaitAcknowledgement } from "../../tests/fixtures/lifecycleAcknowledgement.js";
import { CapabilityScope } from "./CapabilityScope.js";
it("retains each failed cleanup while releasing successful peers across retries", async () => {
const scope = new CapabilityScope("Controlled mixed capability cleanup");
const synchronousFailure = new Error("Synchronous close refusal");
const asynchronousFailure = new Error("Asynchronous close refusal");
let allowSynchronous = false;
let allowAsynchronous = false;
const successful = vi.fn(async () => undefined);
const synchronous = vi.fn(() => {
if (!allowSynchronous) throw synchronousFailure;
return Promise.resolve();
});
const asynchronous = vi.fn(async () => {
if (!allowAsynchronous) throw asynchronousFailure;
});
const rejectedWithoutReason = vi.fn(() =>
allowAsynchronous ? Promise.resolve() : Promise.reject(undefined),
);
scope.own("released-peer", {}, successful);
scope.own("synchronous-owner", {}, synchronous);
scope.own("asynchronous-owner", {}, asynchronous);
scope.own("undefined-rejection-owner", {}, rejectedWithoutReason);
try {
const first: unknown = await scope.close().catch((cause: unknown) => cause);
expect(first).toBeInstanceOf(AggregateError);
if (!(first instanceof AggregateError))
throw new Error("Expected all cleanup failures");
expect(first.message).toBe("Controlled mixed capability cleanup");
expect(first.errors).toEqual([
synchronousFailure,
asynchronousFailure,
undefined,
]);
for (const close of [
successful,
synchronous,
asynchronous,
rejectedWithoutReason,
])
expect(close).toHaveBeenCalledTimes(1);
expect(() => scope.own("late-owner", {}, successful)).toThrow(
"after host shutdown",
);
allowAsynchronous = true;
const second: unknown = await scope
.close()
.catch((cause: unknown) => cause);
expect(second).toBeInstanceOf(AggregateError);
if (!(second instanceof AggregateError))
throw new Error("Expected the remaining owner failure");
expect(second.errors).toEqual([synchronousFailure]);
expect(successful).toHaveBeenCalledTimes(1);
expect(synchronous).toHaveBeenCalledTimes(2);
expect(asynchronous).toHaveBeenCalledTimes(2);
expect(rejectedWithoutReason).toHaveBeenCalledTimes(2);
allowSynchronous = true;
await scope.close();
await scope.close();
expect(synchronous).toHaveBeenCalledTimes(3);
expect(successful).toHaveBeenCalledTimes(1);
expect(asynchronous).toHaveBeenCalledTimes(2);
expect(rejectedWithoutReason).toHaveBeenCalledTimes(2);
} finally {
allowSynchronous = true;
allowAsynchronous = true;
await scope.close();
}
});
it("joins concurrent shutdowns and seals ownership before asynchronous cleanup settles", async () => {
const scope = new CapabilityScope();
let acknowledge = () => {};
const entered = new Promise<void>((resolve) => {
acknowledge = resolve;
});
let release = () => {};
const released = new Promise<void>((resolve) => {
release = resolve;
});
const close = vi.fn(async () => {
acknowledge();
await released;
});
scope.own("controlled-owner", {}, close);
const first = scope.close();
let second: Promise<void> | undefined;
try {
await awaitAcknowledgement(entered, first, "capability cleanup");
second = scope.close();
expect(second).toBe(first);
expect(close).toHaveBeenCalledTimes(1);
expect(() => scope.own("later-owner", {}, async () => undefined)).toThrow(
"after host shutdown",
);
release();
await Promise.all([first, second]);
expect(() =>
scope.own("post-shutdown-owner", {}, async () => undefined),
).toThrow("after host shutdown");
await scope.close();
expect(close).toHaveBeenCalledTimes(1);
} finally {
release();
await Promise.allSettled([
first,
...(second === undefined ? [] : [second]),
]);
await scope.close();
}
});