package org.testcontainers.junit; import com.github.dockerjava.api.model.Network; import org.jetbrains.annotations.NotNull; import org.junit.*; import org.rnorth.ducttape.unreliables.Unreliables; import org.testcontainers.DockerClientFactory; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.utility.TestEnvironment; import redis.clients.jedis.Jedis; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import static org.hamcrest.CoreMatchers.is; import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; import static org.rnorth.visibleassertions.VisibleAssertions.assertThat; /** * Created by rnorth on 21/05/2016. */ public abstract class BaseDockerComposeTest { protected static final int REDIS_PORT = 6379; protected abstract DockerComposeContainer getEnvironment(); private List<String> existingNetworks = new ArrayList<>(); @BeforeClass public static void checkVersion() { Assume.assumeTrue(TestEnvironment.dockerApiAtLeast("1.22")); } @Test public void simpleTest() { Jedis jedis = new Jedis(getEnvironment().getServiceHost("redis_1", REDIS_PORT), getEnvironment().getServicePort("redis_1", REDIS_PORT)); // TODO: remove following resolution of #160 Unreliables.retryUntilSuccess(10, TimeUnit.SECONDS, getLivenessCheck(jedis)); jedis.incr("test"); jedis.incr("test"); jedis.incr("test"); assertEquals("A redis instance defined in compose can be used in isolation", "3", jedis.get("test")); } @Test public void secondTest() { // used in manual checking for cleanup in between tests Jedis jedis = new Jedis(getEnvironment().getServiceHost("redis_1", REDIS_PORT), getEnvironment().getServicePort("redis_1", REDIS_PORT)); // TODO: remove following resolution of #160 Unreliables.retryUntilSuccess(10, TimeUnit.SECONDS, getLivenessCheck(jedis)); jedis.incr("test"); jedis.incr("test"); jedis.incr("test"); assertEquals("Tests use fresh container instances", "3", jedis.get("test")); // if these end up using the same container one of the test methods will fail. // However, @Rule creates a separate DockerComposeContainer instance per test, so this just shouldn't happen } @Before public void captureNetworks() { existingNetworks.addAll(findAllNetworks()); } @After public void verifyNoNetworks() { assertThat("The networks", findAllNetworks(), is(existingNetworks)); } private List<String> findAllNetworks() { return DockerClientFactory.instance().client().listNetworksCmd().exec().stream() .map(Network::getName) .sorted() .collect(Collectors.toList()); } @NotNull private Callable<Boolean> getLivenessCheck(Jedis jedis) { return () -> { jedis.connect(); jedis.ping(); return true; }; } }