Skip to content

Commit

Permalink
Savecommit
Browse files Browse the repository at this point in the history
  • Loading branch information
Bukama committed Apr 20, 2024
1 parent 0d25143 commit a3bf5b4
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 42 deletions.
3 changes: 2 additions & 1 deletion src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@

requires static com.fasterxml.jackson.core;
requires static com.fasterxml.jackson.databind;
requires java.net.http;

exports org.junitpioneer.vintage;
exports org.junitpioneer.vintage;
exports org.junitpioneer.jupiter;
exports org.junitpioneer.jupiter.cartesian;
exports org.junitpioneer.jupiter.params;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@

package org.junitpioneer.jupiter;

import org.junit.jupiter.api.extension.ExtendWith;

import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.junit.jupiter.api.extension.ExtendWith;

/**
* {@code @DisabledIfNotReachable} is a JUnit Jupiter extension to check if a given URL is reachable before executing
* the test and disable the test if it's not.
Expand All @@ -33,8 +33,8 @@
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
@Inherited
@ExtendWith(DisabledIfNotReachableExtension.class)
public @interface DisabledIfNotReachable {
@ExtendWith(DisableIfNotReachableExtension.class)
public @interface DisableIfNotReachable {

/**
* The url to be checked.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,39 @@

import org.junit.jupiter.api.extension.ConditionEvaluationResult;
import org.junit.jupiter.api.extension.ExecutionCondition;
import org.junit.jupiter.api.extension.ExtensionConfigurationException;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ExtensionContext.Namespace;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

import static java.lang.String.format;
import static org.junit.jupiter.api.extension.ConditionEvaluationResult.disabled;
import static org.junit.jupiter.api.extension.ConditionEvaluationResult.enabled;
import static org.junitpioneer.internal.PioneerAnnotationUtils.findClosestEnclosingAnnotation;

class DisabledIfNotReachableExtension implements ExecutionCondition {
class DisableIfNotReachableExtension implements ExecutionCondition {

private static final Namespace NAMESPACE = Namespace.create(DisabledIfNotReachableExtension.class);
private static final Namespace NAMESPACE = Namespace.create(DisableIfNotReachableExtension.class);
private static final String DISABLED_KEY = "DISABLED_KEY";
private static final String DISABLED_VALUE = "";

@Override
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
var optAnnotation = findClosestEnclosingAnnotation(context, DisabledIfNotReachable.class);
var optAnnotation = findClosestEnclosingAnnotation(context, DisableIfNotReachable.class);

if (optAnnotation.isEmpty()) {
return enabled("No @DisabledIfNotReachable annotation found.");
}

var config = readConfigurationFromAnnotation(optAnnotation.get());

return pingUrl(config, context);
}

/**
Expand All @@ -44,56 +53,63 @@ public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext con
*
* Based on <a href="https://stackoverflow.com/users/157882/balusc">BalusC</a>'s answer on StackOverflow to
* <a href="https://stackoverflow.com/a/3584332/2525313">Preferred Java way to ping an HTTP URL for availability</a>
* but with JDK 11 HTTP-Client.
* but with <a href="https://openjdk.org/groups/net/httpclient/intro.html">JDK 11 HTTP-Client</a>.
*
* @param config
* Configuration, including the url and a timeout value, based on annotation value
* @param context
* Extension context to get the unique ID of the test to be executed
*
*
* @return {@code true} if the given HTTP URL has returned response
* code 200-399 on a HEAD request within the given timeout, otherwise
* {@code false}.
*/
private static ConditionEvaluationResult pingUrl(DisabledIfNotReachableConfiguration config, ExtensionContext context) {
private static ConditionEvaluationResult pingUrl(DisabledIfNotReachableConfiguration config,
ExtensionContext context) {

String url = config.getUrl();
int timeout = config.getTimeOut();
boolean reachable = false;

https: //openjdk.org/groups/net/httpclient/intro.html
try (HttpClient client = HttpClient
.newBuilder()
.version(HttpClient.Version.HTTP_2)
.followRedirects(HttpClient.Redirect.NORMAL)
.build()) {

boolean reachable = false;
HttpRequest request = HttpRequest
.newBuilder()
.uri(URI.create(config.url))
.timeout(Duration.ofMillis(config.getTimeout()))
.GET()
.build();

int responseCode = client.send(request, HttpResponse.BodyHandlers.ofString()).statusCode();

// We consider the target reachable if we get an HTTP response code which does not indicate an error.
reachable = (200 <= responseCode && responseCode <= 399);
}
catch (IOException | InterruptedException e) {
// Nothing to do, as the reachable variable is initialized with false anyway.
// The return statement is not placed here as the responseCode is also inspected for the final result.
}

if (reachable) {
return enabled(format("%s is enabled because %s is reachable", context.getUniqueId(), config.getUrl()));
} else {
return disabled(format("%s is disabled because %s could not be reached in %dms", context.getUniqueId(),
config.getUrl(), config.getTimeOut()));
config.getUrl(), config.getTimeout()));
}
}

