Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
4 changes: 2 additions & 2 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ The pre-release phase focuses on:
### Quality & Testing
- [x] Core test suite (80%+ coverage)
- [x] Type hints on all public APIs
- [ ] Integration tests with real ORFS flows
- [x] Integration tests with real ORFS flows
- [ ] Performance benchmarking suite
- [ ] Load testing (50+ concurrent sessions)
- [ ] Memory leak detection
Expand Down Expand Up @@ -192,7 +192,7 @@ We welcome community involvement at every stage:

---

**Last Updated:** 2025-12-08
**Last Updated:** 2026-02-23
**Current Phase:** Phase 1 (Pre-Release → v0.5)

*This roadmap is a living document and will evolve based on community feedback and priorities.*
2 changes: 2 additions & 0 deletions src/openroad_mcp/core/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ async def create_session(
actual_buffer_size = buffer_size or self._default_buffer_size
session = InteractiveSession(session_id, buffer_size=actual_buffer_size)
await session.start(command, env, cwd)
await asyncio.sleep(settings.COMMAND_COMPLETION_DELAY * 1.5)
await session.output_buffer.drain_all()
Comment thread
luarss marked this conversation as resolved.

self._sessions[session_id] = session
self.logger.info(f"Created session {session_id}, total sessions: {len(self._sessions)}")
Expand Down
40 changes: 24 additions & 16 deletions tests/integration/conftest.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,44 @@
"""Pytest configuration for integration tests without mocks."""

import asyncio
import os
from collections.abc import AsyncGenerator
from contextlib import asynccontextmanager

import pytest
import pytest_asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client


@pytest.fixture(scope="session")
def event_loop():
"""Create an event loop for the test session."""
loop = asyncio.new_event_loop()
yield loop
loop.close()


@pytest_asyncio.fixture(scope="function")
async def mcp_client() -> AsyncGenerator[ClientSession]:
"""Fixture providing a MCP client session."""
server_params = StdioServerParameters(command="python", args=["-m", "openroad_mcp.main"], env=None)

@asynccontextmanager
async def _mcp_session(server_params: StdioServerParameters):
"""Shared async context manager for MCP client sessions with cancel-scope guard."""
try:
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
await asyncio.sleep(1.0)
yield session
except RuntimeError as e:
if "cancel scope" in str(e):
# Skip teardown exception (openroad-mcp handles their own teardown)
# anyio emits a RuntimeError on cancel-scope teardown when the MCP
# server subprocess exits
if "cancel scope" in str(e).lower():
pass
else:
raise
Comment thread
coderabbitai[bot] marked this conversation as resolved.


@pytest_asyncio.fixture(scope="function")
async def mcp_client() -> AsyncGenerator[ClientSession]:
"""Fixture providing a MCP client session."""
server_params = StdioServerParameters(
command="python",
args=["-m", "openroad_mcp.main"],
env={
**os.environ,
"OPENROAD_ENABLE_COMMAND_VALIDATION": "false",
},
)

async with _mcp_session(server_params) as session:
yield session
Loading
Loading