From c02e483e8616e4f9d9c88f07e2b86ee1d5877b22 Mon Sep 17 00:00:00 2001 From: Nicholas McDonnell <50747025+mcdonnnj@users.noreply.github.com> Date: Thu, 20 Jul 2023 01:17:34 -0400 Subject: [PATCH] Migrate testing from pytest-dockerc to using python-on-whales The pytest-dockerc plug is unmaintained and there is now a dependency issues with PyYAML because of the release of Cython v3 (which is itself a build dependency for PyYAML). After some research this seemed like the most similar package in terms of functionality to the package we are replacing. Although it is not a pytest plugin it still provides similar access and uses the Docker composition defined in the repository. --- requirements-test.txt | 2 +- tests/conftest.py | 13 +++++++++++-- tests/container_test.py | 29 +++++++++++++++++------------ 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/requirements-test.txt b/requirements-test.txt index 5f3337c..8b41b2f 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,4 +1,4 @@ --requirement requirements.txt pre-commit pytest -pytest-dockerc +python-on-whales diff --git a/tests/conftest.py b/tests/conftest.py index 90938e6..054f09d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,16 +4,25 @@ """ # Third-Party Libraries import pytest +from python_on_whales import docker MAIN_SERVICE_NAME = "example" VERSION_SERVICE_NAME = f"{MAIN_SERVICE_NAME}-version" +@pytest.fixture(scope="session") +def dockerc(): + """Start up the Docker composition.""" + docker.compose.up(detach=True) + yield docker + docker.compose.down() + + @pytest.fixture(scope="session") def main_container(dockerc): """Return the main container from the Docker composition.""" # find the container by name even if it is stopped already - return dockerc.containers(service_names=[MAIN_SERVICE_NAME], stopped=True)[0] + return dockerc.compose.ps(services=[MAIN_SERVICE_NAME], all=True)[0] @pytest.fixture(scope="session") @@ -23,7 +32,7 @@ def version_container(dockerc): The version container should just output the version of its underlying contents. """ # find the container by name even if it is stopped already - return dockerc.containers(service_names=[VERSION_SERVICE_NAME], stopped=True)[0] + return dockerc.compose.ps(services=[VERSION_SERVICE_NAME], all=True)[0] def pytest_addoption(parser): diff --git a/tests/container_test.py b/tests/container_test.py index b92ff86..c6255df 100644 --- a/tests/container_test.py +++ b/tests/container_test.py @@ -22,7 +22,7 @@ def test_container_count(dockerc): """Verify the test composition and container.""" # stopped parameter allows non-running containers in results assert ( - len(dockerc.containers(stopped=True)) == 2 + len(dockerc.compose.ps(all=True)) == 2 ), "Wrong number of containers were started." @@ -30,7 +30,7 @@ def test_wait_for_ready(main_container): """Wait for container to be ready.""" TIMEOUT = 10 for i in range(TIMEOUT): - if READY_MESSAGE in main_container.logs().decode("utf-8"): + if READY_MESSAGE in main_container.logs(): break time.sleep(1) else: @@ -40,18 +40,21 @@ def test_wait_for_ready(main_container): ) -def test_wait_for_exits(main_container, version_container): +def test_wait_for_exits(dockerc, main_container, version_container): """Wait for containers to exit.""" - assert main_container.wait() == 0, "Container service (main) did not exit cleanly" assert ( - version_container.wait() == 0 + dockerc.wait(main_container.id) == 0 + ), "Container service (main) did not exit cleanly" + assert ( + dockerc.wait(version_container.id) == 0 ), "Container service (version) did not exit cleanly" -def test_output(main_container): +def test_output(dockerc, main_container): """Verify the container had the correct output.""" - main_container.wait() # make sure container exited if running test isolated - log_output = main_container.logs().decode("utf-8") + # make sure container exited if running test isolated + dockerc.wait(main_container.id) + log_output = main_container.logs() assert SECRET_QUOTE in log_output, "Secret not found in log output." @@ -69,10 +72,11 @@ def test_release_version(): ), "RELEASE_TAG does not match the project version" -def test_log_version(version_container): +def test_log_version(dockerc, version_container): """Verify the container outputs the correct version to the logs.""" - version_container.wait() # make sure container exited if running test isolated - log_output = version_container.logs().decode("utf-8").strip() + # make sure container exited if running test isolated + dockerc.wait(version_container.id) + log_output = version_container.logs().strip() pkg_vars = {} with open(VERSION_FILE) as f: exec(f.read(), pkg_vars) # nosec @@ -89,5 +93,6 @@ def test_container_version_label_matches(version_container): exec(f.read(), pkg_vars) # nosec project_version = pkg_vars["__version__"] assert ( - version_container.labels["org.opencontainers.image.version"] == project_version + version_container.config.labels["org.opencontainers.image.version"] + == project_version ), "Dockerfile version label does not match project version"