Skip to content

Commit

Permalink
Add methods which copy files to/from containers at run time
Browse files Browse the repository at this point in the history
Resolves #378
  • Loading branch information
lukidzi authored and rnorth committed Nov 26, 2017
1 parent 0e898fc commit 524b957
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 0 deletions.
22 changes: 22 additions & 0 deletions core/src/main/java/org/testcontainers/containers/Container.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.testcontainers.containers.traits.LinkableContainer;
import org.testcontainers.containers.wait.Wait;
import org.testcontainers.containers.wait.WaitStrategy;
import org.testcontainers.utility.MountableFile;

import java.io.IOException;
import java.nio.charset.Charset;
Expand Down Expand Up @@ -408,6 +409,27 @@ ExecResult execInContainer(String... command)
ExecResult execInContainer(Charset outputCharset, String... command)
throws UnsupportedOperationException, IOException, InterruptedException;

/**
*
* Copies a file which resides inside the classpath to the container.
*
* @param mountableLocalFile file which is copied into the container
* @param containerPath destination path inside the container
* @throws IOException if there's an issue communicating with Docker
* @throws InterruptedException if the thread waiting for the response is interrupted
*/
void copyFileToContainer(MountableFile mountableLocalFile, String containerPath) throws IOException, InterruptedException;

/**
* Copies a file which resides inside the container to user defined directory
*
* @param containerPath path to file which is copied from container
* @param destinationPath destination path to which file is copied with file name
* @throws IOException if there's an issue communicating with Docker or receiving entry from TarArchiveInputStream
* @throws InterruptedException if the thread waiting for the response is interrupted
*/
void copyFileFromContainer(String containerPath, String destinationPath) throws IOException, InterruptedException;

List<Integer> getExposedPorts();

List<String> getPortBindings();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import lombok.*;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.jetbrains.annotations.Nullable;
import org.junit.runner.Description;
import org.rnorth.ducttape.ratelimits.RateLimiter;
Expand All @@ -31,6 +33,7 @@
import org.testcontainers.utility.*;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Path;
Expand Down Expand Up @@ -858,6 +861,32 @@ public ExecResult execInContainer(String... command)
return execInContainer(UTF8, command);
}

/**
* {@inheritDoc}
*/
@Override
public void copyFileToContainer(MountableFile mountableLocalFile, String containerPath) throws IOException, InterruptedException {

this.dockerClient
.copyArchiveToContainerCmd(this.containerId)
.withHostResource(mountableLocalFile.getResolvedPath())
.withRemotePath(containerPath)
.exec();
}

/**
* {@inheritDoc}
*/
@Override
public void copyFileFromContainer(String containerPath, String destinationPath) throws IOException, InterruptedException {
try (final TarArchiveInputStream tarInputStream = new TarArchiveInputStream(this.dockerClient
.copyArchiveFromContainerCmd(this.containerId, containerPath)
.exec())) {
tarInputStream.getNextTarEntry();
IOUtils.copy(tarInputStream, new FileOutputStream(destinationPath));
}
}

/**
* {@inheritDoc}
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
package org.testcontainers.junit;

import com.github.dockerjava.api.exception.NotFoundException;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.Files;
import com.google.common.util.concurrent.Uninterruptibles;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.rabbitmq.client.*;
import org.apache.commons.io.FileUtils;
import org.bson.Document;
import org.junit.*;
import org.rnorth.ducttape.RetryCountExceededException;
import org.rnorth.ducttape.unreliables.Unreliables;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.utility.Base58;
import org.testcontainers.utility.MountableFile;
import org.testcontainers.utility.TestEnvironment;

import java.io.*;
Expand Down Expand Up @@ -330,6 +334,54 @@ public void createContainerCmdHookTest() {
}
}

@Test
public void copyToContainerTest() throws Exception {
final File tempResultFolder = Files.createTempDir();

try (final GenericContainer alpineCopyToContainer = new GenericContainer("alpine:3.2")
.withCommand("top")){

alpineCopyToContainer.start();
final MountableFile mountableFile = MountableFile.forClasspathResource("test_copy_to_container.txt");
alpineCopyToContainer.copyFileToContainer(mountableFile, "/home/");
alpineCopyToContainer.copyFileFromContainer("/home/test_copy_to_container.txt",
tempResultFolder.getAbsolutePath() + "/test_copy_to_container.txt");

File expectedFile = new File(mountableFile.getResolvedPath());
File actualFile = new File(tempResultFolder.getAbsolutePath() + "/test_copy_to_container.txt");
assertTrue("Files aren't same ", FileUtils.contentEquals(expectedFile,actualFile));
}
}

@Test(expected = NotFoundException.class)
public void copyFromContainerShouldFailBecauseNoFileTest() throws NotFoundException, IOException, InterruptedException {

try (final GenericContainer alpineCopyToContainer = new GenericContainer("alpine:3.2")
.withCommand("top")) {
alpineCopyToContainer.start();
alpineCopyToContainer.copyFileFromContainer("/home/test.txt", "src/test/resources/copy-from/test.txt");
}
}

@Test
public void shouldCopyFileFromContainerTest() throws IOException, InterruptedException {
final File tempResultFolder = Files.createTempDir();

try (final GenericContainer alpineCopyToContainer = new GenericContainer("alpine:3.2")
.withCommand("top")) {

alpineCopyToContainer.start();
final MountableFile mountableFile = MountableFile.forClasspathResource("test_copy_to_container.txt");
alpineCopyToContainer.copyFileToContainer(mountableFile, "/home/");
alpineCopyToContainer.copyFileFromContainer("/home/test_copy_to_container.txt",
tempResultFolder.getAbsolutePath() + "/test_copy_from_container.txt");

File expectedFile = new File(mountableFile.getResolvedPath());
File actualFile = new File(tempResultFolder.getAbsolutePath() + "/test_copy_from_container.txt");
assertTrue("Files aren't same ", FileUtils.contentEquals(expectedFile,actualFile));
}
}

private BufferedReader getReaderForContainerPort80(GenericContainer container) {

return Unreliables.retryUntilSuccess(10, TimeUnit.SECONDS, () -> {
Expand Down
2 changes: 2 additions & 0 deletions core/src/test/resources/test_copy_to_container.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Some Test
Message

0 comments on commit 524b957

Please sign in to comment.