Skip to content

Commit

Permalink
Merge pull request #222 from dcermak/from_pytestconfig-helper
Browse files Browse the repository at this point in the history
Add ContainerLauncher/PodLauncher.from_pytestconfig "constructors"
  • Loading branch information
dcermak authored Aug 23, 2024
2 parents 3216b4e + bc4dfcd commit 92c1a63
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 46 deletions.
19 changes: 19 additions & 0 deletions pytest_container/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@
import testinfra
from filelock import BaseFileLock
from filelock import FileLock
from pytest import Config
from pytest import param
from pytest_container.helpers import get_always_pull_option
from pytest_container.helpers import get_extra_build_args
from pytest_container.helpers import get_extra_run_args
from pytest_container.inspect import ContainerHealth
from pytest_container.inspect import ContainerInspect
from pytest_container.inspect import PortForwarding
Expand Down Expand Up @@ -1046,6 +1049,22 @@ class ContainerLauncher:
default_factory=lambda: join(tempfile.gettempdir(), str(uuid4()))
)

@staticmethod
def from_pytestconfig(
container: Union[Container, DerivedContainer],
container_runtime: OciRuntimeBase,
pytestconfig: Config,
container_name: str = "",
) -> "ContainerLauncher":
return ContainerLauncher(
container=container,
container_runtime=container_runtime,
rootdir=pytestconfig.rootpath,
extra_build_args=get_extra_build_args(pytestconfig),
extra_run_args=get_extra_run_args(pytestconfig),
container_name=container_name,
)

def __enter__(self) -> "ContainerLauncher":
return self

Expand Down
32 changes: 3 additions & 29 deletions pytest_container/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@
from pytest_container.container import container_and_marks_from_pytest_param
from pytest_container.container import ContainerData
from pytest_container.container import ContainerLauncher
from pytest_container.helpers import get_extra_build_args
from pytest_container.helpers import get_extra_pod_create_args
from pytest_container.helpers import get_extra_run_args
from pytest_container.logging import _logger
from pytest_container.pod import pod_from_pytest_param
from pytest_container.pod import PodData
Expand Down Expand Up @@ -91,27 +88,10 @@ def fixture_funct(
f"A singleton container ({container}) cannot be used in a session level fixture"
)

add_labels = [
"--label",
f"pytest_container.request={request}",
"--label",
f"pytest_container.node.name={request.node.name}",
"--label",
f"pytest_container.scope={request.scope}",
]
try:
add_labels.extend(
["--label", f"pytest_container.path={request.path}"]
)
except AttributeError:
pass

