import { describe, expect, test } from 'bun:test'; import type { DriftFinding } from '../audit/types'; import { failingKeysFromFindings, severityForDriftSeverity, targetKindForCategory, } from './builtin-monitors'; import { healthCoverageFailingKeys } from './health-coverage'; function finding(over: Partial = {}): DriftFinding { return { category: 'machines_reachable', severity: 'drift', code: 'machine_unreachable', message: 'iot unreachable', subject: 'iot', ...over, }; } describe('targetKindForCategory', () => { test('machine-scoped category', () => { expect(targetKindForCategory('machines_reachable')).toBe('machine'); }); test('module-scoped category', () => { expect(targetKindForCategory('backups')).toBe('module'); }); // Machine-scoped so suppression inherits the machine topology: an unreachable // host suppresses its own disk alert instead of paging twice for one dead box. test('disk_space is machine-scoped', () => { expect(targetKindForCategory('disk_space')).toBe('machine'); }); // Whole-system categories have no narrower subject to suppress against. test('unmapped category falls back to system', () => { expect(targetKindForCategory('cli_version')).toBe('system'); expect(targetKindForCategory('schema')).toBe('system'); }); }); describe('severityForDriftSeverity', () => { test('todo never pages, whatever the monitor says', () => { expect(severityForDriftSeverity('todo', 'critical')).toBe('warning'); }); test('drift and blocked take the monitor severity', () => { expect(severityForDriftSeverity('drift', 'critical')).toBe('critical'); expect(severityForDriftSeverity('blocked', 'critical')).toBe('critical'); }); }); describe('failingKeysFromFindings', () => { // Asserts the WHOLE key, not a prefix. A prefix-only assertion is exactly why // #596 survived — machines_reachable emits a UUID where suppression expects a // hostname, and `toContain('builtin:machines_reachable/machine:')` passes for // both. This check must be pinned to the identifier itself. test('disk_space keys on the hostname, in full', () => { const keys = failingKeysFromFindings( 'disk_space', [ finding({ category: 'disk_space', code: 'disk_critical', severity: 'blocked', subject: 'celilo-mgr', message: 'celilo-mgr: root filesystem 96% full', }), ], 'critical', ); expect(keys).toHaveLength(1); expect(keys[0]?.key).toBe('builtin:disk_space/machine:celilo-mgr'); expect(keys[0]?.severity).toBe('critical'); }); // An unmeasurable host records without paging. test('an unmeasured disk downgrades to warning', () => { const keys = failingKeysFromFindings( 'disk_space', [finding({ category: 'disk_space', severity: 'todo', subject: 'iot' })], 'critical', ); expect(keys[0]?.key).toBe('builtin:disk_space/machine:iot'); expect(keys[0]?.severity).toBe('warning'); }); test('projects findings into builtin keys', () => { const keys = failingKeysFromFindings('machines_reachable', [finding()], 'critical'); expect(keys).toEqual([ { key: 'builtin:machines_reachable/machine:iot', severity: 'critical', message: 'iot unreachable', details: undefined, }, ]); }); // A monitor owns exactly one category. Resolution is set-difference over the // keys a monitor reports, so letting a stray category through would make some // OTHER monitor's alerts resolve at random. test('ignores findings from other categories', () => { const mixed = [finding(), finding({ category: 'backups', subject: 'forgejo' })]; const keys = failingKeysFromFindings('machines_reachable', mixed, 'critical'); expect(keys).toHaveLength(1); expect(keys[0].key).toBe('builtin:machines_reachable/machine:iot'); }); test('no findings produces an empty failing set', () => { expect(failingKeysFromFindings('machines_reachable', [], 'critical')).toEqual([]); }); }); describe('healthCoverageFailingKeys', () => { const base = { hasHealthCheckHook: true, cadence: { minutes: 15 } } as const; test('a monitored module produces no finding', () => { expect(healthCoverageFailingKeys([{ id: 'caddy', state: 'VERIFIED', ...base }])).toEqual([]); }); test('a module with no health_check hook is surfaced', () => { const keys = healthCoverageFailingKeys([ { id: 'signal', state: 'INSTALLED', hasHealthCheckHook: false, cadence: null }, ]); expect(keys).toHaveLength(1); expect(keys[0].key).toBe('builtin:health_coverage/module:signal'); expect(keys[0].message).toContain('no health_check hook'); }); test('an operator opt-out raises no finding — it is a decision, not a gap', () => { // The finding would ask for the action they just declined, so nothing they // could do would ever clear it. expect( healthCoverageFailingKeys([ { id: 'lunacycle', state: 'VERIFIED', hasHealthCheckHook: true, cadence: 'manual' }, ]), ).toEqual([]); }); test('a module with a hook but no cadence is surfaced differently', () => { const keys = healthCoverageFailingKeys([ { id: 'caddy', state: 'VERIFIED', hasHealthCheckHook: true, cadence: null }, ]); expect(keys).toHaveLength(1); expect(keys[0].message).toContain('nothing schedules it'); }); // A coverage gap is real but is not an outage — it must never page. test('findings are warning severity', () => { const keys = healthCoverageFailingKeys([ { id: 'caddy', state: 'VERIFIED', hasHealthCheckHook: false, cadence: null }, ]); expect(keys[0].severity).toBe('warning'); }); // Not-yet-deployed modules have nothing to observe; an absent monitor there // is expected, not a gap. test.each(['IMPORTED', 'VALIDATED', 'CONFIGURED', 'DEPLOYING', 'ERROR'] as const)( 'ignores a module in state %s', (state) => { expect( healthCoverageFailingKeys([{ id: 'x', state, hasHealthCheckHook: false, cadence: null }]), ).toEqual([]); }, ); test('reports only the modules that are actually uncovered', () => { const keys = healthCoverageFailingKeys([ { id: 'caddy', state: 'VERIFIED', ...base }, { id: 'signal', state: 'INSTALLED', hasHealthCheckHook: false, cadence: null }, { id: 'forgejo', state: 'INSTALLED', hasHealthCheckHook: true, cadence: null }, ]); expect(keys.map((k) => k.key)).toEqual([ 'builtin:health_coverage/module:signal', 'builtin:health_coverage/module:forgejo', ]); }); });