Files
openclaw/src/acp/control-plane/runtime-cache.test.ts
Peter Steinberger 77f1359612 refactor: extract media and ACP core packages (#88534)
* refactor: extract media and acp core packages

* refactor: remove relocated media and acp sources

* build: wire new core packages into dependency checks

* test: alias new core packages in vitest

* build: keep media sniffer runtime dependency

* docs: refresh plugin sdk api baseline

* fix: keep normalized proposal queries non-empty

* test: keep channel timer tests isolated

* fix: keep rebased plugin checks green

* fix: preserve sms numeric allowlist entries

* test: harden exec foreground timeout failure

* test: remove duplicate skill workshop assertion

* fix: remove channel config lint suppression

* test: refresh lint suppression allowlist
2026-05-31 11:30:33 +01:00

61 lines
2.0 KiB
TypeScript

import type { AcpRuntime } from "@openclaw/acp-core/runtime/types";
import type { AcpRuntimeHandle } from "@openclaw/acp-core/runtime/types";
import { describe, expect, it } from "vitest";
import type { CachedRuntimeState } from "./runtime-cache.js";
import { RuntimeCache } from "./runtime-cache.js";
function mockState(sessionKey: string): CachedRuntimeState {
const runtime = {
async ensureSession() {
return {
sessionKey,
backend: "acpx",
runtimeSessionName: `runtime:${sessionKey}`,
};
},
async *runTurn() {
yield { type: "done" as const };
},
async cancel() {},
async close() {},
} satisfies AcpRuntime;
return {
runtime,
handle: {
sessionKey,
backend: "acpx",
runtimeSessionName: `runtime:${sessionKey}`,
} as AcpRuntimeHandle,
backend: "acpx",
agent: "codex",
mode: "persistent",
configSignature: "config:test",
};
}
describe("RuntimeCache", () => {
it("tracks idle candidates with touch-aware lookups", () => {
const cache = new RuntimeCache();
const actor = "agent:codex:acp:s1";
cache.set(actor, mockState(actor), { now: 1_000 });
expect(cache.collectIdleCandidates({ maxIdleMs: 1_000, now: 1_999 })).toHaveLength(0);
expect(cache.collectIdleCandidates({ maxIdleMs: 1_000, now: 2_000 })).toHaveLength(1);
cache.get(actor, { now: 2_500 });
expect(cache.collectIdleCandidates({ maxIdleMs: 1_000, now: 3_200 })).toHaveLength(0);
expect(cache.collectIdleCandidates({ maxIdleMs: 1_000, now: 3_500 })).toHaveLength(1);
});
it("returns snapshot entries with idle durations", () => {
const cache = new RuntimeCache();
cache.set("a", mockState("a"), { now: 10 });
cache.set("b", mockState("b"), { now: 100 });
const snapshot = cache.snapshot({ now: 1_100 });
const byActor = new Map(snapshot.map((entry) => [entry.actorKey, entry]));
expect(byActor.get("a")?.idleMs).toBe(1_090);
expect(byActor.get("b")?.idleMs).toBe(1_000);
});
});