Source code for pytest_databases.docker.elastic_search

from __future__ import annotations

import contextlib
import dataclasses
import json
import urllib.error
import urllib.request
from typing import TYPE_CHECKING

import pytest

from pytest_databases.types import ServiceContainer

if TYPE_CHECKING:
    from collections.abc import Generator

    from pytest_databases._service import DockerService


[docs] @dataclasses.dataclass class ElasticsearchService(ServiceContainer): scheme: str user: str password: str database: str
def _check_cluster_health(host: str, port: int, *, timeout: float = 2.0) -> bool: request = urllib.request.Request( f"http://{host}:{port}/_cluster/health", headers={"Accept": "application/json"}, ) try: with urllib.request.urlopen(request, timeout=timeout) as response: # noqa: S310 if response.status != 200: return False payload = json.loads(response.read().decode("utf-8")) except (urllib.error.URLError, OSError, ValueError): return False return payload.get("status") in {"yellow", "green"}
[docs] @pytest.fixture(scope="session") def elasticsearch_service_memory_limit() -> str: return "500m"
@contextlib.contextmanager def _provide_elasticsearch_service( docker_service: DockerService, image: str, name: str, memory_limit: str, ) -> Generator[ElasticsearchService, None, None]: user = "elastic" password = "changeme" database = "db" scheme = "http" def check(_service: ServiceContainer) -> bool: return _check_cluster_health(_service.host, _service.port) with docker_service.run( image=image, name=name, container_port=9200, env={ "discovery.type": "single-node", "xpack.security.enabled": "false", "ingest.geoip.downloader.enabled": "false", "cluster.routing.allocation.disk.threshold_enabled": "false", }, check=check, timeout=120, pause=1, transient=True, mem_limit="1g", ) as service: yield ElasticsearchService( host=service.host, port=service.port, container=service.container, user=user, password=password, scheme=scheme, database=database, )
[docs] @pytest.fixture(autouse=False, scope="session") def elasticsearch_7_service( docker_service: DockerService, elasticsearch_service_memory_limit: str, ) -> Generator[ElasticsearchService, None, None]: with _provide_elasticsearch_service( docker_service=docker_service, image="elasticsearch:7.17.19", name="elasticsearch-7", memory_limit=elasticsearch_service_memory_limit, ) as service: yield service
[docs] @pytest.fixture(autouse=False, scope="session") def elasticsearch_8_service( docker_service: DockerService, elasticsearch_service_memory_limit: str, ) -> Generator[ElasticsearchService, None, None]: with _provide_elasticsearch_service( docker_service=docker_service, image="elasticsearch:8.13.0", name="elasticsearch-8", memory_limit=elasticsearch_service_memory_limit, ) as service: yield service
[docs] @pytest.fixture(autouse=False, scope="session") def elasticsearch_service(elasticsearch_8_service: ElasticsearchService) -> ElasticsearchService: return elasticsearch_8_service