From 573a8a2983d6824ea4243c583f96561d71f1f655 Mon Sep 17 00:00:00 2001 From: Joe Lea Date: Mon, 16 May 2016 14:09:55 +0100 Subject: [PATCH 1/3] Extract out versioning code --- .../compose/execution/DefaultDockerCompose.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/palantir/docker/compose/execution/DefaultDockerCompose.java b/src/main/java/com/palantir/docker/compose/execution/DefaultDockerCompose.java index d1097d54a..c504abafe 100644 --- a/src/main/java/com/palantir/docker/compose/execution/DefaultDockerCompose.java +++ b/src/main/java/com/palantir/docker/compose/execution/DefaultDockerCompose.java @@ -39,6 +39,7 @@ public class DefaultDockerCompose implements DockerCompose { + public static final Version VERSION_1_7_0 = Version.valueOf("1.7.0"); private static final Duration COMMAND_TIMEOUT = standardMinutes(2); private static final Logger log = LoggerFactory.getLogger(DefaultDockerCompose.class); @@ -88,16 +89,18 @@ public void rm() throws IOException, InterruptedException { @Override public String exec(DockerComposeExecOption dockerComposeExecOption, String containerName, DockerComposeExecArgument dockerComposeExecArgument) throws IOException, InterruptedException { - verifyDockerComposeVersionAtLeast(Version.valueOf("1.7.0")); + verifyDockerComposeVersionAtLeast(VERSION_1_7_0, "You need at least docker-compose 1.7 to run docker-compose exec"); String[] fullArgs = constructFullDockerComposeExecArguments(dockerComposeExecOption, containerName, dockerComposeExecArgument); return executeDockerComposeCommand(throwingOnError(), fullArgs); } - //Current docker-compose version output format: docker-compose version 1.7.0rc1, build 1ad8866 - private void verifyDockerComposeVersionAtLeast(Version targetVersion) throws IOException, InterruptedException { + private void verifyDockerComposeVersionAtLeast(Version targetVersion, String message) throws IOException, InterruptedException { + validState(version().greaterThanOrEqualTo(targetVersion), message); + } + + private Version version() throws IOException, InterruptedException { String versionOutput = executeDockerComposeCommand(throwingOnError(), "-v"); - Version version = DockerComposeVersion.parseFromDockerComposeVersion(versionOutput); - validState(version.compareTo(targetVersion) >= 0, "You need at least docker-compose 1.7 to run docker-compose exec"); + return DockerComposeVersion.parseFromDockerComposeVersion(versionOutput); } private String[] constructFullDockerComposeExecArguments(DockerComposeExecOption dockerComposeExecOption, From 6dd1e250dc0509f8670c6a0deff5f6b29dcd6d7a Mon Sep 17 00:00:00 2001 From: Joe Lea Date: Mon, 16 May 2016 14:20:57 +0100 Subject: [PATCH 2/3] Enable --follow only on 1.7.0 --- .../compose/execution/DefaultDockerCompose.java | 12 ++++++++++-- .../compose/execution/DockerComposeTest.java | 15 ++++++++++++++- .../execution/DockerComposeVersionTest.java | 4 +++- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/palantir/docker/compose/execution/DefaultDockerCompose.java b/src/main/java/com/palantir/docker/compose/execution/DefaultDockerCompose.java index c504abafe..5a51dfa44 100644 --- a/src/main/java/com/palantir/docker/compose/execution/DefaultDockerCompose.java +++ b/src/main/java/com/palantir/docker/compose/execution/DefaultDockerCompose.java @@ -130,9 +130,9 @@ public Container container(String containerName) { */ @Override public boolean writeLogs(String container, OutputStream output) throws IOException { - Process executedProcess = rawExecutable.execute("logs", "--no-color", container); - IOUtils.copy(executedProcess.getInputStream(), output); try { + Process executedProcess = followLogs(container); + IOUtils.copy(executedProcess.getInputStream(), output); executedProcess.waitFor(COMMAND_TIMEOUT.getMillis(), MILLISECONDS); } catch (InterruptedException e) { return false; @@ -140,6 +140,14 @@ public boolean writeLogs(String container, OutputStream output) throws IOExcepti return true; } + private Process followLogs(String container) throws IOException, InterruptedException { + if (version().greaterThanOrEqualTo(VERSION_1_7_0)) { + return rawExecutable.execute("logs", "--no-color", "--follow", container); + } + + return rawExecutable.execute("logs", "--no-color", container); + } + @Override public Ports ports(String service) throws IOException, InterruptedException { String psOutput = executeDockerComposeCommand(throwingOnError(), "ps", service); diff --git a/src/test/java/com/palantir/docker/compose/execution/DockerComposeTest.java b/src/test/java/com/palantir/docker/compose/execution/DockerComposeTest.java index 435b1301f..15135ad9e 100644 --- a/src/test/java/com/palantir/docker/compose/execution/DockerComposeTest.java +++ b/src/test/java/com/palantir/docker/compose/execution/DockerComposeTest.java @@ -79,13 +79,26 @@ public void ps_parses_and_returns_container_names() throws IOException, Interrup @Test public void logs_calls_docker_compose_with_no_colour_flag() throws IOException, InterruptedException { - when(executedProcess.getInputStream()).thenReturn(toInputStream("logs")); + when(executedProcess.getInputStream()).thenReturn( + toInputStream("docker-compose version 1.5.6, build 1ad8866"), + toInputStream("logs")); ByteArrayOutputStream output = new ByteArrayOutputStream(); compose.writeLogs("db", output); verify(executor).execute("logs", "--no-color", "db"); assertThat(new String(output.toByteArray(), StandardCharsets.UTF_8), is("logs")); } + @Test + public void logs_calls_docker_compose_with_the_follow_flag_when_the_version_is_at_least_1_7_0() throws IOException, InterruptedException { + when(executedProcess.getInputStream()).thenReturn( + toInputStream("docker-compose version 1.7.0, build 1ad8866"), + toInputStream("logs")); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + compose.writeLogs("db", output); + verify(executor).execute("logs", "--no-color", "--follow", "db"); + assertThat(new String(output.toByteArray(), StandardCharsets.UTF_8), is("logs")); + } + @Test public void when_kill_exits_with_a_non_zero_exit_code_an_exception_is_thrown() throws IOException, InterruptedException { when(executedProcess.exitValue()).thenReturn(1); diff --git a/src/test/java/com/palantir/docker/compose/execution/DockerComposeVersionTest.java b/src/test/java/com/palantir/docker/compose/execution/DockerComposeVersionTest.java index 6828ad1a7..f05e1bf9b 100644 --- a/src/test/java/com/palantir/docker/compose/execution/DockerComposeVersionTest.java +++ b/src/test/java/com/palantir/docker/compose/execution/DockerComposeVersionTest.java @@ -43,6 +43,8 @@ public void return_equals_for_the_same_version_strings() throws Exception { @Test public void remove_non_digits_when_passing_version_string() { - assertEquals(Version.valueOf("1.7.0"), DockerComposeVersion.parseFromDockerComposeVersion("docker-compose version 1.7.0rc1, build 1ad8866")); + assertEquals( + DockerComposeVersion.parseFromDockerComposeVersion("docker-compose version 1.7.0rc1, build 1ad8866"), + Version.valueOf("1.7.0")); } } From c1ca809dc605dd71d1bb3eedf0917ba39012d745 Mon Sep 17 00:00:00 2001 From: Joe Lea Date: Mon, 16 May 2016 14:38:40 +0100 Subject: [PATCH 3/3] Have integration test check lines further down the stack --- .../logging/DockerCompositionLoggingIntegrationTest.java | 8 +++++--- .../com/palantir/docker/compose/matchers/IOMatchers.java | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/test/java/com/palantir/docker/compose/logging/DockerCompositionLoggingIntegrationTest.java b/src/test/java/com/palantir/docker/compose/logging/DockerCompositionLoggingIntegrationTest.java index dc25b9159..7bfd3554f 100644 --- a/src/test/java/com/palantir/docker/compose/logging/DockerCompositionLoggingIntegrationTest.java +++ b/src/test/java/com/palantir/docker/compose/logging/DockerCompositionLoggingIntegrationTest.java @@ -16,7 +16,7 @@ package com.palantir.docker.compose.logging; import static com.palantir.docker.compose.connection.waiting.HealthChecks.toHaveAllPortsOpen; -import static com.palantir.docker.compose.matchers.IOMatchers.file; +import static com.palantir.docker.compose.matchers.IOMatchers.fileWithConents; import static com.palantir.docker.compose.matchers.IOMatchers.matchingPattern; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; @@ -53,8 +53,10 @@ public void logs_can_be_saved_to_a_directory() throws IOException, InterruptedEx } finally { loggingComposition.after(); } - assertThat(new File(logFolder.getRoot(), "db.log"), is(file(matchingPattern(".*Attaching to \\w+_db_1.*")))); - assertThat(new File(logFolder.getRoot(), "db2.log"), is(file(matchingPattern(".*Attaching to \\w+_db2_1.*")))); + assertThat(new File(logFolder.getRoot(), "db.log"), is(fileWithConents(matchingPattern( + ".*Attaching to \\w+_db_1.*server started.*")))); + assertThat(new File(logFolder.getRoot(), "db2.log"), is(fileWithConents(matchingPattern( + ".*Attaching to \\w+_db2_1.*server started.*")))); } } diff --git a/src/test/java/com/palantir/docker/compose/matchers/IOMatchers.java b/src/test/java/com/palantir/docker/compose/matchers/IOMatchers.java index c52159ad4..41cf9d204 100644 --- a/src/test/java/com/palantir/docker/compose/matchers/IOMatchers.java +++ b/src/test/java/com/palantir/docker/compose/matchers/IOMatchers.java @@ -84,7 +84,7 @@ protected boolean matchesSafely() { } public static Matcher fileContainingString(String contents) { - return file(containsString(contents)); + return fileWithConents(containsString(contents)); } public static Matcher matchingPattern(String patternStr) { @@ -94,7 +94,7 @@ protected boolean matchesSafely(String text, Description mismatchDescription) { Pattern pattern = Pattern.compile(patternStr, Pattern.DOTALL); boolean matches = pattern.matcher(text).matches(); if (!matches) { - mismatchDescription.appendText("not matching " + patternStr); + mismatchDescription.appendText(text); } return matches; } @@ -106,7 +106,7 @@ public void describeTo(Description description) { }; } - public static Matcher file(Matcher contentsMatcher) { + public static Matcher fileWithConents(Matcher contentsMatcher) { return new FeatureMatcher(contentsMatcher, "file contents", "file contents") { @Override