Share one event loop per test module to stop Windows socketpair churn (#3070)

This commit is contained in:
Max 2026-07-07 13:19:04 +01:00 • committed by GitHub
commit 867bba6263
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,5 +1,5 @@
import os
from collections.abc import Iterator
from collections.abc import AsyncIterator, Iterator
import pytest
@ -18,11 +18,35 @@ from logfire.testing import CaptureLogfire # noqa: E402
import mcp.shared._otel # noqa: E402
@pytest.fixture
def anyio_backend():
@pytest.fixture(scope="session")
def anyio_backend() -> str:
return "asyncio"
@pytest.fixture(scope="module", autouse=True)
async def _module_runner_lease(anyio_backend: str) -> AsyncIterator[None]:
"""Share one event loop across each module's tests instead of one per test.
anyio's pytest plugin tears its runner down whenever the last lease is
released, so with only function-scoped async fixtures every async test
creates and destroys its own event loop. On Windows each loop's self-pipe
is an emulated loopback-TCP socketpair, and churning thousands of those per
run can transiently exhaust kernel socket buffers — surfacing in CI as
`OSError: [WinError 10055]` raised from `asyncio.new_event_loop()` before
an arbitrary test's body even starts. Holding a module-scoped lease caps
the churn at one loop per module per xdist worker.
Modules that parametrize `anyio_backend` or call `trio.run(...)` directly
must shadow this fixture with a sync no-op: a module-scoped lease cannot
depend on the function-scoped parameter (pytest raises ScopeMismatch at
setup), and the lease's live asyncio loop lingers over direct trio runs,
whose signal handling collides with the loop's wakeup fd on Windows. The
lease also makes sniffio report asyncio to the module's sync tests, so a
sync test must not call `anyio.run()` itself.
"""
yield
@pytest.fixture(name="capfire")
def _capfire_isolated(capfire: CaptureLogfire) -> Iterator[CaptureLogfire]:
"""Override of logfire's `capfire` that scopes the MCP tracer to the test.