Skip to content

Commit 89bedea

Browse files
authored
Merge branch 'master' into 1770_docker_host_env
2 parents c24b9e9 + 142e585 commit 89bedea

42 files changed

Lines changed: 384 additions & 262 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88
in-docker_test:
99
runs-on: ubuntu-18.04
1010
steps:
11-
- uses: actions/checkout@v1
11+
- uses: actions/checkout@v2
1212
- name: Build with Gradle
1313
run: |
1414
docker run -i --rm \
@@ -18,4 +18,3 @@ jobs:
1818
-w "$PWD" \
1919
openjdk:8-jdk-alpine \
2020
./gradlew --no-daemon --continue --scan testcontainers:test --tests '*GenericContainerRuleTest'
21-

.github/workflows/gradle-release.yml

Lines changed: 0 additions & 22 deletions
This file was deleted.

.github/workflows/update-docs-version.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88
build:
99
runs-on: ubuntu-18.04
1010
steps:
11-
- uses: actions/checkout@v1
11+
- uses: actions/checkout@v2
1212
- name: Checkout master
1313
run: git checkout master
1414
- name: Update latest_version property in mkdocs.yml

.travis.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
if: tag is present
2+
3+
language: java
4+
jdk:
5+
- openjdk8
6+
7+
sudo: required
8+
services:
9+
- docker
10+
11+
jobs:
12+
include:
13+
14+
- stage: deploy
15+
sudo: false
16+
services: []
17+
install: skip
18+
script: skip
19+
deploy:
20+
provider: script
21+
script: ./gradlew -Pversion=$TRAVIS_TAG release --scan --no-daemon -i
22+
on:
23+
tags: true
24+
branch: master

