diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f0b094..48560b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### 4.2.0 +* Added reusable support + ### 4.1.0 * Added the testcontainers.db-name.init-script property to all the database starters diff --git a/README.md b/README.md index 09e2c4b..7af63ad 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ Usual use cases include: * [Changelog](#Changelog) * [Usage](#Usage) + * [General](#General) + * [Reusable](#Reusable) * [MSSQL](#MSSQL) * [Tests](#MSSQLTests) * [Local development](#MSSQLLocalDevelopment) @@ -59,6 +61,10 @@ Generally, in cases where port placeholders are used (``), the library wil a randomly selected open port and that the selected value will be used by the configuration in the runtime. You can use a concrete value instead of the placeholder - in that case the library will attempt to start the container on the specified port. + +### Reusable +If [reuse is enabled](https://java.testcontainers.org/features/reuse/) this project automatically marks all created containers for reuse. + ### MSSQL diff --git a/infobip-clickhouse-testcontainers-spring-boot-starter/pom.xml b/infobip-clickhouse-testcontainers-spring-boot-starter/pom.xml index 18f8d1f..7948690 100644 --- a/infobip-clickhouse-testcontainers-spring-boot-starter/pom.xml +++ b/infobip-clickhouse-testcontainers-spring-boot-starter/pom.xml @@ -4,7 +4,7 @@ com.infobip infobip-testcontainers-spring-boot-starter - 4.1.1-SNAPSHOT + 4.2.0-SNAPSHOT infobip-clickhouse-testcontainers-spring-boot-starter @@ -42,5 +42,13 @@ org.springframework.boot spring-boot-starter-jdbc + + + + com.infobip + infobip-testcontainers-test-common + test + ${project.version} + diff --git a/infobip-clickhouse-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializer.java b/infobip-clickhouse-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializer.java index c3324d1..f9acecb 100644 --- a/infobip-clickhouse-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializer.java +++ b/infobip-clickhouse-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializer.java @@ -1,37 +1,38 @@ package com.infobip.testcontainers.spring.clickhouse; -import java.util.Objects; -import java.util.Optional; - import com.infobip.testcontainers.InitializerBase; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.core.env.Environment; + +import java.util.Objects; +import java.util.Optional; public class ClickhouseContainerInitializer extends InitializerBase { @Override public void initialize(ConfigurableApplicationContext applicationContext) { - Environment environment = applicationContext.getEnvironment(); - Optional customPropertyPath = Optional.ofNullable(environment.getProperty("testcontainers.clickhouse.custom-path")); - String jdbcUrlPropertyPath = customPropertyPath.orElse("spring.datasource") + ".jdbc-url"; - String jdbcUrlValue = Objects.requireNonNull(environment.getProperty(jdbcUrlPropertyPath)); - ClickhouseContainerWrapper container = Optional.ofNullable( - environment.getProperty("testcontainers.clickhouse.docker.image.version")) - .map(ClickhouseContainerWrapper::new) - .orElseGet(ClickhouseContainerWrapper::new); - - Optional.ofNullable(environment.getProperty("testcontainers.clickhouse.init-script")).ifPresent(container::withInitScript); + var environment = applicationContext.getEnvironment(); + var customPropertyPath = Optional.ofNullable(environment.getProperty("testcontainers.clickhouse.custom-path")); + var jdbcUrlPropertyPath = customPropertyPath.orElse("spring.datasource") + ".jdbc-url"; + var jdbcUrlValue = Objects.requireNonNull(environment.getProperty(jdbcUrlPropertyPath)); + var wrapper = Optional.ofNullable(environment.getProperty("testcontainers.clickhouse.docker.image.version")) + .map(ClickhouseContainerWrapper::new) + .orElseGet(ClickhouseContainerWrapper::new); + var container = handleReusable(wrapper); + + Optional.ofNullable(environment.getProperty("testcontainers.clickhouse.init-script")) + .ifPresent(container::withInitScript); resolveStaticPort(jdbcUrlValue, GENERIC_URL_WITH_PORT_GROUP_PATTERN) - .ifPresent(staticPort -> bindPort(container, staticPort, ClickhouseContainerWrapper.HTTP_PORT)); + .ifPresent(staticPort -> bindPort(container, staticPort, ClickhouseContainerWrapper.HTTP_PORT)); start(container); - String url = replaceHostAndPortPlaceholders(jdbcUrlValue, container, ClickhouseContainerWrapper.HTTP_PORT); + var url = replaceHostAndPortPlaceholders(jdbcUrlValue, container, ClickhouseContainerWrapper.HTTP_PORT); - TestPropertyValues values = TestPropertyValues.of(String.format("%s=%s", jdbcUrlPropertyPath, url)); + var values = TestPropertyValues.of(String.format("%s=%s", jdbcUrlPropertyPath, url)); values.applyTo(applicationContext); - } + registerContainerAsBean(applicationContext); + } } diff --git a/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializerTest.java b/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializerTest.java index 714f246..0fc1d29 100644 --- a/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializerTest.java +++ b/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializerTest.java @@ -4,6 +4,7 @@ import javax.sql.DataSource; +import com.infobip.testcontainers.TestBase; import lombok.AllArgsConstructor; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @@ -13,9 +14,7 @@ @AllArgsConstructor @ActiveProfiles("test") -@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) -@SpringBootTest(classes = Main.class) -class ClickhouseContainerInitializerTest { +class ClickhouseContainerInitializerTest extends TestBase { private DataSource dataSource; diff --git a/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializerWithInitScriptTest.java b/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializerWithInitScriptTest.java index c052c4b..7b39153 100644 --- a/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializerWithInitScriptTest.java +++ b/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializerWithInitScriptTest.java @@ -1,11 +1,10 @@ package com.infobip.testcontainers.spring.clickhouse; +import com.infobip.testcontainers.TestBase; import lombok.AllArgsConstructor; import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.TestConstructor; import javax.sql.DataSource; @@ -13,9 +12,7 @@ @AllArgsConstructor @ActiveProfiles("init-script") -@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) -@SpringBootTest(classes = Main.class) -class ClickhouseContainerInitializerWithInitScriptTest { +class ClickhouseContainerInitializerWithInitScriptTest extends TestBase { private DataSource dataSource; diff --git a/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializerWithReusableTest.java b/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializerWithReusableTest.java new file mode 100644 index 0000000..74d65c1 --- /dev/null +++ b/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializerWithReusableTest.java @@ -0,0 +1,31 @@ +package com.infobip.testcontainers.spring.clickhouse; + +import com.infobip.testcontainers.ReusableTestBase; +import lombok.AllArgsConstructor; +import org.junit.jupiter.api.Test; +import org.springframework.test.context.ActiveProfiles; +import org.testcontainers.containers.ClickHouseContainer; + +import static org.assertj.core.api.BDDAssertions.then; + +@AllArgsConstructor +@ActiveProfiles("reusable") +class ClickhouseContainerInitializerWithReusableTest extends ReusableTestBase { + + private final ClickhouseContainerWrapper wrapper; + private final int port = ClickHouseContainer.NATIVE_PORT; + + @Test + void shouldReuseContainer() { + // given + var givenContainer = new ClickhouseContainerWrapper(); + givenContainer.withReuse(true); + + // when + givenContainer.start(); + + // then + then(givenContainer.getMappedPort(port)).isEqualTo(wrapper.getMappedPort(port)); + } + +} diff --git a/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializerWithStaticPortTest.java b/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializerWithStaticPortTest.java index c3eb946..c527268 100644 --- a/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializerWithStaticPortTest.java +++ b/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializerWithStaticPortTest.java @@ -1,23 +1,20 @@ package com.infobip.testcontainers.spring.clickhouse; -import static com.infobip.testcontainers.spring.clickhouse.DataSourceConfig.CLICKHOUSE_URL_PROPERTY_NAME; -import static org.assertj.core.api.BDDAssertions.then; - -import javax.sql.DataSource; - +import com.infobip.testcontainers.TestBase; import lombok.AllArgsConstructor; import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.core.env.Environment; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.TestConstructor; + +import javax.sql.DataSource; + +import static com.infobip.testcontainers.spring.clickhouse.DataSourceConfig.CLICKHOUSE_URL_PROPERTY_NAME; +import static org.assertj.core.api.BDDAssertions.then; @AllArgsConstructor @ActiveProfiles("static-port") -@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) -@SpringBootTest(classes = Main.class) -class ClickhouseContainerInitializerWithStaticPortTest { +class ClickhouseContainerInitializerWithStaticPortTest extends TestBase { private Environment environment; private DataSource dataSource; diff --git a/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/Main.java b/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/Main.java deleted file mode 100644 index faf8973..0000000 --- a/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/Main.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.infobip.testcontainers.spring.clickhouse; - -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.builder.SpringApplicationBuilder; - -@SpringBootApplication -public class Main { - - public static void main(String[] args) { - new SpringApplicationBuilder(Main.class).run(args); - } - -} diff --git a/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml b/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml new file mode 100644 index 0000000..853ecf1 --- /dev/null +++ b/infobip-clickhouse-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml @@ -0,0 +1,8 @@ +spring: + datasource: + clickhouse: + jdbc-url: jdbc:clickhouse://: + +testcontainers: + clickhouse: + custom-path: "spring.datasource.clickhouse" \ No newline at end of file diff --git a/infobip-kafka-testcontainers-spring-boot-starter/pom.xml b/infobip-kafka-testcontainers-spring-boot-starter/pom.xml index 5fe65b1..58e0584 100644 --- a/infobip-kafka-testcontainers-spring-boot-starter/pom.xml +++ b/infobip-kafka-testcontainers-spring-boot-starter/pom.xml @@ -4,7 +4,7 @@ com.infobip infobip-testcontainers-spring-boot-starter - 4.1.1-SNAPSHOT + 4.2.0-SNAPSHOT infobip-kafka-testcontainers-spring-boot-starter @@ -39,5 +39,12 @@ awaitility test + + + com.infobip + infobip-testcontainers-test-common + test + ${project.version} + diff --git a/infobip-kafka-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/kafka/KafkaContainerInitializer.java b/infobip-kafka-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/kafka/KafkaContainerInitializer.java index 615c5af..ff55707 100644 --- a/infobip-kafka-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/kafka/KafkaContainerInitializer.java +++ b/infobip-kafka-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/kafka/KafkaContainerInitializer.java @@ -1,23 +1,19 @@ package com.infobip.testcontainers.spring.kafka; -import static java.lang.Integer.parseInt; -import static java.lang.Short.parseShort; - -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.TimeUnit; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; - import com.infobip.testcontainers.InitializerBase; import org.apache.kafka.clients.admin.AdminClient; import org.apache.kafka.clients.admin.NewTopic; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.core.env.Environment; + +import java.util.*; +import java.util.concurrent.*; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static java.lang.Integer.parseInt; +import static java.lang.Short.parseShort; public class KafkaContainerInitializer extends InitializerBase { @@ -25,42 +21,64 @@ public class KafkaContainerInitializer extends InitializerBase bindPort(container, staticPort, KafkaContainerWrapper.KAFKA_PORT)); + .ifPresent(staticPort -> bindPort(container, staticPort, KafkaContainerWrapper.KAFKA_PORT)); start(container); - String url = replaceHostAndPortPlaceholders(bootstrapServers, container, KafkaContainerWrapper.KAFKA_PORT); + var url = replaceHostAndPortPlaceholders(bootstrapServers, container, KafkaContainerWrapper.KAFKA_PORT); Optional.ofNullable(environment.getProperty("testcontainers.kafka.topics", String[].class)) - .ifPresent(topics -> createTestKafkaTopics(url, topics)); - TestPropertyValues values = TestPropertyValues.of( - "spring.kafka.bootstrap-servers=" + url); + .ifPresent(topics -> createTestKafkaTopics(container, url, topics)); + var values = TestPropertyValues.of( + "spring.kafka.bootstrap-servers=" + url); values.applyTo(applicationContext); - } - private static void createTestKafkaTopics(String bootstrapServers, String[] topics) { + registerContainerAsBean(applicationContext); + } - List newTopics = Stream.of(topics) - .map(topic -> topic.split(":")) - .map(topicParts -> new NewTopic(topicParts[0], parseInt(topicParts[1]), - parseShort(topicParts[2]))) - .collect(Collectors.toList()); + private static void createTestKafkaTopics(KafkaContainerWrapper container, String bootstrapServers, String[] topics) { - try { - AdminClient.create(Collections.singletonMap("bootstrap.servers", bootstrapServers)) - .createTopics(newTopics) - .all() - .get(60, TimeUnit.SECONDS); + try (var client = AdminClient.create(Collections.singletonMap("bootstrap.servers", bootstrapServers))) { + if(container.isShouldBeReused()) { + deleteTopics(client, topics); + } + createTopics(client, topics); } catch (Exception e) { throw new RuntimeException(e); } } + private static void deleteTopics(AdminClient client, String[] topics) throws ExecutionException, + InterruptedException, TimeoutException { + var existingTopics = client.listTopics().names().get(60, TimeUnit.SECONDS); + var deleteTopics = Stream.of(topics) + .map(topic -> topic.split(":")) + .filter(topic -> !existingTopics.contains(topic[0])) + .map(topicParts -> topicParts[0]) + .toList(); + + client.deleteTopics(deleteTopics); + } + + private static void createTopics(AdminClient client, String[] topics) throws InterruptedException, + ExecutionException, TimeoutException { + var existingTopics = client.listTopics().names().get(60, TimeUnit.SECONDS); + var newTopics = Stream.of(topics) + .map(topic -> topic.split(":")) + .filter(topic -> !existingTopics.contains(topic[0])) + .map(topicParts -> new NewTopic(topicParts[0], parseInt(topicParts[1]), + parseShort(topicParts[2]))) + .toList(); + + client.createTopics(newTopics) + .all() + .get(60, TimeUnit.SECONDS); + } } diff --git a/infobip-kafka-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/kafka/KafkaContainerInitializerTest.java b/infobip-kafka-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/kafka/KafkaContainerInitializerTest.java index 4ba09fb..f7f56c1 100644 --- a/infobip-kafka-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/kafka/KafkaContainerInitializerTest.java +++ b/infobip-kafka-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/kafka/KafkaContainerInitializerTest.java @@ -9,6 +9,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import com.infobip.testcontainers.TestBase; import lombok.AllArgsConstructor; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @@ -19,9 +20,7 @@ @AllArgsConstructor @ActiveProfiles("test") -@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) -@SpringBootTest(classes = Main.class) -class KafkaContainerInitializerTest { +class KafkaContainerInitializerTest extends TestBase { private final KafkaTemplate kafkaTemplate; private final Listener listener; diff --git a/infobip-kafka-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/kafka/KafkaContainerInitializerWithReusableTest.java b/infobip-kafka-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/kafka/KafkaContainerInitializerWithReusableTest.java new file mode 100644 index 0000000..5f1e456 --- /dev/null +++ b/infobip-kafka-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/kafka/KafkaContainerInitializerWithReusableTest.java @@ -0,0 +1,31 @@ +package com.infobip.testcontainers.spring.kafka; + +import com.infobip.testcontainers.ReusableTestBase; +import lombok.AllArgsConstructor; +import org.junit.jupiter.api.Test; +import org.springframework.test.context.ActiveProfiles; +import org.testcontainers.containers.KafkaContainer; + +import static org.assertj.core.api.BDDAssertions.then; + +@AllArgsConstructor +@ActiveProfiles("reusable") +class KafkaContainerInitializerWithReusableTest extends ReusableTestBase { + + private final KafkaContainerWrapper wrapper; + private final int port = KafkaContainer.KAFKA_PORT; + + @Test + void shouldReuseContainer() { + // given + var givenContainer = new KafkaContainerWrapper(); + givenContainer.withReuse(true); + + // when + givenContainer.start(); + + // then + then(givenContainer.getMappedPort(port)).isEqualTo(wrapper.getMappedPort(port)); + } + +} diff --git a/infobip-kafka-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/kafka/KafkaContainerInitializerWithStaticPortTest.java b/infobip-kafka-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/kafka/KafkaContainerInitializerWithStaticPortTest.java index 6b2a662..6f0e109 100644 --- a/infobip-kafka-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/kafka/KafkaContainerInitializerWithStaticPortTest.java +++ b/infobip-kafka-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/kafka/KafkaContainerInitializerWithStaticPortTest.java @@ -1,28 +1,23 @@ package com.infobip.testcontainers.spring.kafka; -import static com.infobip.testcontainers.spring.kafka.Listener.TOPIC; -import static org.assertj.core.api.BDDAssertions.then; -import static org.awaitility.Awaitility.await; - -import java.time.Duration; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - +import com.infobip.testcontainers.TestBase; import lombok.AllArgsConstructor; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.kafka.KafkaProperties; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.support.SendResult; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.TestConstructor; + +import java.time.Duration; +import java.util.concurrent.*; + +import static com.infobip.testcontainers.spring.kafka.Listener.TOPIC; +import static org.assertj.core.api.BDDAssertions.then; +import static org.awaitility.Awaitility.await; @AllArgsConstructor @ActiveProfiles("static-port") -@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) -@SpringBootTest(classes = Main.class) -class KafkaContainerInitializerWithStaticPortTest { +class KafkaContainerInitializerWithStaticPortTest extends TestBase { private final KafkaTemplate kafkaTemplate; private final Listener listener; diff --git a/infobip-kafka-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/kafka/Main.java b/infobip-kafka-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/kafka/Main.java deleted file mode 100644 index 259769c..0000000 --- a/infobip-kafka-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/kafka/Main.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.infobip.testcontainers.spring.kafka; - -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.builder.SpringApplicationBuilder; - -@SpringBootApplication -public class Main { - - public static void main(String[] args) { - new SpringApplicationBuilder(Main.class).run(args); - } -} diff --git a/infobip-kafka-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml b/infobip-kafka-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml new file mode 100644 index 0000000..abce944 --- /dev/null +++ b/infobip-kafka-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml @@ -0,0 +1,8 @@ +spring: + kafka: + consumer: + groupId: test + autoOffsetReset: earliest + bootstrap-servers: : + +testcontainers.kafka.topics: test-topic:1:1 \ No newline at end of file diff --git a/infobip-mssql-testcontainers-spring-boot-starter/pom.xml b/infobip-mssql-testcontainers-spring-boot-starter/pom.xml index 41a8cd3..e97032a 100644 --- a/infobip-mssql-testcontainers-spring-boot-starter/pom.xml +++ b/infobip-mssql-testcontainers-spring-boot-starter/pom.xml @@ -4,7 +4,7 @@ com.infobip infobip-testcontainers-spring-boot-starter - 4.1.1-SNAPSHOT + 4.2.0-SNAPSHOT infobip-mssql-testcontainers-spring-boot-starter @@ -39,5 +39,12 @@ jtds test + + + com.infobip + infobip-testcontainers-test-common + test + ${project.version} + diff --git a/infobip-mssql-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializer.java b/infobip-mssql-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializer.java index 751beb4..dd46c86 100644 --- a/infobip-mssql-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializer.java +++ b/infobip-mssql-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializer.java @@ -24,41 +24,43 @@ public class MSSQLServerContainerInitializer extends InitializerBase urlPropertyNames = getUrlPropertyNames(environment); - Map urlPropertyNameToValue = getUrlPropertyNameToValue(environment, urlPropertyNames); + var environment = applicationContext.getEnvironment(); + var urlPropertyNames = getUrlPropertyNames(environment); + var urlPropertyNameToValue = getUrlPropertyNameToValue(environment, urlPropertyNames); + var wrapper = Optional.ofNullable(environment.getProperty("testcontainers.mssql.docker.image")) + .map(MSSQLServerContainerWrapper::new) + .orElseGet(MSSQLServerContainerWrapper::new); + var container = handleReusable(wrapper); - MSSQLServerContainerWrapper container = Optional.ofNullable( - environment.getProperty("testcontainers.mssql.docker.image")) - .map(MSSQLServerContainerWrapper::new) - .orElseGet(MSSQLServerContainerWrapper::new); - - Optional initScript = Optional.ofNullable( - environment.getProperty("testcontainers.mssql.init-script")).map(container::withInitScript); + var initScript = Optional.ofNullable(environment.getProperty("testcontainers.mssql.init-script")) + .map(container::withInitScript); resolveStaticPort(urlPropertyNameToValue.values(), GENERIC_URL_WITH_PORT_GROUP_PATTERN) - .ifPresent(staticPort -> bindPort(container, staticPort, MS_SQL_SERVER_PORT)); + .ifPresent(staticPort -> bindPort(container, staticPort, MS_SQL_SERVER_PORT)); start(container); - Map replacedNameToValue = replaceHostAndPort(urlPropertyNameToValue, container); - Map testPropertyValues = addMissingUsernameAndPassword(replacedNameToValue, container); - TestPropertyValues values = TestPropertyValues.of(testPropertyValues); + var replacedNameToValue = replaceHostAndPort(urlPropertyNameToValue, container); + var testPropertyValues = addMissingUsernameAndPassword(replacedNameToValue, container); + var values = TestPropertyValues.of(testPropertyValues); values.applyTo(applicationContext); if (initScript.isEmpty()) { - String url = replacedNameToValue.getOrDefault("spring.datasource.url", replacedNameToValue.get("spring.flyway.url")); + String url = replacedNameToValue.getOrDefault("spring.datasource.url", + replacedNameToValue.get("spring.flyway.url")); DatabaseCreator creator = new DatabaseCreator(url, container.getUsername(), container.getPassword()); creator.createDatabaseIfItDoesNotExist(); } + + registerContainerAsBean(applicationContext); } private List getUrlPropertyNames(Environment environment) { - String name = environment.getProperty("testcontainers.mssql.datasource.url.property.name"); + var name = environment.getProperty("testcontainers.mssql.datasource.url.property.name"); if (Objects.nonNull(name)) { return Collections.singletonList(name); } - String[] names = environment.getProperty("testcontainers.mssql.datasource.url.property.names", String[].class); + var names = environment.getProperty("testcontainers.mssql.datasource.url.property.names", String[].class); if (Objects.nonNull(names)) { return Arrays.asList(names); } @@ -84,16 +86,18 @@ private Map replaceHostAndPort(Map urlPropertyNa return urlPropertyNameToValue.entrySet() .stream() .collect(Collectors.toMap(Map.Entry::getKey, - entry -> replaceHostAndPortPlaceholders(entry.getValue(), container, MS_SQL_SERVER_PORT))); + entry -> replaceHostAndPortPlaceholders(entry.getValue(), + container, + MS_SQL_SERVER_PORT))); } private Map addMissingUsernameAndPassword(Map urlPropertyNameToValue, MSSQLServerContainerWrapper container) { - String username = container.getUsername(); - String password = container.getPassword(); + var username = container.getUsername(); + var password = container.getPassword(); - Map testPropertyValues = new HashMap<>(urlPropertyNameToValue); - for (Map.Entry entry : urlPropertyNameToValue.entrySet()) { + var testPropertyValues = new HashMap<>(urlPropertyNameToValue); + for (var entry : urlPropertyNameToValue.entrySet()) { String name = entry.getKey(); if (DEFAULT_PROPERTY_NAMES.contains(name)) { String root = name.substring(0, name.indexOf(".url")); @@ -103,5 +107,4 @@ private Map addMissingUsernameAndPassword(Map ur } return testPropertyValues; } - } diff --git a/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithInitScriptTest.java b/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithInitScriptTest.java index e3023c3..16a1def 100644 --- a/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithInitScriptTest.java +++ b/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithInitScriptTest.java @@ -1,5 +1,6 @@ package com.infobip.testcontainers.spring.mssql; +import com.infobip.testcontainers.TestBase; import lombok.AllArgsConstructor; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; @@ -17,9 +18,7 @@ @AllArgsConstructor @ActiveProfiles("init-script") -@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) -@SpringBootTest(classes = Main.class) -class MSSQLServerContainerInitializerWithInitScriptTest { +class MSSQLServerContainerInitializerWithInitScriptTest extends TestBase { private final DataSourceProperties properties; diff --git a/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithJtdsDriverTest.java b/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithJtdsDriverTest.java index 3a0a541..f60c7b5 100644 --- a/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithJtdsDriverTest.java +++ b/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithJtdsDriverTest.java @@ -1,13 +1,12 @@ package com.infobip.testcontainers.spring.mssql; +import com.infobip.testcontainers.TestBase; import lombok.AllArgsConstructor; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.SimpleDriverDataSource; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.TestConstructor; import java.sql.*; @@ -15,9 +14,7 @@ @AllArgsConstructor @ActiveProfiles("jtds") -@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) -@SpringBootTest(classes = Main.class) -class MSSQLServerContainerInitializerWithJtdsDriverTest { +class MSSQLServerContainerInitializerWithJtdsDriverTest extends TestBase { private final DataSourceProperties properties; diff --git a/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithMicrosoftDriverTest.java b/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithMicrosoftDriverTest.java index c6e5425..9a33e34 100644 --- a/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithMicrosoftDriverTest.java +++ b/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithMicrosoftDriverTest.java @@ -1,14 +1,13 @@ package com.infobip.testcontainers.spring.mssql; +import com.infobip.testcontainers.TestBase; import lombok.AllArgsConstructor; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.core.env.Environment; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.SimpleDriverDataSource; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.TestConstructor; import java.sql.*; @@ -16,9 +15,7 @@ @AllArgsConstructor @ActiveProfiles("microsoft-driver") -@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) -@SpringBootTest(classes = Main.class) -class MSSQLServerContainerInitializerWithMicrosoftDriverTest { +class MSSQLServerContainerInitializerWithMicrosoftDriverTest extends TestBase { private final Environment environment; private final DataSourceProperties properties; diff --git a/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithReusableTest.java b/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithReusableTest.java new file mode 100644 index 0000000..be3d243 --- /dev/null +++ b/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithReusableTest.java @@ -0,0 +1,30 @@ +package com.infobip.testcontainers.spring.mssql; + +import com.infobip.testcontainers.ReusableTestBase; +import lombok.AllArgsConstructor; +import org.junit.jupiter.api.Test; +import org.springframework.test.context.ActiveProfiles; +import org.testcontainers.containers.MSSQLServerContainer; + +import static org.assertj.core.api.BDDAssertions.then; + +@AllArgsConstructor +@ActiveProfiles("reusable") +class MSSQLServerContainerInitializerWithReusableTest extends ReusableTestBase { + + private final MSSQLServerContainerWrapper wrapper; + private final int port = MSSQLServerContainer.MS_SQL_SERVER_PORT; + + @Test + void shouldReuseContainer() { + // given + var givenContainer = new MSSQLServerContainerWrapper(); + givenContainer.withReuse(true); + + // when + givenContainer.start(); + + // then + then(givenContainer.getMappedPort(port)).isEqualTo(wrapper.getMappedPort(port)); + } +} diff --git a/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithStaticPortTest.java b/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithStaticPortTest.java index a50b75c..c8e4fef 100644 --- a/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithStaticPortTest.java +++ b/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithStaticPortTest.java @@ -1,26 +1,21 @@ package com.infobip.testcontainers.spring.mssql; -import static org.assertj.core.api.BDDAssertions.then; - -import java.sql.Driver; -import java.sql.DriverManager; -import java.sql.SQLException; - +import com.infobip.testcontainers.TestBase; import lombok.AllArgsConstructor; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.core.env.Environment; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.SimpleDriverDataSource; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.TestConstructor; + +import java.sql.*; + +import static org.assertj.core.api.BDDAssertions.then; @AllArgsConstructor @ActiveProfiles("static-port") -@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) -@SpringBootTest(classes = Main.class) -class MSSQLServerContainerInitializerWithStaticPortTest { +class MSSQLServerContainerInitializerWithStaticPortTest extends TestBase { private final Environment environment; private final DataSourceProperties properties; diff --git a/infobip-mssql-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml b/infobip-mssql-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml new file mode 100644 index 0000000..8fd5521 --- /dev/null +++ b/infobip-mssql-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml @@ -0,0 +1,3 @@ +spring: + datasource: + url: jdbc:sqlserver://:;database=MicrosoftDriverTestDatabase;trustServerCertificate=true \ No newline at end of file diff --git a/infobip-postgresql-testcontainers-spring-boot-starter/pom.xml b/infobip-postgresql-testcontainers-spring-boot-starter/pom.xml index bebba1b..bf5597a 100644 --- a/infobip-postgresql-testcontainers-spring-boot-starter/pom.xml +++ b/infobip-postgresql-testcontainers-spring-boot-starter/pom.xml @@ -4,7 +4,7 @@ com.infobip infobip-testcontainers-spring-boot-starter - 4.1.1-SNAPSHOT + 4.2.0-SNAPSHOT infobip-postgresql-testcontainers-spring-boot-starter @@ -32,5 +32,13 @@ postgresql ${testcontainers.version} + + + + com.infobip + infobip-testcontainers-test-common + test + ${project.version} + diff --git a/infobip-postgresql-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializer.java b/infobip-postgresql-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializer.java index 472096c..2124294 100644 --- a/infobip-postgresql-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializer.java +++ b/infobip-postgresql-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializer.java @@ -1,43 +1,45 @@ package com.infobip.testcontainers.spring.postgresql; -import java.util.Optional; - import com.infobip.testcontainers.InitializerBase; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.core.env.Environment; import org.springframework.util.StringUtils; +import java.util.Optional; + public class PostgreSQLContainerInitializer extends InitializerBase { @Override public void initialize(ConfigurableApplicationContext applicationContext) { - Environment environment = applicationContext.getEnvironment(); - String dataSourceUrlPropertyName = Optional.ofNullable( - environment.getProperty("testcontainers.postgresql.datasource.url.property.name")) - .orElse("spring.datasource.url"); - String dataSourceUrl = environment.getProperty(dataSourceUrlPropertyName); + var environment = applicationContext.getEnvironment(); + var dataSourceUrlPropertyName = Optional.ofNullable( + environment.getProperty("testcontainers.postgresql.datasource.url.property.name")) + .orElse("spring.datasource.url"); + var dataSourceUrl = environment.getProperty(dataSourceUrlPropertyName); if (StringUtils.isEmpty(dataSourceUrl)) { throw new IllegalStateException("URL for test-container is null or empty."); } - String database = dataSourceUrl.substring(dataSourceUrl.lastIndexOf("/") + 1); - PostgreSQLContainerWrapper container = Optional.ofNullable(environment.getProperty("testcontainers.postgresql.docker.image")) - .map(imageName -> new PostgreSQLContainerWrapper(database, imageName)) - .orElseGet(() -> new PostgreSQLContainerWrapper(database)); + var database = dataSourceUrl.substring(dataSourceUrl.lastIndexOf("/") + 1); + var wrapper = Optional.ofNullable(environment.getProperty("testcontainers.postgresql.docker.image")) + .map(imageName -> new PostgreSQLContainerWrapper(database, imageName)) + .orElseGet(() -> new PostgreSQLContainerWrapper(database)); + var container = handleReusable(wrapper); - Optional.ofNullable(environment.getProperty("testcontainers.postgresql.init-script")).ifPresent(container::withInitScript); + Optional.ofNullable(environment.getProperty("testcontainers.postgresql.init-script")) + .ifPresent(container::withInitScript); resolveStaticPort(dataSourceUrl, GENERIC_URL_WITH_PORT_GROUP_PATTERN) - .ifPresent(staticPort -> bindPort(container, staticPort, PostgreSQLContainerWrapper.POSTGRESQL_PORT)); + .ifPresent(staticPort -> bindPort(container, staticPort, PostgreSQLContainerWrapper.POSTGRESQL_PORT)); start(container); - String url = replaceHostAndPortPlaceholders(dataSourceUrl, container, PostgreSQLContainerWrapper.POSTGRESQL_PORT); - TestPropertyValues values = TestPropertyValues.of(dataSourceUrlPropertyName + "=" + url); + var url = replaceHostAndPortPlaceholders(dataSourceUrl, container, PostgreSQLContainerWrapper.POSTGRESQL_PORT); + var values = TestPropertyValues.of(dataSourceUrlPropertyName + "=" + url); values.applyTo(applicationContext); - } + registerContainerAsBean(applicationContext); + } } diff --git a/infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/Main.java b/infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/Main.java deleted file mode 100644 index 131bd99..0000000 --- a/infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/Main.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.infobip.testcontainers.spring.postgresql; - -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.builder.SpringApplicationBuilder; - -@SpringBootApplication -public class Main { - - public static void main(String[] args) { - new SpringApplicationBuilder(Main.class).run(args); - } - -} \ No newline at end of file diff --git a/infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializerTest.java b/infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializerTest.java index 00bc69b..d112940 100644 --- a/infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializerTest.java +++ b/infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializerTest.java @@ -1,13 +1,12 @@ package com.infobip.testcontainers.spring.postgresql; +import com.infobip.testcontainers.TestBase; import lombok.AllArgsConstructor; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.SimpleDriverDataSource; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.TestConstructor; import java.sql.*; @@ -15,9 +14,7 @@ @AllArgsConstructor @ActiveProfiles("test") -@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) -@SpringBootTest(classes = Main.class) -class PostgreSQLContainerInitializerTest { +class PostgreSQLContainerInitializerTest extends TestBase { private final DataSourceProperties properties; diff --git a/infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializerWithInitScriptTest.java b/infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializerWithInitScriptTest.java index eaa431e..6739791 100644 --- a/infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializerWithInitScriptTest.java +++ b/infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializerWithInitScriptTest.java @@ -1,5 +1,6 @@ package com.infobip.testcontainers.spring.postgresql; +import com.infobip.testcontainers.TestBase; import lombok.AllArgsConstructor; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; @@ -17,9 +18,7 @@ @AllArgsConstructor @ActiveProfiles("init-script") -@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) -@SpringBootTest(classes = Main.class) -class PostgreSQLContainerInitializerWithInitScriptTest { +class PostgreSQLContainerInitializerWithInitScriptTest extends TestBase { private final DataSourceProperties properties; diff --git a/infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializerWithReusableTest.java b/infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializerWithReusableTest.java new file mode 100644 index 0000000..f49f498 --- /dev/null +++ b/infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializerWithReusableTest.java @@ -0,0 +1,31 @@ +package com.infobip.testcontainers.spring.postgresql; + +import com.infobip.testcontainers.ReusableTestBase; +import lombok.AllArgsConstructor; +import org.junit.jupiter.api.Test; +import org.springframework.test.context.ActiveProfiles; +import org.testcontainers.containers.PostgreSQLContainer; + +import static org.assertj.core.api.BDDAssertions.then; + +@AllArgsConstructor +@ActiveProfiles("reusable") +class PostgreSQLContainerInitializerWithReusableTest extends ReusableTestBase { + + private final PostgreSQLContainerWrapper wrapper; + private final int port = PostgreSQLContainer.POSTGRESQL_PORT; + + @Test + void shouldReuseContainer() { + // given + var givenContainer = new PostgreSQLContainerWrapper("TestDatabase"); + givenContainer.withReuse(true); + + // when + givenContainer.start(); + + // then + then(givenContainer.getMappedPort(port)).isEqualTo(wrapper.getMappedPort(port)); + } + +} \ No newline at end of file diff --git a/infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializerWithStaticPortTest.java b/infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializerWithStaticPortTest.java index 985790f..b67a364 100644 --- a/infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializerWithStaticPortTest.java +++ b/infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializerWithStaticPortTest.java @@ -6,6 +6,7 @@ import java.sql.DriverManager; import java.sql.SQLException; +import com.infobip.testcontainers.TestBase; import lombok.AllArgsConstructor; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; @@ -17,9 +18,7 @@ @AllArgsConstructor @ActiveProfiles("static-port") -@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) -@SpringBootTest(classes = Main.class) -class PostgreSQLContainerInitializerWithStaticPortTest { +class PostgreSQLContainerInitializerWithStaticPortTest extends TestBase { private final DataSourceProperties properties; diff --git a/infobip-postgresql-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml b/infobip-postgresql-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml new file mode 100644 index 0000000..69a2534 --- /dev/null +++ b/infobip-postgresql-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml @@ -0,0 +1,5 @@ +spring: + datasource: + url: jdbc:postgresql://:/TestDatabase + username: test + password: test \ No newline at end of file diff --git a/infobip-rabbitmq-testcontainers-spring-boot-starter/pom.xml b/infobip-rabbitmq-testcontainers-spring-boot-starter/pom.xml index b2eabc6..ca7928b 100644 --- a/infobip-rabbitmq-testcontainers-spring-boot-starter/pom.xml +++ b/infobip-rabbitmq-testcontainers-spring-boot-starter/pom.xml @@ -4,7 +4,7 @@ com.infobip infobip-testcontainers-spring-boot-starter - 4.1.1-SNAPSHOT + 4.2.0-SNAPSHOT infobip-rabbitmq-testcontainers-spring-boot-starter @@ -21,5 +21,13 @@ org.springframework.boot spring-boot-starter-amqp + + + + com.infobip + infobip-testcontainers-test-common + test + ${project.version} + diff --git a/infobip-rabbitmq-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/rabbit/RabbitContainerInitializer.java b/infobip-rabbitmq-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/rabbit/RabbitContainerInitializer.java index d96840b..354bf10 100644 --- a/infobip-rabbitmq-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/rabbit/RabbitContainerInitializer.java +++ b/infobip-rabbitmq-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/rabbit/RabbitContainerInitializer.java @@ -13,29 +13,28 @@ public class RabbitContainerInitializer extends InitializerBase { @Override - public void initialize(ConfigurableApplicationContext configurableApplicationContext) { - Environment environment = configurableApplicationContext.getEnvironment(); - RabbitContainerWrapper container = Optional.ofNullable( - environment.getProperty("testcontainers.rabbit.docker.image")) - .map(RabbitContainerWrapper::new) - .orElseGet( - () -> new RabbitContainerWrapper("rabbitmq:3.8.9-alpine")); + public void initialize(ConfigurableApplicationContext applicationContext) { + var environment = applicationContext.getEnvironment(); + var wrapper = Optional.ofNullable(environment.getProperty("testcontainers.rabbit.docker.image")) + .map(RabbitContainerWrapper::new) + .orElseGet(() -> new RabbitContainerWrapper("rabbitmq:3.8.9-alpine")); + var container = handleReusable(wrapper); resolveStaticPort(environment) - .ifPresent(staticPort -> bindPort(container, staticPort, PORT)); + .ifPresent(staticPort -> bindPort(container, staticPort, PORT)); container.waitingFor(Wait.forListeningPort()); start(container); - TestPropertyValues values = TestPropertyValues.of( - String.format("spring.rabbitmq.addresses=%s:%d", container.getHost(), - container.getMappedPort(PORT))); - values.applyTo(configurableApplicationContext); + var values = TestPropertyValues.of( + String.format("spring.rabbitmq.addresses=%s:%d", container.getHost(), container.getMappedPort(PORT))); + values.applyTo(applicationContext); + + registerContainerAsBean(applicationContext); } private Optional resolveStaticPort(Environment environment) { return Optional.ofNullable(environment.getProperty("spring.rabbitmq.port")) .map(Integer::valueOf); } - } diff --git a/infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/rabbit/Main.java b/infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/rabbit/Main.java deleted file mode 100644 index 9284ec9..0000000 --- a/infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/rabbit/Main.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.infobip.testcontainers.spring.rabbit; - -import static org.springframework.amqp.core.BindingBuilder.bind; - -import org.springframework.amqp.core.Binding; -import org.springframework.amqp.core.Queue; -import org.springframework.amqp.core.QueueBuilder; -import org.springframework.amqp.core.TopicExchange; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.context.annotation.Bean; - -@SpringBootApplication -public class Main { - - @Bean - public Queue testQueue() { - return QueueBuilder.durable("test.queue").build(); - } - - @Bean - public TopicExchange testExchange() { - return new TopicExchange("test.exchange"); - } - - @Bean - public Binding bindToTestExchange() { - return bind(testQueue()).to(testExchange()).with("test.key.#"); - } - - public static void main(String[] args) { - new SpringApplicationBuilder(Main.class).run(args); - } -} diff --git a/infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/rabbit/RabbitContainerInitializerTest.java b/infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/rabbit/RabbitContainerInitializerTest.java index 36f86d8..25cb5ce 100644 --- a/infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/rabbit/RabbitContainerInitializerTest.java +++ b/infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/rabbit/RabbitContainerInitializerTest.java @@ -1,23 +1,18 @@ package com.infobip.testcontainers.spring.rabbit; -import static org.assertj.core.api.BDDAssertions.then; - +import com.infobip.testcontainers.TestBase; import lombok.AllArgsConstructor; import org.assertj.core.api.BDDAssertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.amqp.rabbit.core.RabbitTemplate; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.TestConfiguration; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.TestConstructor; + +import static org.assertj.core.api.BDDAssertions.then; @AllArgsConstructor @ActiveProfiles("test") -@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) -@TestConfiguration -@SpringBootTest(classes = Main.class) -class RabbitContainerInitializerTest { +class RabbitContainerInitializerTest extends TestBase { private final RabbitTemplate rabbitTemplate; diff --git a/infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/rabbit/RabbitContainerInitializerWithReusableTest.java b/infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/rabbit/RabbitContainerInitializerWithReusableTest.java new file mode 100644 index 0000000..8f380ea --- /dev/null +++ b/infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/rabbit/RabbitContainerInitializerWithReusableTest.java @@ -0,0 +1,30 @@ +package com.infobip.testcontainers.spring.rabbit; + +import com.infobip.testcontainers.ReusableTestBase; +import lombok.AllArgsConstructor; +import org.junit.jupiter.api.Test; +import org.springframework.test.context.ActiveProfiles; + +import static org.assertj.core.api.BDDAssertions.then; + +@AllArgsConstructor +@ActiveProfiles("reusable") +class RabbitContainerInitializerWithReusableTest extends ReusableTestBase { + + private final RabbitContainerWrapper wrapper; + private final int port = RabbitContainerWrapper.PORT; + + @Test + void shouldReuseContainer() { + // given + var givenContainer = new RabbitContainerWrapper("rabbitmq:3.6.14-alpine"); + givenContainer.withReuse(true); + + // when + givenContainer.start(); + + // then + then(givenContainer.getMappedPort(port)).isEqualTo(wrapper.getMappedPort(port)); + } + +} diff --git a/infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/rabbit/RabbitContainerInitializerWithStaticPortTest.java b/infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/rabbit/RabbitContainerInitializerWithStaticPortTest.java index 6dc3ba9..e1f1878 100644 --- a/infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/rabbit/RabbitContainerInitializerWithStaticPortTest.java +++ b/infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/rabbit/RabbitContainerInitializerWithStaticPortTest.java @@ -1,24 +1,19 @@ package com.infobip.testcontainers.spring.rabbit; -import static org.assertj.core.api.BDDAssertions.then; - +import com.infobip.testcontainers.TestBase; import lombok.AllArgsConstructor; import org.assertj.core.api.BDDAssertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.boot.autoconfigure.amqp.RabbitProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.TestConfiguration; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.TestConstructor; + +import static org.assertj.core.api.BDDAssertions.then; @AllArgsConstructor @ActiveProfiles("static-port") -@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) -@TestConfiguration -@SpringBootTest(classes = Main.class) -class RabbitContainerInitializerWithStaticPortTest { +class RabbitContainerInitializerWithStaticPortTest extends TestBase { private final RabbitTemplate rabbitTemplate; private final RabbitProperties rabbitProperties; diff --git a/infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yml b/infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yml new file mode 100644 index 0000000..80af7dc --- /dev/null +++ b/infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yml @@ -0,0 +1 @@ +testcontainers.rabbit.docker.image: rabbitmq:3.6.14-alpine \ No newline at end of file diff --git a/infobip-redis-testcontainers-spring-boot-starter/pom.xml b/infobip-redis-testcontainers-spring-boot-starter/pom.xml index 78eaa2d..dc03c94 100644 --- a/infobip-redis-testcontainers-spring-boot-starter/pom.xml +++ b/infobip-redis-testcontainers-spring-boot-starter/pom.xml @@ -4,7 +4,7 @@ com.infobip infobip-testcontainers-spring-boot-starter - 4.1.1-SNAPSHOT + 4.2.0-SNAPSHOT infobip-redis-testcontainers-spring-boot-starter @@ -28,5 +28,13 @@ lettuce-core test + + + + com.infobip + infobip-testcontainers-test-common + test + ${project.version} + diff --git a/infobip-redis-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/redis/RedisContainerInitializer.java b/infobip-redis-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/redis/RedisContainerInitializer.java index dec24c2..5e52e04 100644 --- a/infobip-redis-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/redis/RedisContainerInitializer.java +++ b/infobip-redis-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/redis/RedisContainerInitializer.java @@ -6,26 +6,26 @@ import com.infobip.testcontainers.InitializerBase; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.core.env.Environment; public class RedisContainerInitializer extends InitializerBase { @Override public void initialize(ConfigurableApplicationContext applicationContext) { - Environment environment = applicationContext.getEnvironment(); - String redisUrl = Objects.requireNonNull(environment.getProperty("spring.data.redis.url")); - RedisContainerWrapper container = Optional.ofNullable( - environment.getProperty("testcontainers.redis.docker.image")) - .map(RedisContainerWrapper::new) - .orElseGet(() -> new RedisContainerWrapper("redis:6.2.6-alpine")); + var environment = applicationContext.getEnvironment(); + var redisUrl = Objects.requireNonNull(environment.getProperty("spring.data.redis.url")); + var wrapper = Optional.ofNullable(environment.getProperty("testcontainers.redis.docker.image")) + .map(RedisContainerWrapper::new) + .orElseGet(() -> new RedisContainerWrapper("redis:6.2.6-alpine")); + var container = handleReusable(wrapper); resolveStaticPort(redisUrl, GENERIC_URL_WITH_PORT_GROUP_PATTERN) - .ifPresent(staticPort -> bindPort(container, staticPort, RedisContainerWrapper.PORT)); + .ifPresent(staticPort -> bindPort(container, staticPort, RedisContainerWrapper.PORT)); start(container); - String url = replaceHostAndPortPlaceholders(redisUrl, container, RedisContainerWrapper.PORT); - TestPropertyValues values = TestPropertyValues.of("spring.data.redis.url=" + url); + var url = replaceHostAndPortPlaceholders(redisUrl, container, RedisContainerWrapper.PORT); + var values = TestPropertyValues.of("spring.data.redis.url=" + url); values.applyTo(applicationContext); - } + registerContainerAsBean(applicationContext); + } } diff --git a/infobip-redis-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/redis/Main.java b/infobip-redis-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/redis/Main.java deleted file mode 100644 index 46d80d7..0000000 --- a/infobip-redis-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/redis/Main.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.infobip.testcontainers.spring.redis; - -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.builder.SpringApplicationBuilder; - -@SpringBootApplication -public class Main { - - public static void main(String[] args) { - new SpringApplicationBuilder(Main.class).run(args); - } -} \ No newline at end of file diff --git a/infobip-redis-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/redis/RedisContainerInitializerTest.java b/infobip-redis-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/redis/RedisContainerInitializerTest.java index e641992..50a8014 100644 --- a/infobip-redis-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/redis/RedisContainerInitializerTest.java +++ b/infobip-redis-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/redis/RedisContainerInitializerTest.java @@ -1,5 +1,6 @@ package com.infobip.testcontainers.spring.redis; +import com.infobip.testcontainers.TestBase; import lombok.AllArgsConstructor; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @@ -11,9 +12,7 @@ @AllArgsConstructor @ActiveProfiles("test") -@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) -@SpringBootTest(classes = Main.class) -class RedisContainerInitializerTest { +class RedisContainerInitializerTest extends TestBase { private final RedisTemplate template; diff --git a/infobip-redis-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/redis/RedisContainerInitializerWithReusableTest.java b/infobip-redis-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/redis/RedisContainerInitializerWithReusableTest.java new file mode 100644 index 0000000..7bfb4fe --- /dev/null +++ b/infobip-redis-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/redis/RedisContainerInitializerWithReusableTest.java @@ -0,0 +1,29 @@ +package com.infobip.testcontainers.spring.redis; + +import com.infobip.testcontainers.ReusableTestBase; +import lombok.AllArgsConstructor; +import org.junit.jupiter.api.Test; +import org.springframework.test.context.ActiveProfiles; + +import static org.assertj.core.api.BDDAssertions.then; + +@AllArgsConstructor +@ActiveProfiles("reusable") +class RedisContainerInitializerWithReusableTest extends ReusableTestBase { + + private final RedisContainerWrapper wrapper; + private final int port = RedisContainerWrapper.PORT; + + @Test + void shouldReuseContainer() { + // given + var givenContainer = new RedisContainerWrapper(); + givenContainer.withReuse(true); + + // when + givenContainer.start(); + + // then + then(givenContainer.getMappedPort(port)).isEqualTo(wrapper.getMappedPort(port)); + } +} diff --git a/infobip-redis-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/redis/RedisContainerInitializerWithStaticPortTest.java b/infobip-redis-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/redis/RedisContainerInitializerWithStaticPortTest.java index 3369c6a..e59a688 100644 --- a/infobip-redis-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/redis/RedisContainerInitializerWithStaticPortTest.java +++ b/infobip-redis-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/redis/RedisContainerInitializerWithStaticPortTest.java @@ -1,20 +1,17 @@ package com.infobip.testcontainers.spring.redis; -import static org.assertj.core.api.BDDAssertions.then; - +import com.infobip.testcontainers.TestBase; import lombok.AllArgsConstructor; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.data.redis.RedisProperties; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.TestConstructor; + +import static org.assertj.core.api.BDDAssertions.then; @AllArgsConstructor @ActiveProfiles("static-port") -@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) -@SpringBootTest(classes = Main.class) -class RedisContainerInitializerWithStaticPortTest { +class RedisContainerInitializerWithStaticPortTest extends TestBase { private final RedisTemplate template; private final RedisProperties redisProperties; diff --git a/infobip-redis-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml b/infobip-redis-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml new file mode 100644 index 0000000..a54ff00 --- /dev/null +++ b/infobip-redis-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml @@ -0,0 +1,4 @@ +spring: + data: + redis: + url: redis://: \ No newline at end of file diff --git a/infobip-testcontainers-common/pom.xml b/infobip-testcontainers-common/pom.xml index 3049236..2bce484 100644 --- a/infobip-testcontainers-common/pom.xml +++ b/infobip-testcontainers-common/pom.xml @@ -4,7 +4,7 @@ com.infobip infobip-testcontainers-spring-boot-starter - 4.1.1-SNAPSHOT + 4.2.0-SNAPSHOT infobip-testcontainers-common diff --git a/infobip-testcontainers-common/src/main/java/com/infobip/testcontainers/InitializerBase.java b/infobip-testcontainers-common/src/main/java/com/infobip/testcontainers/InitializerBase.java index ab8662b..0b473fb 100644 --- a/infobip-testcontainers-common/src/main/java/com/infobip/testcontainers/InitializerBase.java +++ b/infobip-testcontainers-common/src/main/java/com/infobip/testcontainers/InitializerBase.java @@ -1,21 +1,19 @@ package com.infobip.testcontainers; -import java.util.Collection; -import java.util.Collections; -import java.util.Optional; -import java.util.concurrent.atomic.AtomicReference; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ApplicationListener; -import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.*; import org.springframework.context.event.ContextClosedEvent; import org.testcontainers.containers.Container; +import org.testcontainers.containers.GenericContainer; import org.testcontainers.lifecycle.Startable; +import org.testcontainers.utility.TestcontainersConfiguration; + +import java.util.*; +import java.util.concurrent.atomic.AtomicReference; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public abstract class InitializerBase - implements ApplicationContextInitializer, ApplicationListener { + implements ApplicationContextInitializer, ApplicationListener { public static final String PORT_PLACEHOLDER = ""; public static final String HOST_PLACEHOLDER = ""; @@ -37,7 +35,9 @@ protected void start(C container) { container.start(); } - protected String replaceHostAndPortPlaceholders(String source, Container container, Integer originalContainerPort) { + protected String replaceHostAndPortPlaceholders(String source, + Container container, + Integer originalContainerPort) { return source.replaceAll(HOST_PLACEHOLDER, container.getHost()) .replaceAll(PORT_PLACEHOLDER, container.getMappedPort(originalContainerPort).toString()); } @@ -50,10 +50,11 @@ protected Optional resolveStaticPort(String connectionString, Pattern u .map(Integer::valueOf); } - protected Optional resolveStaticPort(Collection connectionStrings, Pattern urlPatternWithPortGroup) { + protected Optional resolveStaticPort(Collection connectionStrings, + Pattern urlPatternWithPortGroup) { return connectionStrings.stream() .flatMap(connectionString -> resolveStaticPort(connectionString, - urlPatternWithPortGroup).stream()) + urlPatternWithPortGroup).stream()) .findFirst(); } @@ -61,4 +62,20 @@ protected void bindPort(Container container, Integer hostPort, Integer contai container.setPortBindings(Collections.singletonList(hostPort + ":" + containerPort)); } + protected , T extends GenericContainer> T handleReusable(T container) { + + if (TestcontainersConfiguration.getInstance().environmentSupportsReuse()) { + container.withReuse(true); + } + + return container; + } + + protected void registerContainerAsBean(ConfigurableApplicationContext applicationContext) { + var c = container.get(); + var containerClassName = c.getClass().getSimpleName(); + var beanName = Character.toLowerCase(containerClassName.charAt(0)) + containerClassName.substring(1); + applicationContext.getBeanFactory() + .registerSingleton(beanName, c); + } } diff --git a/infobip-testcontainers-test-common/pom.xml b/infobip-testcontainers-test-common/pom.xml new file mode 100644 index 0000000..2ae02e2 --- /dev/null +++ b/infobip-testcontainers-test-common/pom.xml @@ -0,0 +1,29 @@ + + 4.0.0 + + + com.infobip + infobip-testcontainers-spring-boot-starter + 4.2.0-SNAPSHOT + + + infobip-testcontainers-test-common + + + + ${project.groupId} + infobip-testcontainers-common + ${project.version} + + + + org.springframework.boot + spring-boot-starter-test + + + + org.projectlombok + lombok + + + \ No newline at end of file diff --git a/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/Main.java b/infobip-testcontainers-test-common/src/main/java/com/infobip/testcontainers/Main.java similarity index 85% rename from infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/Main.java rename to infobip-testcontainers-test-common/src/main/java/com/infobip/testcontainers/Main.java index 165e45b..a1f7f7d 100644 --- a/infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/Main.java +++ b/infobip-testcontainers-test-common/src/main/java/com/infobip/testcontainers/Main.java @@ -1,4 +1,4 @@ -package com.infobip.testcontainers.spring.mssql; +package com.infobip.testcontainers; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; diff --git a/infobip-testcontainers-test-common/src/main/java/com/infobip/testcontainers/ReusableTestBase.java b/infobip-testcontainers-test-common/src/main/java/com/infobip/testcontainers/ReusableTestBase.java new file mode 100644 index 0000000..ff5fb37 --- /dev/null +++ b/infobip-testcontainers-test-common/src/main/java/com/infobip/testcontainers/ReusableTestBase.java @@ -0,0 +1,38 @@ +package com.infobip.testcontainers; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestConstructor; +import org.testcontainers.utility.TestcontainersConfiguration; + +import java.io.File; + +@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) +@SpringBootTest(classes = Main.class) +public class ReusableTestBase { + + private static final String HOME = System.getProperty("user.home"); + private static final String FILENAME = ".testcontainers.properties"; + private static final File FILE = new File(HOME, FILENAME); + private static final File TEMP_FILE = new File(HOME, FILENAME + ".tmp"); + + @BeforeAll + static void createTestcontainersPropertiesFile() { + if (FILE.exists()) { + FILE.renameTo(TEMP_FILE); + } + + TestcontainersConfiguration.getInstance().updateUserConfig("testcontainers.reuse.enable", "true"); + } + + @AfterAll + static void cleanupTestcontainersPropertiesFile() { + TestcontainersConfiguration.getInstance().updateUserConfig("testcontainers.reuse.enable", "false"); + FILE.delete(); + + if (TEMP_FILE.exists()) { + TEMP_FILE.renameTo(FILE); + } + } +} diff --git a/infobip-testcontainers-test-common/src/main/java/com/infobip/testcontainers/TestBase.java b/infobip-testcontainers-test-common/src/main/java/com/infobip/testcontainers/TestBase.java new file mode 100644 index 0000000..f0bf72f --- /dev/null +++ b/infobip-testcontainers-test-common/src/main/java/com/infobip/testcontainers/TestBase.java @@ -0,0 +1,10 @@ +package com.infobip.testcontainers; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestConstructor; + +@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) +@SpringBootTest(classes = Main.class) +public class TestBase { + +} diff --git a/pom.xml b/pom.xml index b4fbb71..b9e198f 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ com.infobip infobip-testcontainers-spring-boot-starter - 4.1.1-SNAPSHOT + 4.2.0-SNAPSHOT pom Infobip TestContainers Spring Boot Starter @@ -38,9 +38,10 @@ infobip-postgresql-testcontainers-spring-boot-starter infobip-kafka-testcontainers-spring-boot-starter infobip-redis-testcontainers-spring-boot-starter - infobip-testcontainers-common infobip-rabbitmq-testcontainers-spring-boot-starter infobip-clickhouse-testcontainers-spring-boot-starter + infobip-testcontainers-common + infobip-testcontainers-test-common @@ -84,7 +85,7 @@ - 3.1.0 + 3.1.2 1.18.3 @@ -92,10 +93,10 @@ 3.8.1 4.3.0 0.8.10 - 3.0.1 - 3.1.1 - 3.1.0 - 3.1.0 + 3.1.0 + 3.3.0 + 3.1.2 + 3.1.2 UTF-8 @@ -125,19 +126,6 @@ org.springframework.boot spring-boot-autoconfigure - - - - org.springframework.boot - spring-boot-starter-test - test - - - - org.projectlombok - lombok - test -