Update spring-boot-docker-compose to use docker-test plugin

See gh-41228
This commit is contained in:
Andy Wilkinson
2024-06-25 11:32:53 +01:00
parent 3f1f801461
commit 6fbf08fa9a
50 changed files with 21 additions and 16 deletions

View File

@@ -0,0 +1,124 @@
/*
* 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.core;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Path;
import java.time.Duration;
import java.util.Collections;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.springframework.boot.docker.compose.core.DockerCliCommand.ComposeConfig;
import org.springframework.boot.docker.compose.core.DockerCliCommand.ComposeDown;
import org.springframework.boot.docker.compose.core.DockerCliCommand.ComposePs;
import org.springframework.boot.docker.compose.core.DockerCliCommand.ComposeStart;
import org.springframework.boot.docker.compose.core.DockerCliCommand.ComposeStop;
import org.springframework.boot.docker.compose.core.DockerCliCommand.ComposeUp;
import org.springframework.boot.docker.compose.core.DockerCliCommand.Inspect;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.testsupport.container.DisabledIfDockerUnavailable;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.boot.testsupport.process.DisabledIfProcessUnavailable;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.FileCopyUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link DockerCli}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@DisabledIfDockerUnavailable
@DisabledIfProcessUnavailable({ "docker", "compose" })
class DockerCliIntegrationTests {
@TempDir
private static Path tempDir;
@Test
void runBasicCommand() {
DockerCli cli = new DockerCli(null, null, Collections.emptySet());
List<DockerCliContextResponse> context = cli.run(new DockerCliCommand.Context());
assertThat(context).isNotEmpty();
}
@Test
void runLifecycle() throws IOException {
File composeFile = createComposeFile();
DockerCli cli = new DockerCli(null, DockerComposeFile.of(composeFile), Collections.emptySet());
try {
// Verify that no services are running (this is a fresh compose project)
List<DockerCliComposePsResponse> ps = cli.run(new ComposePs());
assertThat(ps).isEmpty();
// List the config and verify that redis is there
DockerCliComposeConfigResponse config = cli.run(new ComposeConfig());
assertThat(config.services()).containsOnlyKeys("redis");
// Run up
cli.run(new ComposeUp(LogLevel.INFO));
// Run ps and use id to run inspect on the id
ps = cli.run(new ComposePs());
assertThat(ps).hasSize(1);
String id = ps.get(0).id();
List<DockerCliInspectResponse> inspect = cli.run(new Inspect(List.of(id)));
assertThat(inspect).isNotEmpty();
assertThat(inspect.get(0).id()).startsWith(id);
// Run stop, then run ps and verify the services are stopped
cli.run(new ComposeStop(Duration.ofSeconds(10)));
ps = cli.run(new ComposePs());
assertThat(ps).isEmpty();
// Run start, verify service is there, then run down and verify they are gone
cli.run(new ComposeStart(LogLevel.INFO));
ps = cli.run(new ComposePs());
assertThat(ps).hasSize(1);
cli.run(new ComposeDown(Duration.ofSeconds(10)));
ps = cli.run(new ComposePs());
assertThat(ps).isEmpty();
}
finally {
// Clean up in any case
quietComposeDown(cli);
}
}
private static void quietComposeDown(DockerCli cli) {
try {
cli.run(new ComposeDown(Duration.ZERO));
}
catch (RuntimeException ex) {
// Ignore
}
}
private static File createComposeFile() throws IOException {
File composeFile = new ClassPathResource("redis-compose.yaml", DockerCliIntegrationTests.class).getFile();
File tempComposeFile = Path.of(tempDir.toString(), composeFile.getName()).toFile();
String composeFileContent = FileCopyUtils.copyToString(new FileReader(composeFile));
composeFileContent = composeFileContent.replace("{imageName}", TestImage.REDIS.toString());
FileCopyUtils.copy(composeFileContent, new FileWriter(tempComposeFile));
return tempComposeFile;
}
}

View File

@@ -0,0 +1,39 @@
/*
* 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.activemq;
import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQConnectionDetails;
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;
/**
* Integration tests for {@link ActiveMQDockerComposeConnectionDetailsFactory}.
*
* @author Stephane Nicoll
*/
class ActiveMQDockerComposeConnectionDetailsFactoryIntegrationTests {
@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

@@ -0,0 +1,47 @@
/*
* 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.cassandra;
import java.util.List;
import org.springframework.boot.autoconfigure.cassandra.CassandraConnectionDetails;
import org.springframework.boot.autoconfigure.cassandra.CassandraConnectionDetails.Node;
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;
/**
* Integration test for {@link CassandraDockerComposeConnectionDetailsFactory}.
*
* @author Scott Frederick
*/
class CassandraDockerComposeConnectionDetailsFactoryIntegrationTests {
@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);
assertThat(node.host()).isNotNull();
assertThat(node.port()).isGreaterThan(0);
assertThat(connectionDetails.getUsername()).isNull();
assertThat(connectionDetails.getPassword()).isNull();
assertThat(connectionDetails.getLocalDatacenter()).isEqualTo("dc1");
}
}

