import asyncio
import contextlib
import importlib.util
from pathlib import Path
from typing import Any
import pytest
MODULE_PATH = Path(__file__).resolve().parents[1] / "enhanced_dash_server.py"
class DummyServer:
def __init__(self, *_args, **_kwargs) -> None: # pragma: no cover - stub
pass
def list_tools(self) -> Any: # pragma: no cover - stub
def decorator(func: Any) -> Any:
return func
return decorator
def call_tool(self) -> Any: # pragma: no cover - stub
def decorator(func: Any) -> Any:
async def wrapper(*args: Any, **kwargs: Any) -> Any:
return await func(*args, **kwargs)
return wrapper
return decorator
async def run(self, *_args, **_kwargs) -> None: # pragma: no cover - stub
pass
@pytest.mark.asyncio
async def test_cancel_task_finishes(stub_modules) -> None:
"""_cancel_task should finish the provided task."""
stub_server = stub_modules["mcp.server"]
stub_server.Server = DummyServer # type: ignore[attr-defined]
spec = importlib.util.spec_from_file_location("enhanced_dash_server", MODULE_PATH)
assert spec and spec.loader
server_mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(server_mod)
_cancel_task = server_mod._cancel_task
nonlocal_flag = []
async def forever():
try:
while True:
await asyncio.sleep(0.1)
finally:
nonlocal_flag.append(True)
task = asyncio.create_task(forever())
await asyncio.sleep(0.1)
await _cancel_task(task)
assert task.done()
assert nonlocal_flag
@pytest.mark.asyncio
async def test_cancel_task_handles_keyboard_interrupt(stub_modules) -> None:
"""_cancel_task should swallow KeyboardInterrupt from a finished task."""
stub_server = stub_modules["mcp.server"]
stub_server.Server = DummyServer # type: ignore[attr-defined]
spec = importlib.util.spec_from_file_location("enhanced_dash_server", MODULE_PATH)
assert spec and spec.loader
server_mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(server_mod)
_cancel_task = server_mod._cancel_task
task: asyncio.Future[Any] = asyncio.Future()
task.set_exception(KeyboardInterrupt())
await _cancel_task(task)