diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractH2AsyncFundamentalsTest.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractH2AsyncFundamentalsTest.java
index 727621bde5..764c82bb47 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractH2AsyncFundamentalsTest.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractH2AsyncFundamentalsTest.java
@@ -69,7 +69,13 @@
abstract class AbstractH2AsyncFundamentalsTest extends AbstractHttpAsyncFundamentalsTest {
public AbstractH2AsyncFundamentalsTest(final URIScheme scheme, final ClientProtocolLevel clientProtocolLevel, final ServerProtocolLevel serverProtocolLevel) {
- super(scheme, clientProtocolLevel, serverProtocolLevel);
+ this(scheme, clientProtocolLevel, serverProtocolLevel, false);
+ }
+
+ public AbstractH2AsyncFundamentalsTest(final URIScheme scheme, final ClientProtocolLevel clientProtocolLevel,
+ final ServerProtocolLevel serverProtocolLevel,
+ final boolean useUnixDomainSocket) {
+ super(scheme, clientProtocolLevel, serverProtocolLevel, useUnixDomainSocket);
}
@Test
@@ -203,4 +209,4 @@ public void cancelled() {
}
}
-}
\ No newline at end of file
+}
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncFundamentalsTest.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncFundamentalsTest.java
index aa18ed4162..fdc2fbc654 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncFundamentalsTest.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncFundamentalsTest.java
@@ -64,6 +64,12 @@ protected AbstractHttpAsyncFundamentalsTest(final URIScheme scheme, final Client
super(scheme, clientProtocolLevel, serverProtocolLevel);
}
+ protected AbstractHttpAsyncFundamentalsTest(final URIScheme scheme, final ClientProtocolLevel clientProtocolLevel,
+ final ServerProtocolLevel serverProtocolLevel,
+ final boolean useUnixDomainSocket) {
+ super(scheme, clientProtocolLevel, serverProtocolLevel, useUnixDomainSocket);
+ }
+
@Test
void testSequentialGetRequests() throws Exception {
configureServer(bootstrap -> bootstrap.register("/random/*", AsyncRandomHandler::new));
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1Async.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1Async.java
index 2318f5de6d..b6fdf02a46 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1Async.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1Async.java
@@ -55,7 +55,11 @@
abstract class TestHttp1Async extends AbstractHttpAsyncFundamentalsTest {
public TestHttp1Async(final URIScheme scheme) {
- super(scheme, ClientProtocolLevel.STANDARD, ServerProtocolLevel.STANDARD);
+ this(scheme, false);
+ }
+
+ public TestHttp1Async(final URIScheme scheme, final boolean useUnixDomainSocket) {
+ super(scheme, ClientProtocolLevel.STANDARD, ServerProtocolLevel.STANDARD, useUnixDomainSocket);
}
@ParameterizedTest(name = "{displayName}; concurrent connections: {0}")
@@ -201,4 +205,4 @@ void testRequestCancellation() throws Exception {
}
}
-}
\ No newline at end of file
+}
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1RequestReExecution.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1RequestReExecution.java
index 7524a23418..4b00ee0202 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1RequestReExecution.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1RequestReExecution.java
@@ -50,7 +50,11 @@
abstract class TestHttp1RequestReExecution extends AbstractIntegrationTestBase {
public TestHttp1RequestReExecution(final URIScheme scheme) {
- super(scheme, ClientProtocolLevel.STANDARD, ServerProtocolLevel.STANDARD);
+ this(scheme, false);
+ }
+
+ public TestHttp1RequestReExecution(final URIScheme scheme, final boolean useUnixDomainSocket) {
+ super(scheme, ClientProtocolLevel.STANDARD, ServerProtocolLevel.STANDARD, useUnixDomainSocket);
}
@BeforeEach
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/UdsAsyncIntegrationTests.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/UdsAsyncIntegrationTests.java
new file mode 100644
index 0000000000..bb2f0be083
--- /dev/null
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/UdsAsyncIntegrationTests.java
@@ -0,0 +1,68 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+package org.apache.hc.client5.testing.async;
+
+import org.apache.hc.core5.http.URIScheme;
+import org.apache.hc.core5.util.VersionInfo;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+
+import static org.apache.hc.core5.util.ReflectionUtils.determineJRELevel;
+import static org.junit.jupiter.api.Assumptions.assumeFalse;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
+
+class UdsAsyncIntegrationTests {
+
+ @Nested
+ @DisplayName("Fundamentals (HTTP/1.1)")
+ class Http1 extends TestHttp1Async {
+ public Http1() {
+ super(URIScheme.HTTP, true);
+ checkForUdsSupport();
+ }
+ }
+
+ @Nested
+ @DisplayName("Request re-execution (HTTP/1.1)")
+ class Http1RequestReExecution extends TestHttp1RequestReExecution {
+ public Http1RequestReExecution() {
+ super(URIScheme.HTTP, true);
+ checkForUdsSupport();
+ }
+ }
+
+ static void checkForUdsSupport() {
+ assumeTrue(determineJRELevel() >= 16, "Async UDS requires Java 16+");
+ final String[] components = VersionInfo
+ .loadVersionInfo("org.apache.hc.core5", UdsAsyncIntegrationTests.class.getClassLoader())
+ .getRelease()
+ .split("[-.]");
+ final int majorVersion = Integer.parseInt(components[0]);
+ final int minorVersion = Integer.parseInt(components[1]);
+ assumeFalse(majorVersion <= 5 && minorVersion <= 3, "Async UDS requires HttpCore 5.4+");
+ }
+}
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/extension/async/TestAsyncResources.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/extension/async/TestAsyncResources.java
index 6cb512c347..d490e9eb76 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/extension/async/TestAsyncResources.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/extension/async/TestAsyncResources.java
@@ -87,6 +87,11 @@ public void afterEach(final ExtensionContext extensionContext) {
client.close(CloseMode.GRACEFUL);
}
if (udsProxy != null) {
+ // The test harness enables UDS through a default RequestConfig set on the client. If a test case
+ // overrides the RequestConfig on a given request, it may connect directly to the test server by mistake.
+ if (udsProxy.getRequestsReceived() == 0) {
+ throw new AssertionError("The UDS proxy did not receive any requests");
+ }
udsProxy.close();
}
if (server != null) {
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/extension/sync/TestClientResources.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/extension/sync/TestClientResources.java
index b18a11f4e1..8a78740d82 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/extension/sync/TestClientResources.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/extension/sync/TestClientResources.java
@@ -76,6 +76,11 @@ public void afterEach(final ExtensionContext extensionContext) {
client.close(CloseMode.GRACEFUL);
}
if (udsProxy != null) {
+ // The test harness enables UDS through a default RequestConfig set on the client. If a test case
+ // overrides the RequestConfig on a given request, it may connect directly to the test server by mistake.
+ if (udsProxy.getRequestsReceived() == 0) {
+ throw new AssertionError("The UDS proxy did not receive any requests");
+ }
udsProxy.close();
}
if (server != null) {
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/extension/sync/UnixDomainProxyServer.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/extension/sync/UnixDomainProxyServer.java
index 048ad41063..30fb9324c0 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/extension/sync/UnixDomainProxyServer.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/extension/sync/UnixDomainProxyServer.java
@@ -42,6 +42,7 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
import static java.util.concurrent.CompletableFuture.supplyAsync;
@@ -50,6 +51,7 @@ public final class UnixDomainProxyServer {
private final ExecutorService executorService;
private final Path socketPath;
private final CountDownLatch serverReady = new CountDownLatch(1);
+ private final AtomicInteger requestsReceived = new AtomicInteger(0);
private volatile AFUNIXServerSocket serverSocket;
public UnixDomainProxyServer(final int port) {
@@ -71,6 +73,10 @@ public Path getSocketPath() {
return socketPath;
}
+ public int getRequestsReceived() {
+ return requestsReceived.get();
+ }
+
public void close() {
try {
serverSocket.close();
@@ -106,6 +112,7 @@ private void runUdsProxy() {
private void serveRequests(final AFUNIXServerSocket server) throws IOException {
while (true) {
final AFUNIXSocket udsClient = server.accept();
+ requestsReceived.incrementAndGet();
final Socket tcpSocket = new Socket("localhost", port);
final CompletableFuture f1 = supplyAsync(() -> pipe(udsClient, tcpSocket), executorService);
final CompletableFuture f2 = supplyAsync(() -> pipe(tcpSocket, udsClient), executorService);
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientRequestExecution.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientRequestExecution.java
index 8e88fd79b5..17173a4253 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientRequestExecution.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientRequestExecution.java
@@ -74,7 +74,11 @@
abstract class TestClientRequestExecution extends AbstractIntegrationTestBase {
public TestClientRequestExecution(final URIScheme scheme) {
- super(scheme, ClientProtocolLevel.STANDARD);
+ this(scheme, false);
+ }
+
+ public TestClientRequestExecution(final URIScheme scheme, final boolean useUnixDomainSocket) {
+ super(scheme, ClientProtocolLevel.STANDARD, useUnixDomainSocket);
}
private static class SimpleService implements HttpRequestHandler {
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestContentCodings.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestContentCodings.java
index 44f46d10b0..6cc1791d32 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestContentCodings.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestContentCodings.java
@@ -66,7 +66,11 @@
abstract class TestContentCodings extends AbstractIntegrationTestBase {
protected TestContentCodings(final URIScheme scheme) {
- super(scheme, ClientProtocolLevel.STANDARD);
+ this(scheme, false);
+ }
+
+ protected TestContentCodings(final URIScheme scheme, final boolean useUnixDomainSocket) {
+ super(scheme, ClientProtocolLevel.STANDARD, useUnixDomainSocket);
}
/**
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/UdsIntegrationTests.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/UdsIntegrationTests.java
new file mode 100644
index 0000000000..75c7259bde
--- /dev/null
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/UdsIntegrationTests.java
@@ -0,0 +1,60 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+package org.apache.hc.client5.testing.sync;
+
+import org.apache.hc.core5.http.URIScheme;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
+
+class UdsIntegrationTests {
+ @Nested
+ @DisplayName("Request execution (HTTP/1.1)")
+ class RequestExecution extends TestClientRequestExecution {
+ public RequestExecution() {
+ super(URIScheme.HTTP, true);
+ }
+ }
+
+ @Nested
+ @DisplayName("Request execution (HTTP/1.1, TLS)")
+ class RequestExecutionTls extends TestClientRequestExecution {
+ public RequestExecutionTls() {
+ super(URIScheme.HTTPS, true);
+ assumeTrue(false, "HTTPS is not currently supported over Unix domain sockets");
+ }
+ }
+
+ @Nested
+ @DisplayName("Content coding (HTTP/1.1)")
+ class ContentCoding extends TestContentCodings {
+ public ContentCoding() {
+ super(URIScheme.HTTP, true);
+ }
+ }
+}