# 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_host_event_accepts_tcp_connect_shape(self): event = { "event": "tcp_connect", "pid": "4242", "ppid": "1", "uid": "1000", "comm": "python3", "remote_ip": "8.8.8.8", "remote_port": "4444", } self.assertIn(100067, self._sids(event)) def test_host_event_accepts_listen_shape(self): event = { "type": "listen", "pid": "4242", "ppid": "1", "uid": "1000", "comm": "python3", "bind_ip": "0.0.0.0", "bind_port": "4444", } self.assertIn(100068, self._sids(event)) def test_unknown_event_shape_still_errors(self): with self.assertRaisesRegex( ValueError, "event JSON must be an exec, syscall, or host event" ): ruleops.test_event(self.cfg, {"pid": 4242}) if __name__ == "__main__": unittest.main()