Merge pull request #1220 from p12tic/types

Enforce types using mypy
This commit is contained in:
Povilas Kanapickas 2025-05-24 17:35:52 +03:00 committed by GitHub
commit 835e3abe95
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
61 changed files with 654 additions and 521 deletions

View File

@ -3,8 +3,8 @@
import asyncio # noqa: F401 import asyncio # noqa: F401
import os import os
import aioredis import aioredis # type: ignore[import-not-found]
from aiohttp import web from aiohttp import web # type: ignore[import-not-found]
REDIS_HOST = os.environ.get("REDIS_HOST", "localhost") REDIS_HOST = os.environ.get("REDIS_HOST", "localhost")
REDIS_PORT = int(os.environ.get("REDIS_PORT", "6379")) REDIS_PORT = int(os.environ.get("REDIS_PORT", "6379"))
@ -16,13 +16,13 @@ routes = web.RouteTableDef()
@routes.get("/") @routes.get("/")
async def hello(request): # pylint: disable=unused-argument async def hello(request: web.Request) -> web.Response: # pylint: disable=unused-argument
counter = await redis.incr("mycounter") counter = await redis.incr("mycounter")
return web.Response(text=f"counter={counter}") return web.Response(text=f"counter={counter}")
@routes.get("/hello.json") @routes.get("/hello.json")
async def hello_json(request): # pylint: disable=unused-argument async def hello_json(request: web.Request) -> web.Response: # pylint: disable=unused-argument
counter = await redis.incr("mycounter") counter = await redis.incr("mycounter")
data = {"counter": counter} data = {"counter": counter}
return web.json_response(data) return web.json_response(data)
@ -31,7 +31,7 @@ async def hello_json(request): # pylint: disable=unused-argument
app.add_routes(routes) app.add_routes(routes)
def main(): def main() -> None:
web.run_app(app, port=8080) web.run_app(app, port=8080)

File diff suppressed because it is too large Load Diff

View File

@ -53,3 +53,21 @@ quote-style = "preserve"
directory = "misc" directory = "misc"
name = "Misc" name = "Misc"
showcontent = true showcontent = true
[tool.mypy]
python_version = "3.9"
namespace_packages = true
explicit_package_bases = true
pretty = true
warn_redundant_casts = true
disallow_untyped_calls = false
disallow_untyped_defs = true
no_implicit_optional = true
mypy_path = "$MYPY_CONFIG_FILE_DIR"
exclude = "build"
[[tool.mypy.overrides]]
module = [
"parameterized.*",
]
ignore_missing_imports = true

View File

@ -4,8 +4,12 @@ cryptography==44.0.3
parameterized==0.9.0 parameterized==0.9.0
pytest==8.0.2 pytest==8.0.2
tox==4.13.0 tox==4.13.0
ruff==0.3.1 mypy==1.15.0
ruff==0.11.11
pylint==3.1.0 pylint==3.1.0
types-PyYAML==6.0.12.20250402
types-requests==2.32.0.20250328
types-setuptools==80.7.0.20250516
# The packages below are transitive dependencies of the packages above and are included here # The packages below are transitive dependencies of the packages above and are included here
# to make testing reproducible. # to make testing reproducible.
@ -24,6 +28,7 @@ filelock==3.13.1
iniconfig==2.0.0 iniconfig==2.0.0
isort==5.13.2 isort==5.13.2
mccabe==0.7.0 mccabe==0.7.0
mypy_extensions==1.1.0
packaging==23.2 packaging==23.2
platformdirs==4.2.0 platformdirs==4.2.0
pluggy==1.4.0 pluggy==1.4.0
@ -32,4 +37,5 @@ python-dotenv==1.0.1
PyYAML==6.0.1 PyYAML==6.0.1
requests requests
tomlkit==0.12.4 tomlkit==0.12.4
typing_extensions==4.13.2
virtualenv==20.26.6 virtualenv==20.26.6

View File

@ -2,7 +2,7 @@ import os
import subprocess import subprocess
def create_base_test_image(): def create_base_test_image() -> None:
subprocess.check_call( subprocess.check_call(
['podman', 'build', '-t', 'nopush/podman-compose-test', '.'], ['podman', 'build', '-t', 'nopush/podman-compose-test', '.'],
cwd=os.path.join(os.path.dirname(__file__), "base_image"), cwd=os.path.join(os.path.dirname(__file__), "base_image"),

View File

@ -10,7 +10,7 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(failure_order): def compose_yaml_path(failure_order: str) -> str:
return os.path.join(test_path(), "abort", f"docker-compose-fail-{failure_order}.yaml") return os.path.join(test_path(), "abort", f"docker-compose-fail-{failure_order}.yaml")
@ -25,7 +25,7 @@ class TestComposeAbort(unittest.TestCase, RunSubprocessMixin):
("exit", "none", 0), ("exit", "none", 0),
("failure", "none", 0), ("failure", "none", 0),
]) ])
def test_abort(self, abort_type, failure_order, expected_exit_code): def test_abort(self, abort_type: str, failure_order: str, expected_exit_code: int) -> None:
try: try:
self.run_subprocess_assert_returncode( self.run_subprocess_assert_returncode(
[ [

View File

@ -11,13 +11,13 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
""" "Returns the path to the compose file used for this test module""" """ "Returns the path to the compose file used for this test module"""
return os.path.join(test_path(), "additional_contexts", "project") return os.path.join(test_path(), "additional_contexts", "project")
class TestComposeBuildAdditionalContexts(unittest.TestCase): class TestComposeBuildAdditionalContexts(unittest.TestCase):
def test_build_additional_context(self): def test_build_additional_context(self) -> None:
"""podman build should receive additional contexts as --build-context """podman build should receive additional contexts as --build-context
See additional_context/project/docker-compose.yaml for context paths See additional_context/project/docker-compose.yaml for context paths

View File

@ -10,7 +10,7 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(scenario): def compose_yaml_path(scenario: str) -> str:
return os.path.join( return os.path.join(
os.path.join(test_path(), "default_net_behavior"), f"docker-compose_{scenario}.yaml" os.path.join(test_path(), "default_net_behavior"), f"docker-compose_{scenario}.yaml"
) )
@ -27,13 +27,13 @@ class TestComposeDefaultNetBehavior(unittest.TestCase, RunSubprocessMixin):
('two_nets_compat', 'default_net_behavior_default'), ('two_nets_compat', 'default_net_behavior_default'),
('with_default_compat', 'default_net_behavior_default'), ('with_default_compat', 'default_net_behavior_default'),
]) ])
def test_nethost(self, scenario, default_net): def test_nethost(self, scenario: str, default_net: str) -> None:
try: try:
self.run_subprocess_assert_returncode( self.run_subprocess_assert_returncode(
[podman_compose_path(), "-f", compose_yaml_path(scenario), "up", "-d"], [podman_compose_path(), "-f", compose_yaml_path(scenario), "up", "-d"],
) )
container_id, _ = self.run_subprocess_assert_returncode( container_id_out, _ = self.run_subprocess_assert_returncode(
[ [
podman_compose_path(), podman_compose_path(),
"-f", "-f",
@ -43,7 +43,7 @@ class TestComposeDefaultNetBehavior(unittest.TestCase, RunSubprocessMixin):
'{{.ID}}', '{{.ID}}',
], ],
) )
container_id = container_id.decode('utf-8').split('\n')[0] container_id = container_id_out.decode('utf-8').split('\n')[0]
output, _ = self.run_subprocess_assert_returncode( output, _ = self.run_subprocess_assert_returncode(
[ [
"podman", "podman",

View File

@ -9,12 +9,12 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(suffix=""): def compose_yaml_path(suffix: str = "") -> str:
return os.path.join(os.path.join(test_path(), "deps"), f"docker-compose{suffix}.yaml") return os.path.join(os.path.join(test_path(), "deps"), f"docker-compose{suffix}.yaml")
class TestComposeBaseDeps(unittest.TestCase, RunSubprocessMixin): class TestComposeBaseDeps(unittest.TestCase, RunSubprocessMixin):
def test_deps(self): def test_deps(self) -> None:
try: try:
output, _ = self.run_subprocess_assert_returncode([ output, _ = self.run_subprocess_assert_returncode([
podman_compose_path(), podman_compose_path(),
@ -37,7 +37,7 @@ class TestComposeBaseDeps(unittest.TestCase, RunSubprocessMixin):
"down", "down",
]) ])
def test_run_nodeps(self): def test_run_nodeps(self) -> None:
try: try:
output, _ = self.run_subprocess_assert_returncode([ output, _ = self.run_subprocess_assert_returncode([
podman_compose_path(), podman_compose_path(),
@ -62,7 +62,7 @@ class TestComposeBaseDeps(unittest.TestCase, RunSubprocessMixin):
"down", "down",
]) ])
def test_up_nodeps(self): def test_up_nodeps(self) -> None:
try: try:
self.run_subprocess_assert_returncode([ self.run_subprocess_assert_returncode([
podman_compose_path(), podman_compose_path(),
@ -89,7 +89,7 @@ class TestComposeBaseDeps(unittest.TestCase, RunSubprocessMixin):
"down", "down",
]) ])
def test_podman_compose_run(self): def test_podman_compose_run(self) -> None:
""" """
This will test depends_on as well This will test depends_on as well
""" """
@ -143,7 +143,7 @@ class TestComposeBaseDeps(unittest.TestCase, RunSubprocessMixin):
class TestComposeConditionalDeps(unittest.TestCase, RunSubprocessMixin): class TestComposeConditionalDeps(unittest.TestCase, RunSubprocessMixin):
def test_deps_succeeds(self): def test_deps_succeeds(self) -> None:
suffix = "-conditional-succeeds" suffix = "-conditional-succeeds"
try: try:
output, _ = self.run_subprocess_assert_returncode([ output, _ = self.run_subprocess_assert_returncode([
@ -167,7 +167,7 @@ class TestComposeConditionalDeps(unittest.TestCase, RunSubprocessMixin):
"down", "down",
]) ])
def test_deps_fails(self): def test_deps_fails(self) -> None:
suffix = "-conditional-fails" suffix = "-conditional-fails"
try: try:
output, _ = self.run_subprocess_assert_returncode([ output, _ = self.run_subprocess_assert_returncode([
@ -188,10 +188,10 @@ class TestComposeConditionalDeps(unittest.TestCase, RunSubprocessMixin):
class TestComposeConditionalDepsHealthy(unittest.TestCase, PodmanAwareRunSubprocessMixin): class TestComposeConditionalDepsHealthy(unittest.TestCase, PodmanAwareRunSubprocessMixin):
def setUp(self): def setUp(self) -> None:
self.podman_version = self.retrieve_podman_version() self.podman_version = self.retrieve_podman_version()
def test_up_deps_healthy(self): def test_up_deps_healthy(self) -> None:
suffix = "-conditional-healthy" suffix = "-conditional-healthy"
try: try:
self.run_subprocess_assert_returncode([ self.run_subprocess_assert_returncode([
@ -261,6 +261,6 @@ class TestComposeConditionalDepsHealthy(unittest.TestCase, PodmanAwareRunSubproc
self.run_subprocess_assert_returncode([ self.run_subprocess_assert_returncode([
podman_compose_path(), podman_compose_path(),
"-f", "-f",
compose_yaml_path(), compose_yaml_path(suffix),
"down", "down",
]) ])

View File

@ -8,12 +8,12 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_base_path(): def compose_base_path() -> str:
return os.path.join(test_path(), "env_file_tests") return os.path.join(test_path(), "env_file_tests")
class TestComposeEnvFile(unittest.TestCase, RunSubprocessMixin): class TestComposeEnvFile(unittest.TestCase, RunSubprocessMixin):
def test_path_env_file_inline(self): def test_path_env_file_inline(self) -> None:
# Test taking env variable value directly from env-file when its path is inline path # Test taking env variable value directly from env-file when its path is inline path
base_path = compose_base_path() base_path = compose_base_path()
path_compose_file = os.path.join(base_path, "project/container-compose.yaml") path_compose_file = os.path.join(base_path, "project/container-compose.yaml")
@ -42,7 +42,7 @@ class TestComposeEnvFile(unittest.TestCase, RunSubprocessMixin):
"down", "down",
]) ])
def test_path_env_file_flat_in_compose_file(self): def test_path_env_file_flat_in_compose_file(self) -> None:
# Test taking env variable value from env-file/project-1.env which was declared in # Test taking env variable value from env-file/project-1.env which was declared in
# compose file's env_file # compose file's env_file
base_path = compose_base_path() base_path = compose_base_path()
@ -74,7 +74,7 @@ class TestComposeEnvFile(unittest.TestCase, RunSubprocessMixin):
"down", "down",
]) ])
def test_path_env_file_obj_in_compose_file(self): def test_path_env_file_obj_in_compose_file(self) -> None:
# take variable value from env-file project-1.env which was declared in compose # take variable value from env-file project-1.env which was declared in compose
# file's env_file by -path: ... # file's env_file by -path: ...
base_path = compose_base_path() base_path = compose_base_path()
@ -106,7 +106,7 @@ class TestComposeEnvFile(unittest.TestCase, RunSubprocessMixin):
"down", "down",
]) ])
def test_exists_optional_env_file_path_in_compose_file(self): def test_exists_optional_env_file_path_in_compose_file(self) -> None:
# test taking env variable values from several env-files when one of them is optional # test taking env variable values from several env-files when one of them is optional
# and exists # and exists
base_path = compose_base_path() base_path = compose_base_path()
@ -139,7 +139,7 @@ class TestComposeEnvFile(unittest.TestCase, RunSubprocessMixin):
"down", "down",
]) ])
def test_missing_optional_env_file_path_in_compose_file(self): def test_missing_optional_env_file_path_in_compose_file(self) -> None:
# test taking env variable values from several env-files when one of them is optional and # test taking env variable values from several env-files when one of them is optional and
# is missing (silently skip it) # is missing (silently skip it)
base_path = compose_base_path() base_path = compose_base_path()
@ -173,7 +173,7 @@ class TestComposeEnvFile(unittest.TestCase, RunSubprocessMixin):
"down", "down",
]) ])
def test_var_value_inline_overrides_env_file_path_inline(self): def test_var_value_inline_overrides_env_file_path_inline(self) -> None:
# Test overriding env value when value is declared in inline command # Test overriding env value when value is declared in inline command
base_path = compose_base_path() base_path = compose_base_path()
path_compose_file = os.path.join(base_path, "project/container-compose.yaml") path_compose_file = os.path.join(base_path, "project/container-compose.yaml")
@ -204,7 +204,7 @@ class TestComposeEnvFile(unittest.TestCase, RunSubprocessMixin):
"down", "down",
]) ])
def test_taking_env_variables_from_env_files_from_different_directories(self): def test_taking_env_variables_from_env_files_from_different_directories(self) -> None:
# FIXME: It is not clear what this test actually tests, but from README.md it looks like: # FIXME: It is not clear what this test actually tests, but from README.md it looks like:
# Test overriding env values by directory env-files-tests/.env file values # Test overriding env values by directory env-files-tests/.env file values
# and only take value from project/.env, when it does not exist in env-files-tests/.env # and only take value from project/.env, when it does not exist in env-files-tests/.env

