Skip to content

Commit

Permalink
Merge pull request quarkusio#41537 from geoand/rest-assured-test-common
Browse files Browse the repository at this point in the history
Simplify code in RestAssuredURLManager
  • Loading branch information
geoand authored Jun 28, 2024
2 parents 788a716 + be7d0e7 commit 6fbcb0e
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 179 deletions.
5 changes: 5 additions & 0 deletions test-framework/common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@
<groupId>org.jboss.logging</groupId>
<artifactId>commons-logging-jboss-logging</artifactId>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
package io.quarkus.test.common;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.time.Duration;
import java.util.Optional;

import org.eclipse.microprofile.config.ConfigProvider;

import io.restassured.RestAssured;
import io.restassured.config.HttpClientConfig;
import io.restassured.config.RestAssuredConfig;

/**
* Utility class that sets the rest assured port to the default test port and meaningful timeouts.
* <p>
* This uses reflection so as to not introduce a dependency on rest-assured
* This class works whether RestAssured is on the classpath or not - if it is not, invoking the methods of the class are
* essentially NO-OPs
* <p>
* TODO: do we actually want this here, or should it be in a different module?
*/
Expand All @@ -19,70 +22,21 @@ public class RestAssuredURLManager {
private static final int DEFAULT_HTTP_PORT = 8081;
private static final int DEFAULT_HTTPS_PORT = 8444;

private static final Field portField;
private static final Field baseURIField;
private static final Field basePathField;
private static final Field configField;

private static final Method setParamMethod;
private static final Method configMethod;
private static final Method httpClientMethod;
private static final Class<?> httpClientConfigClass;

private static int oldPort;
private static String oldBaseURI;
private static String oldBasePath;
private static Object oldRestAssuredConfig; // we can't declare the type here as that would prevent this class for being loaded if RestAssured is not present

private static final boolean REST_ASSURED_PRESENT;

static {
Field p;
Field baseURI;
Field basePath;
Field configF;
Method setParam;
Method configM;
Method httpClient;
Class<?> httpClientConfig;
boolean present = false;
try {
Class<?> restAssured = Class.forName("io.restassured.RestAssured");
p = restAssured.getField("port");
p.setAccessible(true);
baseURI = restAssured.getField("baseURI");
baseURI.setAccessible(true);
basePath = restAssured.getField("basePath");
basePath.setAccessible(true);

configF = restAssured.getField("config");
configF.setAccessible(true);

configM = restAssured.getMethod("config");
configM.setAccessible(true);

httpClientConfig = Class.forName("io.restassured.config.HttpClientConfig");
setParam = httpClientConfig.getMethod("setParam", String.class, Object.class);
setParam.setAccessible(true);

Class<?> restAssuredConfigClass = Class.forName("io.restassured.config.RestAssuredConfig");
httpClient = restAssuredConfigClass.getMethod("httpClient", httpClientConfig);
httpClient.setAccessible(true);

} catch (Exception e) {
p = null;
baseURI = null;
basePath = null;
configF = null;
setParam = null;
httpClientConfig = null;
configM = null;
httpClient = null;
Class.forName("io.restassured.RestAssured");
present = true;
} catch (ClassNotFoundException ignored) {
}
portField = p;
baseURIField = baseURI;
basePathField = basePath;
configField = configF;
setParamMethod = setParam;
httpClientConfigClass = httpClientConfig;
configMethod = configM;
httpClientMethod = httpClient;
REST_ASSURED_PRESENT = present;
}

private RestAssuredURLManager() {
Expand Down Expand Up @@ -111,136 +65,76 @@ public static void setURL(boolean useSecureConnection, Integer port) {
}

public static void setURL(boolean useSecureConnection, Integer port, String additionalPath) {
if (portField != null) {
try {
oldPort = (Integer) portField.get(null);
if (port == null) {
port = useSecureConnection ? getPortFromConfig(DEFAULT_HTTPS_PORT, "quarkus.http.test-ssl-port")
: getPortFromConfig(DEFAULT_HTTP_PORT, "quarkus.lambda.mock-event-server.test-port",
"quarkus.http.test-port");
}
portField.set(null, port);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if (!REST_ASSURED_PRESENT) {
return;
}
if (baseURIField != null) {
try {
oldBaseURI = (String) baseURIField.get(null);
final String protocol = useSecureConnection ? "https://" : "http://";
String host = ConfigProvider.getConfig().getOptionalValue("quarkus.http.host", String.class)
.orElse("localhost");
if (host.equals("0.0.0.0")) {
host = "localhost";
}
String baseURI = protocol + host;
baseURIField.set(null, baseURI);
} catch (IllegalAccessException e) {
e.printStackTrace();
}

oldPort = RestAssured.port;
if (port == null) {
port = useSecureConnection ? getPortFromConfig(DEFAULT_HTTPS_PORT, "quarkus.http.test-ssl-port")
: getPortFromConfig(DEFAULT_HTTP_PORT, "quarkus.lambda.mock-event-server.test-port",
"quarkus.http.test-port");
}
if (basePathField != null) {
try {
oldBasePath = (String) basePathField.get(null);
Optional<String> basePath = ConfigProvider.getConfig().getOptionalValue("quarkus.http.root-path",
String.class);
if (basePath.isPresent() || additionalPath != null) {
StringBuilder bp = new StringBuilder();
if (basePath.isPresent()) {
if (basePath.get().startsWith("/")) {
bp.append(basePath.get().substring(1));
} else {
bp.append(basePath.get());
}
if (bp.toString().endsWith("/")) {
bp.setLength(bp.length() - 1);
}
}
if (additionalPath != null) {
if (!additionalPath.startsWith("/")) {
bp.append("/");
}
bp.append(additionalPath);
if (bp.toString().endsWith("/")) {
bp.setLength(bp.length() - 1);
}
}
basePathField.set(null, bp.toString());
RestAssured.port = port;

oldBaseURI = RestAssured.baseURI;
final String protocol = useSecureConnection ? "https://" : "http://";
String host = ConfigProvider.getConfig().getOptionalValue("quarkus.http.host", String.class)
.orElse("localhost");
if (host.equals("0.0.0.0")) {
host = "localhost";
}
RestAssured.baseURI = protocol + host;

oldBasePath = RestAssured.basePath;
Optional<String> basePath = ConfigProvider.getConfig().getOptionalValue("quarkus.http.root-path",
String.class);
if (basePath.isPresent() || additionalPath != null) {
StringBuilder bp = new StringBuilder();
if (basePath.isPresent()) {
if (basePath.get().startsWith("/")) {
bp.append(basePath.get().substring(1));
} else {
bp.append(basePath.get());
}
if (bp.toString().endsWith("/")) {
bp.setLength(bp.length() - 1);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
if (configField != null) {
try {
Duration timeout = ConfigProvider.getConfig()
.getOptionalValue("quarkus.http.test-timeout", Duration.class).orElse(Duration.ofSeconds(30));
configureTimeouts(timeout);
} catch (Exception e) {
e.printStackTrace();
if (additionalPath != null) {
if (!additionalPath.startsWith("/")) {
bp.append("/");
}
bp.append(additionalPath);
if (bp.toString().endsWith("/")) {
bp.setLength(bp.length() - 1);
}
}
RestAssured.basePath = bp.toString();
}

Duration timeout = ConfigProvider.getConfig()
.getOptionalValue("quarkus.http.test-timeout", Duration.class).orElse(Duration.ofSeconds(30));
configureTimeouts(timeout);
}

/**
* Execute the following code:
*
* <pre>
* {@code
* RestAssured.config = RestAssured.config().httpClient(
* new HttpClientConfig()
* .setParam("http.conn-manager.timeout", 30_000L)
* .setParam("http.connection.timeout", 30_000)
* .setParam("http.socket.timeout", 30_000)
* }
* </pre>
*
*/
private static void configureTimeouts(Duration d) throws Exception {
// Create the HTTP client config:
// new HttpClientConfig()
// .setParam("http.conn-manager.timeout", 30_000L)
// .setParam("http.connection.timeout", 30_000)
// .setParam("http.socket.timeout", 30_000)

Object httpClientConfig = httpClientConfigClass.getDeclaredConstructor().newInstance();
httpClientConfig = setParamMethod.invoke(httpClientConfig, "http.conn-manager.timeout", d.toMillis());
httpClientConfig = setParamMethod.invoke(httpClientConfig, "http.connection.timeout", (int) d.toMillis());
httpClientConfig = setParamMethod.invoke(httpClientConfig, "http.socket.timeout", (int) d.toMillis());

// Retrieve RestAssured config
// restAssuredConfig = RestAssured.config();
Object restAssuredConfig = configMethod.invoke(null);

// Call httpClient method:
// restAssuredConfig = restAssuredConfig.httpClient(httpClientConfig);
restAssuredConfig = httpClientMethod.invoke(restAssuredConfig, httpClientConfig);

// Set the field
configField.set(null, restAssuredConfig);
private static void configureTimeouts(Duration d) {
oldRestAssuredConfig = RestAssured.config();

RestAssured.config = RestAssured.config().httpClient(new HttpClientConfig()
.setParam("http.conn-manager.timeout", d.toMillis()) // this needs to be long
.setParam("http.connection.timeout", (int) d.toMillis()) // this needs to be int
.setParam("http.socket.timeout", (int) d.toMillis())); // same here
}

public static void clearURL() {
if (portField != null) {
try {
portField.set(null, oldPort);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
if (baseURIField != null) {
try {
baseURIField.set(null, oldBaseURI);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
if (basePathField != null) {
try {
basePathField.set(null, oldBasePath);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if (!REST_ASSURED_PRESENT) {
return;
}

RestAssured.port = oldPort;
RestAssured.baseURI = oldBaseURI;
RestAssured.basePath = oldBasePath;
RestAssured.config = (RestAssuredConfig) oldRestAssuredConfig;
}
}

0 comments on commit 6fbcb0e

Please sign in to comment.