Fix asyncpg cross-event-loop errors in the integration test suite
CI / lint (push) Canceled after 0s
CI / typecheck (push) Canceled after 0s
CI / unit-tests (push) Canceled after 0s
CI / integration-tests (push) Canceled after 0s
CI / container-build (push) Canceled after 0s
CI / dependency-audit (push) Canceled after 0s

tests/conftest.py's `engine` fixture is session-scoped (one asyncpg
engine/schema for the whole run, for speed), but pytest-asyncio's
default is a fresh event loop per test function. asyncpg connections
are bound to the event loop that created them, so every test after the
first failed with "cannot perform operation: another operation is in
progress" or "attached to a different loop" the moment it touched the
database. Pinning both the fixture and test loop scope to "session"
in pyproject.toml keeps everything on one loop, matching the
session-scoped engine.

Found by actually running the integration suite for the first time,
against real PostgreSQL + Redis on a devbox.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
NixReaper
2026-09-04 19:23:18 -05:00
co-authored by Claude Sonnet 5
parent 5b38226818
commit dd6ecce78d
+9
View File
@@ -72,4 +72,13 @@ exclude = ["migrations", "tests"]
[tool.pytest.ini_options] [tool.pytest.ini_options]
asyncio_mode = "auto" asyncio_mode = "auto"
# The integration test suite shares one session-scoped asyncpg engine
# (tests/conftest.py:engine) across every test, for speed — schema is
# created once instead of per test. asyncpg connections are bound to the
# event loop they were created in, so every fixture/test must run on that
# same loop; pytest-asyncio's default is a fresh loop per test, which
# breaks that assumption ("another operation is in progress" / "attached
# to a different loop"). Pinning both to "session" fixes it.
asyncio_default_fixture_loop_scope = "session"
asyncio_default_test_loop_scope = "session"
testpaths = ["tests"] testpaths = ["tests"]