Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,15 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Set up test environment variables
run: |
echo "POSTGRES_TEST_DSN=postgresql+asyncpg://a2a:a2a_password@localhost:5432/a2a_test" >> $GITHUB_ENV
echo "MYSQL_TEST_DSN=mysql+aiomysql://a2a:a2a_password@localhost:3306/a2a_test" >> $GITHUB_ENV

- name: Install uv
- name: Install uv for Python ${{ matrix.python-version }}
uses: astral-sh/setup-uv@v6
with:
python-version: ${{ matrix.python-version }}
- name: Add uv to PATH
run: |
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
Expand Down
4 changes: 2 additions & 2 deletions src/a2a/server/request_handlers/default_request_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@
if task.status.state in TERMINAL_TASK_STATES:
raise ServerError(
error=InvalidParamsError(
message=f'Task {task.id} is in terminal state: {task.status.state}'
message=f'Task {task.id} is in terminal state: {task.status.state.value}'
)
)

Expand Down Expand Up @@ -437,22 +437,22 @@
if task.status.state in TERMINAL_TASK_STATES:
raise ServerError(
error=InvalidParamsError(
message=f'Task {task.id} is in terminal state: {task.status.state}'
message=f'Task {task.id} is in terminal state: {task.status.state.value}'
)
)

task_manager = TaskManager(
task_id=task.id,
context_id=task.context_id,
task_store=self.task_store,
initial_message=None,
)

result_aggregator = ResultAggregator(task_manager)

queue = await self._queue_manager.tap(task.id)
if not queue:
raise ServerError(error=TaskNotFoundError())

Check notice on line 455 in src/a2a/server/request_handlers/default_request_handler.py

View workflow job for this annotation

GitHub Actions / Lint Code Base

Copy/pasted code

see src/a2a/server/request_handlers/default_request_handler.py (125-137)

consumer = EventConsumer(queue)
async for event in result_aggregator.consume_and_emit(consumer):
Expand Down
2 changes: 1 addition & 1 deletion tests/server/apps/jsonrpc/test_jsonrpc_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def test_jsonrpc_app_build_method_abstract_raises_typeerror(
# This will fail at definition time if an abstract method is not implemented
with pytest.raises(
TypeError,
match="Can't instantiate abstract class IncompleteJSONRPCApp with abstract method build",
match=".*abstract class IncompleteJSONRPCApp .* abstract method '?build'?",
):

class IncompleteJSONRPCApp(JSONRPCApplication):
Expand Down
18 changes: 12 additions & 6 deletions tests/server/events/test_event_queue.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import sys

from typing import Any
from unittest.mock import (
Expand Down Expand Up @@ -195,15 +196,22 @@ async def test_enqueue_event_when_closed(event_queue: EventQueue) -> None:
await child_queue.dequeue_event(no_wait=True)


@pytest.fixture
def expected_queue_closed_exception():
if sys.version_info < (3, 13):
return asyncio.QueueEmpty
return asyncio.QueueShutDown


@pytest.mark.asyncio
async def test_dequeue_event_closed_and_empty_no_wait(
event_queue: EventQueue,
event_queue: EventQueue, expected_queue_closed_exception
) -> None:
"""Test dequeue_event raises QueueEmpty when closed, empty, and no_wait=True."""
await event_queue.close()
assert event_queue.is_closed()
# Ensure queue is actually empty (e.g. by trying a non-blocking get on internal queue)
with pytest.raises(asyncio.QueueEmpty):
with pytest.raises(expected_queue_closed_exception):
event_queue.queue.get_nowait()

with pytest.raises(asyncio.QueueEmpty, match='Queue is closed.'):
Expand All @@ -212,14 +220,12 @@ async def test_dequeue_event_closed_and_empty_no_wait(

@pytest.mark.asyncio
async def test_dequeue_event_closed_and_empty_waits_then_raises(
event_queue: EventQueue,
event_queue: EventQueue, expected_queue_closed_exception
) -> None:
"""Test dequeue_event raises QueueEmpty eventually when closed, empty, and no_wait=False."""
await event_queue.close()
assert event_queue.is_closed()
with pytest.raises(
asyncio.QueueEmpty
): # Should still raise QueueEmpty as per current implementation
with pytest.raises(expected_queue_closed_exception):
event_queue.queue.get_nowait() # verify internal queue is empty

# This test is tricky because await event_queue.dequeue_event() would hang if not for the close check.
Expand Down
Loading