GithubHelp home page GithubHelp logo

testcontainers / testcontainers-java Goto Github PK

View Code? Open in Web Editor NEW
7.8K 137.0 1.6K 11.94 MB

Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.

Home Page: https://testcontainers.org

License: MIT License

Java 98.72% HTML 0.01% Shell 0.15% Groovy 0.93% Dockerfile 0.04% Batchfile 0.04% FreeMarker 0.11% JavaScript 0.01%
java docker docker-compose junit test-automation jvm testing hacktoberfest

testcontainers-java's Introduction

Testcontainers

Maven Central

Open in GitHub Codespaces

Revved up by Develocity

Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.

Testcontainers logo

License

See LICENSE.

Copyright

Copyright (c) 2015 - 2021 Richard North and other authors.

MS SQL Server module is (c) 2017 - 2021 G DATA Software AG and other authors.

Hashicorp Vault module is (c) 2017 - 2021 Capital One Services, LLC and other authors.

See contributors for all contributors.

testcontainers-java's People

Contributors

aguibert avatar asafm avatar banadiga avatar barrycommins avatar bsideup avatar dadoonet avatar daschl avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar eddumelendez avatar findepi avatar github-actions[bot] avatar jetersen avatar kiview avatar leocross avatar mbaechler avatar meistermeier avatar michael-simons avatar outofcoffee avatar perlun avatar peter-evans avatar pioorg avatar pivovarit avatar qoomon avatar raynigon avatar rnorth avatar sullis avatar vcvitaly avatar yannickweber avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

testcontainers-java's Issues

Unix socket access to docker should not need any configuration

Currently, when one use testcontainers on linux, he needs to configure some env variables.
There are already two strategies to handle configuration diversity : env and docker-machine.
I suggest to add a UnixSocketConfigurationStrategy that try to access docker socket if no other strategy works.

Concerns around using public docker images

I know you raised some concerns over whether the docker container in the public registry can be used, but having looked at it further - if the dockerfile is in a public git repo - is this still an issue? @rnorth

Project self-tests intermittently exceed CircleCI memory limit

It seems something about the tests for this project are chewing up too much memory on CircleCI.

This causes an intermittent build failure, which is something that Just Should Not Happen.

It may require something as simple as lowering maven's heap size, or further investigation. I suspect CircleCI will be having problems if the build process uses up a lot of memory on top of the spawned containers (of which some will be fairly demanding).

CircleCI failure output excerpt:

   PID   RSS %CPU COMMAND
 15970 4318068 67.0 /usr/lib/jvm/jdk1.8.0/jre/bin/java -jar /home/ubuntu/testcontainers-java/modules/postgresql/target/surefire/surefirebooter261774409861515682.jar /home/ubuntu/testcontainers-java/modules/postgresql/target/surefire/surefire8554852648513290392tmp /home/ubuntu/testcontainers-java/modules/postgresql/target/surefire/surefire_2716773776951416696tmp
 12388 395452 10.7 /usr/lib/jvm/jdk1.8.0/bin/java -Xmx512m -classpath /home/ubuntu/.m2/apache-maven-3.2.5/boot/plexus-classworlds-2.5.2.jar -Dclassworlds.conf=/home/ubuntu/.m2/apache-maven-3.2.5/bin/m2.conf -Dmaven.home=/home/ubuntu/.m2/apache-maven-3.2.5 org.codehaus.plexus.classworlds.launcher.Launcher integration-test

Shaded Jersey, Jackson and other libs which expose services can cause conflicts with in-project non-shaded counterparts

Due to the fact that the original entries in META-INF/services are still registered to non-shaded names/keys e.g. javax.ws.rs.ext.MessageBodyWriter (even though their content is already shaded)
they might be found by auto-discovery/service provider features in corresponding libs and loaded instead of their proper (non-TestContainers) counterparts.

One symptom of such behaviour is the exception given below while integrating Dropwizard with TestContainers library for testing and at the same time using io.dropwizard.testing.junit.ResourceTestRule which uses both Jersey and Jackson:

org.glassfish.hk2.api.MultiException:
A MultiException has 2 exceptions.  They are:
1. java.lang.ClassCastException: org.testcontainers.shaded.com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider cannot be cast to javax.ws.rs.ext.MessageBodyReader
2. java.lang.IllegalStateException: Unable to perform operation: create on org.glassfish.jersey.message.internal.MessageBodyFactory

Caused by: java.lang.ClassCastException: org.testcontainers.shaded.com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider cannot be cast to javax.ws.rs.ext.MessageBodyReader

WARN  [2016-02-17 13:12:42,266] org.glassfish.jersey.internal.Errors: The following warnings have been detected: WARNING: Unknown HK2 failure detected:
MultiException stack 1 of 2
java.lang.ClassCastException: org.testcontainers.shaded.com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider cannot be cast to javax.ws.rs.ext.MessageBodyReader
        at org.glassfish.jersey.message.internal.MessageBodyFactory.addReaders(MessageBodyFactory.java:507)
        at org.glassfish.jersey.message.internal.MessageBodyFactory.<init>(MessageBodyFactory.java:226)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at org.glassfish.hk2.utilities.reflection.ReflectionHelper.makeMe(ReflectionHelper.java:1350)
        at org.jvnet.hk2.internal.ClazzCreator.createMe(ClazzCreator.java:271)
        at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:365)
        at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
        at org.jvnet.hk2.internal.SingletonContext$1.compute(SingletonContext.java:83)
        at org.jvnet.hk2.internal.SingletonContext$1.compute(SingletonContext.java:71)
        at org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture$1.call(Cache.java:97)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture.run(Cache.java:154)
        at org.glassfish.hk2.utilities.cache.Cache.compute(Cache.java:199)
        at org.jvnet.hk2.internal.SingletonContext.findOrCreate(SingletonContext.java:122)
        at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2072)
        at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:767)
        at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:706)
        at org.glassfish.jersey.server.model.ComponentModelValidator.<init>(ComponentModelValidator.java:97)
        at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:549)
        at org.glassfish.jersey.server.ApplicationHandler.access$500(ApplicationHandler.java:184)
        at org.glassfish.jersey.server.ApplicationHandler$3.call(ApplicationHandler.java:350)
        at org.glassfish.jersey.server.ApplicationHandler$3.call(ApplicationHandler.java:347)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
        at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:255)
        at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:347)
        at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:299)
        at org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory$InMemoryTestContainer.<init>(InMemoryTestContainerFactory.java:77)
        at org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory$InMemoryTestContainer.<init>(InMemoryTestContainerFactory.java:63)
        at org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory.create(InMemoryTestContainerFactory.java:111)
        at org.glassfish.jersey.test.JerseyTest.createTestContainer(JerseyTest.java:277)
        at org.glassfish.jersey.test.JerseyTest.setUp(JerseyTest.java:609)
        at io.dropwizard.testing.junit.ResourceTestRule$1.evaluate(ResourceTestRule.java:201)
        at org.junit.rules.RunRules.evaluate(RunRules.java:20)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:367)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:274)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
        at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:161)
        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)
        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
MultiException stack 2 of 2
java.lang.IllegalStateException: Unable to perform operation: create on org.glassfish.jersey.message.internal.MessageBodyFactory
        at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:392)
        at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
        at org.jvnet.hk2.internal.SingletonContext$1.compute(SingletonContext.java:83)
        at org.jvnet.hk2.internal.SingletonContext$1.compute(SingletonContext.java:71)
        at org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture$1.call(Cache.java:97)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture.run(Cache.java:154)
        at org.glassfish.hk2.utilities.cache.Cache.compute(Cache.java:199)
        at org.jvnet.hk2.internal.SingletonContext.findOrCreate(SingletonContext.java:122)
        at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2072)
        at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:767)
        at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:706)
        at org.glassfish.jersey.server.model.ComponentModelValidator.<init>(ComponentModelValidator.java:97)
        at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:549)
        at org.glassfish.jersey.server.ApplicationHandler.access$500(ApplicationHandler.java:184)
        at org.glassfish.jersey.server.ApplicationHandler$3.call(ApplicationHandler.java:350)
        at org.glassfish.jersey.server.ApplicationHandler$3.call(ApplicationHandler.java:347)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
        at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:255)
        at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:347)
        at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:299)
        at org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory$InMemoryTestContainer.<init>(InMemoryTestContainerFactory.java:77)
        at org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory$InMemoryTestContainer.<init>(InMemoryTestContainerFactory.java:63)
        at org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory.create(InMemoryTestContainerFactory.java:111)
        at org.glassfish.jersey.test.JerseyTest.createTestContainer(JerseyTest.java:277)
        at org.glassfish.jersey.test.JerseyTest.setUp(JerseyTest.java:609)
        at io.dropwizard.testing.junit.ResourceTestRule$1.evaluate(ResourceTestRule.java:201)
        at org.junit.rules.RunRules.evaluate(RunRules.java:20)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:367)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:274)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
        at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:161)
        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)
        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)

Due to the fact that apart from already shaded service keys also the non-shaded service keys are still there on the classpath from TestContainers and they (all) are pointing to shaded classes,
they are obviously not the ones which the original library from the project expects to find on the classpath - not from the same implementation but both from non-shaded (Dropwizard's) and
shaded (TestContainers') implementations.

There is a connection between this issue and the issue #35 and it's current solution in ver. 1.0.0 - just to give the context.

One solution would be to remove these non-shaded keys while building shaded TestContainers jar and leave only the shaded keys.
As those shaded keys are added manually (for their value/content only to be shaded during the plugin processing) it seems it's enough to filter out the original keys:

diff --git a/core/pom.xml b/core/pom.xml
index 22371f4..f8e4b71 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -129,6 +129,11 @@
                                 <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.github.dockerjava.api.command.*</exclude>
+                                <exclude>META-INF/services/javax.ws.rs.ext.*</exclude>
+                                <exclude>META-INF/services/org.glassfish.hk2.extension.*</exclude>
+                                <exclude>META-INF/services/org.jvnet.hk2.external.generator.*</exclude>
                             </excludes>
                         </filter>
                     </filters>

Docker-Machine installation on Windows can't be found

Due to the following check in DockerMachineClient:

public boolean isInstalled() {
        return executableExists("docker-machine");
}

docker installation on Windows can't be found. On Windows it's necessary to use "docker-machine.exe" instead of just "docker-machine".

For example, the following code:
Files.isExecutable(FileSystems.getDefault().getPath("C:\\Program Files\\Docker Toolbox\\docker-machine.exe"))
works but
Files.isExecutable(FileSystems.getDefault().getPath("C:\\Program Files\\Docker Toolbox\\docker-machine"))
doesn't.

Badly formed image results in hanging test

I was attempting to use a docker image and hadn't included a tag:

@Rule
public GenericContainer composeContainer = new GenericContainer("frodenas/couchdb");

This was resulting in the maven test phase hanging on pulling the image:

14:48:57.225 [main] INFO  org.testcontainers.DockerClientFactory - Disk utilization in Docker environment is 29%
14:48:57.444 [main] INFO  ๐Ÿณ [frodenas/couchdb] - Pulling docker image: frodenas/couchdb. Please be patient; this may take some time but only needs to be done once.

Look at docker event I could see testcontainers repeatedly pulling the image:

$  docker events
2016-02-18T14:48:56.573348524Z container create 49df7a848ebaf62f44247a3e0a4f16435a9362232ce541010c76ad1875a9da43 (image=alpine:3.2, name=goofy_chandrasekhar)
2016-02-18T14:48:56.638367999Z network connect 67ec38ca79fcfa1a0b71de276743ce78cd946ab1bc42acb95761cad029ff56fa (name=bridge, type=bridge, container=49df7a848ebaf62f44247a3e0a4f16435a9362232ce541010c76ad1875a9da43)
2016-02-18T14:48:56.638877689Z container start 49df7a848ebaf62f44247a3e0a4f16435a9362232ce541010c76ad1875a9da43 (image=alpine:3.2, name=goofy_chandrasekhar)
2016-02-18T14:48:56.870480008Z container die 49df7a848ebaf62f44247a3e0a4f16435a9362232ce541010c76ad1875a9da43 (image=alpine:3.2, name=goofy_chandrasekhar)
2016-02-18T14:48:57.062918192Z network disconnect 67ec38ca79fcfa1a0b71de276743ce78cd946ab1bc42acb95761cad029ff56fa (container=49df7a848ebaf62f44247a3e0a4f16435a9362232ce541010c76ad1875a9da43, name=bridge, type=bridge)
2016-02-18T14:48:57.304580317Z container destroy 49df7a848ebaf62f44247a3e0a4f16435a9362232ce541010c76ad1875a9da43 (image=alpine:3.2, name=goofy_chandrasekhar)
2016-02-18T14:49:01.183645303Z image pull frodenas/couchdb (name=frodenas/couchdb)
2016-02-18T14:49:04.499725803Z image pull frodenas/couchdb (name=frodenas/couchdb)
2016-02-18T14:49:07.707602446Z image pull frodenas/couchdb (name=frodenas/couchdb)
2016-02-18T14:49:11.205944772Z image pull frodenas/couchdb (name=frodenas/couchdb)
2016-02-18T14:49:14.405842514Z image pull frodenas/couchdb (name=frodenas/couchdb)
2016-02-18T14:49:17.673538540Z image pull frodenas/couchdb (name=frodenas/couchdb)
[..snipped..]

While I should have specified a tag (latest) testcontainers should handle this case better and warn the developer rather that repeatedly trying.

This is with version 1.0.0.

Working via docker.sock does not necessarily mean containers are running on localhost

In some build setups it may be the case that the build is triggered via Jenkins which itself runs in a docker container. With respect to testcontainers that means that a dockerized Jenkins runs unit tests which in turn start docker containers.

In order to be able to start a docker container from within a docker container, the currently proposed "solution" (it's merely a workaround) is to mount the file /var/run/docker.sock and the binary /usr/bin/docker into the Jenkins container.

This works fine with testcontainers. It detects a working docker.sock file and continues with starting containers. However if those containers do expose ports, testcontainers seems to wait for the port to become available. In the scenario described above it waits on localhost:port if docker communication via UNIX socket has been detected implying that if a socket is used, then the docker daemon must also run on localhost.

This implication is not true when doing docker in docker by the help of mounted socket files.
As a result, testcontainers times out waiting for the exposed port to become available.

Our current workaround for this is to not mount the socket and the binary but instead installing docker client into the container and passing the environment variables DOCKER_HOST, DOCKER_TLS_VERIFY and DOCKER_CERT_PATH to the Jenkins container.

Is it possible to implement some kind of switch that is able to influence the "wait for port to become available" behavior?

Support custom Docker images in the JDBC URL

Make it possible to specify a full docker image name in the JDBC URL and/or custom docker registries, and these might be necessary to allow teams to use their own privately managed images.

getHostIpAddress is confusingly named

Refs #54, getIpAddress and getHostIpAddress are confusingly named.

I think I will:

  • rename getHostIpAddress to getTestHostIpAddress as suggested by @kongslund
  • add getContainerIpAddress as an alias to the current getIpAddress to avoid breaking existing uses
  • deprecate getIpAddress with a view to eventually removing it

Add some DEBUG loggers for connection strategies

I spent some time figuring out why I got an SSLException when trying to make my test container to work.
It appears to be a simple library version conflict on bouncycaste, but the exception cause is not logger at all.
It should be possible to log the exception causes when log level is debug.

Docker client dependencies can cause conflicts with Jersey, Jackson and other libs

When attempting to integrate Testcontainers into a project that uses Dropwizard 0.8.1 (Jersey 2.17), I've been getting some bad dependency clashes despite our use of the shaded docker-client lib.

After some head-scratching and experimenting with various options, what eventually worked was

  • making a temporary version of testcontainers that depends on the non-shaded version of docker-client

  • use maven dependencyManagement to force the crossover Jersey dependencies into sync:

        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-client</artifactId>
            <version>2.17</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-common</artifactId>
            <version>2.17</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.connectors</groupId>
            <artifactId>jersey-apache-connector</artifactId>
            <version>2.17</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>2.17</version>
        </dependency>
    

I think it would be better to either not use the shaded version of the docker-client library, or make it optional (e.g. via a classifier).

Verify/improve Linux compatibility

So far development has taken place on OS X using boot2docker. While using docker should actually be easier on Linux, we've so far concentrated on OS X.

We should make sure the library works equally well in linux environments.

I suspect this is probably a prerequisite for #2, automated tests.

v0.9.6 release

This release will be using the new org name, so some preparation is required.

Default log level is set to DEBUG - should not be specified

Hi Richard

I noticed a lot of debug log when using your test containers and noticed that it is specified in the logback.xml file in the core module.
Can you not specify the level and instead leave that to the project using testcontainers?

Regards Henrik

Example of TC with Spring

@rnorth I guess what I am looking for is an example. The scenario is that a datasource @bean is injected into a test class

    public class TestClass {
        public static final String ID = "101";
        public static final String REF_ID = "101";

        @Inject
        private DataSource dataSource;
        private ExampleDao exampleDao;

        @Before
        public void before() throws Exception {
            exampleDao = new ExampleDaoImpl(dataSource);
        }

        @Test
        public void testRetrieveExample_withValidId() {
            assertThat(customerNumberDao.retrieveExampleFromUserId(ID), is(REF_ID));
        }
   }

Bean:

    @Bean
    public DataSource dataSource() {
        final DriverManagerDataSource ds = new DriverManagerDataSource();
        dataSource.setDriverClassName(ds.DRIVER);
        dataSource.setUrl(ds.URL);
        dataSource.setUsername(ds.USERNAME);
        dataSource.setPassword(ds.PASSWORD);
        return dataSource;
    }

Excuse the formatting/code, I've just whacked this together

Windows support

Windows isn't currently supported. I'd like to support this, but it will require a bit of an investment in dev tooling and CI, so it may not be especially soon.

Help would be gratefully received in this area, as long as we can get these dev and testing aspects right.
#84 and #62 are current known issues with Windows support.

Docker-java client is not thread safe

Hi!

First of all, thanks for this cool project :) Here, at ZeroTurnaround, we created something similar, but will definitely try yours as well :) Even more - you already use our library - zt-exec :)