private DisabledIfNotReachableConfiguration readConfigurationFromAnnotation(DisableIfNotReachable annotation) {

// * @param config
// * The HTTP URL to be pinged.
// * @param timeoutMillis
// * The timeout in millis for both the connection timeout and the
// * response read timeout. Note that the total timeout is effectively
// * two times the given timeout.
// // Otherwise an exception may be thrown on invalid SSL certificates
// String httpUrl = url.replaceFirst("^https", "http");
// try {
// HttpURLConnection connection = (HttpURLConnection) new URL(httpUrl).openConnection();
// connection.setConnectTimeout(timeoutMillis);
// connection.setReadTimeout(timeoutMillis);
// connection.setRequestMethod("HEAD");
// int responseCode = connection.getResponseCode();
// return (200 <= responseCode && responseCode <= 399);
// } catch (IOException exception) {
// return false;
// }
}
if (null == annotation.url()) {
throw new ExtensionConfigurationException("URL must not be null");
}

if (annotation.timeoutMillis() <= 0) {
throw new ExtensionConfigurationException("Timeout must be greater than zero");
}

private DisabledIfNotReachableConfiguration readConfigurationFromAnnotation(DisabledIfNotReachable annotation) {
return new DisabledIfNotReachableConfiguration(annotation.url(), annotation.timeoutMillis());
}

Expand All @@ -102,17 +118,17 @@ private DisabledIfNotReachableConfiguration readConfigurationFromAnnotation(Disa
*/
private class DisabledIfNotReachableConfiguration {

// Change to record when after migrating to Java 16+
// Change to record after migrating to Java 16+
private final String url;
private final int timeOut;
private final int timeout;

public DisabledIfNotReachableConfiguration(String url, int timeOut) {
public DisabledIfNotReachableConfiguration(String url, int timeout) {
this.url = url;
this.timeOut = timeOut;
this.timeout = timeout;
}

public int getTimeOut() {
return timeOut;
public int getTimeout() {
return timeout;
}

public String getUrl() {
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/junitpioneer/jupiter/package-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* <li>{@link org.junitpioneer.jupiter.DefaultLocale} and {@link org.junitpioneer.jupiter.DefaultTimeZone}</li>
* <li>{@link org.junitpioneer.jupiter.DisabledUntil}</li>
* <li>{@link org.junitpioneer.jupiter.DisableIfTestFails}</li>
* <li>{@link org.junitpioneer.jupiter.DisableIfNotReachable}</li>
* <li>{@link org.junitpioneer.jupiter.ExpectedToFail}</li>
* <li>{@link org.junitpioneer.jupiter.ReportEntry}</li>
* <li>{@link org.junitpioneer.jupiter.RetryingTest}</li>
Expand Down

0 comments on commit a3bf5b4

Please sign in to comment.