Add a set of positive tests
Validate that requests go through as expected if the server-side delay is small.
diff --git a/src/test/java/org/apache/sling/uca/impl/AgentIT.java b/src/test/java/org/apache/sling/uca/impl/AgentIT.java
index 17638d7..d67a67d 100644
--- a/src/test/java/org/apache/sling/uca/impl/AgentIT.java
+++ b/src/test/java/org/apache/sling/uca/impl/AgentIT.java
@@ -44,6 +44,7 @@
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.MethodSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -127,7 +128,7 @@
ErrorDescriptor ed = requireNonNull(errorDescriptors.get(clientType), "Unhandled clientType " + clientType);
RecordedThrowable error = assertTimeout(ofSeconds(EXECUTION_TIMEOUT_SECONDS),
- () -> runTest("http://repo1.maven.org:81", clientType, timeouts));
+ () -> runTest("http://repo1.maven.org:81", clientType, timeouts, false));
assertEquals(ed.connectTimeoutClass.getName(), error.className);
assertTrue(error.message.matches(ed.connectTimeoutMessageRegex),
@@ -138,20 +139,32 @@
* Validates that connecting to a host that delays the response fails with a read timeout
*
* @throws IOException various I/O problems
+ * @throws InterruptedException
*/
@ParameterizedTest
@MethodSource("argumentsMatrix")
- public void readTimeout(ClientType clientType, TestTimeouts timeouts, MisbehavingServerControl server) throws IOException {
+ public void readTimeout(ClientType clientType, TestTimeouts timeouts, MisbehavingServerControl server) throws IOException, InterruptedException {
ErrorDescriptor ed = requireNonNull(errorDescriptors.get(clientType), "Unhandled clientType " + clientType);
RecordedThrowable error = assertTimeout(ofSeconds(EXECUTION_TIMEOUT_SECONDS),
- () -> runTest("http://localhost:" + server.getLocalPort(), clientType, timeouts));
-
+ () -> runTest("http://localhost:" + server.getLocalPort(), clientType, timeouts, false));
+
assertEquals(SocketTimeoutException.class.getName(), error.className);
assertEquals(ed.readTimeoutMessage, error.message);
}
+
+ @ParameterizedTest
+ @EnumSource(HttpClientLauncher.ClientType.class)
+ public void connectAndReadSuccess(ClientType clientType, MisbehavingServerControl server) throws IOException, InterruptedException {
+
+ // set a small accept delay for the server so the requests have time to complete
+ server.setHandleDelay(Duration.ofMillis(100));
+
+ assertTimeout(ofSeconds(EXECUTION_TIMEOUT_SECONDS),
+ () ->runTest("http://localhost:" + server.getLocalPort(), clientType, TestTimeouts.DEFAULT, true));
+ }
- private RecordedThrowable runTest(String urlSpec, ClientType clientType, TestTimeouts timeouts) throws IOException, InterruptedException {
+ private RecordedThrowable runTest(String urlSpec, ClientType clientType, TestTimeouts timeouts, boolean expectSuccess) throws IOException, InterruptedException {
Process process = new AgentLauncher(new URL(urlSpec), timeouts, clientType, STDOUT, STDERR).launch();
boolean done = process.waitFor(timeouts.executionTimeout.toMillis(), TimeUnit.MILLISECONDS);
@@ -173,6 +186,13 @@
int exitCode = process.exitValue();
LOG.info("Exited with code {}", exitCode);
+ if ( expectSuccess ) {
+ if ( exitCode != 0 )
+ throw new RuntimeException("Expected success, but command exited with code " + exitCode);
+
+ return null;
+ }
+
if ( exitCode == 0 ) {
throw new RuntimeException("Command terminated successfully. That is unexpected.");
} else {
diff --git a/src/test/java/org/apache/sling/uca/impl/MisbehavingServerControl.java b/src/test/java/org/apache/sling/uca/impl/MisbehavingServerControl.java
index 9b0bf93..0161006 100644
--- a/src/test/java/org/apache/sling/uca/impl/MisbehavingServerControl.java
+++ b/src/test/java/org/apache/sling/uca/impl/MisbehavingServerControl.java
@@ -16,6 +16,8 @@
*/
package org.apache.sling.uca.impl;
+import java.time.Duration;
+
/**
* Allows control of a local server
*
@@ -28,4 +30,16 @@
* @return the port
*/
int getLocalPort();
+
+ /**
+ * Sets a new value for the handleDelay parameter
+ *
+ * <p>This value reflects how long the HTTP handler will wait before handling the client request.</p>
+ *
+ * <p>The value only takes effect for the current test method invocation and will be reset
+ * for the next one.</p>
+ *
+ * @param handleDelay the new duration
+ */
+ void setHandleDelay(Duration handleDelay);
}
diff --git a/src/test/java/org/apache/sling/uca/impl/MisbehavingServerExtension.java b/src/test/java/org/apache/sling/uca/impl/MisbehavingServerExtension.java
index b659451..f5bfe1f 100644
--- a/src/test/java/org/apache/sling/uca/impl/MisbehavingServerExtension.java
+++ b/src/test/java/org/apache/sling/uca/impl/MisbehavingServerExtension.java
@@ -17,13 +17,12 @@
package org.apache.sling.uca.impl;
import java.io.IOException;
-import java.util.concurrent.TimeUnit;
+import java.time.Duration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
@@ -46,6 +45,8 @@
*/
class MisbehavingServerExtension implements BeforeEachCallback, AfterEachCallback, ParameterResolver, MisbehavingServerControl {
+ private static final Duration DEFAULT_HANDLE_DELAY = Duration.ofSeconds(10);
+
private final Logger logger = LoggerFactory.getLogger(getClass());
public int getLocalPort() {
@@ -54,6 +55,8 @@
private Server server;
+ private Duration handleDelay = DEFAULT_HANDLE_DELAY;
+
@Override
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
throws ParameterResolutionException {
@@ -72,31 +75,28 @@
@Override
public void beforeEach(ExtensionContext context) throws Exception {
- server = new Server();
- ServerConnector connector = new ServerConnector(server) {
- @Override
- public void accept(int acceptorID) throws IOException {
- LOG.info("Waiting before accepting");
- try {
- Thread.sleep(TimeUnit.SECONDS.toMillis(10));
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- return;
- }
- super.accept(acceptorID);
- LOG.info("Accepted");
- }
- };
- server.setConnectors(new Connector[] { connector });
+ // reset the delay before each execution to make test logic simpler
+ handleDelay = DEFAULT_HANDLE_DELAY;
+
+ server = new Server(0);
server.setHandler(new AbstractHandler() {
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
+ logger.info("Waiting for " + handleDelay + " before handling");
+ try {
+ Thread.sleep(handleDelay.toMillis());
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return;
+ }
+
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
if ( baseRequest.getHeader("User-Agent") != null )
response.addHeader("Original-User-Agent", baseRequest.getHeader("User-Agent"));
baseRequest.setHandled(true);
+ logger.info("Handled");
}
});
@@ -113,4 +113,9 @@
logger.info("Failed shutting down server", e);
}
}
+
+ @Override
+ public void setHandleDelay(Duration handleDelay) {
+ this.handleDelay = handleDelay;
+ }
}
\ No newline at end of file