Create service connections from Testcontainers-managed containers

Building upon the auto-configuration support for service connections,
this commit adds support for deriving connection details from a
Testcontainers-managed container. Several service-specific
annotations have been introduced. These annotations can be used on a
container field to indicate that it is a source of the details for
a service connection.

See gh-34658

Co-Authored-By: Phillip Webb <pwebb@vmware.com>
Co-Authored-By: Mortitz Halbritter <mkammerer@vmware.com>
This commit is contained in:
Andy Wilkinson
2023-03-22 12:39:20 +00:00
parent 8ec266bea4
commit 95f45eab1f
80 changed files with 2748 additions and 264 deletions

View File

@@ -0,0 +1,91 @@
/*
* Copyright 2012-2023 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.test.autoconfigure.amqp;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.RabbitMQContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
import org.springframework.boot.test.autoconfigure.amqp.RabbitServiceConnectionTests.TestConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
import org.springframework.context.annotation.Bean;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link RabbitServiceConnection}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@SpringBootTest(classes = TestConfiguration.class)
@Testcontainers(disabledWithoutDocker = true)
class RabbitServiceConnectionTests {
@Container
@RabbitServiceConnection
static final RabbitMQContainer rabbit = new RabbitMQContainer(DockerImageNames.rabbit());
@Autowired
RabbitTemplate rabbitTemplate;
@Autowired
TestListener listener;
@Test
void connectionCanBeMadeToKafkaContainer() {
this.rabbitTemplate.convertAndSend("test", "message");
Awaitility.waitAtMost(Duration.ofSeconds(30))
.untilAsserted(() -> assertThat(this.listener.messages).containsExactly("message"));
}
@ImportAutoConfiguration(RabbitAutoConfiguration.class)
static class TestConfiguration {
@Bean
TestListener testListener() {
return new TestListener();
}
}
static class TestListener {
private final List<String> messages = new ArrayList<>();
@RabbitListener(queuesToDeclare = @Queue("test"))
void processMessage(String message) {
this.messages.add(message);
}
}
}

View File

@@ -26,14 +26,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.cassandra.CassandraServiceConnection;
import org.springframework.boot.test.autoconfigure.data.redis.ExampleService;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testsupport.testcontainers.CassandraContainer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.data.cassandra.core.CassandraTemplate;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -42,22 +41,20 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
* Integration test for {@link DataCassandraTest @DataCassandraTest}.
*
* @author Artsiom Yudovin
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@DataCassandraTest(properties = { "spring.cassandra.local-datacenter=datacenter1",
"spring.cassandra.schema-action=create-if-not-exists", "spring.cassandra.connection.connect-timeout=60s",
"spring.cassandra.connection.init-query-timeout=60s", "spring.cassandra.request.timeout=60s" })
@DataCassandraTest(properties = { "spring.cassandra.schema-action=create-if-not-exists",
"spring.cassandra.connection.connect-timeout=60s", "spring.cassandra.connection.init-query-timeout=60s",
"spring.cassandra.request.timeout=60s" })
@Testcontainers(disabledWithoutDocker = true)
class DataCassandraTestIntegrationTests {
@Container
@CassandraServiceConnection
static final CassandraContainer cassandra = new CassandraContainer();
@DynamicPropertySource
static void cassandraProperties(DynamicPropertyRegistry registry) {
registry.add("spring.cassandra.contact-points",
() -> cassandra.getHost() + ":" + cassandra.getFirstMappedPort());
}
@Autowired
private CassandraTemplate cassandraTemplate;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -25,13 +25,12 @@ import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.cassandra.CassandraServiceConnection;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testsupport.testcontainers.CassandraContainer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.stereotype.Service;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
@@ -40,24 +39,21 @@ import static org.assertj.core.api.Assertions.assertThat;
* {@link DataCassandraTest @DataCassandraTest}.
*
* @author Artsiom Yudovin
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@DataCassandraTest(includeFilters = @Filter(Service.class),
properties = { "spring.cassandra.local-datacenter=datacenter1",
"spring.cassandra.schema-action=create-if-not-exists",
properties = { "spring.cassandra.schema-action=create-if-not-exists",
"spring.cassandra.connection.connect-timeout=60s", "spring.cassandra.connection.init-query-timeout=60s",
"spring.cassandra.request.timeout=60s" })
@Testcontainers(disabledWithoutDocker = true)
class DataCassandraTestWithIncludeFilterIntegrationTests {
@Container
@CassandraServiceConnection
static final CassandraContainer cassandra = new CassandraContainer();
@DynamicPropertySource
static void cassandraProperties(DynamicPropertyRegistry registry) {
registry.add("spring.cassandra.contact-points",
() -> cassandra.getHost() + ":" + cassandra.getFirstMappedPort());
}
@Autowired
private ExampleRepository exampleRepository;

View File

@@ -26,11 +26,10 @@ import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.couchbase.CouchbaseServiceConnection;
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
import org.springframework.context.ApplicationContext;
import org.springframework.data.couchbase.core.CouchbaseTemplate;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -39,27 +38,24 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
* Integration test for {@link DataCouchbaseTest @DataCouchbaseTest}.
*
* @author Eddú Meléndez
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@DataCouchbaseTest(properties = "spring.couchbase.env.timeouts.connect=2m")
@DataCouchbaseTest(
properties = { "spring.couchbase.env.timeouts.connect=2m", "spring.data.couchbase.bucket-name=cbbucket" })
@Testcontainers(disabledWithoutDocker = true)
class DataCouchbaseTestIntegrationTests {
private static final String BUCKET_NAME = "cbbucket";
@Container
@CouchbaseServiceConnection
static final CouchbaseContainer couchbase = new CouchbaseContainer(DockerImageNames.couchbase())
.withStartupAttempts(5)
.withStartupTimeout(Duration.ofMinutes(10))
.withBucket(new BucketDefinition(BUCKET_NAME));
@DynamicPropertySource
static void couchbaseProperties(DynamicPropertyRegistry registry) {
registry.add("spring.couchbase.connection-string", couchbase::getConnectionString);
registry.add("spring.couchbase.username", couchbase::getUsername);
registry.add("spring.couchbase.password", couchbase::getPassword);
registry.add("spring.data.couchbase.bucket-name", () -> BUCKET_NAME);
}
@Autowired
private CouchbaseTemplate couchbaseTemplate;

View File

@@ -25,10 +25,9 @@ import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.couchbase.CouchbaseServiceConnection;
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
import org.springframework.data.couchbase.core.ReactiveCouchbaseTemplate;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
@@ -37,27 +36,23 @@ import static org.assertj.core.api.Assertions.assertThat;
* repositories.
*
* @author Eddú Meléndez
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@DataCouchbaseTest
@DataCouchbaseTest(properties = "spring.data.couchbase.bucket-name=cbbucket")
@Testcontainers(disabledWithoutDocker = true)
class DataCouchbaseTestReactiveIntegrationTests {
private static final String BUCKET_NAME = "cbbucket";
@Container
@CouchbaseServiceConnection
static final CouchbaseContainer couchbase = new CouchbaseContainer(DockerImageNames.couchbase())
.withStartupAttempts(5)
.withStartupTimeout(Duration.ofMinutes(10))
.withBucket(new BucketDefinition(BUCKET_NAME));
@DynamicPropertySource
static void couchbaseProperties(DynamicPropertyRegistry registry) {
registry.add("spring.couchbase.connection-string", couchbase::getConnectionString);
registry.add("spring.couchbase.username", couchbase::getUsername);
registry.add("spring.couchbase.password", couchbase::getPassword);
registry.add("spring.data.couchbase.bucket-name", () -> BUCKET_NAME);
}
@Autowired
private ReactiveCouchbaseTemplate couchbaseTemplate;

View File

@@ -25,11 +25,10 @@ import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.couchbase.CouchbaseServiceConnection;
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.stereotype.Service;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
@@ -38,27 +37,23 @@ import static org.assertj.core.api.Assertions.assertThat;
* {@link DataCouchbaseTest @DataCouchbaseTest}.
*
* @author Eddú Meléndez
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@DataCouchbaseTest(includeFilters = @Filter(Service.class))
@DataCouchbaseTest(includeFilters = @Filter(Service.class), properties = "spring.data.couchbase.bucket-name=cbbucket")
@Testcontainers(disabledWithoutDocker = true)
class DataCouchbaseTestWithIncludeFilterIntegrationTests {
private static final String BUCKET_NAME = "cbbucket";
@Container
@CouchbaseServiceConnection
static final CouchbaseContainer couchbase = new CouchbaseContainer(DockerImageNames.couchbase())
.withStartupAttempts(5)
.withStartupTimeout(Duration.ofMinutes(10))
.withBucket(new BucketDefinition(BUCKET_NAME));
@DynamicPropertySource
static void couchbaseProperties(DynamicPropertyRegistry registry) {
registry.add("spring.couchbase.connection-string", couchbase::getConnectionString);
registry.add("spring.couchbase.username", couchbase::getUsername);
registry.add("spring.couchbase.password", couchbase::getPassword);
registry.add("spring.data.couchbase.bucket-name", () -> BUCKET_NAME);
}
@Autowired
private ExampleRepository exampleRepository;

View File

@@ -26,11 +26,10 @@ import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.elasticsearch.ElasticsearchServiceConnection;
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
import org.springframework.context.ApplicationContext;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -39,21 +38,20 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
* Sample test for {@link DataElasticsearchTest @DataElasticsearchTest}
*
* @author Eddú Meléndez
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@DataElasticsearchTest
@Testcontainers(disabledWithoutDocker = true)
class DataElasticsearchTestIntegrationTests {
@Container
@ElasticsearchServiceConnection
static final ElasticsearchContainer elasticsearch = new ElasticsearchContainer(DockerImageNames.elasticsearch())
.withStartupAttempts(5)
.withStartupTimeout(Duration.ofMinutes(10));
@DynamicPropertySource
static void elasticsearchProperties(DynamicPropertyRegistry registry) {
registry.add("spring.elasticsearch.uris", elasticsearch::getHttpHostAddress);
}
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;

View File

@@ -24,10 +24,9 @@ import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.elasticsearch.ElasticsearchServiceConnection;
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
import org.springframework.core.env.Environment;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
@@ -36,21 +35,20 @@ import static org.assertj.core.api.Assertions.assertThat;
* {@link DataElasticsearchTest @DataElasticsearchTest}.
*
* @author Eddú Meléndez
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@DataElasticsearchTest(properties = "spring.profiles.active=test")
@Testcontainers(disabledWithoutDocker = true)
class DataElasticsearchTestPropertiesIntegrationTests {
@Container
@ElasticsearchServiceConnection
static final ElasticsearchContainer elasticsearch = new ElasticsearchContainer(DockerImageNames.elasticsearch())
.withStartupAttempts(5)
.withStartupTimeout(Duration.ofMinutes(10));
@DynamicPropertySource
static void elasticsearchProperties(DynamicPropertyRegistry registry) {
registry.add("spring.elasticsearch.uris", elasticsearch::getHttpHostAddress);
}
@Autowired
private Environment environment;

View File

@@ -24,10 +24,9 @@ import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.elasticsearch.ElasticsearchServiceConnection;
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchTemplate;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
@@ -36,21 +35,20 @@ import static org.assertj.core.api.Assertions.assertThat;
* repositories.
*
* @author Eddú Meléndez
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@DataElasticsearchTest
@Testcontainers(disabledWithoutDocker = true)
class DataElasticsearchTestReactiveIntegrationTests {
@Container
@ElasticsearchServiceConnection
static final ElasticsearchContainer elasticsearch = new ElasticsearchContainer(DockerImageNames.elasticsearch())
.withStartupAttempts(5)
.withStartupTimeout(Duration.ofMinutes(10));
@DynamicPropertySource
static void elasticsearchProperties(DynamicPropertyRegistry registry) {
registry.add("spring.elasticsearch.uris", elasticsearch::getHttpHostAddress);
}
@Autowired
private ReactiveElasticsearchTemplate elasticsearchTemplate;

View File

@@ -25,11 +25,10 @@ import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.elasticsearch.ElasticsearchServiceConnection;
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.stereotype.Service;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
@@ -38,21 +37,20 @@ import static org.assertj.core.api.Assertions.assertThat;
* {@link DataElasticsearchTest @DataElasticsearchTest}.
*
* @author Eddú Meléndez
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@DataElasticsearchTest(includeFilters = @Filter(Service.class))
@Testcontainers(disabledWithoutDocker = true)
class DataElasticsearchTestWithIncludeFilterIntegrationTests {
@Container
@ElasticsearchServiceConnection
static final ElasticsearchContainer elasticsearch = new ElasticsearchContainer(DockerImageNames.elasticsearch())
.withStartupAttempts(5)
.withStartupTimeout(Duration.ofMinutes(10));
@DynamicPropertySource
static void elasticsearchProperties(DynamicPropertyRegistry registry) {
registry.add("spring.elasticsearch.uris", elasticsearch::getHttpHostAddress);
}
@Autowired
private ExampleRepository exampleRepository;

View File

@@ -25,11 +25,10 @@ import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.mongo.MongoServiceConnection;
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
import org.springframework.context.ApplicationContext;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -38,12 +37,16 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
* Sample test for {@link DataMongoTest @DataMongoTest}
*
* @author Michael Simons
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@DataMongoTest
@Testcontainers(disabledWithoutDocker = true)
class DataMongoTestIntegrationTests {
@Container
@MongoServiceConnection
static final MongoDBContainer mongoDB = new MongoDBContainer(DockerImageNames.mongo()).withStartupAttempts(5)
.withStartupTimeout(Duration.ofMinutes(5));
@@ -71,9 +74,4 @@ class DataMongoTestIntegrationTests {
.isThrownBy(() -> this.applicationContext.getBean(ExampleService.class));
}
@DynamicPropertySource
static void mongoProperties(DynamicPropertyRegistry registry) {
registry.add("spring.data.mongodb.uri", mongoDB::getReplicaSetUrl);
}
}

View File

@@ -24,10 +24,9 @@ import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.mongo.MongoServiceConnection;
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
@@ -35,12 +34,16 @@ import static org.assertj.core.api.Assertions.assertThat;
* Sample tests for {@link DataMongoTest @DataMongoTest} using reactive repositories.
*
* @author Stephane Nicoll
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@DataMongoTest
@Testcontainers(disabledWithoutDocker = true)
class DataMongoTestReactiveIntegrationTests {
@Container
@MongoServiceConnection
static final MongoDBContainer mongoDB = new MongoDBContainer(DockerImageNames.mongo()).withStartupAttempts(5)
.withStartupTimeout(Duration.ofMinutes(5));
@@ -50,11 +53,6 @@ class DataMongoTestReactiveIntegrationTests {
@Autowired
private ExampleReactiveRepository exampleRepository;
@DynamicPropertySource
static void mongoProperties(DynamicPropertyRegistry registry) {
registry.add("spring.data.mongodb.uri", mongoDB::getReplicaSetUrl);
}
@Test
void testRepository() {
ExampleDocument exampleDocument = new ExampleDocument();

View File

@@ -24,11 +24,10 @@ import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.mongo.MongoServiceConnection;
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.stereotype.Service;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
@@ -36,23 +35,22 @@ import static org.assertj.core.api.Assertions.assertThat;
* Integration test with custom include filter for {@link DataMongoTest @DataMongoTest}.
*
* @author Michael Simons
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@DataMongoTest(includeFilters = @Filter(Service.class))
@Testcontainers(disabledWithoutDocker = true)
class DataMongoTestWithIncludeFilterIntegrationTests {
@Container
@MongoServiceConnection
static final MongoDBContainer mongoDB = new MongoDBContainer(DockerImageNames.mongo()).withStartupAttempts(5)
.withStartupTimeout(Duration.ofMinutes(5));
@Autowired
private ExampleService service;
@DynamicPropertySource
static void mongoProperties(DynamicPropertyRegistry registry) {
registry.add("spring.data.mongodb.uri", mongoDB::getReplicaSetUrl);
}
@Test
void testService() {
assertThat(this.service.hasCollection("foobar")).isFalse();

View File

@@ -25,14 +25,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.mongo.MongoServiceConnection;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
import org.springframework.context.annotation.Bean;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.MongoTransactionManager;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.springframework.transaction.annotation.Transactional;
import static org.assertj.core.api.Assertions.assertThat;
@@ -41,6 +40,8 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for using {@link DataMongoTest @DataMongoTest} with transactions.
*
* @author Andy Wilkinson
* @author Moritz Halbritter
* @author Phillip Webb
*/
@DataMongoTest
@Transactional
@@ -48,6 +49,7 @@ import static org.assertj.core.api.Assertions.assertThat;
class TransactionalDataMongoTestIntegrationTests {
@Container
@MongoServiceConnection
static final MongoDBContainer mongoDB = new MongoDBContainer(DockerImageNames.mongo()).withStartupAttempts(5)
.withStartupTimeout(Duration.ofMinutes(5));
@@ -62,11 +64,6 @@ class TransactionalDataMongoTestIntegrationTests {
assertThat(exampleDocument.getId()).isNotNull();
}
@DynamicPropertySource
static void mongoProperties(DynamicPropertyRegistry registry) {
registry.add("spring.data.mongodb.uri", mongoDB::getReplicaSetUrl);
}
@TestConfiguration(proxyBeanMethods = false)
static class TransactionManagerConfiguration {

View File

@@ -25,11 +25,10 @@ import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.neo4j.Neo4jServiceConnection;
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
import org.springframework.context.ApplicationContext;
import org.springframework.data.neo4j.core.Neo4jTemplate;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -40,21 +39,19 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
* @author Eddú Meléndez
* @author Stephane Nicoll
* @author Michael Simons
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@DataNeo4jTest
@Testcontainers(disabledWithoutDocker = true)
class DataNeo4jTestIntegrationTests {
@Container
static final Neo4jContainer<?> neo4j = new Neo4jContainer<>(DockerImageNames.neo4j()).withoutAuthentication()
.withStartupAttempts(5)
@Neo4jServiceConnection
static final Neo4jContainer<?> neo4j = new Neo4jContainer<>(DockerImageNames.neo4j()).withStartupAttempts(5)
.withStartupTimeout(Duration.ofMinutes(10));
@DynamicPropertySource
static void neo4jProperties(DynamicPropertyRegistry registry) {
registry.add("spring.neo4j.uri", neo4j::getBoltUrl);
}
@Autowired
private Neo4jTemplate neo4jTemplate;

View File

@@ -24,10 +24,9 @@ import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.neo4j.Neo4jServiceConnection;
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
import org.springframework.core.env.Environment;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
@@ -36,21 +35,20 @@ import static org.assertj.core.api.Assertions.assertThat;
* {@link DataNeo4jTest @DataNeo4jTest}.
*
* @author Artsiom Yudovin
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@Testcontainers(disabledWithoutDocker = true)
@DataNeo4jTest(properties = "spring.profiles.active=test")
class DataNeo4jTestPropertiesIntegrationTests {
@Container
@Neo4jServiceConnection
static final Neo4jContainer<?> neo4j = new Neo4jContainer<>(DockerImageNames.neo4j()).withoutAuthentication()
.withStartupAttempts(5)
.withStartupTimeout(Duration.ofMinutes(10));
@DynamicPropertySource
static void neo4jProperties(DynamicPropertyRegistry registry) {
registry.add("spring.neo4j.uri", neo4j::getBoltUrl);
}
@Autowired
private Environment environment;

View File

@@ -28,6 +28,7 @@ import reactor.test.StepVerifier;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.neo4j.Neo4jServiceConnection;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
import org.springframework.context.ApplicationContext;
@@ -35,8 +36,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.data.neo4j.core.ReactiveDatabaseSelectionProvider;
import org.springframework.data.neo4j.core.ReactiveNeo4jTemplate;
import org.springframework.data.neo4j.core.transaction.ReactiveNeo4jTransactionManager;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@@ -47,7 +46,9 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
*
* @author Michael J. Simons
* @author Scott Frederick
* @since 2.4.0
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@DataNeo4jTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
@@ -55,15 +56,11 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
class DataNeo4jTestReactiveIntegrationTests {
@Container
@Neo4jServiceConnection
static final Neo4jContainer<?> neo4j = new Neo4jContainer<>(DockerImageNames.neo4j()).withoutAuthentication()
.withStartupAttempts(5)
.withStartupTimeout(Duration.ofMinutes(10));
@DynamicPropertySource
static void neo4jProperties(DynamicPropertyRegistry registry) {
registry.add("spring.neo4j.uri", neo4j::getBoltUrl);
}
@Autowired
private ReactiveNeo4jTemplate neo4jTemplate;

View File

@@ -24,11 +24,10 @@ import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.neo4j.Neo4jServiceConnection;
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.stereotype.Service;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
@@ -37,21 +36,20 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Eddú Meléndez
* @author Michael Simons
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@Testcontainers(disabledWithoutDocker = true)
@DataNeo4jTest(includeFilters = @Filter(Service.class))
class DataNeo4jTestWithIncludeFilterIntegrationTests {
@Container
@Neo4jServiceConnection
static final Neo4jContainer<?> neo4j = new Neo4jContainer<>(DockerImageNames.neo4j()).withoutAuthentication()
.withStartupAttempts(5)
.withStartupTimeout(Duration.ofMinutes(10));
@DynamicPropertySource
static void neo4jProperties(DynamicPropertyRegistry registry) {
registry.add("spring.neo4j.uri", neo4j::getBoltUrl);
}
@Autowired
private ExampleService service;

View File

@@ -27,10 +27,7 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.testsupport.testcontainers.RedisContainer;
import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -39,6 +36,9 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
* Integration test for {@link DataRedisTest @DataRedisTest}.
*
* @author Jayaram Pradhan
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@Testcontainers(disabledWithoutDocker = true)
@DataRedisTest
@@ -47,6 +47,7 @@ class DataRedisTestIntegrationTests {
private static final Charset CHARSET = StandardCharsets.UTF_8;
@Container
@RedisServiceConnection
static RedisContainer redis = new RedisContainer();
@Autowired
@@ -58,12 +59,6 @@ class DataRedisTestIntegrationTests {
@Autowired
private ApplicationContext applicationContext;
@DynamicPropertySource
static void redisProperties(DynamicPropertyRegistry registry) {
registry.add("spring.data.redis.host", redis::getHost);
registry.add("spring.data.redis.port", redis::getFirstMappedPort);
}
@Test
void testRepository() {
PersonHash personHash = new PersonHash();
@@ -71,8 +66,10 @@ class DataRedisTestIntegrationTests {
assertThat(personHash.getId()).isNull();
PersonHash savedEntity = this.exampleRepository.save(personHash);
assertThat(savedEntity.getId()).isNotNull();
assertThat(this.operations.execute((RedisConnection connection) -> connection.keyCommands()
.exists(("persons:" + savedEntity.getId()).getBytes(CHARSET)))).isTrue();
assertThat(this.operations
.execute((org.springframework.data.redis.connection.RedisConnection connection) -> connection.keyCommands()
.exists(("persons:" + savedEntity.getId()).getBytes(CHARSET))))
.isTrue();
this.exampleRepository.deleteAll();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -23,8 +23,6 @@ import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.testsupport.testcontainers.RedisContainer;
import org.springframework.core.env.Environment;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
@@ -33,23 +31,21 @@ import static org.assertj.core.api.Assertions.assertThat;
* {@link DataRedisTest @DataRedisTest}.
*
* @author Artsiom Yudovin
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@Testcontainers(disabledWithoutDocker = true)
@DataRedisTest(properties = "spring.profiles.active=test")
class DataRedisTestPropertiesIntegrationTests {
@Container
@RedisServiceConnection
static final RedisContainer redis = new RedisContainer();
@Autowired
private Environment environment;
@DynamicPropertySource
static void redisProperties(DynamicPropertyRegistry registry) {
registry.add("spring.data.redis.host", redis::getHost);
registry.add("spring.data.redis.port", redis::getFirstMappedPort);
}
@Test
void environmentWithNewProfile() {
assertThat(this.environment.getActiveProfiles()).containsExactly("test");

View File

@@ -28,8 +28,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.testsupport.testcontainers.RedisContainer;
import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.core.ReactiveRedisOperations;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -37,12 +35,16 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
* Integration test for {@link DataRedisTest @DataRedisTest} using reactive operations.
*
* @author Stephane Nicoll
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@Testcontainers(disabledWithoutDocker = true)
@DataRedisTest
class DataRedisTestReactiveIntegrationTests {
@Container
@RedisServiceConnection
static RedisContainer redis = new RedisContainer();
@Autowired
@@ -51,12 +53,6 @@ class DataRedisTestReactiveIntegrationTests {
@Autowired
private ApplicationContext applicationContext;
@DynamicPropertySource
static void redisProperties(DynamicPropertyRegistry registry) {
registry.add("spring.data.redis.host", redis::getHost);
registry.add("spring.data.redis.port", redis::getFirstMappedPort);
}
@Test
void testRepository() {
String id = UUID.randomUUID().toString();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -24,8 +24,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.testsupport.testcontainers.RedisContainer;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.stereotype.Service;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
@@ -33,12 +31,16 @@ import static org.assertj.core.api.Assertions.assertThat;
* Integration test with custom include filter for {@link DataRedisTest @DataRedisTest}.
*
* @author Jayaram Pradhan
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@Testcontainers(disabledWithoutDocker = true)
@DataRedisTest(includeFilters = @Filter(Service.class))
class DataRedisTestWithIncludeFilterIntegrationTests {
@Container
@RedisServiceConnection
static final RedisContainer redis = new RedisContainer();
@Autowired
@@ -47,12 +49,6 @@ class DataRedisTestWithIncludeFilterIntegrationTests {
@Autowired
private ExampleService service;
@DynamicPropertySource
static void redisProperties(DynamicPropertyRegistry registry) {
registry.add("spring.data.redis.host", redis::getHost);
registry.add("spring.data.redis.port", redis::getFirstMappedPort);
}
@Test
void testService() {
PersonHash personHash = new PersonHash();

View File

@@ -0,0 +1,62 @@
/*
* Copyright 2012-2023 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.test.autoconfigure.influx;
import org.influxdb.InfluxDB;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.InfluxDBContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration;
import org.springframework.boot.test.autoconfigure.influx.InfluxDbServiceConnectionTests.TestConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link InfluxDbServiceConnection}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@SpringBootTest(classes = TestConfiguration.class)
@Testcontainers(disabledWithoutDocker = true)
class InfluxDbServiceConnectionTests {
@Container
@InfluxDbServiceConnection
static final InfluxDBContainer<?> influxDbService = new InfluxDBContainer<>(DockerImageNames.influxDb());
@Autowired
InfluxDB influxDb;
@Test
void connectionCanBeMadeToInfluxDbContainer() {
assertThat(this.influxDb.version()).isEqualTo("v" + DockerImageNames.influxDb().getVersionPart());
}
@ImportAutoConfiguration(InfluxDbAutoConfiguration.class)
static class TestConfiguration {
}
}

View File

@@ -0,0 +1,92 @@
/*
* Copyright 2012-2023 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.test.autoconfigure.kafka;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.KafkaContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration;
import org.springframework.boot.test.autoconfigure.kafka.KafkaServiceConnectionTests.TestConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
import org.springframework.context.annotation.Bean;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link KafkaServiceConnection}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
@SpringBootTest(classes = TestConfiguration.class,
properties = { "spring.kafka.consumer.group-id=test-group",
"spring.kafka.consumer.auto-offset-reset=earliest" })
@Testcontainers(disabledWithoutDocker = true)
class KafkaServiceConnectionTests {
@Container
@KafkaServiceConnection
static final KafkaContainer kafka = new KafkaContainer(DockerImageNames.kafka());
@Autowired
KafkaTemplate<String, String> kafkaTemplate;
@Autowired
TestListener listener;
@Test
void connectionCanBeMadeToKafkaContainer() {
this.kafkaTemplate.send("test-topic", "test-data");
Awaitility.waitAtMost(Duration.ofSeconds(30))
.untilAsserted(() -> assertThat(this.listener.messages).containsExactly("test-data"));
}
@ImportAutoConfiguration(KafkaAutoConfiguration.class)
static class TestConfiguration {
@Bean
TestListener testListener() {
return new TestListener();
}
}
static class TestListener {
private final List<String> messages = new ArrayList<>();
@KafkaListener(topics = "test-topic")
void processMessage(String message) {
this.messages.add(message);
}
}
}