Rework Docker Compose integration tests

This commit introduces a new annotation, `@DockerComposeTest`,
that allows a test class to have multiple tests, each of which
uses a different Docker Compose YAML file.

Closes gh-41154
This commit is contained in:
Andy Wilkinson 2024-06-19 19:27:10 -07:00 committed by Phillip Webb
parent 491f34d25c
commit 43cd24102f
29 changed files with 324 additions and 375 deletions

View File

@ -16,10 +16,8 @@
package org.springframework.boot.docker.compose.service.connection.activemq;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
@ -29,15 +27,10 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Stephane Nicoll
*/
class ActiveMQDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
class ActiveMQDockerComposeConnectionDetailsFactoryIntegrationTests {
ActiveMQDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("activemq-compose.yaml", TestImage.ACTIVE_MQ);
}
@Test
void runCreatesConnectionDetails() {
ActiveMQConnectionDetails connectionDetails = run(ActiveMQConnectionDetails.class);
@DockerComposeTest(composeFile = "activemq-compose.yaml", image = TestImage.ACTIVE_MQ)
void runCreatesConnectionDetails(ActiveMQConnectionDetails connectionDetails) {
assertThat(connectionDetails.getBrokerUrl()).isNotNull().startsWith("tcp://");
assertThat(connectionDetails.getUser()).isEqualTo("root");
assertThat(connectionDetails.getPassword()).isEqualTo("secret");

View File

@ -18,11 +18,9 @@ package org.springframework.boot.docker.compose.service.connection.cassandra;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.cassandra.CassandraConnectionDetails;
import org.springframework.boot.autoconfigure.cassandra.CassandraConnectionDetails.Node;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
@ -32,15 +30,10 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Scott Frederick
*/
class CassandraDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
class CassandraDockerComposeConnectionDetailsFactoryIntegrationTests {
CassandraDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("cassandra-compose.yaml", TestImage.CASSANDRA);
}
@Test
void runCreatesConnectionDetails() {
CassandraConnectionDetails connectionDetails = run(CassandraConnectionDetails.class);
@DockerComposeTest(composeFile = "cassandra-compose.yaml", image = TestImage.CASSANDRA)
void runCreatesConnectionDetails(CassandraConnectionDetails connectionDetails) {
List<Node> contactPoints = connectionDetails.getContactPoints();
assertThat(contactPoints).hasSize(1);
Node node = contactPoints.get(0);

View File

@ -16,12 +16,10 @@
package org.springframework.boot.docker.compose.service.connection.elasticsearch;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails;
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails.Node;
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails.Node.Protocol;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
@ -33,15 +31,10 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Andy Wilkinson
* @author Phillip Webb
*/
class ElasticsearchDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
class ElasticsearchDockerComposeConnectionDetailsFactoryIntegrationTests {
ElasticsearchDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("elasticsearch-compose.yaml", TestImage.ELASTICSEARCH_8);
}
@Test
void runCreatesConnectionDetails() {
ElasticsearchConnectionDetails connectionDetails = run(ElasticsearchConnectionDetails.class);
@DockerComposeTest(composeFile = "elasticsearch-compose.yaml", image = TestImage.ELASTICSEARCH_8)
void runCreatesConnectionDetails(ElasticsearchConnectionDetails connectionDetails) {
assertThat(connectionDetails.getUsername()).isEqualTo("elastic");
assertThat(connectionDetails.getPassword()).isEqualTo("secret");
assertThat(connectionDetails.getPathPrefix()).isNull();

View File

@ -16,10 +16,8 @@
package org.springframework.boot.docker.compose.service.connection.flyway;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.flyway.FlywayConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
@ -29,15 +27,10 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Andy Wilkinson
*/
class JdbcAdaptingFlywayConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
class JdbcAdaptingFlywayConnectionDetailsFactoryIntegrationTests {
JdbcAdaptingFlywayConnectionDetailsFactoryIntegrationTests() {
super("flyway-compose.yaml", TestImage.POSTGRESQL);
}
@Test
void runCreatesConnectionDetails() {
FlywayConnectionDetails connectionDetails = run(FlywayConnectionDetails.class);
@DockerComposeTest(composeFile = "flyway-compose.yaml", image = TestImage.POSTGRESQL)
void runCreatesConnectionDetails(FlywayConnectionDetails connectionDetails) {
assertThat(connectionDetails.getUsername()).isEqualTo("myuser");
assertThat(connectionDetails.getPassword()).isEqualTo("secret");
assertThat(connectionDetails.getJdbcUrl()).startsWith("jdbc:postgresql://").endsWith("/mydatabase");

View File

@ -16,10 +16,8 @@
package org.springframework.boot.docker.compose.service.connection.liquibase;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
@ -29,15 +27,10 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Andy Wilkinson
*/
class JdbcAdaptingLiquibaseConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
class JdbcAdaptingLiquibaseConnectionDetailsFactoryIntegrationTests {
JdbcAdaptingLiquibaseConnectionDetailsFactoryIntegrationTests() {
super("liquibase-compose.yaml", TestImage.POSTGRESQL);
}
@Test
void runCreatesConnectionDetails() {
LiquibaseConnectionDetails connectionDetails = run(LiquibaseConnectionDetails.class);
@DockerComposeTest(composeFile = "liquibase-compose.yaml", image = TestImage.POSTGRESQL)
void runCreatesConnectionDetails(LiquibaseConnectionDetails connectionDetails) {
assertThat(connectionDetails.getUsername()).isEqualTo("myuser");
assertThat(connectionDetails.getPassword()).isEqualTo("secret");
assertThat(connectionDetails.getJdbcUrl()).startsWith("jdbc:postgresql://").endsWith("/mydatabase");

View File

@ -16,10 +16,8 @@
package org.springframework.boot.docker.compose.service.connection.mariadb;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
@ -31,15 +29,10 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Andy Wilkinson
* @author Phillip Webb
*/
class MariaDbJdbcDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
class MariaDbJdbcDockerComposeConnectionDetailsFactoryIntegrationTests {
MariaDbJdbcDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("mariadb-compose.yaml", TestImage.MARIADB);
}
@Test
void runCreatesConnectionDetails() {
JdbcConnectionDetails connectionDetails = run(JdbcConnectionDetails.class);
@DockerComposeTest(composeFile = "mariadb-compose.yaml", image = TestImage.MARIADB)
void runCreatesConnectionDetails(JdbcConnectionDetails connectionDetails) {
assertThat(connectionDetails.getUsername()).isEqualTo("myuser");
assertThat(connectionDetails.getPassword()).isEqualTo("secret");
assertThat(connectionDetails.getJdbcUrl()).startsWith("jdbc:mariadb://").endsWith("/mydatabase");

View File

@ -17,10 +17,9 @@
package org.springframework.boot.docker.compose.service.connection.mariadb;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
@ -32,15 +31,10 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Andy Wilkinson
* @author Phillip Webb
*/
class MariaDbR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
class MariaDbR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
MariaDbR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("mariadb-compose.yaml", TestImage.MARIADB);
}
@Test
void runCreatesConnectionDetails() {
R2dbcConnectionDetails connectionDetails = run(R2dbcConnectionDetails.class);
@DockerComposeTest(composeFile = "mariadb-compose.yaml", image = TestImage.MARIADB)
void runCreatesConnectionDetails(R2dbcConnectionDetails connectionDetails) {
ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions();
assertThat(connectionFactoryOptions.toString()).contains("database=mydatabase", "driver=mariadb",
"password=REDACTED", "user=myuser");

View File

@ -17,10 +17,9 @@
package org.springframework.boot.docker.compose.service.connection.mongo;
import com.mongodb.ConnectionString;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
@ -33,15 +32,10 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Phillip Webb
* @author Scott Frederick
*/
class MongoDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
class MongoDockerComposeConnectionDetailsFactoryIntegrationTests {
MongoDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("mongo-compose.yaml", TestImage.MONGODB);
}
@Test
void runCreatesConnectionDetails() {
MongoConnectionDetails connectionDetails = run(MongoConnectionDetails.class);
@DockerComposeTest(composeFile = "mongo-compose.yaml", image = TestImage.MONGODB)
void runCreatesConnectionDetails(MongoConnectionDetails connectionDetails) {
ConnectionString connectionString = connectionDetails.getConnectionString();
assertThat(connectionString.getCredential().getUserName()).isEqualTo("root");
assertThat(connectionString.getCredential().getPassword()).isEqualTo("secret".toCharArray());

View File

@ -16,10 +16,8 @@
package org.springframework.boot.docker.compose.service.connection.mysql;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
@ -31,15 +29,10 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Andy Wilkinson
* @author Phillip Webb
*/
class MySqlJdbcDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
class MySqlJdbcDockerComposeConnectionDetailsFactoryIntegrationTests {
MySqlJdbcDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("mysql-compose.yaml", TestImage.MYSQL);
}
@Test
void runCreatesConnectionDetails() {
JdbcConnectionDetails connectionDetails = run(JdbcConnectionDetails.class);
@DockerComposeTest(composeFile = "mysql-compose.yaml", image = TestImage.MYSQL)
void runCreatesConnectionDetails(JdbcConnectionDetails connectionDetails) {
assertThat(connectionDetails.getUsername()).isEqualTo("myuser");
assertThat(connectionDetails.getPassword()).isEqualTo("secret");
assertThat(connectionDetails.getJdbcUrl()).startsWith("jdbc:mysql://").endsWith("/mydatabase");

View File

@ -17,10 +17,9 @@
package org.springframework.boot.docker.compose.service.connection.mysql;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
@ -32,15 +31,10 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Andy Wilkinson
* @author Phillip Webb
*/
class MySqlR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
class MySqlR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
MySqlR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("mysql-compose.yaml", TestImage.MYSQL);
}
@Test
void runCreatesConnectionDetails() {
R2dbcConnectionDetails connectionDetails = run(R2dbcConnectionDetails.class);
@DockerComposeTest(composeFile = "mysql-compose.yaml", image = TestImage.MYSQL)
void runCreatesConnectionDetails(R2dbcConnectionDetails connectionDetails) {
ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions();
assertThat(connectionFactoryOptions.toString()).contains("database=mydatabase", "driver=mysql",
"password=REDACTED", "user=myuser");

View File

@ -16,13 +16,12 @@
package org.springframework.boot.docker.compose.service.connection.neo4j;
import org.junit.jupiter.api.Test;
import org.neo4j.driver.AuthTokens;
import org.neo4j.driver.Driver;
import org.neo4j.driver.GraphDatabase;
import org.springframework.boot.autoconfigure.neo4j.Neo4jConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
@ -33,15 +32,10 @@ import static org.assertj.core.api.Assertions.assertThatNoException;
*
* @author Andy Wilkinson
*/
class Neo4jDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
class Neo4jDockerComposeConnectionDetailsFactoryIntegrationTests {
Neo4jDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("neo4j-compose.yaml", TestImage.NEO4J);
}
@Test
void runCreatesConnectionDetailsThatCanAccessNeo4j() {
Neo4jConnectionDetails connectionDetails = run(Neo4jConnectionDetails.class);
@DockerComposeTest(composeFile = "neo4j-compose.yaml", image = TestImage.NEO4J)
void runCreatesConnectionDetailsThatCanAccessNeo4j(Neo4jConnectionDetails connectionDetails) {
assertThat(connectionDetails.getAuthToken()).isEqualTo(AuthTokens.basic("neo4j", "secret"));
try (Driver driver = GraphDatabase.driver(connectionDetails.getUri(), connectionDetails.getAuthToken())) {
assertThatNoException().isThrownBy(driver::verifyConnectivity);

View File

@ -20,11 +20,10 @@ import java.sql.Driver;
import java.time.Duration;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.OS;
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.boot.testsupport.junit.DisabledOnOs;
@ -41,17 +40,12 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64",
disabledReason = "The Oracle image has no ARM support")
class OracleFreeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests
extends AbstractDockerComposeIntegrationTests {
class OracleFreeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests {
OracleFreeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("oracle-compose.yaml", TestImage.ORACLE_FREE);
}
@Test
@SuppressWarnings("unchecked")
void runCreatesConnectionDetailsThatCanBeUsedToAccessDatabase() throws Exception {
JdbcConnectionDetails connectionDetails = run(JdbcConnectionDetails.class);
@DockerComposeTest(composeFile = "oracle-compose.yaml", image = TestImage.ORACLE_FREE)
void runCreatesConnectionDetailsThatCanBeUsedToAccessDatabase(JdbcConnectionDetails connectionDetails)
throws Exception {
assertThat(connectionDetails.getUsername()).isEqualTo("app_user");
assertThat(connectionDetails.getPassword()).isEqualTo("app_user_secret");
assertThat(connectionDetails.getJdbcUrl()).startsWith("jdbc:oracle:thin:@").endsWith("/freepdb1");

View File

@ -21,11 +21,10 @@ import java.time.Duration;
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.OS;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.boot.testsupport.junit.DisabledOnOs;
@ -40,16 +39,10 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64",
disabledReason = "The Oracle image has no ARM support")
class OracleFreeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests
extends AbstractDockerComposeIntegrationTests {
class OracleFreeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
OracleFreeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("oracle-compose.yaml", TestImage.ORACLE_FREE);
}
@Test
void runCreatesConnectionDetailsThatCanBeUsedToAccessDatabase() {
R2dbcConnectionDetails connectionDetails = run(R2dbcConnectionDetails.class);
@DockerComposeTest(composeFile = "oracle-compose.yaml", image = TestImage.ORACLE_FREE)
void runCreatesConnectionDetailsThatCanBeUsedToAccessDatabase(R2dbcConnectionDetails connectionDetails) {
ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions();
assertThat(connectionFactoryOptions.toString()).contains("database=freepdb1", "driver=oracle",
"password=REDACTED", "user=app_user");

View File

@ -20,11 +20,10 @@ import java.sql.Driver;
import java.time.Duration;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.OS;
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.boot.testsupport.junit.DisabledOnOs;
@ -41,16 +40,12 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64",
disabledReason = "The Oracle image has no ARM support")
class OracleXeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
class OracleXeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests {
OracleXeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("oracle-compose.yaml", TestImage.ORACLE_XE);
}
@Test
@SuppressWarnings("unchecked")
void runCreatesConnectionDetailsThatCanBeUsedToAccessDatabase() throws Exception {
JdbcConnectionDetails connectionDetails = run(JdbcConnectionDetails.class);
@DockerComposeTest(composeFile = "oracle-compose.yaml", image = TestImage.ORACLE_XE)
void runCreatesConnectionDetailsThatCanBeUsedToAccessDatabase(JdbcConnectionDetails connectionDetails)
throws Exception {
assertThat(connectionDetails.getUsername()).isEqualTo("app_user");
assertThat(connectionDetails.getPassword()).isEqualTo("app_user_secret");
assertThat(connectionDetails.getJdbcUrl()).startsWith("jdbc:oracle:thin:@").endsWith("/xepdb1");

View File

@ -21,11 +21,10 @@ import java.time.Duration;
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.OS;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.boot.testsupport.junit.DisabledOnOs;
@ -40,15 +39,10 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64",
disabledReason = "The Oracle image has no ARM support")
class OracleXeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
class OracleXeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
OracleXeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("oracle-compose.yaml", TestImage.ORACLE_XE);
}
@Test
void runCreatesConnectionDetailsThatCanBeUsedToAccessDatabase() {
R2dbcConnectionDetails connectionDetails = run(R2dbcConnectionDetails.class);
@DockerComposeTest(composeFile = "oracle-compose.yaml", image = TestImage.ORACLE_XE)
void runCreatesConnectionDetailsThatCanBeUsedToAccessDatabase(R2dbcConnectionDetails connectionDetails) {
ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions();
assertThat(connectionFactoryOptions.toString()).contains("database=xepdb1", "driver=oracle",
"password=REDACTED", "user=app_user");

View File

@ -16,10 +16,8 @@
package org.springframework.boot.docker.compose.service.connection.otlp;
import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
@ -30,16 +28,10 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Eddú Meléndez
*/
class OpenTelemetryMetricsDockerComposeConnectionDetailsFactoryIntegrationTests
extends AbstractDockerComposeIntegrationTests {
class OpenTelemetryMetricsDockerComposeConnectionDetailsFactoryIntegrationTests {
OpenTelemetryMetricsDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("otlp-compose.yaml", TestImage.OPENTELEMETRY);
}
@Test
void runCreatesConnectionDetails() {
OtlpMetricsConnectionDetails connectionDetails = run(OtlpMetricsConnectionDetails.class);
@DockerComposeTest(composeFile = "otlp-compose.yaml", image = TestImage.OPENTELEMETRY)
void runCreatesConnectionDetails(OtlpMetricsConnectionDetails connectionDetails) {
assertThat(connectionDetails.getUrl()).startsWith("http://").endsWith("/v1/metrics");
}

View File

@ -16,10 +16,8 @@
package org.springframework.boot.docker.compose.service.connection.otlp;
import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
@ -30,16 +28,10 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Eddú Meléndez
*/
class OpenTelemetryTracingDockerComposeConnectionDetailsFactoryIntegrationTests
extends AbstractDockerComposeIntegrationTests {
class OpenTelemetryTracingDockerComposeConnectionDetailsFactoryIntegrationTests {
OpenTelemetryTracingDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("otlp-compose.yaml", TestImage.OPENTELEMETRY);
}
@Test
void runCreatesConnectionDetails() {
OtlpTracingConnectionDetails connectionDetails = run(OtlpTracingConnectionDetails.class);
@DockerComposeTest(composeFile = "otlp-compose.yaml", image = TestImage.OPENTELEMETRY)
void runCreatesConnectionDetails(OtlpTracingConnectionDetails connectionDetails) {
assertThat(connectionDetails.getUrl()).startsWith("http://").endsWith("/v1/traces");
}

View File

@ -16,10 +16,8 @@
package org.springframework.boot.docker.compose.service.connection.postgres;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
@ -31,15 +29,10 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Andy Wilkinson
* @author Phillip Webb
*/
class PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
class PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests {
PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("postgres-compose.yaml", TestImage.POSTGRESQL);
}
@Test
void runCreatesConnectionDetails() {
JdbcConnectionDetails connectionDetails = run(JdbcConnectionDetails.class);
@DockerComposeTest(composeFile = "postgres-compose.yaml", image = TestImage.POSTGRESQL)
void runCreatesConnectionDetails(JdbcConnectionDetails connectionDetails) {
assertThat(connectionDetails.getUsername()).isEqualTo("myuser");
assertThat(connectionDetails.getPassword()).isEqualTo("secret");
assertThat(connectionDetails.getJdbcUrl()).startsWith("jdbc:postgresql://").endsWith("/mydatabase");

View File

@ -17,10 +17,9 @@
package org.springframework.boot.docker.compose.service.connection.postgres;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
@ -32,15 +31,10 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Andy Wilkinson
* @author Phillip Webb
*/
class PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
class PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("postgres-compose.yaml", TestImage.POSTGRESQL);
}
@Test
void runCreatesConnectionDetails() {
R2dbcConnectionDetails connectionDetails = run(R2dbcConnectionDetails.class);
@DockerComposeTest(composeFile = "postgres-compose.yaml", image = TestImage.POSTGRESQL)
void runCreatesConnectionDetails(R2dbcConnectionDetails connectionDetails) {
ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions();
assertThat(connectionFactoryOptions.toString()).contains("database=mydatabase", "driver=postgresql",
"password=REDACTED", "user=myuser");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2023-2024 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,10 +16,8 @@
package org.springframework.boot.docker.compose.service.connection.pulsar;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.pulsar.PulsarConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
@ -29,15 +27,10 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Chris Bono
*/
class PulsarDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
class PulsarDockerComposeConnectionDetailsFactoryIntegrationTests {
PulsarDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("pulsar-compose.yaml", TestImage.PULSAR);
}
@Test
void runCreatesConnectionDetails() {
PulsarConnectionDetails connectionDetails = run(PulsarConnectionDetails.class);
@DockerComposeTest(composeFile = "pulsar-compose.yaml", image = TestImage.PULSAR)
void runCreatesConnectionDetails(PulsarConnectionDetails connectionDetails) {
assertThat(connectionDetails).isNotNull();
assertThat(connectionDetails.getBrokerUrl()).matches("^pulsar://\\S+:\\d+");
assertThat(connectionDetails.getAdminUrl()).matches("^http://\\S+:\\d+");

View File

@ -16,11 +16,9 @@
package org.springframework.boot.docker.compose.service.connection.rabbit;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.amqp.RabbitConnectionDetails;
import org.springframework.boot.autoconfigure.amqp.RabbitConnectionDetails.Address;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
@ -32,15 +30,10 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Andy Wilkinson
* @author Phillip Webb
*/
class RabbitDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
class RabbitDockerComposeConnectionDetailsFactoryIntegrationTests {
RabbitDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("rabbit-compose.yaml", TestImage.RABBITMQ);
}
@Test
void runCreatesConnectionDetails() {
RabbitConnectionDetails connectionDetails = run(RabbitConnectionDetails.class);
@DockerComposeTest(composeFile = "rabbit-compose.yaml", image = TestImage.RABBITMQ)
void runCreatesConnectionDetails(RabbitConnectionDetails connectionDetails) {
assertThat(connectionDetails.getUsername()).isEqualTo("myuser");
assertThat(connectionDetails.getPassword()).isEqualTo("secret");
assertThat(connectionDetails.getVirtualHost()).isEqualTo("/");

View File

@ -16,11 +16,9 @@
package org.springframework.boot.docker.compose.service.connection.redis;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails;
import org.springframework.boot.autoconfigure.data.redis.RedisConnectionDetails.Standalone;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
@ -32,15 +30,10 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Andy Wilkinson
* @author Phillip Webb
*/
class RedisDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
class RedisDockerComposeConnectionDetailsFactoryIntegrationTests {
RedisDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("redis-compose.yaml", TestImage.REDIS);
}
@Test
void runCreatesConnectionDetails() {
RedisConnectionDetails connectionDetails = run(RedisConnectionDetails.class);
@DockerComposeTest(composeFile = "redis-compose.yaml", image = TestImage.REDIS)
void runCreatesConnectionDetails(RedisConnectionDetails connectionDetails) {
Standalone standalone = connectionDetails.getStandalone();
assertThat(connectionDetails.getUsername()).isNull();
assertThat(connectionDetails.getPassword()).isNull();

View File

@ -18,11 +18,10 @@ package org.springframework.boot.docker.compose.service.connection.sqlserver;
import java.sql.Driver;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.OS;
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.boot.testsupport.junit.DisabledOnOs;
@ -39,16 +38,12 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64",
disabledReason = "The SQL server image has no ARM support")
class SqlServerJdbcDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
class SqlServerJdbcDockerComposeConnectionDetailsFactoryIntegrationTests {
SqlServerJdbcDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("mssqlserver-compose.yaml", TestImage.SQL_SERVER);
}
@Test
@SuppressWarnings("unchecked")
void runCreatesConnectionDetailsThatCanBeUsedToAccessDatabase() throws ClassNotFoundException, LinkageError {
JdbcConnectionDetails connectionDetails = run(JdbcConnectionDetails.class);
@DockerComposeTest(composeFile = "mssqlserver-compose.yaml", image = TestImage.SQL_SERVER)
void runCreatesConnectionDetailsThatCanBeUsedToAccessDatabase(JdbcConnectionDetails connectionDetails)
throws ClassNotFoundException, LinkageError {
assertThat(connectionDetails.getUsername()).isEqualTo("SA");
assertThat(connectionDetails.getPassword()).isEqualTo("verYs3cret");
assertThat(connectionDetails.getJdbcUrl()).startsWith("jdbc:sqlserver://");

View File

@ -20,11 +20,10 @@ import java.time.Duration;
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.OS;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.boot.testsupport.junit.DisabledOnOs;
@ -39,16 +38,10 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64",
disabledReason = "The SQL server image has no ARM support")
class SqlServerR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests
extends AbstractDockerComposeIntegrationTests {
class SqlServerR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
SqlServerR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("mssqlserver-compose.yaml", TestImage.SQL_SERVER);
}
@Test
void runCreatesConnectionDetailsThatCanBeUsedToAccessDatabase() {
R2dbcConnectionDetails connectionDetails = run(R2dbcConnectionDetails.class);
@DockerComposeTest(composeFile = "mssqlserver-compose.yaml", image = TestImage.SQL_SERVER)
void runCreatesConnectionDetailsThatCanBeUsedToAccessDatabase(R2dbcConnectionDetails connectionDetails) {
ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions();
assertThat(connectionFactoryOptions.toString()).contains("driver=mssql", "password=REDACTED", "user=SA");
assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.PASSWORD))

View File

@ -1,103 +0,0 @@
/*
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.test;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Path;
import java.util.LinkedHashMap;
import java.util.Map;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.io.TempDir;
import org.testcontainers.utility.DockerImageName;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationShutdownHandlers;
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.boot.testsupport.process.DisabledIfProcessUnavailable;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.function.ThrowingSupplier;
import static org.assertj.core.api.Assertions.fail;
/**
* Abstract base class for integration tests.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Scott Frederick
*/
@DisabledIfProcessUnavailable({ "docker", "version" })
@DisabledIfProcessUnavailable({ "docker", "compose" })
public abstract class AbstractDockerComposeIntegrationTests {
@TempDir
private static Path tempDir;
private final Resource composeResource;
private final DockerImageName dockerImageName;
@AfterAll
static void shutDown() {
SpringApplicationShutdownHandlers shutdownHandlers = SpringApplication.getShutdownHandlers();
((Runnable) shutdownHandlers).run();
}
protected AbstractDockerComposeIntegrationTests(String composeResource, TestImage testImage) {
this.composeResource = new ClassPathResource(composeResource, getClass());
this.dockerImageName = DockerImageName.parse(testImage.toString());
}
protected final <T extends ConnectionDetails> T run(Class<T> type) {
SpringApplication application = new SpringApplication(Config.class);
Map<String, Object> properties = new LinkedHashMap<>();
properties.put("spring.docker.compose.skip.in-tests", "false");
properties.put("spring.docker.compose.file",
transformedComposeFile(ThrowingSupplier.of(this.composeResource::getFile).get(), this.dockerImageName));
properties.put("spring.docker.compose.stop.command", "down");
application.setDefaultProperties(properties);
return application.run().getBean(type);
}
private File transformedComposeFile(File composeFile, DockerImageName imageName) {
File tempComposeFile = Path.of(tempDir.toString(), composeFile.getName()).toFile();
try {
String composeFileContent = FileCopyUtils.copyToString(new FileReader(composeFile));
composeFileContent = composeFileContent.replace("{imageName}", imageName.asCanonicalNameString());
FileCopyUtils.copy(composeFileContent, new FileWriter(tempComposeFile));
}
catch (IOException ex) {
fail("Error transforming Docker compose file '" + composeFile + "' to '" + tempComposeFile + "': "
+ ex.getMessage());
}
return tempComposeFile;
}
@Configuration(proxyBeanMethods = false)
static class Config {
}
}

View File

@ -0,0 +1,69 @@
/*
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.test;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
import org.springframework.boot.testsupport.container.TestImage;
/**
* A {@link Test test} that exercises Spring Boot's Docker Compose support.
* <p>
* Before the test is executed, a {@link SpringApplication} that is configured to use the
* specified Docker Compose file is started. Any bean that exists in the resulting
* application context can be injected as a parameter into the test method. Typically,
* this will be a {@link ConnectionDetails} implementation.
* <p>
* Once the test has executed, the {@link SpringApplication} is tidied up such that the
* Docker Compose services are stopped and destroyed and the application context is
* closed.
*
* @author Andy Wilkinson
*/
@Test
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ExtendWith(DockerComposeTestExtension.class)
public @interface DockerComposeTest {
/**
* The name of the compose file to use. Loaded as a classpath resource relative to the
* test class. The image name in the compose file can be parameterized using
* <code>{image}</code> and it will be replaced using the specified {@link #image}
* reference.
* @return the compose file
*/
String composeFile();
/**
* The Docker image reference.
* @return the Docker image reference
* @see TestImage
*/
TestImage image();
}

View File

@ -0,0 +1,148 @@
/*
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.LinkedHashMap;
import java.util.Map;
import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
import org.junit.jupiter.api.extension.Extension;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
import org.junit.jupiter.api.extension.ExtensionContext.Store;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.api.extension.ParameterResolutionException;
import org.junit.jupiter.api.extension.ParameterResolver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationShutdownHandlers;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import static org.assertj.core.api.Assertions.fail;
/**
* {@link Extension} for {@link DockerComposeTest @DockerComposeTest}.
*
* @author Andy Wilkinson
*/
class DockerComposeTestExtension implements BeforeTestExecutionCallback, AfterTestExecutionCallback, ParameterResolver {
private static final Namespace NAMESPACE = Namespace.create(DockerComposeTestExtension.class);
private static final String STORE_KEY_COMPOSE_FILE = "compose-file";
private static final String STORE_KEY_APPLICATION_CONTEXT = "application-context";
@Override
public void beforeTestExecution(ExtensionContext context) throws Exception {
Path transformedComposeFile = prepareComposeFile(context);
Store store = context.getStore(NAMESPACE);
store.put(STORE_KEY_COMPOSE_FILE, transformedComposeFile);
try {
SpringApplication application = prepareApplication(transformedComposeFile);
store.put(STORE_KEY_APPLICATION_CONTEXT, application.run());
}
catch (Exception ex) {
cleanUp(context);
throw ex;
}
}
private Path prepareComposeFile(ExtensionContext context) {
DockerComposeTest dockerComposeTest = context.getRequiredTestMethod().getAnnotation(DockerComposeTest.class);
TestImage image = dockerComposeTest.image();
Resource composeResource = new ClassPathResource(dockerComposeTest.composeFile(),
context.getRequiredTestClass());
return transformedComposeFile(composeResource, image);
}
private Path transformedComposeFile(Resource composeFileResource, TestImage image) {
try {
Path composeFile = composeFileResource.getFile().toPath();
Path transformedComposeFile = Files.createTempFile("", "-" + composeFile.getFileName().toString());
String transformedContent = Files.readString(composeFile).replace("{imageName}", image.toString());
Files.writeString(transformedComposeFile, transformedContent);
return transformedComposeFile;
}
catch (IOException ex) {
fail("Error transforming Docker compose file '" + composeFileResource + "': " + ex.getMessage());
}
return null;
}
private SpringApplication prepareApplication(Path transformedComposeFile) {
SpringApplication application = new SpringApplication(Config.class);
Map<String, Object> properties = new LinkedHashMap<>();
properties.put("spring.docker.compose.skip.in-tests", "false");
properties.put("spring.docker.compose.file", transformedComposeFile);
properties.put("spring.docker.compose.stop.command", "down");
application.setDefaultProperties(properties);
return application;
}
@Override
public void afterTestExecution(ExtensionContext context) throws Exception {
cleanUp(context);
}
private void cleanUp(ExtensionContext context) throws Exception {
Store store = context.getStore(NAMESPACE);
runShutdownHandlers();
deleteComposeFile(store);
}
private void runShutdownHandlers() {
SpringApplicationShutdownHandlers shutdownHandlers = SpringApplication.getShutdownHandlers();
((Runnable) shutdownHandlers).run();
}
private void deleteComposeFile(Store store) throws IOException {
Path composeFile = store.get(STORE_KEY_COMPOSE_FILE, Path.class);
if (composeFile != null) {
Files.delete(composeFile);
}
}
@Override
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
throws ParameterResolutionException {
return true;
}
@Override
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
throws ParameterResolutionException {
ConfigurableApplicationContext applicationContext = extensionContext.getStore(NAMESPACE)
.get(STORE_KEY_APPLICATION_CONTEXT, ConfigurableApplicationContext.class);
return (applicationContext != null) ? applicationContext.getBean(parameterContext.getParameter().getType())
: null;
}
@Configuration(proxyBeanMethods = false)
static class Config {
}
}

View File

@ -16,10 +16,8 @@
package org.springframework.boot.docker.compose.service.connection.zipkin;
import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConnectionDetails;
import org.springframework.boot.docker.compose.service.connection.test.AbstractDockerComposeIntegrationTests;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
@ -31,15 +29,10 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Andy Wilkinson
* @author Phillip Webb
*/
class ZipkinDockerComposeConnectionDetailsFactoryIntegrationTests extends AbstractDockerComposeIntegrationTests {
class ZipkinDockerComposeConnectionDetailsFactoryIntegrationTests {
ZipkinDockerComposeConnectionDetailsFactoryIntegrationTests() {
super("zipkin-compose.yaml", TestImage.ZIPKIN);
}
@Test
void runCreatesConnectionDetails() {
ZipkinConnectionDetails connectionDetails = run(ZipkinConnectionDetails.class);
@DockerComposeTest(composeFile = "zipkin-compose.yaml", image = TestImage.ZIPKIN)
void runCreatesConnectionDetails(ZipkinConnectionDetails connectionDetails) {
assertThat(connectionDetails.getSpanEndpoint()).startsWith("http://").endsWith("/api/v2/spans");
}

View File

@ -77,10 +77,11 @@
<suppress files="FailureAnalyzers\.java" checks="RedundantModifier" />
<suppress files="SpringBootVersion" checks="JavadocPackage" />
<suppress files="spring-boot-configuration-processor[\\/]src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]boot[\\/]configurationsample[\\/]" checks="SpringDeprecatedCheck"/>
<suppress files="WebEndpointTest\.java" checks="SpringTestFileName" />
<suppress files="CertificateMatchingTest\.java" checks="SpringTestFileName" />
<suppress files="ConversionServiceTest\.java" checks="SpringTestFileName" />
<suppress files="DockerComposeTest\.java" checks="SpringTestFileName" />
<suppress files="WebEndpointTest\.java" checks="SpringTestFileName" />
<suppress files="ImportTestcontainersTests\.java" checks="InterfaceIsType" />
<suppress files="MyContainers\.java" checks="InterfaceIsType" />
<suppress files="CertificateMatchingTest\.java" checks="SpringTestFileName" />
<suppress files="LoadTimeWeaverAwareConsumerContainers\.java" checks="InterfaceIsType" />
</suppressions>