88 lines
2.8 KiB
Python
88 lines
2.8 KiB
Python
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())
|