Skip to content

Commit df5602d

Browse files
committed
migrate oracle
1 parent e1d91a7 commit df5602d

File tree

4 files changed

+104
-278
lines changed

4 files changed

+104
-278
lines changed

src/pytest_databases/_service.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,14 @@ def log(msg):
4949
def _stop_all_containers(client: docker.DockerClient) -> None:
5050
containers: list[Container] = client.containers.list(all=True, filters={"label": "pytest_databases"})
5151
for container in containers:
52-
container.kill()
52+
if container.status == "running":
53+
container.kill()
54+
elif container.status == "stopped":
55+
container.remove()
56+
elif container.status == "removing":
57+
continue
58+
else:
59+
raise ValueError(f"Cannot handle container in state {container.status}")
5360

5461

5562
class DockerService(AbstractContextManager):

src/pytest_databases/docker/docker-compose.oracle.yml

Lines changed: 0 additions & 24 deletions
This file was deleted.
Lines changed: 87 additions & 193 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
from __future__ import annotations
22

3+
import contextlib
34
import os
45
import sys
6+
from dataclasses import dataclass
57
from pathlib import Path
68
from typing import TYPE_CHECKING
79

810
import oracledb
911
import pytest
1012

13+
from pytest_databases._service import DockerService
1114
from pytest_databases.docker import DockerServiceRegistry
1215
from pytest_databases.helpers import simple_string_hash
16+
from pytest_databases.types import ServiceContainer
1317

