fix(ci): use NullPool to avoid asyncpg event loop teardown crash
NullPool creates/destroys connections on demand without maintaining a pool. No dispose() needed, so no event loop race during teardown. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -92,27 +92,29 @@ def setup_database():
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
# Module-level engines — created once, reused across all tests.
|
@pytest_asyncio.fixture
|
||||||
# Avoids per-test engine creation/disposal which triggers asyncpg
|
async def admin_engine():
|
||||||
# event loop issues during pytest-asyncio teardown.
|
"""Admin engine (superuser) -- bypasses RLS.
|
||||||
_admin_engine = create_async_engine(
|
|
||||||
TEST_DATABASE_URL, echo=False, pool_pre_ping=True, pool_size=5, max_overflow=5
|
Function-scoped: created fresh per-test on the test's event loop.
|
||||||
)
|
Not disposed explicitly — asyncpg's pool_pre_ping=False + NullPool
|
||||||
_app_engine = create_async_engine(
|
avoids the event loop teardown crash.
|
||||||
TEST_APP_USER_DATABASE_URL, echo=False, pool_pre_ping=True, pool_size=5, max_overflow=5
|
"""
|
||||||
)
|
from sqlalchemy.pool import NullPool
|
||||||
|
|
||||||
|
engine = create_async_engine(TEST_DATABASE_URL, echo=False, poolclass=NullPool)
|
||||||
|
yield engine
|
||||||
|
# Do NOT dispose — asyncpg teardown races with pytest-asyncio loop closure.
|
||||||
|
# NullPool creates/destroys connections on demand so nothing leaks.
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest_asyncio.fixture
|
||||||
def admin_engine():
|
async def app_engine():
|
||||||
"""Admin engine (superuser) -- bypasses RLS."""
|
|
||||||
return _admin_engine
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def app_engine():
|
|
||||||
"""App-user engine -- RLS enforced."""
|
"""App-user engine -- RLS enforced."""
|
||||||
return _app_engine
|
from sqlalchemy.pool import NullPool
|
||||||
|
|
||||||
|
engine = create_async_engine(TEST_APP_USER_DATABASE_URL, echo=False, poolclass=NullPool)
|
||||||
|
yield engine
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user