Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.1 #167

Merged
merged 40 commits into from
Jul 5, 2016
Merged

1.1 #167

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
fab4ef8
Refactor to use the docker-java v3 with Netty support
rnorth May 1, 2016
249593b
Introduce a wait period between JDBC connection checks to avoid heavy…
rnorth May 2, 2016
53e14cc
Ignore a flapping test
rnorth May 2, 2016
5619c77
Update to release version of docker-java (3.0.0)
rnorth Jun 5, 2016
991873b
Reduce log noise
rnorth Jun 5, 2016
0fab0af
Workaround for SeleniumHQ/docker-selenium#227
rnorth Jun 5, 2016
0c4930d
Make ContainerReaper more intelligent about not trying to kill stoppe…
rnorth Jun 5, 2016
db230d9
Refactor ProxiedUnixSocketConfigurationStrategy and UnixSocketConfigu…
rnorth Jun 10, 2016
bf946c9
Switch Docker Compose tests to use Jedis rather than Redisson to avoi…
rnorth Jun 10, 2016
9246d6c
Tidy up Slf4jLogConsumer output to reduce duplicate whitespace
rnorth Jun 10, 2016
bc41218
Prevent NullPointerException at the end of container output when pipi…
rnorth Jun 10, 2016
68fb35f
Reduce log level for container reaper success messages
rnorth Jun 10, 2016
3478853
Add extra debugging logs to help diagnose any future docker daemon co…
rnorth Jun 10, 2016
5b5d32b
Ensure that linked containers are added to the same network as the co…
rnorth Jun 10, 2016
a933421
Add automated test for passing environment variables through to a doc…
rnorth Jun 11, 2016
cfe1eb2
Add cleanup of networks created by docker-compose
rnorth Jun 11, 2016
eb75a90
Make linked container identification compatible with container names …
rnorth Jun 21, 2016
fafde15
Change to client factory code to use netty command factory
rnorth Jun 21, 2016
7a7c930
Remove profiler logs from build output
rnorth Jul 2, 2016
8adca92
Add logging of Docker API version for diagnostics
rnorth Jul 2, 2016
db4c79c
Fix NPE in DockerMachineClientProviderStrategy due to not retaining s…
rnorth Jul 2, 2016
2846ec8
Implement smarter options for specifying compose service index as per…
rnorth Jul 2, 2016
f08f887
Add test to make sure that an invalid docker-compose file causes a fa…
rnorth Jul 2, 2016
2a9453d
Remove container startup retries. Testing indicates that this is no l…
rnorth Jul 2, 2016
18aa341
Speed up HostPortWaitStrategyTest expected failure
rnorth Jul 2, 2016
c48f7ae
Relax unix socket validation code by using bitmasking rather than a s…
rnorth Jul 3, 2016
f2d2188
General code/javadocs cleanup
rnorth Jul 3, 2016
3f5d716
Add mechanism for ignoring some tests in environments that do not sup…
rnorth Jul 3, 2016
8403cd9
Update docs to add compatibility table
rnorth Jul 3, 2016
0a44d07
Incorporate alpha Windows support into main v1.1 release candidate br…
rnorth Jul 3, 2016
c132aa4
Update docs to reflect merging of Windows support
rnorth Jul 3, 2016
a651031
Fix failure to skip Docker-compose related tests on CircleCI
rnorth Jul 3, 2016
4ebf461
Skip test execution for LocalServerWebDriverContainerTest when not us…
rnorth Jul 3, 2016
1b99dc4
Merge pull request #162 from locationlabs/use_getContainerIpAddress
rnorth Jul 3, 2016
9c57f9f
Add null guards for container networks (workaround for NPE on CircleC…
rnorth Jul 3, 2016
64d3451
Add custom Redis wait strategy as an example and to mitigate #160
rnorth Jul 3, 2016
0ea18cb
Add extra waits for Redis startup in docker compose tests
rnorth Jul 3, 2016
68f6488
Add Javadocs and unit tests for `withNetworkMode` option
rnorth Jul 4, 2016
36a1b6f
Set shade to relocate `jersey.repackaged` classes to address #161
rnorth Jul 5, 2016
57ecdf2
Update docker-compose container image to dduportal/docker-compose:1.7.1
rnorth Jul 5, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions annotations/com/google/common/base/annotations.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<root>
<item name='com.google.common.base.Preconditions void checkArgument(boolean, java.lang.Object)'>
<annotation name='org.jetbrains.annotations.Contract'>
<val val="&quot;false, _ -&gt; fail; true, _ -&gt; _&quot;"/>
</annotation>
</item>
</root>
7 changes: 7 additions & 0 deletions annotations/org/rnorth/ducttape/annotations.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<root>
<item name='org.rnorth.ducttape.Preconditions void check(java.lang.String, boolean)'>
<annotation name='org.jetbrains.annotations.Contract'>
<val val="&quot;_,true-&gt;_;_,false-&gt;fail&quot;"/>
</annotation>
</item>
</root>
44 changes: 36 additions & 8 deletions core/pom.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
Expand All @@ -17,8 +18,22 @@
<dependency>
<groupId>com.github.docker-java</groupId>
<artifactId>docker-java</artifactId>
<version>2.2.0</version>
<version>3.0.0</version>
<exclusions>
<!-- replace with junixsocket -->
<exclusion>
<groupId>de.gesellix</groupId>
<artifactId>unix-socket-factory</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.rnorth</groupId>
<artifactId>tcp-unix-socket-proxy</artifactId>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Until netty and/or docker-java have native support for unix domain sockets, use a slightly hacky but effective workaround of proxying over TCP. For Testcontainers' purposes, there's no perceptible performance impact.

<version>1.0.1</version>
</dependency>

<dependency>
<groupId>org.zeroturnaround</groupId>
<artifactId>zt-exec</artifactId>
Expand All @@ -37,9 +52,9 @@

<!-- Test dependencies -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>1.3.0</version>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.0</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -69,6 +84,13 @@

</dependencies>

<!-- Prevent netty version conflicts with redisson, used for testing -->
<dependencyManagement>
<dependencies>

</dependencies>
</dependencyManagement>

<build>
<plugins>
<plugin>
Expand All @@ -84,8 +106,10 @@
</executions>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer" />
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"/>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
<relocations>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still need to add netty relocation

<relocation>
Expand Down Expand Up @@ -120,6 +144,10 @@
<pattern>com.github.dockerjava</pattern>
<shadedPattern>org.testcontainers.shaded.com.github.dockerjava</shadedPattern>
</relocation>
<relocation>
<pattern>jersey.repackaged</pattern>
<shadedPattern>org.testcontainers.shaded.jersey.repackaged</shadedPattern>
</relocation>
</relocations>
<artifactSet>
<includes>
Expand All @@ -141,7 +169,7 @@
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>META-INF/services/com.fasterxml.jackson.core.*</exclude>
<exclude>META-INF/services/com.fasterxml.jackson.core.*</exclude>
<exclude>META-INF/services/com.github.dockerjava.api.command.*</exclude>
<exclude>META-INF/services/javax.ws.rs.ext.*</exclude>
<exclude>META-INF/services/org.glassfish.hk2.extension.*</exclude>
Expand Down
95 changes: 64 additions & 31 deletions core/src/main/java/org/testcontainers/DockerClientFactory.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
package org.testcontainers;

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.InternalServerErrorException;
import com.github.dockerjava.api.NotFoundException;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.exception.InternalServerErrorException;
import com.github.dockerjava.api.exception.NotFoundException;
import com.github.dockerjava.api.model.Frame;
import com.github.dockerjava.api.model.Image;
import com.github.dockerjava.core.DockerClientBuilder;
import com.github.dockerjava.core.DockerClientConfig;
import com.github.dockerjava.api.model.Info;
import com.github.dockerjava.api.model.Version;
import com.github.dockerjava.core.command.LogContainerResultCallback;
import com.github.dockerjava.core.command.PullImageResultCallback;
import com.github.dockerjava.core.command.WaitContainerResultCallback;
import lombok.Synchronized;
import org.slf4j.Logger;
import org.testcontainers.dockerclient.DockerClientConfigUtils;
import org.testcontainers.dockerclient.DockerConfigurationStrategy;
import org.testcontainers.dockerclient.DockerMachineConfigurationStrategy;
import org.testcontainers.dockerclient.EnvironmentAndSystemPropertyConfigurationStrategy;
import org.testcontainers.dockerclient.UnixSocketConfigurationStrategy;
import org.testcontainers.dockerclient.*;

import java.util.List;

Expand All @@ -34,13 +31,16 @@ public class DockerClientFactory {
private static final Logger LOGGER = getLogger(DockerClientFactory.class);

// Cached client configuration
private DockerClientConfig config;
private DockerClientProviderStrategy strategy;
private boolean preconditionsChecked = false;

private static final List<DockerConfigurationStrategy> CONFIGURATION_STRATEGIES =
asList(new EnvironmentAndSystemPropertyConfigurationStrategy(),
new DockerMachineConfigurationStrategy(),
new UnixSocketConfigurationStrategy());
private static final List<DockerClientProviderStrategy> CONFIGURATION_STRATEGIES =
asList(new EnvironmentAndSystemPropertyClientProviderStrategy(),
new ProxiedUnixSocketClientProviderStrategy(),
new UnixSocketClientProviderStrategy(),
new DockerMachineClientProviderStrategy());
private String activeApiVersion;
private String activeExecutionDriver;

/**
* Private constructor
Expand Down Expand Up @@ -77,15 +77,25 @@ public DockerClient client() {
*/
@Synchronized
public DockerClient client(boolean failFast) {
if (config == null) {
config = DockerConfigurationStrategy.getFirstValidConfig(CONFIGURATION_STRATEGIES);

if (strategy == null) {
strategy = DockerClientProviderStrategy.getFirstValidStrategy(CONFIGURATION_STRATEGIES);
}

DockerClient client = DockerClientBuilder.getInstance(config).build();
DockerClient client = strategy.getClient();

if (!preconditionsChecked) {
String version = client.versionCmd().exec().getVersion();
checkVersion(version);
Info dockerInfo = client.infoCmd().exec();
Version version = client.versionCmd().exec();
activeApiVersion = version.getApiVersion();
activeExecutionDriver = dockerInfo.getExecutionDriver();
LOGGER.info("Connected to docker: \n" +
" Server Version: " + dockerInfo.getServerVersion() + "\n" +
" API Version: " + activeApiVersion + "\n" +
" Operating System: " + dockerInfo.getOperatingSystem() + "\n" +
" Total Memory: " + dockerInfo.getMemTotal() / (1024 * 1024) + " MB");

checkVersion(version.getVersion());
checkDiskSpaceAndHandleExceptions(client);
preconditionsChecked = true;
}
Expand All @@ -98,19 +108,11 @@ public DockerClient client(boolean failFast) {
return client;
}

/**
* @param config docker client configuration to extract the host IP address from
* @return the IP address of the host running Docker
*/
private String dockerHostIpAddress(DockerClientConfig config) {
return DockerClientConfigUtils.getDockerHostIpAddress(config);
}

/**
* @return the IP address of the host running Docker
*/
public String dockerHostIpAddress() {
return dockerHostIpAddress(config);
return strategy.getDockerHostIpAddress();
}

private void checkVersion(String version) {
Expand Down Expand Up @@ -147,10 +149,13 @@ private void checkDiskSpace(DockerClient client) {

client.startContainerCmd(id).exec();

client.waitContainerCmd(id).exec();

LogContainerResultCallback callback = client.logContainerCmd(id).withStdOut().exec(new LogContainerCallback());
LogContainerResultCallback callback = client.logContainerCmd(id).withStdOut(true).exec(new LogContainerCallback());
try {

WaitContainerResultCallback waitCallback = new WaitContainerResultCallback();
client.waitContainerCmd(id).exec(waitCallback);
waitCallback.awaitStarted();

callback.awaitCompletion();
String logResults = callback.toString();

Expand Down Expand Up @@ -183,6 +188,34 @@ private void checkDiskSpace(DockerClient client) {
}
}

/**
* @return the docker API version of the daemon that we have connected to
*/
public String getActiveApiVersion() {
if (!preconditionsChecked) {
client(true);
}
return activeApiVersion;
}

/**
* @return the docker execution driver of the daemon that we have connected to
*/
public String getActiveExecutionDriver() {
if (!preconditionsChecked) {
client(true);
}
return activeExecutionDriver;
}

/**
* @param providerStrategyClass a class that extends {@link DockerMachineClientProviderStrategy}
* @return whether or not the currently active strategy is of the provided type
*/
public boolean isUsing(Class<? extends DockerClientProviderStrategy> providerStrategyClass) {
return providerStrategyClass.isAssignableFrom(this.strategy.getClass());
}

private static class NotEnoughDiskSpaceException extends RuntimeException {
NotEnoughDiskSpaceException(String message) {
super(message);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.testcontainers.containers;

import com.github.dockerjava.api.DockerException;
import com.github.dockerjava.api.exception.DockerException;
import com.github.dockerjava.api.model.Container;
import lombok.Data;
import lombok.EqualsAndHashCode;
Expand All @@ -26,9 +26,9 @@ public class AmbassadorContainer<SELF extends AmbassadorContainer<SELF>> extends
public AmbassadorContainer(LinkableContainer otherContainer, String serviceName, int servicePort) {
super("richnorth/ambassador:latest");

/**
* Use the unique 'identifierPrefix' (random compose project name) so that the ambassador can see
* the container it's supposed to be proxying.
/*
Use the unique 'identifierPrefix' (random compose project name) so that the ambassador can see
the container it's supposed to be proxying.
*/
this.otherContainerName = otherContainer.getContainerName();
this.serviceName = serviceName;
Expand Down
21 changes: 13 additions & 8 deletions core/src/main/java/org/testcontainers/containers/Container.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ public String getStderr() {
/**
* Add a link to another container.
*
* @param otherContainer
* @param alias
* @param otherContainer the other container object to link to
* @param alias the alias (for the other container) that this container should be able to use
*/
void addLink(LinkableContainer otherContainer, String alias);

Expand Down Expand Up @@ -171,12 +171,21 @@ public String getStderr() {

/**
* Add an extra host entry to be passed to the container
* @param hostname
* @param ipAddress
* @param hostname hostname to use for this hosts file entry
* @param ipAddress IP address to use for this hosts file entry
* @return this
*/
SELF withExtraHost(String hostname, String ipAddress);

/**
* Set the network mode for this container, similar to the <code>--net &lt;name&gt;</code>
* option on the docker CLI.
*
* @param networkMode network mode, e.g. including 'host', 'bridge', 'none' or the name of an existing named network.
* @return this
*/
SELF withNetworkMode(String networkMode);

/**
* Map a resource (file or directory) on the classpath to a path inside the container.
* This will only work if you are running your tests outside a Docker container.
Expand Down Expand Up @@ -311,8 +320,6 @@ ExecResult execInContainer(Charset outputCharset, String... command)

Map<String, LinkableContainer> getLinkedContainers();

Duration getMinimumRunningDuration();

DockerClient getDockerClient();

Info getDockerDaemonInfo();
Expand All @@ -339,8 +346,6 @@ ExecResult execInContainer(Charset outputCharset, String... command)

void setLinkedContainers(Map<String, LinkableContainer> linkedContainers);

void setMinimumRunningDuration(Duration minimumRunningDuration);

void setDockerClient(DockerClient dockerClient);

void setDockerDaemonInfo(Info dockerDaemonInfo);
Expand Down
Loading