76 lines
2.9 KiB
JavaScript
76 lines
2.9 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import {readFile} from 'node:fs/promises';
|
|
import vm from 'node:vm';
|
|
import test from 'node:test';
|
|
import {transformSync} from 'esbuild';
|
|
|
|
const source = await readFile(new URL('../index.ts', import.meta.url), 'utf8');
|
|
const lifecycle = source.slice(source.indexOf(' let reconnect_timer:'), source.indexOf(" main_server_socket.on('connect',"));
|
|
const disconnect = source.slice(source.indexOf(" main_server_socket.on('disconnect',"), source.indexOf(' main_server_socket.onAny('));
|
|
const code = transformSync(`${lifecycle}\n${disconnect}`, {loader: 'ts'}).code;
|
|
|
|
function setup(enabled = true, max_attempts = 2) {
|
|
const timers = new Map();
|
|
const handlers = new Map();
|
|
const state = {connects: 0, disconnects: 0};
|
|
const process = {once() {}};
|
|
let id = 0;
|
|
vm.runInNewContext(code, {
|
|
auto_reconnect: {enabled, max_attempts, interval: 100},
|
|
reconnect_interval: 100,
|
|
main_server_socket: {
|
|
on: (event, handler) => handlers.set(event, handler),
|
|
connect: () => state.connects++,
|
|
disconnect: () => state.disconnects++,
|
|
},
|
|
console_print: {log() {}, info() {}, error() {}, warning() {}},
|
|
clear_node_session() {},
|
|
get_bot_context_status: async () => [],
|
|
stop_bot_context: async () => {},
|
|
process,
|
|
setTimeout(callback, delay) {
|
|
if (delay === 10_000) return ++id;
|
|
assert.equal(delay, 100);
|
|
timers.set(++id, callback);
|
|
return id;
|
|
},
|
|
clearTimeout: id => timers.delete(id),
|
|
});
|
|
return {
|
|
state, process, timers,
|
|
disconnect: reason => handlers.get('disconnect')(reason),
|
|
tick() {
|
|
assert.equal(timers.size, 1);
|
|
const [id, callback] = timers.entries().next().value;
|
|
timers.delete(id);
|
|
callback();
|
|
},
|
|
};
|
|
}
|
|
|
|
test('server disconnect retries indefinitely without duplicate timers after the configured limit', () => {
|
|
const app = setup();
|
|
for (let attempt = 0; attempt < 12; attempt++) {
|
|
app.disconnect('io server disconnect');
|
|
app.disconnect('io server disconnect');
|
|
app.tick();
|
|
assert.equal(app.state.connects, attempt + 1);
|
|
}
|
|
app.disconnect('io server disconnect');
|
|
assert.equal(app.state.disconnects, 0);
|
|
assert.equal(app.timers.size, 1);
|
|
assert.equal(app.process.exitCode, undefined);
|
|
});
|
|
|
|
test('disabled reconnect and a zero attempt limit still retry every disconnect reason', () => {
|
|
const app = setup(false, 0);
|
|
for (const reason of ['io server disconnect', 'io client disconnect', 'transport close', 'ping timeout', 'transport error']) {
|
|
app.disconnect(reason);
|
|
app.tick();
|
|
}
|
|
assert.equal(app.state.connects, 5);
|
|
app.disconnect('io client disconnect');
|
|
assert.equal(app.timers.size, 1);
|
|
assert.equal(app.process.exitCode, undefined);
|
|
});
|