import { describe, expect, it } from "vitest";
import {
formatNativeServiceDoctorResult,
inferInstalledNativeServiceMode,
inspectInstalledDevelopmentServiceInput,
inspectInstalledProductionServiceContext,
runNativeServiceDoctor,
type InstalledNativeServiceDefinition,
type NativeServiceDoctorTarget,
} from "./serviceDoctor.js";
import {
createDevelopmentNativeServicePlan,
type NativeServiceAuthoritativeProbe,
type NativeServicePlan,
type ProductionNativeServicePlanInput,
} from "./servicePlan.js";
import { renderLaunchdPlist, renderSystemdUnit } from "./serviceRendering.js";
const shell = {
name: "zsh",
executable: "/bin/zsh",
source: "detected",
detectedExecutable: "/bin/zsh",
} as const;
function productionInput(configured = false): ProductionNativeServicePlanInput {
return {
backend: { kind: "systemd", label: "systemd user services" },
shell,
environment: { PI_WEB_CONFIG: "/home/user/config.json" },
executables: {
sessiond: {
configuredCommand: configured ? "custom sessiond --flag" : undefined,
namedCommand: "pi-web-sessiond",
bundledEntrypointPath: "/package/sessiond.js",
},
web: {
configuredCommand: configured ? "custom web --flag" : undefined,
namedCommand: "pi-web-server",
bundledEntrypointPath: "/package/server.js",
},
},
};
}
function probeWithStatus(status: "satisfied" | "unsatisfied"): NativeServiceAuthoritativeProbe {
return {
run: (request) => Promise.resolve({
kind: "completed",
outcomes: request.prerequisites.map((prerequisite) => ({
prerequisiteId: prerequisite.id,
status,
detail: status === "satisfied" ? null : `${prerequisite.id} missing in manager context`,
})),
}),
};
}
function developmentPlan(kind: "systemd" | "launchd"): NativeServicePlan {
return createDevelopmentNativeServicePlan({
backend: { kind, label: kind },
shell,
environment: { PI_WEB_CONFIG: "/home/user/config & dev.json" },
workingDirectory: "/checkout with space",
packageJsonPath: "/checkout with space/package.json",
});
}
function renderedDefinitions(plan: NativeServicePlan): InstalledNativeServiceDefinition[] {
return plan.services.map((service) => ({
id: service.id,
contents: plan.backend.kind === "systemd"
? renderSystemdUnit(plan, service)
: renderLaunchdPlist(plan, service, "/tmp/logs"),
}));
}
describe("installed native-service mode and definition inspection", () => {
it("infers production, development, absent, and ambiguous service sets", () => {
expect(inferInstalledNativeServiceMode(new Set())).toBe("none");
expect(inferInstalledNativeServiceMode(new Set(["sessiond", "web"]))).toBe("production");
expect(inferInstalledNativeServiceMode(new Set(["sessiond", "uiDev"]))).toBe("development");
expect(inferInstalledNativeServiceMode(new Set(["web", "uiDev"]))).toBe("ambiguous");
expect(inferInstalledNativeServiceMode(new Set(["sessiond"]))).toBe("ambiguous");
});
it.each(["systemd", "launchd"] as const)("reconstructs an exact installed development input from %s definitions", (kind) => {
const plan = developmentPlan(kind);
expect(inspectInstalledDevelopmentServiceInput(plan.backend, renderedDefinitions(plan))).toEqual({
ok: true,
value: {
backend: plan.backend,
shell,
environment: { PI_WEB_CONFIG: "/home/user/config & dev.json" },
workingDirectory: "/checkout with space",
packageJsonPath: "/checkout with space/package.json",
},
});
});
it("reconstructs escaped systemd paths, substitutions, and line controls exactly", () => {
const plan = createDevelopmentNativeServicePlan({
backend: { kind: "systemd", label: "systemd" },
shell: {
name: "zsh",
executable: "/shell $HOME/%h/zsh",
source: "detected",
detectedExecutable: "/shell $HOME/%h/zsh",
},
environment: { PI_WEB_CONFIG: "/config/%h\nnext" },
workingDirectory: "/checkout %h\nnext",
packageJsonPath: "/checkout %h\nnext/package.json",
});
expect(inspectInstalledDevelopmentServiceInput(plan.backend, renderedDefinitions(plan))).toEqual({
ok: true,
value: {
backend: plan.backend,
shell: plan.shell,
environment: plan.services[0]?.environment,
workingDirectory: "/checkout %h\nnext",
packageJsonPath: "/checkout %h\nnext/package.json",
},
});
});
it("inspects legacy systemd definitions without /usr/bin/env or quoted working directories", () => {
const plan = developmentPlan("systemd");
const definitions = renderedDefinitions(plan).map((definition) => ({
...definition,
contents: definition.contents
.replace("ExecStart=/usr/bin/env ", "ExecStart=")
.replace("WorkingDirectory=/checkout\\x20with\\x20space", "WorkingDirectory=/checkout with space"),
}));
expect(inspectInstalledDevelopmentServiceInput(plan.backend, definitions)).toMatchObject({
ok: true,
value: { workingDirectory: "/checkout with space" },
});
});
it("rejects quoted systemd working directories that the manager treats as non-absolute", () => {
const plan = developmentPlan("systemd");
const definitions = renderedDefinitions(plan).map((definition) => ({
...definition,
contents: definition.contents.replace(
"WorkingDirectory=/checkout\\x20with\\x20space",
'WorkingDirectory="/checkout with space"',
),
}));
const inspection = inspectInstalledDevelopmentServiceInput(plan.backend, definitions);
expect(inspection.ok).toBe(false);
if (inspection.ok) throw new Error("Expected quoted working directory inspection to fail");
expect(inspection.message).toContain("invalid quoted working directory");
});
it("rejects unconsumed systemd environment syntax rather than checking a different context", () => {
const plan = developmentPlan("systemd");
const definitions = renderedDefinitions(plan).map((definition) => ({
...definition,
contents: definition.contents.replace("[Service]\n", "[Service]\nEnvironment=PATH=/custom/bin\n"),
}));
const inspection = inspectInstalledDevelopmentServiceInput(plan.backend, definitions);
expect(inspection.ok).toBe(false);
if (inspection.ok) throw new Error("Expected systemd environment inspection to fail");
expect(inspection.message).toContain("environment entry");
});
it.each([
'Environment="PI_WEB_CONFIG=/config" "PATH=/broken"',
"EnvironmentFile=/tmp/pi-web.env",
])("rejects noncanonical systemd environment context: %s", (directive) => {
const plan = developmentPlan("systemd");
const definitions = renderedDefinitions(plan).map((definition) => ({
...definition,
contents: definition.contents.replace("[Service]\n", `[Service]\n${directive}\n`),
}));
expect(inspectInstalledDevelopmentServiceInput(plan.backend, definitions).ok).toBe(false);
});
it("rejects duplicate systemd ExecStart directives", () => {
const plan = developmentPlan("systemd");
const definitions = renderedDefinitions(plan).map((definition) => ({
...definition,
contents: definition.contents.replace(
"Restart=no",
'ExecStart=/usr/bin/env "/bin/zsh" -lc "exec true"\nRestart=no',
),
}));
const inspection = inspectInstalledDevelopmentServiceInput(plan.backend, definitions);
expect(inspection.ok).toBe(false);
if (inspection.ok) throw new Error("Expected duplicate ExecStart inspection to fail");
expect(inspection.message).toContain("exactly one recognized ExecStart");
});
it("rejects malformed launchd environment dictionaries rather than dropping entries", () => {
const plan = developmentPlan("launchd");
const definitions = renderedDefinitions(plan).map((definition) => ({
...definition,
contents: definition.contents.replace(
" \n RunAtLoad",
" BROKEN\n 1\n \n RunAtLoad",
),
}));
const inspection = inspectInstalledDevelopmentServiceInput(plan.backend, definitions);
expect(inspection.ok).toBe(false);
if (inspection.ok) throw new Error("Expected launchd environment inspection to fail");
expect(inspection.message).toContain("environment dictionary");
});
it("rejects a modified development command rather than claiming to check the installed plan", () => {
const plan = developmentPlan("systemd");
const definitions = renderedDefinitions(plan);
const firstDefinition = definitions[0];
if (firstDefinition === undefined) throw new Error("Expected a rendered service definition");
definitions[0] = {
...firstDefinition,
contents: firstDefinition.contents.replace("exec npm run start:sessiond", "exec npm run something-else"),
};
const inspection = inspectInstalledDevelopmentServiceInput(plan.backend, definitions);
expect(inspection.ok).toBe(false);
if (inspection.ok) throw new Error("Expected development inspection to fail");
expect(inspection.message).toContain("does not match the canonical development plan");
});
it("recovers production shell and environment while leaving executable strategy prospective", () => {
const plan = developmentPlan("launchd");
const firstService = plan.services[0];
if (firstService === undefined) throw new Error("Expected a development service");
const productionService = { ...firstService, workingDirectory: null };
const productionPlan: NativeServicePlan = { ...plan, mode: "production", services: [productionService] };
const productionLike = [{
id: "sessiond" as const,
contents: renderLaunchdPlist(productionPlan, productionService, "/tmp/logs"),
}];
expect(inspectInstalledProductionServiceContext(plan.backend, productionLike)).toEqual({
ok: true,
value: {
shell,
environment: { PI_WEB_CONFIG: "/home/user/config & dev.json" },
},
});
});
});
describe("native-service doctor planning and reporting", () => {
it("validates installed development requirements without production binary checks", async () => {
const plan = developmentPlan("launchd");
const inspected = inspectInstalledDevelopmentServiceInput(plan.backend, renderedDefinitions(plan));
if (!inspected.ok) throw new Error(inspected.message);
const result = await runNativeServiceDoctor(
{ kind: "installed-development", input: inspected.value },
{ probe: probeWithStatus("satisfied"), fileExists: () => false },
);
const report = formatNativeServiceDoctorResult(result);
expect(report.ok).toBe(true);
expect(report.lines).toContain("Installed development native-service plan:");
expect(report.plan?.services.flatMap((service) => service.prerequisites)).not.toEqual(
expect.arrayContaining([expect.objectContaining({ command: "pi-web-server" })]),
);
});
it("does not recommend PATH changes for checkout metadata failures", async () => {
const plan = developmentPlan("systemd");
const inspected = inspectInstalledDevelopmentServiceInput(plan.backend, renderedDefinitions(plan));
if (!inspected.ok) throw new Error(inspected.message);
const result = await runNativeServiceDoctor(
{ kind: "installed-development", input: inspected.value },
{
probe: {
run: (request) => Promise.resolve({
kind: "completed",
outcomes: request.prerequisites.map((prerequisite) => ({
prerequisiteId: prerequisite.id,
status: prerequisite.kind === "package-scripts" ? "unsatisfied" as const : "satisfied" as const,
detail: prerequisite.kind === "package-scripts" ? "scripts missing" : null,
})),
}),
},
fileExists: () => true,
},
);
const report = formatNativeServiceDoctorResult(result);
expect(report).toMatchObject({ ok: false, failureKind: "requirements", pathAdviceRecommended: false });
});
it("labels a production check as prospective and reports manager-context requirements", async () => {
const target: NativeServiceDoctorTarget = {
kind: "prospective-production",
input: productionInput(),
reason: "installed executable strategy is not recorded",
};
const result = await runNativeServiceDoctor(target, {
probe: probeWithStatus("unsatisfied"),
fileExists: () => true,
});
const report = formatNativeServiceDoctorResult(result);
expect(report.ok).toBe(false);
expect(report.failureKind).toBe("requirements");
expect(report.lines[0]).toContain("Prospective production native-service plan");
expect(report.lines.join("\n")).toContain("Native service requirement failed");
expect(report.failedPrerequisites).toEqual(expect.arrayContaining([
expect.objectContaining({ kind: "node-version" }),
expect.objectContaining({ kind: "readable-file" }),
]));
});
it("retains the installed production shell when resolution fails before a plan exists", async () => {
const result = await runNativeServiceDoctor(
{ kind: "prospective-production", input: productionInput(), reason: "installed strategy is unknown" },
{ probe: probeWithStatus("unsatisfied"), fileExists: () => false },
);
const report = formatNativeServiceDoctorResult(result);
expect(report).toMatchObject({
ok: false,
failureKind: "requirements",
plan: null,
adviceShell: shell,
pathAdviceRecommended: true,
});
});
it("preserves configured overrides as unverified and does not probe arbitrary commands", async () => {
let calls = 0;
const result = await runNativeServiceDoctor(
{ kind: "prospective-production", input: productionInput(true), reason: "current configured overrides" },
{
probe: { run: () => { calls += 1; return Promise.resolve({ kind: "completed", outcomes: [] }); } },
fileExists: () => false,
},
);
const report = formatNativeServiceDoctorResult(result);
expect(calls).toBe(1);
expect(report.ok).toBe(true);
expect(report.lines.join("\n")).toContain("does not execute arbitrary configured commands");
});
it.each(["manager", "timeout", "malformed-output", "cleanup"] as const)(
"distinguishes %s infrastructure failures from PATH requirement drift",
async (reason) => {
const result = await runNativeServiceDoctor(
{ kind: "prospective-production", input: productionInput(), reason: "no installed services" },
{
probe: { run: () => Promise.resolve({ kind: "infrastructure-failure", reason, message: `${reason} failure` }) },
fileExists: () => true,
},
);
const report = formatNativeServiceDoctorResult(result);
expect(report.ok).toBe(false);
expect(report.failureKind).toBe("infrastructure");
expect(report.lines.join("\n")).toContain(`infrastructure failure (${reason})`);
expect(report.lines.join("\n")).toContain("not proof of a PATH mismatch");
},
);
it("makes mixed or malformed installed definitions a failing inspection result", async () => {
const result = await runNativeServiceDoctor(
{ kind: "inspection-failure", message: "production and development service IDs are both installed" },
{ probe: probeWithStatus("satisfied"), fileExists: () => true },
);
const report = formatNativeServiceDoctorResult(result);
expect(report).toMatchObject({ ok: false, failureKind: "inspection" });
expect(report.lines.join("\n")).toContain("could not be inspected");
});
});