mirror of https://github.com/openclaw/openclaw.git
test: share channel health helpers
This commit is contained in:
parent
944a2c93e3
commit
5eaa14687f
|
|
@ -106,6 +106,24 @@ function createSlackSnapshotManager(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createBusyDisconnectedManager(lastRunActivityAt: number): ChannelManager {
|
||||||
|
const now = Date.now();
|
||||||
|
return createSnapshotManager({
|
||||||
|
discord: {
|
||||||
|
default: {
|
||||||
|
running: true,
|
||||||
|
connected: false,
|
||||||
|
enabled: true,
|
||||||
|
configured: true,
|
||||||
|
lastStartAt: now - 300_000,
|
||||||
|
activeRuns: 1,
|
||||||
|
busy: true,
|
||||||
|
lastRunActivityAt,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function expectRestartedChannel(
|
async function expectRestartedChannel(
|
||||||
manager: ChannelManager,
|
manager: ChannelManager,
|
||||||
channel: ChannelId,
|
channel: ChannelId,
|
||||||
|
|
@ -250,39 +268,13 @@ describe("channel-health-monitor", () => {
|
||||||
|
|
||||||
it("restarts busy channels when run activity is stale", async () => {
|
it("restarts busy channels when run activity is stale", async () => {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const manager = createSnapshotManager({
|
const manager = createBusyDisconnectedManager(now - 26 * 60_000);
|
||||||
discord: {
|
|
||||||
default: {
|
|
||||||
running: true,
|
|
||||||
connected: false,
|
|
||||||
enabled: true,
|
|
||||||
configured: true,
|
|
||||||
lastStartAt: now - 300_000,
|
|
||||||
activeRuns: 1,
|
|
||||||
busy: true,
|
|
||||||
lastRunActivityAt: now - 26 * 60_000,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await expectRestartedChannel(manager, "discord");
|
await expectRestartedChannel(manager, "discord");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("restarts disconnected channels when busy flags are inherited from a prior lifecycle", async () => {
|
it("restarts disconnected channels when busy flags are inherited from a prior lifecycle", async () => {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const manager = createSnapshotManager({
|
const manager = createBusyDisconnectedManager(now - 301_000);
|
||||||
discord: {
|
|
||||||
default: {
|
|
||||||
running: true,
|
|
||||||
connected: false,
|
|
||||||
enabled: true,
|
|
||||||
configured: true,
|
|
||||||
lastStartAt: now - 300_000,
|
|
||||||
activeRuns: 1,
|
|
||||||
busy: true,
|
|
||||||
lastRunActivityAt: now - 301_000,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await expectRestartedChannel(manager, "discord");
|
await expectRestartedChannel(manager, "discord");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,19 @@
|
||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
import { evaluateChannelHealth, resolveChannelRestartReason } from "./channel-health-policy.js";
|
import { evaluateChannelHealth, resolveChannelRestartReason } from "./channel-health-policy.js";
|
||||||
|
|
||||||
|
function evaluateDiscordHealth(
|
||||||
|
account: Record<string, unknown>,
|
||||||
|
now = 100_000,
|
||||||
|
channelId = "discord",
|
||||||
|
) {
|
||||||
|
return evaluateChannelHealth(account, {
|
||||||
|
channelId,
|
||||||
|
now,
|
||||||
|
channelConnectGraceMs: 10_000,
|
||||||
|
staleEventThresholdMs: 30_000,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
describe("evaluateChannelHealth", () => {
|
describe("evaluateChannelHealth", () => {
|
||||||
it("treats disabled accounts as healthy unmanaged", () => {
|
it("treats disabled accounts as healthy unmanaged", () => {
|
||||||
const evaluation = evaluateChannelHealth(
|
const evaluation = evaluateChannelHealth(
|
||||||
|
|
@ -144,48 +157,32 @@ describe("evaluateChannelHealth", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("skips stale-socket detection for channels in webhook mode", () => {
|
it("skips stale-socket detection for channels in webhook mode", () => {
|
||||||
const evaluation = evaluateChannelHealth(
|
const evaluation = evaluateDiscordHealth({
|
||||||
{
|
running: true,
|
||||||
running: true,
|
connected: true,
|
||||||
connected: true,
|
enabled: true,
|
||||||
enabled: true,
|
configured: true,
|
||||||
configured: true,
|
lastStartAt: 0,
|
||||||
lastStartAt: 0,
|
lastEventAt: 0,
|
||||||
lastEventAt: 0,
|
mode: "webhook",
|
||||||
mode: "webhook",
|
});
|
||||||
},
|
|
||||||
{
|
|
||||||
channelId: "discord",
|
|
||||||
now: 100_000,
|
|
||||||
channelConnectGraceMs: 10_000,
|
|
||||||
staleEventThresholdMs: 30_000,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
expect(evaluation).toEqual({ healthy: true, reason: "healthy" });
|
expect(evaluation).toEqual({ healthy: true, reason: "healthy" });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("does not flag stale sockets for channels without event tracking", () => {
|
it("does not flag stale sockets for channels without event tracking", () => {
|
||||||
const evaluation = evaluateChannelHealth(
|
const evaluation = evaluateDiscordHealth({
|
||||||
{
|
running: true,
|
||||||
running: true,
|
connected: true,
|
||||||
connected: true,
|
enabled: true,
|
||||||
enabled: true,
|
configured: true,
|
||||||
configured: true,
|
lastStartAt: 0,
|
||||||
lastStartAt: 0,
|
lastEventAt: null,
|
||||||
lastEventAt: null,
|
});
|
||||||
},
|
|
||||||
{
|
|
||||||
channelId: "discord",
|
|
||||||
now: 100_000,
|
|
||||||
channelConnectGraceMs: 10_000,
|
|
||||||
staleEventThresholdMs: 30_000,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
expect(evaluation).toEqual({ healthy: true, reason: "healthy" });
|
expect(evaluation).toEqual({ healthy: true, reason: "healthy" });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("does not flag stale sockets without an active connected socket", () => {
|
it("does not flag stale sockets without an active connected socket", () => {
|
||||||
const evaluation = evaluateChannelHealth(
|
const evaluation = evaluateDiscordHealth(
|
||||||
{
|
{
|
||||||
running: true,
|
running: true,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
|
@ -193,18 +190,14 @@ describe("evaluateChannelHealth", () => {
|
||||||
lastStartAt: 0,
|
lastStartAt: 0,
|
||||||
lastEventAt: 0,
|
lastEventAt: 0,
|
||||||
},
|
},
|
||||||
{
|
75_000,
|
||||||
channelId: "slack",
|
"slack",
|
||||||
now: 75_000,
|
|
||||||
channelConnectGraceMs: 10_000,
|
|
||||||
staleEventThresholdMs: 30_000,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
expect(evaluation).toEqual({ healthy: true, reason: "healthy" });
|
expect(evaluation).toEqual({ healthy: true, reason: "healthy" });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("ignores inherited event timestamps from a previous lifecycle", () => {
|
it("ignores inherited event timestamps from a previous lifecycle", () => {
|
||||||
const evaluation = evaluateChannelHealth(
|
const evaluation = evaluateDiscordHealth(
|
||||||
{
|
{
|
||||||
running: true,
|
running: true,
|
||||||
connected: true,
|
connected: true,
|
||||||
|
|
@ -213,12 +206,8 @@ describe("evaluateChannelHealth", () => {
|
||||||
lastStartAt: 50_000,
|
lastStartAt: 50_000,
|
||||||
lastEventAt: 10_000,
|
lastEventAt: 10_000,
|
||||||
},
|
},
|
||||||
{
|
75_000,
|
||||||
channelId: "slack",
|
"slack",
|
||||||
now: 75_000,
|
|
||||||
channelConnectGraceMs: 10_000,
|
|
||||||
staleEventThresholdMs: 30_000,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
expect(evaluation).toEqual({ healthy: true, reason: "healthy" });
|
expect(evaluation).toEqual({ healthy: true, reason: "healthy" });
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue