Decorate test containers so tests are skipped without Docker

Closes gh-15901
Closes gh-15638
pull/15951/head
Andy Wilkinson 6 years ago
parent 46bf82ca82
commit 9fb0b97f96

@ -28,6 +28,7 @@ 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.SkippableContainer;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.data.cassandra.config.CassandraSessionFactoryBean;
import org.springframework.data.cassandra.config.SchemaAction;
@ -43,7 +44,8 @@ import static org.assertj.core.api.Assertions.assertThat;
public class CassandraDataAutoConfigurationIntegrationTests {
@ClassRule
public static CassandraContainer<?> cassandra = new CassandraContainer<>();
public static SkippableContainer<CassandraContainer<?>> cassandra = new SkippableContainer<>(
CassandraContainer::new);
private AnnotationConfigApplicationContext context;
@ -51,7 +53,8 @@ public class CassandraDataAutoConfigurationIntegrationTests {
public void setUp() {
this.context = new AnnotationConfigApplicationContext();
TestPropertyValues
.of("spring.data.cassandra.port=" + cassandra.getFirstMappedPort(),
.of("spring.data.cassandra.port="
+ cassandra.getContainer().getFirstMappedPort(),
"spring.data.cassandra.read-timeout=24000",
"spring.data.cassandra.connect-timeout=10000")
.applyTo(this.context.getEnvironment());
@ -96,7 +99,8 @@ public class CassandraDataAutoConfigurationIntegrationTests {
private void createTestKeyspaceIfNotExists() {
Cluster cluster = Cluster.builder().withoutJMXReporting()
.withPort(cassandra.getFirstMappedPort()).addContactPoint("localhost")
.withPort(cassandra.getContainer().getFirstMappedPort())
.addContactPoint(cassandra.getContainer().getContainerIpAddress())
.build();
try (Session session = cluster.connect()) {
session.execute("CREATE KEYSPACE IF NOT EXISTS boot_test"

@ -18,13 +18,17 @@ package org.springframework.boot.test.autoconfigure.data.neo4j;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runners.model.Statement;
import org.neo4j.ogm.session.Session;
import org.testcontainers.containers.Neo4jContainer;
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.SkippableContainer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
@ -46,9 +50,18 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@DataNeo4jTest
public class DataNeo4jTestIntegrationTests {
public static SkippableContainer<Neo4jContainer<?>> neo4j = new SkippableContainer<Neo4jContainer<?>>(
() -> new Neo4jContainer<>().withAdminPassword(null));
@ClassRule
public static Neo4jContainer<?> neo4j = new Neo4jContainer<>()
.withAdminPassword(null);
public static TestRule skippableContainer = new TestRule() {
@Override
public Statement apply(Statement base, Description description) {
return neo4j.apply(base, description);
}
};
@Autowired
private Session session;
@ -81,7 +94,8 @@ public class DataNeo4jTestIntegrationTests {
@Override
public void initialize(
ConfigurableApplicationContext configurableApplicationContext) {
TestPropertyValues.of("spring.data.neo4j.uri=" + neo4j.getBoltUrl())
TestPropertyValues
.of("spring.data.neo4j.uri=" + neo4j.getContainer().getBoltUrl())
.applyTo(configurableApplicationContext.getEnvironment());
}

@ -23,6 +23,7 @@ import org.testcontainers.containers.Neo4jContainer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.testsupport.testcontainers.SkippableContainer;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
@ -43,8 +44,8 @@ import static org.assertj.core.api.Assertions.assertThat;
public class DataNeo4jTestPropertiesIntegrationTests {
@ClassRule
public static Neo4jContainer<?> neo4j = new Neo4jContainer<>()
.withAdminPassword(null);
public static SkippableContainer<Neo4jContainer<?>> neo4j = new SkippableContainer<Neo4jContainer<?>>(
() -> new Neo4jContainer<>().withAdminPassword(null));
@Autowired
private Environment environment;
@ -60,7 +61,8 @@ public class DataNeo4jTestPropertiesIntegrationTests {
@Override
public void initialize(
ConfigurableApplicationContext configurableApplicationContext) {
TestPropertyValues.of("spring.data.neo4j.uri=" + neo4j.getBoltUrl())
TestPropertyValues
.of("spring.data.neo4j.uri=" + neo4j.getContainer().getBoltUrl())
.applyTo(configurableApplicationContext.getEnvironment());
}

@ -23,6 +23,7 @@ import org.testcontainers.containers.Neo4jContainer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.testsupport.testcontainers.SkippableContainer;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan.Filter;
@ -44,8 +45,8 @@ import static org.assertj.core.api.Assertions.assertThat;
public class DataNeo4jTestWithIncludeFilterIntegrationTests {
@ClassRule
public static Neo4jContainer<?> neo4j = new Neo4jContainer<>()
.withAdminPassword(null);
public static SkippableContainer<Neo4jContainer<?>> neo4j = new SkippableContainer<Neo4jContainer<?>>(
() -> new Neo4jContainer<>().withAdminPassword(null));
@Autowired
private ExampleService service;
@ -61,7 +62,8 @@ public class DataNeo4jTestWithIncludeFilterIntegrationTests {
@Override
public void initialize(
ConfigurableApplicationContext configurableApplicationContext) {
TestPropertyValues.of("spring.data.neo4j.uri=" + neo4j.getBoltUrl())
TestPropertyValues
.of("spring.data.neo4j.uri=" + neo4j.getContainer().getBoltUrl())
.applyTo(configurableApplicationContext.getEnvironment());
}

@ -0,0 +1,77 @@
/*
* Copyright 2012-2019 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.function.Supplier;
import org.junit.AssumptionViolatedException;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.testcontainers.DockerClientFactory;
import org.testcontainers.containers.FailureDetectingExternalResource;
import org.testcontainers.containers.GenericContainer;
/**
* A {@link GenericContainer} decorator that skips test execution when Docker is not
* available.
*
* @param <T> type of the underlying container
* @author Andy Wilkinson
*/
public class SkippableContainer<T> implements TestRule {
private final Supplier<T> containerFactory;
private T container;
public SkippableContainer(Supplier<T> containerFactory) {
this.containerFactory = containerFactory;
}
@Override
public Statement apply(Statement base, Description description) {
try {
DockerClientFactory.instance().client();
}
catch (Throwable ex) {
return new SkipStatement();
}
this.container = this.containerFactory.get();
return ((FailureDetectingExternalResource) this.container).apply(base,
description);
}
public T getContainer() {
if (this.container == null) {
throw new IllegalStateException(
"Container cannot be accessed prior to test invocation");
}
return this.container;
}
private static class SkipStatement extends Statement {
@Override
public void evaluate() {
throw new AssumptionViolatedException(
"Could not find a valid Docker environment.");
}
}
}
Loading…
Cancel
Save