What we discovered during our work - DockerClient is not thread safe. We heavily recommend to replace SingletonDockerClient with ThreadLocalDockerClient, or client-per-container.

See docker-java/docker-java#339 (comment)

Failing unit tests on Windows: Invalid Bind Mount Spec

(I know Windows support is not on the table right now, but thought I would note this exception here for others)

When running the unit tests on Windows (after patching for #62) I came across this problem. Looks like this is a relevant related issue: moby/moby#12751.

org.rnorth.ducttape.RetryCountExceededException: Retry limit hit with exception

at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:83)
at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:107)
at org.testcontainers.containers.GenericContainer.starting(GenericContainer.java:423)
at org.testcontainers.containers.FailureDetectingExternalResource$1.evaluate(FailureDetectingExternalResource.java:28)
at org.testcontainers.containers.FailureDetectingExternalResource$1.evaluate(FailureDetectingExternalResource.java:31)
at org.testcontainers.containers.FailureDetectingExternalResource$1.evaluate(FailureDetectingExternalResource.java:31)
at org.testcontainers.containers.FailureDetectingExternalResource$1.evaluate(FailureDetectingExternalResource.java:31)
at org.testcontainers.containers.FailureDetectingExternalResource$1.evaluate(FailureDetectingExternalResource.java:31)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: org.testcontainers.containers.ContainerLaunchException: Could not create/start container
at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:166)
at org.testcontainers.containers.GenericContainer.lambda$start$0(GenericContainer.java:110)
at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:76)
... 26 more
Caused by: com.github.dockerjava.api.InternalServerErrorException: Invalid bind mount spec "/C:/dev/testcontainers-java/core/target/test-classes/mappable-resource/test-resource.txt:/content.txt:ro": volumeinvalid: Invalid volume specification: '/C:/dev/testcontainers-java/core/target/test-classes/mappable-resource/test-resource.txt:/content.txt:ro'

at com.github.dockerjava.jaxrs.filter.ResponseStatusExceptionFilter.filter(ResponseStatusExceptionFilter.java:53)
at org.glassfish.jersey.client.ClientFilteringStages$ResponseFilterStage.apply(ClientFilteringStages.java:134)
at org.glassfish.jersey.client.ClientFilteringStages$ResponseFilterStage.apply(ClientFilteringStages.java:123)
at org.glassfish.jersey.process.internal.Stages.process(Stages.java:171)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:251)
at org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:683)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:424)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:679)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:435)
at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:338)
at com.github.dockerjava.jaxrs.CreateContainerCmdExec.execute(CreateContainerCmdExec.java:32)
at com.github.dockerjava.jaxrs.CreateContainerCmdExec.execute(CreateContainerCmdExec.java:14)
at com.github.dockerjava.jaxrs.AbstrSyncDockerCmdExec.exec(AbstrSyncDockerCmdExec.java:23)
at com.github.dockerjava.core.command.AbstrDockerCmd.exec(AbstrDockerCmd.java:33)
at com.github.dockerjava.core.command.CreateContainerCmdImpl.exec(CreateContainerCmdImpl.java:142)
at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:132)
... 28 more

checkDiskSpace fails for Ubuntu

First off, I found this project to be extremely useful and the source code very pleasant to read :)

This could be more of an issue with either with my configuration or with the Docker remote api than this library, but I ran into a problem with running it on Ubuntu 14.04.3, Docker version 1.9.1, build a34a1d5.

Caused by: java.lang.ArrayIndexOutOfBoundsException: 5
    at org.testcontainers.SingletonDockerClient.checkDiskSpace(SingletonDockerClient.java:172)

It appears that ubuntu formats its df command differently by default, if a path is too long it will insert a line break making it harder to parse. http://askubuntu.com/questions/55702/df-h-command-puts-line-breaks-in-output-how-do-i-fix

