"""Tests for rule executor.""" import pytest from rule_engine.executor import RuleExecutor, Sandbox, ExecutionTimeout def test_executor_simple_rule(): """验证简单规则执行。""" executor = RuleExecutor() code = ''' def rule(facts): if facts.get("subscription") == "premium": return {"action": "discount", "rate": 0.8} return None ''' # 匹配 result = executor.execute_rule(code, {"subscription": "premium", "age": 25}) assert result == {"action": "discount", "rate": 0.8} # 不匹配 result = executor.execute_rule(code, {"subscription": "basic", "age": 25}) assert result is None def test_executor_complex_condition(): """验证复杂条件规则。""" executor = RuleExecutor() code = ''' def rule(facts): age = facts.get("age", 0) subscription = facts.get("subscription") if subscription == "premium" and age >= 18: return {"action": "approve"} return {"action": "deny"} ''' result = executor.execute_rule(code, {"subscription": "premium", "age": 25}) assert result["action"] == "approve" result = executor.execute_rule(code, {"subscription": "premium", "age": 16}) assert result["action"] == "deny" result = executor.execute_rule(code, {"subscription": "basic", "age": 25}) assert result["action"] == "deny" def test_executor_validate_rule_code_valid(): """验证合法代码通过检查。""" executor = RuleExecutor() code = 'def rule(facts):\n return None' assert executor.validate_rule_code(code) is True def test_executor_validate_rule_code_blocked_keyword(): """验证危险关键字被拦截。""" executor = RuleExecutor() assert executor.validate_rule_code('def rule(facts):\n import os') is False assert executor.validate_rule_code('def rule(facts):\n exec("")') is False assert executor.validate_rule_code('def rule(facts):\n eval("")') is False def test_executor_validate_rule_code_syntax_error(): """验证语法错误被检测。""" executor = RuleExecutor() assert executor.validate_rule_code('def rule(facts):\n if .') is False def test_executor_timeout(): """验证执行超时。""" executor = RuleExecutor(timeout_ms=100) code = ''' def rule(facts): # 死循环 while True: pass return None ''' with pytest.raises(RuntimeError) as exc_info: executor.execute_rule(code, {}) assert "timed out" in str(exc_info.value) def test_sandbox_blocks_dangerous_operations(): """验证沙箱拦截危险操作。""" executor = RuleExecutor() # 尝试访问受保护属性 code = ''' def rule(facts): return __builtins__ ''' # 注意:实际 exec 中 __builtins__ 已被替换为白名单 # 所以不会返回真正的 builtins def test_executor_nested_data(): """验证嵌套数据结构处理。""" executor = RuleExecutor() code = ''' def rule(facts): user = facts.get("user", {}) if user.get("subscription") == "premium" and user.get("active"): return {"action": "allow"} return None ''' facts = { "user": { "subscription": "premium", "active": True } } result = executor.execute_rule(code, facts) assert result["action"] == "allow"