Files
wehub-resource-sync 60e0ffc959
Upgrade checks / Notify on failure (push) Has been cancelled
Upgrade checks / Close issue on success (push) Has been cancelled
Schema Crash Test / Real-world schema crash test (232K schemas) (push) Has been cancelled
Run static analysis / static_analysis (push) Has been cancelled
Tests / Tests: Python 3.10 on ubuntu-latest (push) Has been cancelled
Tests / Tests: Python 3.13 on ubuntu-latest (push) Has been cancelled
Tests / Tests: Python 3.10 on windows-latest (push) Has been cancelled
Tests / Tests with lowest-direct dependencies (push) Has been cancelled
Tests / MCP conformance tests (push) Has been cancelled
Tests / Integration tests (push) Has been cancelled
Tests / Package install smoke (push) Has been cancelled
Upgrade checks / Static analysis (push) Has been cancelled
Upgrade checks / Tests: Python 3.10 on ubuntu-latest (push) Has been cancelled
Upgrade checks / Tests: Python 3.13 on ubuntu-latest (push) Has been cancelled
Upgrade checks / Tests: Python 3.10 on windows-latest (push) Has been cancelled
Upgrade checks / Integration tests (push) Has been cancelled
Update MCPServerConfig Schema / update-config-schema (push) Has been cancelled
Update SDK Documentation / update-sdk-docs (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:39:59 +08:00

82 lines
2.5 KiB
Python

"""
Tests for SEP-1686 protocol-level task handling.
Generic protocol tests that use tools as test fixtures.
Tests metadata, notifications, and error handling at the protocol level.
"""
import pytest
from fastmcp import FastMCP
from fastmcp.client import Client
@pytest.fixture
async def task_enabled_server():
"""Create a FastMCP server with task-enabled tools."""
mcp = FastMCP("task-test-server")
@mcp.tool(task=True)
async def simple_tool(message: str) -> str:
"""A simple tool for testing."""
return f"Processed: {message}"
@mcp.tool(task=True)
async def failing_tool() -> str:
"""A tool that always fails."""
raise ValueError("This tool always fails")
return mcp
async def test_task_metadata_includes_task_id_and_ttl(task_enabled_server):
"""Task metadata properly includes server-generated taskId and ttl."""
async with Client(task_enabled_server) as client:
# Submit with specific ttl (server generates task ID)
task = await client.call_tool(
"simple_tool",
{"message": "test"},
task=True,
ttl=30000,
)
assert task
assert not task.returned_immediately
# Server should have generated a task ID
assert task.task_id is not None
assert isinstance(task.task_id, str)
async def test_task_notification_sent_after_submission(task_enabled_server):
"""Server sends an initial task status notification after submission."""
@task_enabled_server.tool(task=True)
async def background_tool(message: str) -> str:
return f"Processed: {message}"
async with Client(task_enabled_server) as client:
task = await client.call_tool("background_tool", {"message": "test"}, task=True)
assert task
assert not task.returned_immediately
# Verify we can query the task
status = await task.status()
assert status.task_id == task.task_id
async def test_failed_task_stores_error(task_enabled_server):
"""Failed tasks store the error in results."""
@task_enabled_server.tool(task=True)
async def failing_task_tool() -> str:
raise ValueError("This tool always fails")
async with Client(task_enabled_server) as client:
task = await client.call_tool("failing_task_tool", task=True)
assert task
assert not task.returned_immediately
# Wait for task to fail
status = await task.wait(state="failed", timeout=2.0)
assert status.status == "failed"