Mac OS X Note: To execute tests on Mac OS X please read about Docker on Mac OS X first.
End-to-end testing requires a lot of non-trivial test fixtures that you want Jenkins to interact with, such as SSH daemon, JIRA server, LDAP server, etc.
To allow us to define such fixtures in a portable and reusable manner, this test harness comes with
a mechanism and convention to define/use fixtures inside Docker. They are
defined in ./fixtures/*
JUnit Tests that require docker fixtures are marked with @WithDocker
annotation.
Cucumber tests are likewise annotated with @native(docker)
annotation.
If docker is not installed when you run tests, these tests are automatically skipped.
##Docker injections
To control docker 2 injections are available.
Docker = "docker"; // Name of the docker command
dockerPortOffset = 40000; // Offset for binding the docker ports to an host ip address
Compare the dockerinject.groovy for a more advanced Docker injection.
Every fixture has a subtype of DockerContainer
defined for it (see
existing examples)
Pick the fixture type you want to use, then insert DockerContainerHolder
for it:
@Inject
DockerContainerHolder<Tomcat7Container> tomcat7;
@Test
public void myTomcat7Test() {
Tomcat7Container c = tomcat7.get();
// interact with 'c' during test
}
DockerContainerHolder
starts a container, and it'll automatically clean-up the container at the end of the test.
The public function ipBound(n) and port(n) allow easily to find out to which host ip address and port a docker container ip address is bound to.
DockerSteps
defines steps that get the fixtures running, such as this:
Given a docker fixture "tomcat7"
In Cucumber we refer to docker fixtures by their IDs, which is specified via @DockerFixture
on the fixture type.
The containers are automatically terminated and cleaned up at the end of test.
Each fixture is defined in terms of a DockerContainer
subtype with @DockerFixture
annotation. This type
exposes various methods needed to interact with the running fixture.
The @DockerFixture
bindIp allows you to bind the accessible ports of the docker container to a local ip address.
A fixture also needs to define Dockerfile
in the resources directory. If a fixture class is
org/acme/FooContainer.java
, then the docker file must be located at org/acme/FooContainer/Dockerfile
.
In case of inner classes, dollar sign ( $ ) is replaced with a slash ( / ).
You can also set custom location of Dockerfile
by using dockerfileFolder
attribute from@DockerFixture
annotation.
A simple example might be:
@DockerFixture(id="test", ports="8080", dockerfileFolder="org/acme/fixture/test")
public class TestContainer extends DockerContainer {
//...
}
In this case the docker file must be located at classpath and in org/ame/fixture/test
instead of the default location.
Depending on the CI infrastructure setup one may need to run the ATH itself in a docker container with access to the host docker service, following a strategy similar to the one described in this article.
When this is needed, the docker fixtures should not be accessed through mapped ports on the docker host, but directly through their container IP and port since they are "sibling" containers to the ATH.
To enable this, set the environment variable SHARED_DOCKER_SERVICE=true
, and then the functions ipBound(n) and port(n)
will just return the container's IP and port where the fixture can be accessed.
TO-DO: Instead of depending on setting this environment variable, in the future we could try to somehow automatically detect the situation.