Get baseline 100% clean coverage (#1553)
This commit is contained in:
parent
da4fce2195
commit
89e9c43acf
12 changed files with 1032 additions and 1084 deletions
|
|
@ -15,16 +15,16 @@ class MockTokenStorage:
|
|||
self._tokens: OAuthToken | None = None
|
||||
self._client_info: OAuthClientInformationFull | None = None
|
||||
|
||||
async def get_tokens(self) -> OAuthToken | None:
|
||||
async def get_tokens(self) -> OAuthToken | None: # pragma: no cover
|
||||
return self._tokens
|
||||
|
||||
async def set_tokens(self, tokens: OAuthToken) -> None:
|
||||
async def set_tokens(self, tokens: OAuthToken) -> None: # pragma: no cover
|
||||
self._tokens = tokens
|
||||
|
||||
async def get_client_info(self) -> OAuthClientInformationFull | None:
|
||||
async def get_client_info(self) -> OAuthClientInformationFull | None: # pragma: no cover
|
||||
return self._client_info
|
||||
|
||||
async def set_client_info(self, client_info: OAuthClientInformationFull) -> None:
|
||||
async def set_client_info(self, client_info: OAuthClientInformationFull) -> None: # pragma: no cover
|
||||
self._client_info = client_info
|
||||
|
||||
|
||||
|
|
@ -45,11 +45,11 @@ def client_metadata():
|
|||
|
||||
@pytest.fixture
|
||||
def rfc7523_oauth_provider(client_metadata: OAuthClientMetadata, mock_storage: MockTokenStorage):
|
||||
async def redirect_handler(url: str) -> None:
|
||||
async def redirect_handler(url: str) -> None: # pragma: no cover
|
||||
"""Mock redirect handler."""
|
||||
pass
|
||||
|
||||
async def callback_handler() -> tuple[str, str | None]:
|
||||
async def callback_handler() -> tuple[str, str | None]: # pragma: no cover
|
||||
"""Mock callback handler."""
|
||||
return "test_auth_code", "test_state"
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class StreamSpyCollection:
|
|||
self.client.sent_messages.clear()
|
||||
self.server.sent_messages.clear()
|
||||
|
||||
def get_client_requests(self, method: str | None = None) -> list[JSONRPCRequest]:
|
||||
def get_client_requests(self, method: str | None = None) -> list[JSONRPCRequest]: # pragma: no cover
|
||||
"""Get client-sent requests, optionally filtered by method."""
|
||||
return [
|
||||
req.message.root
|
||||
|
|
@ -48,15 +48,15 @@ class StreamSpyCollection:
|
|||
if isinstance(req.message.root, JSONRPCRequest) and (method is None or req.message.root.method == method)
|
||||
]
|
||||
|
||||
def get_server_requests(self, method: str | None = None) -> list[JSONRPCRequest]:
|
||||
def get_server_requests(self, method: str | None = None) -> list[JSONRPCRequest]: # pragma: no cover
|
||||
"""Get server-sent requests, optionally filtered by method."""
|
||||
return [
|
||||
return [ # pragma: no cover
|
||||
req.message.root
|
||||
for req in self.server.sent_messages
|
||||
if isinstance(req.message.root, JSONRPCRequest) and (method is None or req.message.root.method == method)
|
||||
]
|
||||
|
||||
def get_client_notifications(self, method: str | None = None) -> list[JSONRPCNotification]:
|
||||
def get_client_notifications(self, method: str | None = None) -> list[JSONRPCNotification]: # pragma: no cover
|
||||
"""Get client-sent notifications, optionally filtered by method."""
|
||||
return [
|
||||
notif.message.root
|
||||
|
|
@ -65,7 +65,7 @@ class StreamSpyCollection:
|
|||
and (method is None or notif.message.root.method == method)
|
||||
]
|
||||
|
||||
def get_server_notifications(self, method: str | None = None) -> list[JSONRPCNotification]:
|
||||
def get_server_notifications(self, method: str | None = None) -> list[JSONRPCNotification]: # pragma: no cover
|
||||
"""Get server-sent notifications, optionally filtered by method."""
|
||||
return [
|
||||
notif.message.root
|
||||
|
|
|
|||
|
|
@ -22,13 +22,13 @@ class MockTokenStorage:
|
|||
self._client_info: OAuthClientInformationFull | None = None
|
||||
|
||||
async def get_tokens(self) -> OAuthToken | None:
|
||||
return self._tokens
|
||||
return self._tokens # pragma: no cover
|
||||
|
||||
async def set_tokens(self, tokens: OAuthToken) -> None:
|
||||
self._tokens = tokens
|
||||
|
||||
async def get_client_info(self) -> OAuthClientInformationFull | None:
|
||||
return self._client_info
|
||||
return self._client_info # pragma: no cover
|
||||
|
||||
async def set_client_info(self, client_info: OAuthClientInformationFull) -> None:
|
||||
self._client_info = client_info
|
||||
|
|
@ -64,11 +64,11 @@ def valid_tokens():
|
|||
def oauth_provider(client_metadata: OAuthClientMetadata, mock_storage: MockTokenStorage):
|
||||
async def redirect_handler(url: str) -> None:
|
||||
"""Mock redirect handler."""
|
||||
pass
|
||||
pass # pragma: no cover
|
||||
|
||||
async def callback_handler() -> tuple[str, str | None]:
|
||||
"""Mock callback handler."""
|
||||
return "test_auth_code", "test_state"
|
||||
return "test_auth_code", "test_state" # pragma: no cover
|
||||
|
||||
return OAuthClientProvider(
|
||||
server_url="https://api.example.com/v1/mcp",
|
||||
|
|
@ -247,10 +247,10 @@ class TestOAuthFlow:
|
|||
"""Test protected resource metadata discovery URL building with fallback."""
|
||||
|
||||
async def redirect_handler(url: str) -> None:
|
||||
pass
|
||||
pass # pragma: no cover
|
||||
|
||||
async def callback_handler() -> tuple[str, str | None]:
|
||||
return "test_auth_code", "test_state"
|
||||
return "test_auth_code", "test_state" # pragma: no cover
|
||||
|
||||
provider = OAuthClientProvider(
|
||||
server_url="https://api.example.com",
|
||||
|
|
@ -663,7 +663,7 @@ class TestRegistrationResponse:
|
|||
|
||||
@property
|
||||
def text(self):
|
||||
if not self._aread_called:
|
||||
if not self._aread_called: # pragma: no cover
|
||||
raise RuntimeError("Response.text accessed before response.aread()")
|
||||
return self._text
|
||||
|
||||
|
|
@ -846,10 +846,10 @@ class TestAuthFlow:
|
|||
# In the buggy version, this would yield the request AGAIN unconditionally
|
||||
# In the fixed version, this should end the generator
|
||||
try:
|
||||
await auth_flow.asend(response) # extra request
|
||||
request_yields += 1
|
||||
# If we reach here, the bug is present
|
||||
pytest.fail(
|
||||
await auth_flow.asend(response) # extra request # pragma: no cover
|
||||
request_yields += 1 # pragma: no cover
|
||||
# If we reach here, the bug is present # pragma: no cover
|
||||
pytest.fail( # pragma: no cover
|
||||
f"Unnecessary retry detected! Request was yielded {request_yields} times. "
|
||||
f"This indicates the retry logic bug that caused 2x performance degradation. "
|
||||
f"The request should only be yielded once for successful responses."
|
||||
|
|
@ -949,7 +949,7 @@ class TestAuthFlow:
|
|||
success_response = httpx.Response(200, request=final_request)
|
||||
try:
|
||||
await auth_flow.asend(success_response)
|
||||
pytest.fail("Should have stopped after successful response")
|
||||
pytest.fail("Should have stopped after successful response") # pragma: no cover
|
||||
except StopAsyncIteration:
|
||||
pass # Expected
|
||||
|
||||
|
|
@ -1043,10 +1043,10 @@ class TestSEP985Discovery:
|
|||
"""Test that client falls back to path-based well-known URI when WWW-Authenticate is absent."""
|
||||
|
||||
async def redirect_handler(url: str) -> None:
|
||||
pass
|
||||
pass # pragma: no cover
|
||||
|
||||
async def callback_handler() -> tuple[str, str | None]:
|
||||
return "test_auth_code", "test_state"
|
||||
return "test_auth_code", "test_state" # pragma: no cover
|
||||
|
||||
provider = OAuthClientProvider(
|
||||
server_url="https://api.example.com/v1/mcp",
|
||||
|
|
@ -1076,10 +1076,10 @@ class TestSEP985Discovery:
|
|||
"""Test that client falls back to root-based URI when path-based returns 404."""
|
||||
|
||||
async def redirect_handler(url: str) -> None:
|
||||
pass
|
||||
pass # pragma: no cover
|
||||
|
||||
async def callback_handler() -> tuple[str, str | None]:
|
||||
return "test_auth_code", "test_state"
|
||||
return "test_auth_code", "test_state" # pragma: no cover
|
||||
|
||||
provider = OAuthClientProvider(
|
||||
server_url="https://api.example.com/v1/mcp",
|
||||
|
|
@ -1177,10 +1177,10 @@ class TestSEP985Discovery:
|
|||
"""Test that WWW-Authenticate header resource_metadata takes priority over well-known URIs."""
|
||||
|
||||
async def redirect_handler(url: str) -> None:
|
||||
pass
|
||||
pass # pragma: no cover
|
||||
|
||||
async def callback_handler() -> tuple[str, str | None]:
|
||||
return "test_auth_code", "test_state"
|
||||
return "test_auth_code", "test_state" # pragma: no cover
|
||||
|
||||
provider = OAuthClientProvider(
|
||||
server_url="https://api.example.com/v1/mcp",
|
||||
|
|
@ -1269,10 +1269,10 @@ class TestWWWAuthenticate:
|
|||
"""Test extraction of various fields from valid WWW-Authenticate headers."""
|
||||
|
||||
async def redirect_handler(url: str) -> None:
|
||||
pass
|
||||
pass # pragma: no cover
|
||||
|
||||
async def callback_handler() -> tuple[str, str | None]:
|
||||
return "test_auth_code", "test_state"
|
||||
return "test_auth_code", "test_state" # pragma: no cover
|
||||
|
||||
provider = OAuthClientProvider(
|
||||
server_url="https://api.example.com/v1/mcp",
|
||||
|
|
@ -1317,10 +1317,10 @@ class TestWWWAuthenticate:
|
|||
"""Test extraction returns None for invalid cases."""
|
||||
|
||||
async def redirect_handler(url: str) -> None:
|
||||
pass
|
||||
pass # pragma: no cover
|
||||
|
||||
async def callback_handler() -> tuple[str, str | None]:
|
||||
return "test_auth_code", "test_state"
|
||||
return "test_auth_code", "test_state" # pragma: no cover
|
||||
|
||||
provider = OAuthClientProvider(
|
||||
server_url="https://api.example.com/v1/mcp",
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ def test_command_execution(mock_config_path: Path):
|
|||
|
||||
test_args = [command] + args + ["--help"]
|
||||
|
||||
result = subprocess.run(test_args, capture_output=True, text=True, timeout=5, check=False)
|
||||
result = subprocess.run(test_args, capture_output=True, text=True, timeout=20, check=False)
|
||||
|
||||
assert result.returncode == 0
|
||||
assert "usage" in result.stdout.lower()
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ UNICODE_TEST_STRINGS = {
|
|||
}
|
||||
|
||||
|
||||
def run_unicode_server(port: int) -> None:
|
||||
def run_unicode_server(port: int) -> None: # pragma: no cover
|
||||
"""Run the Unicode test server in a separate process."""
|
||||
# Import inside the function since this runs in a separate process
|
||||
from collections.abc import AsyncGenerator
|
||||
|
|
@ -167,7 +167,7 @@ def running_unicode_server(unicode_server_port: int) -> Generator[str, None, Non
|
|||
# Clean up - try graceful termination first
|
||||
proc.terminate()
|
||||
proc.join(timeout=2)
|
||||
if proc.is_alive():
|
||||
if proc.is_alive(): # pragma: no cover
|
||||
proc.kill()
|
||||
proc.join(timeout=1)
|
||||
|
||||
|
|
|
|||
|
|
@ -19,27 +19,27 @@ async def full_featured_server():
|
|||
server = FastMCP("test")
|
||||
|
||||
@server.tool(name="test_tool_1")
|
||||
async def test_tool_1() -> str:
|
||||
async def test_tool_1() -> str: # pragma: no cover
|
||||
"""First test tool"""
|
||||
return "Result 1"
|
||||
|
||||
@server.tool(name="test_tool_2")
|
||||
async def test_tool_2() -> str:
|
||||
async def test_tool_2() -> str: # pragma: no cover
|
||||
"""Second test tool"""
|
||||
return "Result 2"
|
||||
|
||||
@server.resource("resource://test/data")
|
||||
async def test_resource() -> str:
|
||||
async def test_resource() -> str: # pragma: no cover
|
||||
"""Test resource"""
|
||||
return "Test data"
|
||||
|
||||
@server.prompt()
|
||||
async def test_prompt(name: str) -> str:
|
||||
async def test_prompt(name: str) -> str: # pragma: no cover
|
||||
"""Test prompt"""
|
||||
return f"Hello, {name}!"
|
||||
|
||||
@server.resource("resource://test/{name}")
|
||||
async def test_template(name: str) -> str:
|
||||
async def test_template(name: str) -> str: # pragma: no cover
|
||||
"""Test resource template"""
|
||||
return f"Data for {name}"
|
||||
|
||||
|
|
@ -209,7 +209,7 @@ async def test_list_tools_with_strict_server_validation():
|
|||
server = Server("strict_server")
|
||||
|
||||
@server.list_tools()
|
||||
async def handle_list_tools(request: ListToolsRequest) -> ListToolsResult:
|
||||
async def handle_list_tools(request: ListToolsRequest) -> ListToolsResult: # pragma: no cover
|
||||
"""Strict handler that validates params field exists"""
|
||||
|
||||
# Simulate strict server validation
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ async def test_logging_callback():
|
|||
async def message_handler(
|
||||
message: RequestResponder[types.ServerRequest, types.ClientResult] | types.ServerNotification | Exception,
|
||||
) -> None:
|
||||
if isinstance(message, Exception):
|
||||
if isinstance(message, Exception): # pragma: no cover
|
||||
raise message
|
||||
|
||||
async with create_session(
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ from mcp.types import ClientNotification, RootsListChangedNotification
|
|||
from tests.test_helpers import wait_for_server
|
||||
|
||||
|
||||
def create_non_sdk_server_app() -> Starlette:
|
||||
def create_non_sdk_server_app() -> Starlette: # pragma: no cover
|
||||
"""Create a minimal server that doesn't follow SDK conventions."""
|
||||
|
||||
async def handle_mcp_request(request: Request) -> Response:
|
||||
|
|
@ -67,7 +67,7 @@ def create_non_sdk_server_app() -> Starlette:
|
|||
return app
|
||||
|
||||
|
||||
def run_non_sdk_server(port: int) -> None:
|
||||
def run_non_sdk_server(port: int) -> None: # pragma: no cover
|
||||
"""Run the non-SDK server in a separate process."""
|
||||
app = create_non_sdk_server_app()
|
||||
config = uvicorn.Config(
|
||||
|
|
@ -95,9 +95,9 @@ def non_sdk_server(non_sdk_server_port: int) -> Generator[None, None, None]:
|
|||
proc.start()
|
||||
|
||||
# Wait for server to be ready
|
||||
try:
|
||||
try: # pragma: no cover
|
||||
wait_for_server(non_sdk_server_port, timeout=10.0)
|
||||
except TimeoutError:
|
||||
except TimeoutError: # pragma: no cover
|
||||
proc.kill()
|
||||
proc.join(timeout=2)
|
||||
pytest.fail("Server failed to start within 10 seconds")
|
||||
|
|
@ -120,7 +120,7 @@ async def test_non_compliant_notification_response(non_sdk_server: None, non_sdk
|
|||
server_url = f"http://127.0.0.1:{non_sdk_server_port}/mcp"
|
||||
returned_exception = None
|
||||
|
||||
async def message_handler(
|
||||
async def message_handler( # pragma: no cover
|
||||
message: RequestResponder[types.ServerRequest, types.ClientResult] | types.ServerNotification | Exception,
|
||||
):
|
||||
nonlocal returned_exception
|
||||
|
|
@ -141,5 +141,5 @@ async def test_non_compliant_notification_response(non_sdk_server: None, non_sdk
|
|||
ClientNotification(RootsListChangedNotification(method="notifications/roots/list_changed"))
|
||||
)
|
||||
|
||||
if returned_exception:
|
||||
if returned_exception: # pragma: no cover
|
||||
pytest.fail(f"Server encountered an exception: {returned_exception}")
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@ async def test_send_request_stream_cleanup():
|
|||
|
||||
# Create a mock session with the minimal required functionality
|
||||
class TestSession(BaseSession[ClientRequest, ClientNotification, ClientResult, Any, Any]):
|
||||
async def _send_response(self, request_id: RequestId, response: SendResultT | ErrorData) -> None:
|
||||
async def _send_response(
|
||||
self, request_id: RequestId, response: SendResultT | ErrorData
|
||||
) -> None: # pragma: no cover
|
||||
pass
|
||||
|
||||
# Create streams
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ async def test_client_session_initialize():
|
|||
)
|
||||
|
||||
# Create a message handler to catch exceptions
|
||||
async def message_handler(
|
||||
async def message_handler( # pragma: no cover
|
||||
message: RequestResponder[types.ServerRequest, types.ClientResult] | types.ServerNotification | Exception,
|
||||
) -> None:
|
||||
if isinstance(message, Exception):
|
||||
|
|
@ -426,7 +426,7 @@ async def test_client_capabilities_with_custom_callbacks():
|
|||
|
||||
received_capabilities = None
|
||||
|
||||
async def custom_sampling_callback(
|
||||
async def custom_sampling_callback( # pragma: no cover
|
||||
context: RequestContext["ClientSession", Any],
|
||||
params: types.CreateMessageRequestParams,
|
||||
) -> types.CreateMessageResult | types.ErrorData:
|
||||
|
|
@ -436,7 +436,7 @@ async def test_client_capabilities_with_custom_callbacks():
|
|||
model="test-model",
|
||||
)
|
||||
|
||||
async def custom_list_roots_callback(
|
||||
async def custom_list_roots_callback( # pragma: no cover
|
||||
context: RequestContext["ClientSession", Any],
|
||||
) -> types.ListRootsResult | types.ErrorData:
|
||||
return types.ListRootsResult(roots=[])
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ class TestClientSessionGroup:
|
|||
mock_session = mock.AsyncMock()
|
||||
|
||||
# --- Prepare Session Group ---
|
||||
def hook(name: str, server_info: types.Implementation) -> str:
|
||||
def hook(name: str, server_info: types.Implementation) -> str: # pragma: no cover
|
||||
return f"{(server_info.name)}-{name}"
|
||||
|
||||
mcp_session_group = ClientSessionGroup(component_name_hook=hook)
|
||||
|
|
@ -344,7 +344,7 @@ class TestClientSessionGroup:
|
|||
timeout=server_params_instance.timeout,
|
||||
sse_read_timeout=server_params_instance.sse_read_timeout,
|
||||
)
|
||||
elif client_type_name == "streamablehttp":
|
||||
elif client_type_name == "streamablehttp": # pragma: no branch
|
||||
assert isinstance(server_params_instance, StreamableHttpParameters)
|
||||
mock_specific_client_func.assert_called_once_with(
|
||||
url=server_params_instance.url,
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ async def test_stdio_client():
|
|||
read_messages: list[JSONRPCMessage] = []
|
||||
async with read_stream:
|
||||
async for message in read_stream:
|
||||
if isinstance(message, Exception):
|
||||
if isinstance(message, Exception): # pragma: no cover
|
||||
raise message
|
||||
|
||||
read_messages.append(message.message)
|
||||
|
|
@ -93,7 +93,7 @@ async def test_stdio_client_nonexistent_command():
|
|||
# Should raise an error when trying to start the process
|
||||
with pytest.raises(OSError) as exc_info:
|
||||
async with stdio_client(server_params) as (_, _):
|
||||
pass
|
||||
pass # pragma: no cover
|
||||
|
||||
# The error should indicate the command was not found (ENOENT: No such file or directory)
|
||||
assert exc_info.value.errno == errno.ENOENT
|
||||
|
|
@ -144,7 +144,7 @@ async def test_stdio_client_universal_cleanup():
|
|||
)
|
||||
|
||||
# Check if we timed out
|
||||
if cancel_scope.cancelled_caught:
|
||||
if cancel_scope.cancelled_caught: # pragma: no cover
|
||||
pytest.fail(
|
||||
"stdio_client cleanup timed out after 8.0 seconds. "
|
||||
"This indicates the cleanup mechanism is hanging and needs fixing."
|
||||
|
|
@ -153,7 +153,7 @@ async def test_stdio_client_universal_cleanup():
|
|||
|
||||
@pytest.mark.anyio
|
||||
@pytest.mark.skipif(sys.platform == "win32", reason="Windows signal handling is different")
|
||||
async def test_stdio_client_sigint_only_process():
|
||||
async def test_stdio_client_sigint_only_process(): # pragma: no cover
|
||||
"""
|
||||
Test cleanup with a process that ignores SIGTERM but responds to SIGINT.
|
||||
"""
|
||||
|
|
@ -195,7 +195,7 @@ async def test_stdio_client_sigint_only_process():
|
|||
# Exit context triggers cleanup - this should not hang
|
||||
pass
|
||||
|
||||
if cancel_scope.cancelled_caught:
|
||||
if cancel_scope.cancelled_caught: # pragma: no cover
|
||||
raise TimeoutError("Test timed out")
|
||||
|
||||
end_time = time.time()
|
||||
|
|
@ -208,7 +208,7 @@ async def test_stdio_client_sigint_only_process():
|
|||
f"Expected < {SIGTERM_IGNORING_PROCESS_TIMEOUT} seconds. "
|
||||
"This suggests the cleanup needs SIGINT/SIGKILL fallback."
|
||||
)
|
||||
except (TimeoutError, Exception) as e:
|
||||
except (TimeoutError, Exception) as e: # pragma: no cover
|
||||
if isinstance(e, TimeoutError) or "timed out" in str(e):
|
||||
pytest.fail(
|
||||
f"stdio_client cleanup timed out after {SIGTERM_IGNORING_PROCESS_TIMEOUT} seconds "
|
||||
|
|
@ -303,7 +303,7 @@ class TestChildProcessCleanup:
|
|||
assert os.path.exists(parent_marker), "Parent process didn't start"
|
||||
|
||||
# Verify child is writing
|
||||
if os.path.exists(marker_file):
|
||||
if os.path.exists(marker_file): # pragma: no branch
|
||||
initial_size = os.path.getsize(marker_file)
|
||||
await anyio.sleep(0.3)
|
||||
size_after_wait = os.path.getsize(marker_file)
|
||||
|
|
@ -318,7 +318,7 @@ class TestChildProcessCleanup:
|
|||
|
||||
# Verify processes stopped
|
||||
await anyio.sleep(0.5)
|
||||
if os.path.exists(marker_file):
|
||||
if os.path.exists(marker_file): # pragma: no branch
|
||||
size_after_cleanup = os.path.getsize(marker_file)
|
||||
await anyio.sleep(0.5)
|
||||
final_size = os.path.getsize(marker_file)
|
||||
|
|
@ -335,7 +335,7 @@ class TestChildProcessCleanup:
|
|||
for f in [marker_file, parent_marker]:
|
||||
try:
|
||||
os.unlink(f)
|
||||
except OSError:
|
||||
except OSError: # pragma: no cover
|
||||
pass
|
||||
|
||||
@pytest.mark.anyio
|
||||
|
|
@ -406,7 +406,7 @@ class TestChildProcessCleanup:
|
|||
|
||||
# Verify all are writing
|
||||
for file_path, name in [(parent_file, "parent"), (child_file, "child"), (grandchild_file, "grandchild")]:
|
||||
if os.path.exists(file_path):
|
||||
if os.path.exists(file_path): # pragma: no branch
|
||||
initial_size = os.path.getsize(file_path)
|
||||
await anyio.sleep(0.3)
|
||||
new_size = os.path.getsize(file_path)
|
||||
|
|
@ -420,7 +420,7 @@ class TestChildProcessCleanup:
|
|||
# Verify all stopped
|
||||
await anyio.sleep(0.5)
|
||||
for file_path, name in [(parent_file, "parent"), (child_file, "child"), (grandchild_file, "grandchild")]:
|
||||
if os.path.exists(file_path):
|
||||
if os.path.exists(file_path): # pragma: no branch
|
||||
size1 = os.path.getsize(file_path)
|
||||
await anyio.sleep(0.3)
|
||||
size2 = os.path.getsize(file_path)
|
||||
|
|
@ -433,7 +433,7 @@ class TestChildProcessCleanup:
|
|||
for f in [parent_file, child_file, grandchild_file]:
|
||||
try:
|
||||
os.unlink(f)
|
||||
except OSError:
|
||||
except OSError: # pragma: no cover
|
||||
pass
|
||||
|
||||
@pytest.mark.anyio
|
||||
|
|
@ -487,7 +487,7 @@ class TestChildProcessCleanup:
|
|||
await anyio.sleep(0.5)
|
||||
|
||||
# Verify child is writing
|
||||
if os.path.exists(marker_file):
|
||||
if os.path.exists(marker_file): # pragma: no cover
|
||||
size1 = os.path.getsize(marker_file)
|
||||
await anyio.sleep(0.3)
|
||||
size2 = os.path.getsize(marker_file)
|
||||
|
|
@ -500,7 +500,7 @@ class TestChildProcessCleanup:
|
|||
|
||||
# Verify child stopped
|
||||
await anyio.sleep(0.5)
|
||||
if os.path.exists(marker_file):
|
||||
if os.path.exists(marker_file): # pragma: no branch
|
||||
size3 = os.path.getsize(marker_file)
|
||||
await anyio.sleep(0.3)
|
||||
size4 = os.path.getsize(marker_file)
|
||||
|
|
@ -512,7 +512,7 @@ class TestChildProcessCleanup:
|
|||
# Clean up marker file
|
||||
try:
|
||||
os.unlink(marker_file)
|
||||
except OSError:
|
||||
except OSError: # pragma: no cover
|
||||
pass
|
||||
|
||||
|
||||
|
|
@ -560,7 +560,7 @@ async def test_stdio_client_graceful_stdin_exit():
|
|||
pytest.fail(
|
||||
"stdio_client cleanup timed out after 5.0 seconds. "
|
||||
"Process should have exited gracefully when stdin was closed."
|
||||
)
|
||||
) # pragma: no cover
|
||||
|
||||
end_time = time.time()
|
||||
elapsed = end_time - start_time
|
||||
|
|
@ -619,7 +619,7 @@ async def test_stdio_client_stdin_close_ignored():
|
|||
pytest.fail(
|
||||
"stdio_client cleanup timed out after 7.0 seconds. "
|
||||
"Process should have been terminated via SIGTERM escalation."
|
||||
)
|
||||
) # pragma: no cover
|
||||
|
||||
end_time = time.time()
|
||||
elapsed = end_time - start_time
|
||||
|
|
|
|||
Loading…
Reference in a new issue