Here is what the Docker remote api returned for me if I'm running on ubuntu:

Filesystem           1K-blocks      Used Available Use% Mounted on
none                   7350760   2461408   4492912  35% /
tmpfs                   379500         0    379500   0% /dev
tmpfs                   379500         0    379500   0% /sys/fs/cgroup
/dev/disk/by-uuid/76cea61b-125c-4ea2-a2b8-06ffe70c1ba6
                       7350760   2461408   4492912  35% /etc/resolv.conf
/dev/disk/by-uuid/76cea61b-125c-4ea2-a2b8-06ffe70c1ba6
                       7350760   2461408   4492912  35% /etc/hostname
/dev/disk/by-uuid/76cea61b-125c-4ea2-a2b8-06ffe70c1ba6
                       7350760   2461408   4492912  35% /etc/hosts
shm                      65536         0     65536   0% /dev/shm
tmpfs                   379500         0    379500   0% /proc/kcore
tmpfs                   379500         0    379500   0% /proc/timer_stats

Assuming there isn't an easy configuration fix or something on my end, when parsing that String it could ignore lines that don't have the correct number of columns. In the meantime I just locally made a fix for it.

Thanks

Database container checkpoint/restore

Some projects have complex test data that is time consuming to reload. This means that either testing takes a very long time (test data has to be reloaded often), or tests aren't sufficiently independent (test data is not reloaded and therefore tests aren't independent). Testcontainers should provide a way to snapshot DB state and quickly reload that state. Docker native Checkpoint/Restore In Userspace looks like the best way to accomplish this.

Follow this PR:
moby/moby#13602

DockerComposeContainer with Selenium Grid example

Hi @rnorth, thanks for the good project!

However, I have several questions:

  • Do you have any samples of using DockerComposeContainer with Selenium Grid? I want to use official selenium images (hub, node-firefox-debug / node-chrome-debug) as separate containers to be able to scale them via docker-compose scale option. Not really sure if it's possible to pass scale image=N cmd args to already started containers.
  • Are you planning to add TestNG support? I noticed that you strictly dependent from JUnit Rules to be able to start / stop containers before / after test execution. What would be an effort to create a similar TestNG runner?

I have new versions for the jersey client in my project due to other dependency

This are my unsatisfied list of dependecies

     <!--<groupId>org.testcontainers</groupId>-->
     <!--<artifactId>testcontainers</artifactId>-->
     <!--<version>0.9.9</version>-->
     <!--<scope>test</scope>-->
     <!--<exclusions>-->
        <!--<exclusion>-->
           <!--<groupId>commons-io</groupId>-->
           <!--<artifactId>commons-io</artifactId>-->
        <!--</exclusion>-->
        <!--<exclusion>-->
           <!--<groupId>org.glassfish.jersey.core</groupId>-->
           <!--<artifactId>jersey-client</artifactId>-->
        <!--</exclusion>-->
        <!--<exclusion>-->
           <!--<groupId>org.slf4j</groupId>-->
           <!--<artifactId>slf4j-api</artifactId>-->
        <!--</exclusion>-->
        <!--<exclusion>-->
           <!--<groupId>org.bouncycastle</groupId>-->
           <!--<artifactId>bcpkix-jdk15on</artifactId>-->
        <!--</exclusion>-->
        <!--<exclusion>-->
           <!--<groupId>org.apache.httpcomponents</groupId>-->
           <!--<artifactId>httpclient</artifactId>-->
        <!--</exclusion>-->
        <!--<exclusion>-->
           <!--<groupId>org.glassfish.jersey.connectors</groupId>-->
           <!--<artifactId>jersey-apache-connector</artifactId>-->
        <!--</exclusion>-->
     <!--</exclusions>-->
  <!--</dependency>-->

