Reputation:
Using DockerComposeContainer from test-containers api in SpringBootApp I have the following issue. The DockerComposeContainer object from test-containers must be annotated with @ClassRule to be started and closed automatically thats give the need the field to be static because of the @ClassRule annotation. If I execute single test it finish successfully but when I execute more than 1 consecutive test's I get error on the second test
Could not start container
org.testcontainers.containers.ContainerLaunchException: Aborting attempt to link to container cn6j5atqrtav_janusgraph_1 as it is not running
at org.testcontainers.containers.GenericContainer..
it come's becouse I use static field for DockerComposeContainer. If i use just @Rule then I cannot pass DockerComposeContainer instance to the @TestConfiguration inner static class's bean that use this field. Why I should use the inner static class, because I override some bean's from the SpringBoot Application's Context. Here is some little example:
@RunWith(SpringRunner.class)
public class IntegrationTestBase {
private static final String DOCKER_COMPOSE_FILE = "src/test/resources/integration/docker-compose-cql-es.yml";
@ClassRule
public static DockerComposeContainer environment =
new DockerComposeContainer(new File(DOCKER_COMPOSE_FILE))
.withExposedService("janusgraph", 8182, Wait.forListeningPort()
.withStartupTimeout(Duration.ofMinutes(1)));
@TestConfiguration
public static class ContextConfig {
@Bean(Constants.GRAPH_TRAVERSAL_SOURCE)
@Scope("prototype")
public GraphTraversalSource graphTraversalSource() {
org.apache.commons.configuration.Configuration remoteConfig = new BaseConfiguration();
remoteConfig.addProperty("gremlin.remote.remoteConnectionClass", "org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteConnection");
remoteConfig.addProperty("gremlin.remote.driver.sourceName", "g");
remoteConfig.addProperty("gremlin.remote.driver.clusterFile", "remote-objects.yaml");
try {
org.apache.commons.configuration.Configuration clusterConfig = new PropertiesConfiguration();
clusterConfig.addProperty("hosts", new String[]{environment.getServiceHost("janusgraph", 8182)}); // I want to use environemnt here without beign static ?
clusterConfig.addProperty("port", environment.getServicePort("janusgraph", 8182));
clusterConfig.addProperty("serializer.className", GryoMessageSerializerV3d0.class.getName());
clusterConfig.addProperty("serializer.config.ioRegistries", JanusGraphIoRegistry.class.getName());
clusterConfig.addProperty("serializer.config.ioRegistries", JanusGraphIoRegistry.class.getName());
final Cluster cluster = Cluster.open(clusterConfig);
Constructor<DriverRemoteConnection> constructor = DriverRemoteConnection.class.getDeclaredConstructor(Cluster.class, boolean.class, String.class);
constructor.setAccessible(true);
DriverRemoteConnection connection = constructor.newInstance(cluster, true, "g");
return JanusGraphFactory.open("inmemory").traversal().withRemote(connection);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
One thing I have tried is to remove the static from DockerComposeContainer and to use @Rule instead of @ClassRule and to make the inner class non static but then I don't override the current SpringBoot Environment and I need to use @Import the IntegrationTestBase into the Inner class to @AutoWired the DockerComposeContainer and I got circular dependency issue that way. Sorry if the question got too broad. That class is a base class to be extended by the test classes, because of that it doesn't have @Test inside it. Link that describe the Configuration of SpringBoot Test's https://howtodoinjava.com/spring-boot2/testing/springboot-test-configuration/
Upvotes: 0
Views: 378
Reputation: 3073
The DockerComposeContainer object from test-containers must be annotated with @ClassRule to be started and closed automatically
There is no MUST, rather SHOULD.
You can drop the annotation altogether and use the Singleton Container pattern, for example.
Upvotes: 1