Really reuse Testcontainers

The `withReuse(true)` and `testcontainers.reuse.enable=true` don't work together with `@Container`.
The JUnit extension gathers those containers and stop them in the end of test class unconditionally.

* Remove `@Container` annotation usage
* Use `@BeforeAll` and `GenericContainer.start()` manually
This way the container ensures to reuse existing running container and don't start a fresh one.
Since the container instance is stored in a `static` property, it is really started only once.
The rest tests in a suite just reuse that existing container.
Ryuk container will take care about their stopping and removal eventually after JVM exit.
This commit is contained in:
Artem Bilan
2022-05-19 11:34:10 -04:00
parent 35a48de428
commit 04b6b9eabf
2 changed files with 20 additions and 14 deletions

View File

@@ -16,8 +16,8 @@
package org.springframework.integration.aws;
import org.junit.jupiter.api.BeforeAll;
import org.testcontainers.containers.localstack.LocalStackContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
@@ -30,6 +30,11 @@ import com.amazonaws.services.kinesis.AmazonKinesisAsync;
import com.amazonaws.services.kinesis.AmazonKinesisAsyncClientBuilder;
/**
* The base contract for JUnit tests based on the container for Localstack.
* The Testcontainers 'reuse' option must be disabled,so, Ryuk container is started
* and will clean all the containers up from this test suite after JVM exit.
* Since the Localstack container instance is shared via static property, it is going to be
* started only once per JVM, therefore the target Docker container is reused automatically.
*
* @author Artem Bilan
*
@@ -38,17 +43,18 @@ import com.amazonaws.services.kinesis.AmazonKinesisAsyncClientBuilder;
@Testcontainers(disabledWithoutDocker = true)
public interface LocalstackContainerTest {
@Container
LocalStackContainer localStack =
LocalStackContainer LOCAL_STACK_CONTAINER =
new LocalStackContainer(
DockerImageName.parse("localstack/localstack:0.14.2")
.asCompatibleSubstituteFor("localstack/localstack"))
DockerImageName.parse("localstack/localstack:0.14.2"))
.withServices(
LocalStackContainer.Service.DYNAMODB,
LocalStackContainer.Service.KINESIS,
LocalStackContainer.Service.CLOUDWATCH)
.withReuse(true);
LocalStackContainer.Service.CLOUDWATCH);
@BeforeAll
static void startContainer() {
LOCAL_STACK_CONTAINER.start();
}
static AmazonDynamoDBAsync dynamoDbClient() {
return applyAwsClientOptions(AmazonDynamoDBAsyncClientBuilder.standard(), LocalStackContainer.Service.DYNAMODB);
@@ -65,8 +71,8 @@ public interface LocalstackContainerTest {
private static <B extends AwsClientBuilder<B, T>, T> T applyAwsClientOptions(B clientBuilder,
LocalStackContainer.Service serviceToBuild) {
return clientBuilder.withEndpointConfiguration(localStack.getEndpointConfiguration(serviceToBuild))
.withCredentials(localStack.getDefaultCredentialsProvider())
return clientBuilder.withEndpointConfiguration(LOCAL_STACK_CONTAINER.getEndpointConfiguration(serviceToBuild))
.withCredentials(LOCAL_STACK_CONTAINER.getDefaultCredentialsProvider())
.build();
}

View File

@@ -147,13 +147,13 @@ public class KplKclIntegrationTests implements LocalstackContainerTest {
@Bean
public KinesisProducerConfiguration kinesisProducerConfiguration() throws URISyntaxException {
URI kinesisUri =
LocalstackContainerTest.localStack.getEndpointOverride(LocalStackContainer.Service.KINESIS);
LocalstackContainerTest.LOCAL_STACK_CONTAINER.getEndpointOverride(LocalStackContainer.Service.KINESIS);
URI cloudWatchUri =
LocalstackContainerTest.localStack.getEndpointOverride(LocalStackContainer.Service.CLOUDWATCH);
LocalstackContainerTest.LOCAL_STACK_CONTAINER.getEndpointOverride(LocalStackContainer.Service.CLOUDWATCH);
return new KinesisProducerConfiguration()
.setCredentialsProvider(LocalstackContainerTest.localStack.getDefaultCredentialsProvider())
.setRegion(LocalstackContainerTest.localStack.getRegion())
.setCredentialsProvider(LocalstackContainerTest.LOCAL_STACK_CONTAINER.getDefaultCredentialsProvider())
.setRegion(LocalstackContainerTest.LOCAL_STACK_CONTAINER.getRegion())
.setKinesisEndpoint(kinesisUri.getHost())
.setKinesisPort(kinesisUri.getPort())
.setCloudwatchEndpoint(cloudWatchUri.getHost())
@@ -176,7 +176,7 @@ public class KplKclIntegrationTests implements LocalstackContainerTest {
KclMessageDrivenChannelAdapter adapter =
new KclMessageDrivenChannelAdapter(
TEST_STREAM, AMAZON_KINESIS, CLOUD_WATCH, DYNAMO_DB,
LocalstackContainerTest.localStack.getDefaultCredentialsProvider());
LocalstackContainerTest.LOCAL_STACK_CONTAINER.getDefaultCredentialsProvider());
adapter.setOutputChannel(kinesisReceiveChannel());
adapter.setErrorChannel(errorChannel());
adapter.setErrorMessageStrategy(new KinesisMessageHeaderErrorMessageStrategy());