After excluding this i have
15:31:15.126 WARN [o.t.DockerClientFactory] Encountered and ignored error while checking disk space javax.ws.rs.ProcessingException: com.fasterxml.jackson.databind.ObjectWriter.getJsonFactory()Lcom/fasterxml/jackson/core/JsonFactory; at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:264) ~[jersey-client-2.22.1.jar:na] at org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:700) ~[jersey-client-2.22.1.jar:na] at org.glassfish.jersey.internal.Errors.process(Errors.java:315) ~[jersey-common-2.22.1.jar:na] at org.glassfish.jersey.internal.Errors.process(Errors.java:297) ~[jersey-common-2.22.1.jar:na] at org.glassfish.jersey.internal.Errors.process(Errors.java:228) ~[jersey-common-2.22.1.jar:na] at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444) ~[jersey-common-2.22.1.jar:na] at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:696) ~[jersey-client-2.22.1.jar:na] at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:448) ~[jersey-client-2.22.1.jar:na] at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:349) ~[jersey-client-2.22.1.jar:na] at com.github.dockerjava.jaxrs.CreateContainerCmdExec.execute(CreateContainerCmdExec.java:32) ~[docker-java-2.1.1.jar:na] at com.github.dockerjava.jaxrs.CreateContainerCmdExec.execute(CreateContainerCmdExec.java:14) ~[docker-java-2.1.1.jar:na] at com.github.dockerjava.jaxrs.AbstrSyncDockerCmdExec.exec(AbstrSyncDockerCmdExec.java:24) ~[docker-java-2.1.1.jar:na] at com.github.dockerjava.core.command.AbstrDockerCmd.exec(AbstrDockerCmd.java:33) ~[docker-java-2.1.1.jar:na] at com.github.dockerjava.core.command.CreateContainerCmdImpl.exec(CreateContainerCmdImpl.java:143) ~[docker-java-2.1.1.jar:na] at org.testcontainers.DockerClientFactory.checkDiskSpace(DockerClientFactory.java:193) [testcontainers-0.9.9.jar:na] at org.testcontainers.DockerClientFactory.checkDiskSpaceAndHandleExceptions(DockerClientFactory.java:173) [testcontainers-0.9.9.jar:na] at org.testcontainers.DockerClientFactory.<init>(DockerClientFactory.java:47) [testcontainers-0.9.9.jar:na] at org.testcontainers.DockerClientFactory.instance(DockerClientFactory.java:60) [testcontainers-0.9.9.jar:na] at org.testcontainers.containers.GenericContainer.<init>(GenericContainer.java:72) [testcontainers-0.9.9.jar:na] at com.videoplaza.forecast.common.DockerSteps.aDockerComposeContainerConfiguration(DockerSteps.java:22) [test-classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_40] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_40] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_40] at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_40] at cucumber.runtime.Utils$1.call(Utils.java:37) [cucumber-core-1.2.4.jar:na] at cucumber.runtime.Timeout.timeout(Timeout.java:13) [cucumber-core-1.2.4.jar:na] at cucumber.runtime.Utils.invoke(Utils.java:31) [cucumber-core-1.2.4.jar:na] at cucumber.runtime.java.JavaStepDefinition.execute(JavaStepDefinition.java:38) [cucumber-java-1.2.4.jar:na] at cucumber.runtime.StepDefinitionMatch.runStep(StepDefinitionMatch.java:37) [cucumber-core-1.2.4.jar:na] at cucumber.runtime.Runtime.runStep(Runtime.java:299) [cucumber-core-1.2.4.jar:na] at cucumber.runtime.model.StepContainer.runStep(StepContainer.java:44) [cucumber-core-1.2.4.jar:na] at cucumber.runtime.model.StepContainer.runSteps(StepContainer.java:39) [cucumber-core-1.2.4.jar:na] at cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:44) [cucumber-core-1.2.4.jar:na] at cucumber.runtime.junit.ExecutionUnitRunner.run(ExecutionUnitRunner.java:91) [cucumber-junit-1.2.4.jar:na] at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:63) [cucumber-junit-1.2.4.jar:na] at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:18) [cucumber-junit-1.2.4.jar:na] at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) [junit-4.12.jar:4.12] at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) [junit-4.12.jar:4.12] at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) [junit-4.12.jar:4.12] at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) [junit-4.12.jar:4.12] at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) [junit-4.12.jar:4.12] at org.junit.runners.ParentRunner.run(ParentRunner.java:363) [junit-4.12.jar:4.12] at cucumber.runtime.junit.FeatureRunner.run(FeatureRunner.java:70) [cucumber-junit-1.2.4.jar:na] at cucumber.api.junit.Cucumber.runChild(Cucumber.java:97) [rmtest-cucumber-2.0.7.jar:na] at cucumber.api.junit.Cucumber.runChild(Cucumber.java:42) [rmtest-cucumber-2.0.7.jar:na] at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) [junit-4.12.jar:4.12] at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) [junit-4.12.jar:4.12] at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) [junit-4.12.jar:4.12] at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) [junit-4.12.jar:4.12] at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) [junit-4.12.jar:4.12] at org.junit.runners.ParentRunner.run(ParentRunner.java:363) [junit-4.12.jar:4.12] at cucumber.api.junit.Cucumber.run(Cucumber.java:102) [rmtest-cucumber-2.0.7.jar:na] at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:283) [surefire-junit4-2.18.1.jar:2.18.1] at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:173) [surefire-junit4-2.18.1.jar:2.18.1] at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153) [surefire-junit4-2.18.1.jar:2.18.1] at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:128) [surefire-junit4-2.18.1.jar:2.18.1] at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203) [surefire-booter-2.18.1.jar:2.18.1] at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155) [surefire-booter-2.18.1.jar:2.18.1] at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103) [surefire-booter-2.18.1.jar:2.18.1] Caused by: java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.ObjectWriter.getJsonFactory()Lcom/fasterxml/jackson/core/JsonFactory; at com.fasterxml.jackson.jaxrs.json.annotation.EndpointConfig.initWriter(EndpointConfig.java:159) ~[jackson-jaxrs-json-provider-2.1.2.jar:2.1.2] at com.fasterxml.jackson.jaxrs.json.annotation.EndpointConfig.forWriting(EndpointConfig.java:63) ~[jackson-jaxrs-json-provider-2.1.2.jar:2.1.2] at com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider.writeTo(JacksonJsonProvider.java:531) ~[jackson-jaxrs-json-provider-2.1.2.jar:2.1.2] at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:265) ~[jersey-common-2.22.1.jar:na] at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:250) ~[jersey-common-2.22.1.jar:na] at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162) ~[jersey-common-2.22.1.jar:na] at com.github.dockerjava.jaxrs.filter.LoggingFilter.aroundWriteTo(LoggingFilter.java:301) ~[docker-java-2.1.1.jar:na] at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162) ~[jersey-common-2.22.1.jar:na] at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1130) ~[jersey-common-2.22.1.jar:na] at org.glassfish.jersey.client.ClientRequest.writeEntity(ClientRequest.java:502) ~[jersey-client-2.22.1.jar:na] at com.github.dockerjava.jaxrs.connector.ApacheConnector$2.writeTo(ApacheConnector.java:578) ~[docker-java-2.1.1.jar:na] at org.apache.http.impl.execchain.RequestEntityProxy.writeTo(RequestEntityProxy.java:123) ~[httpclient-4.5.1.jar:4.5.1] at org.apache.http.impl.DefaultBHttpClientConnection.sendRequestEntity(DefaultBHttpClientConnection.java:158) ~[httpcore-4.4.3.jar:4.4.3] at org.apache.http.impl.conn.CPoolProxy.sendRequestEntity(CPoolProxy.java:162) ~[httpclient-4.5.1.jar:4.5.1] at org.apache.http.protocol.HttpRequestExecutor.doSendRequest(HttpRequestExecutor.java:237) ~[httpcore-4.4.3.jar:4.4.3] at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:122) ~[httpcore-4.4.3.jar:4.4.3] at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271) ~[httpclient-4.5.1.jar:4.5.1] at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184) ~[httpclient-4.5.1.jar:4.5.1] at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88) ~[httpclient-4.5.1.jar:4.5.1] at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) ~[httpclient-4.5.1.jar:4.5.1] at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) ~[httpclient-4.5.1.jar:4.5.1] at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:71) ~[httpclient-4.5.1.jar:4.5.1] at com.github.dockerjava.jaxrs.connector.ApacheConnector.apply(ApacheConnector.java:443) ~[docker-java-2.1.1.jar:na] at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:255) ~[jersey-client-2.22.1.jar:na] ... 58 common frames omitted

