


























@@ -109,6 +109,10 @@ async function expectRestartLaunchAgentKickstartFailure(
109109).rejects.toThrow("launchctl kickstart failed: Input/output error");
110110}
111111112+function launchctlCommandNames(): string[] {
113+return state.launchctlCalls.map(([command]) => command ?? "");
114+}
115+112116function normalizeLaunchctlArgs(file: string, args: string[]): string[] {
113117if (file === "launchctl") {
114118return args;
@@ -400,7 +404,7 @@ describe("launchd bootstrap repair", () => {
400404expect(repair).toEqual({ ok: true, status: "repaired" });
401405402406expectLaunchctlEnableBootstrapOrder(env);
403-expect(state.launchctlCalls.some((call) => call[0] === "kickstart")).toBe(false);
407+expect(launchctlCommandNames()).not.toContain("kickstart");
404408});
405409406410it("treats bootstrap exit 130 as success and nudges the already-loaded service when stopped", async () => {
@@ -426,7 +430,7 @@ describe("launchd bootstrap repair", () => {
426430const repair = await repairLaunchAgentBootstrap({ env });
427431428432expect(repair).toEqual({ ok: true, status: "already-loaded" });
429-expect(state.launchctlCalls.some((call) => call[0] === "kickstart")).toBe(false);
433+expect(launchctlCommandNames()).not.toContain("kickstart");
430434});
431435432436it("treats 'already exists in domain' bootstrap failures as success and nudges the service when stopped", async () => {
@@ -455,7 +459,7 @@ describe("launchd bootstrap repair", () => {
455459status: "bootstrap-failed",
456460detail: expect.stringContaining("Could not find specified service"),
457461});
458-expect(state.launchctlCalls.some((call) => call[0] === "kickstart")).toBe(false);
462+expect(launchctlCommandNames()).not.toContain("kickstart");
459463});
460464461465it("returns a typed kickstart failure when already-loaded recovery cannot nudge the service", async () => {
@@ -637,8 +641,8 @@ describe("launchd install", () => {
637641const domain = typeof process.getuid === "function" ? `gui/${process.getuid()}` : "gui/501";
638642const serviceId = `${domain}/ai.openclaw.gateway`;
639643expect(state.launchctlCalls).toContainEqual(["bootout", serviceId]);
640-expect(state.launchctlCalls.some((call) => call[0] === "disable")).toBe(false);
641-expect(state.launchctlCalls.some((call) => call[0] === "stop")).toBe(false);
644+expect(launchctlCommandNames()).not.toContain("disable");
645+expect(launchctlCommandNames()).not.toContain("stop");
642646expect(output).toContain("Stopped LaunchAgent");
643647});
644648@@ -656,7 +660,7 @@ describe("launchd install", () => {
656660const serviceId = `${domain}/ai.openclaw.gateway`;
657661expect(state.launchctlCalls).toContainEqual(["disable", serviceId]);
658662expect(state.launchctlCalls).toContainEqual(["stop", "ai.openclaw.gateway"]);
659-expect(state.launchctlCalls.some((call) => call[0] === "bootout")).toBe(false);
663+expect(launchctlCommandNames()).not.toContain("bootout");
660664expect(output).toContain("Stopped LaunchAgent");
661665});
662666@@ -678,7 +682,7 @@ describe("launchd install", () => {
678682"disable",
679683`${typeof process.getuid === "function" ? `gui/${process.getuid()}` : "gui/501"}/ai.openclaw.gateway`,
680684]);
681-expect(state.launchctlCalls.some((call) => call[0] === "bootout")).toBe(false);
685+expect(launchctlCommandNames()).not.toContain("bootout");
682686expect(output).toContain("Stopped LaunchAgent");
683687expect(output).not.toContain("degraded");
684688});
@@ -695,7 +699,7 @@ describe("launchd install", () => {
695699696700await stopLaunchAgent({ env, stdout });
697701698-expect(state.launchctlCalls.some((call) => call[0] === "disable")).toBe(false);
702+expect(launchctlCommandNames()).not.toContain("disable");
699703expect(output).toContain("Stopped LaunchAgent");
700704expect(output).not.toContain("degraded");
701705});
@@ -711,8 +715,8 @@ describe("launchd install", () => {
711715712716await stopLaunchAgent({ env, stdout, disable: true });
713717714-expect(state.launchctlCalls.some((call) => call[0] === "stop")).toBe(false);
715-expect(state.launchctlCalls.some((call) => call[0] === "bootout")).toBe(true);
718+expect(launchctlCommandNames()).not.toContain("stop");
719+expect(launchctlCommandNames()).toContain("bootout");
716720expect(output).toContain("Stopped LaunchAgent (degraded)");
717721expect(output).toContain("used bootout fallback");
718722});
@@ -728,8 +732,8 @@ describe("launchd install", () => {
728732729733await runStopLaunchAgentWithFakeTimers({ env, stdout, disable: true });
730734731-expect(state.launchctlCalls.some((call) => call[0] === "stop")).toBe(true);
732-expect(state.launchctlCalls.some((call) => call[0] === "bootout")).toBe(true);
735+expect(launchctlCommandNames()).toContain("stop");
736+expect(launchctlCommandNames()).toContain("bootout");
733737expect(output).toContain("Stopped LaunchAgent (degraded)");
734738expect(output).toContain("did not fully stop the service");
735739});
@@ -746,7 +750,7 @@ describe("launchd install", () => {
746750747751await runStopLaunchAgentWithFakeTimers({ env, stdout, disable: true });
748752749-expect(state.launchctlCalls.some((call) => call[0] === "bootout")).toBe(true);
753+expect(launchctlCommandNames()).toContain("bootout");
750754expect(output).toContain("Stopped LaunchAgent (degraded)");
751755expect(output).toContain("did not fully stop the service");
752756});
@@ -762,7 +766,7 @@ describe("launchd install", () => {
762766763767await stopLaunchAgent({ env, stdout, disable: true });
764768765-expect(state.launchctlCalls.some((call) => call[0] === "bootout")).toBe(true);
769+expect(launchctlCommandNames()).toContain("bootout");
766770expect(output).toContain("Stopped LaunchAgent (degraded)");
767771expect(output).toContain("launchctl stop failed; used bootout fallback");
768772});
@@ -779,7 +783,7 @@ describe("launchd install", () => {
779783780784await runStopLaunchAgentWithFakeTimers({ env, stdout, disable: true });
781785782-expect(state.launchctlCalls.some((call) => call[0] === "bootout")).toBe(true);
786+expect(launchctlCommandNames()).toContain("bootout");
783787expect(output).toContain("Stopped LaunchAgent (degraded)");
784788expect(output).toContain("could not confirm stop");
785789});
@@ -805,8 +809,8 @@ describe("launchd install", () => {
805809await expect(stopLaunchAgent({ env, stdout: new PassThrough() })).rejects.toThrow(
806810"launchctl bootout failed: launchctl bootout permission denied",
807811);
808-expect(state.launchctlCalls.some((call) => call[0] === "disable")).toBe(false);
809-expect(state.launchctlCalls.some((call) => call[0] === "stop")).toBe(false);
812+expect(launchctlCommandNames()).not.toContain("disable");
813+expect(launchctlCommandNames()).not.toContain("stop");
810814});
811815812816it("sanitizes launchctl details before writing warnings (--disable)", async () => {
@@ -842,8 +846,8 @@ describe("launchd install", () => {
842846expect(cleanStaleGatewayProcessesSync).toHaveBeenCalledWith(18789);
843847expect(state.launchctlCalls).toContainEqual(["enable", serviceId]);
844848expect(state.launchctlCalls).toContainEqual(["kickstart", "-k", serviceId]);
845-expect(state.launchctlCalls.some((call) => call[0] === "bootout")).toBe(false);
846-expect(state.launchctlCalls.some((call) => call[0] === "bootstrap")).toBe(false);
849+expect(launchctlCommandNames()).not.toContain("bootout");
850+expect(launchctlCommandNames()).not.toContain("bootstrap");
847851});
848852849853it("uses the configured gateway port for stale cleanup", async () => {
@@ -889,10 +893,10 @@ describe("launchd install", () => {
889893);
890894891895expect(result).toEqual({ outcome: "completed" });
892-expect(state.launchctlCalls.some((call) => call[0] === "enable")).toBe(true);
893-expect(state.launchctlCalls.some((call) => call[0] === "bootstrap")).toBe(true);
896+expect(launchctlCommandNames()).toContain("enable");
897+expect(launchctlCommandNames()).toContain("bootstrap");
894898expect(kickstartCalls).toHaveLength(1);
895-expect(state.launchctlCalls.some((call) => call[0] === "bootout")).toBe(false);
899+expect(launchctlCommandNames()).not.toContain("bootout");
896900});
897901898902it("surfaces the original kickstart failure when the service is still loaded", async () => {
@@ -902,8 +906,8 @@ describe("launchd install", () => {
902906903907await expectRestartLaunchAgentKickstartFailure(env);
904908905-expect(state.launchctlCalls.some((call) => call[0] === "enable")).toBe(true);
906-expect(state.launchctlCalls.some((call) => call[0] === "bootstrap")).toBe(false);
909+expect(launchctlCommandNames()).toContain("enable");
910+expect(launchctlCommandNames()).not.toContain("bootstrap");
907911});
908912909913it("re-bootstraps when kickstart failure leaves the service unloaded (#52208)", async () => {
@@ -914,8 +918,8 @@ describe("launchd install", () => {
914918915919await expectRestartLaunchAgentKickstartFailure(env);
916920917-expect(state.launchctlCalls.some((call) => call[0] === "enable")).toBe(true);
918-expect(state.launchctlCalls.some((call) => call[0] === "bootstrap")).toBe(true);
921+expect(launchctlCommandNames()).toContain("enable");
922+expect(launchctlCommandNames()).toContain("bootstrap");
919923});
920924921925it("skips re-bootstrap when kickstart fails but service is still loaded (#52208)", async () => {
@@ -925,8 +929,8 @@ describe("launchd install", () => {
925929926930await expectRestartLaunchAgentKickstartFailure(env);
927931928-expect(state.launchctlCalls.some((call) => call[0] === "enable")).toBe(true);
929-expect(state.launchctlCalls.some((call) => call[0] === "bootstrap")).toBe(false);
932+expect(launchctlCommandNames()).toContain("enable");
933+expect(launchctlCommandNames()).not.toContain("bootstrap");
930934});
931935932936it("hands restart off to a detached helper when invoked from the current LaunchAgent", async () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。