From 26302ead24182554cd794f0c9f80e487cb7fa290 Mon Sep 17 00:00:00 2001 From: Lewis Gaul Date: Mon, 15 Jan 2024 17:15:19 +0000 Subject: [PATCH] Move most of the remaining tests to use docker_client or ctr_client fixture (#535) --- .../components/test_config.py | 38 ++--- .../components/test_context.py | 40 ++--- .../components/test_manifest.py | 45 +++--- .../python_on_whales/components/test_node.py | 30 ++-- .../components/test_plugin.py | 22 +-- .../components/test_service.py | 107 +++++++------ .../python_on_whales/components/test_stack.py | 78 +++++----- .../python_on_whales/components/test_swarm.py | 46 +++--- .../components/test_system.py | 142 +++++++++++------- 9 files changed, 298 insertions(+), 250 deletions(-) diff --git a/tests/python_on_whales/components/test_config.py b/tests/python_on_whales/components/test_config.py index a133f945..547f6c0f 100644 --- a/tests/python_on_whales/components/test_config.py +++ b/tests/python_on_whales/components/test_config.py @@ -1,41 +1,45 @@ +from pathlib import Path + import pytest -from python_on_whales import docker +from python_on_whales import DockerClient @pytest.mark.usefixtures("swarm_mode") -def test_list_configs(): - assert docker.config.list() == [] +def test_list_configs(docker_client: DockerClient): + assert docker_client.config.list() == [] @pytest.mark.usefixtures("swarm_mode") -def test_create_delete_config(tmp_path): +def test_create_delete_config(docker_client: DockerClient, tmp_path: Path): config_file = tmp_path / "config.conf" config_file.write_text("hello world") - my_conf = docker.config.create("my_conf", config_file) + my_conf = docker_client.config.create("my_conf", config_file) with my_conf: assert my_conf.spec.name == "my_conf" - assert docker.config.list() == [my_conf] - assert docker.config.inspect("my_conf") == my_conf - repr(docker.config.list()) + assert docker_client.config.list() == [my_conf] + assert docker_client.config.inspect("my_conf") == my_conf + repr(docker_client.config.list()) @pytest.mark.usefixtures("swarm_mode") -def test_labels_config(tmp_path): +def test_labels_config(docker_client: DockerClient, tmp_path: Path): config_file = tmp_path / "config.conf" config_file.write_text("hello world") - my_conf = docker.config.create("my_conf", config_file, labels=dict(dodo="dada")) + my_conf = docker_client.config.create( + "my_conf", config_file, labels=dict(dodo="dada") + ) with my_conf: assert my_conf.spec.name == "my_conf" - assert docker.config.list(filters=dict(label="dodo=dada")) == [my_conf] - assert docker.config.list(filters=dict(label="dodo=dadu")) == [] + assert docker_client.config.list(filters=dict(label="dodo=dada")) == [my_conf] + assert docker_client.config.list(filters=dict(label="dodo=dadu")) == [] @pytest.mark.usefixtures("swarm_mode") -def test_remove_empty_config_list(tmp_path): +def test_remove_empty_config_list(docker_client: DockerClient, tmp_path: Path): config_file = tmp_path / "config.conf" config_file.write_text("hello world") - with docker.config.create("my_conf", config_file) as my_conf: - assert docker.config.list() == [my_conf] - docker.config.remove([]) - assert docker.config.list() == [my_conf] + with docker_client.config.create("my_conf", config_file) as my_conf: + assert docker_client.config.list() == [my_conf] + docker_client.config.remove([]) + assert docker_client.config.list() == [my_conf] diff --git a/tests/python_on_whales/components/test_context.py b/tests/python_on_whales/components/test_context.py index 0160885d..7e9aec4a 100644 --- a/tests/python_on_whales/components/test_context.py +++ b/tests/python_on_whales/components/test_context.py @@ -2,7 +2,7 @@ import pytest -from python_on_whales import docker +from python_on_whales import DockerClient from python_on_whales.components.context.models import ContextInspectResult from python_on_whales.test_utils import get_all_jsons @@ -14,13 +14,13 @@ def test_load_json(json_file): # we could do more checks here if needed -def test_create_context(): +def test_create_context(docker_client: DockerClient): testname = "testpow" host = "ssh://test@test.domain" description = "Python on whales testing context" - all_contexts_before = set(docker.context.list()) - with docker.context.create( + all_contexts_before = set(docker_client.context.list()) + with docker_client.context.create( testname, docker=dict(host=host), description=description ) as new_context: assert new_context.name == testname @@ -29,30 +29,32 @@ def test_create_context(): assert new_context not in all_contexts_before - assert new_context in docker.context.list() + assert new_context in docker_client.context.list() -def test_inpect(): - default_context = docker.context.inspect() +def test_inpect(docker_client: DockerClient): + default_context = docker_client.context.inspect() assert default_context.name == "default" - assert default_context == docker.context.inspect("default") - a, b = docker.context.inspect(["default", "default"]) + assert default_context == docker_client.context.inspect("default") + a, b = docker_client.context.inspect(["default", "default"]) assert a == b -def test_list_contexts(): - assert docker.context.list() == [docker.context.inspect("default")] +def test_list_contexts(docker_client: DockerClient): + assert docker_client.context.list() == [docker_client.context.inspect("default")] -def test_use_context(): - docker.context.use("default") +def test_use_context(docker_client: DockerClient): + docker_client.context.use("default") -def test_use_context_returns(): - assert docker.context.use("default") == docker.context.inspect("default") +def test_use_context_returns(docker_client: DockerClient): + assert docker_client.context.use("default") == docker_client.context.inspect( + "default" + ) -def test_remove_empty_context_list(): - all_contexts = set(docker.context.list()) - docker.context.remove([]) - assert all_contexts == set(docker.context.list()) +def test_remove_empty_context_list(docker_client: DockerClient): + all_contexts = set(docker_client.context.list()) + docker_client.context.remove([]) + assert all_contexts == set(docker_client.context.list()) diff --git a/tests/python_on_whales/components/test_manifest.py b/tests/python_on_whales/components/test_manifest.py index f168c98e..fca1f9cc 100644 --- a/tests/python_on_whales/components/test_manifest.py +++ b/tests/python_on_whales/components/test_manifest.py @@ -1,9 +1,10 @@ import json import os +from typing import Generator import pytest -from python_on_whales import docker +from python_on_whales import DockerClient, Image from python_on_whales.components.manifest.cli_wrapper import ( ManifestList, ManifestListInspectResult, @@ -12,26 +13,30 @@ @pytest.fixture -def with_manifest(): +def manifest(docker_client: DockerClient) -> Generator[ManifestList, None, None]: manifest_name = random_name() # utilizing old, pre-manifest-list images images = ["busybox:1.26", "busybox:1.27.1"] - docker.image.pull(images) - with docker.manifest.create(manifest_name, images) as my_manifest: + docker_client.image.pull(images) + with docker_client.manifest.create(manifest_name, images) as my_manifest: yield my_manifest - docker.image.remove(images) + docker_client.image.remove(images) @pytest.fixture -def with_platform_variant_manifest(request): +def platform_variant_manifest( + docker_client: DockerClient, request: pytest.FixtureRequest +) -> Image: image_with_platform_variant = "arm32v7/busybox:1.35" def remove_docker_image(): - docker.image.remove(image_with_platform_variant) + docker_client.image.remove(image_with_platform_variant) request.addfinalizer(remove_docker_image) - docker.image.pull(image_with_platform_variant, quiet=True, platform="linux/arm/v7") - return docker.image.inspect(image_with_platform_variant) + docker_client.image.pull( + image_with_platform_variant, quiet=True, platform="linux/arm/v7" + ) + return docker_client.image.inspect(image_with_platform_variant) @pytest.mark.parametrize("json_file", get_all_jsons("manifests")) @@ -45,23 +50,23 @@ def test_load_json(json_file): os.environ.get("CI", "false") == "true", reason="The creation of manifest doesn't work in github actions for some reason", ) -def test_manifest_create_remove(with_manifest): - assert isinstance(with_manifest, ManifestList) +def test_manifest_create_remove(docker_client: DockerClient, manifest: ManifestList): + assert isinstance(manifest, ManifestList) @pytest.mark.skipif( os.environ.get("CI", "false") == "true", reason="The creation of manifest doesn't work in github actions for some reason", ) -def test_manifest_annotate(with_manifest): - docker.manifest.annotate( - with_manifest.name, "busybox:1.26", os="linux", arch="arm64" +def test_manifest_annotate(docker_client: DockerClient, manifest: ManifestList): + docker_client.manifest.annotate( + manifest.name, "busybox:1.26", os="linux", arch="arm64" ) - assert with_manifest.manifests[0].platform.os == "linux" - assert with_manifest.manifests[0].platform.architecture == "arm64" + assert manifest.manifests[0].platform.os == "linux" + assert manifest.manifests[0].platform.architecture == "arm64" -def test_manifest_platform_variant(with_platform_variant_manifest): - assert "linux" in repr(with_platform_variant_manifest.os) - assert "arm" in repr(with_platform_variant_manifest.architecture) - assert "v7" in repr(with_platform_variant_manifest.variant) +def test_manifest_platform_variant(platform_variant_manifest: Image): + assert "linux" in repr(platform_variant_manifest.os) + assert "arm" in repr(platform_variant_manifest.architecture) + assert "v7" in repr(platform_variant_manifest.variant) diff --git a/tests/python_on_whales/components/test_node.py b/tests/python_on_whales/components/test_node.py index b90d5c19..95a3de83 100644 --- a/tests/python_on_whales/components/test_node.py +++ b/tests/python_on_whales/components/test_node.py @@ -2,7 +2,7 @@ import pytest -from python_on_whales import docker +from python_on_whales import DockerClient from python_on_whales.components.node.models import NodeInspectResult from python_on_whales.test_utils import get_all_jsons @@ -24,40 +24,40 @@ def test_load_json(json_file): @pytest.mark.usefixtures("swarm_mode") -def test_list_nodes(): - nodes = docker.node.list() +def test_list_nodes(docker_client: DockerClient): + nodes = docker_client.node.list() assert nodes[0].id[:12] in repr(nodes) assert len(nodes) == 1 @pytest.mark.usefixtures("swarm_mode") -def test_add_label(): - nodes = docker.node.list() +def test_add_label(docker_client: DockerClient): + nodes = docker_client.node.list() nodes[0].update(labels_add={"foo": "bar"}) assert nodes[0].spec.labels["foo"] == "bar" @pytest.mark.usefixtures("swarm_mode") -def test_remove_label(): - nodes = docker.node.list() +def test_remove_label(docker_client: DockerClient): + nodes = docker_client.node.list() nodes[0].update(labels_add={"foo": "bar"}) nodes[0].update(rm_labels=["foo"]) assert "foo" not in nodes[0].spec.labels @pytest.mark.usefixtures("swarm_mode") -def test_tasks(): - service = docker.service.create("busybox", ["sleep", "infinity"]) +def test_tasks(docker_client: DockerClient): + service = docker_client.service.create("busybox", ["sleep", "infinity"]) - current_node = docker.node.list()[0] + current_node = docker_client.node.list()[0] tasks = current_node.ps() assert len(tasks) > 0 assert tasks[0].desired_state == "running" - docker.service.remove(service) + docker_client.service.remove(service) @pytest.mark.usefixtures("swarm_mode") -def test_list_tasks_node(): - with docker.service.create("busybox", ["sleep", "infinity"]) as my_service: - assert docker.node.ps([]) == [] - assert set(docker.node.ps()) == set(docker.service.ps(my_service)) +def test_list_tasks_node(docker_client: DockerClient): + with docker_client.service.create("busybox", ["sleep", "infinity"]) as my_service: + assert docker_client.node.ps([]) == [] + assert set(docker_client.node.ps()) == set(docker_client.service.ps(my_service)) diff --git a/tests/python_on_whales/components/test_plugin.py b/tests/python_on_whales/components/test_plugin.py index 7d6ba86b..1845d660 100644 --- a/tests/python_on_whales/components/test_plugin.py +++ b/tests/python_on_whales/components/test_plugin.py @@ -4,7 +4,7 @@ import pytest -from python_on_whales import docker +from python_on_whales import DockerClient from python_on_whales.components.plugin.models import PluginInspectResult from python_on_whales.test_utils import get_all_jsons @@ -23,23 +23,23 @@ def test_load_json(json_file): # we could do more checks here if needed -def test_install_plugin_disable_enable(): - with docker.plugin.install(test_plugin_name) as my_plugin: +def test_install_plugin_disable_enable(docker_client: DockerClient): + with docker_client.plugin.install(test_plugin_name) as my_plugin: my_plugin.disable() my_plugin.enable() - assert my_plugin in docker.plugin.list() + assert my_plugin in docker_client.plugin.list() assert "name='vieux/sshfs:latest'" in repr(my_plugin) -def test_plugin_upgrade(): - with docker.plugin.install(test_plugin_name) as my_plugin: +def test_plugin_upgrade(docker_client: DockerClient): + with docker_client.plugin.install(test_plugin_name) as my_plugin: my_plugin.disable() my_plugin.upgrade() -def test_remove_empty_plugin_list(): - with docker.plugin.install(test_plugin_name) as my_plugin: - plugins_set = set(docker.plugin.list()) +def test_remove_empty_plugin_list(docker_client: DockerClient): + with docker_client.plugin.install(test_plugin_name) as my_plugin: + plugins_set = set(docker_client.plugin.list()) assert my_plugin in plugins_set - docker.plugin.remove([]) - assert set(docker.plugin.list()) == plugins_set + docker_client.plugin.remove([]) + assert set(docker_client.plugin.list()) == plugins_set diff --git a/tests/python_on_whales/components/test_service.py b/tests/python_on_whales/components/test_service.py index 672be9c0..4f926d1b 100644 --- a/tests/python_on_whales/components/test_service.py +++ b/tests/python_on_whales/components/test_service.py @@ -4,7 +4,7 @@ import pytest -from python_on_whales import docker +from python_on_whales import DockerClient from python_on_whales.components.service.models import ServiceInspectResult from python_on_whales.exceptions import NoSuchService, NotASwarmManager from python_on_whales.test_utils import get_all_jsons @@ -18,52 +18,52 @@ def test_load_json(json_file): @pytest.mark.usefixtures("swarm_mode") -def test_tasks(): - service = docker.service.create("busybox", ["sleep", "infinity"]) +def test_tasks(docker_client: DockerClient): + service = docker_client.service.create("busybox", ["sleep", "infinity"]) tasks = service.ps() assert len(tasks) > 0 assert tasks[0].desired_state == "running" - docker.service.remove(service) + docker_client.service.remove(service) @pytest.mark.usefixtures("swarm_mode") -def test_get_logs(): - with docker.service.create( +def test_get_logs(docker_client: DockerClient): + with docker_client.service.create( "busybox", ["sh", "-c", "echo dodo && sleep infinity"] ) as my_service: assert my_service.ps()[0].desired_state == "running" - assert docker.service.logs(my_service).split("|")[-1].strip() == "dodo" + assert docker_client.service.logs(my_service).split("|")[-1].strip() == "dodo" @pytest.mark.usefixtures("swarm_mode") -def test_get_list_of_services(): - with docker.service.create( +def test_get_list_of_services(docker_client: DockerClient): + with docker_client.service.create( "busybox", ["sh", "-c", "echo dodo && sleep infinity"] ) as my_service: - list_of_services = docker.service.list() + list_of_services = docker_client.service.list() assert [my_service] == list_of_services @pytest.mark.usefixtures("swarm_mode") -def test_get_list_of_services_no_services(): - assert docker.service.list() == [] +def test_get_list_of_services_no_services(docker_client: DockerClient): + assert docker_client.service.list() == [] @pytest.mark.usefixtures("swarm_mode") -def test_remove_empty_services_list(): - with docker.service.create( +def test_remove_empty_services_list(docker_client: DockerClient): + with docker_client.service.create( "busybox", ["sh", "-c", "echo dodo && sleep infinity"] ) as my_service: - assert my_service in docker.service.list() - set_services = set(docker.service.list()) - docker.service.remove([]) - assert set(docker.service.list()) == set_services + assert my_service in docker_client.service.list() + set_services = set(docker_client.service.list()) + docker_client.service.remove([]) + assert set(docker_client.service.list()) == set_services @pytest.mark.usefixtures("swarm_mode") -def test_service_scale(): - service = docker.service.create("busybox", ["sleep", "infinity"]) +def test_service_scale(docker_client: DockerClient): + service = docker_client.service.create("busybox", ["sleep", "infinity"]) service.scale(3) time.sleep(0.4) assert service.spec.mode["Replicated"] == {"Replicas": 3} @@ -73,9 +73,11 @@ def test_service_scale(): @pytest.mark.usefixtures("swarm_mode") -def test_context_manager(): +def test_context_manager(docker_client: DockerClient): with pytest.raises(RuntimeError): - with docker.service.create("busybox", ["sleep", "infinity"]) as my_service: + with docker_client.service.create( + "busybox", ["sleep", "infinity"] + ) as my_service: assert my_service.spec.task_template.container_spec.image.startswith( "busybox" ) @@ -86,8 +88,8 @@ def test_context_manager(): @pytest.mark.usefixtures("swarm_mode") -def test_service_restart(): - my_service = docker.service.create( +def test_service_restart(docker_client: DockerClient): + my_service = docker_client.service.create( "busybox", ["echo", "Hello"], detach=True, @@ -100,19 +102,19 @@ def test_service_restart(): @pytest.mark.usefixtures("swarm_mode") -def test_service_secrets(): +def test_service_secrets(docker_client: DockerClient): secret_user = None secret_pass = None with tempfile.NamedTemporaryFile() as f: f.write(b"supersecretuser") f.seek(0) - secret_user = docker.secret.create("dbuser", f.name) + secret_user = docker_client.secret.create("dbuser", f.name) with tempfile.NamedTemporaryFile() as f: f.write(b"supersecretpass") f.seek(0) - secret_pass = docker.secret.create("dbpass", f.name) + secret_pass = docker_client.secret.create("dbpass", f.name) - with docker.service.create( + with docker_client.service.create( "ubuntu", ["bash", "-c", "cat /run/secrets/{dbuser,dbpass} && sleep infinity"], secrets=[ @@ -134,11 +136,11 @@ def test_service_secrets(): @pytest.mark.usefixtures("swarm_mode") -def test_service_mounts(): +def test_service_mounts(docker_client: DockerClient): with tempfile.NamedTemporaryFile() as f: f.write(b"config") f.seek(0) - with docker.service.create( + with docker_client.service.create( "ubuntu", ["bash", "-c", f"cat {f.name} && sleep infinity"], mounts=[ @@ -152,73 +154,70 @@ def test_service_mounts(): assert my_service.ps()[0].desired_state == "running" -@pytest.mark.parametrize( - "docker_function", - [docker.service.inspect, docker.service.remove, docker.service.ps], -) +@pytest.mark.parametrize("method", ["inspect", "remove", "ps"]) @pytest.mark.usefixtures("swarm_mode") -def test_some_functions_no_such_service(docker_function): +def test_some_functions_no_such_service(docker_client: DockerClient, method: str): with pytest.raises(NoSuchService): - docker_function("DOODODGOIHURHURI") + getattr(docker_client.service, method)("DOODODGOIHURHURI") @pytest.mark.usefixtures("swarm_mode") -def test_scale_no_such_service(): +def test_scale_no_such_service(docker_client: DockerClient): with pytest.raises(NoSuchService): - docker.service.scale({"DOODODGOIHURHURI": 14}) + docker_client.service.scale({"DOODODGOIHURHURI": 14}) -def test_create_not_swarm_manager(): +def test_create_not_swarm_manager(docker_client: DockerClient): with pytest.raises(NotASwarmManager) as e: - docker.service.create("busybox", ["sleep", "infinity"]) + docker_client.service.create("busybox", ["sleep", "infinity"]) assert "not a swarm manager" in str(e.value).lower() -def test_inspect_not_swarm_manager(): +def test_inspect_not_swarm_manager(docker_client: DockerClient): with pytest.raises(NotASwarmManager) as e: - docker.service.inspect("dodo") + docker_client.service.inspect("dodo") assert "not a swarm manager" in str(e.value).lower() -def test_exists_not_swarm_manager(): +def test_exists_not_swarm_manager(docker_client: DockerClient): with pytest.raises(NotASwarmManager) as e: - docker.service.exists("dodo") + docker_client.service.exists("dodo") assert "not a swarm manager" in str(e.value).lower() -def test_list_not_swarm_manager(): +def test_list_not_swarm_manager(docker_client: DockerClient): with pytest.raises(NotASwarmManager) as e: - docker.service.list() + docker_client.service.list() assert "not a swarm manager" in str(e.value).lower() -def test_ps_not_swarm_manager(): +def test_ps_not_swarm_manager(docker_client: DockerClient): with pytest.raises(NotASwarmManager) as e: - docker.service.ps("dodo") + docker_client.service.ps("dodo") assert "not a swarm manager" in str(e.value).lower() -def test_remove_not_swarm_manager(): +def test_remove_not_swarm_manager(docker_client: DockerClient): with pytest.raises(NotASwarmManager) as e: - docker.service.remove("dodo") + docker_client.service.remove("dodo") assert "not a swarm manager" in str(e.value).lower() -def test_scale_not_swarm_manager(): +def test_scale_not_swarm_manager(docker_client: DockerClient): with pytest.raises(NotASwarmManager) as e: - docker.service.scale({"dodo": 8}) + docker_client.service.scale({"dodo": 8}) assert "not a swarm manager" in str(e.value).lower() -def test_update_not_swarm_manager(): +def test_update_not_swarm_manager(docker_client: DockerClient): with pytest.raises(NotASwarmManager) as e: - docker.service.update("dodo", image="busybox") + docker_client.service.update("dodo", image="busybox") assert "not a swarm manager" in str(e.value).lower() diff --git a/tests/python_on_whales/components/test_stack.py b/tests/python_on_whales/components/test_stack.py index 536ed07a..09d85645 100644 --- a/tests/python_on_whales/components/test_stack.py +++ b/tests/python_on_whales/components/test_stack.py @@ -1,17 +1,21 @@ import time from pathlib import Path +from typing import Generator import pytest -from python_on_whales import docker +from python_on_whales import DockerClient +from python_on_whales.components.stack.cli_wrapper import Stack from python_on_whales.exceptions import NotASwarmManager from python_on_whales.utils import PROJECT_ROOT @pytest.fixture -def with_test_stack(swarm_mode): +def stack( + docker_client: DockerClient, swarm_mode: None +) -> Generator[Stack, None, None]: time.sleep(1) - some_stack = docker.stack.deploy( + some_stack = docker_client.stack.deploy( "some_stack", [PROJECT_ROOT / "tests/python_on_whales/components/test-stack-file.yml"], ) @@ -21,29 +25,29 @@ def with_test_stack(swarm_mode): time.sleep(1) -@pytest.mark.usefixtures("with_test_stack") -def test_services_inspect(): - all_services = docker.service.list() +@pytest.mark.usefixtures("stack") +def test_services_inspect(docker_client: DockerClient): + all_services = docker_client.service.list() assert len(all_services) == 4 - assert set(all_services) == set(docker.stack.services("some_stack")) - assert "name='some_stack'" in repr(docker.stack.list()) + assert set(all_services) == set(docker_client.stack.services("some_stack")) + assert "name='some_stack'" in repr(docker_client.stack.list()) -@pytest.mark.usefixtures("with_test_stack") -def test_remove_empty_stack_list(): - docker.stack.remove([]) - assert docker.stack.list() != [] +@pytest.mark.usefixtures("stack") +def test_remove_empty_stack_list(docker_client: DockerClient): + docker_client.stack.remove([]) + assert docker_client.stack.list() != [] -def test_stack_ps_and_services(with_test_stack): - all_services = docker.service.list() +def test_stack_ps_and_services(docker_client: DockerClient, stack: Stack): + all_services = docker_client.service.list() - assert set(all_services) == set(with_test_stack.services()) + assert set(all_services) == set(stack.services()) - stack_tasks = set(docker.stack.ps("some_stack")) - assert stack_tasks == set(with_test_stack.ps()) + stack_tasks = set(docker_client.stack.ps("some_stack")) + assert stack_tasks == set(stack.ps()) - services_tasks = set(docker.service.ps(all_services)) + services_tasks = set(docker_client.service.ps(all_services)) assert stack_tasks == services_tasks assert len(stack_tasks) > 0 for task in stack_tasks: @@ -51,44 +55,44 @@ def test_stack_ps_and_services(with_test_stack): @pytest.mark.usefixtures("swarm_mode") -def test_stack_variables(): - docker.stack.deploy( +def test_stack_variables(docker_client: DockerClient): + docker_client.stack.deploy( "other_stack", [PROJECT_ROOT / "tests/python_on_whales/components/test-stack-file.yml"], variables={"SOME_VARIABLE": "hello-world"}, ) - agent_service = docker.service.inspect("other_stack_agent") + agent_service = docker_client.service.inspect("other_stack_agent") expected = "SOME_OTHER_VARIABLE=hello-world" assert expected in agent_service.spec.task_template.container_spec.env - docker.stack.remove("other_stack") + docker_client.stack.remove("other_stack") time.sleep(1) @pytest.mark.usefixtures("swarm_mode") -def test_stack_env_files(tmp_path: Path): +def test_stack_env_files(docker_client: DockerClient, tmp_path: Path): env_file = tmp_path / "some.env" env_file.write_text('SOME_VARIABLE="--tls=true" # some var \n # some comment') - third_stack = docker.stack.deploy( + third_stack = docker_client.stack.deploy( "third_stack", [PROJECT_ROOT / "tests/python_on_whales/components/test-stack-file.yml"], env_files=[env_file], ) - agent_service = docker.service.inspect("third_stack_agent") + agent_service = docker_client.service.inspect("third_stack_agent") expected = 'SOME_OTHER_VARIABLE="--tls=true"' assert expected in agent_service.spec.task_template.container_spec.env - assert docker.stack.list() == [third_stack] + assert docker_client.stack.list() == [third_stack] time.sleep(1) - docker.stack.remove(third_stack) + docker_client.stack.remove(third_stack) time.sleep(1) -def test_deploy_not_swarm_manager(): +def test_deploy_not_swarm_manager(docker_client: DockerClient): with pytest.raises(NotASwarmManager) as e: - docker.stack.deploy( + docker_client.stack.deploy( "some_stack", [PROJECT_ROOT / "tests/python_on_whales/components/test-stack-file.yml"], ) @@ -96,29 +100,29 @@ def test_deploy_not_swarm_manager(): assert "not a swarm manager" in str(e.value).lower() -def test_ps_not_swarm_manager(): +def test_ps_not_swarm_manager(docker_client: DockerClient): with pytest.raises(NotASwarmManager) as e: - docker.stack.ps("dodo") + docker_client.stack.ps("dodo") assert "not a swarm manager" in str(e.value).lower() -def test_list_not_swarm_manager(): +def test_list_not_swarm_manager(docker_client: DockerClient): with pytest.raises(NotASwarmManager) as e: - docker.stack.list() + docker_client.stack.list() assert "not a swarm manager" in str(e.value).lower() -def test_remove_not_swarm_manager(): +def test_remove_not_swarm_manager(docker_client: DockerClient): with pytest.raises(NotASwarmManager) as e: - docker.stack.remove("dodo") + docker_client.stack.remove("dodo") assert "not a swarm manager" in str(e.value).lower() -def test_services_not_swarm_manager(): +def test_services_not_swarm_manager(docker_client: DockerClient): with pytest.raises(NotASwarmManager) as e: - docker.stack.services("dodo") + docker_client.stack.services("dodo") assert "not a swarm manager" in str(e.value).lower() diff --git a/tests/python_on_whales/components/test_swarm.py b/tests/python_on_whales/components/test_swarm.py index e9e96e44..b5030d5a 100644 --- a/tests/python_on_whales/components/test_swarm.py +++ b/tests/python_on_whales/components/test_swarm.py @@ -2,23 +2,23 @@ import pytest -from python_on_whales import docker +from python_on_whales import DockerClient from python_on_whales.exceptions import NotASwarmManager @pytest.mark.usefixtures("swarm_mode") -def test_swarm_update_retention_limit(): - docker.swarm.update(task_history_limit=4) +def test_swarm_update_retention_limit(docker_client: DockerClient): + docker_client.swarm.update(task_history_limit=4) assert ( - docker.system.info().swarm.cluster.spec.orchestration.task_history_retention_limit + docker_client.system.info().swarm.cluster.spec.orchestration.task_history_retention_limit == 4 ) @pytest.mark.usefixtures("swarm_mode") -def test_swarm_change_certificate_expiry(): - ca = docker.swarm.ca(certificate_expiry=timedelta(days=1), rotate=True) - info = docker.system.info() +def test_swarm_change_certificate_expiry(docker_client: DockerClient): + ca = docker_client.swarm.ca(certificate_expiry=timedelta(days=1), rotate=True) + info = docker_client.system.info() node_cert_expiry = timedelta( microseconds=info.swarm.cluster.spec.ca_config.node_cert_expiry / 1000 ) @@ -27,41 +27,43 @@ def test_swarm_change_certificate_expiry(): @pytest.mark.usefixtures("swarm_mode") -def test_swarm_update_auto_lock_managers(): +def test_swarm_update_auto_lock_managers(docker_client: DockerClient): assert ( - not docker.system.info().swarm.cluster.spec.encryption_config.auto_lock_managers + not docker_client.system.info().swarm.cluster.spec.encryption_config.auto_lock_managers + ) + docker_client.swarm.update(autolock=True) + assert ( + docker_client.system.info().swarm.cluster.spec.encryption_config.auto_lock_managers ) - docker.swarm.update(autolock=True) - assert docker.system.info().swarm.cluster.spec.encryption_config.auto_lock_managers @pytest.mark.usefixtures("swarm_mode") -def test_swarm_unlock_key(): - docker.swarm.update(autolock=True) - first_key = docker.swarm.unlock_key() +def test_swarm_unlock_key(docker_client: DockerClient): + docker_client.swarm.update(autolock=True) + first_key = docker_client.swarm.unlock_key() # make sure is doesn't change - assert first_key == docker.swarm.unlock_key() + assert first_key == docker_client.swarm.unlock_key() # make sure it changes: - assert first_key != docker.swarm.unlock_key(rotate=True) + assert first_key != docker_client.swarm.unlock_key(rotate=True) -def test_swarm_join_token_not_swarm_manager(): +def test_swarm_join_token_not_swarm_manager(docker_client: DockerClient): with pytest.raises(NotASwarmManager) as e: - docker.swarm.join_token("manager") + docker_client.swarm.join_token("manager") assert "not a swarm manager" in str(e.value).lower() -def test_update_not_swarm_manager(): +def test_update_not_swarm_manager(docker_client: DockerClient): with pytest.raises(NotASwarmManager) as e: - docker.swarm.update(autolock=True) + docker_client.swarm.update(autolock=True) assert "not a swarm manager" in str(e.value).lower() -def test_unlock_key_not_swarm_manager(): +def test_unlock_key_not_swarm_manager(docker_client: DockerClient): with pytest.raises(NotASwarmManager) as e: - docker.swarm.unlock_key() + docker_client.swarm.unlock_key() assert "not a swarm manager" in str(e.value).lower() diff --git a/tests/python_on_whales/components/test_system.py b/tests/python_on_whales/components/test_system.py index 0e0b0c3f..f9790a85 100644 --- a/tests/python_on_whales/components/test_system.py +++ b/tests/python_on_whales/components/test_system.py @@ -6,37 +6,53 @@ import pytest -from python_on_whales import docker +from python_on_whales import DockerClient from python_on_whales.components.system.models import DockerEvent, SystemInfo from python_on_whales.exceptions import DockerException from python_on_whales.test_utils import get_all_jsons, random_name -def test_disk_free(): - docker.pull("busybox") - docker.pull("busybox:1") - docker_items_summary = docker.system.disk_free() +@pytest.mark.parametrize( + "ctr_client", + [ + "docker", + pytest.param( + "podman", + marks=pytest.mark.xfail( + reason="podman does not return reclaimable disk space information" + ), + ), + ], + indirect=True, +) +def test_disk_free(ctr_client: DockerClient): + ctr_client.pull("busybox") + ctr_client.pull("busybox:1") + docker_items_summary = ctr_client.system.disk_free() assert docker_items_summary.images.total_count >= 1 assert docker_items_summary.images.size > 2000 -def test_info(): - info = docker.system.info() +@pytest.mark.parametrize("ctr_client", ["docker", "podman"], indirect=True) +def test_info(ctr_client: DockerClient): + info = ctr_client.system.info() assert "local" in info.plugins.volume -def test_events(): +def test_events(docker_client: DockerClient): name = random_name() - docker.run("hello-world", remove=True, name=name) + docker_client.run("hello-world", remove=True, name=name) # Takes some time for events to register sleep(1) timestamp_1 = datetime.now() # Second run to generate more events - docker.run("hello-world", remove=True, name=name) + docker_client.run("hello-world", remove=True, name=name) # Takes some time for events to register sleep(1) timestamp_2 = datetime.now() - events = list(docker.system.events(until=timestamp_2, filters={"container": name})) + events = list( + docker_client.system.events(until=timestamp_2, filters={"container": name}) + ) # Check that we capture all the events from container create to destroy assert len(events) == 10 actions = set() @@ -44,7 +60,7 @@ def test_events(): actions.add(event.action) assert actions == {"create", "attach", "start", "die", "destroy"} events = list( - docker.system.events( + docker_client.system.events( since=timestamp_1, until=timestamp_2, filters={"container": name} ) ) @@ -52,21 +68,21 @@ def test_events(): assert len(events) == 5 -def test_events_no_arguments(): +def test_events_no_arguments(docker_client: DockerClient): # The removal of the container will happen while we are waiting for an event container_name = random_name() - docker.run( + docker_client.run( "busybox", ["sh", "-c", "sleep 3 && exit 1"], name=container_name, remove=True, detach=True, ) - for event in docker.system.events(): + for event in docker_client.system.events(): assert isinstance(event, DockerEvent) break time.sleep(3) - assert not docker.container.exists(container_name) + assert not docker_client.container.exists(container_name) @pytest.mark.parametrize("json_file", get_all_jsons("system_info")) @@ -84,80 +100,96 @@ def test_parsing_events(): assert parsed.time.date() == date(2020, 12, 28) -def test_prune_prunes_image(): +@pytest.mark.parametrize( + "ctr_client", + [ + "docker", + pytest.param( + "podman", + marks=pytest.mark.xfail( + reason="'podman image list' returns image IDs with 'sha256:' prefix" + ), + ), + ], + indirect=True, +) +def test_prune_prunes_image(ctr_client: DockerClient): # TODO: Test dangling image - for container in docker.container.list(filters={"ancestor": "busybox"}): - docker.container.remove(container, force=True) - image = docker.pull("busybox") - assert image in docker.image.list() + for container in ctr_client.container.list(filters={"ancestor": "busybox"}): + ctr_client.container.remove(container, force=True) + image = ctr_client.pull("busybox") + assert image in ctr_client.image.list() # image not pruned because not dangling - docker.system.prune() - assert image in docker.image.list() + ctr_client.system.prune() + assert image in ctr_client.image.list() # image not pruned because it does not have dne label - docker.system.prune(all=True, filters={"label": "dne"}) - assert image in docker.image.list() + ctr_client.system.prune(all=True, filters={"label": "dne"}) + assert image in ctr_client.image.list() # image not pruned because it is not 1000000 hours old - docker.system.prune(all=True, filters={"until": "1000000h"}) - assert image in docker.image.list() + ctr_client.system.prune(all=True, filters={"until": "1000000h"}) + assert image in ctr_client.image.list() # image not pruned because it does not have dne label and is not 1000000 hours old - docker.system.prune(all=True, filters={"label": "dne", "until": "1000000h"}) - assert image in docker.image.list() + ctr_client.system.prune(all=True, filters={"label": "dne", "until": "1000000h"}) + assert image in ctr_client.image.list() # image pruned - docker.system.prune(all=True) - assert image not in docker.image.list() + ctr_client.system.prune(all=True) + assert image not in ctr_client.image.list() -def test_prune_prunes_container(): - stopped_container = docker.run("hello-world", remove=False, detach=True) - running_container = docker.run( +@pytest.mark.parametrize("ctr_client", ["docker", "podman"], indirect=True) +def test_prune_prunes_container(ctr_client: DockerClient): + stopped_container = ctr_client.run("hello-world", remove=False, detach=True) + running_container = ctr_client.run( "ubuntu", ["sleep", "infinity"], remove=False, detach=True ) - assert stopped_container in docker.container.list(all=True) - assert running_container in docker.container.list() + assert stopped_container in ctr_client.container.list(all=True) + assert running_container in ctr_client.container.list() - docker.system.prune() + ctr_client.system.prune() - assert stopped_container not in docker.container.list(all=True) - assert running_container in docker.container.list() - docker.container.remove(running_container, force=True) + assert stopped_container not in ctr_client.container.list(all=True) + assert running_container in ctr_client.container.list() + ctr_client.container.remove(running_container, force=True) -def test_prune_prunes_network(): +@pytest.mark.parametrize("ctr_client", ["docker", "podman"], indirect=True) +def test_prune_prunes_network(ctr_client: DockerClient): network_name = random_name() - my_net = docker.network.create(network_name) - assert my_net in docker.network.list() - docker.system.prune() - assert my_net not in docker.network.list() + my_net = ctr_client.network.create(network_name) + assert my_net in ctr_client.network.list() + ctr_client.system.prune() + assert my_net not in ctr_client.network.list() -def test_prune_prunes_volumes(): - some_volume = docker.volume.create(driver="local") - docker.run( +@pytest.mark.parametrize("ctr_client", ["docker", "podman"], indirect=True) +def test_prune_prunes_volumes(ctr_client: DockerClient): + some_volume = ctr_client.volume.create(driver="local") + ctr_client.run( "ubuntu", ["touch", "/dodo/dada"], volumes=[(some_volume, "/dodo")], remove=False, ) - assert some_volume in docker.volume.list() + assert some_volume in ctr_client.volume.list() - docker.system.prune() - assert some_volume in docker.volume.list() + ctr_client.system.prune() + assert some_volume in ctr_client.volume.list() - docker.system.prune(volumes=True) - assert some_volume not in docker.volume.list() + ctr_client.system.prune(volumes=True) + assert some_volume not in ctr_client.volume.list() -def test_prune_raises_exception_on_invalid_arguments(): +def test_prune_raises_exception_on_invalid_arguments(docker_client: DockerClient): """ The "until" filter is not supported with "--volumes" docker.system.prune should reflect that """ with pytest.raises(DockerException): - docker.system.prune(volumes=True, filters={"until": "1000000h"}) + docker_client.system.prune(volumes=True, filters={"until": "1000000h"})