Files
xiaoli-cli/tests/test_engines.py
T
Xiaoli Dev ff53a89754 feat: 重写沙箱 + 完整测试套件 (192 tests)
沙箱 v2 - 多层隔离:
- AST 静态分析: 30+ 危险模式检测
- 子进程隔离: 独立进程执行 + 资源限制
- 网络阻断: socket 模块替换
- 模块白名单: 30 个安全模块
- 文件系统限制: 临时目录隔离
- SandboxResult 数据类 + 执行历史

测试套件 (8 个模块, 192 个用例):
- test_sandbox.py:     AST检查(47) + 沙箱执行(15) + 安全拒绝(20) + 超时(2) + 模式对比(3)
- test_conversation.py: 响应解析(13) + 思考标记(5) + 工具提取(10)
- test_config.py:       配置加载/保存/缓存/损坏处理(8)
- test_history.py:      历史CRUD/持久化/边界(12)
- test_engines.py:      引擎管理/加载/切换(14)
- test_plugins.py:      code_editor(10) + code_search(7) + git_tools(4) + tool_manager(7)
- test_integration.py:  沙箱+对话(2) + 历史+对话(2) + 安全链(3) + 提示词(1)
2026-04-25 11:43:47 +08:00

108 lines
3.2 KiB
Python

"""AI 引擎管理器测试"""
import os
import sys
import pytest
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from xiaoli.engines import EngineManager
class TestEngineManager:
"""EngineManager 测试"""
def test_init_empty(self):
mgr = EngineManager()
assert mgr.engines == {}
assert mgr.current is None
def test_set_default_existing(self):
mgr = EngineManager()
mgr.engines = {'test': 'fake_engine'}
assert mgr.set_default('test')
assert mgr.current == 'fake_engine'
def test_set_default_missing(self):
mgr = EngineManager()
assert not mgr.set_default('nonexistent')
def test_switch_existing(self):
mgr = EngineManager()
mgr.engines = {'a': 'engine_a', 'b': 'engine_b'}
assert mgr.switch('b')
assert mgr.current == 'engine_b'
def test_switch_missing(self):
mgr = EngineManager()
assert not mgr.switch('nope')
def test_current_name_none(self):
mgr = EngineManager()
assert mgr.current_name() == '未设置'
def test_current_name_set(self):
mgr = EngineManager()
mgr.current = type('E', (), {'name': 'ollama'})()
assert mgr.current_name() == 'ollama'
def test_names(self):
mgr = EngineManager()
mgr.engines = {'a': 1, 'b': 2, 'c': 3}
names = mgr.names()
assert set(names) == {'a', 'b', 'c'}
def test_generate_no_engine(self):
mgr = EngineManager()
result = mgr.generate("hello")
assert '错误' in result or 'error' in result.lower()
def test_generate_with_engine(self):
mgr = EngineManager()
class FakeEngine:
name = 'fake'
def generate_response(self, user_input, system_prompt=None):
return f"echo: {user_input}"
mgr.current = FakeEngine()
result = mgr.generate("test input")
assert 'test input' in result
def test_load_all_missing_dir(self):
mgr = EngineManager()
result = mgr.load_all('/tmp/nonexistent_engines_dir_12345')
assert result == {}
def test_find_class_patterns(self):
mgr = EngineManager()
import types
mod = types.ModuleType('test')
class TestAI:
def generate_response(self, **kw):
pass
mod.TestAI = TestAI
found = mgr._find_class(mod, 'test')
assert found == 'TestAI'
def test_find_class_no_match(self):
mgr = EngineManager()
import types
mod = types.ModuleType('test')
mod.Foo = 42 # not a class ending in AI
found = mgr._find_class(mod, 'test')
assert found is None
def test_load_all_real_engines(self):
"""测试加载实际引擎目录(不验证引擎可用性,只验证不崩溃)"""
mgr = EngineManager()
engines_dir = os.path.join(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
'ai_engines'
)
if os.path.exists(engines_dir):
mgr.load_all(engines_dir)
# 至少应该尝试加载(可能因缺少依赖而失败)
# 但不应崩溃