Add typing information, 2/n (#1178)

* Add typing to Docker Stack modules. Clean modules up.

* Add typing to Docker Swarm modules.

* Add typing to unit tests.

* Add more typing.

* Add ignore.txt entries.
This commit is contained in:
Felix Fontein
2025-10-25 01:16:04 +02:00
committed by GitHub
parent 3350283bcc
commit 6ad4bfcd40
84 changed files with 1496 additions and 1161 deletions
@@ -4,66 +4,47 @@
from __future__ import annotations
import typing as t
import pytest
class APIErrorMock(Exception):
def __init__(self, message, response=None, explanation=None):
self.message = message
self.response = response
self.explanation = explanation
from ansible_collections.community.docker.plugins.modules import (
docker_swarm_service,
)
@pytest.fixture(autouse=True)
def docker_module_mock(mocker):
docker_module_mock = mocker.MagicMock()
docker_utils_module_mock = mocker.MagicMock()
docker_errors_module_mock = mocker.MagicMock()
docker_errors_module_mock.APIError = APIErrorMock
mock_modules = {
"docker": docker_module_mock,
"docker.utils": docker_utils_module_mock,
"docker.errors": docker_errors_module_mock,
}
return mocker.patch.dict("sys.modules", **mock_modules)
APIError = pytest.importorskip("docker.errors.APIError")
@pytest.fixture(autouse=True)
def docker_swarm_service():
from ansible_collections.community.docker.plugins.modules import (
docker_swarm_service,
)
return docker_swarm_service
def test_retry_on_out_of_sequence_error(mocker, docker_swarm_service):
def test_retry_on_out_of_sequence_error(mocker: t.Any) -> None:
run_mock = mocker.MagicMock(
side_effect=APIErrorMock(
side_effect=APIError(
message="",
response=None,
explanation="rpc error: code = Unknown desc = update out of sequence",
)
)
manager = docker_swarm_service.DockerServiceManager(client=None)
manager.run = run_mock
with pytest.raises(APIErrorMock):
mocker.patch("time.sleep")
manager = docker_swarm_service.DockerServiceManager(client=None) # type: ignore
manager.run = run_mock # type: ignore
with pytest.raises(APIError):
manager.run_safe()
assert run_mock.call_count == 3
def test_no_retry_on_general_api_error(mocker, docker_swarm_service):
def test_no_retry_on_general_api_error(mocker: t.Any) -> None:
run_mock = mocker.MagicMock(
side_effect=APIErrorMock(message="", response=None, explanation="some error")
side_effect=APIError(message="", response=None, explanation="some error")
)
manager = docker_swarm_service.DockerServiceManager(client=None)
manager.run = run_mock
with pytest.raises(APIErrorMock):
mocker.patch("time.sleep")
manager = docker_swarm_service.DockerServiceManager(client=None) # type: ignore
manager.run = run_mock # type: ignore
with pytest.raises(APIError):
manager.run_safe()
assert run_mock.call_count == 1
def test_get_docker_environment(mocker, docker_swarm_service):
def test_get_docker_environment(mocker: t.Any) -> None:
env_file_result = {"TEST1": "A", "TEST2": "B", "TEST3": "C"}
env_dict = {"TEST3": "CC", "TEST4": "D"}
env_string = "TEST3=CC,TEST4=D"
@@ -103,7 +84,7 @@ def test_get_docker_environment(mocker, docker_swarm_service):
assert result == []
def test_get_nanoseconds_from_raw_option(docker_swarm_service):
def test_get_nanoseconds_from_raw_option() -> None:
value = docker_swarm_service.get_nanoseconds_from_raw_option("test", None)
assert value is None
@@ -117,7 +98,7 @@ def test_get_nanoseconds_from_raw_option(docker_swarm_service):
docker_swarm_service.get_nanoseconds_from_raw_option("test", [])
def test_has_dict_changed(docker_swarm_service):
def test_has_dict_changed() -> None:
assert not docker_swarm_service.has_dict_changed(
{"a": 1},
{"a": 1},
@@ -135,8 +116,7 @@ def test_has_dict_changed(docker_swarm_service):
assert not docker_swarm_service.has_dict_changed(None, {})
def test_has_list_changed(docker_swarm_service):
def test_has_list_changed() -> None:
# List comparisons without dictionaries
# I could improve the indenting, but pycodestyle wants this instead
assert not docker_swarm_service.has_list_changed(None, None)
@@ -161,7 +141,7 @@ def test_has_list_changed(docker_swarm_service):
assert docker_swarm_service.has_list_changed([None, 1], [2, 1])
assert docker_swarm_service.has_list_changed([2, 1], [None, 1])
assert docker_swarm_service.has_list_changed(
"command --with args", ["command", "--with", "args"]
["command --with args"], ["command", "--with", "args"]
)
assert docker_swarm_service.has_list_changed(
["sleep", "3400"], ["sleep", "3600"], sort_lists=False
@@ -259,7 +239,7 @@ def test_has_list_changed(docker_swarm_service):
)
def test_have_networks_changed(docker_swarm_service):
def test_have_networks_changed() -> None:
assert not docker_swarm_service.have_networks_changed(None, None)
assert not docker_swarm_service.have_networks_changed([], None)
@@ -329,14 +309,14 @@ def test_have_networks_changed(docker_swarm_service):
)
def test_get_docker_networks(docker_swarm_service):
def test_get_docker_networks() -> None:
network_names = [
"network_1",
"network_2",
"network_3",
"network_4",
]
networks = [
networks: list[str | dict[str, t.Any]] = [
network_names[0],
{"name": network_names[1]},
{"name": network_names[2], "aliases": ["networkalias1"]},
@@ -367,28 +347,27 @@ def test_get_docker_networks(docker_swarm_service):
assert "foo" in network["options"]
# Test missing name
with pytest.raises(TypeError):
docker_swarm_service.get_docker_networks([{"invalid": "err"}], {"err": 1})
docker_swarm_service.get_docker_networks([{"invalid": "err"}], {"err": "x"})
# test for invalid aliases type
with pytest.raises(TypeError):
docker_swarm_service.get_docker_networks(
[{"name": "test", "aliases": 1}], {"test": 1}
[{"name": "test", "aliases": 1}], {"test": "x"}
)
# Test invalid aliases elements
with pytest.raises(TypeError):
docker_swarm_service.get_docker_networks(
[{"name": "test", "aliases": [1]}], {"test": 1}
[{"name": "test", "aliases": [1]}], {"test": "x"}
)
# Test for invalid options type
with pytest.raises(TypeError):
docker_swarm_service.get_docker_networks(
[{"name": "test", "options": 1}], {"test": 1}
[{"name": "test", "options": 1}], {"test": "x"}
)
# Test for invalid networks type
with pytest.raises(TypeError):
docker_swarm_service.get_docker_networks(1, {"test": 1})
# Test for non existing networks
with pytest.raises(ValueError):
docker_swarm_service.get_docker_networks([{"name": "idontexist"}], {"test": 1})
docker_swarm_service.get_docker_networks(
[{"name": "idontexist"}], {"test": "x"}
)
# Test empty values
assert docker_swarm_service.get_docker_networks([], {}) == []
assert docker_swarm_service.get_docker_networks(None, {}) is None