dsh-im-ops/test/channels/dingtalk/connection-supervisor.test.mjs
2026-08-15 15:40:53 +08:00

73 lines
2.1 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { ConnectionSupervisor } from '../../../plugin-src/host/channels/dingtalk/connection-supervisor.mjs';
function scheduler() {
const tasks = [];
return {
tasks,
setTimeout(callback, delay) {
const task = { callback, delay, unref() {} };
tasks.push(task);
return task;
},
clearTimeout(task) {
const index = tasks.indexOf(task);
if (index >= 0) tasks.splice(index, 1);
},
async runNext() {
const task = tasks.shift();
assert.ok(task);
task.callback();
await new Promise((resolve) => setImmediate(resolve));
},
};
}
test('supervisor starts configured DingTalk runtimes after Harness is healthy', async () => {
const timers = scheduler();
let healthChecks = 0;
let initializes = 0;
const supervisor = new ConnectionSupervisor({
harness: { async ensureRunning() { healthChecks += 1; } },
controller: {
async initialize() {
initializes += 1;
return { totals: { configured: 1, connected: 1 } };
},
status() {},
},
setTimeoutImpl: timers.setTimeout,
clearTimeoutImpl: timers.clearTimeout,
healthyIntervalMs: 9_000,
}).start();
await timers.runNext();
assert.equal(healthChecks, 1);
assert.equal(initializes, 1);
assert.equal((await supervisor.ready).totals.connected, 1);
assert.equal(timers.tasks[0].delay, 9_000);
await supervisor.close();
});
test('supervisor retries an offline DingTalk runtime without blocking startup', async () => {
const timers = scheduler();
const warnings = [];
const supervisor = new ConnectionSupervisor({
harness: { async ensureRunning() {} },
controller: {
async initialize() { return { totals: { configured: 2, connected: 1 } }; },
status() {},
},
logger: { warn: (...args) => warnings.push(args) },
retryDelaysMs: [7, 11],
setTimeoutImpl: timers.setTimeout,
clearTimeoutImpl: timers.clearTimeout,
}).start();
await timers.runNext();
assert.equal(timers.tasks[0].delay, 7);
assert.match(warnings[0][0], /1\/2 bots connected/);
await supervisor.close();
});