Confusing error messages when Docker machine initialization fails

When attempting to use testcontainers in OS X, I get the following exception. Note the cause right at the bottom, which has the message "Could not find a suitable docker instance - is DOCKER_HOST defined and pointing to a running Docker daemon?":

java.lang.IllegalStateException: Failed to prepare Docker client
    at org.testcontainers.DockerClientFactory.<init>(DockerClientFactory.java:49)
    at org.testcontainers.DockerClientFactory.instance(DockerClientFactory.java:60)
    at org.testcontainers.containers.GenericContainer.<init>(GenericContainer.java:72)
    at org.testcontainers.containers.JdbcDatabaseContainer.<init>(JdbcDatabaseContainer.java:27)
    at org.testcontainers.containers.PostgreSQLContainer.<init>(PostgreSQLContainer.java:17)
    at org.testcontainers.containers.PostgreSQLContainerProvider.newInstance(PostgreSQLContainerProvider.java:14)
    at org.testcontainers.jdbc.ContainerDatabaseDriver.connect(ContainerDatabaseDriver.java:111)
    at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:161)
    at com.progressfin.dataplatform.DataPlatformETLTest.runInitializationScripts(DataPlatformETLTest.java:121)
    at com.progressfin.dataplatform.DataPlatformETLTest.<init>(DataPlatformETLTest.java:79)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
    at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:29)
    at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:21)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:26)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:88)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:56)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:64)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:50)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
    at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
    at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:106)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:360)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
    at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.IllegalStateException: Could not find a suitable docker instance - is DOCKER_HOST defined and pointing to a running Docker daemon?
    at org.testcontainers.DockerClientFactory.determineConfiguration(DockerClientFactory.java:145)
    at org.testcontainers.DockerClientFactory.client(DockerClientFactory.java:72)
    at org.testcontainers.DockerClientFactory.<init>(DockerClientFactory.java:44)
    ... 45 more

The problem is that this exception's descriptive message has, in my case, nothing to do with the actual cause of the failure. The logs before the point this exception was thrown show this:

[Test worker] INFO org.testcontainers.DockerClientFactory - Checking environment for docker settings
[Test worker] INFO org.apache.http.impl.execchain.RetryExec - I/O exception (org.apache.http.conn.UnsupportedSchemeException) caught when processing request to {s}->https://localhost:2376: https protocol is not supported
[Test worker] INFO org.apache.http.impl.execchain.RetryExec - Retrying request to {s}->https://localhost:2376
[Test worker] INFO org.apache.http.impl.execchain.RetryExec - I/O exception (org.apache.http.conn.UnsupportedSchemeException) caught when processing request to {s}->https://localhost:2376: https protocol is not supported
[Test worker] INFO org.apache.http.impl.execchain.RetryExec - Retrying request to {s}->https://localhost:2376
[Test worker] INFO org.apache.http.impl.execchain.RetryExec - I/O exception (org.apache.http.conn.UnsupportedSchemeException) caught when processing request to {s}->https://localhost:2376: https protocol is not supported
[Test worker] INFO org.apache.http.impl.execchain.RetryExec - Retrying request to {s}->https://localhost:2376
[Test worker] INFO org.testcontainers.DockerClientFactory - Could not initialize docker settings using environment variables: org.apache.http.conn.UnsupportedSchemeException: https protocol is not supported
[Test worker] INFO org.testcontainers.DockerClientFactory - Checking for presence of docker-machine
[Test worker] INFO org.testcontainers.DockerClientFactory - Could not initialize docker settings using docker machine: docker-machine must be installed for use on OS X

That last message is apparently the real cause of the failure, but it's being reported as an info-level log message, one which several of my unit test reporting tools don't even report on.

getMappedPort/getJdbcUrl should fail fast when requested ports have not been mapped

I just tried to use the PostgreSQLContainer from within an existing unit test, as a class rule, but when I try this:

@ClassRule
public static PostgreSQLContainer postgres = new PostgreSQLContainer();

private DataSource makeDataSource() throws SQLException {
    String url = postgres.getJdbcUrl();
    log.info("JDBC URL: {}", url);
    return DataSources.unpooledDataSource(url, postgres.getUsername(), postgres.getPassword());
}

