88 lines
2.3 KiB
Python
88 lines
2.3 KiB
Python
|
|
"""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
|