Polishing.

Rename AssumeConnection to EnabledOnElasticsearch following the typical design of JUnit 5 EnabledOn… annotation programming model. Enable tests by default if the test element isn't annotated with EnabledOnElasticsearch as we assume that the extension was activated by the parent.

Move EnabledOnElasticsearch into utility project.

See #583
Original pull request: #609
This commit is contained in:
Mark Paluch
2021-04-08 10:24:20 +02:00
parent 75b2a08d60
commit b5cecf730b
15 changed files with 168 additions and 207 deletions

View File

@@ -3,7 +3,6 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>spring-data-elasticsearch-example</artifactId>
<name>Spring Data Elasticsearch - Node Client Example</name>
@@ -18,6 +17,11 @@
<dependencies>
<dependency>
<groupId>org.springframework.data.examples</groupId>
<artifactId>spring-data-elasticsearch-example-utils</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2021-2021 the original author or authors.
* Copyright 2020-2021 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.
@@ -15,12 +15,15 @@
*/
package example.springdata.elasticsearch.conference;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.*;
import example.springdata.elasticsearch.util.EnabledOnElasticsearch;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
@@ -40,7 +43,8 @@ import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
* @author Prakhar Gupta
*/
@SpringBootTest(classes = ApplicationConfiguration.class)
public class ElasticsearchOperationsTest {
@EnabledOnElasticsearch
class ElasticsearchOperationsTest {
private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
@@ -48,7 +52,7 @@ public class ElasticsearchOperationsTest {
ElasticsearchOperations operations;
@Test
public void textSearch() throws ParseException {
void textSearch() throws ParseException {
String expectedDate = "2014-10-29";
String expectedWord = "java";
@@ -66,7 +70,7 @@ public class ElasticsearchOperationsTest {
}
@Test
public void geoSpatialSearch() {
void geoSpatialSearch() {
GeoPoint startLocation = new GeoPoint(50.0646501D, 19.9449799D);
String range = "330mi"; // or 530km

View File

@@ -16,11 +16,22 @@
<url>https://github.com/spring-projects/spring-data-elasticsearch</url>
<modules>
<module>util</module>
<module>example</module>
<module>rest</module>
<module>reactive</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.data.examples</groupId>
<artifactId>spring-data-elasticsearch-example-utils</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>

View File

@@ -3,7 +3,6 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>spring-data-elasticsearch-reactive-example</artifactId>
<name>Spring Data Elasticsearch - Reactive Example</name>
@@ -18,6 +17,11 @@
<dependencies>
<dependency>
<groupId>org.springframework.data.examples</groupId>
<artifactId>spring-data-elasticsearch-example-utils</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>

View File

@@ -15,16 +15,16 @@
*/
package example.springdata.elasticsearch.conference;
import example.springdata.elasticsearch.util.AssumeConnection;
import reactor.test.StepVerifier;
import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import example.springdata.elasticsearch.util.EnabledOnElasticsearch;
import reactor.test.StepVerifier;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
@@ -38,9 +38,9 @@ import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
* @author Christoph Strobl
* @author Prakhar Gupta
*/
@AssumeConnection
@EnabledOnElasticsearch
@SpringBootTest(classes = ApplicationConfiguration.class)
public class ReactiveElasticsearchOperationsTest {
class ReactiveElasticsearchOperationsTest {
private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
@@ -48,8 +48,7 @@ public class ReactiveElasticsearchOperationsTest {
ReactiveElasticsearchOperations operations;
@Test
@AssumeConnection
public void textSearch() {
void textSearch() {
String expectedDate = "2014-10-29";
String expectedWord = "java";

View File

@@ -15,16 +15,16 @@
*/
package example.springdata.elasticsearch.conference;
import example.springdata.elasticsearch.util.AssumeConnection;
import reactor.test.StepVerifier;
import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import example.springdata.elasticsearch.util.EnabledOnElasticsearch;
import reactor.test.StepVerifier;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@@ -34,9 +34,9 @@ import org.springframework.boot.test.context.SpringBootTest;
* @author Christoph Strobl
* @author Prakhar Gupta
*/
@AssumeConnection
@EnabledOnElasticsearch
@SpringBootTest(classes = ApplicationConfiguration.class)
public class ReactiveElasticsearchRepositoryTest {
class ReactiveElasticsearchRepositoryTest {
private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
@@ -44,8 +44,7 @@ public class ReactiveElasticsearchRepositoryTest {
ConferenceRepository repository;
@Test
@AssumeConnection
public void textSearch() {
void textSearch() {
String expectedDate = "2014-10-29";
String expectedWord = "java";

View File

@@ -1,69 +0,0 @@
/*
* Copyright 2019-2021 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 example.springdata.elasticsearch.util;
import static org.junit.platform.commons.support.AnnotationSupport.findAnnotation;
import java.io.IOException;
import java.util.Optional;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.junit.jupiter.api.extension.ConditionEvaluationResult;
import org.junit.jupiter.api.extension.ExecutionCondition;
import org.junit.jupiter.api.extension.ExtensionContext;
/**
* @author Christoph Strobl
* @author Prakhar Gupta
*/
public class ElasticsearchAvailable implements ExecutionCondition {
private boolean checkServerRunning(String url) {
boolean isConnectionAvailable = false;
try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
CloseableHttpResponse response = client.execute(new HttpHead(url));
if (response != null && response.getStatusLine() != null) {
isConnectionAvailable = true;
}
} catch (IOException e) {
return isConnectionAvailable;
}
return isConnectionAvailable;
}
@Override
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext extensionContext) {
Optional<AssumeConnection> annotation = findAnnotation(extensionContext.getElement(), AssumeConnection.class);
if (annotation.isPresent()) {
String url = annotation.get().url();
if (checkServerRunning(url)) {
return ConditionEvaluationResult.enabled("Successfully connected to Elasticsearch server. Continuing test!");
} else {
return ConditionEvaluationResult.disabled("Elasticsearch Server seems to be down. Skipping test!");
}
}
return ConditionEvaluationResult.disabled("No connection specified. Skipping test!");
}
}

View File

@@ -3,7 +3,6 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>spring-data-elasticsearch-rest-client-example</artifactId>
<name>Spring Data Elasticsearch - Rest Client Example</name>
@@ -18,6 +17,11 @@
<dependencies>
<dependency>
<groupId>org.springframework.data.examples</groupId>
<artifactId>spring-data-elasticsearch-example-utils</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>

View File

@@ -22,10 +22,8 @@ import javax.annotation.PreDestroy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
/**
* @author Artur Konczak

View File

@@ -15,14 +15,15 @@
*/
package example.springdata.elasticsearch.conference;
import example.springdata.elasticsearch.util.AssumeConnection;
import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.api.Assertions.assertThat;
import example.springdata.elasticsearch.util.EnabledOnElasticsearch;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
@@ -38,9 +39,9 @@ import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
* @author Christoph Strobl
* @author Prakhar Gupta
*/
@AssumeConnection
@EnabledOnElasticsearch
@SpringBootTest(classes = ApplicationConfiguration.class)
public class ElasticsearchOperationsTest {
class ElasticsearchOperationsTest {
private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
@@ -48,8 +49,7 @@ public class ElasticsearchOperationsTest {
ElasticsearchOperations operations;
@Test
@AssumeConnection
public void textSearch() throws ParseException {
void textSearch() throws ParseException {
String expectedDate = "2014-10-29";
String expectedWord = "java";
CriteriaQuery query = new CriteriaQuery(

View File

@@ -1,33 +0,0 @@
/*
* Copyright 2021 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 example.springdata.elasticsearch.util;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.jupiter.api.extension.ExtendWith;
/**
* @author Prakhar Gupta
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@ExtendWith(ElasticsearchAvailable.class)
public @interface AssumeConnection {
String url() default "http://localhost:9200";
}

View File

@@ -1,70 +0,0 @@
/*
* Copyright 2019-2021 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 example.springdata.elasticsearch.util;
import static org.junit.platform.commons.support.AnnotationSupport.findAnnotation;
import java.io.IOException;
import java.util.Optional;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.junit.jupiter.api.extension.ConditionEvaluationResult;
import org.junit.jupiter.api.extension.ExecutionCondition;
import org.junit.jupiter.api.extension.ExtensionContext;
/**
* @author Christoph Strobl
* @author Prakhar Gupta
*/
public class ElasticsearchAvailable implements ExecutionCondition {
private boolean checkServerRunning(String url) {
boolean isConnectionAvailable = false;
try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
CloseableHttpResponse response = client.execute(new HttpHead(url));
if (response != null && response.getStatusLine() != null) {
isConnectionAvailable = true;
}
} catch (IOException e) {
return isConnectionAvailable;
}
return isConnectionAvailable;
}
@Override
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext extensionContext) {
Optional<AssumeConnection> annotation = findAnnotation(extensionContext.getElement(), AssumeConnection.class);
if (annotation.isPresent()) {
String url = annotation.get().url();
if (checkServerRunning(url)) {
return ConditionEvaluationResult
.enabled("Successfully connected to Elasticsearch server. Continuing test!");
} else {
return ConditionEvaluationResult.disabled("Elasticsearch Server seems to be down. Skipping test!");
}
}
return ConditionEvaluationResult.disabled("No connection specified. Skipping test!");
}
}

View File

@@ -0,0 +1,35 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.data.examples</groupId>
<artifactId>spring-data-elasticsearch-examples</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-data-elasticsearch-example-utils</artifactId>
<name>Spring Data Elasticsearch - Example Utilities</name>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2021 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 example.springdata.elasticsearch.util;
import java.util.Optional;
import org.junit.jupiter.api.extension.ConditionEvaluationResult;
import org.junit.jupiter.api.extension.ExecutionCondition;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.platform.commons.support.AnnotationSupport;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
/**
* {@link ExecutionCondition} evaluating {@link EnabledOnElasticsearch @EnableOnElasticsearch}.
*
* @author Christoph Strobl
* @author Prakhar Gupta
*/
class ElasticsearchAvailableCondition implements ExecutionCondition {
@Override
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext extensionContext) {
Optional<EnabledOnElasticsearch> annotation = AnnotationSupport.findAnnotation(extensionContext.getElement(),
EnabledOnElasticsearch.class);
return annotation.map(EnabledOnElasticsearch::url) //
.map(ElasticsearchAvailableCondition::checkServerRunning) //
.orElse(ConditionEvaluationResult.enabled("Enabled by default"));
}
private static ConditionEvaluationResult checkServerRunning(String url) {
RestTemplate template = new RestTemplate();
try {
ResponseEntity<byte[]> entity = template.exchange(url, HttpMethod.HEAD, null, byte[].class);
return ConditionEvaluationResult
.enabled("Successfully connected to Elasticsearch server: " + entity.getStatusCode());
} catch (RuntimeException e) {
return ConditionEvaluationResult.disabled("Elasticsearch unavailable at " + url + "; " + e.getMessage());
}
}
}

View File

@@ -5,7 +5,7 @@
* 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
* 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,
@@ -23,11 +23,26 @@ import java.lang.annotation.Target;
import org.junit.jupiter.api.extension.ExtendWith;
/**
* {@code @EnableOnElasticsearch} is used to signal that the annotated test class or test method is only
* <em>enabled</em> if Elasticsearch is available at {@link #url()}.
* <p>
* When applied at the class level, all test methods within that class will be enabled if Elasticsearch is available.
* <p>
* If a test method is disabled via this annotation, that does not prevent the test class from being instantiated.
* Rather, it prevents the execution of the test method and method-level lifecycle callbacks such as {@code @BeforeEach}
* methods, {@code @AfterEach} methods, and corresponding extension APIs.
*
* @author Prakhar Gupta
* @author Mark Paluch
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@ExtendWith(ElasticsearchAvailable.class)
public @interface AssumeConnection {
@ExtendWith(ElasticsearchAvailableCondition.class)
public @interface EnabledOnElasticsearch {
/**
* URL pointing at the Elasticsearch instance to check.
*/
String url() default "http://localhost:9200";
}