From a614e4bdf9f614bca46bbe098ae08a44c36137b3 Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Thu, 19 May 2022 10:25:48 -0400 Subject: [PATCH] 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 afte JVM exit. **Cherry-pick to `5.5.x`** # Conflicts: # spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/mysql/MySqlContainerTest.java --- .../jdbc/mysql/MySqlContainerTest.java | 17 ++++++++++------- .../mqtt/MosquittoContainerTest.java | 13 ++++++++++--- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/mysql/MySqlContainerTest.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/mysql/MySqlContainerTest.java index fd85e20381..8854b6efd9 100644 --- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/mysql/MySqlContainerTest.java +++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/mysql/MySqlContainerTest.java @@ -16,8 +16,8 @@ package org.springframework.integration.jdbc.mysql; +import org.junit.jupiter.api.BeforeAll; import org.testcontainers.containers.MySQLContainer; -import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.utility.DockerImageName; @@ -25,6 +25,10 @@ import org.springframework.integration.test.util.TestUtils; /** * The base contract for JUnit tests based on the container for MqSQL. + * 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 MqSQL 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 * @@ -33,13 +37,12 @@ import org.springframework.integration.test.util.TestUtils; @Testcontainers(disabledWithoutDocker = true) public interface MySqlContainerTest { - @Container - MySQLContainer MY_SQL_CONTAINER = - new MySQLContainer<>( - DockerImageName.parse(TestUtils.dockerRegistryFromEnv() + "mysql") - .asCompatibleSubstituteFor("mysql")) - .withReuse(true); + MySQLContainer MY_SQL_CONTAINER = new MySQLContainer<>("mysql:8.0.29-oracle"); + @BeforeAll + static void startContainer() { + MY_SQL_CONTAINER.start(); + } static String getDriverClassName() { return MY_SQL_CONTAINER.getDriverClassName(); diff --git a/spring-integration-mqtt/src/test/java/org/springframework/integration/mqtt/MosquittoContainerTest.java b/spring-integration-mqtt/src/test/java/org/springframework/integration/mqtt/MosquittoContainerTest.java index a074bb4fb4..353da21e77 100644 --- a/spring-integration-mqtt/src/test/java/org/springframework/integration/mqtt/MosquittoContainerTest.java +++ b/spring-integration-mqtt/src/test/java/org/springframework/integration/mqtt/MosquittoContainerTest.java @@ -16,13 +16,18 @@ package org.springframework.integration.mqtt; +import org.junit.jupiter.api.BeforeAll; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.integration.test.util.TestUtils; /** + * The base contract for JUnit tests based on the container for MQTT Mosquitto broker. + * 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 Mosquitto 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 * @@ -31,13 +36,15 @@ import org.springframework.integration.test.util.TestUtils; @Testcontainers(disabledWithoutDocker = true) public interface MosquittoContainerTest { - @Container GenericContainer MOSQUITTO_CONTAINER = new GenericContainer<>(TestUtils.dockerRegistryFromEnv() + "eclipse-mosquitto:2.0.12") .withCommand("mosquitto -c /mosquitto-no-auth.conf") - .withReuse(true) .withExposedPorts(1883); + @BeforeAll + static void startContainer() { + MOSQUITTO_CONTAINER.start(); + } static String mqttUrl() { return "tcp://localhost:" + MOSQUITTO_CONTAINER.getFirstMappedPort();