core/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ dependencies {
108108
testCompile 'org.apache.httpcomponents:httpclient:4.5.9'
109109
testCompile 'redis.clients:jedis:3.2.0'
110110
testCompile 'com.rabbitmq:amqp-client:5.8.0'
111-
testCompile 'org.mongodb:mongo-java-driver:3.12.0'
111+
testCompile 'org.mongodb:mongo-java-driver:3.12.1'
112112
testCompile ('org.mockito:mockito-core:3.2.4') {
113113
exclude(module: 'hamcrest-core')
114114
}

core/src/main/java/org/testcontainers/DockerClientFactory.java

Lines changed: 57 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@
1717
import lombok.SneakyThrows;
1818
import lombok.Synchronized;
1919
import lombok.extern.slf4j.Slf4j;
20-
import org.hamcrest.BaseMatcher;
21-
import org.hamcrest.Description;
22-
import org.rnorth.visibleassertions.VisibleAssertions;
2320
import org.testcontainers.dockerclient.DockerClientProviderStrategy;
2421
import org.testcontainers.dockerclient.DockerMachineClientProviderStrategy;
2522
import org.testcontainers.images.TimeLimitedLoggedPullImageResultCallback;
@@ -68,12 +65,16 @@ public class DockerClientFactory {
6865
@VisibleForTesting
6966
DockerClient dockerClient;
7067

68+
@VisibleForTesting
69+
RuntimeException cachedChecksFailure;
70+
7171
private String activeApiVersion;
7272
private String activeExecutionDriver;
7373

7474
@Getter(lazy = true)
7575
private final boolean fileMountingSupported = checkMountableFile();
7676

77+
7778
static {
7879
System.setProperty("org.testcontainers.shaded.io.netty.packagePrefix", "org.testcontainers.shaded.");
7980
}
@@ -124,6 +125,12 @@ public DockerClient client() {
124125
return dockerClient;
125126
}
126127

128+
// fail-fast if checks have failed previously
129+
if (cachedChecksFailure != null) {
130+
log.debug("There is a cached checks failure - throwing", cachedChecksFailure);
131+
throw cachedChecksFailure;
132+
}
133+
127134
final DockerClientProviderStrategy strategy = getOrInitializeStrategy();
128135

129136
String hostIpAddress = strategy.getDockerHostIpAddress();
@@ -140,51 +147,56 @@ public DockerClient client() {
140147
" Operating System: " + dockerInfo.getOperatingSystem() + "\n" +
141148
" Total Memory: " + dockerInfo.getMemTotal() / (1024 * 1024) + " MB");
142149

143-
String ryukContainerId = null;
150+
final String ryukContainerId;
151+
144152
boolean useRyuk = !Boolean.parseBoolean(System.getenv("TESTCONTAINERS_RYUK_DISABLED"));
145153
if (useRyuk) {
154+
log.debug("Ryuk is enabled");
146155
ryukContainerId = ResourceReaper.start(hostIpAddress, client);
147156
log.info("Ryuk started - will monitor and terminate Testcontainers containers on JVM exit");
157+
} else {
158+
log.debug("Ryuk is disabled");
159+
ryukContainerId = null;
148160
}
149161

150162
boolean checksEnabled = !TestcontainersConfiguration.getInstance().isDisableChecks();
151163
if (checksEnabled) {
152-
VisibleAssertions.info("Checking the system...");
153-
checkDockerVersion(version.getVersion());
154-
if (ryukContainerId != null) {
155-
checkDiskSpace(client, ryukContainerId);
156-
} else {
157-
runInsideDocker(
158-
client,
159-
createContainerCmd -> {
160-
createContainerCmd.withName("testcontainers-checks-" + SESSION_ID);
161-
createContainerCmd.getHostConfig().withAutoRemove(true);
162-
createContainerCmd.withCmd("tail", "-f", "/dev/null");
163-
},
164-
(__, containerId) -> {
165-
checkDiskSpace(client, containerId);
166-
return "";
167-
}
168-
);
164+
log.debug("Checks are enabled");
165+
166+
try {
167+
log.info("Checking the system...");
168+
checkDockerVersion(version.getVersion());
169+
if (ryukContainerId != null) {
170+
checkDiskSpace(client, ryukContainerId);
171+
} else {
172+
runInsideDocker(
173+
client,
174+
createContainerCmd -> {
175+
createContainerCmd.withName("testcontainers-checks-" + SESSION_ID);
176+
createContainerCmd.getHostConfig().withAutoRemove(true);
177+
createContainerCmd.withCmd("tail", "-f", "/dev/null");
178+
},
179+
(__, containerId) -> {
180+
checkDiskSpace(client, containerId);
181+
return "";
182+
}
183+
);
184+
}
185+
} catch (RuntimeException e) {
186+
cachedChecksFailure = e;
187+
throw e;
169188
}
189+
} else {
190+
log.debug("Checks are disabled");
170191
}
171192

172193
dockerClient = client;
173194
return dockerClient;
174195
}
175196

176197
private void checkDockerVersion(String dockerVersion) {
177-
VisibleAssertions.assertThat("Docker version", dockerVersion, new BaseMatcher<String>() {
178-
@Override
179-
public boolean matches(Object o) {
180-
return new ComparableVersion(o.toString()).compareTo(new ComparableVersion("1.6.0")) >= 0;
181-
}
182-
183-
@Override
184-
public void describeTo(Description description) {
185-
description.appendText("should be at least 1.6.0");
186-
}
187-
});
198+
boolean versionIsSufficient = new ComparableVersion(dockerVersion).compareTo(new ComparableVersion("1.6.0")) >= 0;
199+
check("Docker server version should be at least 1.6.0", versionIsSufficient);
188200
}
189201

190202
private void checkDiskSpace(DockerClient dockerClient, String id) {
@@ -201,12 +213,21 @@ private void checkDiskSpace(DockerClient dockerClient, String id) {
201213

202214
DiskSpaceUsage df = parseAvailableDiskSpace(outputStream.toString());
203215

204-
VisibleAssertions.assertTrue(
216+
check(
205217
"Docker environment should have more than 2GB free disk space",
206218
df.availableMB.map(it -> it >= 2048).orElse(true)
207219
);
208220
}
209221

222+
private void check(String message, boolean isSuccessful) {
223+
if (isSuccessful) {
224+
log.info("\u2714︎ {}", message);
225+
} else {
226+
log.error("\u274c {}", message);
227+
throw new IllegalStateException("Check failed: " + message);
228+
}
229+
}
230+
210231
private boolean checkMountableFile() {
211232
DockerClient dockerClient = client();
212233

@@ -267,8 +288,8 @@ private <T> T runInsideDocker(DockerClient client, Consumer<CreateContainerCmd>
267288
} finally {
268289
try {
269290
client.removeContainerCmd(id).withRemoveVolumes(true).withForce(true).exec();
270-
} catch (NotFoundException | InternalServerErrorException ignored) {
271-
log.debug("", ignored);
291+
} catch (NotFoundException | InternalServerErrorException e) {
292+
log.debug("Swallowed exception while removing container", e);
272293
}
273294
}
274295
}
@@ -286,7 +307,7 @@ DiskSpaceUsage parseAvailableDiskSpace(String dfOutput) {
286307
for (String line : lines) {
287308
String[] fields = line.split("\\s+");
288309
if (fields.length > 5 && fields[5].equals("/")) {
289-
long availableKB = Long.valueOf(fields[3]);
310+
long availableKB = Long.parseLong(fields[3]);
290311
df.availableMB = Optional.of(availableKB / 1024L);
291312
df.usedPercent = Optional.of(Integer.valueOf(fields[4].replace("%", "")));
292313
break;
@@ -318,10 +339,4 @@ public String getActiveExecutionDriver() {
318339
public boolean isUsing(Class<? extends DockerClientProviderStrategy> providerStrategyClass) {
319340
return strategy != null && providerStrategyClass.isAssignableFrom(this.strategy.getClass());
320341
}
321-
322-
private static class NotEnoughDiskSpaceException extends RuntimeException {
323-
NotEnoughDiskSpaceException(String message) {
324-
super(message);
325-
}
326-
}
327342
}

core/src/main/java/org/testcontainers/containers/Container.java

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -420,61 +420,6 @@ default void followOutput(Consumer<OutputFrame> consumer, OutputFrame.OutputType
420420
@Deprecated
421421
Info fetchDockerDaemonInfo() throws IOException;
422422

423-
/**
424-
* Run a command inside a running container, as though using "docker exec", and interpreting
425-
* the output as UTF8.
426-
* <p>
427-
* @see ExecInContainerPattern#execInContainer(com.github.dockerjava.api.command.InspectContainerResponse, String...)
428-
*/
429-
ExecResult execInContainer(String... command)
430-
throws UnsupportedOperationException, IOException, InterruptedException;
431-
432-
/**
433-
* Run a command inside a running container, as though using "docker exec".
434-
* <p>
435-
* @see ExecInContainerPattern#execInContainer(com.github.dockerjava.api.command.InspectContainerResponse, Charset, String...)
436-
*/
437-
ExecResult execInContainer(Charset outputCharset, String... command)
438-
throws UnsupportedOperationException, IOException, InterruptedException;
439-
440-
/**
441-
*
442-
* Copies a file or directory to the container.
443-
*
444-
* @param mountableFile file or directory which is copied into the container
445-
* @param containerPath destination path inside the container
446-
* @throws IOException if there's an issue communicating with Docker
447-
* @throws InterruptedException if the thread waiting for the response is interrupted
448-
*/
449-
void copyFileToContainer(MountableFile mountableFile, String containerPath) throws IOException, InterruptedException;
450-
451-
/**
452-
*
453-
* Copies a file to the container.
454-
*
455-
* @param transferable file which is copied into the container
456-
* @param containerPath destination path inside the container
457-
*/
458-
void copyFileToContainer(Transferable transferable, String containerPath);
459-
460-
/**
461-
* Copies a file which resides inside the container to user defined directory
462-
*
463-
* @param containerPath path to file which is copied from container
464-
* @param destinationPath destination path to which file is copied with file name
465-
* @throws IOException if there's an issue communicating with Docker or receiving entry from TarArchiveInputStream
466-
* @throws InterruptedException if the thread waiting for the response is interrupted
467-
*/
468-
void copyFileFromContainer(String containerPath, String destinationPath) throws IOException, InterruptedException;
469-
470-
/**
471-
* Streams a file which resides inside the container
472-
*
473-
* @param containerPath path to file which is copied from container
474-
* @param function function that takes InputStream of the copied file
475-
*/
476-
<T> T copyFileFromContainer(String containerPath, ThrowingFunction<InputStream, T> function);
477-
478423
List<String> getPortBindings();
479424

480425
List<String> getExtraHosts();

0 commit comments

Comments
 (0)