/** * Stats runtime config: clamps, seconds aliases, replace. */ import test from 'brittle' import { normalizeStatsConfig, defaultStatsConfig, STATS_LIMITS, updateStatsConfig, getStatsConfig, resetStatsConfigForTests, getStatsRuntimeConfig, } from '../server/services/stats.js' test('normalizeStatsConfig clamps out-of-range values', (t) => { const n = normalizeStatsConfig({ collectIntervalMs: 50, broadcastIntervalMs: 999_999, concurrency: 100, samplesPerTick: 0, listIntervalMs: 100, cacheTtlMs: -5, warnContainers: 1, }) t.is(n.collectIntervalMs, STATS_LIMITS.collectIntervalMs.min) t.is(n.broadcastIntervalMs, STATS_LIMITS.broadcastIntervalMs.max) t.is(n.concurrency, STATS_LIMITS.concurrency.max) t.is(n.samplesPerTick, STATS_LIMITS.samplesPerTick.min) t.is(n.listIntervalMs, STATS_LIMITS.listIntervalMs.min) t.is(n.cacheTtlMs, STATS_LIMITS.cacheTtlMs.min) t.is(n.warnContainers, STATS_LIMITS.warnContainers.min) }) test('normalizeStatsConfig accepts seconds aliases from UI', (t) => { const n = normalizeStatsConfig({ collectIntervalSec: 5, // legacy alias → broadcast when broadcast unset listIntervalSec: 20, concurrency: 4, samplesPerTick: 8, }) t.is(n.broadcastIntervalMs, 5000) t.is(n.collectIntervalMs, 5000) t.is(n.listIntervalMs, 20000) t.is(n.concurrency, 4) t.is(n.samplesPerTick, 8) const n2 = normalizeStatsConfig({ broadcastIntervalSec: 3, collectIntervalSec: 9, }) // explicit broadcast wins over legacy collect alias t.is(n2.broadcastIntervalMs, 3000) }) test('defaultStatsConfig is within limits', (t) => { const d = defaultStatsConfig() t.ok(d.collectIntervalMs >= STATS_LIMITS.collectIntervalMs.min) t.ok(d.concurrency >= 1 && d.concurrency <= 32) t.ok(typeof d.cacheTtlMs === 'number') }) test('updateStatsConfig apply + replace without writing when persist false', (t) => { resetStatsConfigForTests() const applied = updateStatsConfig( { collectIntervalSec: 7, concurrency: 3 }, { persist: false } ) t.is(applied.collectIntervalMs, 7000) t.is(applied.concurrency, 3) t.is(getStatsRuntimeConfig().collectIntervalMs, 7000) const reset = updateStatsConfig({}, { replace: true, persist: false }) // replace rebuilds from defaultStatsConfig (env-aware) t.is(reset.collectIntervalMs, defaultStatsConfig().collectIntervalMs) t.is(reset.concurrency, defaultStatsConfig().concurrency) const snap = getStatsConfig() t.ok('collectIntervalSec' in snap) t.ok('limits' in snap) t.ok(typeof snap.active === 'boolean') resetStatsConfigForTests() })