diff --git a/tox_docker/config.py b/tox_docker/config.py index 6ec0118..8ae71f6 100644 --- a/tox_docker/config.py +++ b/tox_docker/config.py @@ -101,6 +101,19 @@ def __repr__(self) -> str: return repr(str(self)) +class ContainerVar: + def __init__(self, config_line: str) -> None: + if not ENV_VAR.match(config_line): + raise ValueError(f"{config_line!r} is not a valid environment variable") + self.container_var = config_line + + def __str__(self) -> str: + return self.container_var + + def __repr__(self) -> str: + return repr(str(self)) + + class Link: def __init__(self, config_line: str) -> None: target, sep, alias = config_line.partition(":") @@ -128,6 +141,8 @@ def __init__(self, config_line: str) -> None: volume_type, mode, outside, inside = parts if not os.path.isabs(outside): raise ValueError(f"Volume source {outside!r} must be an absolute path") + elif not os.path.exists(outside) and parts[1] == "rw": + os.makedirs(outside, exist_ok=True) if not os.path.isabs(inside): raise ValueError(f"Mount point {inside!r} must be an absolute path") @@ -155,6 +170,7 @@ def __init__( healthcheck_retries: Optional[int] = None, expose: Optional[Collection[ExposedPort]] = None, host_var: Optional[HostVar] = None, + container_var: Optional[ContainerVar] = None, links: Optional[Collection[Link]] = None, volumes: Optional[Collection[Volume]] = None, ) -> None: @@ -167,6 +183,7 @@ def __init__( self.environment: Mapping[str, str] = environment or {} self.expose: Collection[ExposedPort] = expose or [] self.host_var = str(host_var) if host_var else "" + self.container_var = str(container_var) if container_var else "" self.links: Collection[Link] = links or [] self.mounts: Collection[Mount] = [v.docker_mount for v in volumes or ()] @@ -234,6 +251,12 @@ def register_config(self) -> None: default=None, desc="environment variable to pass hostname or IP of container to testenv", ) + self.add_config( + keys=["container_var"], + of_type=Optional[ContainerVar], + default=None, + desc="environment variable to pass the name of the container to testenv", + ) self.add_config( keys=["links"], of_type=List[Link], diff --git a/tox_docker/plugin.py b/tox_docker/plugin.py index b6e38c4..d7e84f1 100644 --- a/tox_docker/plugin.py +++ b/tox_docker/plugin.py @@ -83,6 +83,13 @@ def get_host_env_var(container_config: ContainerConfig) -> str: return escape_env_var(f"{container_config.name}_HOST") +def get_container_env_var(container_config: ContainerConfig) -> str: + if container_config.container_var: + return container_config.container_var + + return escape_env_var(f"{container_config.name}_CONTAINER") + + def get_env_vars( container_config: ContainerConfig, container: Container ) -> Mapping[str, str]: @@ -102,7 +109,8 @@ def get_env_vars( gateway_ip = get_gateway_ip(container) env_var = get_host_env_var(container_config) env[env_var] = gateway_ip - + env_var = get_container_env_var(container_config) + env[env_var] = container_config.runas_name return env diff --git a/tox_docker/tests/test_volumes.py b/tox_docker/tests/test_volumes.py index 1828152..b7b614f 100644 --- a/tox_docker/tests/test_volumes.py +++ b/tox_docker/tests/test_volumes.py @@ -1,4 +1,7 @@ import os +import tempfile + +from tox_docker.config import Volume def test_the_image_is_healthy() -> None: @@ -7,3 +10,15 @@ def test_the_image_is_healthy() -> None: # and thus the bind mount worked as expected volume = os.environ["VOLUME_DIR"] assert "healthy" in os.listdir(volume) + + +def test_volume_creation() -> None: + with tempfile.NamedTemporaryFile() as f: + source = f"{f.name}/test" + assert not os.path.exists(source) + volume = Volume(f"bind:ro:{source}:/tmp/test") + assert volume.docker_mount.source == source + assert volume.docker_mount.target == "/tmp/test" + assert volume.docker_mount.type == "bind" + assert volume.docker_mount.readonly is True + assert os.path.isfile(source)