diff --git a/.baseline/findbugs/excludeFilter.xml b/.baseline/findbugs/excludeFilter.xml
index 1887223f2..d96c8a012 100644
--- a/.baseline/findbugs/excludeFilter.xml
+++ b/.baseline/findbugs/excludeFilter.xml
@@ -9,13 +9,14 @@
-
+
+
diff --git a/appveyor.yml b/appveyor.yml
index d31b56062..212ec6633 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -7,7 +7,8 @@ build_script:
- gradlew.bat compileJava compileTestJava --info --no-daemon
test_script:
- - gradlew.bat dependencies --info --no-daemon
+ - cinst -y docker docker-compose
+ - gradlew.bat test windowsSmokeTest --info --no-daemon
branches:
only:
diff --git a/build.gradle b/build.gradle
index 43a25c96b..934aa4a75 100644
--- a/build.gradle
+++ b/build.gradle
@@ -36,6 +36,7 @@ subprojects {
apply plugin: 'com.palantir.baseline-eclipse'
apply plugin: 'com.palantir.baseline-findbugs'
apply plugin: 'com.palantir.baseline-idea'
+ apply from: "${rootDir}/gradle/integTest.gradle"
apply from: "${rootDir}/gradle/publish.gradle"
apply plugin: 'org.inferred.processors'
diff --git a/circle.yml b/circle.yml
index 995af171f..6433cc320 100644
--- a/circle.yml
+++ b/circle.yml
@@ -18,7 +18,7 @@ test:
override:
- ? >
case $CIRCLE_NODE_INDEX in
- 0) ./gradlew test --info ;;
+ 0) ./gradlew test integTest --info ;;
1) ./gradlew findbugsMain findbugsTest checkstyleMain checkstyleTest javadoc --info ;;
esac
:
diff --git a/docker-compose-rule-core/build.gradle b/docker-compose-rule-core/build.gradle
index 7159dad63..660c561be 100644
--- a/docker-compose-rule-core/build.gradle
+++ b/docker-compose-rule-core/build.gradle
@@ -5,6 +5,7 @@ dependencies {
compile "com.google.guava:guava:$guavaVersion"
compile "joda-time:joda-time:$jodaVersion"
compile "com.github.zafarkhaja:java-semver:$javaSemverVersion"
+ compile "com.google.code.findbugs:jsr305:3.0.0"
compile 'com.jayway.awaitility:awaitility:1.6.5'
@@ -18,7 +19,6 @@ dependencies {
testCompile "org.hamcrest:hamcrest-all:$hamcrestVersion"
testCompile "org.mockito:mockito-core:$mockitoVersion"
testCompile "com.github.tomakehurst:wiremock:2.0.6-beta"
- testCompile "com.google.code.findbugs:jsr305:3.0.0"
testCompile "com.github.stefanbirkner:system-rules:1.16.1"
}
diff --git a/docker-compose-rule-core/src/test/java/com/palantir/docker/compose/connection/ContainerIntegrationTests.java b/docker-compose-rule-core/src/integTest/java/com/palantir/docker/compose/connection/ContainerIntegrationTests.java
similarity index 95%
rename from docker-compose-rule-core/src/test/java/com/palantir/docker/compose/connection/ContainerIntegrationTests.java
rename to docker-compose-rule-core/src/integTest/java/com/palantir/docker/compose/connection/ContainerIntegrationTests.java
index e2ecfa8aa..d4892c551 100644
--- a/docker-compose-rule-core/src/test/java/com/palantir/docker/compose/connection/ContainerIntegrationTests.java
+++ b/docker-compose-rule-core/src/integTest/java/com/palantir/docker/compose/connection/ContainerIntegrationTests.java
@@ -36,7 +36,7 @@ public class ContainerIntegrationTests {
@Test
public void testStateChanges_withoutHealthCheck() throws IOException, InterruptedException {
DockerCompose dockerCompose = new DefaultDockerCompose(
- DockerComposeFiles.from("src/test/resources/no-healthcheck.yaml"),
+ DockerComposeFiles.from("src/integTest/resources/no-healthcheck.yaml"),
dockerMachine,
ProjectName.random());
@@ -60,7 +60,7 @@ public void testStateChanges_withHealthCheck() throws IOException, InterruptedEx
assumeThat("docker-compose version", DockerCompose.version(), new GreaterOrEqual<>(Version.forIntegers(1, 10, 0)));
DockerCompose dockerCompose = new DefaultDockerCompose(
- DockerComposeFiles.from("src/test/resources/native-healthcheck.yaml"),
+ DockerComposeFiles.from("src/integTest/resources/native-healthcheck.yaml"),
dockerMachine,
ProjectName.random());
diff --git a/docker-compose-rule-core/src/test/resources/native-healthcheck.yaml b/docker-compose-rule-core/src/integTest/resources/native-healthcheck.yaml
similarity index 100%
rename from docker-compose-rule-core/src/test/resources/native-healthcheck.yaml
rename to docker-compose-rule-core/src/integTest/resources/native-healthcheck.yaml
diff --git a/docker-compose-rule-core/src/test/resources/no-healthcheck.yaml b/docker-compose-rule-core/src/integTest/resources/no-healthcheck.yaml
similarity index 100%
rename from docker-compose-rule-core/src/test/resources/no-healthcheck.yaml
rename to docker-compose-rule-core/src/integTest/resources/no-healthcheck.yaml
diff --git a/docker-compose-rule-core/src/main/java/com/palantir/docker/compose/execution/Docker.java b/docker-compose-rule-core/src/main/java/com/palantir/docker/compose/execution/Docker.java
index c7ec8aa4c..94c27f407 100644
--- a/docker-compose-rule-core/src/main/java/com/palantir/docker/compose/execution/Docker.java
+++ b/docker-compose-rule-core/src/main/java/com/palantir/docker/compose/execution/Docker.java
@@ -25,7 +25,6 @@
import java.util.Collection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-
import org.apache.commons.lang3.SystemUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -35,7 +34,7 @@ public class Docker {
private static final Logger log = LoggerFactory.getLogger(Docker.class);
// Without java escape characters: ^(\d+)\.(\d+)\.(\d+)(?:-.*)?$
- private static final Pattern VERSION_PATTERN = Pattern.compile("^Docker version (\\d+)\\.(\\d+)\\.(\\d+)(?:-.*)?$");
+ private static final Pattern VERSION_PATTERN = Pattern.compile("^Docker version (\\d+)\\.(\\d+)\\.(\\d+)(?:(-|,).*)?$");
private static final String HEALTH_STATUS_FORMAT =
"--format="
+ "{{if not .State.Running}}DOWN"
diff --git a/docker-compose-rule-core/src/main/java/com/palantir/docker/compose/execution/DockerCommandLocations.java b/docker-compose-rule-core/src/main/java/com/palantir/docker/compose/execution/DockerCommandLocations.java
deleted file mode 100644
index a1e0c0a06..000000000
--- a/docker-compose-rule-core/src/main/java/com/palantir/docker/compose/execution/DockerCommandLocations.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2016 Palantir Technologies, Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.palantir.docker.compose.execution;
-
-import static java.util.Arrays.asList;
-
-import java.io.File;
-import java.util.List;
-import java.util.Optional;
-import java.util.function.Predicate;
-
-public class DockerCommandLocations {
- private static final Predicate IS_NOT_NULL = path -> path != null;
- private static final Predicate FILE_EXISTS = path -> new File(path).exists();
-
- private final List possiblePaths;
-
- public DockerCommandLocations(String... possiblePaths) {
- this.possiblePaths = asList(possiblePaths);
- }
-
- public Optional preferredLocation() {
-
- return possiblePaths.stream()
- .filter(IS_NOT_NULL)
- .filter(FILE_EXISTS)
- .findFirst();
- }
-
- @Override
- public String toString() {
- return "DockerCommandLocations{possiblePaths=" + possiblePaths + "}";
- }
-}
diff --git a/docker-compose-rule-core/src/main/java/com/palantir/docker/compose/execution/DockerCommandLocator.java b/docker-compose-rule-core/src/main/java/com/palantir/docker/compose/execution/DockerCommandLocator.java
new file mode 100644
index 000000000..402d9c8a2
--- /dev/null
+++ b/docker-compose-rule-core/src/main/java/com/palantir/docker/compose/execution/DockerCommandLocator.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2016 Palantir Technologies, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.palantir.docker.compose.execution;
+
+import com.google.common.collect.ImmutableList;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import javax.annotation.Nullable;
+import org.apache.commons.lang3.SystemUtils;
+import org.immutables.value.Value;
+
+@Value.Immutable
+public abstract class DockerCommandLocator {
+
+ private static final List MAC_SEARCH_LOCATIONS = ImmutableList.of("/usr/local/bin", "/usr/bin");
+
+ protected abstract String command();
+
+ @Value.Default
+ protected boolean isWindows() {
+ return SystemUtils.IS_OS_WINDOWS;
+ }
+
+ @Value.Default
+ protected List macSearchLocations() {
+ return MAC_SEARCH_LOCATIONS;
+ }
+
+ @Value.Derived
+ protected String executableName() {
+ if (isWindows()) {
+ return command() + ".exe";
+ }
+ return command();
+ }
+
+ @Nullable
+ protected abstract String locationOverride();
+
+ public String getLocation() {
+ if (locationOverride() != null) {
+ return locationOverride();
+ }
+ return macSearchLocations()
+ .stream()
+ .map(p -> Paths.get(p, executableName()))
+ .filter(Files::exists)
+ .findFirst()
+ .map(Path::toString)
+ .orElse(executableName());
+ }
+
+ public static ImmutableDockerCommandLocator.Builder forCommand(String command) {
+ return ImmutableDockerCommandLocator.builder()
+ .command(command);
+ }
+
+}
diff --git a/docker-compose-rule-core/src/main/java/com/palantir/docker/compose/execution/DockerComposeExecutable.java b/docker-compose-rule-core/src/main/java/com/palantir/docker/compose/execution/DockerComposeExecutable.java
index 9c2daed21..48a54697e 100644
--- a/docker-compose-rule-core/src/main/java/com/palantir/docker/compose/execution/DockerComposeExecutable.java
+++ b/docker-compose-rule-core/src/main/java/com/palantir/docker/compose/execution/DockerComposeExecutable.java
@@ -29,19 +29,12 @@
public abstract class DockerComposeExecutable implements Executable {
private static final Logger log = LoggerFactory.getLogger(DockerComposeExecutable.class);
- private static final DockerCommandLocations DOCKER_COMPOSE_LOCATIONS = new DockerCommandLocations(
- System.getenv("DOCKER_COMPOSE_LOCATION"),
- "/usr/local/bin/docker-compose",
- "/usr/bin/docker-compose"
- );
-
private static String defaultDockerComposePath() {
- String pathToUse = DOCKER_COMPOSE_LOCATIONS.preferredLocation()
- .orElseThrow(() -> new IllegalStateException(
- "Could not find docker-compose, looked in: " + DOCKER_COMPOSE_LOCATIONS));
-
+ DockerCommandLocator commandLocator = DockerCommandLocator.forCommand("docker-compose")
+ .locationOverride(System.getenv("DOCKER_COMPOSE_LOCATION"))
+ .build();
+ String pathToUse = commandLocator.getLocation();
log.debug("Using docker-compose found at " + pathToUse);
-
return pathToUse;
}
diff --git a/docker-compose-rule-core/src/main/java/com/palantir/docker/compose/execution/DockerExecutable.java b/docker-compose-rule-core/src/main/java/com/palantir/docker/compose/execution/DockerExecutable.java
index 1ff5cf01e..5dc9cf755 100644
--- a/docker-compose-rule-core/src/main/java/com/palantir/docker/compose/execution/DockerExecutable.java
+++ b/docker-compose-rule-core/src/main/java/com/palantir/docker/compose/execution/DockerExecutable.java
@@ -26,12 +26,6 @@
public abstract class DockerExecutable implements Executable {
private static final Logger log = LoggerFactory.getLogger(DockerExecutable.class);
- private static final DockerCommandLocations DOCKER_LOCATIONS = new DockerCommandLocations(
- System.getenv("DOCKER_LOCATION"),
- "/usr/local/bin/docker",
- "/usr/bin/docker"
- );
-
@Value.Parameter protected abstract DockerConfiguration dockerConfiguration();
@Override
@@ -41,12 +35,11 @@ public final String commandName() {
@Value.Derived
protected String dockerPath() {
- String pathToUse = DOCKER_LOCATIONS.preferredLocation()
- .orElseThrow(() -> new IllegalStateException(
- "Could not find docker, looked in: " + DOCKER_LOCATIONS));
-
+ DockerCommandLocator commandLocator = DockerCommandLocator.forCommand("docker")
+ .locationOverride(System.getenv("DOCKER_LOCATION"))
+ .build();
+ String pathToUse = commandLocator.getLocation();
log.debug("Using docker found at " + pathToUse);
-
return pathToUse;
}
@@ -66,4 +59,5 @@ public Process execute(String... commands) throws IOException {
public static ImmutableDockerExecutable.Builder builder() {
return ImmutableDockerExecutable.builder();
}
+
}
diff --git a/docker-compose-rule-core/src/test/java/com/palantir/docker/compose/execution/DockerCommandLocationsShould.java b/docker-compose-rule-core/src/test/java/com/palantir/docker/compose/execution/DockerCommandLocationsShould.java
deleted file mode 100644
index f5b2e44eb..000000000
--- a/docker-compose-rule-core/src/test/java/com/palantir/docker/compose/execution/DockerCommandLocationsShould.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2016 Palantir Technologies, Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.palantir.docker.compose.execution;
-
-import static java.util.Optional.empty;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.Is.is;
-
-import java.io.IOException;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-public class DockerCommandLocationsShould {
- private static final String badLocation = "file/that/does/not/exist";
- private static final String otherBadLocation = "another/file/that/does/not/exist";
-
- @Rule public TemporaryFolder folder = new TemporaryFolder();
-
- private String goodLocation;
-
- @Before
- public void setup() throws IOException {
- goodLocation = folder.newFile("docker-compose.yml").getAbsolutePath();
- }
-
- @Test public void
- provide_the_first_docker_command_location_if_it_exists() {
- DockerCommandLocations dockerCommandLocations = new DockerCommandLocations(
- badLocation,
- goodLocation,
- otherBadLocation);
-
- assertThat(dockerCommandLocations.preferredLocation().get(),
- is(goodLocation));
- }
-
- @Test public void
- skip_paths_from_environment_variables_that_are_unset() {
- DockerCommandLocations dockerCommandLocations = new DockerCommandLocations(
- System.getenv("AN_UNSET_DOCKER_COMPOSE_PATH"),
- goodLocation);
-
- assertThat(dockerCommandLocations.preferredLocation().get(),
- is(goodLocation));
- }
-
- @Test public void
- have_no_preferred_path_when_all_possible_paths_are_all_invalid() {
- DockerCommandLocations dockerCommandLocations = new DockerCommandLocations(
- badLocation);
-
- assertThat(dockerCommandLocations.preferredLocation(),
- is(empty()));
- }
-}
diff --git a/docker-compose-rule-core/src/test/java/com/palantir/docker/compose/execution/DockerCommandLocatorShould.java b/docker-compose-rule-core/src/test/java/com/palantir/docker/compose/execution/DockerCommandLocatorShould.java
new file mode 100644
index 000000000..d32348db3
--- /dev/null
+++ b/docker-compose-rule-core/src/test/java/com/palantir/docker/compose/execution/DockerCommandLocatorShould.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2016 Palantir Technologies, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.palantir.docker.compose.execution;
+
+import static java.util.Collections.singletonList;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+
+public class DockerCommandLocatorShould {
+ private static final String command = "not-a-real-command!";
+ private static final String windowsCommand = command + ".exe";
+
+ @Rule public TemporaryFolder folder = new TemporaryFolder();
+
+ @Rule public ExpectedException exception = ExpectedException.none();
+
+ @Test public void
+ returns_the_command_name_when_no_other_paths_contain_command() {
+ DockerCommandLocator locator = DockerCommandLocator.forCommand(command)
+ .isWindows(false)
+ .build();
+
+ assertThat(locator.getLocation(), is(command));
+ }
+
+ @Test public void
+ returns_the_command_name_with_exe_on_windows_when_no_other_paths_contain_command() {
+ DockerCommandLocator locator = DockerCommandLocator.forCommand(command)
+ .isWindows(true)
+ .build();
+
+ assertThat(locator.getLocation(), is(windowsCommand));
+ }
+
+ @Test public void
+ allow_the_path_to_be_overriden() throws IOException {
+ Path overrideFolder = folder.newFolder("override").toPath();
+ String overridenCommand = Files.createFile(overrideFolder.resolve(command)).toString();
+
+ DockerCommandLocator locator = DockerCommandLocator.forCommand(command)
+ .locationOverride(overridenCommand)
+ .isWindows(false)
+ .build();
+
+ assertThat(locator.getLocation(), is(overridenCommand));
+ }
+
+ @Test public void
+ search_in_known_mac_install_locations_for_the_command() throws IOException {
+ Path macSearchFolder = folder.newFolder("override").toPath();
+ String commandLocation = Files.createFile(macSearchFolder.resolve(command)).toString();
+
+ DockerCommandLocator locator = DockerCommandLocator.forCommand(command)
+ .macSearchLocations(singletonList(macSearchFolder.toString()))
+ .isWindows(false)
+ .build();
+
+ assertThat(locator.getLocation(), is(commandLocation));
+ }
+
+}
diff --git a/docker-compose-rule-core/src/test/java/com/palantir/docker/compose/execution/DockerShould.java b/docker-compose-rule-core/src/test/java/com/palantir/docker/compose/execution/DockerShould.java
index a55fbd2aa..73d427533 100644
--- a/docker-compose-rule-core/src/test/java/com/palantir/docker/compose/execution/DockerShould.java
+++ b/docker-compose-rule-core/src/test/java/com/palantir/docker/compose/execution/DockerShould.java
@@ -62,7 +62,7 @@ public void call_docker_network_ls() throws IOException, InterruptedException {
@Test
public void understand_old_version_format() throws IOException, InterruptedException {
- when(executedProcess.getInputStream()).thenReturn(toInputStream("Docker version 1.7.2"));
+ when(executedProcess.getInputStream()).thenReturn(toInputStream("Docker version 1.7.2, build abcdef"));
Version version = docker.configuredVersion();
assertThat(version, is(Version.valueOf("1.7.2")));
diff --git a/docker-compose-rule-core/src/test/java/com/palantir/docker/compose/execution/RetryerShould.java b/docker-compose-rule-core/src/test/java/com/palantir/docker/compose/execution/RetryerShould.java
index 1a2764677..0f60b83d6 100644
--- a/docker-compose-rule-core/src/test/java/com/palantir/docker/compose/execution/RetryerShould.java
+++ b/docker-compose-rule-core/src/test/java/com/palantir/docker/compose/execution/RetryerShould.java
@@ -20,6 +20,7 @@
import static org.hamcrest.Matchers.lessThan;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -27,6 +28,7 @@
import com.google.common.base.Stopwatch;
import com.palantir.docker.compose.utils.MockitoMultiAnswer;
import java.util.concurrent.TimeUnit;
+import org.apache.commons.lang3.SystemUtils;
import org.joda.time.Duration;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -61,11 +63,13 @@ public void should_not_pause_after_last_failure() throws Exception {
@Test
public void retryer_should_wait_after_failure_before_trying_again() throws Exception {
+ assumeTrue("Not running on Windows as Thread.sleep isn't accurate there", !SystemUtils.IS_OS_WINDOWS);
+
Retryer timeRetryer = new Retryer(1, Duration.millis(100));
Stopwatch stopwatch = Stopwatch.createStarted();
when(operation.call()).thenThrow(new DockerExecutionException()).thenAnswer(i -> {
- assertThat(stopwatch.elapsed(TimeUnit.MILLISECONDS), greaterThan(100L));
+ assertThat(stopwatch.elapsed(TimeUnit.MILLISECONDS), greaterThan(98L));
return "success";
});
diff --git a/docker-compose-rule-junit4/build.gradle b/docker-compose-rule-junit4/build.gradle
index f9f2fe3a2..f4eec86fc 100644
--- a/docker-compose-rule-junit4/build.gradle
+++ b/docker-compose-rule-junit4/build.gradle
@@ -23,3 +23,15 @@ dependencies {
if (System.env.CIRCLE_TEST_REPORTS) {
test.reports.junitXml.destination = file(System.env.CIRCLE_TEST_REPORTS)
}
+
+task windowsSmokeTest(type: Test) {
+ testClassesDir = sourceSets.integTest.output.classesDir
+ classpath = sourceSets.integTest.runtimeClasspath
+
+ reports.html.destination = "${project.buildDir}/reports/integTest"
+ reports.junitXml.destination = "${project.buildDir}/integTest-results"
+ binResultsDir = file("${project.buildDir}/integTest-results/binary/integTest")
+
+ include '**/windows/**'
+}
+
diff --git a/docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/AggressiveShutdownStrategyIntegrationTest.java b/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/AggressiveShutdownStrategyIntegrationTest.java
similarity index 93%
rename from docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/AggressiveShutdownStrategyIntegrationTest.java
rename to docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/AggressiveShutdownStrategyIntegrationTest.java
index 058e15e0d..e5cda5646 100644
--- a/docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/AggressiveShutdownStrategyIntegrationTest.java
+++ b/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/AggressiveShutdownStrategyIntegrationTest.java
@@ -16,7 +16,7 @@ public class AggressiveShutdownStrategyIntegrationTest {
@Test
public void shut_down_multiple_containers_immediately() throws Exception {
DockerComposeRule rule = DockerComposeRule.builder()
- .file("src/test/resources/shutdown-strategy.yaml")
+ .file("src/integTest/resources/shutdown-strategy.yaml")
.logCollector(new DoNothingLogCollector())
.retryAttempts(0)
.shutdownStrategy(ShutdownStrategy.AGGRESSIVE)
diff --git a/docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/AggressiveShutdownWithNetworkCleanupStrategyIntegrationTest.java b/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/AggressiveShutdownWithNetworkCleanupStrategyIntegrationTest.java
similarity index 95%
rename from docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/AggressiveShutdownWithNetworkCleanupStrategyIntegrationTest.java
rename to docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/AggressiveShutdownWithNetworkCleanupStrategyIntegrationTest.java
index 35eacafa7..41613ce1f 100644
--- a/docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/AggressiveShutdownWithNetworkCleanupStrategyIntegrationTest.java
+++ b/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/AggressiveShutdownWithNetworkCleanupStrategyIntegrationTest.java
@@ -18,7 +18,7 @@
public class AggressiveShutdownWithNetworkCleanupStrategyIntegrationTest {
private final DockerComposeRule rule = DockerComposeRule.builder()
- .file("src/test/resources/shutdown-strategy-with-network.yaml")
+ .file("src/integTest/resources/shutdown-strategy-with-network.yaml")
.logCollector(new DoNothingLogCollector())
.retryAttempts(0)
.shutdownStrategy(ShutdownStrategy.AGGRESSIVE_WITH_NETWORK_CLEANUP)
diff --git a/docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/DockerComposeRuleIntegrationTest.java b/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/DockerComposeRuleIntegrationTest.java
similarity index 98%
rename from docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/DockerComposeRuleIntegrationTest.java
rename to docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/DockerComposeRuleIntegrationTest.java
index 8162b087e..17dca78e5 100644
--- a/docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/DockerComposeRuleIntegrationTest.java
+++ b/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/DockerComposeRuleIntegrationTest.java
@@ -45,7 +45,7 @@ public class DockerComposeRuleIntegrationTest {
@Rule
public final DockerComposeRule docker = DockerComposeRule.builder()
- .files(DockerComposeFiles.from("src/test/resources/docker-compose.yaml"))
+ .files(DockerComposeFiles.from("src/integTest/resources/docker-compose.yaml"))
.waitingForService("db", toHaveAllPortsOpen())
.waitingForService("db2", toHaveAllPortsOpen())
.waitingForServices(ImmutableList.of("db3", "db4"), toAllHaveAllPortsOpen())
diff --git a/docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/DockerComposeRuleNativeHealthcheckIntegrationTest.java b/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/DockerComposeRuleNativeHealthcheckIntegrationTest.java
similarity index 97%
rename from docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/DockerComposeRuleNativeHealthcheckIntegrationTest.java
rename to docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/DockerComposeRuleNativeHealthcheckIntegrationTest.java
index 6ad62740f..fad8f15fe 100644
--- a/docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/DockerComposeRuleNativeHealthcheckIntegrationTest.java
+++ b/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/DockerComposeRuleNativeHealthcheckIntegrationTest.java
@@ -53,7 +53,7 @@ public void dockerComposeRuleWaitsUntilHealthcheckPasses()
assumeThat("docker-compose version", DockerCompose.version(), new GreaterOrEqual<>(Version.forIntegers(1, 10, 0)));
rule = DockerComposeRule.builder()
- .file("src/test/resources/native-healthcheck.yaml")
+ .file("src/integTest/resources/native-healthcheck.yaml")
.build();
Future> beforeFuture = pool.submit(() -> {
rule.before();
diff --git a/docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/DockerComposeRuleUpContainerIntegrationTest.java b/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/DockerComposeRuleUpContainerIntegrationTest.java
similarity index 97%
rename from docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/DockerComposeRuleUpContainerIntegrationTest.java
rename to docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/DockerComposeRuleUpContainerIntegrationTest.java
index 488a2b949..45f96b8ad 100644
--- a/docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/DockerComposeRuleUpContainerIntegrationTest.java
+++ b/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/DockerComposeRuleUpContainerIntegrationTest.java
@@ -37,7 +37,7 @@ public class DockerComposeRuleUpContainerIntegrationTest {
public final DockerComposeRule dockerComposeRule = DockerComposeRule
.builder()
.shutdownStrategy(AGGRESSIVE)
- .file("src/test/resources/up-integration-test.yaml")
+ .file("src/integTest/resources/up-integration-test.yaml")
.build();
@Test
diff --git a/docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/HostNetworkedPortsIntegrationTest.java b/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/HostNetworkedPortsIntegrationTest.java
similarity index 96%
rename from docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/HostNetworkedPortsIntegrationTest.java
rename to docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/HostNetworkedPortsIntegrationTest.java
index baf59ed37..64f2f117b 100644
--- a/docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/HostNetworkedPortsIntegrationTest.java
+++ b/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/HostNetworkedPortsIntegrationTest.java
@@ -22,7 +22,6 @@
import com.palantir.docker.compose.connection.DockerPort;
import com.palantir.docker.compose.connection.waiting.HealthCheck;
import com.palantir.docker.compose.connection.waiting.SuccessOrFailure;
-
import org.apache.commons.lang3.SystemUtils;
import org.junit.Test;
@@ -40,7 +39,7 @@ private static HealthCheck toBeOpen() {
assumeTrue("Host ports are only accessible on linux", SystemUtils.IS_OS_LINUX);
DockerComposeRule docker = DockerComposeRule.builder()
- .file("src/test/resources/host-networked-docker-compose.yaml")
+ .file("src/integTest/resources/host-networked-docker-compose.yaml")
.waitingForHostNetworkedPort(5432, toBeOpen())
.build();
try {
diff --git a/docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/RemoveConflictingContainersIntegrationTest.java b/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/RemoveConflictingContainersIntegrationTest.java
similarity index 97%
rename from docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/RemoveConflictingContainersIntegrationTest.java
rename to docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/RemoveConflictingContainersIntegrationTest.java
index 84961cc78..800e8f149 100644
--- a/docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/RemoveConflictingContainersIntegrationTest.java
+++ b/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/RemoveConflictingContainersIntegrationTest.java
@@ -25,7 +25,7 @@
public class RemoveConflictingContainersIntegrationTest {
- private static final String DOCKER_COMPOSE_YAML_PATH = "src/test/resources/named-containers-docker-compose.yaml";
+ private static final String DOCKER_COMPOSE_YAML_PATH = "src/integTest/resources/named-containers-docker-compose.yaml";
@Rule
public ExpectedException exception = ExpectedException.none();
diff --git a/docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/execution/EnvironmentVariableIntegrationTest.java b/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/execution/EnvironmentVariableIntegrationTest.java
similarity index 96%
rename from docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/execution/EnvironmentVariableIntegrationTest.java
rename to docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/execution/EnvironmentVariableIntegrationTest.java
index 304ba7dcd..25ddfa1ff 100644
--- a/docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/execution/EnvironmentVariableIntegrationTest.java
+++ b/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/execution/EnvironmentVariableIntegrationTest.java
@@ -39,7 +39,7 @@ public void docker_compose_gets_environment_variables_from_docker_machine_and_pa
.build();
DockerComposeRule dockerComposition = DockerComposeRule.builder()
- .file("src/test/resources/environment/docker-compose.yaml")
+ .file("src/integTest/resources/environment/docker-compose.yaml")
.machine(dockerMachine)
.waitingForService("env-test", toHaveAllPortsOpen())
.saveLogsTo(temporaryFolder.getRoot().getAbsolutePath())
diff --git a/docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/logging/LoggingIntegrationTest.java b/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/logging/LoggingIntegrationTest.java
similarity index 97%
rename from docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/logging/LoggingIntegrationTest.java
rename to docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/logging/LoggingIntegrationTest.java
index f227e0bbe..94a569a5d 100644
--- a/docker-compose-rule-junit4/src/test/java/com/palantir/docker/compose/logging/LoggingIntegrationTest.java
+++ b/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/logging/LoggingIntegrationTest.java
@@ -39,7 +39,7 @@ public class LoggingIntegrationTest {
@Before
public void setUp() {
dockerComposeRule = DockerComposeRule.builder()
- .file("src/test/resources/docker-compose.yaml")
+ .file("src/integTest/resources/docker-compose.yaml")
.waitingForService("db", toHaveAllPortsOpen())
.waitingForService("db2", toHaveAllPortsOpen())
.saveLogsTo(logFolder.getRoot().getAbsolutePath())
diff --git a/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/windows/WindowsIntegrationTest.java b/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/windows/WindowsIntegrationTest.java
new file mode 100644
index 000000000..394004ee9
--- /dev/null
+++ b/docker-compose-rule-junit4/src/integTest/java/com/palantir/docker/compose/windows/WindowsIntegrationTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2016 Palantir Technologies, Inc. All rights reserved.
+ */
+
+package com.palantir.docker.compose.windows;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assume.assumeTrue;
+
+import com.palantir.docker.compose.DockerComposeRule;
+import com.palantir.docker.compose.configuration.DockerComposeFiles;
+import com.palantir.docker.compose.connection.State;
+import java.io.IOException;
+import org.apache.commons.lang3.SystemUtils;
+import org.junit.Test;
+
+public class WindowsIntegrationTest {
+
+ @Test
+ public void can_execute_docker_commands() throws IOException, InterruptedException {
+ assumeTrue("Running on Windows", SystemUtils.IS_OS_WINDOWS);
+
+ DockerComposeRule docker = DockerComposeRule.builder()
+ .files(DockerComposeFiles.from("src/integTest/resources/windows-docker-compose.yaml"))
+ .build();
+ docker.before();
+
+ try {
+ assertThat(docker.containers().container("hello-world").state(), is(State.DOWN));
+ } finally {
+ docker.after();
+ }
+ }
+
+}
diff --git a/docker-compose-rule-junit4/src/test/resources/docker-compose.yaml b/docker-compose-rule-junit4/src/integTest/resources/docker-compose.yaml
similarity index 100%
rename from docker-compose-rule-junit4/src/test/resources/docker-compose.yaml
rename to docker-compose-rule-junit4/src/integTest/resources/docker-compose.yaml
diff --git a/docker-compose-rule-junit4/src/test/resources/environment/docker-compose.yaml b/docker-compose-rule-junit4/src/integTest/resources/environment/docker-compose.yaml
similarity index 100%
rename from docker-compose-rule-junit4/src/test/resources/environment/docker-compose.yaml
rename to docker-compose-rule-junit4/src/integTest/resources/environment/docker-compose.yaml
diff --git a/docker-compose-rule-junit4/src/test/resources/host-networked-docker-compose.yaml b/docker-compose-rule-junit4/src/integTest/resources/host-networked-docker-compose.yaml
similarity index 100%
rename from docker-compose-rule-junit4/src/test/resources/host-networked-docker-compose.yaml
rename to docker-compose-rule-junit4/src/integTest/resources/host-networked-docker-compose.yaml
diff --git a/docker-compose-rule-junit4/src/test/resources/named-containers-docker-compose.yaml b/docker-compose-rule-junit4/src/integTest/resources/named-containers-docker-compose.yaml
similarity index 100%
rename from docker-compose-rule-junit4/src/test/resources/named-containers-docker-compose.yaml
rename to docker-compose-rule-junit4/src/integTest/resources/named-containers-docker-compose.yaml
diff --git a/docker-compose-rule-junit4/src/test/resources/native-healthcheck.yaml b/docker-compose-rule-junit4/src/integTest/resources/native-healthcheck.yaml
similarity index 100%
rename from docker-compose-rule-junit4/src/test/resources/native-healthcheck.yaml
rename to docker-compose-rule-junit4/src/integTest/resources/native-healthcheck.yaml
diff --git a/docker-compose-rule-junit4/src/test/resources/shutdown-strategy-with-network.yaml b/docker-compose-rule-junit4/src/integTest/resources/shutdown-strategy-with-network.yaml
similarity index 100%
rename from docker-compose-rule-junit4/src/test/resources/shutdown-strategy-with-network.yaml
rename to docker-compose-rule-junit4/src/integTest/resources/shutdown-strategy-with-network.yaml
diff --git a/docker-compose-rule-junit4/src/test/resources/shutdown-strategy.yaml b/docker-compose-rule-junit4/src/integTest/resources/shutdown-strategy.yaml
similarity index 100%
rename from docker-compose-rule-junit4/src/test/resources/shutdown-strategy.yaml
rename to docker-compose-rule-junit4/src/integTest/resources/shutdown-strategy.yaml
diff --git a/docker-compose-rule-junit4/src/test/resources/up-integration-test.yaml b/docker-compose-rule-junit4/src/integTest/resources/up-integration-test.yaml
similarity index 100%
rename from docker-compose-rule-junit4/src/test/resources/up-integration-test.yaml
rename to docker-compose-rule-junit4/src/integTest/resources/up-integration-test.yaml
diff --git a/docker-compose-rule-junit4/src/integTest/resources/windows-docker-compose.yaml b/docker-compose-rule-junit4/src/integTest/resources/windows-docker-compose.yaml
new file mode 100644
index 000000000..d1e98b7bc
--- /dev/null
+++ b/docker-compose-rule-junit4/src/integTest/resources/windows-docker-compose.yaml
@@ -0,0 +1,4 @@
+hello-world:
+ image: microsoft/windowsservercore
+ command: echo "Server started"
+
diff --git a/gradle/integTest.gradle b/gradle/integTest.gradle
new file mode 100644
index 000000000..bf1dcea1c
--- /dev/null
+++ b/gradle/integTest.gradle
@@ -0,0 +1,67 @@
+// From https://raw.githubusercontent.com/spring-io/sagan/master/gradle/integTest.gradle
+import org.gradle.api.tasks.testing.Test
+
+/**
+ * This script adds a dedicated integration testing source set (src/integTest) and task
+ * (integTest) when applied to any Java project.
+ *
+ * Configuration:
+ * apply from: path/to/integTest.gradle
+ *
+ * Usage:
+ * gradle integTest
+ * - or -
+ * gradle check
+ */
+
+sourceSets {
+ integTest {
+ java.srcDir 'src/integTest/java'
+ resources.srcDir 'src/integTest/resources'
+ }
+}
+
+task integTest(type: Test) {
+ description = "Runs integration tests."
+
+ testClassesDir = sourceSets.integTest.output.classesDir
+ classpath = sourceSets.integTest.runtimeClasspath
+
+ maxHeapSize = '1024m'
+
+ // ensure we don't overwrite default report directories used by 'test' task
+ reports.html.destination = "${project.buildDir}/reports/integTest"
+ reports.junitXml.destination = "${project.buildDir}/integTest-results"
+ binResultsDir = file("${project.buildDir}/integTest-results/binary/integTest")
+
+ // always run integration tests after unit tests in order to fail fast
+ mustRunAfter test
+}
+
+dependencies {
+ integTestCompile sourceSets.main.output
+ integTestCompile sourceSets.test.output
+ integTestCompile configurations.compile
+ integTestCompile configurations.testCompile
+ integTestRuntime configurations.runtime
+ integTestRuntime configurations.testRuntime
+}
+
+// Ensure unit test tasks (named 'test') always run before integration tests in
+// order to fail as fast as possible
+gradle.projectsEvaluated {
+ def unitTestTasks = []
+ gradle.rootProject.allprojects { project ->
+ unitTestTasks.addAll(project.tasks.findAll { it.name == 'test' })
+ }
+ unitTestTasks.each { unitTestTask ->
+ project.integTest.mustRunAfter unitTestTask
+ }
+}
+
+// Add integration test source directories to IDEA .iml files
+if (project.plugins.hasPlugin('idea')) {
+ idea.module {
+ testSourceDirs += (sourceSets.integTest.java.srcDirs + sourceSets.integTest.resources.srcDirs)
+ }
+}