- 新增 task_report 任务级聚合指标 task_metrics - 补充创建任务幂等与失败路径/冲突测试 - 将后端测试基线提升到 20 passed - 新增 edge-agent 初始化代码、启动脚本与打包脚本 - 新增 http_health_check、check_port、check_process、grep_log 执行器 - 补充 edge-agent 基础测试并提升基线到 10 passed - 同步更新 backend README 与当前进度总结
98 lines
3.2 KiB
Python
98 lines
3.2 KiB
Python
from __future__ import annotations
|
|
|
|
from app.core.config import Settings
|
|
from app.scheduler.polling_runner import PollingRunner
|
|
|
|
|
|
class StubBackendClient:
|
|
def __init__(self) -> None:
|
|
self.heartbeats: list[dict] = []
|
|
self.task_reports: list[dict] = []
|
|
self.event_reports: list[dict] = []
|
|
self._tasks: list[dict] = []
|
|
|
|
def heartbeat(self, capabilities: list[str]) -> dict:
|
|
self.heartbeats.append({"capabilities": capabilities})
|
|
return {"success": True}
|
|
|
|
def pull_tasks(self, max_tasks: int = 5) -> list[dict]:
|
|
return self._tasks[:max_tasks]
|
|
|
|
def report_task(self, payload: dict) -> dict:
|
|
self.task_reports.append(payload)
|
|
return {"success": True}
|
|
|
|
def report_event(self, event_type: str, message: str, detail: dict | None = None) -> dict:
|
|
self.event_reports.append({"event_type": event_type, "message": message, "detail": detail or {}})
|
|
return {"success": True}
|
|
|
|
def close(self) -> None:
|
|
return None
|
|
|
|
|
|
class StubExecutor:
|
|
def execute(self, params: dict) -> tuple[bool, str, dict, dict]:
|
|
return True, "200 OK", {"status_code": 200, "latency_ms": 12}, {"response_body": '{"status":"UP"}'}
|
|
|
|
|
|
def build_settings() -> Settings:
|
|
return Settings(
|
|
backend_base_url="http://127.0.0.1:8000",
|
|
edge_id="edge-shanghai-001",
|
|
edge_name="edge-agent-demo",
|
|
edge_hostname="customer-host-01",
|
|
edge_os_type="WINDOWS",
|
|
edge_agent_version="0.1.0",
|
|
edge_access_token=None,
|
|
poll_interval_ms=1000,
|
|
heartbeat_interval_ms=1000,
|
|
request_timeout_ms=5000,
|
|
default_health_check_timeout_ms=3000,
|
|
)
|
|
|
|
|
|
def test_polling_runner_reports_unsupported_tool() -> None:
|
|
runner = PollingRunner(build_settings())
|
|
runner.backend_client = StubBackendClient()
|
|
runner.backend_client._tasks = [
|
|
{
|
|
"task_id": "task-001",
|
|
"step_id": "step-001",
|
|
"tool_name": "unknown_tool",
|
|
"params": {},
|
|
"expire_at": "2026-04-09 10:00:00.000",
|
|
}
|
|
]
|
|
|
|
runner.run_once()
|
|
|
|
assert len(runner.backend_client.event_reports) == 1
|
|
assert runner.backend_client.event_reports[0]["event_type"] == "UNSUPPORTED_TOOL"
|
|
assert len(runner.backend_client.task_reports) == 1
|
|
assert runner.backend_client.task_reports[0]["success"] is False
|
|
assert runner.backend_client.task_reports[0]["code"] == "UNSUPPORTED_TOOL"
|
|
|
|
|
|
def test_polling_runner_executes_registered_tool() -> None:
|
|
runner = PollingRunner(build_settings())
|
|
runner.backend_client = StubBackendClient()
|
|
runner.registry._executors["http_health_check"] = StubExecutor()
|
|
runner.backend_client._tasks = [
|
|
{
|
|
"task_id": "task-002",
|
|
"step_id": "step-002",
|
|
"tool_name": "http_health_check",
|
|
"params": {"url": "http://service.test/health"},
|
|
"expire_at": "2026-04-09 10:00:00.000",
|
|
}
|
|
]
|
|
|
|
runner.run_once()
|
|
|
|
assert len(runner.backend_client.task_reports) == 1
|
|
report = runner.backend_client.task_reports[0]
|
|
assert report["success"] is True
|
|
assert report["code"] == "OK"
|
|
assert report["data"]["status_code"] == 200
|
|
assert report["evidence"]["response_body"] == '{"status":"UP"}'
|