mirror of
https://github.com/morluto/rea.git
synced 2026-11-09 16:26:36 +00:00
test(process): bind cleanup fixtures to selected resources
This commit is contained in:
1 parent
5d5fe72218
commit
95382c2ba0
3 files changed
+39
-8
No files matched your search
@@ -281,16 +281,26 @@ it
|
||||
} satisfies Parameters<typeof validateVerifierJadxConfiguration>[0];
|
||||
const script = String.raw`
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs';
|
||||
import { syncBuiltinESMExports } from 'node:module';
|
||||
import { validateVerifierJadxConfiguration } from ${JSON.stringify(new URL("../../../scripts/lib/jadx-configuration-inspection.mjs", import.meta.url).href)};
|
||||
import { OwnedFileHandle } from ${JSON.stringify(new URL("../../../dist/filesystem/OwnedFileHandle.js", import.meta.url).href)};
|
||||
import { ArtifactResourceRetryFailure } from ${JSON.stringify(new URL("../../../dist/artifacts/ArtifactResourceScope.js", import.meta.url).href)};
|
||||
const [serializedConfiguration, mode] = process.argv.slice(1);
|
||||
const configuration = JSON.parse(serializedConfiguration);
|
||||
const handles = new Set();
|
||||
const originalOpen = fs.promises.open;
|
||||
fs.promises.open = async (...args) => {
|
||||
const handle = await originalOpen(...args);
|
||||
if (args[0] === configuration.jar) handles.add(handle);
|
||||
return handle;
|
||||
};
|
||||
syncBuiltinESMExports();
|
||||
let attempts = 0, denied = true;
|
||||
const originalClose = OwnedFileHandle.prototype.close;
|
||||
OwnedFileHandle.prototype.close = async function () {
|
||||
handles.add(this.handle); attempts++;
|
||||
if (!handles.has(this.handle)) return originalClose.call(this);
|
||||
attempts++;
|
||||
if ((mode === 'retry-close' && attempts === 1) || (mode === 'retained-close' && denied)) throw new Error('controlled archive close refusal');
|
||||
return originalClose.call(this);
|
||||
};
|
||||
@@ -317,6 +327,8 @@ it
|
||||
} finally {
|
||||
denied = false;
|
||||
OwnedFileHandle.prototype.close = originalClose;
|
||||
fs.promises.open = originalOpen;
|
||||
syncBuiltinESMExports();
|
||||
for (const handle of handles) await handle.close();
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createHash, randomUUID } from "node:crypto";
|
||||
import { execFile } from "node:child_process";
|
||||
import { ChildProcess, execFile } from "node:child_process";
|
||||
import { access, chmod, open, readFile, rm, writeFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { promisify } from "node:util";
|
||||
@@ -72,6 +72,9 @@ for (const deniedStops of [0, 2])
|
||||
`retains a timed-out private-display probe through cleanup retry (denied stops=${String(deniedStops)})`,
|
||||
async () => {
|
||||
const directory = await createTestTempDirectory("rea-probe-owner-retry-");
|
||||
const helperPath = fileURLToPath(
|
||||
new URL("../../../fixtures/x11ProbeHang.py", import.meta.url),
|
||||
);
|
||||
const originalStop = ProviderProcessSupervisor.prototype.stop;
|
||||
const captured: { current?: ProviderProcessSupervisor } = {};
|
||||
let attempts = 0;
|
||||
@@ -81,6 +84,11 @@ for (const deniedStops of [0, 2])
|
||||
this: ProviderProcessSupervisor,
|
||||
settings,
|
||||
) {
|
||||
if (
|
||||
!(this.launch.process instanceof ChildProcess) ||
|
||||
!this.launch.process.spawnargs.includes(helperPath)
|
||||
)
|
||||
return originalStop.call(this, settings);
|
||||
captured.current = this;
|
||||
attempts += 1;
|
||||
return attempts <= deniedStops
|
||||
@@ -105,9 +113,7 @@ for (const deniedStops of [0, 2])
|
||||
selectPrivateDisplay: (settings) =>
|
||||
selectLinuxPrivateDisplayStrategy({
|
||||
...settings,
|
||||
helperPath: fileURLToPath(
|
||||
new URL("../../../fixtures/x11ProbeHang.py", import.meta.url),
|
||||
),
|
||||
helperPath,
|
||||
timeoutMs: 75,
|
||||
}),
|
||||
},
|
||||
@@ -124,7 +130,14 @@ for (const deniedStops of [0, 2])
|
||||
expect(projectAnalysisError(original).details).toMatchObject({
|
||||
diagnostics: { reason: "probe_timeout" },
|
||||
});
|
||||
expect(original.cleanupIncomplete).toBe(deniedStops > 0);
|
||||
const initiallyPending = original.cleanupIncomplete;
|
||||
if (deniedStops > 0) expect(initiallyPending).toBe(true);
|
||||
if (initiallyPending)
|
||||
expect(original.cleanupResources).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.stringMatching(/^hopper-private-display-probe:/u),
|
||||
]),
|
||||
);
|
||||
const supervisor = captured.current;
|
||||
if (supervisor === undefined)
|
||||
throw new Error("Expected the real owned probe");
|
||||
@@ -142,7 +155,9 @@ for (const deniedStops of [0, 2])
|
||||
supervisor.launch.process.exitCode !== null ||
|
||||
supervisor.launch.process.signalCode !== null,
|
||||
).toBe(true);
|
||||
expect(attempts).toBe(deniedStops + 1);
|
||||
const expectedAttempts =
|
||||
deniedStops === 0 && initiallyPending ? 2 : deniedStops + 1;
|
||||
expect(attempts).toBe(expectedAttempts);
|
||||
} finally {
|
||||
stop.mockRestore();
|
||||
if (captured.current !== undefined)
|
||||
|
||||
@@ -17,6 +17,7 @@ const gates = vi.hoisted(() => {
|
||||
hashClose: createGate(),
|
||||
identityRead: createGate(),
|
||||
opens: 0,
|
||||
selectedPath: null as string | null,
|
||||
failClose: false,
|
||||
holdHashClose: false,
|
||||
holdIdentityRead: false,
|
||||
@@ -33,6 +34,7 @@ vi.mock("../../../../src/filesystem/RegularFile.js", async (importOriginal) => {
|
||||
openRegularFile: vi.fn(
|
||||
async (...args: Parameters<typeof original.openRegularFile>) => {
|
||||
const descriptor = await original.openRegularFile(...args);
|
||||
if (args[0] !== gates.selectedPath) return descriptor;
|
||||
const { handle } = descriptor;
|
||||
const index = gates.opens++;
|
||||
const read = handle.read.bind(handle);
|
||||
@@ -71,6 +73,7 @@ import { session } from "./kunaSessionFixture.js";
|
||||
|
||||
beforeEach(() => {
|
||||
gates.opens = 0;
|
||||
gates.selectedPath = null;
|
||||
gates.failClose = false;
|
||||
gates.holdHashClose = false;
|
||||
gates.holdIdentityRead = false;
|
||||
@@ -91,6 +94,7 @@ it
|
||||
async (phase) => {
|
||||
const root = await createTestTempDirectory("rea-kuna-inspection-lifetime-");
|
||||
const executable = await writeFakeKuna(root);
|
||||
gates.selectedPath = executable;
|
||||
const scope = new ArtifactResourceScope();
|
||||
const resourceScope: RetainedResourceScope = {
|
||||
retain: (owner, resource) =>
|
||||
@@ -157,7 +161,7 @@ it
|
||||
gates.hashClose.release();
|
||||
gates.identityRead.release();
|
||||
const fixture = await session("rea-kuna-session-finalization-");
|
||||
gates.opens = 0;
|
||||
gates.selectedPath = fixture.kuna;
|
||||
gates.hashClose = gates.createGate();
|
||||
gates.identityRead = gates.createGate();
|
||||
gates.holdHashClose = phase !== "identity-read";
|
||||
|
||||
Reference in new issue
Block a user