Skip to content

Commit

Permalink
Merge pull request #861 from jiridanek/jd_reduce_need_for_TESTCONTAIN…
Browse files Browse the repository at this point in the history
…ERS_DOCKER_SOCKET_OVERRIDE

NO-JIRA: chore(tests/containers): improve docker socket detection, reducing the need for `TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE`
  • Loading branch information
openshift-merge-bot[bot] authored Jan 24, 2025
2 parents 6628be4 + e87244e commit adbd066
Showing 1 changed file with 33 additions and 2 deletions.
35 changes: 33 additions & 2 deletions tests/containers/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

from typing import TYPE_CHECKING
import os
from typing import Iterable, TYPE_CHECKING

import testcontainers.core.config
import testcontainers.core.container
Expand All @@ -11,6 +12,9 @@
if TYPE_CHECKING:
from pytest import ExitCode, Session, Parser, Metafunc

SECURITY_OPTION_ROOTLESS = "name=rootless"
TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE = "TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE"

SHUTDOWN_RYUK = False

# NOTE: Configure Testcontainers through `testcontainers.core.config` and not through env variables.
Expand All @@ -26,11 +30,13 @@
testcontainers.core.config.testcontainers_config.ryuk_privileged = True


# https://docs.pytest.org/en/latest/reference/reference.html#pytest.hookspec.pytest_addoption
def pytest_addoption(parser: Parser) -> None:
parser.addoption("--image", action="append", default=[],
help="Image to use, can be specified multiple times")


# https://docs.pytest.org/en/latest/reference/reference.html#pytest.hookspec.pytest_generate_tests
def pytest_generate_tests(metafunc: Metafunc) -> None:
if image.__name__ in metafunc.fixturenames:
metafunc.parametrize(image.__name__, metafunc.config.getoption("--image"))
Expand All @@ -43,17 +49,42 @@ def image(request):
yield request.param


# https://docs.pytest.org/en/latest/reference/reference.html#pytest.hookspec.pytest_sessionstart
def pytest_sessionstart(session: Session) -> None:
# first preflight check: ping the Docker API
client = testcontainers.core.docker_client.DockerClient()
assert client.client.ping(), "Failed to connect to Docker"

# determine the local socket path
# NOTE: this will not work for remote docker, but we will cross the bridge when we come to it
socket_path = the_one(adapter.socket_path for adapter in client.client.api.adapters.values())

# set that socket path for ryuk's use, unless user overrode that
if TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE not in os.environ:
testcontainers.core.config.testcontainers_config.ryuk_docker_socket = socket_path

# second preflight check: start the Reaper container
assert testcontainers.core.container.Reaper.get_instance() is not None, "Failed to start Reaper container"
if not testcontainers.core.config.testcontainers_config.ryuk_disabled:
assert testcontainers.core.container.Reaper.get_instance() is not None, "Failed to start Reaper container"


# https://docs.pytest.org/en/latest/reference/reference.html#pytest.hookspec.pytest_sessionfinish
def pytest_sessionfinish(session: Session, exitstatus: int | ExitCode) -> None:
# resolves a shutdown resource leak warning that would be otherwise reported
if SHUTDOWN_RYUK:
testcontainers.core.container.Reaper.delete_instance()


# https://docs.python.org/3/library/functions.html#iter
def the_one[T](iterable: Iterable[T]) -> T:
"""Checks that there is exactly one element in the iterable, and returns it."""
it = iter(iterable)
try:
v = next(it)
except StopIteration:
raise ValueError("No elements in iterable")
try:
next(it)
except StopIteration:
return v
raise ValueError("More than one element in iterable")

0 comments on commit adbd066

Please sign in to comment.