# SPDX-License-Identifier: GPL-3.0-or-later """Emission-based coverage: every built-in SID has a fixture or drill. Event-rule SIDs are covered by JSON fixtures under tests/fixtures/sids/ (replayable by operators via `enodia-sentinel rules test `); the other engines are covered by drills in tests/sid_drills.py. This module replays and runs all of them for real and asserts the emitted sids match the registry in enodia_sentinel.sids. """ import json import unittest from pathlib import Path from enodia_sentinel import ruleops, sids from enodia_sentinel.config import Config from tests.sid_drills import DRILLS FIXTURE_DIR = Path(__file__).resolve().parent / "fixtures" / "sids" def fixture_sids() -> dict[int, set[int]]: """Replay every fixture; map declared sid to sids actually emitted.""" out: dict[int, set[int]] = {} for path in sorted(FIXTURE_DIR.glob("*.json")): declared = int(path.name.split("-", 1)[0]) event = json.loads(path.read_text()) alerts = ruleops.test_event(Config(), event) out[declared] = {a.sid for a in alerts} return out class TestEventFixtures(unittest.TestCase): def test_every_event_rule_sid_has_an_emitting_fixture(self): covered = fixture_sids() wanted = sids.engine_sids("exec_rule") | sids.engine_sids("syscall_rule") for sid in sorted(wanted): self.assertIn(sid, covered, f"no fixture file for sid {sid} in {FIXTURE_DIR}") self.assertIn(sid, covered[sid], f"fixture for sid {sid} did not emit it") def test_fixtures_emit_only_registered_sids(self): registry = sids.all_sids() for declared, emitted in fixture_sids().items(): self.assertLessEqual(emitted, registry, f"fixture {declared} emitted unregistered sids") def drill_sids() -> dict[int, set[int]]: """Run every non-event drill; map declared sid to sids emitted.""" return {sid: {a.sid for a in drill()} for sid, drill in sorted(DRILLS.items())} class TestSidCoverageGate(unittest.TestCase): def test_every_non_event_sid_has_an_emitting_drill(self): covered = drill_sids() event_sids = sids.engine_sids("exec_rule") | sids.engine_sids("syscall_rule") wanted = sids.all_sids() - event_sids self.assertEqual(set(covered), wanted) for sid in sorted(wanted): self.assertIn(sid, covered[sid], f"drill for sid {sid} did not emit it") def test_fixtures_and_drills_equal_registry(self): emitted = set() for sids_for_fixture in fixture_sids().values(): emitted.update(sids_for_fixture) for sids_for_drill in drill_sids().values(): emitted.update(sids_for_drill) self.assertEqual(emitted, sids.all_sids()) if __name__ == "__main__": unittest.main()