1418
if TYPE_CHECKING:
1519
from collections.abc import Generator
@@ -35,223 +39,113 @@ def oracle_responsive(host: str, port: int, service_name: str, user: str, passwo
3539
return False
3640

3741

38-
@pytest.fixture(scope="session")
39-
def oracle_compose_project_name() -> str:
40-
return os.environ.get("COMPOSE_PROJECT_NAME", COMPOSE_PROJECT_NAME)
41-
42-
43-
@pytest.fixture(autouse=False, scope="session")
44-
def oracle_docker_services(
45-
oracle_compose_project_name: str, worker_id: str = "main"
46-
) -> Generator[DockerServiceRegistry, None, None]:
47-
if os.getenv("GITHUB_ACTIONS") == "true" and sys.platform != "linux":
48-
pytest.skip("Docker not available on this platform")
49-
50-
with DockerServiceRegistry(worker_id, compose_project_name=oracle_compose_project_name) as registry:
51-
yield registry
52-
53-
54-
@pytest.fixture(scope="session")
55-
def oracle_user() -> str:
56-
return "app"
57-
58-
59-
@pytest.fixture(scope="session")
60-
def oracle_password() -> str:
61-
return "super-secret"
62-
63-
64-
@pytest.fixture(scope="session")
65-
def oracle_system_password() -> str:
66-
return "super-secret"
67-
68-
69-
@pytest.fixture(scope="session")
70-
def oracle18c_service_name() -> str:
71-
return "xepdb1"
72-
73-
74-
@pytest.fixture(scope="session")
75-
def oracle23ai_service_name() -> str:
76-
return "FREEPDB1"
77-
78-
79-
@pytest.fixture(scope="session")
80-
def oracle_service_name(oracle23ai_service_name: str) -> str:
81-
return oracle23ai_service_name
82-
83-
84-
@pytest.fixture(scope="session")
85-
def oracle18c_port() -> int:
86-
return 1514
87-
88-
89-
@pytest.fixture(scope="session")
90-
def oracle23ai_port() -> int:
91-
return 1513
92-
93-
94-
@pytest.fixture(scope="session")
95-
def default_oracle_service_name() -> str:
96-
return "oracle23ai"
97-
98-
99-
@pytest.fixture(scope="session")
100-
def oracle_port(oracle23ai_port: int) -> int:
101-
return oracle23ai_port
102-
103-
104-
@pytest.fixture(scope="session")
105-
def oracle_docker_compose_files() -> list[Path]:
106-
return [Path(Path(__file__).parent / "docker-compose.oracle.yml")]
107-
108-
109-
@pytest.fixture(scope="session")
110-
def oracle_docker_ip(oracle_docker_services: DockerServiceRegistry) -> str:
111-
return oracle_docker_services.docker_ip
42+
@dataclass
43+
class OracleService(ServiceContainer):
44+
user: str
45+
password: str
46+
system_password: str
47+
service_name: str
48+
49+
50+
@contextlib.contextmanager
51+
def _provide_oracle_service(docker_service: DockerService, image: str, name: str, service_name: str):
52+
user = "app"
53+
password = "super-secret"
54+
system_password = "super-secret"
55+
56+
def check(_service: ServiceContainer) -> bool:
57+
try:
58+
conn = oracledb.connect(
59+
host=_service.host,
60+
port=_service.port,
61+
user=user,
62+
password=password,
63+
service_name=service_name,
64+
)
65+
with conn.cursor() as cursor:
66+
cursor.execute("SELECT 1 FROM dual")
67+
resp = cursor.fetchone()
68+
return resp[0] == 1 if resp is not None else False
69+
except Exception: # noqa: BLE001
70+
return False
71+
72+
with docker_service.run(
73+
image=image,
74+
name=name,
75+
check=check,
76+
container_port=1521,
77+
env={
78+
"ORACLE_PASSWORD": system_password,
79+
"APP_USER_PASSWORD": password,
80+
"APP_USER": user,
81+
},
82+
) as service:
83+
yield OracleService(
84+
host=service.host,
85+
port=service.port,
86+
system_password=system_password,
87+
user=user,
88+
password=password,
89+
service_name=service_name,
90+
)
11291

11392

11493
@pytest.fixture(autouse=False, scope="session")
115-
def oracle23ai_service(
116-
oracle_docker_services: DockerServiceRegistry,
117-
oracle_docker_compose_files: list[Path],
118-
oracle23ai_port: int,
119-
oracle23ai_service_name: str,
120-
oracle_system_password: str,
121-
oracle_user: str,
122-
oracle_password: str,
123-
) -> Generator[None, None, None]:
124-
os.environ["ORACLE_PASSWORD"] = oracle_password
125-
os.environ["ORACLE_SYSTEM_PASSWORD"] = oracle_system_password
126-
os.environ["ORACLE_USER"] = oracle_user
127-
os.environ["ORACLE23AI_SERVICE_NAME"] = oracle23ai_service_name
128-
os.environ["ORACLE23AI_PORT"] = str(oracle23ai_port)
129-
oracle_docker_services.start(
130-
"oracle23ai",
131-
docker_compose_files=oracle_docker_compose_files,
132-
timeout=90,
133-
pause=1,
134-
check=oracle_responsive,
135-
port=oracle23ai_port,
136-
service_name=oracle23ai_service_name,
137-
user=oracle_user,
138-
password=oracle_password,
139-
)
140-
yield
94+
def oracle23ai_service(docker_service: DockerService) -> Generator[OracleService, None, None]:
95+
with _provide_oracle_service(
96+
image="gvenzl/oracle-free:23-slim-faststart",
97+
name="oracle23ai",
98+
service_name="FREEPDB1",
99+
docker_service=docker_service,
100+
) as service:
101+
yield service
141102

142103

143104
@pytest.fixture(autouse=False, scope="session")
144-
def oracle18c_service(
145-
oracle_docker_services: DockerServiceRegistry,
146-
oracle_docker_compose_files: list[Path],
147-
oracle18c_port: int,
148-
oracle18c_service_name: str,
149-
oracle_system_password: str,
150-
oracle_user: str,
151-
oracle_password: str,
152-
) -> Generator[None, None, None]:
153-
os.environ["ORACLE_PASSWORD"] = oracle_password
154-
os.environ["ORACLE_SYSTEM_PASSWORD"] = oracle_system_password
155-
os.environ["ORACLE_USER"] = oracle_user
156-
os.environ["ORACLE18C_SERVICE_NAME"] = oracle18c_service_name
157-
os.environ["ORACLE18C_PORT"] = str(oracle18c_port)
158-
oracle_docker_services.start(
159-
"oracle18c",
160-
docker_compose_files=oracle_docker_compose_files,
161-
timeout=90,
162-
pause=1,
163-
check=oracle_responsive,
164-
port=oracle18c_port,
165-
service_name=oracle18c_service_name,
166-
user=oracle_user,
167-
password=oracle_password,
168-
)
169-
yield
105+
def oracle18c_service(docker_service: DockerService) -> Generator[None, None, None]:
106+
with _provide_oracle_service(
107+
image="gvenzl/oracle-free:23-slim-faststart",
108+
name="oracle18c",
109+
service_name="xepdb1",
110+
docker_service=docker_service,
111+
) as service:
112+
yield service
170113

171114

172115
# alias to the latest
173116
@pytest.fixture(autouse=False, scope="session")
174-
def oracle_service(
175-
oracle_docker_services: DockerServiceRegistry,
176-
default_oracle_service_name: str,
177-
oracle_docker_compose_files: list[Path],
178-
oracle_port: int,
179-
oracle_service_name: str,
180-
oracle_system_password: str,
181-
oracle_user: str,
182-
oracle_password: str,
183-
) -> Generator[None, None]:
184-
os.environ["ORACLE_PASSWORD"] = oracle_password
185-
os.environ["ORACLE_SYSTEM_PASSWORD"] = oracle_system_password
186-
os.environ["ORACLE_USER"] = oracle_user
187-
os.environ["ORACLE_SERVICE_NAME"] = oracle_service_name
188-
os.environ[f"{default_oracle_service_name.upper()}_PORT"] = str(oracle_port)
189-
oracle_docker_services.start(
190-
name=default_oracle_service_name,
191-
docker_compose_files=oracle_docker_compose_files,
192-
timeout=90,
193-
pause=1,
194-
check=oracle_responsive,
195-
port=oracle_port,
196-
service_name=oracle_service_name,
197-
user=oracle_user,
198-
password=oracle_password,
199-
)
200-
yield
117+
def oracle_service(oracle23ai_service: OracleService) -> OracleService:
118+
return oracle23ai_service
201119

202120

203121
@pytest.fixture(autouse=False, scope="session")
204-
def oracle_startup_connection(
205-
oracle_service: DockerServiceRegistry,
206-
oracle_docker_ip: str,
207-
oracle_port: int,
208-
oracle_service_name: str,
209-
oracle_user: str,
210-
oracle_password: str,
122+
def oracle18c_startup_connection(
123+
oracle18c_service: OracleService,
211124
) -> Generator[oracledb.Connection, None, None]:
212125
with oracledb.connect(
213-
host=oracle_docker_ip,
214-
port=oracle_port,
215-
user=oracle_user,
216-
service_name=oracle_service_name,
217-
password=oracle_password,
126+
host=oracle18c_service.host,
127+
port=oracle18c_service.port,
128+
user=oracle18c_service.user,
129+
service_name=oracle18c_service.service_name,
130+
password=oracle18c_service.password,
218131
) as db_connection:
219132
yield db_connection
220133

221134

222135
@pytest.fixture(autouse=False, scope="session")
223-
def oracle18c_startup_connection(
224-
oracle18c_service: DockerServiceRegistry,
225-
oracle_docker_ip: str,
226-
oracle18c_port: int,
227-
oracle18c_service_name: str,
228-
oracle_user: str,
229-
oracle_password: str,
136+
def oracle23ai_startup_connection(
137+
oracle23ai_service: OracleService,
230138
) -> Generator[oracledb.Connection, None, None]:
231139
with oracledb.connect(
232-
host=oracle_docker_ip,
233-
port=oracle18c_port,
234-
user=oracle_user,
235-
service_name=oracle18c_service_name,
236-
password=oracle_password,
140+
host=oracle23ai_service.host,
141+
port=oracle23ai_service.port,
142+
user=oracle23ai_service.user,
143+
service_name=oracle23ai_service.service_name,
144+
password=oracle23ai_service.password,
237145
) as db_connection:
238146
yield db_connection
239147

240148

241149
@pytest.fixture(autouse=False, scope="session")
242-
def oracle23ai_startup_connection(
243-
oracle23ai_service: DockerServiceRegistry,
244-
oracle_docker_ip: str,
245-
oracle23ai_port: int,
246-
oracle23ai_service_name: str,
247-
oracle_user: str,
248-
oracle_password: str,
249-
) -> Generator[oracledb.Connection, None, None]:
250-
with oracledb.connect(
251-
host=oracle_docker_ip,
252-
port=oracle23ai_port,
253-
user=oracle_user,
254-
service_name=oracle23ai_service_name,
255-
password=oracle_password,
256-
) as db_connection:
257-
yield db_connection
150+
def oracle_startup_connection(oracle23ai_startup_connection: oracledb.Connection) -> oracledb.Connection:
151+
return oracledb.oracle23ai_startup_connection

0 commit comments

Comments
 (0)