-
Notifications
You must be signed in to change notification settings - Fork 297
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(core): Reorganize core tests and improve (#693)
Found some loss ends while working on fixing the typing. The idea in this PR is to reorganize the tests to **better reflect** the use case (not all just in `test_core`) This should help help avoid later issues when we fix more typing (allowing better isolation/management) Also took this opportunity to **add missing tests** for `utils` and `config` So now we have: 1. `test_image` - stripped from `test_core` 2. `test_waiting_utils` - stripped from `test_core` 3. a much cleaner `test_core` 4. `test_utils` - new 5. `test_config` - new ```bash ---------- coverage: platform linux, python 3.10.12-final-0 ---------- Name Stmts Miss Branch BrPart Cover Missing --------------------------------------------------------------------------------------- core/testcontainers/core/__init__.py 0 0 0 0 100% core/testcontainers/core/auth.py 31 0 12 0 100% core/testcontainers/core/config.py 59 0 20 0 100% core/testcontainers/core/container.py 159 23 40 9 80% 20, 61-62, 82-84, 121->123, 135, 138, 158-162, 186, 191, 244->260, 250-259, 261 core/testcontainers/core/docker_client.py 118 18 32 9 79% 63-65, 96, 134->133, 138-139, 141, 152, 161, 179, 196, 200-201, 204-208 core/testcontainers/core/exceptions.py 3 0 0 0 100% core/testcontainers/core/generic.py 28 28 0 0 0% 13-82 core/testcontainers/core/image.py 47 2 6 2 92% 10, 68 core/testcontainers/core/labels.py 23 0 8 0 100% core/testcontainers/core/network.py 20 1 0 0 95% 30 core/testcontainers/core/utils.py 46 9 10 2 77% 27->exit, 63-70, 79 core/testcontainers/core/version.py 20 0 12 0 100% core/testcontainers/core/waiting_utils.py 48 8 14 4 81% 26, 60-67, 77, 104->106, 122 --------------------------------------------------------------------------------------- TOTAL 602 89 154 26 83% ```
- Loading branch information
1 parent
794a22e
commit f1665f3
Showing
5 changed files
with
197 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
from testcontainers.core.config import TestcontainersConfiguration as TCC, TC_FILE | ||
|
||
from pytest import MonkeyPatch, mark, LogCaptureFixture | ||
|
||
import logging | ||
import tempfile | ||
|
||
|
||
def test_read_tc_properties(monkeypatch: MonkeyPatch) -> None: | ||
with tempfile.TemporaryDirectory() as tmpdirname: | ||
file = f"{tmpdirname}/{TC_FILE}" | ||
with open(file, "w") as f: | ||
f.write("tc.host=some_value\n") | ||
|
||
monkeypatch.setattr("testcontainers.core.config.TC_GLOBAL", file) | ||
|
||
config = TCC() | ||
assert config.tc_properties == {"tc.host": "some_value"} | ||
|
||
|
||
@mark.parametrize("docker_auth_config_env", ["key=value", ""]) | ||
@mark.parametrize("warning_dict", [{}, {"key": "value"}, {"DOCKER_AUTH_CONFIG": "TEST"}]) | ||
@mark.parametrize("warning_dict_post", [{}, {"key": "value"}, {"DOCKER_AUTH_CONFIG": "TEST"}]) | ||
def test_docker_auth_config( | ||
caplog: LogCaptureFixture, | ||
monkeypatch: MonkeyPatch, | ||
docker_auth_config_env: str, | ||
warning_dict: dict[str, str], | ||
warning_dict_post: dict[str, str], | ||
) -> None: | ||
monkeypatch.setattr("testcontainers.core.config._WARNINGS", warning_dict) | ||
monkeypatch.setenv("DOCKER_AUTH_CONFIG", docker_auth_config_env) | ||
caplog.set_level(logging.WARNING) | ||
|
||
config = TCC() | ||
if not docker_auth_config_env: | ||
assert config.docker_auth_config == "" | ||
assert caplog.text == "" | ||
else: | ||
assert config.docker_auth_config == docker_auth_config_env | ||
|
||
if "DOCKER_AUTH_CONFIG" in warning_dict: | ||
assert warning_dict["DOCKER_AUTH_CONFIG"] in caplog.text | ||
|
||
if warning_dict == {}: | ||
monkeypatch.setattr("testcontainers.core.config._WARNINGS", warning_dict_post) | ||
|
||
config.docker_auth_config = "new_value" | ||
assert config.docker_auth_config == "new_value" | ||
|
||
|
||
def test_tc_properties_get_tc_host() -> None: | ||
config = TCC() | ||
config.tc_properties = {"tc.host": "some_value"} | ||
assert config.tc_properties_get_tc_host() == "some_value" | ||
|
||
|
||
def test_timeout() -> None: | ||
config = TCC() | ||
config.max_tries = 2 | ||
config.sleep_time = 3 | ||
assert config.timeout == 6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import pytest | ||
import tempfile | ||
import random | ||
import os | ||
|
||
from pathlib import Path | ||
from typing import Optional | ||
|
||
from testcontainers.core.container import DockerContainer | ||
from testcontainers.core.image import DockerImage | ||
|
||
|
||
@pytest.mark.parametrize("test_cleanup", [True, False]) | ||
@pytest.mark.parametrize("test_image_tag", [None, "test-image:latest"]) | ||
def test_docker_image(test_image_tag: Optional[str], test_cleanup: bool, check_for_image) -> None: | ||
with tempfile.TemporaryDirectory() as temp_directory: | ||
# It's important to use a random string to avoid image caching | ||
random_string = "Hello from Docker Image! " + str(random.randint(0, 1000)) | ||
with open(f"{temp_directory}/Dockerfile", "w") as f: | ||
f.write( | ||
f""" | ||
FROM alpine:latest | ||
CMD echo "{random_string}" | ||
""" | ||
) | ||
with DockerImage(path=temp_directory, tag=test_image_tag, clean_up=test_cleanup) as image: | ||
image_short_id = image.short_id | ||
assert image.tag is test_image_tag, f"Expected {test_image_tag}, got {image.tag}" | ||
assert image.short_id is not None, "Short ID should not be None" | ||
assert image.get_wrapped_image() is not None | ||
logs = image.get_logs() | ||
assert isinstance(logs, list), "Logs should be a list" | ||
assert logs[0] == {"stream": "Step 1/2 : FROM alpine:latest"} | ||
assert logs[3] == {"stream": f'Step 2/2 : CMD echo "{random_string}"'} | ||
with DockerContainer(str(image)) as container: | ||
assert container._container.image.short_id.endswith(image_short_id), "Image ID mismatch" | ||
assert container.get_logs() == ((random_string + "\n").encode(), b""), "Container logs mismatch" | ||
|
||
check_for_image(image_short_id, test_cleanup) | ||
|
||
|
||
@pytest.mark.parametrize("dockerfile_path", [None, Path("subdir/my.Dockerfile")]) | ||
def test_docker_image_with_custom_dockerfile_path(dockerfile_path: Optional[Path]) -> None: | ||
with tempfile.TemporaryDirectory() as temp_directory: | ||
temp_dir_path = Path(temp_directory) | ||
if dockerfile_path: | ||
os.makedirs(temp_dir_path / dockerfile_path.parent, exist_ok=True) | ||
dockerfile_rel_path = dockerfile_path | ||
dockerfile_kwargs = {"dockerfile_path": dockerfile_path} | ||
else: | ||
dockerfile_rel_path = Path("Dockerfile") # default | ||
dockerfile_kwargs = {} | ||
|
||
with open(temp_dir_path / dockerfile_rel_path, "x") as f: | ||
f.write( | ||
f""" | ||
FROM alpine:latest | ||
CMD echo "Hello world!" | ||
""" | ||
) | ||
with DockerImage(path=temp_directory, tag="test", clean_up=True, no_cache=True, **dockerfile_kwargs) as image: | ||
image_short_id = image.short_id | ||
assert image.get_wrapped_image() is not None | ||
with DockerContainer(str(image)) as container: | ||
assert container._container.image.short_id.endswith(image_short_id), "Image ID mismatch" | ||
assert container.get_logs() == (("Hello world!\n").encode(), b""), "Container logs mismatch" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
from pytest import MonkeyPatch, raises, mark | ||
|
||
from testcontainers.core import utils | ||
|
||
|
||
def test_setup_logger() -> None: | ||
assert utils.setup_logger("test") is not None | ||
|
||
|
||
@mark.parametrize("platform, expected", [("linux", "linux"), ("linux2", "linux"), ("darwin", "mac"), ("win32", "win")]) | ||
def test_os_name(monkeypatch: MonkeyPatch, platform: str, expected: str) -> None: | ||
assert utils.os_name() is not None | ||
monkeypatch.setattr("sys.platform", platform) | ||
assert utils.os_name() == expected | ||
|
||
|
||
def test_is_mac(monkeypatch: MonkeyPatch) -> None: | ||
monkeypatch.setattr("testcontainers.core.utils.os_name", lambda: "mac") | ||
assert utils.is_mac() | ||
|
||
|
||
def test_is_linux(monkeypatch: MonkeyPatch) -> None: | ||
monkeypatch.setattr("testcontainers.core.utils.os_name", lambda: "linux") | ||
assert utils.is_linux() | ||
|
||
|
||
def test_is_windows(monkeypatch: MonkeyPatch) -> None: | ||
monkeypatch.setattr("testcontainers.core.utils.os_name", lambda: "win") | ||
assert utils.is_windows() | ||
|
||
|
||
def test_is_arm(monkeypatch: MonkeyPatch) -> None: | ||
assert not utils.is_arm() | ||
monkeypatch.setattr("platform.machine", lambda: "arm64") | ||
assert utils.is_arm() | ||
monkeypatch.setattr("platform.machine", lambda: "aarch64") | ||
assert utils.is_arm() | ||
|
||
|
||
def test_inside_container(monkeypatch: MonkeyPatch) -> None: | ||
assert not utils.inside_container() | ||
monkeypatch.setattr("os.path.exists", lambda _: True) | ||
assert utils.inside_container() | ||
|
||
|
||
def test_raise_for_deprecated_parameters() -> None: | ||
kwargs = {"key": "value"} | ||
current = "key" | ||
replacement = "new_key" | ||
with raises(ValueError) as e: | ||
result = utils.raise_for_deprecated_parameter(kwargs, current, replacement) | ||
assert str(e.value) == "Parameter 'deprecated' is deprecated and should be replaced by 'replacement'." | ||
assert result == {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import pytest | ||
|
||
from testcontainers.core.container import DockerContainer | ||
from testcontainers.core.waiting_utils import wait_for_logs | ||
|
||
|
||
def test_wait_for_logs() -> None: | ||
with DockerContainer("hello-world") as container: | ||
wait_for_logs(container, "Hello from Docker!") | ||
|
||
|
||
def test_timeout_is_raised_when_waiting_for_logs() -> None: | ||
with pytest.raises(TimeoutError), DockerContainer("alpine").with_command("sleep 2") as container: | ||
wait_for_logs(container, "Hello from Docker!", timeout=1e-3) |