Add persistent device traffic history charts
Build and Deploy Gateway / build-and-push (push) Successful in 14s
Build and Deploy Gateway / deploy (push) Successful in 6s

This commit is contained in:
2026-08-07 19:34:59 +03:00
parent cf90fd5b4e
commit ef4847a3e1
7 changed files with 174 additions and 45 deletions
+45
View File
@@ -273,6 +273,51 @@ test('device traffic totals persist exact deltas across polls and process epochs
assert.equal(snapshot.source.traffic.error, 'traffic unavailable');
});
test('device traffic history stays in bounded service memory and survives client snapshots', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'harbor-device-history-'));
t.after(() => fs.rmSync(directory, { recursive: true, force: true }));
const filePath = path.join(directory, 'devices.json');
const store = createJsonStore({ filePath, defaultValue: {}, migrate: migrateDeviceInventoryState });
const mac = '00:11:22:33:44:55';
let observedAt = '2026-08-07T12:00:00.000Z';
let uploadBytes = '100';
let proxyDownloadBytes = '20';
const createService = () => createDeviceInventoryService({
store,
observe: () => ({
observedAt,
error: null,
observations: [{ ip: '192.168.50.7', mac, interface: 'eth0', observedAt, active: true }],
}),
observeTraffic: () => ({
epoch: 'epoch-a',
generation: 'rules-a',
observedAt,
source: { error: null },
devices: [{
ip: '192.168.50.7', mac, interface: 'eth0', uploadBytes, downloadBytes: '0',
proxyUploadBytes: '0', proxyDownloadBytes,
}],
}),
});
const service = createService();
assert.deepEqual((await service.refresh()).devices[0].trafficHistory, []);
observedAt = '2026-08-07T12:00:15.000Z';
uploadBytes = '130';
proxyDownloadBytes = '25';
const snapshot = await service.refresh();
assert.equal(snapshot.trafficHistoryCapacity, 120);
assert.deepEqual(snapshot.devices[0].trafficHistory, [{
observedAt,
gatewayBytes: '30',
proxyBytes: '5',
}]);
assert.deepEqual(service.snapshot().devices[0].trafficHistory, snapshot.devices[0].trafficHistory);
assert.doesNotMatch(fs.readFileSync(filePath, 'utf8'), /trafficHistory/);
assert.deepEqual(createService().snapshot().devices[0].trafficHistory, []);
});
test('legacy dataplane samples preserve saved proxy totals while Gateway totals keep advancing', async (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'harbor-device-proxy-legacy-'));
t.after(() => fs.rmSync(directory, { recursive: true, force: true }));