Files
EvoScientist-Multi/tests/conftest.py
T

63 lines
2.2 KiB
Python

"""Shared fixtures for EvoScientist tests."""
import asyncio
import pytest
def run_async(coro):
"""Run an async coroutine safely, cancelling pending tasks before closing.
This prevents 'Event loop is closed' errors from asyncio.Queue cleanup
when tasks are still waiting on Queue.get() at teardown time.
"""
loop = asyncio.new_event_loop()
try:
return loop.run_until_complete(coro)
finally:
# Cancel all pending tasks so Queue getters don't raise on close
pending = asyncio.all_tasks(loop)
for task in pending:
task.cancel()
if pending:
loop.run_until_complete(asyncio.gather(*pending, return_exceptions=True))
loop.run_until_complete(loop.shutdown_asyncgens())
loop.close()
@pytest.fixture
def sample_tool_call():
"""A minimal tool call dict."""
return {"id": "tc_001", "name": "execute", "args": {"command": "ls -la"}}
@pytest.fixture
def sample_tool_result():
"""A minimal tool result dict."""
return {"name": "execute", "content": "[OK] file1.py file2.py", "success": True}
@pytest.fixture
def sample_events():
"""A sequence of stream event dicts covering common types."""
return [
{"type": "thinking", "content": "Let me think..."},
{"type": "text", "content": "Here is the answer."},
{"type": "tool_call", "id": "tc_001", "name": "execute", "args": {"command": "ls"}},
{"type": "tool_result", "name": "execute", "content": "[OK] done", "success": True},
{"type": "subagent_start", "name": "research-agent", "description": "Find papers"},
{"type": "subagent_tool_call", "subagent": "research-agent", "name": "tavily_search", "args": {"query": "test"}, "id": "tc_sa_001"},
{"type": "subagent_tool_result", "subagent": "research-agent", "name": "tavily_search", "content": "Results...", "success": True},
{"type": "subagent_end", "name": "research-agent"},
{"type": "done", "response": "Here is the answer."},
]
@pytest.fixture
def tmp_workspace(tmp_path):
"""Provide a temporary workspace directory path."""
ws = tmp_path / "workspace"
ws.mkdir()
return str(ws)