





















@@ -35,6 +35,7 @@ const state = vi.hoisted(() => ({
3535printFailuresRemaining: 0,
3636bootstrapError: "",
3737bootstrapCode: 1,
38+bootstrapLoadsServiceOnFailure: false,
3839kickstartError: "",
3940kickstartCode: 1,
4041kickstartFailuresRemaining: 0,
@@ -199,6 +200,10 @@ vi.mock("./exec-file.js", () => ({
199200}
200201if (call[0] === "bootstrap") {
201202if (state.bootstrapError) {
203+if (state.bootstrapLoadsServiceOnFailure) {
204+state.serviceLoaded = true;
205+state.serviceRunning = true;
206+}
202207return { stdout: "", stderr: state.bootstrapError, code: state.bootstrapCode };
203208}
204209state.serviceLoaded = true;
@@ -304,6 +309,7 @@ beforeEach(() => {
304309state.printFailuresRemaining = 0;
305310state.bootstrapError = "";
306311state.bootstrapCode = 1;
312+state.bootstrapLoadsServiceOnFailure = false;
307313state.kickstartError = "";
308314state.kickstartCode = 1;
309315state.kickstartFailuresRemaining = 0;
@@ -1261,6 +1267,44 @@ describe("launchd install", () => {
12611267expect(launchctlCommandNames()).not.toContain("kickstart");
12621268});
126312691270+it("treats a concurrent launchd bootstrap as success when the service is loaded", async () => {
1271+const env = {
1272+ ...createDefaultLaunchdEnv(),
1273+OPENCLAW_GATEWAY_PORT: "18789",
1274+};
1275+const plistPath = resolveLaunchAgentPlistPath(env);
1276+state.files.set(
1277+plistPath,
1278+[
1279+'<?xml version="1.0" encoding="UTF-8"?>',
1280+'<plist version="1.0">',
1281+" <dict>",
1282+" <key>Label</key>",
1283+" <string>ai.openclaw.gateway</string>",
1284+" <key>ProgramArguments</key>",
1285+" <array>",
1286+" <string>node</string>",
1287+" <string>gateway.js</string>",
1288+" </array>",
1289+" <key>StandardOutPath</key>",
1290+" <string>/Users/test/.openclaw-default/logs/gateway.log</string>",
1291+" </dict>",
1292+"</plist>",
1293+].join("\n"),
1294+);
1295+state.bootstrapError = "Bootstrap failed: 37: Operation already in progress";
1296+state.bootstrapCode = 5;
1297+state.bootstrapLoadsServiceOnFailure = true;
1298+1299+await restartLaunchAgent({
1300+ env,
1301+stdout: new PassThrough(),
1302+});
1303+1304+expect(launchctlCommandNames()).toEqual(["enable", "bootout", "enable", "bootstrap", "print"]);
1305+expect(launchctlCommandNames()).not.toContain("kickstart");
1306+});
1307+12641308it("uses the configured gateway port for stale cleanup", async () => {
12651309const env = {
12661310 ...createDefaultLaunchdEnv(),
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。