Files
openclaw/src/gateway/server-active-work.test.ts
Peter Steinberger 1bcc4c5e70 feat(gateway): add cooperative host suspension (#103618)
* feat(gateway): add cooperative suspension preparation

* style: satisfy suspension lint checks

* test(gateway): reset work admission between shared suites

* fix(gateway): reject upgrades during suspension

* fix(gateway): preserve admitted work during suspension

* test(gateway): isolate suspension and restart state

* fix(gateway): close suspension false-ready gaps

* refactor(protocol): slim suspension declaration graph

* refactor(plugin-sdk): sever protocol registry edges

* fix(gateway): preserve admitted restart follow-ups

* fix(gateway): make suspension recovery fail closed

* fix(protocol): keep validation formatter re-export only

* test(gateway): simplify deferred fixture type

* style(gateway): clarify suspension entry name

* fix(gateway): retain detached work admission
2026-07-10 20:24:53 +01:00

58 lines
1.9 KiB
TypeScript

// Covers server-local chat, cron watcher, queued-turn, and terminal blockers.
import { describe, expect, it, vi } from "vitest";
import { createGatewayServerActiveWorkInspectors } from "./server-active-work.js";
import type { GatewayRequestContext } from "./server-methods/shared-types.js";
vi.mock("../cron/active-jobs.js", () => ({
getActiveCronJobCount: vi.fn(() => 2),
}));
vi.mock("../tasks/cron-task-cancel.js", () => ({
getSuspensionVisibleCronTaskRunCount: vi.fn(() => 4),
}));
function controller(aborted = false): AbortController {
const value = new AbortController();
if (aborted) {
value.abort();
}
return value;
}
describe("gateway server active work inspectors", () => {
it("filters completed chat entries while retaining persistence and watcher blockers", () => {
const context = {
cron: { getSuspensionBlockerCount: () => 1 },
chatAbortControllers: new Map([
["active", { controller: controller() }],
["aborted", { controller: controller(true) }],
[
"persisting",
{
controller: controller(),
registrationCleanupRequested: true,
controlUiVisible: true,
projectSessionTerminalPending: true,
},
],
]),
chatQueuedTurns: new Map([
["queued", { controller: controller() }],
["cancelled", { controller: controller(true) }],
]),
terminalSessions: { size: 2 },
} as unknown as Pick<
GatewayRequestContext,
"chatAbortControllers" | "chatQueuedTurns" | "cron" | "terminalSessions"
>;
const inspectors = createGatewayServerActiveWorkInspectors(context);
expect(inspectors.getCronRuns?.()).toBe(5);
expect(inspectors.getChatRuns?.()).toBe(1);
expect(inspectors.getQueuedTurns?.()).toBe(1);
expect(inspectors.getTerminalPersistence?.()).toBe(1);
expect(inspectors.getTerminalSessions?.()).toBe(2);
});
});