Skip to content

Commit

Permalink
Update ResourceReaper to reap networks earlier
Browse files Browse the repository at this point in the history
For docker-compose instances with custom networks, these need
to be reaped after each test as they could potentially define
overlapping subnets.
  • Loading branch information
valdisrigdon committed Aug 22, 2016
1 parent 45fa877 commit 7131b8d
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

import static org.testcontainers.containers.BindMode.READ_ONLY;
import static org.testcontainers.containers.BindMode.READ_WRITE;
import static com.google.common.collect.ComparisonChain.start;

/**
* Container which launches Docker Compose, for the purposes of launching a defined set of containers.
Expand Down Expand Up @@ -130,6 +131,12 @@ private void registerContainersForShutdown() {

// Ensure that the default network for this compose environment, if any, is also cleaned up
ResourceReaper.instance().registerNetworkForCleanup(identifier + "_default");
// Compose can define their own networks as well; ensure these are cleaned up
dockerClient.listNetworksCmd().exec().forEach(network -> {
if (network.getName().contains(identifier)) {
ResourceReaper.instance().registerNetworkForCleanup(network.getName());
}
});

// remember the IDs to allow containers to be killed as soon as we reach stop()
spawnedContainerIds = containers.stream()
Expand Down Expand Up @@ -185,6 +192,9 @@ public void finished(Description description) {
// shut down all the ambassador containers
ambassadorContainers.forEach((String address, AmbassadorContainer container) -> container.stop());

// remove the networks before removing the containers
ResourceReaper.instance().removeNetworks(identifier);

// kill the spawned service containers
spawnedContainerIds.forEach(id -> ResourceReaper.instance().stopAndRemoveContainer(id));
spawnedContainerIds.clear();
Expand Down Expand Up @@ -305,4 +315,4 @@ public void start() {
}
logger().info("Docker compose has finished running");
}
}
}
28 changes: 19 additions & 9 deletions core/src/main/java/org/testcontainers/utility/ResourceReaper.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
package org.testcontainers.utility;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.DockerClientFactory;

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.InspectContainerResponse;
import com.github.dockerjava.api.exception.DockerException;
import com.github.dockerjava.api.exception.InternalServerErrorException;
import com.github.dockerjava.api.exception.NotFoundException;
import com.github.dockerjava.api.model.Network;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.DockerClientFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
* Component that responsible for container removal and automatic cleanup of dead containers at JVM shutdown.
Expand Down Expand Up @@ -121,6 +122,14 @@ public void registerNetworkForCleanup(String networkName) {
registeredNetworks.add(networkName);
}

/**
* Removes any networks that contain the identifier.
* @param identifier
*/
public void removeNetworks(String identifier) {
removeNetwork(identifier);
}

private void removeNetwork(String networkName) {
List<Network> networks;
try {
Expand All @@ -133,10 +142,11 @@ private void removeNetwork(String networkName) {
for (Network network : networks) {
try {
dockerClient.removeNetworkCmd(network.getId()).exec();
registeredNetworks.remove(network.getId());
LOGGER.debug("Removed network: {}", networkName);
} catch (DockerException e) {
LOGGER.trace("Error encountered removing network (name: {}) - it may not have been removed", network.getName());
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
package org.testcontainers.junit;

import static org.hamcrest.CoreMatchers.is;
import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals;
import static org.rnorth.visibleassertions.VisibleAssertions.assertThat;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import org.jetbrains.annotations.NotNull;
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
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.concurrent.Callable;
import java.util.concurrent.TimeUnit;

import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals;
import com.github.dockerjava.api.model.Network;
import redis.clients.jedis.Jedis;

/**
* Created by rnorth on 21/05/2016.
Expand All @@ -23,6 +33,8 @@ public abstract class BaseDockerComposeTest {

protected abstract DockerComposeContainer getEnvironment();

private List<String> existingNetworks = new ArrayList<>();

@BeforeClass
public static void checkVersion() {
Assume.assumeTrue(TestEnvironment.dockerApiAtLeast("1.22"));
Expand Down Expand Up @@ -59,6 +71,23 @@ public void secondTest() {
// 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 () -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.testcontainers.junit;

import java.io.File;

import org.junit.Rule;
import org.testcontainers.containers.DockerComposeContainer;

public class DockerComposeV2WithNetworkTest extends BaseDockerComposeTest {

@Rule
public DockerComposeContainer environment = new DockerComposeContainer(new File("src/test/resources/v2-compose-test-with-network.yml"))
.withExposedService("redis_1", REDIS_PORT);

@Override
protected DockerComposeContainer getEnvironment() {
return environment;
}



}
9 changes: 9 additions & 0 deletions core/src/test/resources/v2-compose-test-with-network.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
version: '2'
services:
redis:
image: redis
networks:
- redis-net

networks:
redis-net:

0 comments on commit 7131b8d

Please sign in to comment.