11from __future__ import annotations
22
3+ import contextlib
4+ import dataclasses
35import os
46import sys
57from pathlib import Path
911from elasticsearch7 import Elasticsearch as Elasticsearch7
1012from elasticsearch7 import Elasticsearch as Elasticsearch8
1113
14+ from pytest_databases ._service import DockerService
1215from pytest_databases .docker import DockerServiceRegistry
1316from pytest_databases .helpers import simple_string_hash
17+ from pytest_databases .types import ServiceContainer
1418
1519if TYPE_CHECKING :
1620 from collections .abc import Generator
1721
1822
19- COMPOSE_PROJECT_NAME : str = f"pytest-databases-elasticsearch-{ simple_string_hash (__file__ )} "
23+ @dataclasses .dataclass
24+ class ElasticsearchService (ServiceContainer ):
25+ scheme : str
26+ user : str
27+ password : str
28+ database : str
2029
2130
2231def elasticsearch7_responsive (scheme : str , host : str , port : int , user : str , password : str , database : str ) -> bool :
@@ -39,22 +48,6 @@ def elasticsearch8_responsive(scheme: str, host: str, port: int, user: str, pass
3948 return False
4049
4150
42- @pytest .fixture (scope = "session" )
43- def elasticsearch_compose_project_name () -> str :
44- return os .environ .get ("COMPOSE_PROJECT_NAME" , COMPOSE_PROJECT_NAME )
45-
46-
47- @pytest .fixture (autouse = False , scope = "session" )
48- def elasticsearch_docker_services (
49- elasticsearch_compose_project_name : str , worker_id : str = "main"
50- ) -> Generator [DockerServiceRegistry , None , None ]:
51- if os .getenv ("GITHUB_ACTIONS" ) == "true" and sys .platform != "linux" :
52- pytest .skip ("Docker not available on this platform" )
53-
54- with DockerServiceRegistry (worker_id , compose_project_name = elasticsearch_compose_project_name ) as registry :
55- yield registry
56-
57-
5851@pytest .fixture (scope = "session" )
5952def elasticsearch_user () -> str :
6053 return "elastic"
@@ -75,102 +68,71 @@ def elasticsearch_scheme() -> str:
7568 return "http"
7669
7770
78- @pytest .fixture (scope = "session" )
79- def elasticsearch7_port () -> int :
80- return 9200
81-
82-
83- @pytest .fixture (scope = "session" )
84- def elasticsearch8_port () -> int :
85- return 9201
86-
87-
88- @pytest .fixture (scope = "session" )
89- def elasticsearch_docker_compose_files () -> list [Path ]:
90- return [Path (Path (__file__ ).parent / "docker-compose.elasticsearch.yml" )]
91-
92-
93- @pytest .fixture (scope = "session" )
94- def default_elasticsearch_service_name () -> str :
95- return "elasticsearch8"
96-
97-
98- @pytest .fixture (scope = "session" )
99- def elasticsearch_docker_ip (elasticsearch_docker_services : DockerServiceRegistry ) -> str :
100- return elasticsearch_docker_services .docker_ip
71+ @contextlib .contextmanager
72+ def _provide_elasticsearch_service (
73+ docker_service : DockerService ,
74+ image : str ,
75+ name : str ,
76+ client_cls : type [Elasticsearch7 | Elasticsearch8 ],
77+ ):
78+ user = "elastic"
79+ password = "changeme"
80+ database = "db"
81+ scheme = "http"
82+
83+ def check (_service : ServiceContainer ) -> bool :
84+ try :
85+ with client_cls (
86+ hosts = [{"host" : _service .host , "port" : _service .port , "scheme" : scheme }],
87+ verify_certs = False ,
88+ http_auth = (user , password ),
89+ ) as client :
90+ return client .ping ()
91+ except Exception : # noqa: BLE001
92+ return False
93+
94+ with docker_service .run (
95+ image = image ,
96+ name = name ,
97+ container_port = 9200 ,
98+ env = {
99+ "discovery.type" : "single-node" ,
100+ "xpack.security.enabled" : "false" ,
101+ },
102+ check = check ,
103+ ) as service :
104+ yield ElasticsearchService (
105+ host = service .host ,
106+ port = service .port ,
107+ user = user ,
108+ password = password ,
109+ scheme = scheme ,
110+ database = database ,
111+ )
101112
102113
103114@pytest .fixture (autouse = False , scope = "session" )
104- def elasticsearch7_service (
105- elasticsearch_docker_services : DockerServiceRegistry ,
106- elasticsearch_docker_compose_files : list [Path ],
107- elasticsearch7_port : int ,
108- elasticsearch_database : str ,
109- elasticsearch_user : str ,
110- elasticsearch_password : str ,
111- elasticsearch_scheme : str ,
112- ) -> Generator [None , None , None ]:
113- elasticsearch_docker_services .start (
114- "elasticsearch7" ,
115- docker_compose_files = elasticsearch_docker_compose_files ,
116- timeout = 45 ,
117- pause = 1 ,
118- check = elasticsearch7_responsive ,
119- port = elasticsearch7_port ,
120- database = elasticsearch_database ,
121- user = elasticsearch_user ,
122- password = elasticsearch_password ,
123- scheme = elasticsearch_scheme ,
124- )
125- yield
115+ def elasticsearch7_service (docker_service : DockerService ) -> Generator [ElasticsearchService , None , None ]:
116+ with _provide_elasticsearch_service (
117+ docker_service = docker_service ,
118+ image = "elasticsearch:7.17.19" ,
119+ name = "elasticsearch-7" ,
120+ client_cls = Elasticsearch7 ,
121+ ) as service :
122+ yield service
126123
127124
128125@pytest .fixture (autouse = False , scope = "session" )
129- def elasticsearch8_service (
130- elasticsearch_docker_services : DockerServiceRegistry ,
131- elasticsearch_docker_compose_files : list [Path ],
132- elasticsearch8_port : int ,
133- elasticsearch_database : str ,
134- elasticsearch_user : str ,
135- elasticsearch_password : str ,
136- elasticsearch_scheme : str ,
137- ) -> Generator [None , None , None ]:
138- elasticsearch_docker_services .start (
139- "elasticsearch8" ,
140- docker_compose_files = elasticsearch_docker_compose_files ,
141- timeout = 45 ,
142- pause = 1 ,
143- check = elasticsearch8_responsive ,
144- port = elasticsearch8_port ,
145- database = elasticsearch_database ,
146- user = elasticsearch_user ,
147- password = elasticsearch_password ,
148- scheme = elasticsearch_scheme ,
149- )
150- yield
126+ def elasticsearch8_service (docker_service : DockerService ) -> Generator [ElasticsearchService , None , None ]:
127+ with _provide_elasticsearch_service (
128+ docker_service = docker_service ,
129+ image = "elasticsearch:8.13.0" ,
130+ name = "elasticsearch-8" ,
131+ client_cls = Elasticsearch8 ,
132+ ) as service :
133+ yield service
151134
152135
153136@pytest .fixture (autouse = False , scope = "session" )
154- def elasticsearch_service (
155- elasticsearch_docker_services : DockerServiceRegistry ,
156- default_elasticsearch_service_name : str ,
157- elasticsearch_docker_compose_files : list [Path ],
158- elasticsearch8_port : int ,
159- elasticsearch_database : str ,
160- elasticsearch_user : str ,
161- elasticsearch_password : str ,
162- elasticsearch_scheme : str ,
163- ) -> Generator [None , None , None ]:
164- elasticsearch_docker_services .start (
165- name = default_elasticsearch_service_name ,
166- docker_compose_files = elasticsearch_docker_compose_files ,
167- timeout = 45 ,
168- pause = 1 ,
169- check = elasticsearch8_responsive ,
170- port = elasticsearch8_port ,
171- database = elasticsearch_database ,
172- user = elasticsearch_user ,
173- password = elasticsearch_password ,
174- scheme = elasticsearch_scheme ,
175- )
176- yield
137+ def elasticsearch_service (elasticsearch8_service ) -> ElasticsearchService :
138+ return elasticsearch8_service
0 commit comments