test(process): expose unavailable capture and unexpected teardown failures
This commit is contained in:
parent
6b92002597
commit
90b06db6c0
|
|
@ -1,52 +1,55 @@
|
|||
import { rm, writeFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { expect, it } from "vitest";
|
||||
import { expect } from "vitest";
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
import { itWithCaptureCapability } from "./processCaptureCapability.js";
|
||||
|
||||
import {
|
||||
captureProcessScenario,
|
||||
probeProcessCaptureCapability,
|
||||
} from "../../../src/process/capture/ProcessHarness.js";
|
||||
import { captureProcessScenario } from "../../../src/process/capture/ProcessHarness.js";
|
||||
import { parseProcessScenario } from "../../../src/domain/process/processCapture.js";
|
||||
|
||||
it("captures one command's terminal output, selected files, and owned cleanup", async () => {
|
||||
const root = await createTestTempDirectory("rea-process-capture-");
|
||||
const script = join(root, "task.mjs");
|
||||
await writeFile(
|
||||
script,
|
||||
[
|
||||
'import { writeFile } from "node:fs/promises";',
|
||||
"process.stdout.write(`value:${process.env.CAPTURE_VALUE}\\n`);",
|
||||
'await writeFile("state.txt", "created");',
|
||||
].join("\n"),
|
||||
);
|
||||
try {
|
||||
const capability = await probeProcessCaptureCapability();
|
||||
if (!capability.available) return;
|
||||
const result = await captureProcessScenario(
|
||||
parseProcessScenario({
|
||||
executable: process.execPath,
|
||||
arguments: [script],
|
||||
working_directory: root,
|
||||
environment: { CAPTURE_VALUE: "caller-selected" },
|
||||
filesystem_observation_paths: ["."],
|
||||
}),
|
||||
itWithCaptureCapability(
|
||||
"captures one command's terminal output, selected files, and owned cleanup",
|
||||
async () => {
|
||||
const root = await createTestTempDirectory("rea-process-capture-");
|
||||
const script = join(root, "task.mjs");
|
||||
await writeFile(
|
||||
script,
|
||||
[
|
||||
'import { writeFile } from "node:fs/promises";',
|
||||
"process.stdout.write(`value:${process.env.CAPTURE_VALUE}\\n`);",
|
||||
'await writeFile("state.txt", "created");',
|
||||
].join("\n"),
|
||||
);
|
||||
if (!result.ok) throw result.error;
|
||||
expect(result.value.frames.map(({ data }) => data).join("")).toContain(
|
||||
"value:caller-selected",
|
||||
);
|
||||
expect(result.value.files_after).toContainEqual(
|
||||
expect.objectContaining({ path: "root_0:state.txt" }),
|
||||
);
|
||||
expect(result.value.filesystem_effects).toContainEqual(
|
||||
expect.objectContaining({ status: "created", path: "root_0:state.txt" }),
|
||||
);
|
||||
expect(result.value.cleanup).toEqual({
|
||||
owned_process_group: "verified",
|
||||
temporary_root: "removed",
|
||||
});
|
||||
} finally {
|
||||
await rm(root, { recursive: true, force: true });
|
||||
}
|
||||
}, 20_000);
|
||||
try {
|
||||
const result = await captureProcessScenario(
|
||||
parseProcessScenario({
|
||||
executable: process.execPath,
|
||||
arguments: [script],
|
||||
working_directory: root,
|
||||
environment: { CAPTURE_VALUE: "caller-selected" },
|
||||
filesystem_observation_paths: ["."],
|
||||
}),
|
||||
);
|
||||
if (!result.ok) throw result.error;
|
||||
expect(result.value.frames.map(({ data }) => data).join("")).toContain(
|
||||
"value:caller-selected",
|
||||
);
|
||||
expect(result.value.files_after).toContainEqual(
|
||||
expect.objectContaining({ path: "root_0:state.txt" }),
|
||||
);
|
||||
expect(result.value.filesystem_effects).toContainEqual(
|
||||
expect.objectContaining({
|
||||
status: "created",
|
||||
path: "root_0:state.txt",
|
||||
}),
|
||||
);
|
||||
expect(result.value.cleanup).toEqual({
|
||||
owned_process_group: "verified",
|
||||
temporary_root: "removed",
|
||||
});
|
||||
} finally {
|
||||
await rm(root, { recursive: true, force: true });
|
||||
}
|
||||
},
|
||||
20_000,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { fileURLToPath } from "node:url";
|
|||
import { expect, onTestFinished } from "vitest";
|
||||
import { AndroidAnalysisService } from "../../../src/application/android/AndroidAnalysisService.js";
|
||||
import { createAndroidAnalysisProvider } from "../../../src/composition/android.js";
|
||||
import { ProviderCleanupError } from "../../../src/domain/providerCleanupError.js";
|
||||
import {
|
||||
ProviderProcessSupervisor,
|
||||
spawnOwnedProviderProcess,
|
||||
|
|
@ -74,7 +75,18 @@ export const createJadxProtocolFixture = async (mode = "normal") => {
|
|||
return spawned;
|
||||
},
|
||||
);
|
||||
onTestFinished(() => provider.close().catch(() => undefined));
|
||||
onTestFinished(async () => {
|
||||
try {
|
||||
await provider.close();
|
||||
} catch (cause) {
|
||||
if (
|
||||
mode !== "cleanup-failure" ||
|
||||
!(cause instanceof ProviderCleanupError) ||
|
||||
cause.providerId !== "jadx"
|
||||
)
|
||||
throw cause;
|
||||
}
|
||||
});
|
||||
return {
|
||||
service: new AndroidAnalysisService(provider),
|
||||
provider,
|
||||
|
|
|
|||
Loading…
Reference in New Issue