more_agent/tests/test_basic.py

528 lines
17 KiB
Python
Raw Normal View History

2026-05-12 05:13:49 +00:00
"""
MACP 基础测试模块
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
对核心服务层进行单元测试验证各模块基本功能正确性
2026-05-12 05:03:18 +00:00
"""
2026-05-12 05:13:49 +00:00
from __future__ import annotations
2026-05-12 05:03:18 +00:00
import pytest
from fastapi.testclient import TestClient
from app.main import app
2026-05-12 05:13:49 +00:00
from app.models import (
Document,
DocumentStatus,
FileType,
GjbRule,
GjbStandard,
KnowledgeChunk,
KnowledgeLevel,
McpTool,
MemoryEntry,
MemoryType,
Skill,
Template,
TemplateType,
Workflow,
)
from app.services import (
DocumentService,
GjbValidatorService,
KnowledgeBaseService,
McpToolService,
MemoryService,
ModelService,
MultimodalService,
SandboxService,
SkillService,
TemplateService,
)
# =============================================================================
# 客户端 Fixture
# =============================================================================
@pytest.fixture
def client():
"""FastAPI 测试客户端"""
with TestClient(app) as c:
yield c
# =============================================================================
# 健康检查测试
# =============================================================================
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
class TestHealthCheck:
"""健康检查接口测试"""
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_health_endpoint(self, client):
"""测试 /api/health 接口"""
response = client.get("/api/health")
assert response.status_code == 200
data = response.json()
assert data["status"] == "ok"
assert data["service"] == "MACP Platform"
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_root_endpoint(self, client):
"""测试根路径"""
response = client.get("/")
assert response.status_code == 200
data = response.json()
assert "MACP" in data["message"]
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
# =============================================================================
# 模板管理服务测试SRS-MACP_F-001
# =============================================================================
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
class TestTemplateService:
"""文档模板管理服务测试"""
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def setup_method(self):
self.service = TemplateService()
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_list_templates(self):
"""测试获取模板列表"""
templates = self.service.list_templates()
assert len(templates) >= 2
assert any(t.name == "GJB438C 软件需求规格说明书模板" for t in templates)
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_create_template(self):
"""测试创建模板"""
new_tpl = Template(
name="测试模板",
template_type=TemplateType.SRS,
gjb_standard=GjbStandard.GJB438C,
)
result = self.service.create_template(new_tpl)
assert result.id is not None
assert result.name == "测试模板"
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_get_template_not_found(self):
"""测试获取不存在的模板"""
result = self.service.get_template("NONEXIST")
assert result is None
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_delete_template(self):
"""测试删除模板"""
assert self.service.delete_template("TPL-001") is True
assert self.service.delete_template("NONEXIST") is False
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
# =============================================================================
# 文档管理服务测试
# =============================================================================
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
class TestDocumentService:
"""文档管理服务测试"""
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def setup_method(self):
self.service = DocumentService()
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_list_documents(self):
"""测试获取文档列表"""
docs = self.service.list_documents()
assert len(docs) >= 2
def test_create_document(self):
"""测试创建文档"""
new_doc = Document(
title="测试文档",
template_id="TPL-001",
2026-05-12 05:03:18 +00:00
)
2026-05-12 05:13:49 +00:00
result = self.service.create_document(new_doc)
assert result.id is not None
assert result.status == DocumentStatus.DRAFT
def test_get_document(self):
"""测试获取文档详情"""
doc = self.service.get_document("DOC-001")
assert doc is not None
assert doc.title == "某型雷达系统软件需求规格说明书"
# =============================================================================
# GJB合规验证服务测试SRS-MACP_F-002
# =============================================================================
class TestGjbValidatorService:
"""GJB合规验证服务测试"""
def setup_method(self):
self.service = GjbValidatorService()
self.doc_service = DocumentService()
def test_list_rules(self):
"""测试获取规则列表"""
rules = self.service.list_rules()
assert len(rules) >= 7
def test_validate_document(self):
"""测试文档合规验证"""
doc = self.doc_service.get_document("DOC-001")
assert doc is not None
report = self.service.validate_document(doc)
assert report.document_id == "DOC-001"
assert report.total_rules >= 7
assert isinstance(report.non_compliant_items, list)
# =============================================================================
# MCP工具管理服务测试SRS-MACP_F-004
# =============================================================================
class TestMcpToolService:
"""MCP工具管理服务测试"""
def setup_method(self):
self.service = McpToolService()
def test_list_tools(self):
"""测试获取MCP工具列表"""
tools = self.service.list_tools()
assert len(tools) >= 2
def test_register_tool(self):
"""测试注册MCP工具"""
new_tool = McpTool(
name="test_tool",
description="测试工具",
2026-05-12 05:03:18 +00:00
)
2026-05-12 05:13:49 +00:00
result = self.service.register_tool(new_tool)
assert result.id is not None
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_debug_tool(self):
"""测试MCP工具调试"""
result = self.service.debug_tool("MCP-001", {"test": "data"})
assert result["success"] is True
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_debug_tool_not_found(self):
"""测试调试不存在的工具"""
result = self.service.debug_tool("NONEXIST", {})
assert result["success"] is False
# =============================================================================
# Skills编排服务测试SRS-MACP_F-005
# =============================================================================
class TestSkillService:
"""Skills流程编排服务测试"""
def setup_method(self):
self.service = SkillService()
def test_list_skills(self):
"""测试获取Skills列表"""
skills = self.service.list_skills()
assert len(skills) >= 2
def test_create_skill(self):
"""测试创建Skill"""
new_skill = Skill(
name="测试Skill",
prompt_template="测试模板",
)
result = self.service.create_skill(new_skill)
assert result.id is not None
def test_execute_skill(self):
"""测试执行Skill"""
result = self.service.execute_skill("SK-001", {"document_id": "DOC-001"})
assert result["success"] is True
assert result["skill_id"] == "SK-001"
def test_list_workflows(self):
"""测试获取工作流列表"""
workflows = self.service.list_workflows()
assert len(workflows) >= 1
# =============================================================================
# 智能体记忆管理服务测试SRS-MACP_F-006
# =============================================================================
class TestMemoryService:
"""智能体记忆管理服务测试"""
def setup_method(self):
self.service = MemoryService()
def test_list_memories(self):
"""测试获取记忆列表"""
memories = self.service.list_memories()
assert len(memories) >= 2
def test_create_memory(self):
"""测试创建记忆"""
new_mem = MemoryEntry(
session_id="SESS-TEST",
summary="测试记忆",
original_dialogue="测试对话内容",
memory_type=MemoryType.SHORT_TERM,
2026-05-12 05:03:18 +00:00
)
2026-05-12 05:13:49 +00:00
result = self.service.create_memory(new_mem)
assert result.id is not None
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_search_memories(self):
"""测试搜索记忆"""
results = self.service.search_memories("GJB438C")
assert len(results) >= 1
def test_delete_memory(self):
"""测试删除记忆"""
assert self.service.delete_memory("MEM-001") is True
assert self.service.delete_memory("NONEXIST") is False
# =============================================================================
# 知识库交互服务测试SRS-MACP_F-008
# =============================================================================
class TestKnowledgeBaseService:
"""知识库交互服务测试"""
def setup_method(self):
self.service = KnowledgeBaseService()
def test_list_chunks(self):
"""测试获取知识库片段"""
chunks = self.service.list_chunks()
assert len(chunks) >= 3
def test_list_chunks_by_level(self):
"""测试按层级过滤知识库片段"""
docs = self.service.list_chunks(KnowledgeLevel.DOCUMENT)
assert all(c.level == KnowledgeLevel.DOCUMENT for c in docs)
def test_search_chunks(self):
"""测试搜索知识库"""
results = self.service.search_chunks("GJB438C")
assert len(results) >= 1
def test_get_chunk_not_found(self):
"""测试获取不存在的知识库片段"""
result = self.service.get_chunk("NONEXIST")
assert result is None
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
# =============================================================================
# 大模型接入管理服务测试SRS-MACP_F-009
# =============================================================================
class TestModelService:
"""大模型接入管理服务测试"""
def setup_method(self):
self.service = ModelService()
def test_list_models(self):
"""测试获取模型配置列表"""
models = self.service.list_models()
assert len(models) >= 2
def test_get_primary_model(self):
"""测试获取主用模型"""
model = self.service.get_primary_model()
assert model is not None
assert model.is_primary is True
def test_health_check(self):
"""测试模型健康检查"""
result = self.service.health_check("MDL-001")
assert result["healthy"] is True
def test_failover(self):
"""测试模型故障转移"""
model = self.service.failover("MDL-001")
assert model is not None
assert model.is_primary is True
# =============================================================================
# 多模态处理服务测试SRS-MACP_F-010
# =============================================================================
class TestMultimodalService:
"""多模态输入处理服务测试"""
def setup_method(self):
self.service = MultimodalService()
def test_process_image(self):
"""测试图片处理"""
result = self.service.process_file("test.jpg", FileType.IMAGE)
assert result.ocr_text is not None
assert result.file_type == FileType.IMAGE
def test_process_audio(self):
"""测试音频处理"""
result = self.service.process_file("test.mp3", FileType.AUDIO)
assert result.asr_transcript is not None
assert result.file_type == FileType.AUDIO
def test_process_video(self):
"""测试视频处理"""
result = self.service.process_file("test.mp4", FileType.VIDEO)
assert result.ocr_text is not None
assert result.asr_transcript is not None
assert len(result.key_frames) > 0
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_get_result(self):
"""测试获取处理结果"""
result = self.service.process_file("test.png", FileType.IMAGE)
fetched = self.service.get_result(result.id)
assert fetched is not None
assert fetched.id == result.id
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
# =============================================================================
# 安全沙箱执行服务测试SRS-MACP_F-007
# =============================================================================
class TestSandboxService:
"""安全沙箱执行服务测试"""
def setup_method(self):
self.service = SandboxService()
def test_execute_code(self):
"""测试沙箱执行代码"""
result = self.service.execute_code("print('hello')", "python")
assert result["status"] == "completed"
assert result["execution_id"] is not None
def test_get_execution_logs(self):
"""测试获取执行日志"""
self.service.execute_code("x = 1 + 1", "python")
logs = self.service.get_execution_logs()
assert len(logs) >= 1
# =============================================================================
# API 接口集成测试
# =============================================================================
class TestApiEndpoints:
"""API 接口集成测试"""
def test_get_templates_api(self, client):
"""测试获取模板列表接口"""
response = client.get("/api/v1/templates")
2026-05-12 05:03:18 +00:00
assert response.status_code == 200
data = response.json()
2026-05-12 05:13:49 +00:00
assert data["code"] == 200
assert len(data["data"]) >= 2
def test_create_template_api(self, client):
"""测试创建模板接口"""
payload = {
"name": "API测试模板",
"template_type": "SRS",
"gjb_standard": "GJB438C",
}
response = client.post("/api/v1/templates", json=payload)
2026-05-12 05:03:18 +00:00
assert response.status_code == 200
data = response.json()
2026-05-12 05:13:49 +00:00
assert data["message"] == "模板创建成功"
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_get_documents_api(self, client):
"""测试获取文档列表接口"""
response = client.get("/api/v1/documents")
2026-05-12 05:03:18 +00:00
assert response.status_code == 200
data = response.json()
2026-05-12 05:13:49 +00:00
assert data["code"] == 200
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_validate_document_api(self, client):
"""测试文档合规验证接口"""
response = client.post("/api/v1/documents/DOC-001/validate")
assert response.status_code == 200
data = response.json()
assert data["code"] == 200
assert "验证完成" in data["message"]
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_get_rules_api(self, client):
"""测试获取规则列表接口"""
response = client.get("/api/v1/rules")
assert response.status_code == 200
data = response.json()
assert data["code"] == 200
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_get_skills_api(self, client):
"""测试获取Skills列表接口"""
response = client.get("/api/v1/skills")
assert response.status_code == 200
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_execute_skill_api(self, client):
"""测试执行Skill接口"""
response = client.post(
"/api/v1/skills/execute",
params={"skill_id": "SK-001"},
json={"document_id": "DOC-001"},
2026-05-12 05:03:18 +00:00
)
assert response.status_code == 200
data = response.json()
2026-05-12 05:13:49 +00:00
assert data["data"]["success"] is True
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_get_memory_api(self, client):
"""测试获取记忆列表接口"""
response = client.get("/api/v1/memory")
assert response.status_code == 200
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_search_knowledge_api(self, client):
"""测试搜索知识库接口"""
response = client.post(
"/api/v1/knowledge/search",
params={"query": "GJB438C", "top_k": 3},
2026-05-12 05:03:18 +00:00
)
assert response.status_code == 200
data = response.json()
2026-05-12 05:13:49 +00:00
assert len(data["data"]) >= 1
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_get_models_api(self, client):
"""测试获取模型配置列表接口"""
response = client.get("/api/v1/models")
assert response.status_code == 200
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_multimodal_process_api(self, client):
"""测试多模态处理接口"""
2026-05-12 05:03:18 +00:00
response = client.post(
2026-05-12 05:13:49 +00:00
"/api/v1/multimodal/process",
params={"file_name": "test.jpg", "file_type": "IMAGE"},
2026-05-12 05:03:18 +00:00
)
assert response.status_code == 200
2026-05-12 05:13:49 +00:00
def test_sandbox_execute_api(self, client):
"""测试沙箱执行接口"""
2026-05-12 05:03:18 +00:00
response = client.post(
2026-05-12 05:13:49 +00:00
"/api/v1/sandbox/execute",
params={"code": "print('hello')", "language": "python"},
2026-05-12 05:03:18 +00:00
)
2026-05-12 05:13:49 +00:00
assert response.status_code == 200
def test_mcp_tools_api(self, client):
"""测试获取MCP工具列表接口"""
response = client.get("/api/v1/mcp-tools")
assert response.status_code == 200
def test_404_error(self, client):
"""测试404错误"""
response = client.get("/api/v1/templates/NONEXIST")
assert response.status_code == 404
def test_get_workflows_api(self, client):
"""测试获取工作流列表接口"""
response = client.get("/api/v1/workflows")
assert response.status_code == 200
2026-05-12 05:03:18 +00:00
2026-05-12 05:13:49 +00:00
def test_get_mcp_tool_debug(self, client):
"""测试MCP工具调试接口"""
2026-05-12 05:03:18 +00:00
response = client.post(
2026-05-12 05:13:49 +00:00
"/api/v1/mcp-tools/MCP-001/debug",
json={"input": "test"},
2026-05-12 05:03:18 +00:00
)
2026-05-12 05:13:49 +00:00
assert response.status_code == 200