Skip to content

Commit

Permalink
feat(compose): ability to retain volumes when using context manager (#…
Browse files Browse the repository at this point in the history
…659)

# changes

On fiddling with a local project of mine, I realised we default to
removing volumes when using compose.
This is neat, but the context manager should also allow control over the
volumes kept.

This change adds the `keep_volumes` flag and hooks into `self.stop()`
that already had the option.

I added a test to cover the new functionality :
  • Loading branch information
totallyzen authored Aug 3, 2024
1 parent b1453e8 commit e1e3d13
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 1 deletion.
3 changes: 2 additions & 1 deletion core/testcontainers/compose/compose.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ class DockerCompose:
pull: bool = False
build: bool = False
wait: bool = True
keep_volumes: bool = False
env_file: Optional[str] = None
services: Optional[list[str]] = None
docker_command_path: Optional[str] = None
Expand All @@ -178,7 +179,7 @@ def __enter__(self) -> "DockerCompose":
return self

def __exit__(self, exc_type, exc_val, exc_tb) -> None:
self.stop()
self.stop(not self.keep_volumes)

def docker_compose_command(self) -> list[str]:
"""
Expand Down
17 changes: 17 additions & 0 deletions core/tests/compose_fixtures/basic_volume/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
services:
alpine:
image: alpine:latest
init: true
command:
- sh
- -c
- 'while true; do sleep 0.1 ; date -Ins; done'
read_only: true
volumes:
- type: volume
source: my-data
target: /var/lib/example/data
read_only: false

volumes:
my-data: {}
22 changes: 22 additions & 0 deletions core/tests/test_compose.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import subprocess
from pathlib import Path
from re import split
from time import sleep
Expand Down Expand Up @@ -147,6 +148,27 @@ def test_compose_logs():
assert not line or container.Service in next(iter(line.split("|")), None)


def test_compose_volumes():
_file_in_volume = "/var/lib/example/data/hello"
volumes = DockerCompose(context=FIXTURES / "basic_volume", keep_volumes=True)
with volumes:
stdout, stderr, exitcode = volumes.exec_in_container(
["/bin/sh", "-c", f"echo hello > {_file_in_volume}"], "alpine"
)
assert exitcode == 0

# execute another time to confirm the file is still there, but we're not keeping the volumes this time
volumes.keep_volumes = False
with volumes:
stdout, stderr, exitcode = volumes.exec_in_container(["cat", _file_in_volume], "alpine")
assert exitcode == 0
assert "hello" in stdout

# third time we expect the file to be missing
with volumes, pytest.raises(subprocess.CalledProcessError):
volumes.exec_in_container(["cat", _file_in_volume], "alpine")


# noinspection HttpUrlsUsage
def test_compose_ports():
# fairly straight forward - can we get the right port to request it
Expand Down

0 comments on commit e1e3d13

Please sign in to comment.