Skip to content

Commit f51663b

Browse files
committed
cleanup
1 parent df5602d commit f51663b

25 files changed

+130
-140
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@ line-length = 120
647647
## Testing Tools
648648

649649
[tool.pytest.ini_options]
650-
addopts = " --doctest-glob='*.md'"
650+
addopts = " --doctest-glob='*.md' --dist=loadgroup"
651651
filterwarnings = [
652652
"ignore::DeprecationWarning:pkg_resources",
653653
"ignore::DeprecationWarning:xdist.*",

src/pytest_databases/_service.py

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,36 @@
22

33
import contextlib
44
import json
5-
import multiprocessing
65
import os
7-
import pathlib
8-
import secrets
9-
import subprocess
6+
import subprocess # noqa: S404
107
import time
118
from contextlib import AbstractContextManager, contextmanager
12-
from functools import partial
13-
from typing import Callable, Generator, Any
9+
from typing import TYPE_CHECKING, Any, Callable, Generator, Self
1410

15-
import docker
1611
import filelock
1712
import pytest
18-
from docker.models.containers import Container
19-
from docker.errors import ImageNotFound
2013

14+
import docker
15+
from docker.errors import ImageNotFound
2116
from pytest_databases.helpers import get_xdist_worker_id
2217
from pytest_databases.types import ServiceContainer
2318

19+
if TYPE_CHECKING:
20+
import multiprocessing
21+
import pathlib
22+
from types import TracebackType
23+
24+
from docker.models.containers import Container
25+
2426

2527
def get_docker_host() -> str:
2628
result = subprocess.run(
27-
["docker", "context", "ls", "--format=json"],
29+
["docker", "context", "ls", "--format=json"], # noqa: S607
2830
text=True,
2931
capture_output=True,
3032
check=True,
3133
)
32-
contexts = (json.loads(l) for l in result.stdout.splitlines())
34+
contexts = (json.loads(line) for line in result.stdout.splitlines())
3335
return next(context["DockerEndpoint"] for context in contexts if context["Current"] is True)
3436

3537

@@ -40,12 +42,6 @@ def get_docker_client() -> docker.DockerClient:
4042
return docker.DockerClient.from_env(environment=env)
4143

4244

43-
def log(msg):
44-
log_file = pathlib.Path("out.log")
45-
with log_file.open("a") as f:
46-
f.write(msg + "\n")
47-
48-
4945
def _stop_all_containers(client: docker.DockerClient) -> None:
5046
containers: list[Container] = client.containers.list(all=True, filters={"label": "pytest_databases"})
5147
for container in containers:
@@ -56,7 +52,8 @@ def _stop_all_containers(client: docker.DockerClient) -> None:
5652
elif container.status == "removing":
5753
continue
5854
else:
59-
raise ValueError(f"Cannot handle container in state {container.status}")
55+
msg = f"Cannot handle container in state {container.status}"
56+
raise ValueError(msg)
6057

6158

6259
class DockerService(AbstractContextManager):
@@ -72,13 +69,13 @@ def __init__(
7269
self._session = session
7370
self._is_xdist = get_xdist_worker_id() is not None
7471

75-
def _daemon(self):
72+
def _daemon(self) -> None:
7673
while (self._tmp_path / "ctrl").exists():
7774
time.sleep(0.1)
7875
self._stop_all_containers()
7976

80-
def __enter__(self) -> DockerService:
81-
if self._is_xdist or True:
77+
def __enter__(self) -> Self:
78+
if self._is_xdist:
8279
ctrl_file = _get_ctrl_file(self._session)
8380
with filelock.FileLock(ctrl_file.with_suffix(".lock")):
8481
if not ctrl_file.exists():
@@ -88,7 +85,13 @@ def __enter__(self) -> DockerService:
8885
self._stop_all_containers()
8986
return self
9087

91-
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
88+
def __exit__(
89+
self,
90+
/,
91+
__exc_type: type[BaseException] | None,
92+
__exc_value: BaseException | None,
93+
__traceback: TracebackType | None,
94+
) -> None:
9295
if not self._is_xdist:
9396
self._stop_all_containers()
9497

@@ -97,7 +100,8 @@ def _get_container(self, name: str) -> Container | None:
97100
filters={"name": name},
98101
)
99102
if len(containers) > 1:
100-
raise ValueError(f"More than one running container found")
103+
msg = "More than one running container found"
104+
raise ValueError(msg)
101105
if containers:
102106
return containers[0]
103107
return None
@@ -115,12 +119,13 @@ def run(
115119
env: dict[str, Any] | None = None,
116120
exec_after_start: str | list[str] | None = None,
117121
check: Callable[[ServiceContainer], bool] | None = None,
118-
wait_for_log: str | None = None,
122+
wait_for_log: str | bytes | None = None,
119123
timeout: int = 10,
120-
pause: int = 0.1,
124+
pause: float = 0.1,
121125
) -> Generator[ServiceContainer, None, None]:
122126
if check is None and wait_for_log is None:
123-
raise ValueError(f"Must set at least check or wait_for_log")
127+
msg = "Must set at least check or wait_for_log"
128+
raise ValueError(msg)
124129

125130
name = f"pytest_databases_{name}"
126131
lock = filelock.FileLock(self._tmp_path / name) if self._is_xdist else contextlib.nullcontext()
@@ -154,21 +159,24 @@ def run(
154159

155160
started = time.time()
156161
if wait_for_log:
157-
wait_for_log = wait_for_log.encode()
162+
if isinstance(wait_for_log, str):
163+
wait_for_log = wait_for_log.encode()
158164
while time.time() - started < timeout:
159165
if wait_for_log in container.logs():
160166
break
161167
time.sleep(pause)
162168
else:
163-
raise ValueError(f"Service {name!r} failed to come online")
169+
msg = f"Service {name!r} failed to come online"
170+
raise ValueError(msg)
164171

165172
if check:
166173
while time.time() - started < timeout:
167174
if check(service) is True:
168175
break
169176
time.sleep(pause)
170177
else:
171-
raise ValueError(f"Service {name!r} failed to come online")
178+
msg = f"Service {name!r} failed to come online"
179+
raise ValueError(msg)
172180

173181
if exec_after_start:
174182
container.exec_run(exec_after_start)
@@ -208,13 +216,12 @@ def _get_base_tmp_path(tmp_path_factory: pytest.TempPathFactory) -> pathlib.Path
208216

209217

210218
def _get_ctrl_file(session: pytest.Session) -> pathlib.Path:
211-
tmp_path = _get_base_tmp_path(session.config._tmp_path_factory)
219+
tmp_path = _get_base_tmp_path(session.config._tmp_path_factory) # type: ignore[attr-defined]
212220
return tmp_path / "ctrl"
213221

214222

215223
@pytest.hookimpl(wrapper=True)
216-
def pytest_sessionfinish(session: pytest.Session, exitstatus):
217-
"""Insert teardown that you want to occur only once here"""
224+
def pytest_sessionfinish(session: pytest.Session, exitstatus: int) -> Generator[Any, Any, Any]:
218225
try:
219226
return (yield)
220227
finally:

src/pytest_databases/docker/alloydb_omni.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,44 @@
11
from __future__ import annotations
22

3+
import dataclasses
34
from typing import TYPE_CHECKING
45

56
import psycopg
67
import pytest
78

8-
from pytest_databases._service import DockerService
9-
from pytest_databases.docker import DockerServiceRegistry
109
from pytest_databases.docker.postgres import (
1110
_make_connection_string,
1211
_provide_postgres_service,
13-
PostgresService as AlloyDBService,
1412
)
15-
16-
__all__ = ("AlloyDBService",)
17-
13+
from pytest_databases.types import ServiceContainer
1814

1915
if TYPE_CHECKING:
2016
from collections.abc import Generator
2117

18+
from pytest_databases._service import DockerService
19+
20+
21+
@dataclasses.dataclass
22+
class AlloyDBService(ServiceContainer):
23+
database: str
24+
password: str
25+
user: str
26+
2227

2328
@pytest.fixture(autouse=False, scope="session")
2429
def alloydb_omni_service(
2530
docker_service: DockerService,
26-
) -> Generator[DockerServiceRegistry, None, None]:
31+
) -> Generator[AlloyDBService, None, None]:
2732
with _provide_postgres_service(
2833
docker_service=docker_service, image="google/alloydbomni", name="alloydb-omni"
2934
) as service:
30-
yield service
35+
yield AlloyDBService(
36+
host=service.host,
37+
port=service.port,
38+
password=service.password,
39+
database=service.database,
40+
user=service.user,
41+
)
3142

3243

3344
@pytest.fixture(autouse=False, scope="session")

src/pytest_databases/docker/azure_blob.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
from __future__ import annotations
22

33
import json
4-
import secrets
54
import subprocess # noqa: S404
65
from dataclasses import dataclass
7-
from typing import AsyncGenerator, Generator
6+
from typing import TYPE_CHECKING, AsyncGenerator, Generator
87

98
import pytest
109
from azure.storage.blob import ContainerClient
1110
from azure.storage.blob.aio import ContainerClient as AsyncContainerClient
1211

13-
from pytest_databases._service import DockerService
1412
from pytest_databases.helpers import get_xdist_worker_num
1513
from pytest_databases.types import ServiceContainer
1614

15+
if TYPE_CHECKING:
16+
from pytest_databases._service import DockerService
17+
1718

1819
@dataclass
1920
class AzureBlobService(ServiceContainer):

src/pytest_databases/docker/bigquery.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@
88
from google.auth.credentials import AnonymousCredentials, Credentials
99
from google.cloud import bigquery
1010

11-
from pytest_databases._service import DockerService
1211
from pytest_databases.helpers import get_xdist_worker_id
1312
from pytest_databases.types import ServiceContainer
1413

1514
if TYPE_CHECKING:
1615
from collections.abc import Generator
1716

17+
from pytest_databases._service import DockerService
18+
1819

1920
@dataclass
2021
class BigQueryService(ServiceContainer):

src/pytest_databases/docker/cockroachdb.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11
from __future__ import annotations
22

3-
import os
4-
import sys
53
from dataclasses import dataclass
6-
from pathlib import Path
74
from typing import TYPE_CHECKING
85

96
import psycopg
107
import pytest
118

129
from pytest_databases._service import DockerService, ServiceContainer
13-
from pytest_databases.docker import DockerServiceRegistry
14-
from pytest_databases.docker.dragonfly import dragonfly_image
15-
from pytest_databases.helpers import simple_string_hash, get_xdist_worker_num
10+
from pytest_databases.helpers import get_xdist_worker_num
1611

1712
if TYPE_CHECKING:
1813
from collections.abc import Generator

src/pytest_databases/docker/elastic_search.py

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,19 @@
22

33
import contextlib
44
import dataclasses
5-
import os
6-
import sys
7-
from pathlib import Path
85
from typing import TYPE_CHECKING
96

107
import pytest
118
from elasticsearch7 import Elasticsearch as Elasticsearch7
129
from elasticsearch7 import Elasticsearch as Elasticsearch8
1310

14-
from pytest_databases._service import DockerService
15-
from pytest_databases.docker import DockerServiceRegistry
16-
from pytest_databases.helpers import simple_string_hash
1711
from pytest_databases.types import ServiceContainer
1812

1913
if TYPE_CHECKING:
2014
from collections.abc import Generator
2115

16+
from pytest_databases._service import DockerService
17+
2218

2319
@dataclasses.dataclass
2420
class ElasticsearchService(ServiceContainer):
@@ -48,33 +44,13 @@ def elasticsearch8_responsive(scheme: str, host: str, port: int, user: str, pass
4844
return False
4945

5046

51-
@pytest.fixture(scope="session")
52-
def elasticsearch_user() -> str:
53-
return "elastic"
54-
55-
56-
@pytest.fixture(scope="session")
57-
def elasticsearch_password() -> str:
58-
return "changeme"
59-
60-
61-
@pytest.fixture(scope="session")
62-
def elasticsearch_database() -> str:
63-
return "db"
64-
65-
66-
@pytest.fixture(scope="session")
67-
def elasticsearch_scheme() -> str:
68-
return "http"
69-
70-
7147
@contextlib.contextmanager
7248
def _provide_elasticsearch_service(
7349
docker_service: DockerService,
7450
image: str,
7551
name: str,
7652
client_cls: type[Elasticsearch7 | Elasticsearch8],
77-
):
53+
) -> Generator[ElasticsearchService, None, None]:
7854
user = "elastic"
7955
password = "changeme"
8056
database = "db"
@@ -100,6 +76,8 @@ def check(_service: ServiceContainer) -> bool:
10076
"xpack.security.enabled": "false",
10177
},
10278
check=check,
79+
timeout=120,
80+
pause=1,
10381
) as service:
10482
yield ElasticsearchService(
10583
host=service.host,
@@ -134,5 +112,5 @@ def elasticsearch8_service(docker_service: DockerService) -> Generator[Elasticse
134112

135113

136114
@pytest.fixture(autouse=False, scope="session")
137-
def elasticsearch_service(elasticsearch8_service) -> ElasticsearchService:
115+
def elasticsearch_service(elasticsearch8_service: ElasticsearchService) -> ElasticsearchService:
138116
return elasticsearch8_service

src/pytest_databases/docker/keydb.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
from pytest_databases._service import DockerService
1515

1616

17-
1817
@dataclasses.dataclass
1918
class KeydbService(ServiceContainer):
2019
db: int

src/pytest_databases/docker/mariadb.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
import pymysql
88
import pytest
99

10-
from pytest_databases._service import DockerService
1110
from pytest_databases.helpers import get_xdist_worker_num
1211
from pytest_databases.types import ServiceContainer
1312

1413
if TYPE_CHECKING:
1514
from collections.abc import Generator
1615

16+
from pytest_databases._service import DockerService
17+
1718

1819
@dataclass
1920
class MariaDBService(ServiceContainer):

0 commit comments

Comments
 (0)