diff --git a/pom.xml b/pom.xml index 2b5fe2119..9ee5cad51 100644 --- a/pom.xml +++ b/pom.xml @@ -67,6 +67,7 @@ 1.3 1.6 2.3.3 + 1.10.19 2.2 @@ -195,6 +196,13 @@ test + + org.mockito + mockito-core + ${mockito.version} + test + + com.google.code.findbugs annotations diff --git a/src/main/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandler.java b/src/main/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandler.java index d4f19f2e3..706228d04 100644 --- a/src/main/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandler.java +++ b/src/main/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandler.java @@ -81,7 +81,7 @@ public int read() throws IOException { } if (current != null && current.readableBytes() > 0) { - return current.readByte(); + return current.readByte() & 0xff; } else { return read(); } diff --git a/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveFromContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveFromContainerCmdExecTest.java index aa4dcc575..caec336a2 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveFromContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveFromContainerCmdExecTest.java @@ -6,7 +6,14 @@ import java.io.InputStream; import java.lang.reflect.Method; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; +import org.apache.commons.io.IOUtils; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; @@ -16,6 +23,7 @@ import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.api.exception.NotFoundException; +import com.github.dockerjava.core.util.CompressArchiveUtil; import com.github.dockerjava.netty.AbstractNettyDockerClientTest; @Test(groups = "integration") @@ -70,4 +78,36 @@ public void copyFromNonExistingContainer() throws Exception { } catch (NotFoundException ignored) { } } + + @Test + public void copyFromContainerBinaryFile() throws Exception { + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withName("docker-java-itest-copyFromContainerBinaryFile").exec(); + + LOG.info("Created container: {}", container); + assertThat(container.getId(), not(isEmptyOrNullString())); + + Path temp = Files.createTempFile("", ".tar.gz"); + Path binaryFile = Paths.get("src/test/resources/testCopyFromArchive/binary.dat"); + CompressArchiveUtil.tar(binaryFile, temp, true, false); + + try (InputStream uploadStream = Files.newInputStream(temp)) { + dockerClient.copyArchiveToContainerCmd(container.getId()).withTarInputStream(uploadStream).exec(); + } + + InputStream response = dockerClient.copyArchiveFromContainerCmd(container.getId(), "/binary.dat").exec(); + Boolean bytesAvailable = response.available() > 0; + assertTrue(bytesAvailable, "The file was not copied from the container."); + + try (TarArchiveInputStream tarInputStream = new TarArchiveInputStream(response)) { + TarArchiveEntry nextTarEntry = tarInputStream.getNextTarEntry(); + + assertEquals(nextTarEntry.getName(), "binary.dat"); + try (InputStream binaryFileInputStream = Files.newInputStream(binaryFile, StandardOpenOption.READ)) { + assertTrue(IOUtils.contentEquals(binaryFileInputStream, tarInputStream)); + } + + assertNull(tarInputStream.getNextTarEntry(), "Nothing except binary.dat is expected to be copied."); + } + } } diff --git a/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java b/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java new file mode 100644 index 000000000..6652f3eba --- /dev/null +++ b/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java @@ -0,0 +1,53 @@ +package com.github.dockerjava.netty.handler; + +import static org.testng.Assert.assertTrue; + +import java.io.InputStream; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufInputStream; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelHandlerContext; +import org.apache.commons.io.IOUtils; +import org.mockito.Mockito; +import org.testng.annotations.Test; + +import com.github.dockerjava.core.async.ResultCallbackTemplate; + +/** + * @author Alexander Koshevoy + */ +public class HttpResponseStreamHandlerTest { + @Test + public void testNoBytesSkipped() throws Exception { + ResultCallbackTest callback = new ResultCallbackTest(); + HttpResponseStreamHandler streamHandler = new HttpResponseStreamHandler(callback); + ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); + ByteBuf buffer = generateByteBuf(); + streamHandler.channelRead0(ctx, buffer); + streamHandler.channelReadComplete(ctx); + + assertTrue(IOUtils.contentEquals(callback.getInputStream(), new ByteBufInputStream(buffer))); + } + + private ByteBuf generateByteBuf() { + byte[] array = new byte[256]; + for (int i = 0; i < array.length; i++) { + array[i] = (byte) i; + } + return Unpooled.copiedBuffer(array); + } + + private static class ResultCallbackTest extends ResultCallbackTemplate { + private InputStream stream; + + @Override + public void onNext(InputStream stream) { + this.stream = stream; + } + + public InputStream getInputStream() { + return stream; + } + } +} diff --git a/src/test/resources/testCopyFromArchive/binary.dat b/src/test/resources/testCopyFromArchive/binary.dat new file mode 100644 index 000000000..61bcc872c Binary files /dev/null and b/src/test/resources/testCopyFromArchive/binary.dat differ