feat: 完成 issue #43 ④ 敏感度路由规则引擎(本地/云端分级)
This commit is contained in:
@@ -132,5 +132,59 @@ class RuleModelTest(unittest.TestCase):
|
||||
self.assertEqual(hits[0][0], "1234")
|
||||
|
||||
|
||||
class EngineDiagnosticsTest(unittest.TestCase):
|
||||
"""规则引擎诊断(issue #43):priority / validate / stats / describe。"""
|
||||
|
||||
def test_priority_from_mapping(self):
|
||||
rule = RouterRule.from_mapping(
|
||||
{"name": "r", "pattern": "x", "target": "block", "priority": 1})
|
||||
self.assertEqual(rule.priority, 1)
|
||||
self.assertEqual(RouterRule.from_mapping(
|
||||
{"name": "r2", "pattern": "x", "target": "local"}).priority, 0)
|
||||
|
||||
def test_priority_orders_rules(self):
|
||||
# block 规则 priority=1 → 先于 local 规则(priority=10)命中
|
||||
# 用“紧急停泵”避免命中内置 rt_emergency_cmd(pattern=停机)
|
||||
rules = [
|
||||
RouterRule.from_mapping(
|
||||
{"name": "low", "pattern": "紧急停泵", "target": "local", "priority": 10}),
|
||||
RouterRule.from_mapping(
|
||||
{"name": "high", "pattern": "紧急停泵", "target": "block", "priority": 1}),
|
||||
]
|
||||
router = SensitivityRouter(rules=rules)
|
||||
self.assertEqual(router.route("紧急停泵").target, "block")
|
||||
names = router.rule_names
|
||||
self.assertLess(names.index("high"), names.index("low")) # priority 升序
|
||||
|
||||
def test_validate_rules(self):
|
||||
# 合法规则集(含内置保底):无问题;重复名在合并时按 name 覆盖不产生冲突
|
||||
router = SensitivityRouter(rules=[
|
||||
RouterRule.from_mapping({"name": "a", "pattern": "x", "target": "local"}),
|
||||
])
|
||||
self.assertEqual(router.validate_rules(), [])
|
||||
|
||||
def test_stats(self):
|
||||
router = SensitivityRouter(rules=[
|
||||
RouterRule.from_mapping({"name": "a", "pattern": "x", "target": "local"}),
|
||||
RouterRule.from_mapping(
|
||||
{"name": "b", "kind": "regex", "pattern": r"\d+", "target": "cloud"}),
|
||||
])
|
||||
stats = router.stats()
|
||||
self.assertEqual(stats["by_target"]["local"], 3) # 内置 PII 2 条 + a
|
||||
self.assertEqual(stats["by_target"]["cloud"], 1)
|
||||
self.assertEqual(stats["by_kind"]["regex"], 3) # 内置 PII 2 条 + b
|
||||
|
||||
def test_describe_hit_chain(self):
|
||||
router = SensitivityRouter(rules=[
|
||||
RouterRule.from_mapping({"name": "a", "pattern": "紧急停泵", "target": "local"}),
|
||||
RouterRule.from_mapping(
|
||||
{"name": "b", "pattern": "紧急停泵", "target": "block", "priority": 1}),
|
||||
])
|
||||
desc = router.describe("紧急停泵")
|
||||
names = [h["name"] for h in desc["hits"]]
|
||||
self.assertEqual(names, ["a", "b"]) # priority 升序(a=0 先于 b=1)
|
||||
self.assertEqual(router.route("紧急停泵").target, "local") # 决策取首个命中(a)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user