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"}'