Add rule event compatibility tests

This commit is contained in:
Luna 2026-07-08 17:09:00 -07:00
parent 66472134d8
commit a7535cfc56
2 changed files with 83 additions and 1 deletions

View file

@ -175,7 +175,7 @@ turning Sentinel into a noisy rules dump.
event type, match fields, expected false positives, and drill coverage. event type, match fields, expected false positives, and drill coverage.
- ✅ Require a fixture or safe red-team drill for every built-in SID, including - ✅ Require a fixture or safe red-team drill for every built-in SID, including
event-only and correlation SIDs. event-only and correlation SIDs.
- Add compatibility tests for rule JSON/event schema evolution. - Add compatibility tests for rule JSON/event schema evolution.
- ✅ Extend triage so false-positive suggestions are tied to SID/classtype and can - ✅ Extend triage so false-positive suggestions are tied to SID/classtype and can
emit TOML snippets for allowlists, correlation windows, or severity overrides. emit TOML snippets for allowlists, correlation windows, or severity overrides.
- ✅ Add post-alert enrichment consistently across detections: - ✅ Add post-alert enrichment consistently across detections:

82
tests/test_rule_compat.py Normal file
View file

@ -0,0 +1,82 @@
# SPDX-License-Identifier: GPL-3.0-or-later
"""Compatibility tests for rule event JSON evolution."""
import unittest
from enodia_sentinel import ruleops
from enodia_sentinel.config import Config
class TestRuleEventCompatibility(unittest.TestCase):
def setUp(self):
self.cfg = Config()
def _sids(self, event):
return {a.sid for a in ruleops.test_event(self.cfg, event)}
def test_exec_event_accepts_type_alias(self):
event = {
"type": "execve",
"pid": "4242",
"ppid": "1",
"uid": "1000",
"parent_comm": "nginx",
"filename": "/usr/bin/sh",
"argv": ["-c", "id"],
}
self.assertIn(100003, self._sids(event))
def test_exec_event_kind_can_be_inferred_from_fields(self):
event = {
"pid": 4242,
"ppid": 1,
"uid": 1000,
"parent_comm": "bash",
"filename": "/tmp/payload",
"argv": [],
}
self.assertIn(100001, self._sids(event))
def test_syscall_event_accepts_type_alias_and_numeric_strings(self):
event = {
"type": "sys",
"pid": "4242",
"ppid": "1",
"uid": "1000",
"comm": "loader",
"syscall": "mprotect",
"args": ["0x1000", "0x1000", "0x6"],
}
self.assertIn(100060, self._sids(event))
def test_syscall_event_kind_can_be_inferred_from_fields(self):
event = {
"pid": 4242,
"ppid": 1,
"uid": 1000,
"comm": "loader",
"syscall": "memfd_create",
}
self.assertIn(100062, self._sids(event))
def test_syscall_arg_fields_override_args_array(self):
event = {
"event": "syscall",
"pid": 4242,
"ppid": 1,
"uid": 1000,
"comm": "loader",
"syscall": "mmap",
"args": [0, 4096, 0],
"arg2": "0x6",
}
self.assertIn(100061, self._sids(event))
def test_unknown_event_shape_still_errors(self):
with self.assertRaisesRegex(
ValueError, "event JSON must be an exec or syscall event"
):
ruleops.test_event(self.cfg, {"pid": 4242})
if __name__ == "__main__":
unittest.main()