58 lines
1.9 KiB
Python

from collections.abc import Generator
import pytest
# Attempt import of testcontainers
postgres_container_cls = None
try:
try:
from testcontainers.community.postgres import PostgresContainer as _PostgresContainer
postgres_container_cls = _PostgresContainer
except ImportError:
from testcontainers.postgres import PostgresContainer as _PostgresContainer
postgres_container_cls = _PostgresContainer
except ImportError:
postgres_container_cls = None
@pytest.fixture(scope="session")
def postgres_container_url() -> Generator[str]:
"""Provides a disposable PostgreSQL 16 container URL strictly via Docker testcontainers.
Scoped to session to avoid duplicating container startup across tests.
No ambient admin or SQLite fallbacks.
"""
if postgres_container_cls is None:
raise RuntimeError(
"testcontainers package is required for PostgreSQL integration tests. "
"SQLite/localhost fallbacks are strictly prohibited."
)
try:
container = postgres_container_cls("postgres:16-alpine")
container.start()
host = container.get_container_host_ip()
port = container.get_exposed_port(5432)
user = container.username
password = container.password
dbname = container.dbname
url = f"postgresql+asyncpg://{user}:{password}@{host}:{port}/{dbname}"
try:
yield url
finally:
container.stop()
except Exception as exc:
raise RuntimeError(
f"Failed to start PostgreSQL testcontainer: {exc}. "
"Docker daemon must be running and accessible for integration tests. "
"SQLite/localhost fallbacks are prohibited."
) from exc
@pytest.fixture
def temp_postgres_db(postgres_container_url: str) -> str:
"""Yields disposable PostgreSQL container database URL."""
return postgres_container_url