Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enable copyFileToContainer feature during container startup #742

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -175,6 +175,15 @@ default SELF withFileSystemBind(String hostPath, String containerPath) {
*/
SELF withExposedPorts(Integer... ports);

/**
* Set the file to be copied before starting a created container
*
* @param mountableFile a Mountable file with path of source file / folder on host machine
* @param containerPath a destination path on conatiner to which the files / folders to be copied
* @return this
*/
SELF withCopyFileToContainer(MountableFile mountableFile, String containerPath);

/**
* Add an environment variable to be passed to the container.
*
Expand Down
Expand Up @@ -43,6 +43,22 @@ default boolean isRunning() {
}
}

/**
* @return is the container created?
*/
default boolean isCreated() {
if (getContainerId() == null) {
return false;
}

try {
String status = getCurrentContainerInfo().getState().getStatus();
return "created".equalsIgnoreCase(status) || isRunning();
} catch (DockerException e) {
return false;
}
}

/**
* @return has the container health state 'healthy'?
*/
Expand Down
Expand Up @@ -138,6 +138,8 @@ public class GenericContainer<SELF extends GenericContainer<SELF>>
@Nullable
private String workingDirectory = null;

private Map<MountableFile, String> copyToFileContainerPathMap = new HashMap<>();

/*
* Unique instance of DockerClient for use by this container object.
*/
Expand Down Expand Up @@ -231,6 +233,7 @@ private void tryStart(Profiler profiler) {
applyConfiguration(createCommand);

containerId = createCommand.exec().getId();
copyToFileContainerPathMap.forEach(this::copyFileToContainer);

logger().info("Starting container with ID: {}", containerId);
profiler.start("Start container");
Expand Down Expand Up @@ -835,6 +838,15 @@ public SELF withWorkingDirectory(String workDir) {
return self();
}

/**
* {@inheritDoc}
*/
@Override
public SELF withCopyFileToContainer(MountableFile mountableFile, String containerPath) {
copyToFileContainerPathMap.put(mountableFile, containerPath);
return self();
}

/**
* Get the IP address that this container may be reached on (may not be the local machine).
*
Expand Down Expand Up @@ -940,8 +952,8 @@ public ExecResult execInContainer(String... command)
@Override
public void copyFileToContainer(MountableFile mountableLocalFile, String containerPath) {

if (!isRunning()) {
throw new IllegalStateException("copyFileToContainer can only be used while the Container is running");
if (!isCreated()) {
throw new IllegalStateException("copyFileToContainer can only be used with created / running container");
}

this.dockerClient
Expand Down
@@ -0,0 +1,25 @@
package org.testcontainers.junit;

import org.junit.Assert;
import org.junit.Test;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.utility.MountableFile;
import java.io.IOException;

public class CopyFileToContainerTest {
private static String containerPath = "/tmp";
private static String fileName = "test-resource.txt";

@Test
public void checkFileCopied() throws IOException, InterruptedException {
try(
GenericContainer container = new GenericContainer("alpine:latest")
.withCommand("sleep","3000")
.withCopyFileToContainer(MountableFile.forClasspathResource("/mappable-resource/"), containerPath)
) {
container.start();
String filesList = container.execInContainer("ls","/tmp/mappable-resource").getStdout();
Assert.assertTrue(filesList.contains(fileName));
}
}
}
2 changes: 1 addition & 1 deletion core/src/test/resources/logback-test.xml
Expand Up @@ -26,4 +26,4 @@
<Marker>PROFILER</Marker>
<OnMatch>DENY</OnMatch>
</turboFilter>
</configuration>
</configuration>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is of course an unnecessary change, but rest LGTM.