Files
peardock/test/stats-idle.test.js
T
Raven Scott 637c386e33
Release rolling / release (push) Successful in 7m55s
Bring Back Realtime Table Stats
2026-08-04 22:37:41 -04:00

123 lines
3.3 KiB
JavaScript

/**
* Peer-demand stats: no Docker collection until a peer sets view interest.
*/
import test from 'brittle'
import { PeerRegistry } from '../server/core/peer-registry.js'
test('PeerRegistry onChange fires on add/remove and size transitions', (t) => {
const reg = new PeerRegistry()
/** @type {Array<[number, number]>} */
const events = []
const unsub = reg.onChange((size, prev) => events.push([size, prev]))
const s1 = { id: 'peer-aaa', destroy() {} }
const s2 = { id: 'peer-bbb', destroy() {} }
reg.add(s1)
t.is(reg.size, 1)
t.alike(events[events.length - 1], [1, 0])
reg.add(s2)
t.is(reg.size, 2)
t.alike(events[events.length - 1], [2, 1])
reg.remove('peer-aaa')
t.is(reg.size, 1)
t.alike(events[events.length - 1], [1, 2])
reg.remove('peer-bbb')
t.is(reg.size, 0)
t.alike(events[events.length - 1], [0, 1])
const n = events.length
reg.remove('nope')
t.is(events.length, n)
unsub()
reg.add(s1)
t.is(events.length, n, 'unsubscribed listener not called')
reg.clear()
})
test('PeerRegistry.broadcast is a no-op with zero peers', (t) => {
const reg = new PeerRegistry()
let pushed = 0
reg.broadcast('push:test', { x: 1 })
t.is(pushed, 0)
reg.add({
id: 'p1',
push() {
pushed += 1
},
destroy() {},
})
reg.broadcast('push:test', { x: 1 })
t.is(pushed, 1)
reg.clear()
})
test('stats service: idle until view interest; pauses when interest cleared', async (t) => {
const stats = await import('../server/services/stats.js')
const { peers } = await import('../server/core/peer-registry.js')
peers.clear()
stats.stopStatsBroadcast()
stats.resetStatsConfigForTests?.()
stats.startStatsBroadcast()
t.is(stats.isStatsCollectionActive(), false, 'idle with no interest')
const fake = {
id: 'test-peer-stats-idle',
role: 'viewer',
push() {},
destroy() {},
}
peers.add(fake)
await new Promise((r) => setTimeout(r, 30))
// Connected alone is NOT enough — must declare interest
t.is(stats.isStatsCollectionActive(), false, 'peer connected but no view interest')
stats.setPeerStatsInterest(fake.id, true, { view: 'containers' })
await new Promise((r) => setTimeout(r, 30))
t.is(stats.isStatsCollectionActive(), true, 'active after setStatsInterest')
t.is(stats.getStatsInterestCount(), 1)
stats.setPeerStatsInterest(fake.id, false)
await new Promise((r) => setTimeout(r, 20))
t.is(stats.isStatsCollectionActive(), false, 'paused after interest cleared')
t.is(stats.getStatsInterestCount(), 0)
stats.stopStatsBroadcast()
peers.clear()
})
test('stats interest cleared when peer removed from registry', async (t) => {
const stats = await import('../server/services/stats.js')
const { peers } = await import('../server/core/peer-registry.js')
peers.clear()
stats.stopStatsBroadcast()
stats.resetStatsConfigForTests?.()
stats.startStatsBroadcast()
const fake = {
id: 'test-peer-stats-drop',
role: 'viewer',
push() {},
destroy() {},
}
peers.add(fake)
stats.setPeerStatsInterest(fake.id, true, { view: 'dashboard' })
t.is(stats.isStatsCollectionActive(), true)
peers.remove(fake.id)
await new Promise((r) => setTimeout(r, 20))
t.is(stats.isStatsCollectionActive(), false, 'paused after peer disconnect')
t.is(stats.getStatsInterestCount(), 0)
stats.stopStatsBroadcast()
peers.clear()
})