Files
roboco/tests/unit/runtime/test_dispatch_qa_no_preclaim.py
T

54 lines
2.0 KiB
Python
Raw Normal View History

2026-07-02 15:36:49 +02:00
"""QA dispatch must not pre-claim the review task.
Live 2026-07-02 (ba7b751c): the unassigned-QA branch claimed the task
BEFORE spawning (awaiting_qa -> claimed via the transitioning claim), then
spawned a QA agent whose own verbs demand awaiting_qa — claim_review bounced
("cannot claim from 'claimed'"), pass_review bounced, and the agent gave up
and unclaimed. The assigned-QA branch and the external-PR reviewer dispatch
both already spawn WITHOUT pre-claiming (the agent claims itself via
claim_review); the unassigned branch must match.
"""
from __future__ import annotations
from typing import Any, cast
from unittest.mock import AsyncMock, MagicMock
from uuid import uuid4
import pytest
from roboco.runtime.orchestrator import AgentOrchestrator
def _orch() -> tuple[AgentOrchestrator, AsyncMock, AsyncMock]:
orch = AgentOrchestrator.__new__(AgentOrchestrator)
orch._pm_respawn_tracker = {}
orch._bg_tasks = set()
any_orch = cast("Any", orch)
any_orch._is_task_handled_this_tick = lambda _tid: False
any_orch._select_agent_for_cell = lambda _team, _role: "be-qa"
any_orch._is_agent_active = lambda _slug: False
any_orch._pm_respawn_should_gate = AsyncMock(return_value=False)
any_orch._build_qa_prompt = lambda _t: "review it"
any_orch._task_git_context = lambda _t: None
claim = AsyncMock(return_value=True)
spawn = AsyncMock()
any_orch._claim_task_for_agent = claim
any_orch.spawn_agent = spawn
return orch, claim, spawn
@pytest.mark.asyncio
async def test_unassigned_qa_dispatch_spawns_without_preclaim() -> None:
orch, claim, spawn = _orch()
task = {"id": str(uuid4()), "team": "backend", "assigned_to": None}
cast("Any", orch)._fetch_tasks = AsyncMock(return_value=[task])
await orch._dispatch_qa_work(MagicMock())
claim.assert_not_awaited()
spawn.assert_awaited_once()
spawn_call = spawn.await_args
assert spawn_call is not None
assert spawn_call.kwargs["task_id"] == task["id"]
assert spawn_call.kwargs["agent_id"] == "be-qa"