morluto/rea, scoped to src/application/reverse, at 87a5be3000: the project's own tests caught 27 of 38 planted faults, 11 got through, and corral proved 7 of those missing tests by writing a test and running it.
import { expect, it, vi } from "vitest";
import { ReverseEngineeringService, type ReverseEngineeringServiceOptions, digestFile } from "../../src/application/reverse/ReverseEngineeringService.ts";
import { createReverseEngineeringCommandPort } from "../../src/composition/reverseEngineering.js";
import { OwnedCommandFailure } from "../../src/process/OwnedCommand.js";
import type { ProviderProcessSupervisor } from "../../src/process/ProviderProcess.js";
import { createReadStream } from "node:fs";
import { once } from "node:events";
import { fileURLToPath } from "node:url";
it("corral retains an ordinary command cleanup failure until its owner finishes cleanup", async () => {
let corralCleanupComplete = false;
const corralStop = vi.fn(async () =>
corralCleanupComplete
? { status: "complete" as const }
: { status: "incomplete" as const, reason: "process remains alive" },
);
const corralOwner: NonNullable<OwnedCommandFailure["cleanupOwner"]> =
Object.create(null);
Object.defineProperty(corralOwner, "stop", { value: corralStop });
const corralOwnedFailure: OwnedCommandFailure = Object.create(
OwnedCommandFailure.prototype,
);
Object.defineProperties(corralOwnedFailure, {
reason: { value: "cleanup" },
cleanupOwner: { value: corralOwner },
cleanupFailure: { value: "process remains alive" },
resources: { value: [] },
collectionFailure: { value: false },
snapshot: {
value: {
exitCode: 0,
signal: null,
diagnosticTruncated: false,
stdout: { text: "observed output", bytes: 15, invalidUtf8: false },
stderr: { text: "", bytes: 0, invalidUtf8: false },
},
},
});
const corralRunOwned = vi.fn<
NonNullable<ReverseEngineeringServiceOptions["runOwned"]>
>();
corralRunOwned.mockRejectedValue(corralOwnedFailure);
const corralService = new ReverseEngineeringService({
commands: createReverseEngineeringCommandPort({}),
runOwned: corralRunOwned,
});
try {
const corralFirst = await corralService.inspectWithObjdump({
operation: "architectures",
});
expect(corralFirst.ok).toBe(false);
if (corralFirst.ok) throw new Error("Expected incomplete provider cleanup");
expect(corralFirst.error).toMatchObject({
_tag: "AnalysisOutputError",
cleanupIncomplete: true,
});
const corralBlocked = await corralService.inspectWithObjdump({
operation: "architectures",
});
expect(corralBlocked).toMatchObject({
ok: false,
error: { _tag: "AnalysisOutputError", cleanupIncomplete: true },
});
expect(corralRunOwned).toHaveBeenCalledTimes(1);
expect(corralStop).toHaveBeenCalledTimes(1);
expect(corralFirst.error.cleanupIncomplete).toBe(true);
corralCleanupComplete = true;
expect(await corralService.retryCleanup()).toMatchObject({ ok: true });
expect(corralStop).toHaveBeenCalledTimes(2);
expect(corralFirst.error.cleanupIncomplete).toBe(false);
if (corralBlocked.ok) throw new Error("Expected admission to be blocked");
expect(corralBlocked.error.cleanupIncomplete).toBe(false);
} finally {
corralCleanupComplete = true;
await corralService.close();
}
});
it("corral resolves the original cleanup failure only after its retained owner finishes cleanup", async () => {
let corralCleanupComplete = false;
const corralStop = vi.fn(async () =>
corralCleanupComplete
? { status: "complete" as const }
: { status: "incomplete" as const, reason: "provider still alive" },
);
const corralOwnedFailure = Object.assign(
Object.create(OwnedCommandFailure.prototype) as OwnedCommandFailure,
{
reason: "cleanup",
cleanupFailure: "provider still alive",
cleanupOwner: { stop: corralStop },
resources: [],
collectionFailure: false,
snapshot: {
stdout: { text: "elf64-x86-64", bytes: 12, invalidUtf8: false },
stderr: { text: "", bytes: 0, invalidUtf8: false },
exitCode: 0,
signal: null,
diagnosticTruncated: false,
},
},
);
const corralRunOwned = vi.fn(async (): Promise<never> => {
throw corralOwnedFailure;
});
const corralService = new ReverseEngineeringService({
commands: createReverseEngineeringCommandPort({}),
runOwned: corralRunOwned,
});
try {
const corralFirst = await corralService.inspectWithObjdump({
operation: "architectures",
});
expect(corralFirst.ok).toBe(false);
if (corralFirst.ok) throw new Error("Expected incomplete cleanup failure");
expect(corralFirst.error).toMatchObject({
_tag: "AnalysisOutputError",
cleanupIncomplete: true,
});
expect(corralRunOwned).toHaveBeenCalledTimes(1);
const corralBlocked = await corralService.inspectWithObjdump({
operation: "architectures",
});
expect(corralBlocked).toMatchObject({
ok: false,
error: {
_tag: "AnalysisOutputError",
cleanupIncomplete: true,
},
});
expect(corralStop).toHaveBeenCalledTimes(1);
expect(corralRunOwned).toHaveBeenCalledTimes(1);
expect(corralFirst.error.cleanupIncomplete).toBe(true);
corralCleanupComplete = true;
expect(await corralService.retryCleanup()).toMatchObject({ ok: true });
expect(corralStop).toHaveBeenCalledTimes(2);
// The original caller's failure must observe the completed cleanup too.
expect(corralFirst.error.cleanupIncomplete).toBe(false);
if (corralBlocked.ok) throw new Error("Expected admission to be blocked");
expect(corralBlocked.error.cleanupIncomplete).toBe(false);
await corralService.close();
expect(
await corralService.inspectWithObjdump({ operation: "architectures" }),
).toMatchObject({ ok: false });
expect(corralRunOwned).toHaveBeenCalledTimes(1);
} finally {
corralCleanupComplete = true;
await corralService.close();
}
});
it("retains cleanup obligations when provider launch fails and blocks another command", async () => {
const corralStop = vi.fn(async () => ({
status: "incomplete" as const,
reason: "provider process group remains alive",
}));
const corralOwner = {
stop: corralStop,
} as unknown as ProviderProcessSupervisor;
const corralLaunchFailure = Object.setPrototypeOf(
Object.assign(new Error("provider launch failed with incomplete cleanup"), {
reason: "launch",
snapshot: null,
cleanupFailure: "provider process group remains alive",
cleanupOwner: corralOwner,
resources: [],
collectionFailure: false,
cause: Object.assign(new Error("executable unavailable"), {
code: "ENOENT",
}),
}),
OwnedCommandFailure.prototype,
) as OwnedCommandFailure;
const corralRunOwned = vi.fn(async () => {
throw corralLaunchFailure;
});
const corralService = new ReverseEngineeringService({
commands: createReverseEngineeringCommandPort({}),
runOwned: corralRunOwned,
});
const corralFirst = await corralService.inspectWithObjdump({
operation: "architectures",
});
expect(corralRunOwned).toHaveBeenCalledTimes(1);
expect(corralFirst).toMatchObject({
ok: false,
error: {
_tag: "AnalysisCapabilityUnavailableError",
cleanupIncomplete: true,
},
});
const corralSecond = await corralService.inspectWithObjdump({
operation: "architectures",
});
expect(corralSecond).toMatchObject({
ok: false,
error: {
_tag: "AnalysisOutputError",
cleanupIncomplete: true,
},
});
expect(corralStop).toHaveBeenCalledTimes(1);
expect(corralRunOwned).toHaveBeenCalledTimes(1);
});
it("corral retains access-denied cleanup ownership until the provider owner actually stops", async () => {
let corralCleanupComplete = false;
const corralStop = vi.fn(async () =>
corralCleanupComplete
? { status: "complete" as const }
: {
status: "incomplete" as const,
reason: "Provider descendants remain alive",
},
);
const corralResources: readonly string[] = [];
const corralFailure = Object.assign(
Object.create(OwnedCommandFailure.prototype) as Error,
{
reason: "exit",
cause: Object.assign(new Error("Permission denied"), { code: "EACCES" }),
snapshot: {
exitCode: "EACCES",
signal: null,
stdout: { text: "partial output", bytes: 14, invalidUtf8: false },
stderr: { text: "permission denied", bytes: 17, invalidUtf8: false },
diagnosticTruncated: false,
},
cleanupFailure: "Provider descendants remain alive",
cleanupOwner: { stop: corralStop },
resources: corralResources,
collectionFailure: false,
},
);
const corralRunOwned = vi.fn(async (): Promise<never> => {
throw corralFailure;
});
const corralService = new ReverseEngineeringService({
commands: createReverseEngineeringCommandPort({}),
runOwned: corralRunOwned,
});
try {
const corralDenied = await corralService.inspectWithObjdump({
operation: "architectures",
});
expect(corralDenied).toMatchObject({
ok: false,
error: {
_tag: "AnalysisAccessDeniedError",
cleanupIncomplete: true,
capturedOutput: {
stdout: "partial output",
stderr: "permission denied",
},
},
});
if (corralDenied.ok) throw new Error("Expected access denial");
const corralBlocked = await corralService.inspectWithObjdump({
operation: "architectures",
});
expect(corralBlocked).toMatchObject({
ok: false,
error: {
_tag: "AnalysisOutputError",
cleanupIncomplete: true,
},
});
expect(corralStop).toHaveBeenCalledTimes(1);
expect(corralRunOwned).toHaveBeenCalledTimes(1);
expect(corralDenied.error.cleanupIncomplete).toBe(true);
corralCleanupComplete = true;
expect(await corralService.retryCleanup()).toMatchObject({ ok: true });
expect(corralStop).toHaveBeenCalledTimes(2);
expect(corralDenied.error.cleanupIncomplete).toBe(false);
expect(corralRunOwned).toHaveBeenCalledTimes(1);
} finally {
corralCleanupComplete = true;
await corralService.close();
}
});
it("corral rejects summary requests without retention before launching a provider", async () => {
const corralProviderRun = vi.fn(async () => ({
stdout: "elf64-x86-64",
stderr: "",
}));
const corralService = new ReverseEngineeringService({
commands: createReverseEngineeringCommandPort({}),
run: corralProviderRun,
});
try {
const corralResult = await corralService.inspectWithObjdump({
operation: "architectures",
detail: "summary",
});
expect(corralResult.ok).toBe(false);
expect(corralProviderRun).not.toHaveBeenCalled();
} finally {
await corralService.close();
}
});
it("corral preserves every cleanup failure when concurrent commands retain the same owner", async () => {
let corralCleanupComplete = false;
const corralStop = vi.fn(async () => {
return (
corralCleanupComplete
? { status: "complete" }
: { status: "incomplete", reason: "provider is still alive" }
) as unknown as Awaited<ReturnType<ProviderProcessSupervisor["stop"]>>;
});
const corralOwner = {
stop: corralStop,
} as unknown as ProviderProcessSupervisor;
const corralRejectors: Array<(reason: unknown) => void> = [];
let corralAnnounceStarted: () => void = () => {
throw new Error("Startup barrier was not initialized");
};
const corralStarted = new Promise<void>((resolve) => {
corralAnnounceStarted = resolve;
});
const corralRunOwned = vi.fn<
NonNullable<ReverseEngineeringServiceOptions["runOwned"]>
>(
async () =>
await new Promise<never>((_resolve, reject) => {
corralRejectors.push(reject);
if (corralRejectors.length === 2) corralAnnounceStarted();
}),
);
const corralService = new ReverseEngineeringService({
commands: createReverseEngineeringCommandPort({}),
runOwned: corralRunOwned,
});
const corralFailure = (): OwnedCommandFailure =>
Object.assign(
Object.create(OwnedCommandFailure.prototype) as OwnedCommandFailure,
{
message: "Provider cleanup is incomplete",
reason: "timeout",
snapshot: null,
cleanupFailure: "provider is still alive",
cleanupOwner: corralOwner,
resources: [],
collectionFailure: false,
},
);
const corralFirstPromise = corralService.inspectWithObjdump({
operation: "architectures",
});
const corralSecondPromise = corralService.inspectWithObjdump({
operation: "architectures",
});
await corralStarted;
corralRejectors[0]!(corralFailure());
const corralFirst = await corralFirstPromise;
expect(corralFirst.ok).toBe(false);
if (corralFirst.ok) throw new Error("Expected first cleanup failure");
expect(corralFirst.error.cleanupIncomplete).toBe(true);
const corralBlocked = await corralService.inspectWithObjdump({
operation: "architectures",
});
expect(corralBlocked.ok).toBe(false);
if (corralBlocked.ok) throw new Error("Expected cleanup admission rejection");
expect(corralBlocked.error.cleanupIncomplete).toBe(true);
expect(corralRunOwned).toHaveBeenCalledTimes(2);
corralRejectors[1]!(corralFailure());
const corralSecond = await corralSecondPromise;
expect(corralSecond.ok).toBe(false);
if (corralSecond.ok) throw new Error("Expected second cleanup failure");
expect(corralSecond.error.cleanupIncomplete).toBe(true);
corralCleanupComplete = true;
expect(await corralService.retryCleanup()).toMatchObject({ ok: true });
expect(corralStop).toHaveBeenCalledTimes(2);
expect(corralFirst.error.cleanupIncomplete).toBe(false);
expect(corralBlocked.error.cleanupIncomplete).toBe(false);
expect(corralSecond.error.cleanupIncomplete).toBe(false);
await corralService.close();
});
it("corral clears the completed artifact digest deadline before it can destroy the stream again", async () => {
vi.useFakeTimers({ toFake: ["setTimeout", "clearTimeout"] });
const corralPath = fileURLToPath(
new URL("../../src/application/reverse/ReverseEngineeringService.ts", import.meta.url),
);
const corralStream = createReadStream(corralPath);
const corralClosed = once(corralStream, "close");
const corralDestroy = vi.spyOn(corralStream, "destroy");
try {
const corralDigest = await digestFile(
corralPath,
undefined,
undefined,
60_000,
() => corralStream,
);
await corralClosed;
expect(corralDigest).toMatch(/^[a-f0-9]{64}$/);
corralDestroy.mockClear();
await vi.advanceTimersByTimeAsync(60_001);
expect(corralDestroy).not.toHaveBeenCalled();
expect(vi.getTimerCount()).toBe(0);
} finally {
corralDestroy.mockRestore();
corralStream.destroy();
vi.useRealTimers();
}
});
A proven fault was caught by a test corral wrote and ran; an unproven one was not, so it may be a missing test or a fault no test can see.
s5/m2 · line 137 proven
- failures: this.#pendingCleanup.get(owner)?.failures ?? new Set(), + failures: new Set(),
s2/m3 · line 226 proven
- if (!ready.ok) return ready; + if (!ready.ok) void ready;
s0/m12 · line 550 proven
- { cause, ...ownedCleanupOptions(cause) },
+ { cause },s0/m18 · line 591 proven
- ...ownedCleanupOptions(cause),
s0/m5 · line 647 proven
- if (failure !== undefined && cleanupOwner !== undefined) + if (failure !== undefined && cleanupOwner === undefined)
s0/m8 · line 647 proven
- if (failure !== undefined && cleanupOwner !== undefined) + if (failure !== undefined && cleanupOwner !== undefined && !cleanupIncomplete)
s6/m3 · line 1042 proven
- clearTimeout(timer);
s0/m13 · line 526 unproven
- ...ownedCleanupOptions(cause),
s0/m14 · line 530 unproven
- ...ownedCleanupOptions(cause),
s0/m15 · line 541 unproven
- ...ownedCleanupOptions(cause),
s0/m6 · line 648 unproven
- failure = this.#registerCleanupFailure(failure, cleanupOwner); + failure = this.#registerCleanupFailure(failure, undefined);