refactor(test): share container fixtures across the integration and e2e suites
Why: - tests/e2e/ cannot reach fixtures defined in a per-boundary conftest, and `pytest_plugins` is only honoured in the root conftest. Changes: - move the Postgres/MinIO/Qdrant container fixtures into tests/support/containers.py and register it as a root plugin - fold MinIO bucket creation into `minio_settings`; an autouse fixture in a globally registered plugin would pull a container into unit runs - add a `postgres_settings` fixture so a component can be built from it directly Impact: - no behavior change; `pytest -m unit` still needs no Docker Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,52 +0,0 @@
|
||||
import uuid
|
||||
from collections.abc import AsyncIterator, Iterator
|
||||
|
||||
import pytest
|
||||
import pytest_asyncio
|
||||
from qdrant_client import AsyncQdrantClient
|
||||
from testcontainers.community.qdrant import QdrantContainer
|
||||
|
||||
from src.config import QdrantSettings
|
||||
from src.infrastructure.qdrant.client import create_client
|
||||
|
||||
# Pinned to match the `qdrant-client` major/minor in pyproject.toml. The
|
||||
# testcontainers default image trails it far enough that the client emits an
|
||||
# incompatibility warning, and testing against a version we do not deploy is
|
||||
# the wrong signal anyway.
|
||||
_QDRANT_IMAGE = "qdrant/qdrant:v1.19.0"
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def qdrant_container() -> Iterator[QdrantContainer]:
|
||||
with QdrantContainer(image=_QDRANT_IMAGE) as container:
|
||||
yield container
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def qdrant_url(qdrant_container: QdrantContainer) -> str:
|
||||
"""The container's REST URL, pinned to IPv4.
|
||||
|
||||
Same gotcha as postgres_url/minio_settings (see their conftests):
|
||||
testcontainers reports the host as `localhost`, which resolves to `::1`
|
||||
first, but Docker publishes the mapped port on IPv4 only. The IPv6 SYN is
|
||||
dropped rather than refused, so the client hangs until its timeout instead
|
||||
of falling back to the second address -- the connection does not fail, it
|
||||
hangs.
|
||||
"""
|
||||
host = qdrant_container.get_container_host_ip().replace("localhost", "127.0.0.1")
|
||||
return f"http://{host}:{qdrant_container.get_exposed_port(6333)}"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def qdrant_settings(qdrant_url: str) -> QdrantSettings:
|
||||
"""Settings naming a collection unique to this test (ADR-0016 isolation)."""
|
||||
return QdrantSettings(url=qdrant_url, collection=f"chunks_{uuid.uuid4().hex}")
|
||||
|
||||
|
||||
@pytest_asyncio.fixture(loop_scope="session")
|
||||
async def qdrant_client(qdrant_settings: QdrantSettings) -> AsyncIterator[AsyncQdrantClient]:
|
||||
client = create_client(qdrant_settings)
|
||||
try:
|
||||
yield client
|
||||
finally:
|
||||
await client.close()
|
||||
Reference in New Issue
Block a user