Files

65 lines
2.6 KiB
TypeScript

import { mkdir, rm, writeFile } from "node:fs/promises";
import { expect, it } from "vitest";
import { ApktoolCommandCleanup } from "../../../src/apktool/ApktoolCommandCleanup.js";
import { inspectApktoolClient } from "../../../src/apktool/ApktoolConfiguration.js";
import { createApktoolProcessFixture } from "../../fixtures/apktoolProcessTree.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { observePosixProcess } from "../../support/process/observePosixProcess.js";
it
.skipIf(process.platform === "win32")
.each(["malformed", "unreadable"] as const)(
"retains fixture cleanup ownership when its published marker becomes %s",
async (failure) => {
const root = await createTestTempDirectory("rea-apktool-marker-failure-");
const fixture = await createApktoolProcessFixture(root, "probe");
await expect(fixture.readMarker()).resolves.toBeUndefined();
const commands = new ApktoolCommandCleanup();
const controller = new AbortController();
const probe = inspectApktoolClient(
{ command: fixture.command, commandSource: "environment" },
commands,
{ signal: controller.signal, environment: process.env },
).catch((cause: unknown) => cause);
try {
await expect
.poll(async () => (await fixture.readMarker())?.ready, {
timeout: 10_000,
interval: 25,
})
.toBe(true);
const marker = await fixture.readMarker();
if (marker === undefined) throw new Error("Fixture marker disappeared");
const pids = [marker.rootPid, marker.childPid];
expect(await Promise.all(pids.map(observePosixProcess))).toEqual([
expect.objectContaining({ kind: "running" }),
expect.objectContaining({ kind: "running" }),
]);
if (failure === "malformed") {
await writeFile(fixture.markerPath, "not-json");
} else {
await rm(fixture.markerPath);
await mkdir(fixture.markerPath);
}
await expect(fixture.readMarker()).rejects.toThrow();
// No cancellation has run: fallback teardown must use the last valid
// token owner even when the current marker cannot be read or parsed.
await expect(fixture.cleanup()).rejects.toThrow();
await expect
.poll(
async () =>
(await Promise.all(pids.map(observePosixProcess))).every(
({ kind }) => kind !== "running",
),
{ timeout: 5_000, interval: 25 },
)
.toBe(true);
} finally {
controller.abort();
await fixture.cleanup([probe, commands.close()]);
}
},
30_000,
);