Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.
This PR attempts to improve the API for transferring content from the container to the host system.
The problem with the current API
Currently testcontainers-java has the method ContainerState#copyFileFromContainer(String containerPath, String hostPath) which only supports copying a single file. If you try to copy a directory, the method will create an empty file in the file system of the host.
The second method is the copyFileFromContainer(String containerPath, ThrowingFunction<InputStream, T> function) method, which allows you to use a generic InputStream. Internally, however, this input stream is a TarArchiveInputStream that has been advanced to the first entry. This means that when reading from the input stream, only this first entry is read. It is therefore not possible to read the entire tar archive with this API. If you try to copy a directory, it will read 0 bytes.
The added API
This PR adds two new methods and doesn’t change the signature of the two existing ones.
The first method is copyArchiveFromContainer(String containerPath, ThrowingFunction<InputStream, T> function), which simply passes the raw archive stream from dockerClient to the consumer function. This allows users to implement their own consumers for handling the tar archive.
The second method is copyPathFromContainer(String containerPath, String hostPath), which copies all files and directories from the specified container path to the specified host path.
If the containerPath points to a file, the behaviour is identical to that of the copyFileFromContainer method. However, if the file points to a directory, the file/directory structure within this directory is mirrored to the host file system within the specified hostPath directory. All required directories on the host system are created automatically.
This PR attempts to improve the API for transferring content from the container to the host system.
The problem with the current API
Currently
testcontainers-java
has the methodContainerState#copyFileFromContainer(String containerPath, String hostPath)
which only supports copying a single file. If you try to copy a directory, the method will create an empty file in the file system of the host.The second method is the
copyFileFromContainer(String containerPath, ThrowingFunction<InputStream, T> function)
method, which allows you to use a genericInputStream
. Internally, however, this input stream is aTarArchiveInputStream
that has been advanced to the first entry. This means that when reading from the input stream, only this first entry is read. It is therefore not possible to read the entire tar archive with this API. If you try to copy a directory, it will read 0 bytes.The added API
This PR adds two new methods and doesn’t change the signature of the two existing ones.
The first method is
copyArchiveFromContainer(String containerPath, ThrowingFunction<InputStream, T> function)
, which simply passes the raw archive stream fromdockerClient
to the consumer function. This allows users to implement their own consumers for handling the tar archive.The second method is
copyPathFromContainer(String containerPath, String hostPath)
, which copies all files and directories from the specified container path to the specified host path. If thecontainerPath
points to a file, the behaviour is identical to that of thecopyFileFromContainer
method. However, if the file points to a directory, the file/directory structure within this directory is mirrored to the host file system within the specifiedhostPath
directory. All required directories on the host system are created automatically.This would also provide a real solution to #1647.