├── profile.png ├── infobip-rabbitmq-testcontainers-spring-boot-starter ├── src │ ├── test │ │ ├── resources │ │ │ ├── application-reusable.yml │ │ │ ├── application-test.yml │ │ │ └── application-static-port.yml │ │ └── java │ │ │ └── com │ │ │ └── infobip │ │ │ └── testcontainers │ │ │ └── spring │ │ │ └── rabbit │ │ │ ├── RabbitContainerInitializerWithReusableTest.java │ │ │ ├── RabbitContainerInitializerTest.java │ │ │ └── RabbitContainerInitializerWithStaticPortTest.java │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── spring.factories │ │ └── java │ │ └── com │ │ └── infobip │ │ └── testcontainers │ │ └── spring │ │ └── rabbit │ │ ├── RabbitContainerWrapper.java │ │ └── RabbitContainerInitializer.java └── pom.xml ├── infobip-mysql-testcontainers-spring-boot-starter ├── src │ ├── test │ │ ├── resources │ │ │ ├── application-reusable.yaml │ │ │ ├── application-static-port.yaml │ │ │ ├── application-init-script.yaml │ │ │ ├── application-test.yaml │ │ │ └── db │ │ │ │ └── init-script.sql │ │ └── java │ │ │ └── com │ │ │ └── infobip │ │ │ └── testcontainers │ │ │ └── spring │ │ │ └── mysql │ │ │ ├── MySQLContainerInitializerWithReusableTest.java │ │ │ ├── MySQLContainerInitializerWithInitScriptTest.java │ │ │ ├── MySQLContainerInitializerWithStaticPortTest.java │ │ │ └── MySQLContainerInitializerTest.java │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── spring.factories │ │ └── java │ │ └── com │ │ └── infobip │ │ └── testcontainers │ │ └── spring │ │ └── mysql │ │ ├── MySQLContainerWrapper.java │ │ └── MySQLContainerInitializer.java └── pom.xml ├── infobip-redis-testcontainers-spring-boot-starter ├── src │ ├── test │ │ ├── resources │ │ │ ├── application-reusable.yaml │ │ │ ├── application-test.yaml │ │ │ └── application-static-port.yaml │ │ └── java │ │ │ └── com │ │ │ └── infobip │ │ │ └── testcontainers │ │ │ └── spring │ │ │ └── redis │ │ │ ├── RedisContainerInitializerWithReusableTest.java │ │ │ ├── RedisContainerInitializerTest.java │ │ │ └── RedisContainerInitializerWithStaticPortTest.java │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── spring.factories │ │ └── java │ │ └── com │ │ └── infobip │ │ └── testcontainers │ │ └── spring │ │ └── redis │ │ ├── RedisContainerWrapper.java │ │ └── RedisContainerInitializer.java └── pom.xml ├── .gitignore ├── infobip-mssql-testcontainers-spring-boot-starter ├── src │ ├── test │ │ ├── resources │ │ │ ├── application-jtds.yaml │ │ │ ├── application-reusable.yaml │ │ │ ├── application-init-script.yaml │ │ │ ├── db │ │ │ │ └── init-script.sql │ │ │ ├── application-static-port.yaml │ │ │ └── application-microsoft-driver.yaml │ │ └── java │ │ │ └── com │ │ │ └── infobip │ │ │ └── testcontainers │ │ │ └── spring │ │ │ └── mssql │ │ │ ├── MSSQLServerContainerInitializerWithReusableTest.java │ │ │ ├── MSSQLServerContainerInitializerWithJtdsDriverTest.java │ │ │ ├── MSSQLServerContainerInitializerWithInitScriptTest.java │ │ │ ├── MSSQLServerContainerInitializerWithStaticPortTest.java │ │ │ └── MSSQLServerContainerInitializerWithMicrosoftDriverTest.java │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── spring.factories │ │ └── java │ │ └── com │ │ └── infobip │ │ └── testcontainers │ │ └── spring │ │ └── mssql │ │ ├── MSSQLServerContainerWrapper.java │ │ ├── DatabaseCreator.java │ │ └── MSSQLServerContainerInitializer.java └── pom.xml ├── infobip-postgresql-testcontainers-spring-boot-starter ├── src │ ├── test │ │ ├── resources │ │ │ ├── application-test.yaml │ │ │ ├── application-reusable.yaml │ │ │ ├── application-static-port.yaml │ │ │ ├── db │ │ │ │ └── init-script.sql │ │ │ └── application-init-script.yaml │ │ └── java │ │ │ └── com │ │ │ └── infobip │ │ │ └── testcontainers │ │ │ └── spring │ │ │ └── postgresql │ │ │ ├── PostgreSQLContainerInitializerWithReusableTest.java │ │ │ ├── PostgreSQLContainerInitializerTest.java │ │ │ ├── PostgreSQLContainerInitializerWithInitScriptTest.java │ │ │ └── PostgreSQLContainerInitializerWithStaticPortTest.java │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── spring.factories │ │ └── java │ │ └── com │ │ └── infobip │ │ └── testcontainers │ │ └── spring │ │ └── postgresql │ │ ├── PostgreSQLContainerWrapper.java │ │ └── PostgreSQLContainerInitializer.java └── pom.xml ├── infobip-clickhouse-testcontainers-spring-boot-starter ├── src │ ├── test │ │ ├── resources │ │ │ ├── db │ │ │ │ └── init-script.sql │ │ │ ├── application-reusable.yaml │ │ │ ├── application-test.yaml │ │ │ ├── application-static-port.yaml │ │ │ └── application-init-script.yaml │ │ └── java │ │ │ └── com │ │ │ └── infobip │ │ │ └── testcontainers │ │ │ └── spring │ │ │ └── clickhouse │ │ │ ├── DataSourceConfig.java │ │ │ ├── ClickhouseContainerInitializerWithInitScriptTest.java │ │ │ ├── ClickhouseContainerInitializerTest.java │ │ │ ├── ClickhouseContainerInitializerWithReusableTest.java │ │ │ └── ClickhouseContainerInitializerWithStaticPortTest.java │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── spring.factories │ │ └── java │ │ └── com │ │ └── infobip │ │ └── testcontainers │ │ └── spring │ │ └── clickhouse │ │ ├── ClickhouseContainerWrapper.java │ │ └── ClickhouseContainerInitializer.java └── pom.xml ├── infobip-kafka-testcontainers-spring-boot-starter ├── src │ ├── test │ │ ├── resources │ │ │ ├── application-reusable.yaml │ │ │ ├── application-test.yaml │ │ │ └── application-static-port.yaml │ │ └── java │ │ │ └── com │ │ │ └── infobip │ │ │ └── testcontainers │ │ │ └── spring │ │ │ └── kafka │ │ │ ├── Listener.java │ │ │ ├── KafkaContainerInitializerWithReusableTest.java │ │ │ ├── KafkaContainerInitializerTest.java │ │ │ └── KafkaContainerInitializerWithStaticPortTest.java │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── spring.factories │ │ └── java │ │ └── com │ │ └── infobip │ │ └── testcontainers │ │ └── spring │ │ └── kafka │ │ ├── KafkaContainerWrapper.java │ │ └── KafkaContainerInitializer.java └── pom.xml ├── infobip-testcontainers-test-common ├── src │ └── main │ │ └── java │ │ └── com │ │ └── infobip │ │ └── testcontainers │ │ ├── TestBase.java │ │ ├── Main.java │ │ └── ReusableTestBase.java └── pom.xml ├── infobip-testcontainers-common ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── infobip │ └── testcontainers │ └── InitializerBase.java ├── .github └── workflows │ └── maven.yml ├── CHANGELOG.md ├── infobip-testcontainers-bom └── pom.xml ├── pom.xml ├── LICENSE └── README.md /profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infobip/infobip-testcontainers-spring-boot-starter/HEAD/profile.png -------------------------------------------------------------------------------- /infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yml: -------------------------------------------------------------------------------- 1 | testcontainers.rabbit.docker.image: rabbitmq:3.6.14-alpine -------------------------------------------------------------------------------- /infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/resources/application-test.yml: -------------------------------------------------------------------------------- 1 | testcontainers.rabbit.docker.image: rabbitmq:3.6.14-alpine 2 | -------------------------------------------------------------------------------- /infobip-mysql-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:mysql://:/TestDatabase -------------------------------------------------------------------------------- /infobip-redis-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | data: 3 | redis: 4 | url: redis://: -------------------------------------------------------------------------------- /infobip-redis-testcontainers-spring-boot-starter/src/test/resources/application-test.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | data: 3 | redis: 4 | url: redis://: 5 | -------------------------------------------------------------------------------- /infobip-redis-testcontainers-spring-boot-starter/src/test/resources/application-static-port.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | data: 3 | redis: 4 | url: redis://:5006 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .project 3 | .settings/* 4 | **/target/* 5 | *.iml 6 | .idea 7 | /.settings 8 | /target 9 | **/*.class 10 | /bin 11 | **./.DS_Store 12 | .java-version -------------------------------------------------------------------------------- /infobip-mssql-testcontainers-spring-boot-starter/src/test/resources/application-jtds.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:jtds:sqlserver://:/JtdsTestDatabase 4 | -------------------------------------------------------------------------------- /infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/resources/application-static-port.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | rabbitmq: 3 | port: 5005 4 | 5 | testcontainers.rabbit.docker.image: rabbitmq:3.6.14-alpine 6 | -------------------------------------------------------------------------------- /infobip-mysql-testcontainers-spring-boot-starter/src/test/resources/application-static-port.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:mysql://:5005/TestDatabase 4 | username: test 5 | password: test -------------------------------------------------------------------------------- /infobip-postgresql-testcontainers-spring-boot-starter/src/test/resources/application-test.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:postgresql://:/TestDatabase 4 | username: test 5 | password: test -------------------------------------------------------------------------------- /infobip-mssql-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:sqlserver://:;database=MicrosoftDriverTestDatabase;trustServerCertificate=true -------------------------------------------------------------------------------- /infobip-postgresql-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:postgresql://:/TestDatabase 4 | username: test 5 | password: test -------------------------------------------------------------------------------- /infobip-postgresql-testcontainers-spring-boot-starter/src/test/resources/application-static-port.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:postgresql://:5004/TestDatabase 4 | username: test 5 | password: test -------------------------------------------------------------------------------- /infobip-mysql-testcontainers-spring-boot-starter/src/test/resources/application-init-script.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:mysql://:/TestDatabase 4 | 5 | testcontainers: 6 | mysql: 7 | init-script: db/init-script.sql -------------------------------------------------------------------------------- /infobip-postgresql-testcontainers-spring-boot-starter/src/test/resources/db/init-script.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE test_table( 2 | id serial PRIMARY KEY, 3 | name VARCHAR(4) NOT NULL 4 | ); 5 | 6 | INSERT INTO test_table(id, name) 7 | VALUES (1, 'Test'); 8 | -------------------------------------------------------------------------------- /infobip-clickhouse-testcontainers-spring-boot-starter/src/test/resources/db/init-script.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE test_table 2 | ( 3 | id Int32, 4 | name String 5 | ) ENGINE = MergeTree() ORDER BY id; 6 | 7 | INSERT INTO test_table (id, name) 8 | VALUES (1, 'Test'); -------------------------------------------------------------------------------- /infobip-mssql-testcontainers-spring-boot-starter/src/test/resources/application-init-script.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:jtds:sqlserver://:/JtdsTestDatabase 4 | 5 | testcontainers: 6 | mssql: 7 | init-script: db/init-script.sql -------------------------------------------------------------------------------- /infobip-kafka-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | kafka: 3 | consumer: 4 | groupId: test 5 | autoOffsetReset: earliest 6 | bootstrap-servers: : 7 | 8 | testcontainers.kafka.topics: test-topic:1:1 -------------------------------------------------------------------------------- /infobip-kafka-testcontainers-spring-boot-starter/src/test/resources/application-test.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | kafka: 3 | consumer: 4 | groupId: test 5 | autoOffsetReset: earliest 6 | bootstrap-servers: : 7 | 8 | testcontainers.kafka.topics: test-topic:1:1 9 | -------------------------------------------------------------------------------- /infobip-clickhouse-testcontainers-spring-boot-starter/src/test/resources/application-reusable.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | clickhouse: 4 | jdbc-url: jdbc:clickhouse://: 5 | 6 | testcontainers: 7 | clickhouse: 8 | custom-path: "spring.datasource.clickhouse" -------------------------------------------------------------------------------- /infobip-clickhouse-testcontainers-spring-boot-starter/src/test/resources/application-test.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | clickhouse: 4 | jdbc-url: jdbc:clickhouse://: 5 | 6 | testcontainers: 7 | clickhouse: 8 | custom-path: "spring.datasource.clickhouse" 9 | -------------------------------------------------------------------------------- /infobip-kafka-testcontainers-spring-boot-starter/src/test/resources/application-static-port.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | kafka: 3 | consumer: 4 | groupId: static 5 | autoOffsetReset: earliest 6 | bootstrap-servers: :5002 7 | 8 | testcontainers.kafka.topics: test-topic:1:1 9 | -------------------------------------------------------------------------------- /infobip-clickhouse-testcontainers-spring-boot-starter/src/test/resources/application-static-port.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | clickhouse: 4 | jdbc-url: jdbc:clickhouse://:5001 5 | 6 | testcontainers: 7 | clickhouse: 8 | custom-path: "spring.datasource.clickhouse" 9 | -------------------------------------------------------------------------------- /infobip-mysql-testcontainers-spring-boot-starter/src/test/resources/application-test.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:mysql://:/TestDatabase 4 | r2dbc: 5 | url: r2dbc:pool:mysql://:/TestDatabase 6 | flyway: 7 | url: jdbc:mysql://:/TestDatabase -------------------------------------------------------------------------------- /infobip-mysql-testcontainers-spring-boot-starter/src/test/resources/db/init-script.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS test_table; 2 | 3 | CREATE TABLE test_table( 4 | id serial PRIMARY KEY, 5 | name VARCHAR(4) NOT NULL 6 | ); 7 | 8 | INSERT INTO test_table(id, name) 9 | VALUES (1, 'Test'); 10 | -------------------------------------------------------------------------------- /infobip-postgresql-testcontainers-spring-boot-starter/src/test/resources/application-init-script.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:postgresql://:/ 4 | username: test 5 | password: test 6 | 7 | testcontainers: 8 | postgresql: 9 | init-script: db/init-script.sql -------------------------------------------------------------------------------- /infobip-kafka-testcontainers-spring-boot-starter/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.context.ApplicationContextInitializer=com.infobip.testcontainers.spring.kafka.KafkaContainerInitializer 2 | org.springframework.context.ApplicationListener=com.infobip.testcontainers.spring.kafka.KafkaContainerInitializer -------------------------------------------------------------------------------- /infobip-mysql-testcontainers-spring-boot-starter/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.context.ApplicationContextInitializer=com.infobip.testcontainers.spring.mysql.MySQLContainerInitializer 2 | org.springframework.context.ApplicationListener=com.infobip.testcontainers.spring.mysql.MySQLContainerInitializer -------------------------------------------------------------------------------- /infobip-redis-testcontainers-spring-boot-starter/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.context.ApplicationContextInitializer=com.infobip.testcontainers.spring.redis.RedisContainerInitializer 2 | org.springframework.context.ApplicationListener=com.infobip.testcontainers.spring.redis.RedisContainerInitializer -------------------------------------------------------------------------------- /infobip-rabbitmq-testcontainers-spring-boot-starter/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.context.ApplicationContextInitializer=com.infobip.testcontainers.spring.rabbit.RabbitContainerInitializer 2 | org.springframework.context.ApplicationListener=com.infobip.testcontainers.spring.rabbit.RabbitContainerInitializer -------------------------------------------------------------------------------- /infobip-mssql-testcontainers-spring-boot-starter/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.context.ApplicationContextInitializer=com.infobip.testcontainers.spring.mssql.MSSQLServerContainerInitializer 2 | org.springframework.context.ApplicationListener=com.infobip.testcontainers.spring.mssql.MSSQLServerContainerInitializer -------------------------------------------------------------------------------- /infobip-clickhouse-testcontainers-spring-boot-starter/src/test/resources/application-init-script.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | clickhouse: 4 | jdbc-url: jdbc:clickhouse://: 5 | 6 | testcontainers: 7 | clickhouse: 8 | init-script: db/init-script.sql 9 | custom-path: "spring.datasource.clickhouse" 10 | -------------------------------------------------------------------------------- /infobip-mssql-testcontainers-spring-boot-starter/src/test/resources/db/init-script.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE JtdsTestDatabase; 2 | 3 | USE JtdsTestDatabase; 4 | 5 | CREATE TABLE test_table ( 6 | id INT PRIMARY KEY IDENTITY(1,1), 7 | name VARCHAR(4) NOT NULL 8 | ); 9 | 10 | INSERT INTO test_table (name) 11 | VALUES ('Test'); 12 | -------------------------------------------------------------------------------- /infobip-postgresql-testcontainers-spring-boot-starter/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.context.ApplicationContextInitializer=com.infobip.testcontainers.spring.postgresql.PostgreSQLContainerInitializer 2 | org.springframework.context.ApplicationListener=com.infobip.testcontainers.spring.postgresql.PostgreSQLContainerInitializer -------------------------------------------------------------------------------- /infobip-clickhouse-testcontainers-spring-boot-starter/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.context.ApplicationContextInitializer=com.infobip.testcontainers.spring.clickhouse.ClickhouseContainerInitializer 2 | org.springframework.context.ApplicationListener=com.infobip.testcontainers.spring.clickhouse.ClickhouseContainerInitializer 3 | -------------------------------------------------------------------------------- /infobip-testcontainers-test-common/src/main/java/com/infobip/testcontainers/TestBase.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers; 2 | 3 | import org.springframework.boot.test.context.SpringBootTest; 4 | import org.springframework.test.context.TestConstructor; 5 | 6 | @TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) 7 | @SpringBootTest(classes = Main.class) 8 | public class TestBase { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /infobip-mssql-testcontainers-spring-boot-starter/src/test/resources/application-static-port.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:sqlserver://:5003;database=MicrosoftDriverTestDatabase;trustServerCertificate=true 4 | r2dbc: 5 | url: r2dbc:pool:mssql://:5003/InfobipSpringDataJdbcQuerydslTest;trustServerCertificate=true 6 | flyway: 7 | url: jdbc:sqlserver://:5003;database=MicrosoftDriverTestDatabase;trustServerCertificate=true 8 | -------------------------------------------------------------------------------- /infobip-testcontainers-test-common/src/main/java/com/infobip/testcontainers/Main.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers; 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication; 4 | import org.springframework.boot.builder.SpringApplicationBuilder; 5 | 6 | @SpringBootApplication 7 | public class Main { 8 | 9 | public static void main(String[] args) { 10 | new SpringApplicationBuilder(Main.class).run(args); 11 | } 12 | 13 | } -------------------------------------------------------------------------------- /infobip-mssql-testcontainers-spring-boot-starter/src/test/resources/application-microsoft-driver.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:sqlserver://:;database=MicrosoftDriverTestDatabase;trustServerCertificate=true 4 | r2dbc: 5 | url: r2dbc:pool:mssql://:/InfobipSpringDataJdbcQuerydslTest;trustServerCertificate=true 6 | flyway: 7 | url: jdbc:sqlserver://:;database=MicrosoftDriverTestDatabase;trustServerCertificate=true 8 | -------------------------------------------------------------------------------- /infobip-kafka-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/kafka/KafkaContainerWrapper.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.kafka; 2 | 3 | import org.testcontainers.containers.KafkaContainer; 4 | 5 | public class KafkaContainerWrapper extends KafkaContainer { 6 | 7 | public KafkaContainerWrapper() { 8 | } 9 | 10 | public KafkaContainerWrapper(String confluentPlatformVersion) { 11 | super(confluentPlatformVersion); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /infobip-clickhouse-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerWrapper.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.clickhouse; 2 | 3 | import org.testcontainers.containers.ClickHouseContainer; 4 | 5 | public class ClickhouseContainerWrapper extends ClickHouseContainer { 6 | 7 | public ClickhouseContainerWrapper() { 8 | } 9 | 10 | public ClickhouseContainerWrapper(String image) { 11 | super(image); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /infobip-rabbitmq-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/rabbit/RabbitContainerWrapper.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.rabbit; 2 | 3 | import org.testcontainers.containers.GenericContainer; 4 | 5 | public class RabbitContainerWrapper extends GenericContainer { 6 | 7 | public static final int PORT = 5672; 8 | 9 | public RabbitContainerWrapper(String image) { 10 | super(image); 11 | withExposedPorts(PORT); 12 | } 13 | } -------------------------------------------------------------------------------- /infobip-mysql-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/mysql/MySQLContainerWrapper.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.mysql; 2 | 3 | public class MySQLContainerWrapper extends org.testcontainers.containers.MySQLContainer { 4 | 5 | public MySQLContainerWrapper(String databaseName) { 6 | this(databaseName, IMAGE + ":" + DEFAULT_TAG); 7 | } 8 | 9 | public MySQLContainerWrapper(String databaseName, String dockerImageName) { 10 | super(dockerImageName); 11 | withDatabaseName(databaseName); 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /infobip-redis-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/redis/RedisContainerWrapper.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.redis; 2 | 3 | import org.testcontainers.containers.GenericContainer; 4 | 5 | public class RedisContainerWrapper extends GenericContainer { 6 | 7 | public static final int PORT = 6379; 8 | 9 | public RedisContainerWrapper() { 10 | this("redis:6.2.6-alpine"); 11 | } 12 | 13 | public RedisContainerWrapper(String dockerImageName) { 14 | super(dockerImageName); 15 | withExposedPorts(PORT); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /infobip-postgresql-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerWrapper.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.postgresql; 2 | 3 | public class PostgreSQLContainerWrapper 4 | extends org.testcontainers.containers.PostgreSQLContainer { 5 | 6 | public PostgreSQLContainerWrapper(String databaseName) { 7 | this(databaseName, IMAGE + ":" + DEFAULT_TAG); 8 | } 9 | 10 | public PostgreSQLContainerWrapper(String databaseName, String dockerImageName) { 11 | super(dockerImageName); 12 | withDatabaseName(databaseName); 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /infobip-testcontainers-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | 5 | com.infobip 6 | infobip-testcontainers-spring-boot-starter 7 | 5.0.1-SNAPSHOT 8 | 9 | 10 | infobip-testcontainers-common 11 | infobip-testcontainers-common 12 | 13 | 14 | 15 | org.testcontainers 16 | testcontainers-junit-jupiter 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /infobip-kafka-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/kafka/Listener.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.kafka; 2 | 3 | import java.util.concurrent.atomic.AtomicReference; 4 | 5 | import lombok.AllArgsConstructor; 6 | import org.springframework.kafka.annotation.KafkaListener; 7 | import org.springframework.messaging.handler.annotation.Payload; 8 | import org.springframework.stereotype.Component; 9 | 10 | @AllArgsConstructor 11 | @Component 12 | class Listener { 13 | 14 | public static final String TOPIC = "test-topic"; 15 | 16 | private final AtomicReference value = new AtomicReference<>(); 17 | 18 | @KafkaListener(topics = TOPIC) 19 | public void handle(@Payload String value) { 20 | this.value.set(value); 21 | } 22 | 23 | String getValue() { 24 | return value.get(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /infobip-mssql-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerWrapper.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.mssql; 2 | 3 | import org.testcontainers.utility.DockerImageName; 4 | 5 | public class MSSQLServerContainerWrapper 6 | extends org.testcontainers.containers.MSSQLServerContainer { 7 | 8 | @Deprecated 9 | public MSSQLServerContainerWrapper() { 10 | super("mcr.microsoft.com/mssql/server:2019-latest"); 11 | } 12 | 13 | public MSSQLServerContainerWrapper(String image) { 14 | super(image); 15 | } 16 | 17 | public MSSQLServerContainerWrapper(DockerImageName dockerImageName) { 18 | super(dockerImageName); 19 | } 20 | 21 | @Override 22 | protected void configure() { 23 | addEnv("ACCEPT_EULA", "Y"); 24 | addEnv("SA_PASSWORD", getPassword()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/DataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.clickhouse; 2 | 3 | import javax.sql.DataSource; 4 | 5 | import org.springframework.boot.jdbc.DataSourceBuilder; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.core.env.Environment; 9 | import ru.yandex.clickhouse.ClickHouseDriver; 10 | 11 | @Configuration 12 | public class DataSourceConfig { 13 | 14 | static final String CLICKHOUSE_URL_PROPERTY_NAME = "spring.datasource.clickhouse.jdbc-url"; 15 | 16 | @Bean 17 | public DataSource getDataSource(Environment environment) { 18 | return DataSourceBuilder.create() 19 | .driverClassName(ClickHouseDriver.class.getName()) 20 | .url(environment.getProperty(CLICKHOUSE_URL_PROPERTY_NAME)) 21 | .build(); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /infobip-redis-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/redis/RedisContainerInitializerWithReusableTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.redis; 2 | 3 | import com.infobip.testcontainers.ReusableTestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.test.context.ActiveProfiles; 7 | 8 | import static org.assertj.core.api.BDDAssertions.then; 9 | 10 | @AllArgsConstructor 11 | @ActiveProfiles("reusable") 12 | class RedisContainerInitializerWithReusableTest extends ReusableTestBase { 13 | 14 | private final RedisContainerWrapper wrapper; 15 | private final int port = RedisContainerWrapper.PORT; 16 | 17 | @Test 18 | void shouldReuseContainer() { 19 | // given 20 | var givenContainer = new RedisContainerWrapper(); 21 | givenContainer.withReuse(true); 22 | 23 | // when 24 | givenContainer.start(); 25 | 26 | // then 27 | then(givenContainer.getMappedPort(port)).isEqualTo(wrapper.getMappedPort(port)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/rabbit/RabbitContainerInitializerWithReusableTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.rabbit; 2 | 3 | import com.infobip.testcontainers.ReusableTestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.test.context.ActiveProfiles; 7 | 8 | import static org.assertj.core.api.BDDAssertions.then; 9 | 10 | @AllArgsConstructor 11 | @ActiveProfiles("reusable") 12 | class RabbitContainerInitializerWithReusableTest extends ReusableTestBase { 13 | 14 | private final RabbitContainerWrapper wrapper; 15 | private final int port = RabbitContainerWrapper.PORT; 16 | 17 | @Test 18 | void shouldReuseContainer() { 19 | // given 20 | var givenContainer = new RabbitContainerWrapper("rabbitmq:3.6.14-alpine"); 21 | givenContainer.withReuse(true); 22 | 23 | // when 24 | givenContainer.start(); 25 | 26 | // then 27 | then(givenContainer.getMappedPort(port)).isEqualTo(wrapper.getMappedPort(port)); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializerWithInitScriptTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.clickhouse; 2 | 3 | import com.infobip.testcontainers.TestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.jdbc.core.JdbcTemplate; 7 | import org.springframework.test.context.ActiveProfiles; 8 | 9 | import javax.sql.DataSource; 10 | 11 | import static org.assertj.core.api.BDDAssertions.then; 12 | 13 | @AllArgsConstructor 14 | @ActiveProfiles("init-script") 15 | class ClickhouseContainerInitializerWithInitScriptTest extends TestBase { 16 | 17 | private DataSource dataSource; 18 | 19 | @Test 20 | void shouldCreateContainer() { 21 | //given 22 | JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); 23 | 24 | //when 25 | String result = jdbcTemplate.queryForObject("SELECT name FROM test_table WHERE id = 1", String.class); 26 | 27 | //then 28 | then(result).isEqualTo("Test"); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /infobip-kafka-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/kafka/KafkaContainerInitializerWithReusableTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.kafka; 2 | 3 | import com.infobip.testcontainers.ReusableTestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.test.context.ActiveProfiles; 7 | import org.testcontainers.containers.KafkaContainer; 8 | 9 | import static org.assertj.core.api.BDDAssertions.then; 10 | 11 | @AllArgsConstructor 12 | @ActiveProfiles("reusable") 13 | class KafkaContainerInitializerWithReusableTest extends ReusableTestBase { 14 | 15 | private final KafkaContainerWrapper wrapper; 16 | private final int port = KafkaContainer.KAFKA_PORT; 17 | 18 | @Test 19 | void shouldReuseContainer() { 20 | // given 21 | var givenContainer = new KafkaContainerWrapper(); 22 | givenContainer.withReuse(true); 23 | 24 | // when 25 | givenContainer.start(); 26 | 27 | // then 28 | then(givenContainer.getMappedPort(port)).isEqualTo(wrapper.getMappedPort(port)); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializerTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.clickhouse; 2 | 3 | import static org.assertj.core.api.BDDAssertions.then; 4 | 5 | import javax.sql.DataSource; 6 | 7 | import com.infobip.testcontainers.TestBase; 8 | import lombok.AllArgsConstructor; 9 | import org.junit.jupiter.api.Test; 10 | import org.springframework.boot.test.context.SpringBootTest; 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | import org.springframework.test.context.ActiveProfiles; 13 | import org.springframework.test.context.TestConstructor; 14 | 15 | @AllArgsConstructor 16 | @ActiveProfiles("test") 17 | class ClickhouseContainerInitializerTest extends TestBase { 18 | 19 | private DataSource dataSource; 20 | 21 | @Test 22 | void shouldCreateContainer() { 23 | //given 24 | JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); 25 | 26 | //when 27 | String result = jdbcTemplate.queryForObject("SELECT 1", String.class); 28 | 29 | //then 30 | then(result).isEqualTo("1"); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /infobip-mysql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mysql/MySQLContainerInitializerWithReusableTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.mysql; 2 | 3 | import com.infobip.testcontainers.ReusableTestBase; 4 | import com.infobip.testcontainers.spring.mysql.MySQLContainerWrapper; 5 | import lombok.AllArgsConstructor; 6 | import org.junit.jupiter.api.Test; 7 | import org.springframework.test.context.ActiveProfiles; 8 | 9 | import static org.assertj.core.api.BDDAssertions.then; 10 | 11 | @AllArgsConstructor 12 | @ActiveProfiles("reusable") 13 | class MySQLContainerInitializerWithReusableTest extends ReusableTestBase { 14 | 15 | private final MySQLContainerWrapper wrapper; 16 | private final int port = MySQLContainerWrapper.MYSQL_PORT; 17 | 18 | @Test 19 | void shouldReuseContainer() { 20 | // given 21 | var givenContainer = new MySQLContainerWrapper("TestDatabase"); 22 | givenContainer.withReuse(true); 23 | 24 | // when 25 | givenContainer.start(); 26 | 27 | // then 28 | then(givenContainer.getMappedPort(port)).isEqualTo(wrapper.getMappedPort(port)); 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithReusableTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.mssql; 2 | 3 | import com.infobip.testcontainers.ReusableTestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.test.context.ActiveProfiles; 7 | import org.testcontainers.containers.MSSQLServerContainer; 8 | 9 | import static org.assertj.core.api.BDDAssertions.then; 10 | 11 | @AllArgsConstructor 12 | @ActiveProfiles("reusable") 13 | class MSSQLServerContainerInitializerWithReusableTest extends ReusableTestBase { 14 | 15 | private final MSSQLServerContainerWrapper wrapper; 16 | private final int port = MSSQLServerContainer.MS_SQL_SERVER_PORT; 17 | 18 | @Test 19 | void shouldReuseContainer() { 20 | // given 21 | var givenContainer = new MSSQLServerContainerWrapper(); 22 | givenContainer.withReuse(true); 23 | 24 | // when 25 | givenContainer.start(); 26 | 27 | // then 28 | then(givenContainer.getMappedPort(port)).isEqualTo(wrapper.getMappedPort(port)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializerWithReusableTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.clickhouse; 2 | 3 | import com.infobip.testcontainers.ReusableTestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.test.context.ActiveProfiles; 7 | import org.testcontainers.containers.ClickHouseContainer; 8 | 9 | import static org.assertj.core.api.BDDAssertions.then; 10 | 11 | @AllArgsConstructor 12 | @ActiveProfiles("reusable") 13 | class ClickhouseContainerInitializerWithReusableTest extends ReusableTestBase { 14 | 15 | private final ClickhouseContainerWrapper wrapper; 16 | private final int port = ClickHouseContainer.NATIVE_PORT; 17 | 18 | @Test 19 | void shouldReuseContainer() { 20 | // given 21 | var givenContainer = new ClickhouseContainerWrapper(); 22 | givenContainer.withReuse(true); 23 | 24 | // when 25 | givenContainer.start(); 26 | 27 | // then 28 | then(givenContainer.getMappedPort(port)).isEqualTo(wrapper.getMappedPort(port)); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializerWithReusableTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.postgresql; 2 | 3 | import com.infobip.testcontainers.ReusableTestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.test.context.ActiveProfiles; 7 | import org.testcontainers.containers.PostgreSQLContainer; 8 | 9 | import static org.assertj.core.api.BDDAssertions.then; 10 | 11 | @AllArgsConstructor 12 | @ActiveProfiles("reusable") 13 | class PostgreSQLContainerInitializerWithReusableTest extends ReusableTestBase { 14 | 15 | private final PostgreSQLContainerWrapper wrapper; 16 | private final int port = PostgreSQLContainer.POSTGRESQL_PORT; 17 | 18 | @Test 19 | void shouldReuseContainer() { 20 | // given 21 | var givenContainer = new PostgreSQLContainerWrapper("TestDatabase"); 22 | givenContainer.withReuse(true); 23 | 24 | // when 25 | givenContainer.start(); 26 | 27 | // then 28 | then(givenContainer.getMappedPort(port)).isEqualTo(wrapper.getMappedPort(port)); 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/rabbit/RabbitContainerInitializerTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.rabbit; 2 | 3 | import com.infobip.testcontainers.TestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.assertj.core.api.BDDAssertions; 6 | import org.junit.jupiter.api.DisplayName; 7 | import org.junit.jupiter.api.Test; 8 | import org.springframework.amqp.rabbit.core.RabbitTemplate; 9 | import org.springframework.test.context.ActiveProfiles; 10 | 11 | import static org.assertj.core.api.BDDAssertions.then; 12 | 13 | @AllArgsConstructor 14 | @ActiveProfiles("test") 15 | class RabbitContainerInitializerTest extends TestBase { 16 | 17 | private final RabbitTemplate rabbitTemplate; 18 | 19 | @Test 20 | @DisplayName("Should initialize rabbit container and send message to exchange") 21 | void shouldInitialize() { 22 | // given 23 | String givenMessage = "test"; 24 | 25 | // when 26 | Throwable actual = BDDAssertions.catchThrowable( 27 | () -> rabbitTemplate.convertAndSend("test.exchange", "test.key.bar", givenMessage)); 28 | 29 | // then 30 | then(actual).isNull(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /infobip-testcontainers-test-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | 5 | com.infobip 6 | infobip-testcontainers-spring-boot-starter 7 | 5.0.1-SNAPSHOT 8 | 9 | 10 | infobip-testcontainers-test-common 11 | infobip-testcontainers-test-common 12 | 13 | 14 | 15 | ${project.groupId} 16 | infobip-testcontainers-common 17 | ${project.version} 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-test 23 | 24 | 25 | 26 | org.projectlombok 27 | lombok 28 | 29 | 30 | -------------------------------------------------------------------------------- /infobip-redis-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/redis/RedisContainerInitializerTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.redis; 2 | 3 | import com.infobip.testcontainers.TestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.data.redis.core.RedisTemplate; 8 | import org.springframework.test.context.ActiveProfiles; 9 | import org.springframework.test.context.TestConstructor; 10 | 11 | import static org.assertj.core.api.BDDAssertions.then; 12 | 13 | @AllArgsConstructor 14 | @ActiveProfiles("test") 15 | class RedisContainerInitializerTest extends TestBase { 16 | 17 | private final RedisTemplate template; 18 | 19 | @Test 20 | void shouldCreateContainer() { 21 | 22 | // given 23 | String givenKey = "givenKey"; 24 | String givenHashKey = "givenHashKey"; 25 | String givenData = "givenData"; 26 | template.opsForHash().put(givenKey, givenHashKey, givenData); 27 | 28 | // when 29 | Object actual = template.opsForHash().get(givenKey, givenHashKey); 30 | 31 | // then 32 | then(actual).isEqualTo(givenData); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /infobip-rabbitmq-testcontainers-spring-boot-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | 5 | com.infobip 6 | infobip-testcontainers-spring-boot-starter 7 | 5.0.1-SNAPSHOT 8 | 9 | 10 | infobip-rabbitmq-testcontainers-spring-boot-starter 11 | infobip-rabbitmq-testcontainers-spring-boot-starter 12 | 13 | 14 | 15 | ${project.groupId} 16 | infobip-testcontainers-common 17 | ${project.version} 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-amqp 24 | 25 | 26 | 27 | 28 | com.infobip 29 | infobip-testcontainers-test-common 30 | test 31 | ${project.version} 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /infobip-redis-testcontainers-spring-boot-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | 5 | com.infobip 6 | infobip-testcontainers-spring-boot-starter 7 | 5.0.1-SNAPSHOT 8 | 9 | 10 | infobip-redis-testcontainers-spring-boot-starter 11 | infobip-redis-testcontainers-spring-boot-starter 12 | 13 | 14 | 15 | ${project.groupId} 16 | infobip-testcontainers-common 17 | ${project.version} 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-data-redis 24 | 25 | 26 | 27 | io.lettuce 28 | lettuce-core 29 | test 30 | 31 | 32 | 33 | 34 | com.infobip 35 | infobip-testcontainers-test-common 36 | test 37 | ${project.version} 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /infobip-redis-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/redis/RedisContainerInitializerWithStaticPortTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.redis; 2 | 3 | import com.infobip.testcontainers.TestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.boot.data.redis.autoconfigure.DataRedisProperties; 7 | import org.springframework.data.redis.core.RedisTemplate; 8 | import org.springframework.test.context.ActiveProfiles; 9 | 10 | import static org.assertj.core.api.BDDAssertions.then; 11 | 12 | @AllArgsConstructor 13 | @ActiveProfiles("static-port") 14 | class RedisContainerInitializerWithStaticPortTest extends TestBase { 15 | 16 | private final RedisTemplate template; 17 | private final DataRedisProperties redisProperties; 18 | 19 | @Test 20 | void shouldCreateContainer() { 21 | // given 22 | String givenKey = "givenKey"; 23 | String givenHashKey = "givenHashKey"; 24 | String givenData = "givenData"; 25 | template.opsForHash().put(givenKey, givenHashKey, givenData); 26 | 27 | // when 28 | Object actual = template.opsForHash().get(givenKey, givenHashKey); 29 | 30 | // then 31 | then(actual).isEqualTo(givenData); 32 | } 33 | 34 | @Test 35 | void shouldSetHostInProperties() { 36 | // then 37 | then(redisProperties.getUrl()).contains("localhost:5006"); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /infobip-clickhouse-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializerWithStaticPortTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.clickhouse; 2 | 3 | import com.infobip.testcontainers.TestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.core.env.Environment; 7 | import org.springframework.jdbc.core.JdbcTemplate; 8 | import org.springframework.test.context.ActiveProfiles; 9 | 10 | import javax.sql.DataSource; 11 | 12 | import static com.infobip.testcontainers.spring.clickhouse.DataSourceConfig.CLICKHOUSE_URL_PROPERTY_NAME; 13 | import static org.assertj.core.api.BDDAssertions.then; 14 | 15 | @AllArgsConstructor 16 | @ActiveProfiles("static-port") 17 | class ClickhouseContainerInitializerWithStaticPortTest extends TestBase { 18 | 19 | private Environment environment; 20 | private DataSource dataSource; 21 | 22 | @Test 23 | void shouldCreateContainerWithStaticPort() { 24 | //given 25 | JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); 26 | 27 | //when 28 | String result = jdbcTemplate.queryForObject("SELECT 1", String.class); 29 | 30 | //then 31 | then(result).isEqualTo("1"); 32 | } 33 | 34 | @Test 35 | void shouldResolveHostInUrl() { 36 | // then 37 | then(environment.getProperty(CLICKHOUSE_URL_PROPERTY_NAME)).isEqualTo("jdbc:clickhouse://localhost:5001"); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven 3 | 4 | name: maven 5 | 6 | on: [push, workflow_dispatch, pull_request] 7 | 8 | jobs: 9 | build: 10 | 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Set up JDK 17 16 | uses: actions/setup-java@v1 17 | with: 18 | java-version: 17 19 | - name: Cache local Maven repository 20 | uses: actions/cache@v4 21 | with: 22 | path: ~/.m2/repository 23 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} 24 | restore-keys: | 25 | ${{ runner.os }}-maven- 26 | - name: Build with Maven 27 | run: mvn -B package --file pom.xml 28 | - name: "Report: Coverage via coveralls.io" 29 | run: | 30 | export CI_BRANCH=${BRANCH_NAME_OR_REF#refs/heads/} 31 | export CI_PULL_REQUEST=$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH") 32 | mvn coveralls:report -DrepoToken=$COVERALLS_SECRET 33 | env: 34 | CI_NAME: github 35 | BRANCH_NAME_OR_REF: ${{ github.head_ref || github.ref }} 36 | CI_BUILD_NUMBER: ${{ github.run_id }} 37 | CI_BUILD_URL: https://github.com/${{ github.repository }}/commit/${{ github.event.after }}/checks 38 | COVERALLS_SECRET: ${{ secrets.GITHUB_TOKEN }} 39 | 40 | -------------------------------------------------------------------------------- /infobip-testcontainers-test-common/src/main/java/com/infobip/testcontainers/ReusableTestBase.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers; 2 | 3 | import org.junit.jupiter.api.AfterAll; 4 | import org.junit.jupiter.api.BeforeAll; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.TestConstructor; 7 | import org.testcontainers.utility.TestcontainersConfiguration; 8 | 9 | import java.io.File; 10 | 11 | @TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) 12 | @SpringBootTest(classes = Main.class) 13 | public class ReusableTestBase { 14 | 15 | private static final String HOME = System.getProperty("user.home"); 16 | private static final String FILENAME = ".testcontainers.properties"; 17 | private static final File FILE = new File(HOME, FILENAME); 18 | private static final File TEMP_FILE = new File(HOME, FILENAME + ".tmp"); 19 | 20 | @BeforeAll 21 | static void createTestcontainersPropertiesFile() { 22 | if (FILE.exists()) { 23 | FILE.renameTo(TEMP_FILE); 24 | } 25 | 26 | TestcontainersConfiguration.getInstance().updateUserConfig("testcontainers.reuse.enable", "true"); 27 | } 28 | 29 | @AfterAll 30 | static void cleanupTestcontainersPropertiesFile() { 31 | TestcontainersConfiguration.getInstance().updateUserConfig("testcontainers.reuse.enable", "false"); 32 | FILE.delete(); 33 | 34 | if (TEMP_FILE.exists()) { 35 | TEMP_FILE.renameTo(FILE); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /infobip-rabbitmq-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/rabbit/RabbitContainerInitializerWithStaticPortTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.rabbit; 2 | 3 | import com.infobip.testcontainers.TestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.assertj.core.api.BDDAssertions; 6 | import org.junit.jupiter.api.DisplayName; 7 | import org.junit.jupiter.api.Test; 8 | import org.springframework.amqp.rabbit.core.RabbitTemplate; 9 | import org.springframework.boot.amqp.autoconfigure.RabbitProperties; 10 | import org.springframework.test.context.ActiveProfiles; 11 | 12 | import static org.assertj.core.api.BDDAssertions.then; 13 | 14 | @AllArgsConstructor 15 | @ActiveProfiles("static-port") 16 | class RabbitContainerInitializerWithStaticPortTest extends TestBase { 17 | 18 | private final RabbitTemplate rabbitTemplate; 19 | private final RabbitProperties rabbitProperties; 20 | 21 | @Test 22 | @DisplayName("Should initialize rabbit container and send message to exchange") 23 | void shouldInitialize() { 24 | // given 25 | String givenMessage = "test"; 26 | 27 | // when 28 | Throwable actual = BDDAssertions.catchThrowable( 29 | () -> rabbitTemplate.convertAndSend("test.exchange", "test.key.bar", givenMessage)); 30 | 31 | // then 32 | then(actual).isNull(); 33 | } 34 | 35 | @Test 36 | void shouldUseStaticPort() { 37 | // then 38 | then(rabbitProperties.getAddresses()).contains("localhost:5005"); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /infobip-postgresql-testcontainers-spring-boot-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | 5 | com.infobip 6 | infobip-testcontainers-spring-boot-starter 7 | 5.0.1-SNAPSHOT 8 | 9 | 10 | infobip-postgresql-testcontainers-spring-boot-starter 11 | infobip-postgresql-testcontainers-spring-boot-starter 12 | 13 | 14 | 15 | ${project.groupId} 16 | infobip-testcontainers-common 17 | ${project.version} 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-jdbc 24 | 25 | 26 | 27 | org.postgresql 28 | postgresql 29 | 30 | 31 | 32 | org.testcontainers 33 | testcontainers-postgresql 34 | 35 | 36 | 37 | 38 | com.infobip 39 | infobip-testcontainers-test-common 40 | test 41 | ${project.version} 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /infobip-redis-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/redis/RedisContainerInitializer.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.redis; 2 | 3 | import java.util.Objects; 4 | import java.util.Optional; 5 | 6 | import com.infobip.testcontainers.InitializerBase; 7 | import org.springframework.boot.test.util.TestPropertyValues; 8 | import org.springframework.context.ConfigurableApplicationContext; 9 | 10 | public class RedisContainerInitializer extends InitializerBase { 11 | 12 | @Override 13 | public void initialize(ConfigurableApplicationContext applicationContext) { 14 | var environment = applicationContext.getEnvironment(); 15 | var redisUrl = Objects.requireNonNull(environment.getProperty("spring.data.redis.url")); 16 | var wrapper = Optional.ofNullable(environment.getProperty("testcontainers.redis.docker.image")) 17 | .map(RedisContainerWrapper::new) 18 | .orElseGet(() -> new RedisContainerWrapper("redis:6.2.6-alpine")); 19 | var container = handleReusable(wrapper); 20 | resolveStaticPort(redisUrl, GENERIC_URL_WITH_PORT_GROUP_PATTERN) 21 | .ifPresent(staticPort -> bindPort(container, staticPort, RedisContainerWrapper.PORT)); 22 | 23 | start(container); 24 | 25 | var url = replaceHostAndPortPlaceholders(redisUrl, container, RedisContainerWrapper.PORT); 26 | var values = TestPropertyValues.of("spring.data.redis.url=" + url); 27 | values.applyTo(applicationContext); 28 | 29 | registerContainerAsBean(applicationContext); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializerTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.postgresql; 2 | 3 | import com.infobip.testcontainers.TestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties; 7 | import org.springframework.jdbc.core.JdbcTemplate; 8 | import org.springframework.jdbc.datasource.SimpleDriverDataSource; 9 | import org.springframework.test.context.ActiveProfiles; 10 | 11 | import java.sql.*; 12 | 13 | import static org.assertj.core.api.BDDAssertions.then; 14 | 15 | @AllArgsConstructor 16 | @ActiveProfiles("test") 17 | class PostgreSQLContainerInitializerTest extends TestBase { 18 | 19 | private final DataSourceProperties properties; 20 | 21 | @Test 22 | void shouldCreateContainer() { 23 | // given 24 | JdbcTemplate jdbcTemplate = new JdbcTemplate(new SimpleDriverDataSource( 25 | getDriver(properties.getUrl()), 26 | properties.getUrl(), 27 | properties.getUsername(), 28 | properties.getPassword())); 29 | 30 | // when 31 | String actual = jdbcTemplate.queryForObject("SELECT current_database();", String.class); 32 | 33 | // then 34 | then(actual).isEqualTo("TestDatabase"); 35 | } 36 | 37 | private Driver getDriver(String jdbcUrl) { 38 | try { 39 | return DriverManager.getDriver(jdbcUrl); 40 | } catch (SQLException e) { 41 | throw new IllegalArgumentException(e); 42 | } 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithJtdsDriverTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.mssql; 2 | 3 | import com.infobip.testcontainers.TestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties; 7 | import org.springframework.jdbc.core.JdbcTemplate; 8 | import org.springframework.jdbc.datasource.SimpleDriverDataSource; 9 | import org.springframework.test.context.ActiveProfiles; 10 | 11 | import java.sql.*; 12 | 13 | import static org.assertj.core.api.BDDAssertions.then; 14 | 15 | @AllArgsConstructor 16 | @ActiveProfiles("jtds") 17 | class MSSQLServerContainerInitializerWithJtdsDriverTest extends TestBase { 18 | 19 | private final DataSourceProperties properties; 20 | 21 | @Test 22 | void shouldCreateDatabase() { 23 | // given 24 | JdbcTemplate jdbcTemplate = new JdbcTemplate(new SimpleDriverDataSource( 25 | getDriver(properties.getUrl()), 26 | properties.getUrl(), 27 | properties.getUsername(), 28 | properties.getPassword())); 29 | 30 | // when 31 | String actual = jdbcTemplate.queryForObject("SELECT db_name()", String.class); 32 | 33 | // then 34 | then(actual).isEqualTo("JtdsTestDatabase"); 35 | } 36 | 37 | private Driver getDriver(String jdbcUrl) { 38 | try { 39 | return DriverManager.getDriver(jdbcUrl); 40 | } catch (SQLException e) { 41 | throw new IllegalArgumentException(e); 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /infobip-mssql-testcontainers-spring-boot-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | 5 | com.infobip 6 | infobip-testcontainers-spring-boot-starter 7 | 5.0.1-SNAPSHOT 8 | 9 | 10 | infobip-mssql-testcontainers-spring-boot-starter 11 | infobip-mssql-testcontainers-spring-boot-starter 12 | 13 | 14 | 15 | ${project.groupId} 16 | infobip-testcontainers-common 17 | ${project.version} 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-jdbc 24 | 25 | 26 | 27 | org.testcontainers 28 | testcontainers-mssqlserver 29 | 30 | 31 | 32 | com.microsoft.sqlserver 33 | mssql-jdbc 34 | 35 | 36 | 37 | 38 | net.sourceforge.jtds 39 | jtds 40 | test 41 | 42 | 43 | 44 | com.infobip 45 | infobip-testcontainers-test-common 46 | test 47 | ${project.version} 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /infobip-mysql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mysql/MySQLContainerInitializerWithInitScriptTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.mysql; 2 | 3 | import com.infobip.testcontainers.TestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties; 7 | import org.springframework.jdbc.core.JdbcTemplate; 8 | import org.springframework.jdbc.datasource.SimpleDriverDataSource; 9 | import org.springframework.test.context.ActiveProfiles; 10 | 11 | import java.sql.Driver; 12 | import java.sql.DriverManager; 13 | import java.sql.SQLException; 14 | 15 | import static org.assertj.core.api.BDDAssertions.then; 16 | 17 | @AllArgsConstructor 18 | @ActiveProfiles("init-script") 19 | class MySQLContainerInitializerWithInitScriptTest extends TestBase { 20 | 21 | private final DataSourceProperties properties; 22 | 23 | @Test 24 | void shouldCreateContainerWithInitScript() { 25 | // given 26 | JdbcTemplate jdbcTemplate = new JdbcTemplate(new SimpleDriverDataSource( 27 | getDriver(properties.getUrl()), 28 | properties.getUrl(), 29 | properties.getUsername(), 30 | properties.getPassword())); 31 | 32 | // when 33 | String actual = jdbcTemplate.queryForObject("SELECT name FROM test_table LIMIT 1", String.class); 34 | 35 | // then 36 | then(actual).isEqualTo("Test"); 37 | } 38 | 39 | private Driver getDriver(String jdbcUrl) { 40 | try { 41 | return DriverManager.getDriver(jdbcUrl); 42 | } catch (SQLException e) { 43 | throw new IllegalArgumentException(e); 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithInitScriptTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.mssql; 2 | 3 | import com.infobip.testcontainers.TestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.junit.jupiter.api.Disabled; 6 | import org.junit.jupiter.api.Test; 7 | import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties; 8 | import org.springframework.jdbc.core.JdbcTemplate; 9 | import org.springframework.jdbc.datasource.SimpleDriverDataSource; 10 | import org.springframework.test.context.ActiveProfiles; 11 | 12 | import java.sql.*; 13 | 14 | import static org.assertj.core.api.BDDAssertions.then; 15 | 16 | @Disabled 17 | @AllArgsConstructor 18 | @ActiveProfiles("init-script") 19 | class MSSQLServerContainerInitializerWithInitScriptTest extends TestBase { 20 | 21 | private final DataSourceProperties properties; 22 | 23 | @Test 24 | void shouldCreateDatabase() { 25 | // given 26 | JdbcTemplate jdbcTemplate = new JdbcTemplate(new SimpleDriverDataSource( 27 | getDriver(properties.getUrl()), 28 | properties.getUrl(), 29 | properties.getUsername(), 30 | properties.getPassword())); 31 | 32 | // when 33 | String actual = jdbcTemplate.queryForObject("SELECT TOP 1 name FROM test_table", String.class); 34 | 35 | // then 36 | then(actual).isEqualTo("Test"); 37 | } 38 | 39 | private Driver getDriver(String jdbcUrl) { 40 | try { 41 | return DriverManager.getDriver(jdbcUrl); 42 | } catch (SQLException e) { 43 | throw new IllegalArgumentException(e); 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /infobip-kafka-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/kafka/KafkaContainerInitializerTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.kafka; 2 | 3 | import static com.infobip.testcontainers.spring.kafka.Listener.TOPIC; 4 | import static org.assertj.core.api.BDDAssertions.then; 5 | import static org.awaitility.Awaitility.await; 6 | 7 | import java.time.Duration; 8 | import java.util.concurrent.ExecutionException; 9 | import java.util.concurrent.TimeUnit; 10 | import java.util.concurrent.TimeoutException; 11 | 12 | import com.infobip.testcontainers.TestBase; 13 | import lombok.AllArgsConstructor; 14 | import org.junit.jupiter.api.Test; 15 | import org.springframework.boot.test.context.SpringBootTest; 16 | import org.springframework.kafka.core.KafkaTemplate; 17 | import org.springframework.kafka.support.SendResult; 18 | import org.springframework.test.context.ActiveProfiles; 19 | import org.springframework.test.context.TestConstructor; 20 | 21 | @AllArgsConstructor 22 | @ActiveProfiles("test") 23 | class KafkaContainerInitializerTest extends TestBase { 24 | 25 | private final KafkaTemplate kafkaTemplate; 26 | private final Listener listener; 27 | 28 | @Test 29 | void shouldCreateContainer() throws InterruptedException, ExecutionException, TimeoutException { 30 | // given 31 | String givenValue = this.getClass().getName(); 32 | 33 | // when 34 | SendResult actual = kafkaTemplate.send(TOPIC, "key", givenValue) 35 | .get(10, TimeUnit.SECONDS); 36 | 37 | // then 38 | then(actual).isNotNull(); 39 | await().atMost(Duration.ofSeconds(10)) 40 | .untilAsserted(() -> then(listener.getValue()).isEqualTo(givenValue)); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /infobip-mysql-testcontainers-spring-boot-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | com.infobip 7 | infobip-testcontainers-spring-boot-starter 8 | 5.0.1-SNAPSHOT 9 | 10 | 11 | infobip-mysql-testcontainers-spring-boot-starter 12 | infobip-mysql-testcontainers-spring-boot-starter 13 | 14 | 15 | 16 | ${project.groupId} 17 | infobip-testcontainers-common 18 | ${project.version} 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-jdbc 25 | 26 | 27 | 28 | com.mysql 29 | mysql-connector-j 30 | 31 | 32 | 33 | 34 | org.testcontainers 35 | testcontainers-mysql 36 | 37 | 38 | 39 | 40 | com.infobip 41 | infobip-testcontainers-test-common 42 | test 43 | ${project.version} 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /infobip-kafka-testcontainers-spring-boot-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | 5 | com.infobip 6 | infobip-testcontainers-spring-boot-starter 7 | 5.0.1-SNAPSHOT 8 | 9 | 10 | infobip-kafka-testcontainers-spring-boot-starter 11 | infobip-kafka-testcontainers-spring-boot-starter 12 | 13 | 14 | 15 | ${project.groupId} 16 | infobip-testcontainers-common 17 | ${project.version} 18 | 19 | 20 | 21 | com.fasterxml.jackson.core 22 | jackson-databind 23 | 24 | 25 | 26 | 27 | org.testcontainers 28 | testcontainers-kafka 29 | 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-kafka 34 | 35 | 36 | 37 | org.springframework.kafka 38 | spring-kafka 39 | 40 | 41 | 42 | 43 | org.awaitility 44 | awaitility 45 | test 46 | 47 | 48 | 49 | com.infobip 50 | infobip-testcontainers-test-common 51 | test 52 | ${project.version} 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /infobip-clickhouse-testcontainers-spring-boot-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | 5 | com.infobip 6 | infobip-testcontainers-spring-boot-starter 7 | 5.0.1-SNAPSHOT 8 | 9 | 10 | infobip-clickhouse-testcontainers-spring-boot-starter 11 | infobip-clickhouse-testcontainers-spring-boot-starter 12 | 13 | 14 | 0.3.2 15 | 16 | 17 | 18 | 19 | ${project.groupId} 20 | infobip-testcontainers-common 21 | ${project.version} 22 | 23 | 24 | 25 | com.fasterxml.jackson.core 26 | jackson-databind 27 | 28 | 29 | 30 | 31 | org.testcontainers 32 | testcontainers-clickhouse 33 | 34 | 35 | 36 | com.clickhouse 37 | clickhouse-jdbc 38 | ${clickhouse-jdbc.version} 39 | 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-starter-jdbc 44 | 45 | 46 | 47 | 48 | com.infobip 49 | infobip-testcontainers-test-common 50 | test 51 | ${project.version} 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ### 5.0.0 2 | * Upgraded to Spring Boot 4 and testcontainers 2 3 | 4 | ### 4.4.4 5 | * Added BOM (Bill of materials) 6 | 7 | ### 4.3.4 8 | * Upgraded to Spring Boot 3.3.1 and testcontainers 1.20.0 9 | * Upgraded mssql module base image to mcr.microsoft.com/mssql/server:2019-latest 10 | 11 | ### 4.3.0 12 | * Added support for MySQL 13 | 14 | ### 4.2.0 15 | * Added reusable support 16 | 17 | ### 4.1.0 18 | 19 | * Added the testcontainers.db-name.init-script property to all the database starters 20 | * Added tests to cover the new feature 21 | * Fixed inconsistent formatting & typos in various places 22 | * Uplift clickhouse driver version 23 | * Removed redundant property from PostgreSQL starter 24 | 25 | ### 4.0.0 26 | 27 | * upgraded to Spring Boot 3.0.0 and testcontainers 1.17.6 28 | 29 | ### 3.5.1 30 | * renamed infobip-rabbitmq-testcontainers-spring-boot module to infobip-rabbitmq-testcontainers-spring-boot-starter 31 | 32 | ### 3.5.0 33 | * upgraded to spring-boot-dependencies 2.7.0 and testcontainers 1.17.1 34 | * fixed DatabaseCreator to support mssql-jdbc with encrypted flag set to true (which is now the default behavior in upgraded version) 35 | 36 | ### 3.4.0 37 | * upgraded to spring-boot-dependencies 2.6.2 and testcontainers 1.16.2 38 | 39 | ### 3.3.0 40 | General: 41 | * Added support for starting containers on a predefined port 42 | 43 | ### 3.2.0 44 | 45 | #### ClickHouse: 46 | * Added support for ClickHouse 47 | * Custom path for ClickHouse jdbc properties can be provided under `testcontainers.clickhouse.custom-path` property. In case custom path is not provided, properties under `spring.datasource` will be used 48 | 49 | ### 3.1.0 50 | 51 | #### MSSQL: 52 | * username and password are now automatically injected and don't need to be explicitly set in configuration (note that they are not overriden if they do exist) 53 | * `spring.flyway` and `spring.r2dbc` are now supported 54 | -------------------------------------------------------------------------------- /infobip-kafka-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/kafka/KafkaContainerInitializerWithStaticPortTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.kafka; 2 | 3 | import com.infobip.testcontainers.TestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.boot.kafka.autoconfigure.KafkaProperties; 7 | import org.springframework.kafka.core.KafkaTemplate; 8 | import org.springframework.kafka.support.SendResult; 9 | import org.springframework.test.context.ActiveProfiles; 10 | 11 | import java.time.Duration; 12 | import java.util.concurrent.*; 13 | 14 | import static com.infobip.testcontainers.spring.kafka.Listener.TOPIC; 15 | import static org.assertj.core.api.BDDAssertions.then; 16 | import static org.awaitility.Awaitility.await; 17 | 18 | @AllArgsConstructor 19 | @ActiveProfiles("static-port") 20 | class KafkaContainerInitializerWithStaticPortTest extends TestBase { 21 | 22 | private final KafkaTemplate kafkaTemplate; 23 | private final Listener listener; 24 | private final KafkaProperties kafkaProperties; 25 | 26 | @Test 27 | void shouldCreateContainer() throws InterruptedException, ExecutionException, TimeoutException { 28 | // given 29 | String givenValue = this.getClass().getName(); 30 | 31 | // when 32 | SendResult actual = kafkaTemplate.send(TOPIC, "key", givenValue) 33 | .get(10, TimeUnit.SECONDS); 34 | 35 | // then 36 | then(actual).isNotNull(); 37 | await().atMost(Duration.ofSeconds(10)) 38 | .untilAsserted(() -> then(listener.getValue()).isEqualTo(givenValue)); 39 | } 40 | 41 | @Test 42 | void shouldResolveHostInUrl() { 43 | // then 44 | then(kafkaProperties.getBootstrapServers()).containsExactly("localhost:5002"); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /infobip-rabbitmq-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/rabbit/RabbitContainerInitializer.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.rabbit; 2 | 3 | import static com.infobip.testcontainers.spring.rabbit.RabbitContainerWrapper.PORT; 4 | 5 | import java.util.Optional; 6 | 7 | import com.infobip.testcontainers.InitializerBase; 8 | import org.springframework.boot.test.util.TestPropertyValues; 9 | import org.springframework.context.ConfigurableApplicationContext; 10 | import org.springframework.core.env.Environment; 11 | import org.testcontainers.containers.wait.strategy.Wait; 12 | 13 | public class RabbitContainerInitializer extends InitializerBase { 14 | 15 | @Override 16 | public void initialize(ConfigurableApplicationContext applicationContext) { 17 | var environment = applicationContext.getEnvironment(); 18 | var wrapper = Optional.ofNullable(environment.getProperty("testcontainers.rabbit.docker.image")) 19 | .map(RabbitContainerWrapper::new) 20 | .orElseGet(() -> new RabbitContainerWrapper("rabbitmq:3.8.9-alpine")); 21 | var container = handleReusable(wrapper); 22 | 23 | resolveStaticPort(environment) 24 | .ifPresent(staticPort -> bindPort(container, staticPort, PORT)); 25 | 26 | container.waitingFor(Wait.forListeningPort()); 27 | start(container); 28 | 29 | var values = TestPropertyValues.of( 30 | String.format("spring.rabbitmq.addresses=%s:%d", container.getHost(), container.getMappedPort(PORT))); 31 | values.applyTo(applicationContext); 32 | 33 | registerContainerAsBean(applicationContext); 34 | } 35 | 36 | private Optional resolveStaticPort(Environment environment) { 37 | return Optional.ofNullable(environment.getProperty("spring.rabbitmq.port")) 38 | .map(Integer::valueOf); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /infobip-mysql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mysql/MySQLContainerInitializerWithStaticPortTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.mysql; 2 | 3 | import static org.assertj.core.api.BDDAssertions.then; 4 | 5 | import java.sql.Driver; 6 | import java.sql.DriverManager; 7 | import java.sql.SQLException; 8 | 9 | import com.infobip.testcontainers.TestBase; 10 | import lombok.AllArgsConstructor; 11 | import org.junit.jupiter.api.Test; 12 | import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties; 13 | import org.springframework.jdbc.core.JdbcTemplate; 14 | import org.springframework.jdbc.datasource.SimpleDriverDataSource; 15 | import org.springframework.test.context.ActiveProfiles; 16 | 17 | @AllArgsConstructor 18 | @ActiveProfiles("static-port") 19 | class MySQLContainerInitializerWithStaticPortTest extends TestBase { 20 | 21 | private final DataSourceProperties properties; 22 | 23 | @Test 24 | void shouldCreateContainer() { 25 | // given 26 | JdbcTemplate jdbcTemplate = new JdbcTemplate(new SimpleDriverDataSource( 27 | getDriver(properties.getUrl()), 28 | properties.getUrl(), 29 | properties.getUsername(), 30 | properties.getPassword())); 31 | 32 | // when 33 | String actual = jdbcTemplate.queryForObject("SELECT database();", String.class); 34 | 35 | // then 36 | then(actual).isEqualTo("TestDatabase"); 37 | } 38 | 39 | @Test 40 | void shouldReplaceHostInJdbcUrl() { 41 | // when 42 | String actual = properties.getUrl(); 43 | 44 | // then 45 | then(actual).contains("localhost:5005"); 46 | } 47 | 48 | private Driver getDriver(String jdbcUrl) { 49 | try { 50 | return DriverManager.getDriver(jdbcUrl); 51 | } catch (SQLException e) { 52 | throw new IllegalArgumentException(e); 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializerWithInitScriptTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.postgresql; 2 | 3 | import com.infobip.testcontainers.TestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.jdbc.core.JdbcTemplate; 9 | import org.springframework.jdbc.datasource.SimpleDriverDataSource; 10 | import org.springframework.test.context.ActiveProfiles; 11 | import org.springframework.test.context.TestConstructor; 12 | 13 | import java.sql.Driver; 14 | import java.sql.DriverManager; 15 | import java.sql.SQLException; 16 | 17 | import static org.assertj.core.api.BDDAssertions.then; 18 | 19 | @AllArgsConstructor 20 | @ActiveProfiles("init-script") 21 | class PostgreSQLContainerInitializerWithInitScriptTest extends TestBase { 22 | 23 | private final DataSourceProperties properties; 24 | 25 | @Test 26 | void shouldCreateContainerWithInitScript() { 27 | // given 28 | JdbcTemplate jdbcTemplate = new JdbcTemplate(new SimpleDriverDataSource( 29 | getDriver(properties.getUrl()), 30 | properties.getUrl(), 31 | properties.getUsername(), 32 | properties.getPassword())); 33 | 34 | // when 35 | String actual = jdbcTemplate.queryForObject("SELECT name FROM test_table FETCH FIRST ROW ONLY;", String.class); 36 | 37 | // then 38 | then(actual).isEqualTo("Test"); 39 | } 40 | 41 | private Driver getDriver(String jdbcUrl) { 42 | try { 43 | return DriverManager.getDriver(jdbcUrl); 44 | } catch (SQLException e) { 45 | throw new IllegalArgumentException(e); 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /infobip-clickhouse-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/clickhouse/ClickhouseContainerInitializer.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.clickhouse; 2 | 3 | import com.infobip.testcontainers.InitializerBase; 4 | import org.springframework.boot.test.util.TestPropertyValues; 5 | import org.springframework.context.ConfigurableApplicationContext; 6 | 7 | import java.util.Objects; 8 | import java.util.Optional; 9 | 10 | public class ClickhouseContainerInitializer extends InitializerBase { 11 | 12 | @Override 13 | public void initialize(ConfigurableApplicationContext applicationContext) { 14 | var environment = applicationContext.getEnvironment(); 15 | var customPropertyPath = Optional.ofNullable(environment.getProperty("testcontainers.clickhouse.custom-path")); 16 | var jdbcUrlPropertyPath = customPropertyPath.orElse("spring.datasource") + ".jdbc-url"; 17 | var jdbcUrlValue = Objects.requireNonNull(environment.getProperty(jdbcUrlPropertyPath)); 18 | var wrapper = Optional.ofNullable(environment.getProperty("testcontainers.clickhouse.docker.image.version")) 19 | .map(ClickhouseContainerWrapper::new) 20 | .orElseGet(ClickhouseContainerWrapper::new); 21 | var container = handleReusable(wrapper); 22 | 23 | Optional.ofNullable(environment.getProperty("testcontainers.clickhouse.init-script")) 24 | .ifPresent(container::withInitScript); 25 | 26 | resolveStaticPort(jdbcUrlValue, GENERIC_URL_WITH_PORT_GROUP_PATTERN) 27 | .ifPresent(staticPort -> bindPort(container, staticPort, ClickhouseContainerWrapper.HTTP_PORT)); 28 | 29 | start(container); 30 | 31 | var url = replaceHostAndPortPlaceholders(jdbcUrlValue, container, ClickhouseContainerWrapper.HTTP_PORT); 32 | 33 | var values = TestPropertyValues.of(String.format("%s=%s", jdbcUrlPropertyPath, url)); 34 | values.applyTo(applicationContext); 35 | 36 | registerContainerAsBean(applicationContext); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /infobip-postgresql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializerWithStaticPortTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.postgresql; 2 | 3 | import static org.assertj.core.api.BDDAssertions.then; 4 | 5 | import java.sql.Driver; 6 | import java.sql.DriverManager; 7 | import java.sql.SQLException; 8 | 9 | import com.infobip.testcontainers.TestBase; 10 | import lombok.AllArgsConstructor; 11 | import org.junit.jupiter.api.Test; 12 | import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties; 13 | import org.springframework.boot.test.context.SpringBootTest; 14 | import org.springframework.jdbc.core.JdbcTemplate; 15 | import org.springframework.jdbc.datasource.SimpleDriverDataSource; 16 | import org.springframework.test.context.ActiveProfiles; 17 | import org.springframework.test.context.TestConstructor; 18 | 19 | @AllArgsConstructor 20 | @ActiveProfiles("static-port") 21 | class PostgreSQLContainerInitializerWithStaticPortTest extends TestBase { 22 | 23 | private final DataSourceProperties properties; 24 | 25 | @Test 26 | void shouldCreateContainer() { 27 | // given 28 | JdbcTemplate jdbcTemplate = new JdbcTemplate(new SimpleDriverDataSource( 29 | getDriver(properties.getUrl()), 30 | properties.getUrl(), 31 | properties.getUsername(), 32 | properties.getPassword())); 33 | 34 | // when 35 | String actual = jdbcTemplate.queryForObject("SELECT current_database();", String.class); 36 | 37 | // then 38 | then(actual).isEqualTo("TestDatabase"); 39 | } 40 | 41 | @Test 42 | void shouldReplaceHostInJdbcUrl() { 43 | // when 44 | String actual = properties.getUrl(); 45 | 46 | // then 47 | then(actual).contains("localhost:5004"); 48 | } 49 | 50 | private Driver getDriver(String jdbcUrl) { 51 | try { 52 | return DriverManager.getDriver(jdbcUrl); 53 | } catch (SQLException e) { 54 | throw new IllegalArgumentException(e); 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /infobip-postgresql-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/postgresql/PostgreSQLContainerInitializer.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.postgresql; 2 | 3 | import com.infobip.testcontainers.InitializerBase; 4 | import org.springframework.boot.test.util.TestPropertyValues; 5 | import org.springframework.context.ConfigurableApplicationContext; 6 | import org.springframework.util.StringUtils; 7 | 8 | import java.util.Optional; 9 | 10 | public class PostgreSQLContainerInitializer extends InitializerBase { 11 | 12 | @Override 13 | public void initialize(ConfigurableApplicationContext applicationContext) { 14 | var environment = applicationContext.getEnvironment(); 15 | var dataSourceUrlPropertyName = Optional.ofNullable( 16 | environment.getProperty("testcontainers.postgresql.datasource.url.property.name")) 17 | .orElse("spring.datasource.url"); 18 | var dataSourceUrl = environment.getProperty(dataSourceUrlPropertyName); 19 | 20 | if (StringUtils.isEmpty(dataSourceUrl)) { 21 | throw new IllegalStateException("URL for test-container is null or empty."); 22 | } 23 | 24 | var database = dataSourceUrl.substring(dataSourceUrl.lastIndexOf("/") + 1); 25 | var wrapper = Optional.ofNullable(environment.getProperty("testcontainers.postgresql.docker.image")) 26 | .map(imageName -> new PostgreSQLContainerWrapper(database, imageName)) 27 | .orElseGet(() -> new PostgreSQLContainerWrapper(database)); 28 | var container = handleReusable(wrapper); 29 | 30 | Optional.ofNullable(environment.getProperty("testcontainers.postgresql.init-script")) 31 | .ifPresent(container::withInitScript); 32 | 33 | resolveStaticPort(dataSourceUrl, GENERIC_URL_WITH_PORT_GROUP_PATTERN) 34 | .ifPresent(staticPort -> bindPort(container, staticPort, PostgreSQLContainerWrapper.POSTGRESQL_PORT)); 35 | 36 | start(container); 37 | 38 | var url = replaceHostAndPortPlaceholders(dataSourceUrl, container, PostgreSQLContainerWrapper.POSTGRESQL_PORT); 39 | var values = TestPropertyValues.of(dataSourceUrlPropertyName + "=" + url); 40 | 41 | values.applyTo(applicationContext); 42 | 43 | registerContainerAsBean(applicationContext); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /infobip-mssql-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/mssql/DatabaseCreator.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.mssql; 2 | 3 | import java.sql.Driver; 4 | import java.sql.DriverManager; 5 | import java.sql.SQLException; 6 | import java.util.Objects; 7 | import java.util.Optional; 8 | import java.util.regex.Matcher; 9 | import java.util.regex.Pattern; 10 | 11 | import org.springframework.jdbc.core.JdbcTemplate; 12 | import org.springframework.jdbc.datasource.SimpleDriverDataSource; 13 | 14 | class DatabaseCreator { 15 | 16 | private final JdbcTemplate template; 17 | private final String databaseExistsQuery; 18 | private final String createDatabaseQuery; 19 | 20 | DatabaseCreator(String url, String username, String password) { 21 | String databaseUrlPattern = getDatabaseUrlPattern(url); 22 | Pattern jdbcBaseUrlWithDbNamePattern = Pattern.compile(databaseUrlPattern); 23 | Matcher matcher = jdbcBaseUrlWithDbNamePattern.matcher(url); 24 | 25 | if (!matcher.matches()) { 26 | throw new IllegalArgumentException(url + " does not match " + databaseUrlPattern); 27 | } 28 | 29 | String otherParameters = Optional.ofNullable(matcher.group("otherParameters")).orElse(""); 30 | String jdbcBaseUrl = matcher.group("jdbcBaseUrl") + otherParameters; 31 | String databaseName = matcher.group("databaseName"); 32 | databaseExistsQuery = String.format("SELECT count(*) FROM sys.databases WHERE name='%s'", databaseName); 33 | createDatabaseQuery = String.format("CREATE DATABASE %s", databaseName); 34 | this.template = new JdbcTemplate( 35 | new SimpleDriverDataSource(getDriver(jdbcBaseUrl), jdbcBaseUrl, username, password)); 36 | } 37 | 38 | private String getDatabaseUrlPattern(String url) { 39 | if (url.startsWith("jdbc:jtds")) { 40 | return "(?.*)/(?[^;]*);?(?.*)"; 41 | } 42 | 43 | return "(?.*);database=(?[^;]*)(?;.*)?"; 44 | } 45 | 46 | void createDatabaseIfItDoesNotExist() { 47 | if(!databaseExists()) { 48 | template.execute(createDatabaseQuery); 49 | } 50 | } 51 | 52 | private boolean databaseExists() { 53 | return Objects.equals(template.queryForObject(databaseExistsQuery, Integer.class), 1); 54 | } 55 | 56 | private Driver getDriver(String jdbcUrl) { 57 | try { 58 | return DriverManager.getDriver(jdbcUrl); 59 | } catch (SQLException e) { 60 | throw new IllegalArgumentException(e); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithStaticPortTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.mssql; 2 | 3 | import com.infobip.testcontainers.TestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties; 7 | import org.springframework.core.env.Environment; 8 | import org.springframework.jdbc.core.JdbcTemplate; 9 | import org.springframework.jdbc.datasource.SimpleDriverDataSource; 10 | import org.springframework.test.context.ActiveProfiles; 11 | 12 | import java.sql.*; 13 | 14 | import static org.assertj.core.api.BDDAssertions.then; 15 | 16 | @AllArgsConstructor 17 | @ActiveProfiles("static-port") 18 | class MSSQLServerContainerInitializerWithStaticPortTest extends TestBase { 19 | 20 | private final Environment environment; 21 | private final DataSourceProperties properties; 22 | private final MSSQLServerContainerWrapper mSSQLServerContainerWrapper; 23 | 24 | @Test 25 | void shouldCreateContainer() { 26 | // given 27 | JdbcTemplate jdbcTemplate = new JdbcTemplate(new SimpleDriverDataSource( 28 | getDriver(properties.getUrl()), 29 | properties.getUrl(), 30 | properties.getUsername(), 31 | properties.getPassword())); 32 | 33 | // when 34 | String actual = jdbcTemplate.queryForObject("SELECT db_name()", String.class); 35 | 36 | // then 37 | then(actual).isEqualTo("MicrosoftDriverTestDatabase"); 38 | } 39 | 40 | @Test 41 | void shouldReplaceHostInJdbcUrl() { 42 | // when 43 | String actual = environment.getProperty("spring.datasource.url"); 44 | 45 | // then 46 | then(actual).contains("localhost:5003"); 47 | } 48 | 49 | @Test 50 | void shouldReplaceHostInR2dbc() { 51 | // when 52 | String actual = environment.getProperty("spring.r2dbc.url"); 53 | 54 | // then 55 | then(actual).contains("localhost:5003"); 56 | } 57 | 58 | @Test 59 | void shouldReplaceHostInFlyway() { 60 | // when 61 | String actual = environment.getProperty("spring.flyway.url"); 62 | 63 | // then 64 | then(actual).contains("localhost:5003"); 65 | } 66 | 67 | private Driver getDriver(String jdbcUrl) { 68 | try { 69 | return DriverManager.getDriver(jdbcUrl); 70 | } catch (SQLException e) { 71 | throw new IllegalArgumentException(e); 72 | } 73 | } 74 | 75 | @Test 76 | void shouldBindContainerToStaticPort() { 77 | // when 78 | String jdbcUrl = environment.getProperty("spring.datasource.url"); 79 | String r2dbcUrl = environment.getProperty("spring.r2dbc.url"); 80 | String flywayUrl = environment.getProperty("spring.flyway.url"); 81 | 82 | // then 83 | then(jdbcUrl).contains("localhost:5003"); 84 | then(r2dbcUrl).contains("localhost:5003"); 85 | then(flywayUrl).contains("localhost:5003"); 86 | 87 | then(mSSQLServerContainerWrapper.getPortBindings()) 88 | .hasSize(1) 89 | .contains("5003:1433/tcp"); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /infobip-testcontainers-common/src/main/java/com/infobip/testcontainers/InitializerBase.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers; 2 | 3 | import org.springframework.context.*; 4 | import org.springframework.context.event.ContextClosedEvent; 5 | import org.testcontainers.containers.Container; 6 | import org.testcontainers.containers.GenericContainer; 7 | import org.testcontainers.lifecycle.Startable; 8 | import org.testcontainers.utility.TestcontainersConfiguration; 9 | 10 | import java.util.*; 11 | import java.util.concurrent.atomic.AtomicReference; 12 | import java.util.regex.Matcher; 13 | import java.util.regex.Pattern; 14 | 15 | public abstract class InitializerBase 16 | implements ApplicationContextInitializer, ApplicationListener { 17 | 18 | public static final String PORT_PLACEHOLDER = ""; 19 | public static final String HOST_PLACEHOLDER = ""; 20 | 21 | protected static final Pattern GENERIC_URL_WITH_PORT_GROUP_PATTERN = Pattern.compile(".*://.*:(\\d+)([/;].*)?"); 22 | 23 | private final AtomicReference container = new AtomicReference<>(); 24 | 25 | @Override 26 | public void onApplicationEvent(ContextClosedEvent event) { 27 | C value = container.get(); 28 | if (value != null) { 29 | value.stop(); 30 | } 31 | } 32 | 33 | protected void start(C container) { 34 | this.container.set(container); 35 | container.start(); 36 | } 37 | 38 | protected String replaceHostAndPortPlaceholders(String source, 39 | Container container, 40 | Integer originalContainerPort) { 41 | return source.replaceAll(HOST_PLACEHOLDER, container.getHost()) 42 | .replaceAll(PORT_PLACEHOLDER, container.getMappedPort(originalContainerPort).toString()); 43 | } 44 | 45 | protected Optional resolveStaticPort(String connectionString, Pattern urlPatternWithPortGroup) { 46 | return Optional.ofNullable(connectionString) 47 | .map(urlPatternWithPortGroup::matcher) 48 | .filter(Matcher::matches) 49 | .map(matcher -> matcher.group(1)) 50 | .map(Integer::valueOf); 51 | } 52 | 53 | protected Optional resolveStaticPort(Collection connectionStrings, 54 | Pattern urlPatternWithPortGroup) { 55 | return connectionStrings.stream() 56 | .flatMap(connectionString -> resolveStaticPort(connectionString, 57 | urlPatternWithPortGroup).stream()) 58 | .findFirst(); 59 | } 60 | 61 | protected void bindPort(Container container, Integer hostPort, Integer containerPort) { 62 | container.setPortBindings(Collections.singletonList(hostPort + ":" + containerPort)); 63 | } 64 | 65 | protected , T extends GenericContainer> T handleReusable(T container) { 66 | 67 | if (TestcontainersConfiguration.getInstance().environmentSupportsReuse()) { 68 | container.withReuse(true); 69 | } 70 | 71 | return container; 72 | } 73 | 74 | protected void registerContainerAsBean(ConfigurableApplicationContext applicationContext) { 75 | var c = container.get(); 76 | var containerClassName = c.getClass().getSimpleName(); 77 | var beanName = Character.toLowerCase(containerClassName.charAt(0)) + containerClassName.substring(1); 78 | applicationContext.getBeanFactory() 79 | .registerSingleton(beanName, c); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /infobip-mysql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mysql/MySQLContainerInitializerTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.mysql; 2 | 3 | import com.infobip.testcontainers.TestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties; 7 | import org.springframework.core.env.Environment; 8 | import org.springframework.jdbc.core.JdbcTemplate; 9 | import org.springframework.jdbc.datasource.SimpleDriverDataSource; 10 | import org.springframework.test.context.ActiveProfiles; 11 | 12 | import java.sql.*; 13 | 14 | import static org.assertj.core.api.BDDAssertions.then; 15 | 16 | @AllArgsConstructor 17 | @ActiveProfiles("test") 18 | class MySQLContainerInitializerTest extends TestBase { 19 | 20 | private final Environment environment; 21 | private final DataSourceProperties properties; 22 | 23 | @Test 24 | void shouldCreateContainer() { 25 | // given 26 | JdbcTemplate jdbcTemplate = new JdbcTemplate(new SimpleDriverDataSource( 27 | getDriver(properties.getUrl()), 28 | properties.getUrl(), 29 | properties.getUsername(), 30 | properties.getPassword())); 31 | 32 | // when 33 | String actual = jdbcTemplate.queryForObject("SELECT database();", String.class); 34 | 35 | // then 36 | then(actual).isEqualTo("TestDatabase"); 37 | } 38 | 39 | @Test 40 | void shouldInsertUsername() { 41 | // when 42 | String actual = properties.getUsername(); 43 | 44 | // then 45 | then(actual).isNotBlank(); 46 | } 47 | 48 | @Test 49 | void shouldInsertPassword() { 50 | // when 51 | String actual = properties.getPassword(); 52 | 53 | // then 54 | then(actual).isNotBlank(); 55 | } 56 | 57 | @Test 58 | void shouldReplaceHostAndPortInR2dbc() { 59 | // when 60 | String actual = environment.getProperty("spring.r2dbc.url"); 61 | 62 | // then 63 | then(actual).isNotBlank() 64 | .doesNotContain("") 65 | .doesNotContain(""); 66 | } 67 | 68 | @Test 69 | void shouldInsertUsernameInR2dbc() { 70 | // when 71 | String actual = environment.getProperty("spring.r2dbc.username"); 72 | 73 | // then 74 | then(actual).isNotBlank(); 75 | } 76 | 77 | @Test 78 | void shouldInsertPasswordInR2dbc() { 79 | // when 80 | String actual = environment.getProperty("spring.r2dbc.password"); 81 | 82 | // then 83 | then(actual).isNotBlank(); 84 | } 85 | 86 | @Test 87 | void shouldReplaceHostAndPortInFlyway() { 88 | // when 89 | String actual = environment.getProperty("spring.flyway.url"); 90 | 91 | // then 92 | then(actual).isNotBlank() 93 | .doesNotContain("") 94 | .doesNotContain(""); 95 | } 96 | 97 | @Test 98 | void shouldInsertUsernameInFlyway() { 99 | // when 100 | String actual = environment.getProperty("spring.flyway.username"); 101 | 102 | // then 103 | then(actual).isNotBlank(); 104 | } 105 | 106 | @Test 107 | void shouldInsertPasswordInFlyway() { 108 | // when 109 | String actual = environment.getProperty("spring.flyway.password"); 110 | 111 | // then 112 | then(actual).isNotBlank(); 113 | } 114 | 115 | private Driver getDriver(String jdbcUrl) { 116 | try { 117 | return DriverManager.getDriver(jdbcUrl); 118 | } catch (SQLException e) { 119 | throw new IllegalArgumentException(e); 120 | } 121 | } 122 | 123 | } -------------------------------------------------------------------------------- /infobip-mssql-testcontainers-spring-boot-starter/src/test/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializerWithMicrosoftDriverTest.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.mssql; 2 | 3 | import com.infobip.testcontainers.TestBase; 4 | import lombok.AllArgsConstructor; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.boot.jdbc.autoconfigure.DataSourceProperties; 7 | import org.springframework.core.env.Environment; 8 | import org.springframework.jdbc.core.JdbcTemplate; 9 | import org.springframework.jdbc.datasource.SimpleDriverDataSource; 10 | import org.springframework.test.context.ActiveProfiles; 11 | 12 | import java.sql.*; 13 | 14 | import static org.assertj.core.api.BDDAssertions.then; 15 | 16 | @AllArgsConstructor 17 | @ActiveProfiles("microsoft-driver") 18 | class MSSQLServerContainerInitializerWithMicrosoftDriverTest extends TestBase { 19 | 20 | private final Environment environment; 21 | private final DataSourceProperties properties; 22 | 23 | @Test 24 | void shouldCreateContainer() { 25 | // given 26 | JdbcTemplate jdbcTemplate = new JdbcTemplate(new SimpleDriverDataSource( 27 | getDriver(properties.getUrl()), 28 | properties.getUrl(), 29 | properties.getUsername(), 30 | properties.getPassword())); 31 | 32 | // when 33 | String actual = jdbcTemplate.queryForObject("SELECT db_name()", String.class); 34 | 35 | // then 36 | then(actual).isEqualTo("MicrosoftDriverTestDatabase"); 37 | } 38 | 39 | @Test 40 | void shouldInsertUsername() { 41 | // when 42 | String actual = properties.getUsername(); 43 | 44 | // then 45 | then(actual).isNotBlank(); 46 | } 47 | 48 | @Test 49 | void shouldInsertPassword() { 50 | // when 51 | String actual = properties.getPassword(); 52 | 53 | // then 54 | then(actual).isNotBlank(); 55 | } 56 | 57 | @Test 58 | void shouldReplaceHostAndPortInR2dbc() { 59 | // when 60 | String actual = environment.getProperty("spring.r2dbc.url"); 61 | 62 | // then 63 | then(actual).isNotBlank() 64 | .doesNotContain("") 65 | .doesNotContain(""); 66 | } 67 | 68 | @Test 69 | void shouldInsertUsernameInR2dbc() { 70 | // when 71 | String actual = environment.getProperty("spring.r2dbc.username"); 72 | 73 | // then 74 | then(actual).isNotBlank(); 75 | } 76 | 77 | @Test 78 | void shouldInsertPasswordInR2dbc() { 79 | // when 80 | String actual = environment.getProperty("spring.r2dbc.password"); 81 | 82 | // then 83 | then(actual).isNotBlank(); 84 | } 85 | 86 | @Test 87 | void shouldReplaceHostAndPortInFlyway() { 88 | // when 89 | String actual = environment.getProperty("spring.flyway.url"); 90 | 91 | // then 92 | then(actual).isNotBlank() 93 | .doesNotContain("") 94 | .doesNotContain(""); 95 | } 96 | 97 | @Test 98 | void shouldInsertUsernameInFlyway() { 99 | // when 100 | String actual = environment.getProperty("spring.flyway.username"); 101 | 102 | // then 103 | then(actual).isNotBlank(); 104 | } 105 | 106 | @Test 107 | void shouldInsertPasswordInFlyway() { 108 | // when 109 | String actual = environment.getProperty("spring.flyway.password"); 110 | 111 | // then 112 | then(actual).isNotBlank(); 113 | } 114 | 115 | private Driver getDriver(String jdbcUrl) { 116 | try { 117 | return DriverManager.getDriver(jdbcUrl); 118 | } catch (SQLException e) { 119 | throw new IllegalArgumentException(e); 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /infobip-kafka-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/kafka/KafkaContainerInitializer.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.kafka; 2 | 3 | import com.infobip.testcontainers.InitializerBase; 4 | import org.apache.kafka.clients.admin.AdminClient; 5 | import org.apache.kafka.clients.admin.NewTopic; 6 | import org.springframework.boot.test.util.TestPropertyValues; 7 | import org.springframework.context.ConfigurableApplicationContext; 8 | 9 | import java.util.*; 10 | import java.util.concurrent.*; 11 | import java.util.regex.Pattern; 12 | import java.util.stream.Stream; 13 | 14 | import static java.lang.Integer.parseInt; 15 | import static java.lang.Short.parseShort; 16 | 17 | public class KafkaContainerInitializer extends InitializerBase { 18 | 19 | private static final Pattern KAFKA_SERVER_PATTERN = Pattern.compile("^.*:(\\d+).*"); 20 | 21 | @Override 22 | public void initialize(ConfigurableApplicationContext applicationContext) { 23 | var environment = applicationContext.getEnvironment(); 24 | var bootstrapServers = Objects.requireNonNull(environment.getProperty("spring.kafka.bootstrap-servers")); 25 | var wrapper = Optional.ofNullable(environment.getProperty("testcontainers.kafka.docker.image.version")) 26 | .map(KafkaContainerWrapper::new) 27 | .orElseGet(KafkaContainerWrapper::new); 28 | var container = handleReusable(wrapper); 29 | 30 | resolveStaticPort(bootstrapServers, KAFKA_SERVER_PATTERN) 31 | .ifPresent(staticPort -> bindPort(container, staticPort, KafkaContainerWrapper.KAFKA_PORT)); 32 | 33 | start(container); 34 | var url = replaceHostAndPortPlaceholders(bootstrapServers, container, KafkaContainerWrapper.KAFKA_PORT); 35 | 36 | Optional.ofNullable(environment.getProperty("testcontainers.kafka.topics", String[].class)) 37 | .ifPresent(topics -> createTestKafkaTopics(container, url, topics)); 38 | var values = TestPropertyValues.of( 39 | "spring.kafka.bootstrap-servers=" + url); 40 | values.applyTo(applicationContext); 41 | 42 | registerContainerAsBean(applicationContext); 43 | } 44 | 45 | private static void createTestKafkaTopics(KafkaContainerWrapper container, String bootstrapServers, String[] topics) { 46 | 47 | try (var client = AdminClient.create(Collections.singletonMap("bootstrap.servers", bootstrapServers))) { 48 | if(container.isShouldBeReused()) { 49 | deleteTopics(client, topics); 50 | } 51 | createTopics(client, topics); 52 | } catch (Exception e) { 53 | throw new RuntimeException(e); 54 | } 55 | } 56 | 57 | private static void deleteTopics(AdminClient client, String[] topics) throws ExecutionException, 58 | InterruptedException, TimeoutException { 59 | var existingTopics = client.listTopics().names().get(60, TimeUnit.SECONDS); 60 | var deleteTopics = Stream.of(topics) 61 | .map(topic -> topic.split(":")) 62 | .filter(topic -> !existingTopics.contains(topic[0])) 63 | .map(topicParts -> topicParts[0]) 64 | .toList(); 65 | 66 | client.deleteTopics(deleteTopics); 67 | } 68 | 69 | private static void createTopics(AdminClient client, String[] topics) throws InterruptedException, 70 | ExecutionException, TimeoutException { 71 | var existingTopics = client.listTopics().names().get(60, TimeUnit.SECONDS); 72 | var newTopics = Stream.of(topics) 73 | .map(topic -> topic.split(":")) 74 | .filter(topic -> !existingTopics.contains(topic[0])) 75 | .map(topicParts -> new NewTopic(topicParts[0], parseInt(topicParts[1]), 76 | parseShort(topicParts[2]))) 77 | .toList(); 78 | 79 | client.createTopics(newTopics) 80 | .all() 81 | .get(60, TimeUnit.SECONDS); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /infobip-mysql-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/mysql/MySQLContainerInitializer.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.mysql; 2 | 3 | import com.infobip.testcontainers.InitializerBase; 4 | import org.springframework.boot.test.util.TestPropertyValues; 5 | import org.springframework.context.ConfigurableApplicationContext; 6 | import org.springframework.core.env.Environment; 7 | 8 | import java.util.*; 9 | import java.util.stream.Collectors; 10 | 11 | import static org.testcontainers.containers.MySQLContainer.MYSQL_PORT; 12 | 13 | public class MySQLContainerInitializer extends InitializerBase { 14 | 15 | private static final List DEFAULT_PROPERTY_NAMES = Arrays.asList("spring.datasource.url", 16 | "spring.flyway.url", 17 | "spring.r2dbc.url"); 18 | 19 | @Override 20 | public void initialize(ConfigurableApplicationContext applicationContext) { 21 | var environment = applicationContext.getEnvironment(); 22 | var urlPropertyNames = getUrlPropertyNames(environment); 23 | var urlPropertyNameToValue = getUrlPropertyNameToValue(environment, urlPropertyNames); 24 | var dataSourceUrlPropertyName = Optional.ofNullable( 25 | environment.getProperty("testcontainers.mysql.datasource.url.property.name")) 26 | .orElse("spring.datasource.url"); 27 | var dataSourceUrl = Objects.requireNonNull(environment.getProperty(dataSourceUrlPropertyName)); 28 | var database = dataSourceUrl.substring(dataSourceUrl.lastIndexOf("/") + 1); 29 | var wrapper = Optional.ofNullable(environment.getProperty("testcontainers.mysql.docker.image")) 30 | .map(imageName -> new MySQLContainerWrapper(database, imageName)) 31 | .orElseGet(() -> new MySQLContainerWrapper(database)); 32 | var container = handleReusable(wrapper); 33 | 34 | Optional.ofNullable(environment.getProperty("testcontainers.mysql.init-script")) 35 | .ifPresent(container::withInitScript); 36 | 37 | resolveStaticPort(dataSourceUrl, GENERIC_URL_WITH_PORT_GROUP_PATTERN) 38 | .ifPresent(staticPort -> bindPort(container, staticPort, MYSQL_PORT)); 39 | 40 | start(container); 41 | 42 | var replacedNameToValue = replaceHostAndPort(urlPropertyNameToValue, container); 43 | var testPropertyValues = addMissingUsernameAndPassword(replacedNameToValue, container); 44 | var values = TestPropertyValues.of(testPropertyValues); 45 | 46 | values.applyTo(applicationContext); 47 | 48 | registerContainerAsBean(applicationContext); 49 | } 50 | 51 | private List getUrlPropertyNames(Environment environment) { 52 | var name = environment.getProperty("testcontainers.mysql.datasource.url.property.name"); 53 | if (Objects.nonNull(name)) { 54 | return Collections.singletonList(name); 55 | } 56 | 57 | var names = environment.getProperty("testcontainers.mysql.datasource.url.property.names", String[].class); 58 | if (Objects.nonNull(names)) { 59 | return Arrays.asList(names); 60 | } 61 | 62 | return DEFAULT_PROPERTY_NAMES; 63 | } 64 | 65 | private Map getUrlPropertyNameToValue(Environment environment, List names) { 66 | Map propertyNameToValue = new HashMap<>(); 67 | 68 | for (String name : names) { 69 | String value = environment.getProperty(name); 70 | if (Objects.nonNull(value)) { 71 | propertyNameToValue.put(name, value); 72 | } 73 | } 74 | 75 | return propertyNameToValue; 76 | } 77 | 78 | private Map replaceHostAndPort(Map urlPropertyNameToValue, 79 | MySQLContainerWrapper container) { 80 | return urlPropertyNameToValue.entrySet() 81 | .stream() 82 | .collect(Collectors.toMap(Map.Entry::getKey, 83 | entry -> replaceHostAndPortPlaceholders(entry.getValue(), 84 | container, 85 | MYSQL_PORT))); 86 | } 87 | 88 | private Map addMissingUsernameAndPassword(Map urlPropertyNameToValue, 89 | MySQLContainerWrapper container) { 90 | var username = container.getUsername(); 91 | var password = container.getPassword(); 92 | 93 | var testPropertyValues = new HashMap<>(urlPropertyNameToValue); 94 | for (var entry : urlPropertyNameToValue.entrySet()) { 95 | String name = entry.getKey(); 96 | if (DEFAULT_PROPERTY_NAMES.contains(name)) { 97 | String root = name.substring(0, name.indexOf(".url")); 98 | testPropertyValues.put(root + ".username", username); 99 | testPropertyValues.put(root + ".password", password); 100 | } 101 | } 102 | return testPropertyValues; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /infobip-mssql-testcontainers-spring-boot-starter/src/main/java/com/infobip/testcontainers/spring/mssql/MSSQLServerContainerInitializer.java: -------------------------------------------------------------------------------- 1 | package com.infobip.testcontainers.spring.mssql; 2 | 3 | import static org.testcontainers.containers.MSSQLServerContainer.IMAGE; 4 | import static org.testcontainers.containers.MSSQLServerContainer.MS_SQL_SERVER_PORT; 5 | 6 | import java.util.Arrays; 7 | import java.util.Collections; 8 | import java.util.HashMap; 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.Objects; 12 | import java.util.Optional; 13 | import java.util.stream.Collectors; 14 | 15 | import com.infobip.testcontainers.InitializerBase; 16 | import org.springframework.boot.test.util.TestPropertyValues; 17 | import org.springframework.context.ConfigurableApplicationContext; 18 | import org.springframework.core.env.Environment; 19 | import org.testcontainers.utility.DockerImageName; 20 | 21 | public class MSSQLServerContainerInitializer extends InitializerBase { 22 | 23 | private static final List DEFAULT_PROPERTY_NAMES = Arrays.asList("spring.datasource.url", 24 | "spring.flyway.url", 25 | "spring.r2dbc.url"); 26 | 27 | @Override 28 | public void initialize(ConfigurableApplicationContext applicationContext) { 29 | var environment = applicationContext.getEnvironment(); 30 | var urlPropertyNames = getUrlPropertyNames(environment); 31 | var urlPropertyNameToValue = getUrlPropertyNameToValue(environment, urlPropertyNames); 32 | var wrapper = Optional.ofNullable(environment.getProperty("testcontainers.mssql.docker.image")) 33 | .map((name)->DockerImageName.parse(name).asCompatibleSubstituteFor(IMAGE)) 34 | .map(MSSQLServerContainerWrapper::new) 35 | .orElseGet(MSSQLServerContainerWrapper::new); 36 | var container = handleReusable(wrapper); 37 | 38 | var initScript = Optional.ofNullable(environment.getProperty("testcontainers.mssql.init-script")) 39 | .map(container::withInitScript); 40 | 41 | resolveStaticPort(urlPropertyNameToValue.values(), GENERIC_URL_WITH_PORT_GROUP_PATTERN) 42 | .ifPresent(staticPort -> bindPort(container, staticPort, MS_SQL_SERVER_PORT)); 43 | 44 | start(container); 45 | var replacedNameToValue = replaceHostAndPort(urlPropertyNameToValue, container); 46 | var testPropertyValues = addMissingUsernameAndPassword(replacedNameToValue, container); 47 | var values = TestPropertyValues.of(testPropertyValues); 48 | 49 | values.applyTo(applicationContext); 50 | if (initScript.isEmpty()) { 51 | String url = replacedNameToValue.getOrDefault("spring.datasource.url", 52 | replacedNameToValue.get("spring.flyway.url")); 53 | DatabaseCreator creator = new DatabaseCreator(url, container.getUsername(), container.getPassword()); 54 | creator.createDatabaseIfItDoesNotExist(); 55 | } 56 | 57 | registerContainerAsBean(applicationContext); 58 | } 59 | 60 | private List getUrlPropertyNames(Environment environment) { 61 | var name = environment.getProperty("testcontainers.mssql.datasource.url.property.name"); 62 | if (Objects.nonNull(name)) { 63 | return Collections.singletonList(name); 64 | } 65 | 66 | var names = environment.getProperty("testcontainers.mssql.datasource.url.property.names", String[].class); 67 | if (Objects.nonNull(names)) { 68 | return Arrays.asList(names); 69 | } 70 | 71 | return DEFAULT_PROPERTY_NAMES; 72 | } 73 | 74 | private Map getUrlPropertyNameToValue(Environment environment, List names) { 75 | Map propertyNameToValue = new HashMap<>(); 76 | 77 | for (String name : names) { 78 | String value = environment.getProperty(name); 79 | if (Objects.nonNull(value)) { 80 | propertyNameToValue.put(name, value); 81 | } 82 | } 83 | 84 | return propertyNameToValue; 85 | } 86 | 87 | private Map replaceHostAndPort(Map urlPropertyNameToValue, 88 | MSSQLServerContainerWrapper container) { 89 | return urlPropertyNameToValue.entrySet() 90 | .stream() 91 | .collect(Collectors.toMap(Map.Entry::getKey, 92 | entry -> replaceHostAndPortPlaceholders(entry.getValue(), 93 | container, 94 | MS_SQL_SERVER_PORT))); 95 | } 96 | 97 | private Map addMissingUsernameAndPassword(Map urlPropertyNameToValue, 98 | MSSQLServerContainerWrapper container) { 99 | var username = container.getUsername(); 100 | var password = container.getPassword(); 101 | 102 | var testPropertyValues = new HashMap<>(urlPropertyNameToValue); 103 | for (var entry : urlPropertyNameToValue.entrySet()) { 104 | String name = entry.getKey(); 105 | if (DEFAULT_PROPERTY_NAMES.contains(name)) { 106 | String root = name.substring(0, name.indexOf(".url")); 107 | testPropertyValues.put(root + ".username", username); 108 | testPropertyValues.put(root + ".password", password); 109 | } 110 | } 111 | return testPropertyValues; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /infobip-testcontainers-bom/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | com.infobip 6 | infobip-testcontainers-bom 7 | infobip-testcontainers-bom 8 | 5.0.1-SNAPSHOT 9 | pom 10 | 11 | Infobip TestContainers Spring Boot Starter provides Spring Boot starters that ease the use of Testcontainers in test and local development scenarios. 12 | 13 | 14 | Infobip Ltd. 15 | https://www.infobip.com/ 16 | 17 | 18 | https://github.com/infobip/infobip-testcontainers-spring-boot-starter 19 | 20 | 21 | 22 | Apache License, Version 2.0 23 | http://www.apache.org/licenses/LICENSE-2.0.txt 24 | repo 25 | A business-friendly OSS license 26 | 27 | 28 | 29 | 30 | git@github.com:infobip/infobip-testcontainers-spring-boot-starter.git 31 | scm:git:git@github.com:infobip/infobip-testcontainers-spring-boot-starter.git 32 | scm:git:git@github.com:infobip/infobip-testcontainers-spring-boot-starter.git 33 | infobip-testcontainers-spring-boot-starter-4.4.22 34 | 35 | 36 | 37 | 38 | lpandzic 39 | Lovro Pandžić 40 | lovro.pandzic@infobip.com 41 | Infobip Ltd. 42 | 43 | 44 | NGril 45 | Niko Gril 46 | niko.gril@infobip.com> 47 | Infobip Ltd. 48 | 49 | 50 | FraneJelavic 51 | Frane Jelavić 52 | frane.jelavic@infobip.com> 53 | Infobip Ltd. 54 | 55 | 56 | igor-susic 57 | Igor Šušić 58 | igor.susic@infobip.com 59 | Infobip Ltd. 60 | 61 | 62 | tin-stavinoha 63 | Tin Stavinoha 64 | tin.stavinoha@infobip.com 65 | Infobip Ltd. 66 | 67 | 68 | rjalic 69 | Roko Jalić 70 | roko.jalic@infobip.com 71 | Infobip Ltd. 72 | 73 | 74 | 75 | 76 | 3.1.0 77 | 0.9.0 78 | 79 | 80 | 81 | 82 | 83 | com.infobip 84 | infobip-mssql-testcontainers-spring-boot-starter 85 | ${project.version} 86 | 87 | 88 | com.infobip 89 | infobip-mysql-testcontainers-spring-boot-starter 90 | ${project.version} 91 | 92 | 93 | com.infobip 94 | infobip-postgresql-testcontainers-spring-boot-starter 95 | ${project.version} 96 | 97 | 98 | com.infobip 99 | infobip-kafka-testcontainers-spring-boot-starter 100 | ${project.version} 101 | 102 | 103 | com.infobip 104 | infobip-redis-testcontainers-spring-boot-starter 105 | ${project.version} 106 | 107 | 108 | com.infobip 109 | infobip-rabbitmq-testcontainers-spring-boot-starter 110 | ${project.version} 111 | 112 | 113 | com.infobip 114 | infobip-clickhouse-testcontainers-spring-boot-starter 115 | ${project.version} 116 | 117 | 118 | com.infobip 119 | infobip-testcontainers-common 120 | ${project.version} 121 | 122 | 123 | com.infobip 124 | infobip-testcontainers-test-common 125 | ${project.version} 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | org.apache.maven.plugins 134 | maven-gpg-plugin 135 | ${maven-gpg-plugin.version} 136 | 137 | 138 | sign-artifacts 139 | verify 140 | 141 | sign 142 | 143 | 144 | 145 | 146 | 147 | 148 | org.sonatype.central 149 | central-publishing-maven-plugin 150 | ${central-publishing-maven-plugin.version} 151 | true 152 | 153 | central 154 | true 155 | published 156 | true 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | release-to-central 165 | 166 | 167 | 168 | org.sonatype.central 169 | central-publishing-maven-plugin 170 | 171 | false 172 | 173 | 174 | 175 | 176 | 177 | 178 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | com.infobip 5 | infobip-testcontainers-spring-boot-starter 6 | 5.0.1-SNAPSHOT 7 | pom 8 | 9 | Infobip TestContainers Spring Boot Starter 10 | 11 | Infobip TestContainers Spring Boot Starter provides Spring Boot starters that ease the use of Testcontainers in test and local development scenarios. 12 | 13 | 14 | Infobip Ltd. 15 | https://www.infobip.com/ 16 | 17 | 18 | https://github.com/infobip/infobip-testcontainers-spring-boot-starter 19 | 20 | 21 | 22 | Apache License, Version 2.0 23 | http://www.apache.org/licenses/LICENSE-2.0.txt 24 | repo 25 | A business-friendly OSS license 26 | 27 | 28 | 29 | 30 | git@github.com:infobip/infobip-testcontainers-spring-boot-starter.git 31 | scm:git:git@github.com:infobip/infobip-testcontainers-spring-boot-starter.git 32 | scm:git:git@github.com:infobip/infobip-testcontainers-spring-boot-starter.git 33 | infobip-testcontainers-spring-boot-starter-4.4.22 34 | 35 | 36 | 37 | infobip-mssql-testcontainers-spring-boot-starter 38 | infobip-mysql-testcontainers-spring-boot-starter 39 | infobip-postgresql-testcontainers-spring-boot-starter 40 | infobip-kafka-testcontainers-spring-boot-starter 41 | infobip-redis-testcontainers-spring-boot-starter 42 | infobip-rabbitmq-testcontainers-spring-boot-starter 43 | infobip-clickhouse-testcontainers-spring-boot-starter 44 | infobip-testcontainers-common 45 | infobip-testcontainers-test-common 46 | infobip-testcontainers-bom 47 | 48 | 49 | 50 | 51 | lpandzic 52 | Lovro Pandžić 53 | lovro.pandzic@infobip.com 54 | Infobip Ltd. 55 | 56 | 57 | NGril 58 | Niko Gril 59 | niko.gril@infobip.com> 60 | Infobip Ltd. 61 | 62 | 63 | FraneJelavic 64 | Frane Jelavić 65 | frane.jelavic@infobip.com> 66 | Infobip Ltd. 67 | 68 | 69 | igor-susic 70 | Igor Šušić 71 | igor.susic@infobip.com 72 | Infobip Ltd. 73 | 74 | 75 | tin-stavinoha 76 | Tin Stavinoha 77 | tin.stavinoha@infobip.com 78 | Infobip Ltd. 79 | 80 | 81 | rjalic 82 | Roko Jalić 83 | roko.jalic@infobip.com 84 | Infobip Ltd. 85 | 86 | 87 | 88 | 89 | 90 | 4.0.0 91 | 92 | 93 | 3.8.1 94 | 4.3.0 95 | 0.8.10 96 | 3.1.0 97 | 3.3.0 98 | 3.1.2 99 | 3.1.2 100 | 101 | 102 | UTF-8 103 | 17 104 | 105 | 106 | 107 | 108 | 109 | org.springframework.boot 110 | spring-boot-dependencies 111 | ${spring-boot.version} 112 | pom 113 | import 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | org.springframework.boot 122 | spring-boot-test 123 | 124 | 125 | 126 | org.springframework.boot 127 | spring-boot-autoconfigure 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | org.apache.maven.plugins 136 | maven-surefire-plugin 137 | ${maven-surefire-plugin.version} 138 | 139 | 140 | org.apache.maven.plugins 141 | maven-failsafe-plugin 142 | ${maven-failsafe-plugin.version} 143 | 144 | 145 | 146 | 147 | 148 | org.apache.maven.plugins 149 | maven-compiler-plugin 150 | ${maven-compiler-plugin.version} 151 | 152 | ${java.version} 153 | -parameters 154 | -parameters 155 | utf8 156 | 157 | 158 | 159 | org.jacoco 160 | jacoco-maven-plugin 161 | ${jacoco-maven-plugin.version} 162 | 163 | 164 | 165 | prepare-agent 166 | 167 | 168 | 169 | report 170 | test 171 | 172 | report 173 | 174 | 175 | 176 | 177 | 178 | 179 | org.eluder.coveralls 180 | coveralls-maven-plugin 181 | ${coveralls-maven-plugin.version} 182 | 183 | 184 | javax.xml.bind 185 | jaxb-api 186 | 2.3.1 187 | 188 | 189 | 190 | 191 | 192 | org.apache.maven.plugins 193 | maven-source-plugin 194 | 3.3.0 195 | 196 | 197 | attach-sources 198 | package 199 | 200 | jar-no-fork 201 | 202 | 203 | 204 | 205 | 206 | 207 | org.apache.maven.plugins 208 | maven-javadoc-plugin 209 | ${maven-javadoc-plugin.version} 210 | 211 | none 212 | 213 | 214 | 215 | attach-javadocs 216 | package 217 | 218 | jar 219 | 220 | 221 | 222 | 223 | 224 | 225 | org.apache.maven.plugins 226 | maven-gpg-plugin 227 | ${maven-gpg-plugin.version} 228 | 229 | 230 | sign-artifacts 231 | verify 232 | 233 | sign 234 | 235 | 236 | 237 | 238 | 239 | 240 | org.sonatype.central 241 | central-publishing-maven-plugin 242 | 0.9.0 243 | true 244 | 245 | central 246 | true 247 | published 248 | true 249 | 250 | 251 | 252 | 253 | org.apache.maven.plugins 254 | maven-deploy-plugin 255 | 3.1.2 256 | 257 | true 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | release-to-central 266 | 267 | 268 | 269 | org.sonatype.central 270 | central-publishing-maven-plugin 271 | 272 | false 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [2020] [Infobip] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Infobip Testcontainers Spring Boot Starter 2 | 3 | [![](https://github.com/infobip/infobip-testcontainers-spring-boot-starter/workflows/maven/badge.svg)](https://github.com/infobip/infobip-testcontainers-spring-boot-starter/actions?query=workflow%3Amaven) 4 | [![Maven Central](https://maven-badges.sml.io/sonatype-central/com.infobip/infobip-testcontainers-spring-boot-starter/badge.svg)](https://maven-badges.sml.io/sonatype-central/com.infobip/infobip-testcontainers-spring-boot-starter) 5 | [![Coverage Status](https://coveralls.io/repos/github/infobip/infobip-testcontainers-spring-boot-starter/badge.svg?branch=master)](https://coveralls.io/github/infobip/infobip-testcontainers-spring-boot-starter?branch=master) 6 | 7 | Library containing Spring Boot starters which manage lifecycle (start/stop) of [testcontainers](https://www.testcontainers.org/). 8 | 9 | Usual use cases include: 10 | - tests (container is started during test spring context initialization and stopped during context destruction) 11 | - local development (e.g. to remove manual setup of local DB) 12 | 13 | ## Contents 14 | 15 | * [Changelog](#Changelog) 16 | * [Usage](#Usage) 17 | * [General](#General) 18 | * [Reusable](#Reusable) 19 | * [MSSQL](#MSSQL) 20 | * [Tests](#MSSQLTests) 21 | * [Local development](#MSSQLLocalDevelopment) 22 | * [Docker image version](#MSSQLDockerImage) 23 | * [Initialization script](#MSSQLInitScript) 24 | * [MySQL](#MySQL) 25 | * [Tests](#MySQLTests) 26 | * [Local development](#MySQLLocalDevelopment) 27 | * [Docker image version](#MySQLDockerImage) 28 | * [Initialization script](#MySQLInitScript) 29 | * [PostgreSQL](#PostgreSQL) 30 | * [Tests](#PostgreSQLTests) 31 | * [Local development](#PostgreSQLLocalDevelopment) 32 | * [Docker image version](#PostgreSQLDockerImage) 33 | * [Initialization script](#PostgreSQLInitScript) 34 | * [Redis](#Redis) 35 | * [Tests](#RedisTests) 36 | * [Local development](#RedisDevelopment) 37 | * [Docker image version](#RedisDockerImage) 38 | * [Kafka](#Kafka) 39 | * [Automatic topic creation](#KafkaTopic) 40 | * [Tests](#KafkaTests) 41 | * [Local development](#KafkaLocalDevelopment) 42 | * [Docker image version](#KafkaDockerImageVersion) 43 | * [RabbitMQ](#RabbitMq) 44 | * [Tests](#RabbitMqTests) 45 | * [Local development](#RabbitMqLocalDevelopment) 46 | * [Docker image version](#RabbitMqDockerImage) 47 | * [ClickHouse](#ClickHouse) 48 | * [Tests](#ClickHouseTests) 49 | * [Local development](#ClickHouseLocalDevelopment) 50 | * [Docker image version](#ClickHouseDockerImage) 51 | * [Initialization script](#ClickHouseInitScript) 52 | 53 | 54 | ## Changelog 55 | 56 | For changes check the [changelog](CHANGELOG.md). 57 | 58 | 59 | ## Usage 60 | 61 | 62 | ### General 63 | 64 | This library tries to reuse existing Spring Boot configuration classes and enhance their behaviour by performing some extra steps around them. 65 | Generally, in cases where port placeholders are used (``), the library will make sure that the appropriate Docker container is started on 66 | a randomly selected open port and that the selected value will be used by the configuration in the runtime. 67 | 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. 68 | 69 | 70 | ### Reusable 71 | If [reuse is enabled](https://java.testcontainers.org/features/reuse/) this project automatically marks all created containers for reuse. 72 | 73 | 74 | ### MSSQL 75 | 76 | **Disclaimer**: by using this testcontainer you accept the EULA for mssql docker image as [required here](https://hub.docker.com/_/microsoft-mssql-server). 77 | 78 | 79 | #### Tests: 80 | 81 | Include the dependency: 82 | 83 | ```xml 84 | 85 | com.infobip 86 | infobip-mssql-testcontainers-spring-boot-starter 87 | ${infobip-mssql-testcontainers-spring-boot-starter.version} 88 | test 89 | 90 | ``` 91 | 92 | jTDS: 93 | 94 | ```yaml 95 | spring: 96 | datasource: 97 | url: jdbc:jtds:sqlserver://:/FooBarDb 98 | ``` 99 | 100 | Microsoft driver: 101 | 102 | ```yaml 103 | spring: 104 | datasource: 105 | url: jdbc:sqlserver://:;database=FooBarDb 106 | ``` 107 | 108 | Logical database is automatically created. 109 | Container IP address is resolved based on running host, meaning on local machine `` will resolve to `localhost` 110 | while inside Docker placeholder will resolve to `containerIp`. 111 | When `` placeholder is used, container will be mapped on random port and automatically substituted. 112 | 113 | 114 | #### Local Development: 115 | 116 | Add the following profile: 117 | 118 | ```xml 119 | 120 | 121 | development 122 | 123 | 124 | com.infobip 125 | infobip-mssql-testcontainers-spring-boot-starter 126 | ${infobip-mssql-testcontainers-spring-boot-starter.version} 127 | 128 | 129 | 130 | 131 | ``` 132 | 133 | Before starting the application locally, activate development profile: 134 | 135 | ![profile.png](profile.png) 136 | 137 | and update your local configuration (e.g. application-development.yaml): 138 | 139 | jTDS: 140 | 141 | ```yaml 142 | spring: 143 | datasource: 144 | url: jdbc:jtds:sqlserver://:/FooBarDb_test_${user.name} 145 | ``` 146 | 147 | Microsoft driver: 148 | 149 | ```yaml 150 | spring: 151 | datasource: 152 | url: jdbc:sqlserver://:;database=FooBarDb_test_${user.name} 153 | ``` 154 | 155 | 156 | #### Docker image: 157 | 158 | To change the docker image used simply add the following property (e.g. in yaml): 159 | 160 | ```yaml 161 | testcontainers.mssql.docker.image: mcr.microsoft.com/mssql/server:2017-CU12 162 | ``` 163 | 164 | 165 | #### Initialization script 166 | 167 | To add an SQL script with which the container will be initialized with add the following property (e.g. in yaml): 168 | 169 | ```yaml 170 | testcontainers.mssql.init-script: db/init-script.sql 171 | ``` 172 | 173 | 174 | ### MySQL 175 | 176 | 177 | #### Tests: 178 | 179 | Include the dependency: 180 | 181 | ```xml 182 | 183 | com.infobip 184 | infobip-mysql-testcontainers-spring-boot-starter 185 | ${infobip-mysql-testcontainers-spring-boot-starter.version} 186 | test 187 | 188 | ``` 189 | 190 | Configuration: 191 | 192 | ```yaml 193 | spring: 194 | datasource: 195 | url: jdbc:mysql://:/FooBarDb 196 | username: test 197 | password: test 198 | ``` 199 | 200 | Logical database is automatically created. 201 | Container IP address is resolved based on running host, meaning on local machine `` will resolve to `localhost` 202 | while inside Docker placeholder will resolve to `containerIp`. 203 | When `` placeholder is used, container will be mapped on random port and automatically substituted. 204 | 205 | 206 | #### Local Development: 207 | 208 | Add the following profile: 209 | 210 | ```xml 211 | 212 | 213 | development 214 | 215 | 216 | com.infobip 217 | infobip-mysql-testcontainers-spring-boot-starter 218 | ${infobip-mysql-testcontainers-spring-boot-starter.version} 219 | test 220 | 221 | 222 | 223 | 224 | ``` 225 | 226 | Before starting the application locally, activate development profile: 227 | 228 | ![profile.png](profile.png) 229 | 230 | and update your local configuration (e.g. application-development.yaml): 231 | 232 | ```yaml 233 | spring: 234 | datasource: 235 | url: jdbc:mysql://:/FooBarDb_test_${user.name} 236 | username: test 237 | password: test 238 | ``` 239 | 240 | 241 | #### Docker image: 242 | 243 | To change the docker image used simply add the following property (e.g. in yaml): 244 | 245 | ```yaml 246 | testcontainers.mysql.docker.image: mysql:5.7.34 247 | ``` 248 | 249 | 250 | #### Initialization script 251 | 252 | To add an SQL script with which the container will be initialized with add the following property (e.g. in yaml): 253 | 254 | ```yaml 255 | testcontainers.mysql.init-script: db/init-script.sql 256 | ``` 257 | 258 | 259 | ### PostgreSQL 260 | 261 | 262 | #### Tests: 263 | 264 | Include the dependency: 265 | 266 | ```xml 267 | 268 | com.infobip 269 | infobip-postgresql-testcontainers-spring-boot-starter 270 | ${infobip-postgresql-testcontainers-spring-boot-starter.version} 271 | test 272 | 273 | ``` 274 | 275 | Configuration: 276 | 277 | ```yaml 278 | spring: 279 | datasource: 280 | url: jdbc:postgresql://:/FooBarDb 281 | username: test 282 | password: test 283 | ``` 284 | 285 | Logical database is automatically created. 286 | Container IP address is resolved based on running host, meaning on local machine `` will resolve to `localhost` 287 | while inside Docker placeholder will resolve to `containerIp`. 288 | When `` placeholder is used, container will be mapped on random port and automatically substituted. 289 | 290 | 291 | #### Local Development: 292 | 293 | Add the following profile: 294 | 295 | ```xml 296 | 297 | 298 | development 299 | 300 | 301 | com.infobip 302 | infobip-postgresql-testcontainers-spring-boot-starter 303 | ${infobip-postgresql-testcontainers-spring-boot-starter.version} 304 | test 305 | 306 | 307 | 308 | 309 | ``` 310 | 311 | Before starting the application locally, activate development profile: 312 | 313 | ![profile.png](profile.png) 314 | 315 | and update your local configuration (e.g. application-development.yaml): 316 | 317 | ```yaml 318 | spring: 319 | datasource: 320 | url: jdbc:postgresql://:/FooBarDb_test_${user.name} 321 | username: test 322 | password: test 323 | ``` 324 | 325 | 326 | #### Docker image: 327 | 328 | To change the docker image used simply add the following property (e.g. in yaml): 329 | 330 | ```yaml 331 | testcontainers.postgresql.docker.image: postgres:15 332 | ``` 333 | 334 | 335 | #### Initialization script 336 | 337 | To add an SQL script with which the container will be initialized with add the following property (e.g. in yaml): 338 | 339 | ```yaml 340 | testcontainers.postgresql.init-script: db/init-script.sql 341 | ``` 342 | 343 | 344 | ### Redis 345 | 346 | 347 | #### Tests: 348 | 349 | Include the dependency: 350 | 351 | ```xml 352 | 353 | com.infobip 354 | infobip-redis-testcontainers-spring-boot-starter 355 | ${infobip-redis-testcontainers-spring-boot-starter.version} 356 | test 357 | 358 | ``` 359 | 360 | Configuration: 361 | 362 | ```yaml 363 | spring: 364 | redis: 365 | url: redis://: 366 | ``` 367 | 368 | Container IP address is resolved based on running host, meaning on local machine `` will resolve to `localhost` 369 | while inside Docker placeholder will resolve to `containerIp`. 370 | When `` placeholder is used, container will be mapped on random port and automatically substituted. 371 | 372 | 373 | #### Local Development: 374 | 375 | Add the following profile: 376 | 377 | ```xml 378 | 379 | 380 | development 381 | 382 | 383 | com.infobip 384 | infobip-redis-testcontainers-spring-boot-starter 385 | ${infobip-redis-testcontainers-spring-boot-starter.version} 386 | test 387 | 388 | 389 | 390 | 391 | ``` 392 | 393 | Before starting the application locally, activate development profile: 394 | 395 | ![profile.png](profile.png) 396 | 397 | and update your local configuration (e.g. application-development.yaml): 398 | 399 | ```yaml 400 | spring: 401 | redis: 402 | url: redis://: 403 | ``` 404 | 405 | 406 | #### Docker image: 407 | 408 | To change the docker image used simply add the following property (e.g. in yaml): 409 | 410 | ```yaml 411 | testcontainers.redis.docker.image: redis:5.0.7-alpine 412 | ``` 413 | 414 | 415 | ### Kafka 416 | 417 | 418 | #### Automatic topic creation 419 | 420 | Format: `::` 421 | 422 | ```yaml 423 | testcontainers.kafka.topics: test-topic:1:1, test-topic-2:1:1 424 | ``` 425 | 426 | 427 | #### Tests: 428 | 429 | Include the dependency: 430 | 431 | ```xml 432 | 433 | com.infobip 434 | infobip-kafka-testcontainers-spring-boot-starter 435 | ${infobip-kafka-testcontainers-spring-boot-starter.version} 436 | test 437 | 438 | ``` 439 | 440 | Configuration: 441 | 442 | ```yaml 443 | spring: 444 | kafka: 445 | bootstrap-servers: : 446 | ``` 447 | 448 | Logical database is automatically created. 449 | Container IP address is resolved based on running host, meaning on local machine `` will resolve to `localhost` 450 | while inside Docker placeholder will resolve to `containerIp`. 451 | When `` placeholder is used, container will be mapped on random port and automatically substituted. 452 | 453 | 454 | #### Local Development: 455 | 456 | Add the following profile: 457 | 458 | ```xml 459 | 460 | 461 | development 462 | 463 | 464 | com.infobip 465 | infobip-kafka-testcontainers-spring-boot-starter 466 | ${infobip-kafka-testcontainers-spring-boot-starter.version} 467 | test 468 | 469 | 470 | 471 | 472 | ``` 473 | 474 | Before starting the application locally, activate development profile: 475 | 476 | ![profile.png](profile.png) 477 | 478 | and update your local configuration (e.g. application-development.yaml): 479 | 480 | ```yaml 481 | spring: 482 | kafka: 483 | bootstrap-servers: : 484 | ``` 485 | 486 | 487 | #### Docker image: 488 | 489 | To change the docker image version used simply add the following property (e.g. in yaml): 490 | 491 | ```yaml 492 | testcontainers.kafka.docker.image.version: 2.1.0 493 | ``` 494 | 495 | 496 | ### RabbitMq 497 | 498 | 499 | #### Tests: 500 | 501 | Include the dependency: 502 | 503 | ```xml 504 | 505 | com.infobip 506 | infobip-rabbitmq-testcontainers-spring-boot-starter 507 | ${infobip-rabbitmq-testcontainers-spring-boot-starter.version} 508 | test 509 | 510 | ``` 511 | 512 | #### Test Configuration: 513 | 514 | To configure RabbitMq in tests you need to create it's configuration for example: 515 | 516 | ```java 517 | @Configuration 518 | @Profile({"test", "development"}) 519 | public class RabbitConfigTestEnv { 520 | 521 | @Bean 522 | public Queue testQueue() { 523 | return QueueBuilder.durable("test.queue").build(); 524 | } 525 | 526 | @Bean 527 | public TopicExchange testExchange() { 528 | return new TopicExchange("test.exchange"); 529 | } 530 | 531 | @Bean 532 | public Binding bindToTestExchange() { 533 | return bind(testQueue()).to(testExchange()).with("test.key.#"); 534 | } 535 | } 536 | ``` 537 | 538 | This class should live inside test files and there you can create queues, exchanges and key routing bindings or receivers. 539 | In this example method: 540 | * `testQueue` creates queue with name `test.queue` 541 | * `testExchange` creates exchange with name `test.exchange` 542 | * `bindToTestExchange` tells Rabbit to send any message sent to test exchange, with key of value `test.key.#` to our test queue 543 | 544 | Important: Queues are declared in Rabbit only after some message is sent to the queue. 545 | If you log into `docker` and try to find queue, it won't be listed if no message was sent to it. 546 | 547 | 548 | #### Local Development: 549 | 550 | Add the following profile: 551 | 552 | ```xml 553 | 554 | 555 | development 556 | 557 | 558 | com.infobip 559 | infobip-rabbitmq-testcontainers-spring-boot-starter 560 | ${infobip-rabbitmq-testcontainers-spring-boot-starter.version} 561 | test 562 | 563 | 564 | 565 | 566 | ``` 567 | 568 | Before starting the application locally, activate development profile: 569 | 570 | ![profile.png](profile.png) 571 | 572 | 573 | #### Docker image: 574 | 575 | To change the docker image used simply add the following property (e.g. in yaml): 576 | 577 | ```yaml 578 | testcontainers.rabbit.docker.image: rabbitmq:3.6.14-alpine 579 | ``` 580 | 581 | ### ClickHouse 582 | 583 | 584 | #### Tests 585 | 586 | Include the dependency: 587 | 588 | ```xml 589 | 590 | com.infobip 591 | infobip-clickhouse-testcontainers-spring-boot-starter 592 | ${infobip-clickhouse-testcontainers-spring-boot-starter.version} 593 | test 594 | 595 | ``` 596 | 597 | 598 | #### Local development 599 | 600 | Add the following profile: 601 | 602 | ```xml 603 | 604 | 605 | development 606 | 607 | 608 | com.infobip 609 | infobip-clickhouse-testcontainers-spring-boot-starter 610 | ${infobip-clickhouse-testcontainers-spring-boot-starter.version} 611 | test 612 | 613 | 614 | 615 | 616 | ``` 617 | 618 | Before starting the application locally, activate development profile: 619 | 620 | ![profile.png](profile.png) 621 | 622 | and update your local configuration (e.g. application-development.yaml): 623 | 624 | ```yaml 625 | spring: 626 | datasource: 627 | jdbc-url: : 628 | ``` 629 | In case your datasource configuration is different from default one you can provide custom configuration property path 630 | ```yaml 631 | testcontainers.clickhouse.custom-path: "spring.datasource.clickhouse" 632 | ``` 633 | in this case your configuration would look like this 634 | 635 | ```yaml 636 | spring: 637 | datasource: 638 | clickhouse: 639 | jdbc-url: : 640 | ``` 641 | 642 | 643 | #### Docker image version 644 | 645 | To change the docker image used simply add the following property (e.g. in yaml): 646 | 647 | ```yaml 648 | testcontainers.clickhouse.docker.image: clickhouse:latest 649 | ``` 650 | 651 | 652 | #### Initialization script 653 | 654 | To add an SQL script with which the container will be initialized with add the following property (e.g. in yaml): 655 | 656 | ```yaml 657 | testcontainers.clickhouse.init-script: db/init-script.sql 658 | ``` 659 | 660 | ## Contributing 661 | 662 | If you have an idea for a new feature or want to report a bug please use the issue tracker. 663 | 664 | Pull requests are welcome! 665 | 666 | ## License 667 | 668 | This library is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0). 669 | 670 | --------------------------------------------------------------------------------