with ContainerLauncher(
with ContainerLauncher.from_pytestconfig(
container=container,
container_runtime=container_runtime,
rootdir=pytestconfig.rootpath,
extra_build_args=get_extra_build_args(pytestconfig),
extra_run_args=get_extra_run_args(pytestconfig) + add_labels,
pytestconfig=pytestconfig,
) as launcher:
# we want to ensure that the container's logs are saved at "all
# cost", especially when the container fails to launch for some
Expand Down Expand Up @@ -146,13 +126,7 @@ def fixture_funct(
skip("Pods are only supported in podman")

pod = pod_from_pytest_param(request.param)
with PodLauncher(
pod,
rootdir=pytestconfig.rootpath,
extra_build_args=get_extra_build_args(pytestconfig),
extra_run_args=get_extra_run_args(pytestconfig),
extra_pod_create_args=get_extra_pod_create_args(pytestconfig),
) as launcher:
with PodLauncher.from_pytestconfig(pod, pytestconfig) as launcher:
try:
launcher.launch_pod()
pod_data = launcher.pod_data
Expand Down
17 changes: 17 additions & 0 deletions pytest_container/pod.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@
from typing import Union

from _pytest.mark import ParameterSet
from pytest import Config
from pytest_container.container import Container
from pytest_container.container import ContainerData
from pytest_container.container import ContainerLauncher
from pytest_container.container import create_host_port_port_forward
from pytest_container.container import DerivedContainer
from pytest_container.container import lock_host_port_search
from pytest_container.helpers import get_extra_build_args
from pytest_container.helpers import get_extra_pod_create_args
from pytest_container.helpers import get_extra_run_args
from pytest_container.inspect import PortForwarding
from pytest_container.logging import _logger
from pytest_container.runtime import get_selected_runtime
Expand Down Expand Up @@ -128,6 +132,19 @@ class PodLauncher:

_stack: contextlib.ExitStack = field(default_factory=contextlib.ExitStack)

@staticmethod
def from_pytestconfig(
pod: Pod, pytestconfig: Config, pod_name: str = ""
) -> "PodLauncher":
return PodLauncher(
pod,
pytestconfig.rootpath,
extra_build_args=get_extra_build_args(pytestconfig),
extra_run_args=get_extra_run_args(pytestconfig),
extra_pod_create_args=get_extra_pod_create_args(pytestconfig),
pod_name=pod_name,
)

def __enter__(self) -> "PodLauncher":
runtime = get_selected_runtime()
if runtime != PodmanRuntime():
Expand Down
24 changes: 12 additions & 12 deletions tests/test_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ def test_launcher_creates_and_cleanes_up_volumes(
pytestconfig: pytest.Config,
container_runtime: OciRuntimeBase,
) -> None:
with ContainerLauncher(
cont, container_runtime, pytestconfig.rootpath
with ContainerLauncher.from_pytestconfig(
cont, container_runtime, pytestconfig
) as launcher:
launcher.launch_container()

Expand Down Expand Up @@ -130,8 +130,8 @@ def test_launcher_cleanes_up_volumes_from_image(
container_runtime: OciRuntimeBase,
host: Any,
) -> None:
with ContainerLauncher(
cont, container_runtime, pytestconfig.rootpath
with ContainerLauncher.from_pytestconfig(
cont, container_runtime, pytestconfig
) as launcher:
launcher.launch_container()

Expand All @@ -158,8 +158,8 @@ def test_launcher_cleanes_up_volumes_from_image(
def test_launcher_container_data_not_available_after_exit(
container_runtime: OciRuntimeBase, pytestconfig: pytest.Config
) -> None:
with ContainerLauncher(
LEAP, container_runtime, pytestconfig.rootpath
with ContainerLauncher.from_pytestconfig(
LEAP, container_runtime, pytestconfig
) as launcher:
launcher.launch_container()
assert launcher.container_data
Expand All @@ -175,10 +175,10 @@ def test_launcher_fails_on_failing_healthcheck(
):
container_name = "container_with_failing_healthcheck"
with pytest.raises(RuntimeError) as runtime_err_ctx:
with ContainerLauncher(
with ContainerLauncher.from_pytestconfig(
container=CONTAINER_THAT_FAILS_TO_LAUNCH,
container_runtime=container_runtime,
rootdir=pytestconfig.rootpath,
pytestconfig=pytestconfig,
container_name=container_name,
) as launcher:
launcher.launch_container()
Expand Down Expand Up @@ -252,8 +252,8 @@ def test_derived_container_pulls_base(
host.run(f"{container_runtime.runner_binary} rmi {registry_url}")

reg = DerivedContainer(base=registry_url)
with ContainerLauncher(
reg, container_runtime, pytestconfig.rootpath
with ContainerLauncher.from_pytestconfig(
reg, container_runtime, pytestconfig
) as launcher:
launcher.launch_container()
assert launcher.container_data.container_id
Expand Down Expand Up @@ -333,10 +333,10 @@ def test_launcher_unlocks_on_preparation_failure(

def try_launch():
with pytest.raises(subprocess.CalledProcessError):
with ContainerLauncher(
with ContainerLauncher.from_pytestconfig(
container_with_wrong_url,
container_runtime,
pytestconfig.rootpath,
pytestconfig,
) as launcher:
launcher.launch_container()
assert False, "The container must not have launched"
Expand Down
10 changes: 6 additions & 4 deletions tests/test_pod.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ def test_pod_launcher_pod_data_not_ready(
if container_runtime != PodmanRuntime():
pytest.skip("pods only work with podman")

with PodLauncher(pod=TEST_POD, rootdir=pytestconfig.rootpath) as launcher:
with PodLauncher.from_pytestconfig(
pod=TEST_POD, pytestconfig=pytestconfig
) as launcher:
with pytest.raises(RuntimeError) as rt_err_ctx:
_ = launcher.pod_data

Expand All @@ -97,9 +99,9 @@ def test_pod_launcher_cleanup(
name = "i_will_fail_to_launch"

with pytest.raises(RuntimeError) as rt_err_ctx:
with PodLauncher(
with PodLauncher.from_pytestconfig(
pod=Pod(containers=[LEAP, CONTAINER_THAT_FAILS_TO_LAUNCH]),
rootdir=pytestconfig.rootpath,
pytestconfig=pytestconfig,
pod_name=name,
) as launcher:
launcher.launch_pod()
Expand All @@ -121,7 +123,7 @@ def test_pod_launcher_fails_with_non_podman(
pytest.skip("pods work with podman")

with pytest.raises(RuntimeError) as rt_err_ctx:
with PodLauncher(pod=TEST_POD, rootdir=Path("/")) as _:
with PodLauncher(pod=TEST_POD, rootdir=Path("/tmp")) as _:
pass

assert "pods can only be created with podman" in str(rt_err_ctx.value)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_port_forwarding.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ def test_pod_bind_to_host_port(
],
)

with PodLauncher(pod=pod, rootdir=pytestconfig.rootpath) as launcher:
with PodLauncher.from_pytestconfig(pod, pytestconfig) as launcher:
launcher.launch_pod()

assert launcher.pod_data.forwarded_ports[0].host_port == PORT
Expand Down

0 comments on commit 92c1a63

Please sign in to comment.