Files
reactor/test/integration/tick-loop.integration.test.js

135 lines
3.4 KiB
JavaScript

const test = require('node:test');
const assert = require('node:assert/strict');
const NodeClass = require('../../src/nodeClass');
const { makeNodeStub } = require('../helpers/factories');
test('_tick emits source effluent on process output', () => {
const inst = Object.create(NodeClass.prototype);
const node = makeNodeStub();
inst.node = node;
inst._output = { formatMsg() { return null; } };
inst.source = {
get getEffluent() {
return { topic: 'Fluent', payload: { inlet: 0, F: 1, C: [] }, timestamp: 1 };
},
};
inst._tick();
assert.equal(node._sent.length, 1);
assert.equal(node._sent[0][0].topic, 'Fluent');
assert.equal(node._sent[0][1], null);
assert.equal(node._sent[0][2], null);
});
test('_tick emits reactor telemetry on influx output', () => {
const inst = Object.create(NodeClass.prototype);
const node = makeNodeStub();
let captured = null;
inst.node = node;
inst.config = { functionality: { softwareType: 'reactor' }, general: { id: 'reactor-node-1' } };
inst._output = {
formatMsg(output, config, format) {
captured = { output, config, format };
return { topic: 'reactor_reactor-node-1', payload: { measurement: 'reactor_reactor-node-1', fields: output } };
}
};
inst.source = {
temperature: 19.5,
get getGridProfile() {
return null;
},
get getEffluent() {
return {
topic: 'Fluent',
payload: {
inlet: 0,
F: 42,
C: [2.1, 30, 100, 16, 0, 1, 8, 25, 75, 1500, 0, 15, 2500]
},
timestamp: 1
};
},
};
inst._tick();
assert.equal(node._sent.length, 1);
assert.equal(node._sent[0][0].topic, 'Fluent');
assert.equal(node._sent[0][1].topic, 'reactor_reactor-node-1');
assert.equal(captured.format, 'influxdb');
assert.equal(captured.output.flow_total, 42);
assert.equal(captured.output.temperature, 19.5);
assert.equal(captured.output.S_O, 2.1);
assert.equal(captured.output.S_NH, 16);
assert.equal(captured.output.X_TS, 2500);
});
test('_startTickLoop schedules periodic tick after startup delay', () => {
const inst = Object.create(NodeClass.prototype);
const delays = [];
const intervals = [];
let tickCount = 0;
inst._tick = () => {
tickCount += 1;
};
const originalSetTimeout = global.setTimeout;
const originalSetInterval = global.setInterval;
global.setTimeout = (fn, ms) => {
delays.push(ms);
fn();
return 10;
};
global.setInterval = (fn, ms) => {
intervals.push(ms);
fn();
return 22;
};
try {
inst._startTickLoop();
} finally {
global.setTimeout = originalSetTimeout;
global.setInterval = originalSetInterval;
}
assert.deepEqual(delays, [1000]);
assert.deepEqual(intervals, [1000]);
assert.equal(inst._tickInterval, 22);
assert.equal(tickCount, 1);
});
test('_attachCloseHandler clears tick interval and calls done callback', () => {
const inst = Object.create(NodeClass.prototype);
const node = makeNodeStub();
inst.node = node;
inst._tickInterval = 55;
const cleared = [];
const originalClearInterval = global.clearInterval;
global.clearInterval = (id) => {
cleared.push(id);
};
let doneCalled = 0;
try {
inst._attachCloseHandler();
node._handlers.close(() => {
doneCalled += 1;
});
} finally {
global.clearInterval = originalClearInterval;
}
assert.deepEqual(cleared, [55]);
assert.equal(doneCalled, 1);
});