Skip to content

Commit 77164e4

Browse files
committed
Merge branch 'feat/pytest-container-management' of https://github.com/d-v-b/datajoint-python into feat/djzarr
2 parents 0719b4b + b3f82d9 commit 77164e4

File tree

2 files changed

+39
-24
lines changed

2 files changed

+39
-24
lines changed

.codespellrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
skip = .git,*.pdf,*.svg,*.csv,*.ipynb,*.drawio
33
# Rever -- nobody knows
44
# numer -- numerator variable
5-
ignore-words-list = rever,numer
5+
ignore-words-list = rever,numer,astroid

tests/conftest.py

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ def pytest_configure(config):
4545
pass
4646

4747

48-
49-
5048
# Global container registry for cleanup
5149
_active_containers = set()
5250
_docker_client = None
@@ -63,18 +61,24 @@ def _get_docker_client():
6361
def _cleanup_containers():
6462
"""Clean up any remaining containers"""
6563
if _active_containers:
66-
logger.info(f"Emergency cleanup: {len(_active_containers)} containers to clean up")
64+
logger.info(
65+
f"Emergency cleanup: {len(_active_containers)} containers to clean up"
66+
)
6767
try:
6868
client = _get_docker_client()
6969
for container_id in list(_active_containers):
7070
try:
7171
container = client.containers.get(container_id)
7272
container.remove(force=True)
73-
logger.info(f"Emergency cleanup: removed container {container_id[:12]}")
73+
logger.info(
74+
f"Emergency cleanup: removed container {container_id[:12]}"
75+
)
7476
except docker.errors.NotFound:
7577
logger.debug(f"Container {container_id[:12]} already removed")
7678
except Exception as e:
77-
logger.error(f"Error cleaning up container {container_id[:12]}: {e}")
79+
logger.error(
80+
f"Error cleaning up container {container_id[:12]}: {e}"
81+
)
7882
finally:
7983
_active_containers.discard(container_id)
8084
except Exception as e:
@@ -101,7 +105,9 @@ def _unregister_container(container):
101105

102106
def _signal_handler(signum, frame):
103107
"""Handle signals to ensure container cleanup"""
104-
logger.warning(f"Received signal {signum}, performing emergency container cleanup...")
108+
logger.warning(
109+
f"Received signal {signum}, performing emergency container cleanup..."
110+
)
105111
_cleanup_containers()
106112

107113
# Restore default signal handler and re-raise the signal
@@ -150,9 +156,7 @@ def mysql_container(docker_client):
150156
container = docker_client.containers.run(
151157
f"datajoint/mysql:{mysql_ver}",
152158
name=container_name,
153-
environment={
154-
"MYSQL_ROOT_PASSWORD": "password"
155-
},
159+
environment={"MYSQL_ROOT_PASSWORD": "password"},
156160
command="mysqld --default-authentication-plugin=mysql_native_password",
157161
ports={"3306/tcp": None}, # Let Docker assign random port
158162
detach=True,
@@ -162,7 +166,7 @@ def mysql_container(docker_client):
162166
"timeout": 30000000000, # 30s in nanoseconds
163167
"retries": 5,
164168
"interval": 15000000000, # 15s in nanoseconds
165-
}
169+
},
166170
)
167171

168172
# Register container for cleanup
@@ -172,7 +176,9 @@ def mysql_container(docker_client):
172176
# Wait for health check
173177
max_wait = 120 # 2 minutes
174178
start_time = time.time()
175-
logger.info(f"Waiting for MySQL container {container_name} to become healthy (max {max_wait}s)")
179+
logger.info(
180+
f"Waiting for MySQL container {container_name} to become healthy (max {max_wait}s)"
181+
)
176182

177183
while time.time() - start_time < max_wait:
178184
container.reload()
@@ -182,15 +188,19 @@ def mysql_container(docker_client):
182188
break
183189
time.sleep(2)
184190
else:
185-
logger.error(f"MySQL container {container_name} failed to become healthy within {max_wait}s")
191+
logger.error(
192+
f"MySQL container {container_name} failed to become healthy within {max_wait}s"
193+
)
186194
container.remove(force=True)
187195
raise RuntimeError("MySQL container failed to become healthy")
188196

189197
# Get the mapped port
190198
port_info = container.attrs["NetworkSettings"]["Ports"]["3306/tcp"]
191199
if port_info:
192200
host_port = port_info[0]["HostPort"]
193-
logger.info(f"MySQL container {container_name} is healthy and accessible on localhost:{host_port}")
201+
logger.info(
202+
f"MySQL container {container_name} is healthy and accessible on localhost:{host_port}"
203+
)
194204
else:
195205
raise RuntimeError("Failed to get MySQL port mapping")
196206

@@ -223,14 +233,11 @@ def minio_container(docker_client):
223233
container = docker_client.containers.run(
224234
f"minio/minio:{minio_ver}",
225235
name=container_name,
226-
environment={
227-
"MINIO_ACCESS_KEY": "datajoint",
228-
"MINIO_SECRET_KEY": "datajoint"
229-
},
230-
command=['server', '--address', ':9000', '/data'],
236+
environment={"MINIO_ACCESS_KEY": "datajoint", "MINIO_SECRET_KEY": "datajoint"},
237+
command=["server", "--address", ":9000", "/data"],
231238
ports={"9000/tcp": None}, # Let Docker assign random port
232239
detach=True,
233-
remove=True
240+
remove=True,
234241
)
235242

236243
# Register container for cleanup
@@ -250,20 +257,26 @@ def minio_container(docker_client):
250257
minio_url = f"http://localhost:{host_port}"
251258
max_wait = 60
252259
start_time = time.time()
253-
logger.info(f"Waiting for MinIO container {container_name} to become ready (max {max_wait}s)")
260+
logger.info(
261+
f"Waiting for MinIO container {container_name} to become ready (max {max_wait}s)"
262+
)
254263

255264
while time.time() - start_time < max_wait:
256265
try:
257266
response = requests.get(f"{minio_url}/minio/health/live", timeout=5)
258267
if response.status_code == 200:
259-
logger.info(f"MinIO container {container_name} is ready and accessible at {minio_url}")
268+
logger.info(
269+
f"MinIO container {container_name} is ready and accessible at {minio_url}"
270+
)
260271
break
261272
except requests.exceptions.RequestException:
262273
logger.debug(f"MinIO container {container_name} not ready yet, retrying...")
263274
pass
264275
time.sleep(2)
265276
else:
266-
logger.error(f"MinIO container {container_name} failed to become ready within {max_wait}s")
277+
logger.error(
278+
f"MinIO container {container_name} failed to become ready within {max_wait}s"
279+
)
267280
container.remove(force=True)
268281
raise RuntimeError("MinIO container failed to become ready")
269282

@@ -336,7 +349,9 @@ def configure_datajoint_for_containers(mysql_container):
336349
os.environ["DJ_PORT"] = str(port)
337350

338351
# Verify the environment variables were set
339-
logger.info(f"🔧 Environment after setting: DJ_HOST={os.environ.get('DJ_HOST')}, DJ_PORT={os.environ.get('DJ_PORT')}")
352+
logger.info(
353+
f"🔧 Environment after setting: DJ_HOST={os.environ.get('DJ_HOST')}, DJ_PORT={os.environ.get('DJ_PORT')}"
354+
)
340355

341356
# Also update DataJoint's configuration directly for in-process connections
342357
dj.config["database.host"] = host

0 commit comments

Comments
 (0)