Browse Source

Polish "Upgrade to Testcontainers 1.20.2"

This commit review the original upgrade to retain compatiblity with the
deprecated Cassandra and ConfluentKafka containers.

This commit also fixes the SSL Cassandra tests. The new container uses
a custom wait strategy that uses plain text and does not work with an
SSL container.

Closes gh-42670

Co-authored-by: Moritz Halbritter <moritz.halbritter@broadcom.com>
pull/42707/head
Stéphane Nicoll 1 year ago
parent
commit
e0152097f3
  1. 69
      spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/cassandra/DeprecatedCassandraContainerConnectionDetailsFactoryTests.java
  2. 97
      spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/kafka/DeprecatedConfluentKafkaContainerConnectionDetailsFactoryIntegrationTests.java
  3. 83
      spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/cassandra/DeprecatedCassandraContainerConnectionDetailsFactory.java
  4. 64
      spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/kafka/DeprecatedConfluentKafkaContainerConnectionDetailsFactory.java
  5. 2
      spring-boot-project/spring-boot-testcontainers/src/main/resources/META-INF/spring.factories
  6. 19
      spring-boot-project/spring-boot-tools/spring-boot-test-support-docker/src/main/java/org/springframework/boot/testsupport/container/TestImage.java
  7. 2
      spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-cassandra/src/dockerTest/java/smoketest/data/cassandra/SecureCassandraContainer.java

69
spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/cassandra/DeprecatedCassandraContainerConnectionDetailsFactoryTests.java

@ -0,0 +1,69 @@
/*
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.testcontainers.service.connection.cassandra;
import com.datastax.oss.driver.api.core.CqlSession;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.CassandraContainer;
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.cassandra.CassandraAutoConfiguration;
import org.springframework.boot.autoconfigure.cassandra.CassandraConnectionDetails;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link DeprecatedCassandraContainerConnectionDetailsFactory}.
*
* @author Andy Wilkinson
* @deprecated since 3.4.0 for removal in 3.6.0
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
@Deprecated(since = "3.4.0", forRemoval = true)
class DeprecatedCassandraContainerConnectionDetailsFactoryTests {
@Container
@ServiceConnection
static final CassandraContainer<?> cassandra = TestImage.container(CassandraContainer.class);
@Autowired(required = false)
private CassandraConnectionDetails connectionDetails;
@Autowired
private CqlSession cqlSession;
@Test
void connectionCanBeMadeToCassandraContainer() {
assertThat(this.connectionDetails).isNotNull();
assertThat(this.cqlSession.getMetadata().getNodes()).hasSize(1);
}
@Configuration(proxyBeanMethods = false)
@ImportAutoConfiguration(CassandraAutoConfiguration.class)
static class TestConfiguration {
}
}

97
spring-boot-project/spring-boot-testcontainers/src/dockerTest/java/org/springframework/boot/testcontainers/service/connection/kafka/DeprecatedConfluentKafkaContainerConnectionDetailsFactoryIntegrationTests.java

@ -0,0 +1,97 @@
/*
* 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.testcontainers.service.connection.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.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link DeprecatedConfluentKafkaContainerConnectionDetailsFactory}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 3.6.0
*/
@SpringJUnitConfig
@Testcontainers(disabledWithoutDocker = true)
@TestPropertySource(properties = { "spring.kafka.consumer.group-id=test-group",
"spring.kafka.consumer.auto-offset-reset=earliest" })
@Deprecated(since = "3.4.0", forRemoval = true)
class DeprecatedConfluentKafkaContainerConnectionDetailsFactoryIntegrationTests {
@Container
@ServiceConnection
static final KafkaContainer kafka = TestImage.container(KafkaContainer.class);
@Autowired
private KafkaTemplate<String, String> kafkaTemplate;
@Autowired
private TestListener listener;
@Test
void connectionCanBeMadeToKafkaContainer() {
this.kafkaTemplate.send("test-topic", "test-data");
Awaitility.waitAtMost(Duration.ofMinutes(4))
.untilAsserted(() -> assertThat(this.listener.messages).containsExactly("test-data"));
}
@Configuration(proxyBeanMethods = false)
@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);
}
}
}

83
spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/cassandra/DeprecatedCassandraContainerConnectionDetailsFactory.java

