Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ContainerLauncher/PodLauncher.from_pytestconfig "constructors" #222

Merged
merged 2 commits into from
Aug 23, 2024
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
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