openclaw/src/agents/bash-tools.exec-host-shared...

78 lines
2.7 KiB
TypeScript

import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const mocks = vi.hoisted(() => ({
sendExecApprovalFollowup: vi.fn(),
logWarn: vi.fn(),
}));
vi.mock("./bash-tools.exec-approval-followup.js", () => ({
sendExecApprovalFollowup: mocks.sendExecApprovalFollowup,
}));
vi.mock("../logger.js", () => ({
logWarn: mocks.logWarn,
}));
let sendExecApprovalFollowupResult: typeof import("./bash-tools.exec-host-shared.js").sendExecApprovalFollowupResult;
let maxExecApprovalFollowupFailureLogKeys: typeof import("./bash-tools.exec-host-shared.js").MAX_EXEC_APPROVAL_FOLLOWUP_FAILURE_LOG_KEYS;
let sendExecApprovalFollowup: typeof import("./bash-tools.exec-approval-followup.js").sendExecApprovalFollowup;
let logWarn: typeof import("../logger.js").logWarn;
describe("sendExecApprovalFollowupResult", () => {
beforeAll(async () => {
({
sendExecApprovalFollowupResult,
MAX_EXEC_APPROVAL_FOLLOWUP_FAILURE_LOG_KEYS: maxExecApprovalFollowupFailureLogKeys,
} = await import("./bash-tools.exec-host-shared.js"));
({ sendExecApprovalFollowup } = await import("./bash-tools.exec-approval-followup.js"));
({ logWarn } = await import("../logger.js"));
});
beforeEach(() => {
vi.mocked(sendExecApprovalFollowup).mockReset();
vi.mocked(logWarn).mockReset();
});
it("logs repeated followup dispatch failures once per approval id and error message", async () => {
vi.mocked(sendExecApprovalFollowup).mockRejectedValue(new Error("Channel is required"));
const target = {
approvalId: "approval-log-once",
sessionKey: "agent:main:main",
};
await sendExecApprovalFollowupResult(target, "Exec finished");
await sendExecApprovalFollowupResult(target, "Exec finished");
expect(logWarn).toHaveBeenCalledTimes(1);
expect(logWarn).toHaveBeenCalledWith(
"exec approval followup dispatch failed (id=approval-log-once): Channel is required",
);
});
it("evicts oldest followup failure dedupe keys after reaching the cap", async () => {
vi.mocked(sendExecApprovalFollowup).mockRejectedValue(new Error("Channel is required"));
for (let i = 0; i <= maxExecApprovalFollowupFailureLogKeys; i += 1) {
await sendExecApprovalFollowupResult(
{
approvalId: `approval-${i}`,
sessionKey: "agent:main:main",
},
"Exec finished",
);
}
await sendExecApprovalFollowupResult(
{
approvalId: "approval-0",
sessionKey: "agent:main:main",
},
"Exec finished",
);
expect(logWarn).toHaveBeenCalledTimes(maxExecApprovalFollowupFailureLogKeys + 2);
expect(logWarn).toHaveBeenLastCalledWith(
"exec approval followup dispatch failed (id=approval-0): Channel is required",
);
});
});