@ -0,0 +1,83 @@
/*
* 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.testcontainers.service.connection.cassandra;
import java.net.InetSocketAddress;
import java.util.List;
import org.testcontainers.containers.CassandraContainer;
import org.springframework.boot.autoconfigure.cassandra.CassandraConnectionDetails;
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory;
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
/**
* {@link ContainerConnectionDetailsFactory} to create {@link CassandraConnectionDetails}
* from a {@link ServiceConnection @ServiceConnection}-annotated
* {@link CassandraContainer}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 3.6.0 in favor of
* {@link CassandraContainerConnectionDetailsFactory}.
*/
@Deprecated(since = "3.4.0", forRemoval = true)
class DeprecatedCassandraContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<CassandraContainer<?>, CassandraConnectionDetails> {
@Override
protected CassandraConnectionDetails getContainerConnectionDetails(
ContainerConnectionSource<CassandraContainer<?>> source) {
return new CassandraContainerConnectionDetails(source);
}
/**
* {@link CassandraConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class CassandraContainerConnectionDetails
extends ContainerConnectionDetails<CassandraContainer<?>> implements CassandraConnectionDetails {
private CassandraContainerConnectionDetails(ContainerConnectionSource<CassandraContainer<?>> source) {
super(source);
}
@Override
public List<Node> getContactPoints() {
InetSocketAddress contactPoint = getContainer().getContactPoint();
return List.of(new Node(contactPoint.getHostString(), contactPoint.getPort()));
}
@Override
public String getUsername() {
return getContainer().getUsername();
}
@Override
public String getPassword() {
return getContainer().getPassword();
}
@Override
public String getLocalDatacenter() {
return getContainer().getLocalDatacenter();
}
}
}

64
spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/kafka/DeprecatedConfluentKafkaContainerConnectionDetailsFactory.java

@ -0,0 +1,64 @@
/*
* 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.testcontainers.service.connection.kafka;
import java.util.List;
import org.testcontainers.containers.KafkaContainer;
import org.springframework.boot.autoconfigure.kafka.KafkaConnectionDetails;
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory;
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
/**
* {@link ContainerConnectionDetailsFactory} to create {@link KafkaConnectionDetails} from
* a {@link ServiceConnection @ServiceConnection}-annotated {@link KafkaContainer}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 3.6.0 in favor of
* {@link ConfluentKafkaContainerConnectionDetailsFactory}.
*/
@Deprecated(since = "3.4.0", forRemoval = true)
class DeprecatedConfluentKafkaContainerConnectionDetailsFactory
extends ContainerConnectionDetailsFactory<KafkaContainer, KafkaConnectionDetails> {
@Override
protected KafkaConnectionDetails getContainerConnectionDetails(ContainerConnectionSource<KafkaContainer> source) {
return new ConfluentKafkaContainerConnectionDetails(source);
}
/**
* {@link KafkaConnectionDetails} backed by a {@link ContainerConnectionSource}.
*/
private static final class ConfluentKafkaContainerConnectionDetails
extends ContainerConnectionDetails<KafkaContainer> implements KafkaConnectionDetails {
private ConfluentKafkaContainerConnectionDetails(ContainerConnectionSource<KafkaContainer> source) {
super(source);
}
@Override
public List<String> getBootstrapServers() {
return List.of(getContainer().getBootstrapServers());
}
}
}

2
spring-boot-project/spring-boot-testcontainers/src/main/resources/META-INF/spring.factories

@ -13,6 +13,7 @@ org.springframework.boot.testcontainers.service.connection.activemq.ActiveMQCont
org.springframework.boot.testcontainers.service.connection.activemq.ArtemisContainerConnectionDetailsFactory,\ org.springframework.boot.testcontainers.service.connection.activemq.ArtemisContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.amqp.RabbitContainerConnectionDetailsFactory,\ org.springframework.boot.testcontainers.service.connection.amqp.RabbitContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.cassandra.CassandraContainerConnectionDetailsFactory,\ org.springframework.boot.testcontainers.service.connection.cassandra.CassandraContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.cassandra.DeprecatedCassandraContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.couchbase.CouchbaseContainerConnectionDetailsFactory,\ org.springframework.boot.testcontainers.service.connection.couchbase.CouchbaseContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.elasticsearch.ElasticsearchContainerConnectionDetailsFactory,\ org.springframework.boot.testcontainers.service.connection.elasticsearch.ElasticsearchContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.flyway.FlywayContainerConnectionDetailsFactory,\ org.springframework.boot.testcontainers.service.connection.flyway.FlywayContainerConnectionDetailsFactory,\
@ -20,6 +21,7 @@ org.springframework.boot.testcontainers.service.connection.hazelcast.HazelcastCo
org.springframework.boot.testcontainers.service.connection.jdbc.JdbcContainerConnectionDetailsFactory,\ org.springframework.boot.testcontainers.service.connection.jdbc.JdbcContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.kafka.ApacheKafkaContainerConnectionDetailsFactory,\ org.springframework.boot.testcontainers.service.connection.kafka.ApacheKafkaContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.kafka.ConfluentKafkaContainerConnectionDetailsFactory,\ org.springframework.boot.testcontainers.service.connection.kafka.ConfluentKafkaContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.kafka.DeprecatedConfluentKafkaContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.ldap.OpenLdapContainerConnectionDetailsFactory,\ org.springframework.boot.testcontainers.service.connection.ldap.OpenLdapContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.liquibase.LiquibaseContainerConnectionDetailsFactory,\ org.springframework.boot.testcontainers.service.connection.liquibase.LiquibaseContainerConnectionDetailsFactory,\
org.springframework.boot.testcontainers.service.connection.mongo.MongoContainerConnectionDetailsFactory,\ org.springframework.boot.testcontainers.service.connection.mongo.MongoContainerConnectionDetailsFactory,\

19
spring-boot-project/spring-boot-tools/spring-boot-test-support-docker/src/main/java/org/springframework/boot/testsupport/container/TestImage.java

@ -83,6 +83,16 @@ public enum TestImage {
CASSANDRA("cassandra", "3.11.10", () -> CassandraContainer.class, CASSANDRA("cassandra", "3.11.10", () -> CassandraContainer.class,
(container) -> ((CassandraContainer) container).withStartupTimeout(Duration.ofMinutes(10))), (container) -> ((CassandraContainer) container).withStartupTimeout(Duration.ofMinutes(10))),
/**
* A container image suitable for testing Cassandra using the deprecated
* {@link org.testcontainers.containers.CassandraContainer}.
* @deprecated since 3.4.0 for removal in 3.6.0 in favor of {@link #CASSANDRA}
*/
@Deprecated(since = "3.4.0", forRemoval = true)
CASSANDRA_DEPRECATED("cassandra", "3.11.10", () -> org.testcontainers.containers.CassandraContainer.class,
(container) -> ((org.testcontainers.containers.CassandraContainer<?>) container)
.withStartupTimeout(Duration.ofMinutes(10))),
/** /**
* A container image suitable for testing Couchbase. * A container image suitable for testing Couchbase.
*/ */
@ -119,6 +129,15 @@ public enum TestImage {
*/ */
CONFLUENT_KAFKA("confluentinc/cp-kafka", "7.4.0", () -> ConfluentKafkaContainer.class), CONFLUENT_KAFKA("confluentinc/cp-kafka", "7.4.0", () -> ConfluentKafkaContainer.class),
/**
* A container image suitable for testing Confluent's distribution of Kafka using the
* deprecated {@link org.testcontainers.containers.KafkaContainer}.
* @deprecated since 3.4.0 for removal in 3.6.0 in favor of {@link #CONFLUENT_KAFKA}
*/
@Deprecated(since = "3.4.0", forRemoval = true)
CONFLUENT_KAFKA_DEPRECATED("confluentinc/cp-kafka", "7.4.0",
() -> org.testcontainers.containers.KafkaContainer.class),
/** /**
* A container image suitable for testing OpenLDAP. * A container image suitable for testing OpenLDAP.
*/ */

2
spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-data-cassandra/src/dockerTest/java/smoketest/data/cassandra/SecureCassandraContainer.java

@ -17,6 +17,7 @@
package smoketest.data.cassandra; package smoketest.data.cassandra;
import org.testcontainers.cassandra.CassandraContainer; import org.testcontainers.cassandra.CassandraContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.utility.DockerImageName; import org.testcontainers.utility.DockerImageName;
import org.testcontainers.utility.MountableFile; import org.testcontainers.utility.MountableFile;
@ -29,6 +30,7 @@ class SecureCassandraContainer extends CassandraContainer {
SecureCassandraContainer(DockerImageName dockerImageName) { SecureCassandraContainer(DockerImageName dockerImageName) {
super(dockerImageName); super(dockerImageName);
setWaitStrategy(Wait.defaultWaitStrategy()); // default strategy uses plain text
withCopyFileToContainer(MountableFile.forClasspathResource("/ssl/cassandra.yaml"), withCopyFileToContainer(MountableFile.forClasspathResource("/ssl/cassandra.yaml"),
"/etc/cassandra/cassandra.yaml"); "/etc/cassandra/cassandra.yaml");
withCopyFileToContainer(MountableFile.forClasspathResource("/ssl/test-server.p12"), withCopyFileToContainer(MountableFile.forClasspathResource("/ssl/test-server.p12"),

Loading…
Cancel
Save