feat(host-agent): report assignment outcomes
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from datetime import UTC, datetime
|
||||
|
||||
from cloud.internal_api.models import AssignmentModel, TerminalResultResponse
|
||||
from host_agent.assignment import AssignmentExecutionResult
|
||||
from host_agent.processor import AssignmentProcessor
|
||||
|
||||
|
||||
def _assignment() -> AssignmentModel:
|
||||
return AssignmentModel(
|
||||
task_id="task-a",
|
||||
attempt=1,
|
||||
lease_id="lease-a",
|
||||
lease_expires_at=datetime(2026, 7, 12, tzinfo=UTC),
|
||||
host_id="host-a",
|
||||
device_id="device-a",
|
||||
goal="open settings",
|
||||
)
|
||||
|
||||
|
||||
def test_processor_reports_success_with_execution_metadata() -> None:
|
||||
async def scenario() -> None:
|
||||
reports: list[dict[str, object]] = []
|
||||
|
||||
class SuccessfulExecutor:
|
||||
async def run(self, assignment):
|
||||
return AssignmentExecutionResult(
|
||||
status="done",
|
||||
failure_reason="ignored success detail",
|
||||
metadata={"runtime_task_id": "runtime-a"},
|
||||
)
|
||||
|
||||
class RecordingClient:
|
||||
async def report_result(self, assignment, **kwargs):
|
||||
reports.append(kwargs)
|
||||
return TerminalResultResponse(status="recorded")
|
||||
|
||||
result = await AssignmentProcessor(
|
||||
RecordingClient(), # type: ignore[arg-type]
|
||||
SuccessfulExecutor(),
|
||||
).process(_assignment())
|
||||
|
||||
assert result.report_status == "recorded"
|
||||
assert reports == [
|
||||
{
|
||||
"status": "done",
|
||||
"failure_reason": None,
|
||||
"result": {"runtime_task_id": "runtime-a"},
|
||||
}
|
||||
]
|
||||
|
||||
asyncio.run(scenario())
|
||||
|
||||
|
||||
def test_processor_preserves_runtime_failure_reason() -> None:
|
||||
async def scenario() -> None:
|
||||
reports: list[dict[str, object]] = []
|
||||
|
||||
class FailedExecutor:
|
||||
async def run(self, assignment):
|
||||
return AssignmentExecutionResult(
|
||||
status="failed",
|
||||
failure_reason="planner unavailable",
|
||||
metadata={"runtime_status": "failed"},
|
||||
)
|
||||
|
||||
class RecordingClient:
|
||||
async def report_result(self, assignment, **kwargs):
|
||||
reports.append(kwargs)
|
||||
return TerminalResultResponse(status="already_recorded")
|
||||
|
||||
result = await AssignmentProcessor(
|
||||
RecordingClient(), # type: ignore[arg-type]
|
||||
FailedExecutor(),
|
||||
).process(_assignment())
|
||||
|
||||
assert result.report_status == "already_recorded"
|
||||
assert result.execution.failure_reason == "planner unavailable"
|
||||
assert reports[0] == {
|
||||
"status": "failed",
|
||||
"failure_reason": "planner unavailable",
|
||||
"result": {"runtime_status": "failed"},
|
||||
}
|
||||
|
||||
asyncio.run(scenario())
|
||||
Reference in New Issue
Block a user