From 201da97774520bf04cfa37c14a1b6691855bb332 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 8 Jan 2018 16:28:32 -0800 Subject: [PATCH] Further refine test containers --- ...DataAutoConfigurationIntegrationTests.java | 12 +-- ...disRepositoriesAutoConfigurationTests.java | 10 +-- .../SessionAutoConfigurationRedisTests.java | 3 +- .../neo4j/DataNeo4jTestIntegrationTests.java | 10 +-- ...TestWithIncludeFilterIntegrationTests.java | 9 +-- .../redis/DataRedisTestIntegrationTests.java | 10 +-- ...TestWithIncludeFilterIntegrationTests.java | 10 +-- .../testcontainers/CassandraContainer.java | 75 +++++++++++++++++++ ...ockerTestContainer.java => Container.java} | 33 +++++--- ...estContainers.java => Neo4jContainer.java} | 62 +++------------ .../testcontainers/RedisContainer.java | 33 ++++++++ 11 files changed, 161 insertions(+), 106 deletions(-) create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/CassandraContainer.java rename spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/{DockerTestContainer.java => Container.java} (66%) rename spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/{TestContainers.java => Neo4jContainer.java} (53%) create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/RedisContainer.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfigurationIntegrationTests.java index 9e22010ba0..006b43bef3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfigurationIntegrationTests.java @@ -22,14 +22,12 @@ import org.junit.After; import org.junit.Before; import org.junit.ClassRule; import org.junit.Test; -import org.testcontainers.containers.GenericContainer; import org.springframework.boot.autoconfigure.AutoConfigurationPackages; import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; import org.springframework.boot.autoconfigure.data.cassandra.city.City; import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.testsupport.testcontainers.DockerTestContainer; -import org.springframework.boot.testsupport.testcontainers.TestContainers; +import org.springframework.boot.testsupport.testcontainers.CassandraContainer; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.data.cassandra.config.CassandraSessionFactoryBean; import org.springframework.data.cassandra.config.SchemaAction; @@ -45,16 +43,14 @@ import static org.assertj.core.api.Assertions.assertThat; public class CassandraDataAutoConfigurationIntegrationTests { @ClassRule - public static DockerTestContainer> cassandra = new DockerTestContainer<>( - TestContainers::cassandra); + public static CassandraContainer cassandra = new CassandraContainer(); private AnnotationConfigApplicationContext context; @Before public void setUp() { this.context = new AnnotationConfigApplicationContext(); - TestPropertyValues - .of("spring.data.cassandra.port=" + cassandra.getMappedPort(9042)) + TestPropertyValues.of("spring.data.cassandra.port=" + cassandra.getMappedPort()) .applyTo(this.context.getEnvironment()); } @@ -96,7 +92,7 @@ public class CassandraDataAutoConfigurationIntegrationTests { } private void createTestKeyspaceIfNotExists() { - Cluster cluster = Cluster.builder().withPort(cassandra.getMappedPort(9042)) + Cluster cluster = Cluster.builder().withPort(cassandra.getMappedPort()) .addContactPoint("localhost").build(); try (Session session = cluster.connect()) { session.execute("CREATE KEYSPACE IF NOT EXISTS boot_test" diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisRepositoriesAutoConfigurationTests.java index 4b5271e83a..69825da0e2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisRepositoriesAutoConfigurationTests.java @@ -20,7 +20,6 @@ import org.junit.After; import org.junit.Before; import org.junit.ClassRule; import org.junit.Test; -import org.testcontainers.containers.GenericContainer; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; @@ -29,8 +28,7 @@ import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage; import org.springframework.boot.autoconfigure.data.redis.city.City; import org.springframework.boot.autoconfigure.data.redis.city.CityRepository; import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.testsupport.testcontainers.DockerTestContainer; -import org.springframework.boot.testsupport.testcontainers.TestContainers; +import org.springframework.boot.testsupport.testcontainers.RedisContainer; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; @@ -45,15 +43,13 @@ import static org.assertj.core.api.Assertions.assertThat; public class RedisRepositoriesAutoConfigurationTests { @ClassRule - public static DockerTestContainer> redis = new DockerTestContainer<>( - TestContainers::redis); + public static RedisContainer redis = new RedisContainer(); private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); @Before public void setUp() { - TestPropertyValues - .of("spring.redis.port=" + redis.getMappedPort(6379)) + TestPropertyValues.of("spring.redis.port=" + redis.getMappedPort()) .applyTo(this.context.getEnvironment()); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationRedisTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationRedisTests.java index 0baf891599..c4f79bb190 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationRedisTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationRedisTests.java @@ -18,7 +18,6 @@ package org.springframework.boot.autoconfigure.session; import org.junit.ClassRule; import org.junit.Test; -import org.testcontainers.containers.GenericContainer; import org.springframework.beans.DirectFieldAccessor; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -48,7 +47,7 @@ public class SessionAutoConfigurationRedisTests extends AbstractSessionAutoConfigurationTests { @ClassRule - public static DockerTestContainer> redis = new DockerTestContainer<>( + public static DockerTestContainer redis = new DockerTestContainer( TestContainers::redis); protected final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestIntegrationTests.java index 873cde1c95..8a82bcbb47 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestIntegrationTests.java @@ -22,13 +22,11 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.neo4j.ogm.session.Session; -import org.testcontainers.containers.GenericContainer; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.testsupport.testcontainers.DockerTestContainer; -import org.springframework.boot.testsupport.testcontainers.TestContainers; +import org.springframework.boot.testsupport.testcontainers.Neo4jContainer; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; @@ -49,8 +47,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class DataNeo4jTestIntegrationTests { @ClassRule - public static DockerTestContainer> neo4j = new DockerTestContainer<>( - TestContainers::neo4j); + public static Neo4jContainer neo4j = new Neo4jContainer(); @Rule public ExpectedException thrown = ExpectedException.none(); @@ -87,8 +84,7 @@ public class DataNeo4jTestIntegrationTests { public void initialize( ConfigurableApplicationContext configurableApplicationContext) { TestPropertyValues - .of("spring.data.neo4j.uri=bolt://localhost:" - + neo4j.getMappedPort(7687)) + .of("spring.data.neo4j.uri=bolt://localhost:" + neo4j.getMappedPort()) .applyTo(configurableApplicationContext.getEnvironment()); } diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java index 14abdeb372..9ba5e1fe8e 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java @@ -19,12 +19,10 @@ package org.springframework.boot.test.autoconfigure.data.neo4j; import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; -import org.testcontainers.containers.GenericContainer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.testsupport.testcontainers.DockerTestContainer; -import org.springframework.boot.testsupport.testcontainers.TestContainers; +import org.springframework.boot.testsupport.testcontainers.Neo4jContainer; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.ComponentScan.Filter; @@ -45,8 +43,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class DataNeo4jTestWithIncludeFilterIntegrationTests { @ClassRule - public static DockerTestContainer> neo4j = new DockerTestContainer<>( - TestContainers::neo4j); + public static Neo4jContainer neo4j = new Neo4jContainer(); @Autowired private ExampleService service; @@ -63,7 +60,7 @@ public class DataNeo4jTestWithIncludeFilterIntegrationTests { public void initialize( ConfigurableApplicationContext configurableApplicationContext) { TestPropertyValues - .of("spring.data.neo4j.uri=bolt://localhost:" + neo4j.getMappedPort(7687)) + .of("spring.data.neo4j.uri=bolt://localhost:" + neo4j.getMappedPort()) .applyTo(configurableApplicationContext.getEnvironment()); } diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/redis/DataRedisTestIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/redis/DataRedisTestIntegrationTests.java index 9d30d727e8..b1795389db 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/redis/DataRedisTestIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/redis/DataRedisTestIntegrationTests.java @@ -24,13 +24,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; -import org.testcontainers.containers.GenericContainer; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.testsupport.testcontainers.DockerTestContainer; -import org.springframework.boot.testsupport.testcontainers.TestContainers; +import org.springframework.boot.testsupport.testcontainers.RedisContainer; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; @@ -52,8 +50,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class DataRedisTestIntegrationTests { @ClassRule - public static DockerTestContainer> redis = new DockerTestContainer<>( - TestContainers::redis); + public static RedisContainer redis = new RedisContainer(); @Rule public ExpectedException thrown = ExpectedException.none(); @@ -93,8 +90,7 @@ public class DataRedisTestIntegrationTests { @Override public void initialize( ConfigurableApplicationContext configurableApplicationContext) { - TestPropertyValues - .of("spring.redis.port=" + redis.getMappedPort(6379)) + TestPropertyValues.of("spring.redis.port=" + redis.getMappedPort()) .applyTo(configurableApplicationContext.getEnvironment()); } diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/redis/DataRedisTestWithIncludeFilterIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/redis/DataRedisTestWithIncludeFilterIntegrationTests.java index 9f1fe84e95..cc8dd7140b 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/redis/DataRedisTestWithIncludeFilterIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/redis/DataRedisTestWithIncludeFilterIntegrationTests.java @@ -19,12 +19,10 @@ package org.springframework.boot.test.autoconfigure.data.redis; import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; -import org.testcontainers.containers.GenericContainer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.testsupport.testcontainers.DockerTestContainer; -import org.springframework.boot.testsupport.testcontainers.TestContainers; +import org.springframework.boot.testsupport.testcontainers.RedisContainer; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.ComponentScan.Filter; @@ -45,8 +43,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class DataRedisTestWithIncludeFilterIntegrationTests { @ClassRule - public static DockerTestContainer> redis = new DockerTestContainer<>( - TestContainers::redis); + public static RedisContainer redis = new RedisContainer(); @Autowired private ExampleRepository exampleRepository; @@ -69,8 +66,7 @@ public class DataRedisTestWithIncludeFilterIntegrationTests { @Override public void initialize( ConfigurableApplicationContext configurableApplicationContext) { - TestPropertyValues - .of("spring.redis.port=" + redis.getMappedPort(6379)) + TestPropertyValues.of("spring.redis.port=" + redis.getMappedPort()) .applyTo(configurableApplicationContext.getEnvironment()); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/CassandraContainer.java b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/CassandraContainer.java new file mode 100644 index 0000000000..d54581299b --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/CassandraContainer.java @@ -0,0 +1,75 @@ +/* + * Copyright 2012-2018 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 + * + * http://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.testsupport.testcontainers; + +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; + +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.exceptions.NoHostAvailableException; +import org.rnorth.ducttape.TimeoutException; +import org.rnorth.ducttape.unreliables.Unreliables; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.HostPortWaitStrategy; + +/** + * A {@link GenericContainer} for Cassandra. + * + * @author Andy Wilkinson + * @author Madhura Bhave + */ +public class CassandraContainer extends Container { + + private static final int PORT = 9042; + + public CassandraContainer() { + super("cassandra:3.11.1", PORT, + (container) -> container.waitingFor(new WaitStrategy())); + } + + private static class WaitStrategy extends HostPortWaitStrategy { + + @Override + protected void waitUntilReady() { + super.waitUntilReady(); + + try { + Unreliables.retryUntilTrue((int) this.startupTimeout.getSeconds(), + TimeUnit.SECONDS, checkConnection()); + } + catch (TimeoutException ex) { + throw new IllegalStateException(ex); + } + } + + private Callable checkConnection() { + return () -> { + try (Cluster cluster = Cluster.builder() + .withPort(this.container.getMappedPort(PORT)) + .addContactPoint("localhost").build()) { + cluster.connect(); + return true; + } + catch (IllegalArgumentException | NoHostAvailableException ex) { + return false; + } + }; + } + + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/DockerTestContainer.java b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/Container.java similarity index 66% rename from spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/DockerTestContainer.java rename to spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/Container.java index f9a2074dff..c5d874719c 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/DockerTestContainer.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/Container.java @@ -16,6 +16,7 @@ package org.springframework.boot.testsupport.testcontainers; +import java.util.function.Consumer; import java.util.function.Supplier; import org.junit.AssumptionViolatedException; @@ -29,17 +30,31 @@ import org.testcontainers.containers.GenericContainer; * {@link TestRule} for working with an optional Docker environment. Spins up a * {@link GenericContainer} if a valid docker environment is found. * - * @param the type of the container * @author Madhura Bhave + * @author Phillip Webb */ -public class DockerTestContainer> implements TestRule { +class Container implements TestRule { - private final Supplier containerSupplier; + private final int port; - private T container; + private final Supplier> containerFactory; - public DockerTestContainer(Supplier containerSupplier) { - this.containerSupplier = containerSupplier; + private GenericContainer container; + + > Container(String dockerImageName, int port) { + this(dockerImageName, port, null); + } + + @SuppressWarnings({ "unchecked", "resource" }) + > Container(String dockerImageName, int port, + Consumer customizer) { + this.port = port; + this.containerFactory = () -> { + T container = (T) new GenericContainer<>(dockerImageName) + .withExposedPorts(port); + customizer.accept(container); + return container; + }; } @Override @@ -50,12 +65,12 @@ public class DockerTestContainer> implements TestR catch (Throwable t) { return new SkipStatement(); } - this.container = this.containerSupplier.get(); + this.container = this.containerFactory.get(); return this.container.apply(base, description); } - public int getMappedPort(int originalPort) { - return this.container.getMappedPort(originalPort); + public int getMappedPort() { + return this.container.getMappedPort(this.port); } private static class SkipStatement extends Statement { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/TestContainers.java b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/Neo4jContainer.java similarity index 53% rename from spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/TestContainers.java rename to spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/Neo4jContainer.java index efbad3d019..6bbb2c9865 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/TestContainers.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/Neo4jContainer.java @@ -19,8 +19,6 @@ package org.springframework.boot.testsupport.testcontainers; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; -import com.datastax.driver.core.Cluster; -import com.datastax.driver.core.exceptions.NoHostAvailableException; import org.neo4j.ogm.config.Configuration; import org.neo4j.ogm.session.SessionFactory; import org.rnorth.ducttape.TimeoutException; @@ -29,69 +27,26 @@ import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.HostPortWaitStrategy; /** - * Provides utility methods that allow creation of docker containers for - * tests. + * A {@link GenericContainer} for Neo4J. * * @author Andy Wilkinson * @author Madhura Bhave */ -public abstract class TestContainers { +public class Neo4jContainer extends Container { - @SuppressWarnings("resource") - public static GenericContainer redis() { - return new GenericContainer<>("redis:4.0.6").withExposedPorts(6379); + public Neo4jContainer() { + super("neo4j:3.3.1", 7687, (container) -> container.waitingFor(new WaitStrategy()) + .withEnv("NEO4J_AUTH", "none")); } - @SuppressWarnings("resource") - public static GenericContainer cassandra() { - return new GenericContainer<>("cassandra:3.11.1").withExposedPorts(9042) - .waitingFor(new CassandraConnectionVerifyingWaitStrategy()); - } - - public static GenericContainer neo4j() { - return new GenericContainer<>("neo4j:3.3.1").withExposedPorts(7687) - .waitingFor(new Neo4jConnectionVerifyingWaitStrategy()) - .withEnv("NEO4J_AUTH", "none"); - } - - private static class CassandraConnectionVerifyingWaitStrategy extends HostPortWaitStrategy { - - @Override - protected void waitUntilReady() { - super.waitUntilReady(); - - try { - Unreliables.retryUntilTrue((int) this.startupTimeout.getSeconds(), - TimeUnit.SECONDS, checkConnection()); - } - catch (TimeoutException ex) { - throw new IllegalStateException(ex); - } - } - - private Callable checkConnection() { - return () -> { - try (Cluster cluster = Cluster.builder().withPort(this.container.getMappedPort(9042)) - .addContactPoint("localhost") - .build()) { - cluster.connect(); - return true; - } - catch (IllegalArgumentException | NoHostAvailableException ex) { - return false; - } - }; - } - - } - - private static class Neo4jConnectionVerifyingWaitStrategy extends HostPortWaitStrategy { + private static class WaitStrategy extends HostPortWaitStrategy { @Override protected void waitUntilReady() { super.waitUntilReady(); Configuration configuration = new Configuration.Builder() - .uri("bolt://localhost:" + this.container.getMappedPort(7687)).build(); + .uri("bolt://localhost:" + this.container.getMappedPort(7687)) + .build(); SessionFactory sessionFactory = new SessionFactory(configuration, "org.springframework.boot.test.autoconfigure.data.neo4j"); try { @@ -114,6 +69,7 @@ public abstract class TestContainers { } }; } + } } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/RedisContainer.java b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/RedisContainer.java new file mode 100644 index 0000000000..48df602597 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/RedisContainer.java @@ -0,0 +1,33 @@ +/* + * Copyright 2012-2018 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 + * + * http://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.testsupport.testcontainers; + +import org.testcontainers.containers.GenericContainer; + +/** + * A {@link GenericContainer} for Redis. + * + * @author Andy Wilkinson + * @author Madhura Bhave + */ +public class RedisContainer extends Container { + + public RedisContainer() { + super("redis:4.0.6", 6379); + } + +}