Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ exclude: "^docs/conf.py"

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
rev: v6.0.0
hooks:
- id: trailing-whitespace
- id: check-added-large-files
Expand All @@ -19,7 +19,7 @@ repos:

# Ruff replaces black, flake8, autoflake and isort
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: "v0.11.11" # make sure this is always consistent with hatch configs
rev: "v0.13.3" # make sure this is always consistent with hatch configs
hooks:
- id: ruff
args: [--config, ./pyproject.toml]
Expand Down
26 changes: 21 additions & 5 deletions src/pytest_databases/_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@

import filelock
import pytest
from docker import DockerClient
from docker.errors import APIError, ImageNotFound
from typing_extensions import Self

from docker import DockerClient
from pytest_databases.helpers import get_xdist_worker_id
from pytest_databases.types import ServiceContainer

Expand Down Expand Up @@ -139,6 +139,7 @@ def run(
shm_size: int | None = None,
mem_limit: str | None = None,
platform: str | None = None,
protocol: str = "tcp",
) -> Generator[ServiceContainer, None, None]:
if check is None and wait_for_log is None:
msg = "Must set at least check or wait_for_log"
Expand Down Expand Up @@ -176,17 +177,32 @@ def run(
# spins it up and the metadata becomes available, so we're redoing the
# check with a small incremental backup here
for i in range(10):
container.reload()
if any(v for v in container.ports.values()):
break
container.reload()
time.sleep(0.1 + (i / 10))
else:
msg = f"Service {name!r} failed to create container"
raise ValueError(msg)

host_port = int(
container.ports[next(k for k in container.ports if k.startswith(str(container_port)))][0]["HostPort"]
)
# Get port binding based on protocol configuration
binding = None
if protocol == "both":
binding = container.ports.get(f"{container_port}/tcp") or container.ports.get(f"{container_port}/udp")
elif protocol in {"tcp", "udp"}:
binding = container.ports.get(f"{container_port}/{protocol}")
else:
msg = f"Invalid protocol '{protocol}'. Must be 'tcp', 'udp', or 'both'."
raise ValueError(msg)

if not binding:
msg = (
f"Container port {container_port}/{protocol} not found in exposed ports. "
f"Available ports: {list(container.ports.keys())}"
)
raise RuntimeError(msg)

host_port = int(binding[0]["HostPort"])
service = ServiceContainer(
host=container_host,
port=host_port,
Expand Down
4 changes: 2 additions & 2 deletions tests/test_redis.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ def test_two({redis_compatible_service}: RedisService) -> None:
assert not client.get("one")
client.set("one", "1")
assert client.get("one") == b"1"


def test_use_same_db({redis_compatible_service}: RedisService) -> None:
client_0 = redis.Redis(host={redis_compatible_service}.host, port={redis_compatible_service}.port, db=0)
client_1 = redis.Redis(host={redis_compatible_service}.host, port={redis_compatible_service}.port, db=1)
Expand Down
Loading
Loading