refactor: share launchd bootstrap ordering assertions

This commit is contained in:
Peter Steinberger 2026-03-13 19:12:58 +00:00
parent feba7ea8fd
commit cba07a400a
1 changed files with 21 additions and 28 deletions

View File

@ -31,6 +31,25 @@ const launchdRestartHandoffState = vi.hoisted(() => ({
})); }));
const defaultProgramArguments = ["node", "-e", "process.exit(0)"]; const defaultProgramArguments = ["node", "-e", "process.exit(0)"];
function expectLaunchctlEnableBootstrapOrder(env: Record<string, string | undefined>) {
const domain = typeof process.getuid === "function" ? `gui/${process.getuid()}` : "gui/501";
const label = "ai.openclaw.gateway";
const plistPath = resolveLaunchAgentPlistPath(env);
const serviceId = `${domain}/${label}`;
const enableIndex = state.launchctlCalls.findIndex(
(c) => c[0] === "enable" && c[1] === serviceId,
);
const bootstrapIndex = state.launchctlCalls.findIndex(
(c) => c[0] === "bootstrap" && c[1] === domain && c[2] === plistPath,
);
expect(enableIndex).toBeGreaterThanOrEqual(0);
expect(bootstrapIndex).toBeGreaterThanOrEqual(0);
expect(enableIndex).toBeLessThan(bootstrapIndex);
return { domain, label, serviceId, bootstrapIndex };
}
function normalizeLaunchctlArgs(file: string, args: string[]): string[] { function normalizeLaunchctlArgs(file: string, args: string[]): string[] {
if (file === "launchctl") { if (file === "launchctl") {
return args; return args;
@ -219,25 +238,12 @@ describe("launchd bootstrap repair", () => {
const repair = await repairLaunchAgentBootstrap({ env }); const repair = await repairLaunchAgentBootstrap({ env });
expect(repair.ok).toBe(true); expect(repair.ok).toBe(true);
const domain = typeof process.getuid === "function" ? `gui/${process.getuid()}` : "gui/501"; const { serviceId, bootstrapIndex } = expectLaunchctlEnableBootstrapOrder(env);
const label = "ai.openclaw.gateway";
const plistPath = resolveLaunchAgentPlistPath(env);
const serviceId = `${domain}/${label}`;
const enableIndex = state.launchctlCalls.findIndex(
(c) => c[0] === "enable" && c[1] === serviceId,
);
const bootstrapIndex = state.launchctlCalls.findIndex(
(c) => c[0] === "bootstrap" && c[1] === domain && c[2] === plistPath,
);
const kickstartIndex = state.launchctlCalls.findIndex( const kickstartIndex = state.launchctlCalls.findIndex(
(c) => c[0] === "kickstart" && c[1] === "-k" && c[2] === serviceId, (c) => c[0] === "kickstart" && c[1] === "-k" && c[2] === serviceId,
); );
expect(enableIndex).toBeGreaterThanOrEqual(0);
expect(bootstrapIndex).toBeGreaterThanOrEqual(0);
expect(kickstartIndex).toBeGreaterThanOrEqual(0); expect(kickstartIndex).toBeGreaterThanOrEqual(0);
expect(enableIndex).toBeLessThan(bootstrapIndex);
expect(bootstrapIndex).toBeLessThan(kickstartIndex); expect(bootstrapIndex).toBeLessThan(kickstartIndex);
}); });
}); });
@ -258,23 +264,10 @@ describe("launchd install", () => {
programArguments: defaultProgramArguments, programArguments: defaultProgramArguments,
}); });
const domain = typeof process.getuid === "function" ? `gui/${process.getuid()}` : "gui/501"; const { serviceId } = expectLaunchctlEnableBootstrapOrder(env);
const label = "ai.openclaw.gateway";
const plistPath = resolveLaunchAgentPlistPath(env);
const serviceId = `${domain}/${label}`;
const enableIndex = state.launchctlCalls.findIndex(
(c) => c[0] === "enable" && c[1] === serviceId,
);
const bootstrapIndex = state.launchctlCalls.findIndex(
(c) => c[0] === "bootstrap" && c[1] === domain && c[2] === plistPath,
);
const installKickstartIndex = state.launchctlCalls.findIndex( const installKickstartIndex = state.launchctlCalls.findIndex(
(c) => c[0] === "kickstart" && c[2] === serviceId, (c) => c[0] === "kickstart" && c[2] === serviceId,
); );
expect(enableIndex).toBeGreaterThanOrEqual(0);
expect(bootstrapIndex).toBeGreaterThanOrEqual(0);
expect(enableIndex).toBeLessThan(bootstrapIndex);
expect(installKickstartIndex).toBe(-1); expect(installKickstartIndex).toBe(-1);
}); });