Skip to content

Commit

Permalink
Allow for optionally passing options to .remove
Browse files Browse the repository at this point in the history
The `Docker::Container` `remove` method in [docker-api conditionally accepts a hash of
options](https://github.com/upserve/docker-api/blob/6f7b7cd2b790ec0ca69f805d72ae0c504c8b2f49/lib/docker/container.rb#L248)

Furthermore, removing a docker container, by default, will [not remove the volumes](https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerDelete)
unless you pass `v: true` as a parameter.

Without the ability to pass `v: true` we can end up with many dangling
volumes that take up disk space.

This commit adds an optional hash argument to the `DockerContainer`
`#remove` method, it defaults to an empty hash.

To assist with tests I've also added:
  - `DockerContainer#mounts` method which returns an array of the mount
  hashes from the container `#info`
  - `DockerContainer#mount_names` which returns an array of the mount
  names (ids)
  • Loading branch information
HeyNonster committed Dec 12, 2023
1 parent 0855cb9 commit bb66e6d
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 3 deletions.
23 changes: 21 additions & 2 deletions core/lib/testcontainers/docker_container.rb
Original file line number Diff line number Diff line change
Expand Up @@ -530,11 +530,12 @@ def kill(signal: "SIGKILL")

# Removes the container.
#
# @param options [Hash] Additional options to send to the container remove command.
# @return [DockerContainer] The DockerContainer instance.
# @return [nil] If the container does not exist.
# @raise [ConnectionError] If the connection to the Docker daemon fails.
def remove
@_container&.remove
def remove(options = {})
@_container&.remove(options)
@_container = nil
self
rescue Excon::Error::Socket => e
Expand Down Expand Up @@ -732,6 +733,24 @@ def first_mapped_port
container_ports.map { |port| mapped_port(port) }.first
end

# Returns the container's mounts.
#
# @return [Array<Hash>] An array of the container's mounts.
# @raise [ConnectionError] If the connection to the Docker daemon fails.
# @raise [ContainerNotStartedError] If the container has not been started.
def mounts
info["Mounts"]
end

# Returns the container's mount names.
#
# @return [Array<String>] The container's mount names.
# @raise [ConnectionError] If the connection to the Docker daemon fails.
# @raise [ContainerNotStartedError] If the container has not been started.
def mount_names
mounts.map { |mount| mount["Name"] }
end

# Returns the value for the given environment variable.
#
# @param key [String] The environment variable's key.
Expand Down
22 changes: 21 additions & 1 deletion core/test/docker_container_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,16 @@ def test_it_returns_the_container_port_bindings
assert_equal({"80/tcp" => [{"HostPort" => "8080"}], "8080/tcp" => [{"HostPort" => "8081"}], "443/tcp" => [{"HostPort" => "443"}]}, container.port_bindings)
end

def test_it_returns_the_container_volumes
def test_it_creates_and_returns_the_container_volumes
container = Testcontainers::DockerContainer.new("hello-world", volumes: ["/tmp"])
container.start
mount_name = container.mount_names.first

assert_equal mount_name, Docker::Volume.get(mount_name).id
assert_equal({"/tmp" => {}}, container.volumes)
ensure
container.stop if container.exists? && container.running?
container.remove({v: true}) if container.exists?
end

def test_it_returns_the_container_labels
Expand Down Expand Up @@ -271,6 +278,19 @@ def test_it_removes_a_container
container.remove if container.exists?
end

def test_it_removes_a_container_and_its_volumes
container = Testcontainers::DockerContainer.new("hello-world", volumes: ["/tmp"])
container.start
mount_name = container.mount_names.first
container.remove({v: true})

refute container.exists?
assert_raises(Docker::Error::NotFoundError) { Docker::Volume.get(mount_name) }
ensure
container.stop if container.exists? && container.running?
container.remove({v: true}) if container.exists?
end

def test_it_restarts_a_container
@long_running_container.start
@long_running_container.restart
Expand Down

0 comments on commit bb66e6d

Please sign in to comment.