"""Tests for the agent dispatcher.""" import os import tempfile import pytest from unittest.mock import AsyncMock from agent.dispatcher import Dispatcher from agent.task_queue import PersistentTaskQueue @pytest.fixture async def task_queue(): """Create a temporary task queue for testing.""" fd, db_path = tempfile.mkstemp(suffix=".db") os.close(fd) queue = PersistentTaskQueue(db_path=db_path) await queue.initialize() yield queue await queue.close() os.unlink(db_path) @pytest.mark.asyncio async def test_dispatcher_processes_task(task_queue): """Dispatcher가 큐에서 작업을 꺼내 처리한다.""" await task_queue.enqueue( "thread-1", "gitea", { "issue_number": 42, "repo_owner": "quant", "repo_name": "galaxis-po", "message": "Fix the bug", }, ) mock_run_agent = AsyncMock(return_value={"pr_url": "http://..."}) dispatcher = Dispatcher(task_queue=task_queue) dispatcher._run_agent_for_task = mock_run_agent await dispatcher._poll_once() mock_run_agent.assert_called_once() pending = await task_queue.get_pending() assert len(pending) == 0 @pytest.mark.asyncio async def test_dispatcher_skips_when_empty(task_queue): """큐가 비어있으면 아무 작업도 하지 않는다.""" mock_run_agent = AsyncMock() dispatcher = Dispatcher(task_queue=task_queue) dispatcher._run_agent_for_task = mock_run_agent await dispatcher._poll_once() mock_run_agent.assert_not_called() @pytest.mark.asyncio async def test_dispatcher_handles_failure(task_queue): """에이전트 실행 실패 시 작업을 failed로 표시한다.""" await task_queue.enqueue( "thread-1", "gitea", { "issue_number": 42, "repo_owner": "quant", "repo_name": "galaxis-po", "message": "Fix", }, ) mock_run_agent = AsyncMock(side_effect=Exception("Agent crashed")) dispatcher = Dispatcher(task_queue=task_queue) dispatcher._run_agent_for_task = mock_run_agent await dispatcher._poll_once() # 실패 후 다음 작업 dequeue 가능해야 함 await task_queue.enqueue("thread-2", "gitea", {"message": "Next"}) task = await task_queue.dequeue() assert task is not None