View File

@@ -0,0 +1,50 @@
/*
* 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.elasticsearch;
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.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link ElasticsearchDockerComposeConnectionDetailsFactory}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class ElasticsearchDockerComposeConnectionDetailsFactoryIntegrationTests {
@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();
assertThat(connectionDetails.getNodes()).hasSize(1);
Node node = connectionDetails.getNodes().get(0);
assertThat(node.hostname()).isNotNull();
assertThat(node.port()).isGreaterThan(0);
assertThat(node.protocol()).isEqualTo(Protocol.HTTP);
assertThat(node.username()).isEqualTo("elastic");
assertThat(node.password()).isEqualTo("secret");
}
}

View File

@@ -0,0 +1,39 @@
/*
* 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.flyway;
import org.springframework.boot.autoconfigure.flyway.FlywayConnectionDetails;
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;
/**
* Integration tests for {@link JdbcAdaptingFlywayConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
class JdbcAdaptingFlywayConnectionDetailsFactoryIntegrationTests {
@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

@@ -0,0 +1,39 @@
/*
* 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.liquibase;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseConnectionDetails;
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;
/**
* Integration tests for {@link JdbcAdaptingLiquibaseConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
class JdbcAdaptingLiquibaseConnectionDetailsFactoryIntegrationTests {
@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

@@ -0,0 +1,41 @@
/*
* 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.mariadb;
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
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;
/**
* Integration tests for {@link MariaDbJdbcDockerComposeConnectionDetailsFactory}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class MariaDbJdbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@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

@@ -0,0 +1,44 @@
/*
* 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.mariadb;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
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;
/**
* Integration tests for {@link MariaDbR2dbcDockerComposeConnectionDetailsFactory}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class MariaDbR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@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");
assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.PASSWORD)).isEqualTo("secret");
}
}

View File

@@ -0,0 +1,47 @@
/*
* 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.mongo;
import com.mongodb.ConnectionString;
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails;
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;
/**
* Integration tests for {@link MongoDockerComposeConnectionDetailsFactory}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @author Scott Frederick
*/
class MongoDockerComposeConnectionDetailsFactoryIntegrationTests {
@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());
assertThat(connectionString.getCredential().getSource()).isEqualTo("admin");
assertThat(connectionString.getDatabase()).isEqualTo("mydatabase");
assertThat(connectionDetails.getGridFs()).isNull();
}
}

View File

