89 lines
2.6 KiB
TypeScript
89 lines
2.6 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
|
|
import type { ProcessOwnershipHost } from "./ProcessOwnership.js";
|
|
import {
|
|
observeProcessStartIdentity,
|
|
signalProcessWithStartIdentity,
|
|
} from "./ProcessOwnershipObservation.js";
|
|
|
|
const host = (identity: string | undefined): ProcessOwnershipHost => ({
|
|
platform: "linux",
|
|
listProcesses: async () =>
|
|
identity === undefined
|
|
? []
|
|
: [
|
|
{
|
|
pid: 42,
|
|
parentPid: 1,
|
|
processGroupId: 42,
|
|
uid: 1000,
|
|
state: "S",
|
|
command: "/bin/fixture",
|
|
},
|
|
],
|
|
environment: async () => ({}),
|
|
processIdentities: async () =>
|
|
new Map([[42, { state: "readable", identity: identity ?? "" }]]),
|
|
signalGroup: () => undefined,
|
|
});
|
|
|
|
describe("process start identity lease", () => {
|
|
it("captures a readable identity for a live PID", async () => {
|
|
await expect(
|
|
observeProcessStartIdentity(42, host("start-1")),
|
|
).resolves.toEqual({
|
|
state: "readable",
|
|
identity: "start-1",
|
|
});
|
|
});
|
|
|
|
it("signals the PID when its launch identity still matches", async () => {
|
|
const sendSignal = vi.fn();
|
|
await expect(
|
|
signalProcessWithStartIdentity(42, "start-1", "SIGKILL", {
|
|
host: host("start-1"),
|
|
sendSignal,
|
|
}),
|
|
).resolves.toBe("signaled");
|
|
expect(sendSignal).toHaveBeenCalledWith(42, "SIGKILL");
|
|
});
|
|
|
|
it("does not signal a reused PID even when its command is unchanged", async () => {
|
|
const sendSignal = vi.fn();
|
|
await expect(
|
|
signalProcessWithStartIdentity(42, "start-1", "SIGKILL", {
|
|
host: host("start-2"),
|
|
sendSignal,
|
|
}),
|
|
).resolves.toBe("identity-changed");
|
|
expect(sendSignal).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("does not signal when the PID identity is unavailable", async () => {
|
|
const unavailable: ProcessOwnershipHost = {
|
|
...host("start-1"),
|
|
processIdentities: async () =>
|
|
new Map([[42, { state: "unavailable", reason: "reader unavailable" }]]),
|
|
};
|
|
const sendSignal = vi.fn();
|
|
await expect(
|
|
signalProcessWithStartIdentity(42, "start-1", "SIGKILL", {
|
|
host: unavailable,
|
|
sendSignal,
|
|
}),
|
|
).resolves.toBe("unverified");
|
|
expect(sendSignal).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("reports an already-gone PID without signaling", async () => {
|
|
const sendSignal = vi.fn();
|
|
await expect(
|
|
signalProcessWithStartIdentity(42, "start-1", "SIGKILL", {
|
|
host: host(undefined),
|
|
sendSignal,
|
|
}),
|
|
).resolves.toBe("gone");
|
|
expect(sendSignal).not.toHaveBeenCalled();
|
|
});
|
|
});
|