fix(ci): use module-level engines to avoid event loop teardown crash

Per-test engine creation/disposal triggers asyncpg event loop errors
during pytest-asyncio teardown. Module-level engines are created once
and reused across all tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jason Staack
2026-03-15 06:42:30 -05:00
parent 34bb60bd12
commit 402b25f418

View File

@@ -92,30 +92,27 @@ def setup_database():
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@pytest_asyncio.fixture # Module-level engines — created once, reused across all tests.
async def admin_engine(): # Avoids per-test engine creation/disposal which triggers asyncpg
# event loop issues during pytest-asyncio teardown.
_admin_engine = create_async_engine(
TEST_DATABASE_URL, echo=False, pool_pre_ping=True, pool_size=5, max_overflow=5
)
_app_engine = create_async_engine(
TEST_APP_USER_DATABASE_URL, echo=False, pool_pre_ping=True, pool_size=5, max_overflow=5
)
@pytest.fixture
def admin_engine():
"""Admin engine (superuser) -- bypasses RLS.""" """Admin engine (superuser) -- bypasses RLS."""
engine = create_async_engine( return _admin_engine
TEST_DATABASE_URL, echo=False, pool_pre_ping=True, pool_size=5, max_overflow=5
)
yield engine
try:
await engine.dispose()
except RuntimeError:
pass # Event loop may be closed during final teardown
@pytest_asyncio.fixture @pytest.fixture
async def app_engine(): def app_engine():
"""App-user engine -- RLS enforced.""" """App-user engine -- RLS enforced."""
engine = create_async_engine( return _app_engine
TEST_APP_USER_DATABASE_URL, echo=False, pool_pre_ping=True, pool_size=5, max_overflow=5
)
yield engine
try:
await engine.dispose()
except RuntimeError:
pass # Event loop may be closed during final teardown
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------