...the log message prints the following out:

JDBC URL: jdbc:postgresql://192.168.99.100:null/test

...which causes the Postgres JDBC driver to reject the URL with a "java.sql.SQLException: No suitable driver" exception.

If I edit the code above to hardcode the following URL by hand:

String url = "jdbc:postgresql://192.168.99.100:5432/test"; //postgres.getJdbcUrl();

...I get the following error instead:

org.postgresql.util.PSQLException: Connection to 192.168.99.100:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:252)
    at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:66)
    ...

...which goes to show that the null in the URL is the cause of the failure.

Versions:

  1. testcontainers-java: 1.0.0
  2. docker-machine: 0.5.4, build 6643d0e
  3. docker: 1.9.1, API: 1.21, go1.4.3, Git commit a34a1d5
  4. OS X Yosemite 10.10.4

Using unix socket to access docker daemon

I try to make GenericContainer launch a container using unix:///var/run/docker.sock as DOCKER_HOST.
I looks like it's the way to go based on https://github.com/docker-java/docker-java documentation, but it fails with :

org.testcontainers.shaded.javax.ws.rs.ProcessingException: org.newsclub.net.unix.AFUNIXSocketException: No such file or directory (socket: /home/matthieu/code/james-gitsvn/server/protocols/jmap-integration-testing/:80)
    at org.testcontainers.shaded.com.github.dockerjava.jaxrs.connector.ApacheConnector.apply(ApacheConnector.java:490)
    at org.testcontainers.shaded.org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:246)
    at org.testcontainers.shaded.org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:683)
    at org.testcontainers.shaded.org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.testcontainers.shaded.org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.testcontainers.shaded.org.glassfish.jersey.internal.Errors.process(Errors.java:228)
    at org.testcontainers.shaded.org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:424)
    at org.testcontainers.shaded.org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:679)
    at org.testcontainers.shaded.org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:408)
    at org.testcontainers.shaded.org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:308)
    at org.testcontainers.shaded.com.github.dockerjava.jaxrs.VersionCmdExec.execute(VersionCmdExec.java:25)
    at org.testcontainers.shaded.com.github.dockerjava.jaxrs.VersionCmdExec.execute(VersionCmdExec.java:12)
    at org.testcontainers.shaded.com.github.dockerjava.jaxrs.AbstrSyncDockerCmdExec.exec(AbstrSyncDockerCmdExec.java:24)
    at org.testcontainers.shaded.com.github.dockerjava.core.command.AbstrDockerCmd.exec(AbstrDockerCmd.java:33)
    at org.testcontainers.DockerClientFactory.client(DockerClientFactory.java:75)
    at org.testcontainers.containers.GenericContainer.<init>(GenericContainer.java:71)
    at org.apache.james.jmap.ContainerTest.<init>(ContainerTest.java:36)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:195)
    at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:244)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:241)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.newsclub.net.unix.AFUNIXSocketException: No such file or directory (socket: /home/matthieu/code/james-gitsvn/server/protocols/jmap-integration-testing/:80)
    at org.newsclub.net.unix.NativeUnixSocket.connect(Native Method)
    at org.newsclub.net.unix.AFUNIXSocketImpl.connect(AFUNIXSocketImpl.java:134)
    at org.newsclub.net.unix.AFUNIXSocket.connect(AFUNIXSocket.java:97)
    at org.testcontainers.shaded.com.github.dockerjava.jaxrs.ApacheUnixSocket.connect(ApacheUnixSocket.java:64)
    at org.testcontainers.shaded.com.github.dockerjava.jaxrs.UnixConnectionSocketFactory.connectSocket(UnixConnectionSocketFactory.java:73)
    at org.testcontainers.shaded.org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:118)
    at org.testcontainers.shaded.org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:314)
    at org.testcontainers.shaded.org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:357)
    at org.testcontainers.shaded.org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:218)
    at org.testcontainers.shaded.org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:194)
    at org.testcontainers.shaded.org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:85)
    at org.testcontainers.shaded.org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
    at org.testcontainers.shaded.org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:186)
    at org.testcontainers.shaded.org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)
    at org.testcontainers.shaded.com.github.dockerjava.jaxrs.connector.ApacheConnector.apply(ApacheConnector.java:443)
    ... 38 more

Is there something I don't understand ?

Proposal: Containerised DB for production

In README.md there are two usage scenarios described, one of which is:

Containerized database using a specially modified JDBC URL: after making a very simple modification to your system's JDBC URL string, TestContainers will provide a disposable stand-in database that can be used without requiring modification to your application code.

Imagine using a similar mechanism to spin up a persistent DB instance, or for that matter a Redis container, with the intention that it serves as a fast in memory cache. Both of these examples could be production use cases.

Taking this even further, with the changes coming to Docker Networking with libnetwork in 1.8 and beyond, these wouldn't even have to be on the same server, as their lifecycle could be orchestrated on a separate node via Swarm/Kubernetes/Mesos etc.

In this way an application could theoretically instantiate its own dependencies; like an inside-out Docker Compose.

Thoughts?

Organisation? Roadmap?

I've started working on a version of this for .NET. Would be good to start to put together documentation around what TC delivers right now and then future work as well.

Time to turn it into a github organisation? @rnorth

Allow for port bindings to be setup between container and host

Some applications such as Couchbase have reserved ports which must be exposed with the same port number on the host. As such, the current mapped port settings will not help us create these containers and be sure that the same reserved ports are exposed.

If the testcontainers library could add a method such as withPortBinding(exposedPort, hostPort) that allowed the setup of these port bindings then I think it would fix this issue.

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.