@@ -0,0 +1,41 @@
/*
* 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.mysql;
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
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;
/**
* Integration tests for {@link MySqlJdbcDockerComposeConnectionDetailsFactory}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class MySqlJdbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@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

@@ -0,0 +1,44 @@
/*
* 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.mysql;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
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;
/**
* Integration tests for {@link MySqlR2dbcDockerComposeConnectionDetailsFactory}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class MySqlR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@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");
assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.PASSWORD)).isEqualTo("secret");
}
}

View File

@@ -0,0 +1,45 @@
/*
* 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.neo4j;
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.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatNoException;
/**
* Integration tests for {@link Neo4jDockerComposeConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
class Neo4jDockerComposeConnectionDetailsFactoryIntegrationTests {
@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

@@ -0,0 +1,65 @@
/*
* 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.oracle;
import java.sql.Driver;
import java.time.Duration;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.condition.OS;
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
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;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
import org.springframework.util.ClassUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link OracleFreeJdbcDockerComposeConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64",
disabledReason = "The Oracle image has no ARM support")
class OracleFreeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@SuppressWarnings("unchecked")
@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");
SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
dataSource.setUrl(connectionDetails.getJdbcUrl());
dataSource.setUsername(connectionDetails.getUsername());
dataSource.setPassword(connectionDetails.getPassword());
dataSource.setDriverClass((Class<? extends Driver>) ClassUtils.forName(connectionDetails.getDriverClassName(),
getClass().getClassLoader()));
Awaitility.await().atMost(Duration.ofMinutes(1)).ignoreExceptions().untilAsserted(() -> {
JdbcTemplate template = new JdbcTemplate(dataSource);
assertThat(template.queryForObject(DatabaseDriver.ORACLE.getValidationQuery(), String.class))
.isEqualTo("Hello");
});
}
}

View File

@@ -0,0 +1,61 @@
/*
* 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.oracle;
import java.time.Duration;
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.condition.OS;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
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;
import org.springframework.r2dbc.core.DatabaseClient;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link OracleFreeR2dbcDockerComposeConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64",
disabledReason = "The Oracle image has no ARM support")
class OracleFreeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@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");
assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.PASSWORD))
.isEqualTo("app_user_secret");
Awaitility.await().atMost(Duration.ofMinutes(1)).ignoreExceptions().untilAsserted(() -> {
Object result = DatabaseClient.create(ConnectionFactories.get(connectionFactoryOptions))
.sql(DatabaseDriver.ORACLE.getValidationQuery())
.map((row, metadata) -> row.get(0))
.first()
.block(Duration.ofSeconds(30));
assertThat(result).isEqualTo("Hello");
});
}
}

View File

@@ -0,0 +1,65 @@
/*
* 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.oracle;
import java.sql.Driver;
import java.time.Duration;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.condition.OS;
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
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;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
import org.springframework.util.ClassUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link OracleXeJdbcDockerComposeConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64",
disabledReason = "The Oracle image has no ARM support")
class OracleXeJdbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@SuppressWarnings("unchecked")
@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");
SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
dataSource.setUrl(connectionDetails.getJdbcUrl());
dataSource.setUsername(connectionDetails.getUsername());
dataSource.setPassword(connectionDetails.getPassword());
dataSource.setDriverClass((Class<? extends Driver>) ClassUtils.forName(connectionDetails.getDriverClassName(),
getClass().getClassLoader()));
Awaitility.await().atMost(Duration.ofMinutes(1)).ignoreExceptions().untilAsserted(() -> {
JdbcTemplate template = new JdbcTemplate(dataSource);
assertThat(template.queryForObject(DatabaseDriver.ORACLE.getValidationQuery(), String.class))
.isEqualTo("Hello");
});
}
}

View File

@@ -0,0 +1,61 @@
/*
* 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.oracle;
import java.time.Duration;
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.condition.OS;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
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;
import org.springframework.r2dbc.core.DatabaseClient;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link OracleXeR2dbcDockerComposeConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64",
disabledReason = "The Oracle image has no ARM support")
class OracleXeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@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");
assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.PASSWORD))
.isEqualTo("app_user_secret");
Awaitility.await().atMost(Duration.ofMinutes(1)).ignoreExceptions().untilAsserted(() -> {
Object result = DatabaseClient.create(ConnectionFactories.get(connectionFactoryOptions))
.sql(DatabaseDriver.ORACLE.getValidationQuery())
.map((row, metadata) -> row.get(0))
.first()
.block(Duration.ofSeconds(30));
assertThat(result).isEqualTo("Hello");
});
}
}

View File

@@ -0,0 +1,38 @@
/*
* 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.otlp;
import org.springframework.boot.actuate.autoconfigure.metrics.export.otlp.OtlpMetricsConnectionDetails;
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;
/**
* Integration tests for
* {@link OpenTelemetryMetricsDockerComposeConnectionDetailsFactory}.
*
* @author Eddú Meléndez
*/
class OpenTelemetryMetricsDockerComposeConnectionDetailsFactoryIntegrationTests {
@DockerComposeTest(composeFile = "otlp-compose.yaml", image = TestImage.OPENTELEMETRY)
void runCreatesConnectionDetails(OtlpMetricsConnectionDetails connectionDetails) {
assertThat(connectionDetails.getUrl()).startsWith("http://").endsWith("/v1/metrics");
}
}

