























@@ -1,10 +1,14 @@
11import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
2+import { formatCliCommand } from "../cli/command-format.js";
23import type { ExtraGatewayService } from "../daemon/inspect.js";
34import * as launchd from "../daemon/launchd.js";
45import type { GatewayRestartHandoff } from "../infra/restart-handoff.js";
56import { withEnvAsync } from "../test-utils/env.js";
67import { createDoctorPrompter } from "./doctor-prompter.js";
7-import { EXTERNAL_SERVICE_REPAIR_NOTE } from "./doctor-service-repair-policy.js";
8+import {
9+EXTERNAL_SERVICE_REPAIR_NOTE,
10+SERVICE_REPAIR_POLICY_ENV,
11+} from "./doctor-service-repair-policy.js";
812913const service = vi.hoisted(() => ({
1014isLoaded: vi.fn(),
@@ -164,6 +168,7 @@ describe("maybeRepairGatewayDaemon", () => {
164168});
165169166170afterEach(() => {
171+vi.useRealTimers();
167172if (originalPlatformDescriptor) {
168173Object.defineProperty(process, "platform", originalPlatformDescriptor);
169174}
@@ -266,6 +271,8 @@ describe("maybeRepairGatewayDaemon", () => {
266271});
267272268273it("reports recent restart handoffs during deep doctor", async () => {
274+vi.useFakeTimers();
275+vi.setSystemTime(40_000);
269276setPlatform("linux");
270277service.readCommand.mockResolvedValueOnce({
271278programArguments: ["/bin/node", "cli", "gateway"],
@@ -306,11 +313,7 @@ describe("maybeRepairGatewayDaemon", () => {
306313expect(handoffEnv?.OPENCLAW_STATE_DIR).toBe("/tmp/openclaw-service");
307314expect(handoffEnv?.OPENCLAW_CONFIG_PATH).toBe("/tmp/openclaw-service/openclaw.json");
308315expect(note).toHaveBeenCalledWith(
309-expect.stringContaining("Recent restart handoff: full-process via systemd"),
310-"Gateway",
311-);
312-expect(note).toHaveBeenCalledWith(
313-expect.stringContaining("reason=plugin source changed"),
316+"Recent restart handoff: full-process via systemd; source=plugin-change; reason=plugin source changed; pid=12345; age=30s; expiresIn=30s",
314317"Gateway",
315318);
316319});
@@ -382,7 +385,7 @@ describe("maybeRepairGatewayDaemon", () => {
382385expect(service.install).not.toHaveBeenCalled();
383386expect(service.restart).not.toHaveBeenCalled();
384387expect(note).toHaveBeenCalledWith(
385-expect.stringContaining("openclaw gateway install"),
388+`Run ${formatCliCommand("openclaw gateway install")} when you want to install the gateway service.`,
386389"Gateway",
387390);
388391});
@@ -428,7 +431,13 @@ describe("maybeRepairGatewayDaemon", () => {
428431expect(service.install).not.toHaveBeenCalled();
429432expect(service.restart).not.toHaveBeenCalled();
430433expect(note).toHaveBeenCalledWith(
431-expect.stringContaining("System-level OpenClaw gateway service detected"),
434+[
435+"System-level OpenClaw gateway service detected while the user gateway service is not installed.",
436+"- openclaw-gateway.service (unit: /etc/systemd/system/openclaw-gateway.service)",
437+"OpenClaw will not install a second user-level gateway service automatically.",
438+"Run `openclaw gateway status --deep` or `openclaw doctor --deep` to inspect duplicate services.",
439+`Set ${SERVICE_REPAIR_POLICY_ENV}=external if a system supervisor owns the gateway lifecycle.`,
440+].join("\n"),
432441"Gateway",
433442);
434443});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。