View File

@ -8,14 +8,14 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join(os.path.join(test_path(), "env_tests"), "container-compose.yml") return os.path.join(os.path.join(test_path(), "env_tests"), "container-compose.yml")
class TestComposeEnv(unittest.TestCase, RunSubprocessMixin): class TestComposeEnv(unittest.TestCase, RunSubprocessMixin):
"""Test that inline environment variable overrides environment variable from compose file.""" """Test that inline environment variable overrides environment variable from compose file."""
def test_env(self): def test_env(self) -> None:
try: try:
output, _ = self.run_subprocess_assert_returncode([ output, _ = self.run_subprocess_assert_returncode([
podman_compose_path(), podman_compose_path(),
@ -50,7 +50,7 @@ class TestComposeEnv(unittest.TestCase, RunSubprocessMixin):
- https://github.com/compose-spec/compose-spec/blob/main/04-version-and-name.md - https://github.com/compose-spec/compose-spec/blob/main/04-version-and-name.md
""" """
def test_project_name(self): def test_project_name(self) -> None:
try: try:
output, _ = self.run_subprocess_assert_returncode([ output, _ = self.run_subprocess_assert_returncode([
podman_compose_path(), podman_compose_path(),
@ -68,7 +68,7 @@ class TestComposeEnv(unittest.TestCase, RunSubprocessMixin):
"down", "down",
]) ])
def test_project_name_override(self): def test_project_name_override(self) -> None:
try: try:
output, _ = self.run_subprocess_assert_returncode([ output, _ = self.run_subprocess_assert_returncode([
podman_compose_path(), podman_compose_path(),

View File

@ -8,12 +8,12 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join(os.path.join(test_path(), "exit_from"), "docker-compose.yaml") return os.path.join(os.path.join(test_path(), "exit_from"), "docker-compose.yaml")
class TestComposeExitFrom(unittest.TestCase, RunSubprocessMixin): class TestComposeExitFrom(unittest.TestCase, RunSubprocessMixin):
def test_exit_code_sh1(self): def test_exit_code_sh1(self) -> None:
try: try:
self.run_subprocess_assert_returncode( self.run_subprocess_assert_returncode(
[ [
@ -33,7 +33,7 @@ class TestComposeExitFrom(unittest.TestCase, RunSubprocessMixin):
"down", "down",
]) ])
def test_exit_code_sh2(self): def test_exit_code_sh2(self) -> None:
try: try:
self.run_subprocess_assert_returncode( self.run_subprocess_assert_returncode(
[ [
@ -53,7 +53,7 @@ class TestComposeExitFrom(unittest.TestCase, RunSubprocessMixin):
"down", "down",
]) ])
def test_podman_compose_exit_from(self): def test_podman_compose_exit_from(self) -> None:
up_cmd = [ up_cmd = [
"coverage", "coverage",
"run", "run",

View File

@ -8,12 +8,12 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join(os.path.join(test_path(), "extends"), "docker-compose.yaml") return os.path.join(os.path.join(test_path(), "extends"), "docker-compose.yaml")
class TestComposeExteds(unittest.TestCase, RunSubprocessMixin): class TestComposeExteds(unittest.TestCase, RunSubprocessMixin):
def test_extends_service_launch_echo(self): def test_extends_service_launch_echo(self) -> None:
try: try:
self.run_subprocess_assert_returncode([ self.run_subprocess_assert_returncode([
podman_compose_path(), podman_compose_path(),
@ -38,7 +38,7 @@ class TestComposeExteds(unittest.TestCase, RunSubprocessMixin):
"down", "down",
]) ])
def test_extends_service_launch_echo1(self): def test_extends_service_launch_echo1(self) -> None:
try: try:
self.run_subprocess_assert_returncode([ self.run_subprocess_assert_returncode([
podman_compose_path(), podman_compose_path(),
@ -63,7 +63,7 @@ class TestComposeExteds(unittest.TestCase, RunSubprocessMixin):
"down", "down",
]) ])
def test_extends_service_launch_env1(self): def test_extends_service_launch_env1(self) -> None:
try: try:
self.run_subprocess_assert_returncode([ self.run_subprocess_assert_returncode([
podman_compose_path(), podman_compose_path(),

View File

@ -9,12 +9,12 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join(os.path.join(test_path(), "extends_w_empty_service"), "docker-compose.yml") return os.path.join(os.path.join(test_path(), "extends_w_empty_service"), "docker-compose.yml")
class TestComposeExtendsWithEmptyService(unittest.TestCase, RunSubprocessMixin): class TestComposeExtendsWithEmptyService(unittest.TestCase, RunSubprocessMixin):
def test_extends_w_empty_service(self): def test_extends_w_empty_service(self) -> None:
try: try:
self.run_subprocess_assert_returncode( self.run_subprocess_assert_returncode(
[ [
@ -39,7 +39,7 @@ class TestComposeExtendsWithEmptyService(unittest.TestCase, RunSubprocessMixin):
"down", "down",
]) ])
def test_podman_compose_extends_w_empty_service(self): def test_podman_compose_extends_w_empty_service(self) -> None:
""" """
Test that podman-compose can execute podman-compose -f <file> up with extended File which Test that podman-compose can execute podman-compose -f <file> up with extended File which
includes an empty service. (e.g. if the file is used as placeholder for more complex includes an empty service. (e.g. if the file is used as placeholder for more complex

View File

@ -8,12 +8,12 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join(os.path.join(test_path(), "extends_w_file"), "docker-compose.yml") return os.path.join(os.path.join(test_path(), "extends_w_file"), "docker-compose.yml")
class TestComposeExtendsWithFile(unittest.TestCase, RunSubprocessMixin): class TestComposeExtendsWithFile(unittest.TestCase, RunSubprocessMixin):
def test_extends_w_file(self): # when file is Dockerfile for building the image def test_extends_w_file(self) -> None: # when file is Dockerfile for building the image
try: try:
self.run_subprocess_assert_returncode( self.run_subprocess_assert_returncode(
[ [

View File

@ -9,12 +9,12 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join(os.path.join(test_path(), "extends_w_file_subdir"), "docker-compose.yml") return os.path.join(os.path.join(test_path(), "extends_w_file_subdir"), "docker-compose.yml")
class TestComposeExtendsWithFileSubdir(unittest.TestCase, RunSubprocessMixin): class TestComposeExtendsWithFileSubdir(unittest.TestCase, RunSubprocessMixin):
def test_extends_w_file_subdir(self): # when file is Dockerfile for building the image def test_extends_w_file_subdir(self) -> None: # when file is Dockerfile for building the image
try: try:
self.run_subprocess_assert_returncode( self.run_subprocess_assert_returncode(
[ [
@ -39,7 +39,7 @@ class TestComposeExtendsWithFileSubdir(unittest.TestCase, RunSubprocessMixin):
"down", "down",
]) ])
def test_podman_compose_extends_w_file_subdir(self): def test_podman_compose_extends_w_file_subdir(self) -> None:
""" """
Test that podman-compose can execute podman-compose -f <file> up with extended File which Test that podman-compose can execute podman-compose -f <file> up with extended File which
includes a build context includes a build context

View File

@ -10,7 +10,7 @@ from tests.integration.test_utils import test_path
class TestFilesystem(unittest.TestCase, RunSubprocessMixin): class TestFilesystem(unittest.TestCase, RunSubprocessMixin):
def test_compose_symlink(self): def test_compose_symlink(self) -> None:
"""The context of podman-compose.yml should come from the same directory as the file even """The context of podman-compose.yml should come from the same directory as the file even
if it is a symlink if it is a symlink
""" """

View File

@ -6,26 +6,26 @@ import unittest
from tests.integration.test_utils import RunSubprocessMixin from tests.integration.test_utils import RunSubprocessMixin
def base_path(): def base_path() -> str:
"""Returns the base path for the project""" """Returns the base path for the project"""
return os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) return os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
def test_path(): def test_path() -> str:
"""Returns the path to the tests directory""" """Returns the path to the tests directory"""
return os.path.join(base_path(), "tests/integration") return os.path.join(base_path(), "tests/integration")
def podman_compose_path(): def podman_compose_path() -> str:
"""Returns the path to the podman compose script""" """Returns the path to the podman compose script"""
return os.path.join(base_path(), "podman_compose.py") return os.path.join(base_path(), "podman_compose.py")
def is_root(): def is_root() -> bool:
return os.geteuid() == 0 return os.geteuid() == 0
def failure_exitcode_when_rootful(): def failure_exitcode_when_rootful() -> int:
if is_root(): if is_root():
return 125 return 125
return 0 return 0
@ -37,7 +37,7 @@ def failure_exitcode_when_rootful():
# Test all combinations of command line argument in_pod and compose file argument in_pod. # Test all combinations of command line argument in_pod and compose file argument in_pod.
class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin): class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin):
# compose file provides x-podman in_pod=false # compose file provides x-podman in_pod=false
def test_x_podman_in_pod_false_command_line_in_pod_not_exists(self): def test_x_podman_in_pod_false_command_line_in_pod_not_exists(self) -> None:
""" """
Test that podman-compose will not create a pod, when x-podman in_pod=false and command line Test that podman-compose will not create a pod, when x-podman in_pod=false and command line
does not provide this option does not provide this option
@ -82,7 +82,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin):
# throws an error, can not actually find this pod because it was not created # throws an error, can not actually find this pod because it was not created
self.run_subprocess_assert_returncode(command_rm_pod, expected_returncode=1) self.run_subprocess_assert_returncode(command_rm_pod, expected_returncode=1)
def test_x_podman_in_pod_false_command_line_in_pod_true(self): def test_x_podman_in_pod_false_command_line_in_pod_true(self) -> None:
""" """
Test that podman-compose does not allow pod creating even with command line in_pod=True Test that podman-compose does not allow pod creating even with command line in_pod=True
when --userns and --pod are set together: throws an error when --userns and --pod are set together: throws an error
@ -115,7 +115,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin):
# been created) and have expected_returncode=1 (see FIXME above) # been created) and have expected_returncode=1 (see FIXME above)
self.run_subprocess_assert_returncode(command_rm_pod) self.run_subprocess_assert_returncode(command_rm_pod)
def test_x_podman_in_pod_false_command_line_in_pod_false(self): def test_x_podman_in_pod_false_command_line_in_pod_false(self) -> None:
""" """
Test that podman-compose will not create a pod as command line sets in_pod=False Test that podman-compose will not create a pod as command line sets in_pod=False
""" """
@ -160,7 +160,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin):
# can not actually find this pod because it was not created # can not actually find this pod because it was not created
self.run_subprocess_assert_returncode(command_rm_pod, 1) self.run_subprocess_assert_returncode(command_rm_pod, 1)
def test_x_podman_in_pod_false_command_line_in_pod_empty_string(self): def test_x_podman_in_pod_false_command_line_in_pod_empty_string(self) -> None:
""" """
Test that podman-compose will not create a pod, when x-podman in_pod=false and command line Test that podman-compose will not create a pod, when x-podman in_pod=false and command line
command line in_pod="" command line in_pod=""
@ -207,7 +207,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin):
self.run_subprocess_assert_returncode(command_rm_pod, 1) self.run_subprocess_assert_returncode(command_rm_pod, 1)
# compose file provides x-podman in_pod=true # compose file provides x-podman in_pod=true
def test_x_podman_in_pod_true_command_line_in_pod_not_exists(self): def test_x_podman_in_pod_true_command_line_in_pod_not_exists(self) -> None:
""" """
Test that podman-compose does not allow pod creating when --userns and --pod are set Test that podman-compose does not allow pod creating when --userns and --pod are set
together even when x-podman in_pod=true: throws an error together even when x-podman in_pod=true: throws an error
@ -240,7 +240,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin):
# created) and have expected_returncode=1 (see FIXME above) # created) and have expected_returncode=1 (see FIXME above)
self.run_subprocess_assert_returncode(command_rm_pod) self.run_subprocess_assert_returncode(command_rm_pod)
def test_x_podman_in_pod_true_command_line_in_pod_true(self): def test_x_podman_in_pod_true_command_line_in_pod_true(self) -> None:
""" """
Test that podman-compose does not allow pod creating when --userns and --pod are set Test that podman-compose does not allow pod creating when --userns and --pod are set
together even when x-podman in_pod=true and and command line in_pod=True: throws an error together even when x-podman in_pod=true and and command line in_pod=True: throws an error
@ -274,7 +274,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin):
# been created) and have expected_returncode=1 (see FIXME above) # been created) and have expected_returncode=1 (see FIXME above)
self.run_subprocess_assert_returncode(command_rm_pod) self.run_subprocess_assert_returncode(command_rm_pod)
def test_x_podman_in_pod_true_command_line_in_pod_false(self): def test_x_podman_in_pod_true_command_line_in_pod_false(self) -> None:
""" """
Test that podman-compose will not create a pod as command line sets in_pod=False Test that podman-compose will not create a pod as command line sets in_pod=False
""" """
@ -319,7 +319,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin):
# can not actually find this pod because it was not created # can not actually find this pod because it was not created
self.run_subprocess_assert_returncode(command_rm_pod, 1) self.run_subprocess_assert_returncode(command_rm_pod, 1)
def test_x_podman_in_pod_true_command_line_in_pod_empty_string(self): def test_x_podman_in_pod_true_command_line_in_pod_empty_string(self) -> None:
""" """
Test that podman-compose does not allow pod creating when --userns and --pod are set Test that podman-compose does not allow pod creating when --userns and --pod are set
together even when x-podman in_pod=true and command line in_pod="": throws an error together even when x-podman in_pod=true and command line in_pod="": throws an error
@ -354,7 +354,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin):
self.run_subprocess_assert_returncode(command_rm_pod) self.run_subprocess_assert_returncode(command_rm_pod)
# compose file does not provide x-podman in_pod # compose file does not provide x-podman in_pod
def test_x_podman_in_pod_not_exists_command_line_in_pod_not_exists(self): def test_x_podman_in_pod_not_exists_command_line_in_pod_not_exists(self) -> None:
""" """
Test that podman-compose does not allow pod creating when --userns and --pod are set Test that podman-compose does not allow pod creating when --userns and --pod are set
together: throws an error together: throws an error
@ -387,7 +387,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin):
# created) and have expected_returncode=1 (see FIXME above) # created) and have expected_returncode=1 (see FIXME above)
self.run_subprocess_assert_returncode(command_rm_pod) self.run_subprocess_assert_returncode(command_rm_pod)
def test_x_podman_in_pod_not_exists_command_line_in_pod_true(self): def test_x_podman_in_pod_not_exists_command_line_in_pod_true(self) -> None:
""" """
Test that podman-compose does not allow pod creating when --userns and --pod are set Test that podman-compose does not allow pod creating when --userns and --pod are set
together even when x-podman in_pod=true: throws an error together even when x-podman in_pod=true: throws an error
@ -421,7 +421,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin):
# been created) and have expected_returncode=1 (see FIXME above) # been created) and have expected_returncode=1 (see FIXME above)
self.run_subprocess_assert_returncode(command_rm_pod) self.run_subprocess_assert_returncode(command_rm_pod)
def test_x_podman_in_pod_not_exists_command_line_in_pod_false(self): def test_x_podman_in_pod_not_exists_command_line_in_pod_false(self) -> None:
""" """
Test that podman-compose will not create a pod as command line sets in_pod=False Test that podman-compose will not create a pod as command line sets in_pod=False
""" """
@ -467,7 +467,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin):
# can not actually find this pod because it was not created # can not actually find this pod because it was not created
self.run_subprocess_assert_returncode(command_rm_pod, 1) self.run_subprocess_assert_returncode(command_rm_pod, 1)
def test_x_podman_in_pod_custom_name(self): def test_x_podman_in_pod_custom_name(self) -> None:
""" """
Test that podman-compose will create a pod with a custom name Test that podman-compose will create a pod with a custom name
""" """
@ -494,7 +494,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin):
command_rm_pod = ["podman", "pod", "rm", "custom_test_pod_name"] command_rm_pod = ["podman", "pod", "rm", "custom_test_pod_name"]
self.run_subprocess_assert_returncode(command_rm_pod) self.run_subprocess_assert_returncode(command_rm_pod)
def test_x_podman_in_pod_not_exists_command_line_in_pod_empty_string(self): def test_x_podman_in_pod_not_exists_command_line_in_pod_empty_string(self) -> None:
""" """
Test that podman-compose does not allow pod creating when --userns and --pod are set Test that podman-compose does not allow pod creating when --userns and --pod are set
together: throws an error together: throws an error

View File

@ -7,7 +7,7 @@ from tests.integration.test_utils import RunSubprocessMixin
class TestPodmanComposeInclude(unittest.TestCase, RunSubprocessMixin): class TestPodmanComposeInclude(unittest.TestCase, RunSubprocessMixin):
def test_podman_compose_include(self): def test_podman_compose_include(self) -> None:
""" """
Test that podman-compose can execute podman-compose -f <file> up with include Test that podman-compose can execute podman-compose -f <file> up with include
:return: :return:

View File

@ -8,12 +8,12 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join(os.path.join(test_path(), "interpolation"), "docker-compose.yml") return os.path.join(os.path.join(test_path(), "interpolation"), "docker-compose.yml")
class TestComposeInterpolation(unittest.TestCase, RunSubprocessMixin): class TestComposeInterpolation(unittest.TestCase, RunSubprocessMixin):
def test_interpolation(self): def test_interpolation(self) -> None:
try: try:
self.run_subprocess_assert_returncode([ self.run_subprocess_assert_returncode([
"env", "env",

View File

@ -9,12 +9,12 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join(os.path.join(test_path(), "ipam_default"), "docker-compose.yaml") return os.path.join(os.path.join(test_path(), "ipam_default"), "docker-compose.yaml")
class TestComposeIpamDefault(unittest.TestCase, RunSubprocessMixin): class TestComposeIpamDefault(unittest.TestCase, RunSubprocessMixin):
def test_ipam_default(self): def test_ipam_default(self) -> None:
try: try:
self.run_subprocess_assert_returncode( self.run_subprocess_assert_returncode(
[podman_compose_path(), "-f", compose_yaml_path(), "up", "-d"], [podman_compose_path(), "-f", compose_yaml_path(), "up", "-d"],

View File

@ -12,7 +12,7 @@ from tests.integration.test_utils import test_path
class TestLifetime(unittest.TestCase, RunSubprocessMixin): class TestLifetime(unittest.TestCase, RunSubprocessMixin):
def test_up_single_container(self): def test_up_single_container(self) -> None:
"""Podman compose up should be able to start containers one after another""" """Podman compose up should be able to start containers one after another"""
compose_path = os.path.join(test_path(), "lifetime/up_single_container/docker-compose.yml") compose_path = os.path.join(test_path(), "lifetime/up_single_container/docker-compose.yml")
@ -68,7 +68,7 @@ class TestLifetime(unittest.TestCase, RunSubprocessMixin):
("no_ports", "up_single_container_many_times"), ("no_ports", "up_single_container_many_times"),
("with_ports", "up_single_container_many_times_with_ports"), ("with_ports", "up_single_container_many_times_with_ports"),
]) ])
def test_up_single_container_many_times(self, name, subdir): def test_up_single_container_many_times(self, name: str, subdir: str) -> None:
"""Podman compose up should be able to start a container many times after it finishes """Podman compose up should be able to start a container many times after it finishes
running. running.
""" """

View File

@ -9,7 +9,7 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join( return os.path.join(
test_path(), test_path(),
"merge/reset_and_override_tags/override_tag_attribute/docker-compose.yaml", "merge/reset_and_override_tags/override_tag_attribute/docker-compose.yaml",
@ -18,7 +18,7 @@ def compose_yaml_path():
class TestComposeOverrideTagAttribute(unittest.TestCase, RunSubprocessMixin): class TestComposeOverrideTagAttribute(unittest.TestCase, RunSubprocessMixin):
# test if a service attribute from docker-compose.yaml file is overridden # test if a service attribute from docker-compose.yaml file is overridden
def test_override_tag_attribute(self): def test_override_tag_attribute(self) -> None:
override_file = os.path.join( override_file = os.path.join(
test_path(), test_path(),
"merge/reset_and_override_tags/override_tag_attribute/docker-compose.override_attribute.yaml", "merge/reset_and_override_tags/override_tag_attribute/docker-compose.override_attribute.yaml",

View File

@ -9,7 +9,7 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join( return os.path.join(
test_path(), test_path(),
"merge/reset_and_override_tags/override_tag_service/docker-compose.yaml", "merge/reset_and_override_tags/override_tag_service/docker-compose.yaml",
@ -18,7 +18,7 @@ def compose_yaml_path():
class TestComposeOverrideTagService(unittest.TestCase, RunSubprocessMixin): class TestComposeOverrideTagService(unittest.TestCase, RunSubprocessMixin):
# test if whole service from docker-compose.yaml file is overridden in another file # test if whole service from docker-compose.yaml file is overridden in another file
def test_override_tag_service(self): def test_override_tag_service(self) -> None:
override_file = os.path.join( override_file = os.path.join(
test_path(), test_path(),
"merge/reset_and_override_tags/override_tag_service/docker-compose.override_service.yaml", "merge/reset_and_override_tags/override_tag_service/docker-compose.override_service.yaml",

View File

@ -8,7 +8,7 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join( return os.path.join(
test_path(), test_path(),
"merge/reset_and_override_tags/reset_tag_attribute/docker-compose.yaml", "merge/reset_and_override_tags/reset_tag_attribute/docker-compose.yaml",
@ -17,7 +17,7 @@ def compose_yaml_path():
class TestComposeResetTagAttribute(unittest.TestCase, RunSubprocessMixin): class TestComposeResetTagAttribute(unittest.TestCase, RunSubprocessMixin):
# test if the attribute of the service is correctly reset # test if the attribute of the service is correctly reset
def test_reset_tag_attribute(self): def test_reset_tag_attribute(self) -> None:
reset_file = os.path.join( reset_file = os.path.join(
test_path(), test_path(),
"merge/reset_and_override_tags/reset_tag_attribute/docker-compose.reset_attribute.yaml", "merge/reset_and_override_tags/reset_tag_attribute/docker-compose.reset_attribute.yaml",

View File

@ -8,7 +8,7 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join( return os.path.join(
test_path(), "merge/reset_and_override_tags/reset_tag_service/docker-compose.yaml" test_path(), "merge/reset_and_override_tags/reset_tag_service/docker-compose.yaml"
) )
@ -16,7 +16,7 @@ def compose_yaml_path():
class TestComposeResetTagService(unittest.TestCase, RunSubprocessMixin): class TestComposeResetTagService(unittest.TestCase, RunSubprocessMixin):
# test if whole service from docker-compose.yaml file is reset # test if whole service from docker-compose.yaml file is reset
def test_reset_tag_service(self): def test_reset_tag_service(self) -> None:
reset_file = os.path.join( reset_file = os.path.join(
test_path(), test_path(),
"merge/reset_and_override_tags/reset_tag_service/docker-compose.reset_service.yaml", "merge/reset_and_override_tags/reset_tag_service/docker-compose.reset_service.yaml",

View File

@ -9,14 +9,14 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(compose_name): def compose_yaml_path(compose_name: str) -> str:
""" "Returns the path to the compose file used for this test module""" """ "Returns the path to the compose file used for this test module"""
base_path = os.path.join(test_path(), "merge/volumes_merge/") base_path = os.path.join(test_path(), "merge/volumes_merge/")
return os.path.join(base_path, compose_name) return os.path.join(base_path, compose_name)
class TestComposeVolumesMerge(unittest.TestCase, RunSubprocessMixin): class TestComposeVolumesMerge(unittest.TestCase, RunSubprocessMixin):
def test_volumes_merge(self): def test_volumes_merge(self) -> None:
# test if additional compose file overrides host path and access mode of a volume # test if additional compose file overrides host path and access mode of a volume
try: try:
self.run_subprocess_assert_returncode([ self.run_subprocess_assert_returncode([

View File

@ -8,12 +8,12 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join(os.path.join(test_path(), "multicompose"), "docker-compose.yml") return os.path.join(os.path.join(test_path(), "multicompose"), "docker-compose.yml")
class TestComposeMulticompose(unittest.TestCase, RunSubprocessMixin): class TestComposeMulticompose(unittest.TestCase, RunSubprocessMixin):
def test_multicompose(self): def test_multicompose(self) -> None:
try: try:
self.run_subprocess_assert_returncode( self.run_subprocess_assert_returncode(
[ [

View File

@ -10,20 +10,20 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join(os.path.join(test_path(), "nethost"), "docker-compose.yaml") return os.path.join(os.path.join(test_path(), "nethost"), "docker-compose.yaml")
class TestComposeNethost(unittest.TestCase, RunSubprocessMixin): class TestComposeNethost(unittest.TestCase, RunSubprocessMixin):
# check if container listens for http requests and sends response back # check if container listens for http requests and sends response back
# as network_mode: host allows to connect to container easily # as network_mode: host allows to connect to container easily
def test_nethost(self): def test_nethost(self) -> None:
try: try:
self.run_subprocess_assert_returncode( self.run_subprocess_assert_returncode(
[podman_compose_path(), "-f", compose_yaml_path(), "up", "-d"], [podman_compose_path(), "-f", compose_yaml_path(), "up", "-d"],
) )
container_id, _ = self.run_subprocess_assert_returncode( container_id_out, _ = self.run_subprocess_assert_returncode(
[ [
podman_compose_path(), podman_compose_path(),
"-f", "-f",
@ -33,7 +33,7 @@ class TestComposeNethost(unittest.TestCase, RunSubprocessMixin):
'{{.ID}}', '{{.ID}}',
], ],
) )
container_id = container_id.decode('utf-8').split('\n')[0] container_id = container_id_out.decode('utf-8').split('\n')[0]
output, _ = self.run_subprocess_assert_returncode( output, _ = self.run_subprocess_assert_returncode(
[ [
"podman", "podman",

View File

@ -11,13 +11,13 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join(os.path.join(test_path(), "nets_test1"), "docker-compose.yml") return os.path.join(os.path.join(test_path(), "nets_test1"), "docker-compose.yml")
class TestComposeNetsTest1(unittest.TestCase, RunSubprocessMixin): class TestComposeNetsTest1(unittest.TestCase, RunSubprocessMixin):
# test if port mapping works as expected # test if port mapping works as expected
def test_nets_test1(self): def test_nets_test1(self) -> None:
try: try:
self.run_subprocess_assert_returncode( self.run_subprocess_assert_returncode(
[ [

View File

@ -11,13 +11,13 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join(os.path.join(test_path(), "nets_test2"), "docker-compose.yml") return os.path.join(os.path.join(test_path(), "nets_test2"), "docker-compose.yml")
class TestComposeNetsTest2(unittest.TestCase, RunSubprocessMixin): class TestComposeNetsTest2(unittest.TestCase, RunSubprocessMixin):
# test if port mapping works as expected with networks top-level element # test if port mapping works as expected with networks top-level element
def test_nets_test2(self): def test_nets_test2(self) -> None:
try: try:
self.run_subprocess_assert_returncode( self.run_subprocess_assert_returncode(
[ [

View File

@ -10,7 +10,7 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join(os.path.join(test_path(), "nets_test3"), "docker-compose.yml") return os.path.join(os.path.join(test_path(), "nets_test3"), "docker-compose.yml")
@ -28,8 +28,12 @@ class TestComposeNetsTest3(unittest.TestCase, RunSubprocessMixin):
("nets_test3_web1_1", "alias21", b"", 1), ("nets_test3_web1_1", "alias21", b"", 1),
]) ])
def test_nets_test3( def test_nets_test3(
self, container_name, nework_alias_name, expected_text, expected_returncode self,
): container_name: str,
nework_alias_name: str,
expected_text: bytes,
expected_returncode: int,
) -> None:
try: try:
self.run_subprocess_assert_returncode( self.run_subprocess_assert_returncode(
[ [

View File

@ -8,14 +8,14 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join(os.path.join(test_path(), "nets_test_ip"), "docker-compose.yml") return os.path.join(os.path.join(test_path(), "nets_test_ip"), "docker-compose.yml")
class TestComposeNetsTestIp(unittest.TestCase, RunSubprocessMixin): class TestComposeNetsTestIp(unittest.TestCase, RunSubprocessMixin):
# test if services retain custom ipv4_address and mac_address matching the subnet provided # test if services retain custom ipv4_address and mac_address matching the subnet provided
# in networks top-level element # in networks top-level element
def test_nets_test_ip(self): def test_nets_test_ip(self) -> None:
try: try:
self.run_subprocess_assert_returncode( self.run_subprocess_assert_returncode(
[ [

View File

@ -9,6 +9,7 @@ Tests the podman networking parameters
# pylint: disable=redefined-outer-name # pylint: disable=redefined-outer-name
import os import os
import unittest import unittest
from typing import Generator
from tests.integration.test_utils import RunSubprocessMixin from tests.integration.test_utils import RunSubprocessMixin
from tests.integration.test_utils import podman_compose_path from tests.integration.test_utils import podman_compose_path
@ -17,11 +18,11 @@ from tests.integration.test_utils import test_path
class TestPodmanComposeNetwork(RunSubprocessMixin, unittest.TestCase): class TestPodmanComposeNetwork(RunSubprocessMixin, unittest.TestCase):
@staticmethod @staticmethod
def compose_file(): def compose_file() -> str:
"""Returns the path to the compose file used for this test module""" """Returns the path to the compose file used for this test module"""
return os.path.join(test_path(), "nets_test_ip", "docker-compose.yml") return os.path.join(test_path(), "nets_test_ip", "docker-compose.yml")
def teardown(self): def teardown(self) -> Generator[None, None, None]:
""" """
Ensures that the services within the "profile compose file" are removed between Ensures that the services within the "profile compose file" are removed between
each test case. each test case.
@ -40,7 +41,7 @@ class TestPodmanComposeNetwork(RunSubprocessMixin, unittest.TestCase):
] ]
self.run_subprocess(down_cmd) self.run_subprocess(down_cmd)
def test_networks(self): def test_networks(self) -> None:
up_cmd = [ up_cmd = [
"coverage", "coverage",
"run", "run",
@ -115,7 +116,7 @@ class TestPodmanComposeNetwork(RunSubprocessMixin, unittest.TestCase):
self.assertIn(f"ether {mac}", out.decode('utf-8')) self.assertIn(f"ether {mac}", out.decode('utf-8'))
self.assertIn(f"inet {ip}/", out.decode('utf-8')) self.assertIn(f"inet {ip}/", out.decode('utf-8'))
def test_down_with_network(self): def test_down_with_network(self) -> None:
try: try:
self.run_subprocess_assert_returncode([ self.run_subprocess_assert_returncode([
"coverage", "coverage",

View File

@ -10,10 +10,10 @@ from tests.integration.test_utils import test_path
class TestPodmanComposeNetworkInterfaceName(RunSubprocessMixin, unittest.TestCase): class TestPodmanComposeNetworkInterfaceName(RunSubprocessMixin, unittest.TestCase):
def compose_file(self): def compose_file(self) -> str:
return os.path.join(test_path(), "network_interface_name", "docker-compose.yml") return os.path.join(test_path(), "network_interface_name", "docker-compose.yml")
def up(self): def up(self) -> None:
up_cmd = [ up_cmd = [
"coverage", "coverage",
"run", "run",
@ -26,7 +26,7 @@ class TestPodmanComposeNetworkInterfaceName(RunSubprocessMixin, unittest.TestCas
] ]
self.run_subprocess_assert_returncode(up_cmd) self.run_subprocess_assert_returncode(up_cmd)
def down(self): def down(self) -> None:
down_cmd = [ down_cmd = [
"coverage", "coverage",
"run", "run",
@ -38,7 +38,7 @@ class TestPodmanComposeNetworkInterfaceName(RunSubprocessMixin, unittest.TestCas
] ]
self.run_subprocess(down_cmd) self.run_subprocess(down_cmd)
def test_interface_name(self): def test_interface_name(self) -> None:
try: try:
self.up() self.up()

View File

@ -11,18 +11,18 @@ from tests.integration.test_utils import test_path
class TestPodmanComposeNetworkScopedAliases(RunSubprocessMixin, unittest.TestCase): class TestPodmanComposeNetworkScopedAliases(RunSubprocessMixin, unittest.TestCase):
@staticmethod @staticmethod
def compose_file(): def compose_file() -> str:
"""Returns the path to the compose file used for this test module""" """Returns the path to the compose file used for this test module"""
return os.path.join(test_path(), "network_scoped_aliases", "docker-compose.yaml") return os.path.join(test_path(), "network_scoped_aliases", "docker-compose.yaml")
def test_network_scoped_aliases(self): def test_network_scoped_aliases(self) -> None:
try: try:
self.up() self.up()
self.verify() self.verify()
finally: finally:
self.down() self.down()
def up(self): def up(self) -> None:
up_cmd = [ up_cmd = [
"coverage", "coverage",
"run", "run",
@ -36,7 +36,7 @@ class TestPodmanComposeNetworkScopedAliases(RunSubprocessMixin, unittest.TestCas
self.run_subprocess_assert_returncode(up_cmd) self.run_subprocess_assert_returncode(up_cmd)
def down(self): def down(self) -> None:
down_cmd = [ down_cmd = [
"coverage", "coverage",
"run", "run",
@ -48,7 +48,7 @@ class TestPodmanComposeNetworkScopedAliases(RunSubprocessMixin, unittest.TestCas
] ]
self.run_subprocess(down_cmd) self.run_subprocess(down_cmd)
def verify(self): def verify(self) -> None:
expected_results = [ expected_results = [
("utils-net0", "web1", ["172.19.3.11"]), ("utils-net0", "web1", ["172.19.3.11"]),
("utils-net0", "secure-web", ["172.19.3.11"]), ("utils-net0", "secure-web", ["172.19.3.11"]),
@ -72,7 +72,7 @@ class TestPodmanComposeNetworkScopedAliases(RunSubprocessMixin, unittest.TestCas
addresses = self.parse_dnslookup(out.decode()) addresses = self.parse_dnslookup(out.decode())
self.assertEqual(addresses, expected_result) self.assertEqual(addresses, expected_result)
def parse_dnslookup(self, output): def parse_dnslookup(self, output: str) -> list[str]:
lines = output.splitlines() lines = output.splitlines()
addresses = [] addresses = []
for line in lines: for line in lines:

View File

@ -8,13 +8,13 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join(os.path.join(test_path(), "no_services"), "docker-compose.yaml") return os.path.join(os.path.join(test_path(), "no_services"), "docker-compose.yaml")
class TestComposeNoServices(unittest.TestCase, RunSubprocessMixin): class TestComposeNoServices(unittest.TestCase, RunSubprocessMixin):
# test if a network was created, but not the services # test if a network was created, but not the services
def test_no_services(self): def test_no_services(self) -> None:
try: try:
output, return_code = self.run_subprocess_assert_returncode( output, return_code = self.run_subprocess_assert_returncode(
[ [

View File

@ -7,23 +7,23 @@ import unittest
from tests.integration.test_utils import RunSubprocessMixin from tests.integration.test_utils import RunSubprocessMixin
def base_path(): def base_path() -> str:
"""Returns the base path for the project""" """Returns the base path for the project"""
return os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) return os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
def test_path(): def test_path() -> str:
"""Returns the path to the tests directory""" """Returns the path to the tests directory"""
return os.path.join(base_path(), "tests/integration") return os.path.join(base_path(), "tests/integration")
def podman_compose_path(): def podman_compose_path() -> str:
"""Returns the path to the podman compose script""" """Returns the path to the podman compose script"""
return os.path.join(base_path(), "podman_compose.py") return os.path.join(base_path(), "podman_compose.py")
class TestPodmanComposePodArgs(unittest.TestCase, RunSubprocessMixin): class TestPodmanComposePodArgs(unittest.TestCase, RunSubprocessMixin):
def load_pod_info(self, pod_name): def load_pod_info(self, pod_name: str) -> dict:
output, _ = self.run_subprocess_assert_returncode([ output, _ = self.run_subprocess_assert_returncode([
"podman", "podman",
"pod", "pod",
@ -37,7 +37,7 @@ class TestPodmanComposePodArgs(unittest.TestCase, RunSubprocessMixin):
return pod_info[0] return pod_info[0]
return pod_info return pod_info
def run_pod_args_test(self, config, args, expected): def run_pod_args_test(self, config: str, args: list, expected: list) -> None:
""" """
Helper to run podman up with a docker-compose.yml config, additional Helper to run podman up with a docker-compose.yml config, additional
(--pod-args) arguments and compare the CreateCommand of the resulting (--pod-args) arguments and compare the CreateCommand of the resulting
@ -78,7 +78,7 @@ class TestPodmanComposePodArgs(unittest.TestCase, RunSubprocessMixin):
command_rm_pod = ["podman", "pod", "rm", pod_name] command_rm_pod = ["podman", "pod", "rm", pod_name]
self.run_subprocess_assert_returncode(command_rm_pod) self.run_subprocess_assert_returncode(command_rm_pod)
def test_x_podman_pod_args_unset_unset(self): def test_x_podman_pod_args_unset_unset(self) -> None:
""" """
Test that podman-compose will use the default pod-args when unset in Test that podman-compose will use the default pod-args when unset in
both docker-compose.yml and command line both docker-compose.yml and command line
@ -89,7 +89,7 @@ class TestPodmanComposePodArgs(unittest.TestCase, RunSubprocessMixin):
["--infra=false", "--share="], ["--infra=false", "--share="],
) )
def test_x_podman_pod_args_unset_empty(self): def test_x_podman_pod_args_unset_empty(self) -> None:
""" """
Test that podman-compose will use empty pod-args when unset in Test that podman-compose will use empty pod-args when unset in
docker-compose.yml and passing an empty value on the command line docker-compose.yml and passing an empty value on the command line
@ -100,7 +100,7 @@ class TestPodmanComposePodArgs(unittest.TestCase, RunSubprocessMixin):
[], [],
) )
def test_x_podman_pod_args_unset_set(self): def test_x_podman_pod_args_unset_set(self) -> None:
""" """
Test that podman-compose will use the passed pod-args when unset in Test that podman-compose will use the passed pod-args when unset in
docker-compose.yml and passing a non-empty value on the command line docker-compose.yml and passing a non-empty value on the command line
@ -111,7 +111,7 @@ class TestPodmanComposePodArgs(unittest.TestCase, RunSubprocessMixin):
["--infra=false", "--share=", "--cpus=1"], ["--infra=false", "--share=", "--cpus=1"],
) )
def test_x_podman_pod_args_empty_unset(self): def test_x_podman_pod_args_empty_unset(self) -> None:
""" """
Test that podman-compose will use empty pod-args when set to an Test that podman-compose will use empty pod-args when set to an
empty value in docker-compose.yml and unset on the command line empty value in docker-compose.yml and unset on the command line
@ -122,7 +122,7 @@ class TestPodmanComposePodArgs(unittest.TestCase, RunSubprocessMixin):
[], [],
) )
def test_x_podman_pod_args_empty_empty(self): def test_x_podman_pod_args_empty_empty(self) -> None:
""" """
Test that podman-compose will use empty pod-args when set to an Test that podman-compose will use empty pod-args when set to an
empty value in both docker-compose.yml and command line empty value in both docker-compose.yml and command line
@ -133,7 +133,7 @@ class TestPodmanComposePodArgs(unittest.TestCase, RunSubprocessMixin):
[], [],
) )
def test_x_podman_pod_args_empty_set(self): def test_x_podman_pod_args_empty_set(self) -> None:
""" """
Test that podman-compose will use the passed pod-args when set to an Test that podman-compose will use the passed pod-args when set to an
empty value in docker-compose.yml and passing a non-empty value on the empty value in docker-compose.yml and passing a non-empty value on the
@ -145,7 +145,7 @@ class TestPodmanComposePodArgs(unittest.TestCase, RunSubprocessMixin):
["--infra=false", "--share=", "--cpus=1"], ["--infra=false", "--share=", "--cpus=1"],
) )
def test_x_podman_pod_args_set_unset(self): def test_x_podman_pod_args_set_unset(self) -> None:
""" """
Test that podman-compose will use the set pod-args when set to a Test that podman-compose will use the set pod-args when set to a
non-empty value in docker-compose.yml and unset on the command line non-empty value in docker-compose.yml and unset on the command line
@ -156,7 +156,7 @@ class TestPodmanComposePodArgs(unittest.TestCase, RunSubprocessMixin):
["--infra=false", "--share=", "--cpus=2"], ["--infra=false", "--share=", "--cpus=2"],
) )
def test_x_podman_pod_args_set_empty(self): def test_x_podman_pod_args_set_empty(self) -> None:
""" """
Test that podman-compose will use empty pod-args when set to a Test that podman-compose will use empty pod-args when set to a
non-empty value in docker-compose.yml and passing an empty value on non-empty value in docker-compose.yml and passing an empty value on
@ -168,7 +168,7 @@ class TestPodmanComposePodArgs(unittest.TestCase, RunSubprocessMixin):
[], [],
) )
def test_x_podman_pod_args_set_set(self): def test_x_podman_pod_args_set_set(self) -> None:
""" """
Test that podman-compose will use the passed pod-args when set to a Test that podman-compose will use the passed pod-args when set to a
non-empty value in both docker-compose.yml and command line non-empty value in both docker-compose.yml and command line

View File

@ -15,7 +15,7 @@ from tests.integration.test_utils import test_path
class TestPodmanCompose(unittest.TestCase, RunSubprocessMixin): class TestPodmanCompose(unittest.TestCase, RunSubprocessMixin):
def test_up_with_ports(self): def test_up_with_ports(self) -> None:
up_cmd = [ up_cmd = [
"coverage", "coverage",
"run", "run",

View File

@ -17,13 +17,13 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def profile_compose_file(): def profile_compose_file() -> str:
""" "Returns the path to the `profile` compose file used for this test module""" """ "Returns the path to the `profile` compose file used for this test module"""
return os.path.join(test_path(), "profile", "docker-compose.yml") return os.path.join(test_path(), "profile", "docker-compose.yml")
class TestComposeConfig(unittest.TestCase, RunSubprocessMixin): class TestComposeConfig(unittest.TestCase, RunSubprocessMixin):
def test_config_no_profiles(self): def test_config_no_profiles(self) -> None:
""" """
Tests podman-compose config command without profile enablement. Tests podman-compose config command without profile enablement.
""" """
@ -59,7 +59,7 @@ class TestComposeConfig(unittest.TestCase, RunSubprocessMixin):
), ),
], ],
) )
def test_config_profiles(self, profiles, expected_services): def test_config_profiles(self, profiles: list, expected_services: dict) -> None:
""" """
Tests podman-compose Tests podman-compose
:param profiles: The enabled profiles for the parameterized test. :param profiles: The enabled profiles for the parameterized test.
@ -81,7 +81,7 @@ class TestComposeConfig(unittest.TestCase, RunSubprocessMixin):
self.assertEqual(expected_services, actual_services) self.assertEqual(expected_services, actual_services)
def test_config_quiet(self): def test_config_quiet(self) -> None:
""" """
Tests podman-compose config command with the --quiet flag. Tests podman-compose config command with the --quiet flag.
""" """

View File

@ -9,6 +9,7 @@ Tests the podman compose up and down commands used to create and remove services
# pylint: disable=redefined-outer-name # pylint: disable=redefined-outer-name
import os import os
import unittest import unittest
from typing import List
from parameterized import parameterized from parameterized import parameterized
@ -17,13 +18,13 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def profile_compose_file(): def profile_compose_file() -> str:
""" "Returns the path to the `profile` compose file used for this test module""" """ "Returns the path to the `profile` compose file used for this test module"""
return os.path.join(test_path(), "profile", "docker-compose.yml") return os.path.join(test_path(), "profile", "docker-compose.yml")
class TestUpDown(unittest.TestCase, RunSubprocessMixin): class TestUpDown(unittest.TestCase, RunSubprocessMixin):
def tearDown(self): def tearDown(self) -> None:
""" """
Ensures that the services within the "profile compose file" are removed between each test Ensures that the services within the "profile compose file" are removed between each test
case. case.
@ -60,7 +61,7 @@ class TestUpDown(unittest.TestCase, RunSubprocessMixin):
), ),
], ],
) )
def test_up(self, profiles, expected_services): def test_up(self, profiles: List[str], expected_services: dict) -> None:
up_cmd = [ up_cmd = [
"coverage", "coverage",
"run", "run",

View File

@ -8,7 +8,7 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join(os.path.join(test_path(), "seccomp"), "docker-compose.yml") return os.path.join(os.path.join(test_path(), "seccomp"), "docker-compose.yml")
@ -20,7 +20,7 @@ class TestComposeSeccomp(unittest.TestCase, RunSubprocessMixin):
) )
# test if seccomp uses custom seccomp profile file 'default.json' where command mkdir is not # test if seccomp uses custom seccomp profile file 'default.json' where command mkdir is not
# allowed # allowed
def test_seccomp(self): def test_seccomp(self) -> None:
try: try:
output, _, return_code = self.run_subprocess( output, _, return_code = self.run_subprocess(
[podman_compose_path(), "-f", compose_yaml_path(), "run", "--rm", "web1"], [podman_compose_path(), "-f", compose_yaml_path(), "run", "--rm", "web1"],

View File

@ -10,7 +10,7 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(): def compose_yaml_path() -> str:
return os.path.join(os.path.join(test_path(), "secrets"), "docker-compose.yaml") return os.path.join(os.path.join(test_path(), "secrets"), "docker-compose.yaml")
@ -22,12 +22,12 @@ class TestComposeNoSecrets(unittest.TestCase, RunSubprocessMixin):
"podman_compose_test_secret_custom_name", "podman_compose_test_secret_custom_name",
] ]
def setUp(self): def setUp(self) -> None:
for secret in self.created_secrets: for secret in self.created_secrets:
p = Popen(["podman", "secret", "create", secret, "-"], stdin=PIPE) p = Popen(["podman", "secret", "create", secret, "-"], stdin=PIPE)
p.communicate(secret.encode('utf-8')) p.communicate(secret.encode('utf-8'))
def tearDown(self): def tearDown(self) -> None:
for secret in self.created_secrets: for secret in self.created_secrets:
self.run_subprocess_assert_returncode([ self.run_subprocess_assert_returncode([
"podman", "podman",
@ -37,7 +37,7 @@ class TestComposeNoSecrets(unittest.TestCase, RunSubprocessMixin):
]) ])
# test if secrets are saved and available in respective files of a container # test if secrets are saved and available in respective files of a container
def test_secrets(self): def test_secrets(self) -> None:
try: try:
_, error, _ = self.run_subprocess( _, error, _ = self.run_subprocess(
[ [

View File

@ -11,7 +11,7 @@ from tests.integration.test_utils import test_path
class TestPodmanCompose(unittest.TestCase, RunSubprocessMixin): class TestPodmanCompose(unittest.TestCase, RunSubprocessMixin):
def test_selinux(self): def test_selinux(self) -> None:
# test if when using volumes type:bind with selinux:z option, container ackquires a # test if when using volumes type:bind with selinux:z option, container ackquires a
# respective host:source:z mapping in CreateCommand list # respective host:source:z mapping in CreateCommand list
compose_path = os.path.join(test_path(), "selinux", "docker-compose.yml") compose_path = os.path.join(test_path(), "selinux", "docker-compose.yml")

View File

@ -8,13 +8,13 @@ from tests.integration.test_utils import podman_compose_path
from tests.integration.test_utils import test_path from tests.integration.test_utils import test_path
def compose_yaml_path(test_ref_folder): def compose_yaml_path(test_ref_folder: str) -> str:
return os.path.join(test_path(), "service_scale", test_ref_folder, "docker-compose.yml") return os.path.join(test_path(), "service_scale", test_ref_folder, "docker-compose.yml")
class TestComposeScale(unittest.TestCase, RunSubprocessMixin): class TestComposeScale(unittest.TestCase, RunSubprocessMixin):
# scale-up using `scale` prarmeter in docker-compose.yml # scale-up using `scale` prarmeter in docker-compose.yml
def test_scaleup_scale_parameter(self): def test_scaleup_scale_parameter(self) -> None:
try: try:
output, _, return_code = self.run_subprocess([ output, _, return_code = self.run_subprocess([
podman_compose_path(), podman_compose_path(),
@ -43,7 +43,7 @@ class TestComposeScale(unittest.TestCase, RunSubprocessMixin):
]) ])
# scale-up using `deploy => replicas` prarmeter in docker-compose.yml # scale-up using `deploy => replicas` prarmeter in docker-compose.yml
def test_scaleup_deploy_replicas_parameter(self): def test_scaleup_deploy_replicas_parameter(self) -> None:
try: try:
output, _, return_code = self.run_subprocess([ output, _, return_code = self.run_subprocess([
podman_compose_path(), podman_compose_path(),
@ -72,7 +72,7 @@ class TestComposeScale(unittest.TestCase, RunSubprocessMixin):
]) ])
# scale-up using `--scale <SERVICE>=<number of replicas>` argument in CLI # scale-up using `--scale <SERVICE>=<number of replicas>` argument in CLI
def test_scaleup_cli(self): def test_scaleup_cli(self) -> None:
try: try:
output, _, return_code = self.run_subprocess([ output, _, return_code = self.run_subprocess([
podman_compose_path(), podman_compose_path(),

View File

@ -7,22 +7,22 @@ import time
from pathlib import Path from pathlib import Path
def base_path(): def base_path() -> Path:
"""Returns the base path for the project""" """Returns the base path for the project"""
return Path(__file__).parent.parent.parent return Path(__file__).parent.parent.parent
def test_path(): def test_path() -> str:
"""Returns the path to the tests directory""" """Returns the path to the tests directory"""
return os.path.join(base_path(), "tests/integration") return os.path.join(base_path(), "tests/integration")
def podman_compose_path(): def podman_compose_path() -> str:
"""Returns the path to the podman compose script""" """Returns the path to the podman compose script"""
return os.path.join(base_path(), "podman_compose.py") return os.path.join(base_path(), "podman_compose.py")
def is_systemd_available(): def is_systemd_available() -> bool:
try: try:
with open("/proc/1/comm", "r", encoding="utf-8") as fh: with open("/proc/1/comm", "r", encoding="utf-8") as fh:
return fh.read().strip() == "systemd" return fh.read().strip() == "systemd"
@ -31,10 +31,10 @@ def is_systemd_available():
class RunSubprocessMixin: class RunSubprocessMixin:
def is_debug_enabled(self): def is_debug_enabled(self) -> bool:
return "TESTS_DEBUG" in os.environ return "TESTS_DEBUG" in os.environ
def run_subprocess(self, args): def run_subprocess(self, args: list[str]) -> tuple[bytes, bytes, int]:
begin = time.time() begin = time.time()
if self.is_debug_enabled(): if self.is_debug_enabled():
print("TEST_CALL", args) print("TEST_CALL", args)
@ -50,11 +50,13 @@ class RunSubprocessMixin:
print("STDERR:", err.decode('utf-8')) print("STDERR:", err.decode('utf-8'))
return out, err, proc.returncode return out, err, proc.returncode
def run_subprocess_assert_returncode(self, args, expected_returncode=0): def run_subprocess_assert_returncode(
self, args: list[str], expected_returncode: int = 0
) -> tuple[bytes, bytes]:
out, err, returncode = self.run_subprocess(args) out, err, returncode = self.run_subprocess(args)
decoded_out = out.decode('utf-8') decoded_out = out.decode('utf-8')
decoded_err = err.decode('utf-8') decoded_err = err.decode('utf-8')
self.assertEqual( self.assertEqual( # type: ignore[attr-defined]
returncode, returncode,
expected_returncode, expected_returncode,
f"Invalid return code of process {returncode} != {expected_returncode}\n" f"Invalid return code of process {returncode} != {expected_returncode}\n"
@ -64,7 +66,7 @@ class RunSubprocessMixin:
class PodmanAwareRunSubprocessMixin(RunSubprocessMixin): class PodmanAwareRunSubprocessMixin(RunSubprocessMixin):
def retrieve_podman_version(self): def retrieve_podman_version(self) -> tuple[int, int, int]:
out, _ = self.run_subprocess_assert_returncode(["podman", "--version"]) out, _ = self.run_subprocess_assert_returncode(["podman", "--version"])
matcher = re.match(r"\D*(\d+)\.(\d+)\.(\d+)", out.decode('utf-8')) matcher = re.match(r"\D*(\d+)\.(\d+)\.(\d+)", out.decode('utf-8'))
if matcher: if matcher:

View File

@ -10,7 +10,7 @@ from tests.integration.test_utils import test_path
class TestPodmanCompose(unittest.TestCase, RunSubprocessMixin): class TestPodmanCompose(unittest.TestCase, RunSubprocessMixin):
def test_uidmaps(self): def test_uidmaps(self) -> None:
compose_path = os.path.join(test_path(), "uidmaps", "docker-compose.yml") compose_path = os.path.join(test_path(), "uidmaps", "docker-compose.yml")
try: try:
self.run_subprocess_assert_returncode([ self.run_subprocess_assert_returncode([

View File

@ -10,7 +10,7 @@ from tests.integration.test_utils import test_path
class TestUlimit(unittest.TestCase, RunSubprocessMixin): class TestUlimit(unittest.TestCase, RunSubprocessMixin):
def test_ulimit(self): def test_ulimit(self) -> None:
compose_path = os.path.join(test_path(), "ulimit/docker-compose.yaml") compose_path = os.path.join(test_path(), "ulimit/docker-compose.yaml")
try: try:
self.run_subprocess_assert_returncode([ self.run_subprocess_assert_returncode([

View File

@ -26,7 +26,7 @@ class TestPodmanCompose(unittest.TestCase, RunSubprocessMixin):
"--force-recreate", "--force-recreate",
] ]
def setUp(self): def setUp(self) -> None:
""" """
Retag the debian image before each test to no mess with the other integration tests when Retag the debian image before each test to no mess with the other integration tests when
testing the `--rmi` argument testing the `--rmi` argument
@ -40,7 +40,7 @@ class TestPodmanCompose(unittest.TestCase, RunSubprocessMixin):
self.run_subprocess_assert_returncode(tag_cmd) self.run_subprocess_assert_returncode(tag_cmd)
@classmethod @classmethod
def tearDownClass(cls): def tearDownClass(cls) -> None:
""" """
Ensures that the images that were created for this tests will be removed Ensures that the images that were created for this tests will be removed
""" """
@ -54,7 +54,7 @@ class TestPodmanCompose(unittest.TestCase, RunSubprocessMixin):
] ]
cls().run_subprocess_assert_returncode(rmi_cmd) cls().run_subprocess_assert_returncode(rmi_cmd)
def test_down(self): def test_down(self) -> None:
down_cmd = [ down_cmd = [
"coverage", "coverage",
"run", "run",
@ -116,7 +116,7 @@ class TestPodmanCompose(unittest.TestCase, RunSubprocessMixin):
"docker.io/library/debian:up-down-test", "docker.io/library/debian:up-down-test",
]) ])
def test_down_with_volumes(self): def test_down_with_volumes(self) -> None:
down_cmd = [ down_cmd = [
"coverage", "coverage",
"run", "run",
@ -179,7 +179,7 @@ class TestPodmanCompose(unittest.TestCase, RunSubprocessMixin):
"docker.io/library/debian:up-down-test", "docker.io/library/debian:up-down-test",
]) ])
def test_down_without_orphans(self): def test_down_without_orphans(self) -> None:
down_cmd = [ down_cmd = [
"coverage", "coverage",
"run", "run",
@ -258,7 +258,7 @@ class TestPodmanCompose(unittest.TestCase, RunSubprocessMixin):
) )
self.run_subprocess_assert_returncode(["podman", "volume", "exists", "up_down_web2_vol"], 1) self.run_subprocess_assert_returncode(["podman", "volume", "exists", "up_down_web2_vol"], 1)
def test_down_with_orphans(self): def test_down_with_orphans(self) -> None:
down_cmd = [ down_cmd = [
"coverage", "coverage",
"run", "run",
@ -322,7 +322,7 @@ class TestPodmanCompose(unittest.TestCase, RunSubprocessMixin):
"docker.io/library/debian:up-down-test", "docker.io/library/debian:up-down-test",
]) ])
def test_down_with_images_default(self): def test_down_with_images_default(self) -> None:
down_cmd = [ down_cmd = [
"coverage", "coverage",
"run", "run",
@ -379,7 +379,7 @@ class TestPodmanCompose(unittest.TestCase, RunSubprocessMixin):
["podman", "image", "exists", "docker.io/library/debian:up-down-test"], 1 ["podman", "image", "exists", "docker.io/library/debian:up-down-test"], 1
) )
def test_down_with_images_all(self): def test_down_with_images_all(self) -> None:
down_cmd = [ down_cmd = [
"coverage", "coverage",
"run", "run",
@ -437,7 +437,7 @@ class TestPodmanCompose(unittest.TestCase, RunSubprocessMixin):
["podman", "image", "exists", "docker.io/library/debian:up-down-test"], 1 ["podman", "image", "exists", "docker.io/library/debian:up-down-test"], 1
) )
def test_down_with_images_all_and_orphans(self): def test_down_with_images_all_and_orphans(self) -> None:
down_cmd = [ down_cmd = [
"coverage", "coverage",
"run", "run",
@ -497,7 +497,7 @@ class TestPodmanCompose(unittest.TestCase, RunSubprocessMixin):
["podman", "image", "exists", "docker.io/library/debian:up-down-test"], 1 ["podman", "image", "exists", "docker.io/library/debian:up-down-test"], 1
) )
def test_down_with_images_local(self): def test_down_with_images_local(self) -> None:
down_cmd = [ down_cmd = [
"coverage", "coverage",
"run", "run",

View File

@ -16,7 +16,7 @@ from tests.integration.test_utils import test_path
class TestPodmanCompose(unittest.TestCase, RunSubprocessMixin): class TestPodmanCompose(unittest.TestCase, RunSubprocessMixin):
def test_down_with_vols(self): def test_down_with_vols(self) -> None:
up_cmd = [ up_cmd = [
"coverage", "coverage",
"run", "run",

View File

@ -7,7 +7,7 @@ from podman_compose import compose_exec_args
class TestComposeExecArgs(unittest.TestCase): class TestComposeExecArgs(unittest.TestCase):
def test_minimal(self): def test_minimal(self) -> None:
cnt = get_minimal_container() cnt = get_minimal_container()
args = get_minimal_args() args = get_minimal_args()
@ -15,7 +15,7 @@ class TestComposeExecArgs(unittest.TestCase):
expected = ["--interactive", "--tty", "container_name"] expected = ["--interactive", "--tty", "container_name"]
self.assertEqual(result, expected) self.assertEqual(result, expected)
def test_additional_env_value_equals(self): def test_additional_env_value_equals(self) -> None:
cnt = get_minimal_container() cnt = get_minimal_container()
args = get_minimal_args() args = get_minimal_args()
args.env = ["key=valuepart1=valuepart2"] args.env = ["key=valuepart1=valuepart2"]
@ -31,11 +31,11 @@ class TestComposeExecArgs(unittest.TestCase):
self.assertEqual(result, expected) self.assertEqual(result, expected)
def get_minimal_container(): def get_minimal_container() -> dict:
return {} return {}
def get_minimal_args(): def get_minimal_args() -> argparse.Namespace:
return argparse.Namespace( return argparse.Namespace(
T=None, T=None,
cnt_command=None, cnt_command=None,

View File

@ -3,66 +3,67 @@
import io import io
import unittest import unittest
from typing import Union
from podman_compose import Podman from podman_compose import Podman
class DummyReader: class DummyReader:
def __init__(self, data=None): def __init__(self, data: Union[list[bytes], None] = None):
self.data = data or [] self.data = data or []
async def readuntil(self, _): async def readuntil(self, _: str) -> bytes:
return self.data.pop(0) return self.data.pop(0)
def at_eof(self): def at_eof(self) -> bool:
return len(self.data) == 0 return len(self.data) == 0
class TestComposeRunLogFormat(unittest.IsolatedAsyncioTestCase): class TestComposeRunLogFormat(unittest.IsolatedAsyncioTestCase):
def setUp(self): def setUp(self) -> None:
self.p = get_minimal_podman() self.p = get_minimal_podman()
self.buffer = io.StringIO() self.buffer = io.StringIO()
async def test_single_line_single_chunk(self): async def test_single_line_single_chunk(self) -> None:
reader = DummyReader([b'hello, world\n']) reader = DummyReader([b'hello, world\n'])
await self.p._format_stream(reader, self.buffer, 'LL:') await self.p._format_stream(reader, self.buffer, 'LL:') # type: ignore[arg-type]
self.assertEqual(self.buffer.getvalue(), 'LL: hello, world\n') self.assertEqual(self.buffer.getvalue(), 'LL: hello, world\n')
async def test_empty(self): async def test_empty(self) -> None:
reader = DummyReader([]) reader = DummyReader([])
await self.p._format_stream(reader, self.buffer, 'LL:') await self.p._format_stream(reader, self.buffer, 'LL:') # type: ignore[arg-type]
self.assertEqual(self.buffer.getvalue(), '') self.assertEqual(self.buffer.getvalue(), '')
async def test_empty2(self): async def test_empty2(self) -> None:
reader = DummyReader([b'']) reader = DummyReader([b''])
await self.p._format_stream(reader, self.buffer, 'LL:') await self.p._format_stream(reader, self.buffer, 'LL:') # type: ignore[arg-type]
self.assertEqual(self.buffer.getvalue(), '') self.assertEqual(self.buffer.getvalue(), '')
async def test_empty_line(self): async def test_empty_line(self) -> None:
reader = DummyReader([b'\n']) reader = DummyReader([b'\n'])
await self.p._format_stream(reader, self.buffer, 'LL:') await self.p._format_stream(reader, self.buffer, 'LL:') # type: ignore[arg-type]
self.assertEqual(self.buffer.getvalue(), 'LL: \n') self.assertEqual(self.buffer.getvalue(), 'LL: \n')
async def test_line_split(self): async def test_line_split(self) -> None:
reader = DummyReader([b'hello,', b' world\n']) reader = DummyReader([b'hello,', b' world\n'])
await self.p._format_stream(reader, self.buffer, 'LL:') await self.p._format_stream(reader, self.buffer, 'LL:') # type: ignore[arg-type]
self.assertEqual(self.buffer.getvalue(), 'LL: hello, world\n') self.assertEqual(self.buffer.getvalue(), 'LL: hello, world\n')
async def test_two_lines_in_one_chunk(self): async def test_two_lines_in_one_chunk(self) -> None:
reader = DummyReader([b'hello\nbye\n']) reader = DummyReader([b'hello\nbye\n'])
await self.p._format_stream(reader, self.buffer, 'LL:') await self.p._format_stream(reader, self.buffer, 'LL:') # type: ignore[arg-type]
self.assertEqual(self.buffer.getvalue(), 'LL: hello\nLL: bye\n') self.assertEqual(self.buffer.getvalue(), 'LL: hello\nLL: bye\n')
async def test_double_blank(self): async def test_double_blank(self) -> None:
reader = DummyReader([b'hello\n\n\nbye\n']) reader = DummyReader([b'hello\n\n\nbye\n'])
await self.p._format_stream(reader, self.buffer, 'LL:') await self.p._format_stream(reader, self.buffer, 'LL:') # type: ignore[arg-type]
self.assertEqual(self.buffer.getvalue(), 'LL: hello\nLL: \nLL: \nLL: bye\n') self.assertEqual(self.buffer.getvalue(), 'LL: hello\nLL: \nLL: \nLL: bye\n')
async def test_no_new_line_at_end(self): async def test_no_new_line_at_end(self) -> None:
reader = DummyReader([b'hello\nbye']) reader = DummyReader([b'hello\nbye'])
await self.p._format_stream(reader, self.buffer, 'LL:') await self.p._format_stream(reader, self.buffer, 'LL:') # type: ignore[arg-type]
self.assertEqual(self.buffer.getvalue(), 'LL: hello\nLL: bye\n') self.assertEqual(self.buffer.getvalue(), 'LL: hello\nLL: bye\n')
def get_minimal_podman(): def get_minimal_podman() -> Podman:
return Podman(None) return Podman(None) # type: ignore[arg-type]

View File

@ -8,7 +8,7 @@ from podman_compose import compose_run_update_container_from_args
class TestComposeRunUpdateContainerFromArgs(unittest.TestCase): class TestComposeRunUpdateContainerFromArgs(unittest.TestCase):
def test_minimal(self): def test_minimal(self) -> None:
cnt = get_minimal_container() cnt = get_minimal_container()
compose = get_minimal_compose() compose = get_minimal_compose()
args = get_minimal_args() args = get_minimal_args()
@ -18,7 +18,7 @@ class TestComposeRunUpdateContainerFromArgs(unittest.TestCase):
expected_cnt = {"name": "default_name", "tty": True} expected_cnt = {"name": "default_name", "tty": True}
self.assertEqual(cnt, expected_cnt) self.assertEqual(cnt, expected_cnt)
def test_additional_env_value_equals(self): def test_additional_env_value_equals(self) -> None:
cnt = get_minimal_container() cnt = get_minimal_container()
compose = get_minimal_compose() compose = get_minimal_compose()
args = get_minimal_args() args = get_minimal_args()
@ -35,7 +35,7 @@ class TestComposeRunUpdateContainerFromArgs(unittest.TestCase):
} }
self.assertEqual(cnt, expected_cnt) self.assertEqual(cnt, expected_cnt)
def test_publish_ports(self): def test_publish_ports(self) -> None:
cnt = get_minimal_container() cnt = get_minimal_container()
compose = get_minimal_compose() compose = get_minimal_compose()
args = get_minimal_args() args = get_minimal_args()
@ -51,15 +51,15 @@ class TestComposeRunUpdateContainerFromArgs(unittest.TestCase):
self.assertEqual(cnt, expected_cnt) self.assertEqual(cnt, expected_cnt)
def get_minimal_container(): def get_minimal_container() -> dict:
return {} return {}
def get_minimal_compose(): def get_minimal_compose() -> PodmanCompose:
return PodmanCompose() return PodmanCompose()
def get_minimal_args(): def get_minimal_args() -> argparse.Namespace:
return argparse.Namespace( return argparse.Namespace(
T=None, T=None,
cnt_command=None, cnt_command=None,

View File

@ -2,14 +2,16 @@
import os import os
import unittest import unittest
from typing import Any
from unittest import mock from unittest import mock
from parameterized import parameterized from parameterized import parameterized
from podman_compose import PodmanCompose
from podman_compose import container_to_args from podman_compose import container_to_args
def create_compose_mock(project_name="test_project_name"): def create_compose_mock(project_name: str = "test_project_name") -> PodmanCompose:
compose = mock.Mock() compose = mock.Mock()
compose.project_name = project_name compose.project_name = project_name
compose.dirname = "test_dirname" compose.dirname = "test_dirname"
@ -19,14 +21,14 @@ def create_compose_mock(project_name="test_project_name"):
compose.networks = {} compose.networks = {}
compose.x_podman = {} compose.x_podman = {}
async def podman_output(*args, **kwargs): async def podman_output(*args: Any, **kwargs: Any) -> None:
pass pass
compose.podman.output = mock.Mock(side_effect=podman_output) compose.podman.output = mock.Mock(side_effect=podman_output)
return compose return compose
def get_minimal_container(): def get_minimal_container() -> dict[str, Any]:
return { return {
"name": "project_name_service_name1", "name": "project_name_service_name1",
"service_name": "service_name", "service_name": "service_name",
@ -34,13 +36,13 @@ def get_minimal_container():
} }
def get_test_file_path(rel_path): def get_test_file_path(rel_path: str) -> str:
repo_root = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) repo_root = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
return os.path.realpath(os.path.join(repo_root, rel_path)) return os.path.realpath(os.path.join(repo_root, rel_path))
class TestContainerToArgs(unittest.IsolatedAsyncioTestCase): class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
async def test_minimal(self): async def test_minimal(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -56,7 +58,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_runtime(self): async def test_runtime(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -75,7 +77,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_sysctl_list(self): async def test_sysctl_list(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -99,7 +101,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_sysctl_map(self): async def test_sysctl_map(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -123,7 +125,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_sysctl_wrong_type(self): async def test_sysctl_wrong_type(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -133,7 +135,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
cnt["sysctls"] = wrong_type cnt["sysctls"] = wrong_type
await container_to_args(c, cnt) await container_to_args(c, cnt)
async def test_pid(self): async def test_pid(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -152,7 +154,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_http_proxy(self): async def test_http_proxy(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -170,7 +172,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_uidmaps_extension_old_path(self): async def test_uidmaps_extension_old_path(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -179,7 +181,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
await container_to_args(c, cnt) await container_to_args(c, cnt)
async def test_uidmaps_extension(self): async def test_uidmaps_extension(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -200,7 +202,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_gidmaps_extension(self): async def test_gidmaps_extension(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -221,7 +223,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_rootfs_extension(self): async def test_rootfs_extension(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -240,7 +242,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_no_hosts_extension(self): async def test_no_hosts_extension(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -258,7 +260,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_env_file_str(self): async def test_env_file_str(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -282,7 +284,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_env_file_str_not_exists(self): async def test_env_file_str_not_exists(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -291,7 +293,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
await container_to_args(c, cnt) await container_to_args(c, cnt)
async def test_env_file_str_array_one_path(self): async def test_env_file_str_array_one_path(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -315,7 +317,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_env_file_str_array_two_paths(self): async def test_env_file_str_array_two_paths(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -344,7 +346,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_env_file_obj_required(self): async def test_env_file_obj_required(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -368,7 +370,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_env_file_obj_required_non_existent_path(self): async def test_env_file_obj_required_non_existent_path(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -377,7 +379,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
await container_to_args(c, cnt) await container_to_args(c, cnt)
async def test_env_file_obj_optional(self): async def test_env_file_obj_optional(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -394,7 +396,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_gpu_count_all(self): async def test_gpu_count_all(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -422,7 +424,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_gpu_count_specific(self): async def test_gpu_count_specific(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -458,7 +460,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_gpu_device_ids_all(self): async def test_gpu_device_ids_all(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -492,7 +494,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_gpu_device_ids_specific(self): async def test_gpu_device_ids_specific(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -534,7 +536,9 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
(True, "z", ["-v", "./foo:/mnt:z"]), (True, "z", ["-v", "./foo:/mnt:z"]),
(True, "Z", ["-v", "./foo:/mnt:Z"]), (True, "Z", ["-v", "./foo:/mnt:Z"]),
]) ])
async def test_selinux_volume(self, prefer_volume, selinux_type, expected_additional_args): async def test_selinux_volume(
self, prefer_volume: bool, selinux_type: str, expected_additional_args: list
) -> None:
c = create_compose_mock() c = create_compose_mock()
c.prefer_volume_over_mount = prefer_volume c.prefer_volume_over_mount = prefer_volume
@ -572,7 +576,9 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
("compat_no_dash", True, "test_project_name", "test_project_name_network1"), ("compat_no_dash", True, "test_project_name", "test_project_name_network1"),
("compat_dash", True, "test_project-name", "test_projectname_network1"), ("compat_dash", True, "test_project-name", "test_projectname_network1"),
]) ])
async def test_network_default_name(self, name, is_compat, project_name, expected_network_name): async def test_network_default_name(
self, name: str, is_compat: bool, project_name: str, expected_network_name: str
) -> None:
c = create_compose_mock(project_name) c = create_compose_mock(project_name)
c.x_podman = {"default_net_name_compat": is_compat} c.x_podman = {"default_net_name_compat": is_compat}
c.networks = {'network1': {}} c.networks = {'network1': {}}
@ -591,7 +597,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_device(self): async def test_device(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
@ -613,7 +619,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_cpuset(self): async def test_cpuset(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
cnt["cpuset"] = "0-1" cnt["cpuset"] = "0-1"
@ -631,7 +637,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_pids_limit_container_level(self): async def test_pids_limit_container_level(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
cnt["pids_limit"] = 100 cnt["pids_limit"] = 100
@ -649,7 +655,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_pids_limit_deploy_section(self): async def test_pids_limit_deploy_section(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
cnt["deploy"] = {"resources": {"limits": {"pids": 100}}} cnt["deploy"] = {"resources": {"limits": {"pids": 100}}}
@ -667,7 +673,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_pids_limit_both_same(self): async def test_pids_limit_both_same(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
cnt["pids_limit"] = 100 cnt["pids_limit"] = 100
@ -686,7 +692,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_pids_limit_both_different(self): async def test_pids_limit_both_different(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
cnt["pids_limit"] = 100 cnt["pids_limit"] = 100
@ -695,7 +701,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
await container_to_args(c, cnt) await container_to_args(c, cnt)
async def test_heathcheck_string(self): async def test_healthcheck_string(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
cnt["healthcheck"] = { cnt["healthcheck"] = {
@ -715,7 +721,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_heathcheck_cmd_args(self): async def test_healthcheck_cmd_args(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
cnt["healthcheck"] = { cnt["healthcheck"] = {
@ -735,7 +741,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_heathcheck_cmd_shell(self): async def test_healthcheck_cmd_shell(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
cnt["healthcheck"] = { cnt["healthcheck"] = {
@ -755,7 +761,7 @@ class TestContainerToArgs(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_heathcheck_cmd_shell_error(self): async def test_healthcheck_cmd_shell_error(self) -> None:
c = create_compose_mock() c = create_compose_mock()
cnt = get_minimal_container() cnt = get_minimal_container()
cnt["healthcheck"] = { cnt["healthcheck"] = {

View File

@ -10,12 +10,12 @@ from tests.unit.test_container_to_args import create_compose_mock
from tests.unit.test_container_to_args import get_minimal_container from tests.unit.test_container_to_args import get_minimal_container
def repo_root(): def repo_root() -> str:
return os.path.dirname(os.path.dirname(os.path.dirname(__file__))) return os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
class TestContainerToArgsSecrets(unittest.IsolatedAsyncioTestCase): class TestContainerToArgsSecrets(unittest.IsolatedAsyncioTestCase):
async def test_pass_secret_as_env_variable(self): async def test_pass_secret_as_env_variable(self) -> None:
c = create_compose_mock() c = create_compose_mock()
c.declared_secrets = { c.declared_secrets = {
"my_secret": {"external": "true"} # must have external or name value "my_secret": {"external": "true"} # must have external or name value
@ -43,7 +43,7 @@ class TestContainerToArgsSecrets(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_secret_as_env_external_true_has_no_name(self): async def test_secret_as_env_external_true_has_no_name(self) -> None:
c = create_compose_mock() c = create_compose_mock()
c.declared_secrets = { c.declared_secrets = {
"my_secret": { "my_secret": {
@ -74,7 +74,7 @@ class TestContainerToArgsSecrets(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_pass_secret_as_env_variable_no_external(self): async def test_pass_secret_as_env_variable_no_external(self) -> None:
c = create_compose_mock() c = create_compose_mock()
c.declared_secrets = { c.declared_secrets = {
"my_secret": {} # must have external or name value "my_secret": {} # must have external or name value
@ -124,7 +124,9 @@ class TestContainerToArgsSecrets(unittest.IsolatedAsyncioTestCase):
}, },
), ),
]) ])
async def test_secret_name(self, test_name, declared_secrets, add_to_minimal_container): async def test_secret_name(
self, test_name: str, declared_secrets: dict, add_to_minimal_container: dict
) -> None:
c = create_compose_mock() c = create_compose_mock()
c.declared_secrets = declared_secrets c.declared_secrets = declared_secrets
@ -136,7 +138,7 @@ class TestContainerToArgsSecrets(unittest.IsolatedAsyncioTestCase):
await container_to_args(c, cnt) await container_to_args(c, cnt)
self.assertIn('ERROR: undeclared secret: ', str(context.exception)) self.assertIn('ERROR: undeclared secret: ', str(context.exception))
async def test_secret_string_no_external_name_in_declared_secrets(self): async def test_secret_string_no_external_name_in_declared_secrets(self) -> None:
c = create_compose_mock() c = create_compose_mock()
c.declared_secrets = {"my_secret_name": {"external": "true"}} c.declared_secrets = {"my_secret_name": {"external": "true"}}
cnt = get_minimal_container() cnt = get_minimal_container()
@ -157,7 +159,7 @@ class TestContainerToArgsSecrets(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_secret_string_options_external_name_in_declared_secrets(self): async def test_secret_string_options_external_name_in_declared_secrets(self) -> None:
c = create_compose_mock() c = create_compose_mock()
c.declared_secrets = { c.declared_secrets = {
"my_secret_name": { "my_secret_name": {
@ -195,7 +197,9 @@ class TestContainerToArgsSecrets(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_secret_string_external_name_in_declared_secrets_does_not_match_secret(self): async def test_secret_string_external_name_in_declared_secrets_does_not_match_secret(
self,
) -> None:
c = create_compose_mock() c = create_compose_mock()
c.declared_secrets = { c.declared_secrets = {
"my_secret_name": { "my_secret_name": {
@ -213,7 +217,7 @@ class TestContainerToArgsSecrets(unittest.IsolatedAsyncioTestCase):
await container_to_args(c, cnt) await container_to_args(c, cnt)
self.assertIn('ERROR: Custom name/target reference ', str(context.exception)) self.assertIn('ERROR: Custom name/target reference ', str(context.exception))
async def test_secret_target_does_not_match_secret_name_secret_type_not_env(self): async def test_secret_target_does_not_match_secret_name_secret_type_not_env(self) -> None:
c = create_compose_mock() c = create_compose_mock()
c.declared_secrets = { c.declared_secrets = {
"my_secret_name": { "my_secret_name": {
@ -234,7 +238,7 @@ class TestContainerToArgsSecrets(unittest.IsolatedAsyncioTestCase):
await container_to_args(c, cnt) await container_to_args(c, cnt)
self.assertIn('ERROR: Custom name/target reference ', str(context.exception)) self.assertIn('ERROR: Custom name/target reference ', str(context.exception))
async def test_secret_target_does_not_match_secret_name_secret_type_env(self): async def test_secret_target_does_not_match_secret_name_secret_type_env(self) -> None:
c = create_compose_mock() c = create_compose_mock()
c.declared_secrets = { c.declared_secrets = {
"my_secret_name": { "my_secret_name": {
@ -260,7 +264,7 @@ class TestContainerToArgsSecrets(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_secret_target_matches_secret_name_secret_type_not_env(self): async def test_secret_target_matches_secret_name_secret_type_not_env(self) -> None:
c = create_compose_mock() c = create_compose_mock()
c.declared_secrets = { c.declared_secrets = {
"my_secret_name": { "my_secret_name": {
@ -342,8 +346,12 @@ class TestContainerToArgsSecrets(unittest.IsolatedAsyncioTestCase):
), ),
]) ])
async def test_file_secret( async def test_file_secret(
self, test_name, declared_secrets, add_to_minimal_container, expected_volume_ref self,
): test_name: str,
declared_secrets: dict,
add_to_minimal_container: dict,
expected_volume_ref: str,
) -> None:
c = create_compose_mock() c = create_compose_mock()
c.declared_secrets = declared_secrets c.declared_secrets = declared_secrets
cnt = get_minimal_container() cnt = get_minimal_container()
@ -362,7 +370,7 @@ class TestContainerToArgsSecrets(unittest.IsolatedAsyncioTestCase):
], ],
) )
async def test_file_secret_unused_params_warning(self): async def test_file_secret_unused_params_warning(self) -> None:
c = create_compose_mock() c = create_compose_mock()
c.declared_secrets = { c.declared_secrets = {
"file_secret": { "file_secret": {

View File

@ -2,6 +2,7 @@ import unittest
from parameterized import parameterized from parameterized import parameterized
from podman_compose import PodmanCompose
from podman_compose import get_net_args from podman_compose import get_net_args
from tests.unit.test_container_to_args import create_compose_mock from tests.unit.test_container_to_args import create_compose_mock
@ -10,7 +11,7 @@ SERVICE_NAME = "service_name"
CONTAINER_NAME = f"{PROJECT_NAME}_{SERVICE_NAME}_1" CONTAINER_NAME = f"{PROJECT_NAME}_{SERVICE_NAME}_1"
def get_networked_compose(num_networks=1): def get_networked_compose(num_networks: int = 1) -> PodmanCompose:
compose = create_compose_mock(PROJECT_NAME) compose = create_compose_mock(PROJECT_NAME)
for network in range(num_networks): for network in range(num_networks):
compose.networks[f"net{network}"] = { compose.networks[f"net{network}"] = {
@ -30,7 +31,7 @@ def get_networked_compose(num_networks=1):
return compose return compose
def get_minimal_container(): def get_minimal_container() -> dict:
return { return {
"name": CONTAINER_NAME, "name": CONTAINER_NAME,
"service_name": SERVICE_NAME, "service_name": SERVICE_NAME,
@ -39,7 +40,7 @@ def get_minimal_container():
class TestGetNetArgs(unittest.TestCase): class TestGetNetArgs(unittest.TestCase):
def test_minimal(self): def test_minimal(self) -> None:
compose = get_networked_compose() compose = get_networked_compose()
container = get_minimal_container() container = get_minimal_container()
@ -49,7 +50,7 @@ class TestGetNetArgs(unittest.TestCase):
args = get_net_args(compose, container) args = get_net_args(compose, container)
self.assertListEqual(expected_args, args) self.assertListEqual(expected_args, args)
def test_default_net_is_None(self): def test_default_net_is_None(self) -> None:
compose = get_networked_compose() compose = get_networked_compose()
container = get_minimal_container() container = get_minimal_container()
@ -64,7 +65,7 @@ class TestGetNetArgs(unittest.TestCase):
args = get_net_args(compose, container) args = get_net_args(compose, container)
self.assertListEqual(expected_args, args) self.assertListEqual(expected_args, args)
def test_one_net(self): def test_one_net(self) -> None:
compose = get_networked_compose() compose = get_networked_compose()
container = get_minimal_container() container = get_minimal_container()
container["networks"] = {"net0": {}} container["networks"] = {"net0": {}}
@ -75,7 +76,7 @@ class TestGetNetArgs(unittest.TestCase):
args = get_net_args(compose, container) args = get_net_args(compose, container)
self.assertListEqual(expected_args, args) self.assertListEqual(expected_args, args)
def test_alias(self): def test_alias(self) -> None:
compose = get_networked_compose() compose = get_networked_compose()
container = get_minimal_container() container = get_minimal_container()
container["networks"] = {"net0": {}} container["networks"] = {"net0": {}}
@ -87,7 +88,7 @@ class TestGetNetArgs(unittest.TestCase):
args = get_net_args(compose, container) args = get_net_args(compose, container)
self.assertListEqual(expected_args, args) self.assertListEqual(expected_args, args)
def test_aliases_on_network_scope(self): def test_aliases_on_network_scope(self) -> None:
compose = get_networked_compose() compose = get_networked_compose()
container = get_minimal_container() container = get_minimal_container()
container["networks"] = {"net0": {"aliases": ["alias1"]}} container["networks"] = {"net0": {"aliases": ["alias1"]}}
@ -98,7 +99,7 @@ class TestGetNetArgs(unittest.TestCase):
args = get_net_args(compose, container) args = get_net_args(compose, container)
self.assertListEqual(expected_args, args) self.assertListEqual(expected_args, args)
def test_one_ipv4(self): def test_one_ipv4(self) -> None:
ip = "192.168.0.42" ip = "192.168.0.42"
compose = get_networked_compose() compose = get_networked_compose()
container = get_minimal_container() container = get_minimal_container()
@ -110,7 +111,7 @@ class TestGetNetArgs(unittest.TestCase):
args = get_net_args(compose, container) args = get_net_args(compose, container)
self.assertEqual(expected_args, args) self.assertEqual(expected_args, args)
def test_one_ipv6(self): def test_one_ipv6(self) -> None:
ipv6_address = "fd00:0::42" ipv6_address = "fd00:0::42"
compose = get_networked_compose() compose = get_networked_compose()
container = get_minimal_container() container = get_minimal_container()
@ -122,7 +123,7 @@ class TestGetNetArgs(unittest.TestCase):
args = get_net_args(compose, container) args = get_net_args(compose, container)
self.assertListEqual(expected_args, args) self.assertListEqual(expected_args, args)
def test_one_mac(self): def test_one_mac(self) -> None:
mac = "00:11:22:33:44:55" mac = "00:11:22:33:44:55"
compose = get_networked_compose() compose = get_networked_compose()
container = get_minimal_container() container = get_minimal_container()
@ -135,7 +136,7 @@ class TestGetNetArgs(unittest.TestCase):
args = get_net_args(compose, container) args = get_net_args(compose, container)
self.assertListEqual(expected_args, args) self.assertListEqual(expected_args, args)
def test_one_mac_two_nets(self): def test_one_mac_two_nets(self) -> None:
mac = "00:11:22:33:44:55" mac = "00:11:22:33:44:55"
compose = get_networked_compose(num_networks=6) compose = get_networked_compose(num_networks=6)
container = get_minimal_container() container = get_minimal_container()
@ -153,7 +154,7 @@ class TestGetNetArgs(unittest.TestCase):
"mac_address", "mac_address",
"x-podman.mac_address", "x-podman.mac_address",
]) ])
def test_mac_on_network(self, mac_attr): def test_mac_on_network(self, mac_attr: str) -> None:
mac = "00:11:22:33:44:55" mac = "00:11:22:33:44:55"
compose = get_networked_compose() compose = get_networked_compose()
container = get_minimal_container() container = get_minimal_container()
@ -165,7 +166,7 @@ class TestGetNetArgs(unittest.TestCase):
args = get_net_args(compose, container) args = get_net_args(compose, container)
self.assertListEqual(expected_args, args) self.assertListEqual(expected_args, args)
def test_two_nets_as_dict(self): def test_two_nets_as_dict(self) -> None:
compose = get_networked_compose(num_networks=2) compose = get_networked_compose(num_networks=2)
container = get_minimal_container() container = get_minimal_container()
container["networks"] = {"net0": {}, "net1": {}} container["networks"] = {"net0": {}, "net1": {}}
@ -177,7 +178,7 @@ class TestGetNetArgs(unittest.TestCase):
args = get_net_args(compose, container) args = get_net_args(compose, container)
self.assertListEqual(expected_args, args) self.assertListEqual(expected_args, args)
def test_two_nets_as_list(self): def test_two_nets_as_list(self) -> None:
compose = get_networked_compose(num_networks=2) compose = get_networked_compose(num_networks=2)
container = get_minimal_container() container = get_minimal_container()
container["networks"] = ["net0", "net1"] container["networks"] = ["net0", "net1"]
@ -189,7 +190,7 @@ class TestGetNetArgs(unittest.TestCase):
args = get_net_args(compose, container) args = get_net_args(compose, container)
self.assertListEqual(expected_args, args) self.assertListEqual(expected_args, args)
def test_two_ipv4(self): def test_two_ipv4(self) -> None:
ip0 = "192.168.0.42" ip0 = "192.168.0.42"
ip1 = "192.168.1.42" ip1 = "192.168.1.42"
compose = get_networked_compose(num_networks=2) compose = get_networked_compose(num_networks=2)
@ -203,7 +204,7 @@ class TestGetNetArgs(unittest.TestCase):
args = get_net_args(compose, container) args = get_net_args(compose, container)
self.assertListEqual(expected_args, args) self.assertListEqual(expected_args, args)
def test_two_ipv6(self): def test_two_ipv6(self) -> None:
ip0 = "fd00:0::42" ip0 = "fd00:0::42"
ip1 = "fd00:1::42" ip1 = "fd00:1::42"
compose = get_networked_compose(num_networks=2) compose = get_networked_compose(num_networks=2)
@ -218,7 +219,7 @@ class TestGetNetArgs(unittest.TestCase):
self.assertListEqual(expected_args, args) self.assertListEqual(expected_args, args)
# custom extension; not supported by docker-compose # custom extension; not supported by docker-compose
def test_two_mac(self): def test_two_mac(self) -> None:
mac0 = "00:00:00:00:00:01" mac0 = "00:00:00:00:00:01"
mac1 = "00:00:00:00:00:02" mac1 = "00:00:00:00:00:02"
compose = get_networked_compose(num_networks=2) compose = get_networked_compose(num_networks=2)
@ -235,7 +236,7 @@ class TestGetNetArgs(unittest.TestCase):
args = get_net_args(compose, container) args = get_net_args(compose, container)
self.assertListEqual(expected_args, args) self.assertListEqual(expected_args, args)
def test_mixed_mac(self): def test_mixed_mac(self) -> None:
ip4_0 = "192.168.0.42" ip4_0 = "192.168.0.42"
ip4_1 = "192.168.1.42" ip4_1 = "192.168.1.42"
ip4_2 = "192.168.2.42" ip4_2 = "192.168.2.42"
@ -256,7 +257,7 @@ class TestGetNetArgs(unittest.TestCase):
) )
self.assertRaisesRegex(RuntimeError, expected_exception, get_net_args, compose, container) self.assertRaisesRegex(RuntimeError, expected_exception, get_net_args, compose, container)
def test_mixed_config(self): def test_mixed_config(self) -> None:
ip4_0 = "192.168.0.42" ip4_0 = "192.168.0.42"
ip4_1 = "192.168.1.42" ip4_1 = "192.168.1.42"
ip6_0 = "fd00:0::42" ip6_0 = "fd00:0::42"
@ -297,7 +298,7 @@ class TestGetNetArgs(unittest.TestCase):
("ns:my_namespace", ["--network=ns:my_namespace"]), ("ns:my_namespace", ["--network=ns:my_namespace"]),
("container:my_container", ["--network=container:my_container"]), ("container:my_container", ["--network=container:my_container"]),
]) ])
def test_network_modes(self, network_mode, expected_args): def test_network_modes(self, network_mode: str, expected_args: list) -> None:
compose = get_networked_compose() compose = get_networked_compose()
container = get_minimal_container() container = get_minimal_container()
container["network_mode"] = network_mode container["network_mode"] = network_mode
@ -309,7 +310,7 @@ class TestGetNetArgs(unittest.TestCase):
args = get_net_args(compose, container) args = get_net_args(compose, container)
self.assertListEqual(expected_args, args) self.assertListEqual(expected_args, args)
def test_network_mode_invalid(self): def test_network_mode_invalid(self) -> None:
compose = get_networked_compose() compose = get_networked_compose()
container = get_minimal_container() container = get_minimal_container()
container["network_mode"] = "invalid_mode" container["network_mode"] = "invalid_mode"
@ -317,7 +318,7 @@ class TestGetNetArgs(unittest.TestCase):
with self.assertRaises(SystemExit): with self.assertRaises(SystemExit):
get_net_args(compose, container) get_net_args(compose, container)
def test_network__mode_service(self): def test_network__mode_service(self) -> None:
compose = get_networked_compose() compose = get_networked_compose()
compose.container_names_by_service = { compose.container_names_by_service = {
"service_1": ["container_1"], "service_1": ["container_1"],

View File

@ -4,7 +4,7 @@ from podman_compose import get_network_create_args
class TestGetNetworkCreateArgs(unittest.TestCase): class TestGetNetworkCreateArgs(unittest.TestCase):
def test_minimal(self): def test_minimal(self) -> None:
net_desc = { net_desc = {
"labels": [], "labels": [],
"internal": False, "internal": False,
@ -26,7 +26,7 @@ class TestGetNetworkCreateArgs(unittest.TestCase):
args = get_network_create_args(net_desc, proj_name, net_name) args = get_network_create_args(net_desc, proj_name, net_name)
self.assertEqual(args, expected_args) self.assertEqual(args, expected_args)
def test_ipv6(self): def test_ipv6(self) -> None:
net_desc = { net_desc = {
"labels": [], "labels": [],
"internal": False, "internal": False,
@ -49,7 +49,7 @@ class TestGetNetworkCreateArgs(unittest.TestCase):
args = get_network_create_args(net_desc, proj_name, net_name) args = get_network_create_args(net_desc, proj_name, net_name)
self.assertEqual(args, expected_args) self.assertEqual(args, expected_args)
def test_bridge(self): def test_bridge(self) -> None:
net_desc = { net_desc = {
"labels": [], "labels": [],
"internal": False, "internal": False,
@ -77,7 +77,7 @@ class TestGetNetworkCreateArgs(unittest.TestCase):
args = get_network_create_args(net_desc, proj_name, net_name) args = get_network_create_args(net_desc, proj_name, net_name)
self.assertEqual(args, expected_args) self.assertEqual(args, expected_args)
def test_ipam_driver_default(self): def test_ipam_driver_default(self) -> None:
net_desc = { net_desc = {
"labels": [], "labels": [],
"internal": False, "internal": False,
@ -113,7 +113,7 @@ class TestGetNetworkCreateArgs(unittest.TestCase):
args = get_network_create_args(net_desc, proj_name, net_name) args = get_network_create_args(net_desc, proj_name, net_name)
self.assertEqual(args, expected_args) self.assertEqual(args, expected_args)
def test_ipam_driver(self): def test_ipam_driver(self) -> None:
net_desc = { net_desc = {
"labels": [], "labels": [],
"internal": False, "internal": False,
@ -151,7 +151,7 @@ class TestGetNetworkCreateArgs(unittest.TestCase):
args = get_network_create_args(net_desc, proj_name, net_name) args = get_network_create_args(net_desc, proj_name, net_name)
self.assertEqual(args, expected_args) self.assertEqual(args, expected_args)
def test_complete(self): def test_complete(self) -> None:
net_desc = { net_desc = {
"labels": ["label1", "label2"], "labels": ["label1", "label2"],
"internal": True, "internal": True,
@ -202,7 +202,7 @@ class TestGetNetworkCreateArgs(unittest.TestCase):
args = get_network_create_args(net_desc, proj_name, net_name) args = get_network_create_args(net_desc, proj_name, net_name)
self.assertEqual(args, expected_args) self.assertEqual(args, expected_args)
def test_disable_dns(self): def test_disable_dns(self) -> None:
net_desc = { net_desc = {
"labels": [], "labels": [],
"internal": False, "internal": False,
@ -226,7 +226,7 @@ class TestGetNetworkCreateArgs(unittest.TestCase):
args = get_network_create_args(net_desc, proj_name, net_name) args = get_network_create_args(net_desc, proj_name, net_name)
self.assertEqual(args, expected_args) self.assertEqual(args, expected_args)
def test_dns_string(self): def test_dns_string(self) -> None:
net_desc = { net_desc = {
"labels": [], "labels": [],
"internal": False, "internal": False,
@ -251,7 +251,7 @@ class TestGetNetworkCreateArgs(unittest.TestCase):
args = get_network_create_args(net_desc, proj_name, net_name) args = get_network_create_args(net_desc, proj_name, net_name)
self.assertEqual(args, expected_args) self.assertEqual(args, expected_args)
def test_dns_list(self): def test_dns_list(self) -> None:
net_desc = { net_desc = {
"labels": [], "labels": [],
"internal": False, "internal": False,

View File

@ -18,5 +18,5 @@ class TestIsPathGitUrl(unittest.TestCase):
("suffix_and_prefix", "git://host.xz/path/to/repo.git", True), ("suffix_and_prefix", "git://host.xz/path/to/repo.git", True),
("empty_url_path", "http://#fragment", False), ("empty_url_path", "http://#fragment", False),
]) ])
def test_is_path_git_url(self, test_name, path, result): def test_is_path_git_url(self, test_name: str, path: str, result: bool) -> None:
self.assertEqual(is_path_git_url(path), result) self.assertEqual(is_path_git_url(path), result)

View File

@ -1,5 +1,7 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
import unittest import unittest
from typing import Any
from typing import Union
from parameterized import parameterized from parameterized import parameterized
@ -29,7 +31,7 @@ class TestNormalizeService(unittest.TestCase):
{"build": {"additional_contexts": ["ctx=../ctx", "ctx2=../ctx2"]}}, {"build": {"additional_contexts": ["ctx=../ctx", "ctx2=../ctx2"]}},
), ),
]) ])
def test_simple(self, input, expected): def test_simple(self, input: dict[str, Any], expected: dict[str, Any]) -> None:
self.assertEqual(normalize_service(input), expected) self.assertEqual(normalize_service(input), expected)
@parameterized.expand([ @parameterized.expand([
@ -46,7 +48,9 @@ class TestNormalizeService(unittest.TestCase):
{"build": {"context": "./sub_dir/dir-1", "dockerfile": "dockerfile-1"}}, {"build": {"context": "./sub_dir/dir-1", "dockerfile": "dockerfile-1"}},
), ),
]) ])
def test_normalize_service_with_sub_dir(self, input, expected): def test_normalize_service_with_sub_dir(
self, input: dict[str, Any], expected: dict[str, Any]
) -> None:
self.assertEqual(normalize_service(input, sub_dir="./sub_dir"), expected) self.assertEqual(normalize_service(input, sub_dir="./sub_dir"), expected)
@parameterized.expand([ @parameterized.expand([
@ -60,7 +64,7 @@ class TestNormalizeService(unittest.TestCase):
["bash", "-c", "sleep infinity"], ["bash", "-c", "sleep infinity"],
), ),
]) ])
def test_command_like(self, input, expected): def test_command_like(self, input: Union[list[str], str], expected: list[str]) -> None:
for key in ['command', 'entrypoint']: for key in ['command', 'entrypoint']:
input_service = {} input_service = {}
input_service[key] = input input_service[key] = input

View File

@ -2,6 +2,7 @@
# pylint: disable=protected-access # pylint: disable=protected-access
import unittest import unittest
from typing import Any
from parameterized import parameterized from parameterized import parameterized
@ -66,7 +67,7 @@ class TestRecSubs(unittest.TestCase):
] ]
@parameterized.expand(substitutions) @parameterized.expand(substitutions)
def test_rec_subs(self, desc, input, expected): def test_rec_subs(self, desc: str, input: Any, expected: Any) -> None:
sub_dict = {"v1": "high priority", "empty": ""} sub_dict = {"v1": "high priority", "empty": ""}
result = rec_subs(input, sub_dict) result = rec_subs(input, sub_dict)
self.assertEqual(result, expected, msg=desc) self.assertEqual(result, expected, msg=desc)

View File

@ -6,7 +6,7 @@ from podman_compose import parse_short_mount
class ParseShortMountTests(unittest.TestCase): class ParseShortMountTests(unittest.TestCase):
def test_multi_propagation(self): def test_multi_propagation(self) -> None:
self.assertEqual( self.assertEqual(
parse_short_mount("/foo/bar:/baz:U,Z", "/"), parse_short_mount("/foo/bar:/baz:U,Z", "/"),
{ {