View File

@@ -0,0 +1,38 @@
/*
* 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.otlp;
import org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingConnectionDetails;
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;
/**
* Integration tests for
* {@link OpenTelemetryTracingDockerComposeConnectionDetailsFactory}.
*
* @author Eddú Meléndez
*/
class OpenTelemetryTracingDockerComposeConnectionDetailsFactoryIntegrationTests {
@DockerComposeTest(composeFile = "otlp-compose.yaml", image = TestImage.OPENTELEMETRY)
void runCreatesConnectionDetails(OtlpTracingConnectionDetails connectionDetails) {
assertThat(connectionDetails.getUrl()).startsWith("http://").endsWith("/v1/traces");
}
}

View File

@@ -0,0 +1,41 @@
/*
* 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.postgres;
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
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;
/**
* Integration tests for {@link PostgresJdbcDockerComposeConnectionDetailsFactory}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@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

@@ -0,0 +1,44 @@
/*
* 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.postgres;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
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;
/**
* Integration tests for {@link PostgresR2dbcDockerComposeConnectionDetailsFactory}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@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");
assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.PASSWORD)).isEqualTo("secret");
}
}

View File

@@ -0,0 +1,39 @@
/*
* 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.pulsar;
import org.springframework.boot.autoconfigure.pulsar.PulsarConnectionDetails;
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;
/**
* Integration test for {@link PulsarDockerComposeConnectionDetailsFactory}.
*
* @author Chris Bono
*/
class PulsarDockerComposeConnectionDetailsFactoryIntegrationTests {
@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

@@ -0,0 +1,46 @@
/*
* 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.rabbit;
import org.springframework.boot.autoconfigure.amqp.RabbitConnectionDetails;
import org.springframework.boot.autoconfigure.amqp.RabbitConnectionDetails.Address;
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;
/**
* Integration tests for {@link RabbitDockerComposeConnectionDetailsFactory}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class RabbitDockerComposeConnectionDetailsFactoryIntegrationTests {
@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("/");
assertThat(connectionDetails.getAddresses()).hasSize(1);
Address address = connectionDetails.getFirstAddress();
assertThat(address.host()).isNotNull();
assertThat(address.port()).isGreaterThan(0);
}
}

View File

@@ -0,0 +1,48 @@
/*
* 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.redis;
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.DockerComposeTest;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration test for {@link RedisDockerComposeConnectionDetailsFactory}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class RedisDockerComposeConnectionDetailsFactoryIntegrationTests {
@DockerComposeTest(composeFile = "redis-compose.yaml", image = TestImage.REDIS)
void runCreatesConnectionDetails(RedisConnectionDetails connectionDetails) {
Standalone standalone = connectionDetails.getStandalone();
assertThat(connectionDetails.getUsername()).isNull();
assertThat(connectionDetails.getPassword()).isNull();
assertThat(connectionDetails.getCluster()).isNull();
assertThat(connectionDetails.getSentinel()).isNull();
assertThat(standalone).isNotNull();
assertThat(standalone.getDatabase()).isZero();
assertThat(standalone.getPort()).isGreaterThan(0);
assertThat(standalone.getHost()).isNotNull();
}
}

View File

@@ -0,0 +1,74 @@
/*
* 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.sqlserver;
import java.sql.Driver;
import org.junit.jupiter.api.condition.OS;
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
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;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
import org.springframework.util.ClassUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link SqlServerJdbcDockerComposeConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64",
disabledReason = "The SQL server image has no ARM support")
class SqlServerJdbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@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://");
checkDatabaseAccess(connectionDetails);
}
@DockerComposeTest(composeFile = "mssqlserver-with-jdbc-parameters-compose.yaml", image = TestImage.SQL_SERVER)
void runWithJdbcParametersCreatesConnectionDetailsThatCanBeUsedToAccessDatabase(
JdbcConnectionDetails connectionDetails) throws ClassNotFoundException {
assertThat(connectionDetails.getUsername()).isEqualTo("SA");
assertThat(connectionDetails.getPassword()).isEqualTo("verYs3cret");
assertThat(connectionDetails.getJdbcUrl()).startsWith("jdbc:sqlserver://")
.contains(";sendStringParametersAsUnicode=false;");
checkDatabaseAccess(connectionDetails);
}
@SuppressWarnings("unchecked")
private void checkDatabaseAccess(JdbcConnectionDetails connectionDetails) throws ClassNotFoundException {
SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
dataSource.setUrl(connectionDetails.getJdbcUrl());
dataSource.setUsername(connectionDetails.getUsername());
dataSource.setPassword(connectionDetails.getPassword());
dataSource.setDriverClass((Class<? extends Driver>) ClassUtils.forName(connectionDetails.getDriverClassName(),
getClass().getClassLoader()));
JdbcTemplate template = new JdbcTemplate(dataSource);
assertThat(template.queryForObject(DatabaseDriver.SQLSERVER.getValidationQuery(), Integer.class)).isEqualTo(1);
}
}

View File

@@ -0,0 +1,57 @@
/*
* 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.sqlserver;
import java.time.Duration;
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.junit.jupiter.api.condition.OS;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
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;
import org.springframework.r2dbc.core.DatabaseClient;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link SqlServerR2dbcDockerComposeConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64",
disabledReason = "The SQL server image has no ARM support")
class SqlServerR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@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))
.isEqualTo("verYs3cret");
Object result = DatabaseClient.create(ConnectionFactories.get(connectionFactoryOptions))
.sql(DatabaseDriver.SQLSERVER.getValidationQuery())
.map((row, metadata) -> row.get(0))
.first()
.block(Duration.ofSeconds(30));
assertThat(result).isEqualTo(1);
}
}

View File

@@ -0,0 +1,73 @@
/*
* 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.DisabledIfDockerUnavailable;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.boot.testsupport.process.DisabledIfProcessUnavailable;
/**
* 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)
@DisabledIfDockerUnavailable
@DisabledIfProcessUnavailable({ "docker", "compose" })
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

@@ -0,0 +1,39 @@
/*
* 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.zipkin;
import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConnectionDetails;
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;
/**
* Integration tests for {@link ZipkinDockerComposeConnectionDetailsFactory}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class ZipkinDockerComposeConnectionDetailsFactoryIntegrationTests {
@DockerComposeTest(composeFile = "zipkin-compose.yaml", image = TestImage.ZIPKIN)
void runCreatesConnectionDetails(ZipkinConnectionDetails connectionDetails) {
assertThat(connectionDetails.getSpanEndpoint()).startsWith("http://").endsWith("/api/v2/spans");
}
}

View File

@@ -0,0 +1,5 @@
services:
redis:
image: '{imageName}'
ports:
- '6379'

View File

@@ -0,0 +1,8 @@
services:
activemq:
image: '{imageName}'
ports:
- '61616'
environment:
ACTIVEMQ_USERNAME: 'root'
ACTIVEMQ_PASSWORD: 'secret'

View File

@@ -0,0 +1,12 @@
services:
cassandra:
image: '{imageName}'
ports:
- '9042'
environment:
- 'CASSANDRA_SNITCH=GossipingPropertyFileSnitch'
- 'JVM_OPTS=-Dcassandra.skip_wait_for_gossip_to_settle=0 -Dcassandra.initial_token=0'
- 'HEAP_NEWSIZE=128M'
- 'MAX_HEAP_SIZE=1024M'
- 'CASSANDRA_ENDPOINT_SNITCH=GossipingPropertyFileSnitch'
- 'CASSANDRA_DC=dc1'

View File

@@ -0,0 +1,11 @@
services:
elasticsearch:
image: '{imageName}'
environment:
- 'ELASTIC_PASSWORD=secret'
- 'ES_JAVA_OPTS=-Xmx512m'
- 'xpack.security.enabled=false'
- 'discovery.type=single-node'
ports:
- '9200'
- '9300'

View File

@@ -0,0 +1,9 @@
services:
database:
image: '{imageName}'
ports:
- '5432'
environment:
- 'POSTGRES_USER=myuser'
- 'POSTGRES_DB=mydatabase'
- 'POSTGRES_PASSWORD=secret'

View File

@@ -0,0 +1,9 @@
services:
database:
image: '{imageName}'
ports:
- '5432'
environment:
- 'POSTGRES_USER=myuser'
- 'POSTGRES_DB=mydatabase'
- 'POSTGRES_PASSWORD=secret'

View File

@@ -0,0 +1,11 @@
services:
database:
image: '{imageName}'
ports:
- '3306'
environment:
- 'MARIADB_ROOT_PASSWORD=verysecret'
- 'MARIADB_USER=myuser'
- 'MARIADB_PASSWORD=secret'
- 'MARIADB_DATABASE=mydatabase'

View File

@@ -0,0 +1,9 @@
services:
mongo:
image: '{imageName}'
ports:
- '27017'
environment:
MONGO_INITDB_ROOT_USERNAME: 'root'
MONGO_INITDB_ROOT_PASSWORD: 'secret'
MONGO_INITDB_DATABASE: 'mydatabase'

View File

@@ -0,0 +1,10 @@
services:
database:
image: '{imageName}'
ports:
- '3306'
environment:
- 'MYSQL_ROOT_PASSWORD=verysecret'
- 'MYSQL_USER=myuser'
- 'MYSQL_PASSWORD=secret'
- 'MYSQL_DATABASE=mydatabase'

View File

@@ -0,0 +1,8 @@
services:
neo4j:
image: '{imageName}'
ports:
- '7687'
environment:
- 'NEO4J_AUTH=neo4j/secret'

View File

@@ -0,0 +1,15 @@
services:
database:
image: '{imageName}'
ports:
- '1521'
environment:
- 'APP_USER=app_user'
- 'APP_USER_PASSWORD=app_user_secret'
- 'ORACLE_PASSWORD=secret'
healthcheck:
test: ["CMD-SHELL", "healthcheck.sh"]
interval: 10s
timeout: 5s
retries: 10

View File

@@ -0,0 +1,9 @@
services:
database:
image: '{imageName}'
ports:
- '5432'
environment:
- 'POSTGRES_USER=myuser'
- 'POSTGRES_DB=mydatabase'
- 'POSTGRES_PASSWORD=secret'

View File

@@ -0,0 +1,9 @@
services:
pulsar:
image: '{imageName}'
ports:
- '8080'
- '6650'
command: bin/pulsar standalone
healthcheck:
test: curl http://127.0.0.1:8080/admin/v2/namespaces/public/default

View File

@@ -0,0 +1,8 @@
services:
rabbitmq:
image: '{imageName}'
environment:
- 'RABBITMQ_DEFAULT_USER=myuser'
- 'RABBITMQ_DEFAULT_PASS=secret'
ports:
- '5672'

View File

@@ -0,0 +1,9 @@
services:
database:
image: '{imageName}'
ports:
- '1433'
environment:
- 'MSSQL_PID=express'
- 'MSSQL_SA_PASSWORD=verYs3cret'
- 'ACCEPT_EULA=yes'

View File

@@ -0,0 +1,11 @@
services:
database:
image: '{imageName}'
ports:
- '1433'
environment:
- 'MSSQL_PID=express'
- 'MSSQL_SA_PASSWORD=verYs3cret'
- 'ACCEPT_EULA=yes'
labels:
org.springframework.boot.jdbc.parameters: sendStringParametersAsUnicode=false