






















@@ -10,6 +10,7 @@ import {
1010readGatewayRestartHandoffSync,
1111writeGatewayRestartHandoffSync,
1212} from "./restart-handoff.js";
13+import type { GatewayRestartHandoff } from "./restart-handoff.js";
13141415const tempDirs: string[] = [];
1516@@ -26,6 +27,16 @@ function handoffPath(env: NodeJS.ProcessEnv): string {
2627return path.join(env.OPENCLAW_STATE_DIR ?? "", GATEWAY_SUPERVISOR_RESTART_HANDOFF_FILENAME);
2728}
282930+function expectWrittenHandoff(
31+opts: Parameters<typeof writeGatewayRestartHandoffSync>[0],
32+): GatewayRestartHandoff {
33+const handoff = writeGatewayRestartHandoffSync(opts);
34+if (handoff === null) {
35+throw new Error("Expected gateway restart handoff to be written");
36+}
37+return handoff;
38+}
39+2940describe("gateway restart handoff", () => {
3041afterEach(() => {
3142for (const dir of tempDirs.splice(0)) {
@@ -68,16 +79,14 @@ describe("gateway restart handoff", () => {
6879it("consumes a fresh handoff by exited pid instead of current process pid", () => {
6980const env = createHandoffEnv();
708171-expect(
72-writeGatewayRestartHandoffSync({
73- env,
74-pid: process.pid + 1,
75-reason: "update.run",
76-restartKind: "update-process",
77-supervisorMode: "systemd",
78-createdAt: 2_000,
79-}),
80-).not.toBeNull();
82+expectWrittenHandoff({
83+ env,
84+pid: process.pid + 1,
85+reason: "update.run",
86+restartKind: "update-process",
87+supervisorMode: "systemd",
88+createdAt: 2_000,
89+});
81908291expect(
8392consumeGatewayRestartHandoffForExitedProcessSync({
@@ -97,15 +106,13 @@ describe("gateway restart handoff", () => {
97106it("rejects handoffs for a different exited pid and clears them", () => {
98107const env = createHandoffEnv();
99108100-expect(
101-writeGatewayRestartHandoffSync({
102- env,
103-pid: 111,
104-restartKind: "full-process",
105-supervisorMode: "external",
106-createdAt: 1_000,
107-}),
108-).not.toBeNull();
109+expectWrittenHandoff({
110+ env,
111+pid: 111,
112+restartKind: "full-process",
113+supervisorMode: "external",
114+createdAt: 1_000,
115+});
109116110117expect(
111118consumeGatewayRestartHandoffForExitedProcessSync({
@@ -120,16 +127,14 @@ describe("gateway restart handoff", () => {
120127it("rejects a handoff when the supplied process instance does not match", () => {
121128const env = createHandoffEnv();
122129123-expect(
124-writeGatewayRestartHandoffSync({
125- env,
126-pid: 111,
127-processInstanceId: "gateway-instance-1",
128-restartKind: "full-process",
129-supervisorMode: "external",
130-createdAt: 1_000,
131-}),
132-).not.toBeNull();
130+expectWrittenHandoff({
131+ env,
132+pid: 111,
133+processInstanceId: "gateway-instance-1",
134+restartKind: "full-process",
135+supervisorMode: "external",
136+createdAt: 1_000,
137+});
133138134139expect(
135140consumeGatewayRestartHandoffForExitedProcessSync({
@@ -168,16 +173,14 @@ describe("gateway restart handoff", () => {
168173it("rejects expired and oversized handoff files", () => {
169174const env = createHandoffEnv();
170175171-expect(
172-writeGatewayRestartHandoffSync({
173- env,
174-pid: 111,
175-restartKind: "full-process",
176-supervisorMode: "external",
177-createdAt: 1_000,
178-ttlMs: 1_000,
179-}),
180-).not.toBeNull();
176+expectWrittenHandoff({
177+ env,
178+pid: 111,
179+restartKind: "full-process",
180+supervisorMode: "external",
181+createdAt: 1_000,
182+ttlMs: 1_000,
183+});
181184expect(readGatewayRestartHandoffSync(env, 2_001)).toBeNull();
182185183186fs.writeFileSync(handoffPath(env), "x".repeat(8192), { encoding: "utf8", mode: 0o600 });
@@ -231,14 +234,12 @@ describe("gateway restart handoff", () => {
231234return;
232235}
233236234-expect(
235-writeGatewayRestartHandoffSync({
236- env,
237-pid: 12_345,
238-restartKind: "full-process",
239-supervisorMode: "external",
240-}),
241-).not.toBeNull();
237+expectWrittenHandoff({
238+ env,
239+pid: 12_345,
240+restartKind: "full-process",
241+supervisorMode: "external",
242+});
242243243244expect(fs.readFileSync(targetPath, "utf8")).toBe("keep");
244245expect(fs.lstatSync(handoffPath(env)).isSymbolicLink()).toBe(false);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。