You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2025/09/25 09:20:26 UTC

(httpcomponents-core) branch master updated: HTTPCORE-785: Improved ALPN tests with the default (Oracle) and Conscrypt security providers

This is an automated email from the ASF dual-hosted git repository.

olegk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git


The following commit(s) were added to refs/heads/master by this push:
     new f9201670f HTTPCORE-785: Improved ALPN tests with the default (Oracle) and Conscrypt security providers
f9201670f is described below

commit f9201670ffc4f3e4f1b338a291dfa0f0c5bc89d7
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Wed Sep 24 16:52:48 2025 +0200

    HTTPCORE-785: Improved ALPN tests with the default (Oracle) and Conscrypt security providers
---
 .../extension/SecurityProviderResource.java        |  88 +++++++
 ...2ProtocolNegotiationTest.java => AlpnTest.java} |  27 +-
 ...roviderIntegrationTests.java => AlpnTests.java} |  33 ++-
 .../testing/nio/JSSEProviderIntegrationTest.java   | 293 ---------------------
 4 files changed, 130 insertions(+), 311 deletions(-)

diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/SecurityProviderResource.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/SecurityProviderResource.java
new file mode 100644
index 000000000..34e7e84b9
--- /dev/null
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/SecurityProviderResource.java
@@ -0,0 +1,88 @@
+/*
+ * ====================================================================
+ * 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
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.core5.testing.extension;
+
+import java.security.Provider;
+import java.security.Security;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.conscrypt.Conscrypt;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
+public class SecurityProviderResource implements BeforeEachCallback, AfterEachCallback {
+
+    private final String securityProviderName;
+
+    private Provider securityProvider;
+
+    public SecurityProviderResource(final String securityProviderName) {
+        super();
+        this.securityProviderName = securityProviderName;
+    }
+
+    @Override
+    public void beforeEach(final ExtensionContext context) throws Exception {
+        if ("Conscrypt".equalsIgnoreCase(securityProviderName)) {
+            final Set<String> supportedArchitectures = new HashSet<>(Arrays.asList("x86", "x86_64",
+                    "x86-64", "amd64", "aarch64", "armeabi-v7a", "arm64-v8a"));
+            Assumptions.assumeTrue(supportedArchitectures.contains(System.getProperty("os.arch")));
+            try {
+                securityProvider = Conscrypt.newProviderBuilder().provideTrustManager(true).build();
+            } catch (final UnsatisfiedLinkError e) {
+                Assertions.fail("Conscrypt provider failed to be loaded: " + e.getMessage());
+            }
+        } else if ("Oracle".equalsIgnoreCase(securityProviderName)) {
+            securityProvider = null;
+        } else if ("SUN".equalsIgnoreCase(securityProviderName)) {
+            securityProvider = null;
+        } else {
+            throw new AssertionError("Unsupported security provider: " + securityProviderName);
+        }
+        if (securityProvider != null) {
+            Security.insertProviderAt(securityProvider, 1);
+        }
+    }
+
+    @Override
+    public void afterEach(final ExtensionContext context) throws Exception {
+        if (securityProvider != null) {
+            Security.removeProvider(securityProvider.getName());
+            securityProvider = null;
+        }
+    }
+
+    public Provider securityProvider() {
+        return securityProvider;
+    }
+
+}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ProtocolNegotiationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/AlpnTest.java
similarity index 87%
rename from httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ProtocolNegotiationTest.java
rename to httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/AlpnTest.java
index 09d6ce3e1..045c4ee21 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ProtocolNegotiationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/AlpnTest.java
@@ -31,6 +31,9 @@
 
 import java.net.InetSocketAddress;
 import java.util.concurrent.Future;
+import java.util.function.Function;
+
+import javax.net.ssl.SSLContext;
 
 import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.ContentType;
@@ -48,35 +51,47 @@
 import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
+import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
 import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
 import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
 import org.apache.hc.core5.http2.HttpVersionPolicy;
-import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
 import org.apache.hc.core5.http2.ssl.H2ServerTlsStrategy;
 import org.apache.hc.core5.reactor.IOReactorConfig;
 import org.apache.hc.core5.reactor.ListenerEndpoint;
 import org.apache.hc.core5.testing.SSLTestContexts;
+import org.apache.hc.core5.testing.extension.SecurityProviderResource;
 import org.apache.hc.core5.testing.extension.nio.H2AsyncRequesterResource;
 import org.apache.hc.core5.testing.extension.nio.H2AsyncServerResource;
 import org.apache.hc.core5.util.Timeout;
 import org.hamcrest.CoreMatchers;
+import org.junit.jupiter.api.Order;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-class H2ProtocolNegotiationTest {
+abstract class AlpnTest {
 
     private static final Timeout TIMEOUT = Timeout.ofMinutes(1);
 
     @RegisterExtension
+    @Order(1)
+    private final SecurityProviderResource securityProviderResource;
+    @RegisterExtension
+    @Order(2)
     private final H2AsyncServerResource serverResource;
     @RegisterExtension
+    @Order(3)
     private final H2AsyncRequesterResource clientResource;
 
-    public H2ProtocolNegotiationTest() {
+    public AlpnTest(final String securityProviderName,
+                    final Function<SSLContext, TlsStrategy> serverTlsStrategyFactory,
+                    final Function<SSLContext, TlsStrategy> clientTlsStrategyFactory) {
+        this.securityProviderResource = new SecurityProviderResource(securityProviderName);
         this.serverResource = new H2AsyncServerResource();
         this.serverResource.configure(bootstrap -> bootstrap
                 .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
-                .setTlsStrategy(new H2ServerTlsStrategy(SSLTestContexts.createServerSSLContext()))
+                .setTlsStrategy(serverTlsStrategyFactory != null ?
+                        serverTlsStrategyFactory.apply(SSLTestContexts.createServerSSLContext()) :
+                        new H2ServerTlsStrategy(SSLTestContexts.createServerSSLContext()))
                 .setIOReactorConfig(
                         IOReactorConfig.custom()
                                 .setSoTimeout(TIMEOUT)
@@ -89,7 +104,9 @@ public H2ProtocolNegotiationTest() {
         this.clientResource = new H2AsyncRequesterResource();
         this.clientResource.configure(bootstrap -> bootstrap
                 .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
-                .setTlsStrategy(new H2ClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
+                .setTlsStrategy(clientTlsStrategyFactory != null ?
+                        clientTlsStrategyFactory.apply(SSLTestContexts.createServerSSLContext()) :
+                        new H2ServerTlsStrategy(SSLTestContexts.createServerSSLContext()))
                 .setIOReactorConfig(IOReactorConfig.custom()
                         .setSoTimeout(TIMEOUT)
                         .build())
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/JSSEProviderIntegrationTests.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/AlpnTests.java
similarity index 56%
rename from httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/JSSEProviderIntegrationTests.java
rename to httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/AlpnTests.java
index f168cfc9c..4bcae56d9 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/JSSEProviderIntegrationTests.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/AlpnTests.java
@@ -27,41 +27,48 @@
 
 package org.apache.hc.core5.testing.nio;
 
+import org.apache.hc.core5.http2.ssl.ConscryptClientTlsStrategy;
+import org.apache.hc.core5.http2.ssl.ConscryptServerTlsStrategy;
+import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
+import org.apache.hc.core5.http2.ssl.H2ServerTlsStrategy;
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.condition.DisabledOnOs;
+import org.junit.jupiter.api.condition.EnabledForJreRange;
+import org.junit.jupiter.api.condition.JRE;
 import org.junit.jupiter.api.condition.OS;
 
-class JSSEProviderIntegrationTests {
+class AlpnTests {
 
     @Nested
-    @DisplayName("Oracle (default)")
-    class Oracle extends JSSEProviderIntegrationTest {
+    @DisplayName("ALPN Oracle")
+    class OracleJSSEAlpnTest extends AlpnTest {
 
-        public Oracle() {
-            super("Oracle", null);
+        public OracleJSSEAlpnTest() throws Exception {
+            super("Oracle", H2ServerTlsStrategy::new, H2ClientTlsStrategy::new);
         }
 
     }
 
     @Nested
-    @DisplayName("Conscrypt (TLSv1.2)")
+    @DisplayName("ALPN Conscrypt (Java 9 or newer)")
     @DisabledOnOs(OS.MAC)
-    class ConscryptTlsV1_2 extends JSSEProviderIntegrationTest {
+    @EnabledForJreRange(min = JRE.JAVA_9)
+    class ConscryptJSSEAlpnTest extends AlpnTest {
 
-        public ConscryptTlsV1_2() {
-            super("Conscrypt", "TLSv1.2");
+        public ConscryptJSSEAlpnTest() throws Exception {
+            super("Conscrypt", H2ServerTlsStrategy::new, H2ClientTlsStrategy::new);
         }
 
     }
 
     @Nested
-    @DisplayName("Conscrypt (TLSv1.3)")
+    @DisplayName("ALPN Conscrypt (Conscrypt specific TLS strategies)")
     @DisabledOnOs(OS.MAC)
-    class ConscryptTlsV1_3 extends JSSEProviderIntegrationTest {
+    class ConscryptJSSEAndStrategiesAlpnTest extends AlpnTest {
 
-        public ConscryptTlsV1_3() {
-            super("Conscrypt", "TLSv1.3");
+        public ConscryptJSSEAndStrategiesAlpnTest() throws Exception {
+            super("Conscrypt", ConscryptServerTlsStrategy::new, ConscryptClientTlsStrategy::new);
         }
 
     }
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/JSSEProviderIntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/JSSEProviderIntegrationTest.java
deleted file mode 100644
index 36a3d9f5c..000000000
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/JSSEProviderIntegrationTest.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * ====================================================================
- * 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
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.hc.core5.testing.nio;
-
-import java.net.InetSocketAddress;
-import java.net.URL;
-import java.security.Provider;
-import java.security.SecureRandom;
-import java.security.Security;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.Future;
-
-import org.apache.hc.core5.http.HttpHeaders;
-import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.http.HttpResponse;
-import org.apache.hc.core5.http.Message;
-import org.apache.hc.core5.http.message.BasicHttpRequest;
-import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
-import org.apache.hc.core5.http.nio.support.AsyncRequestBuilder;
-import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
-import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
-import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
-import org.apache.hc.core5.http.protocol.RequestValidateHost;
-import org.apache.hc.core5.http.support.BasicRequestBuilder;
-import org.apache.hc.core5.reactor.IOReactorConfig;
-import org.apache.hc.core5.ssl.SSLContextBuilder;
-import org.apache.hc.core5.util.TimeValue;
-import org.apache.hc.core5.util.Timeout;
-import org.conscrypt.Conscrypt;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Assumptions;
-import org.junit.jupiter.api.Order;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.AfterEachCallback;
-import org.junit.jupiter.api.extension.BeforeEachCallback;
-import org.junit.jupiter.api.extension.ExtensionContext;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-abstract class JSSEProviderIntegrationTest {
-
-    private final String securityProviderName;
-    private final String protocolVersion;
-
-    public JSSEProviderIntegrationTest(final String securityProviderName, final String protocolVersion) {
-        super();
-        this.securityProviderName = securityProviderName;
-        this.protocolVersion = protocolVersion;
-    }
-
-    private static final Timeout TIMEOUT = Timeout.ofMinutes(1);
-    private static final int REQ_NUM = 25;
-
-    private Provider securityProvider;
-
-    class SecurityProviderResource implements BeforeEachCallback, AfterEachCallback {
-
-        @Override
-        public void beforeEach(final ExtensionContext context) throws Exception {
-            if ("Conscrypt".equalsIgnoreCase(securityProviderName)) {
-                final Set<String> supportedArchitectures = new HashSet<>(Arrays.asList("x86", "x86_64",
-                        "x86-64", "amd64", "aarch64", "armeabi-v7a", "arm64-v8a"));
-                Assumptions.assumeTrue(supportedArchitectures.contains(System.getProperty("os.arch")));
-                try {
-                    securityProvider = Conscrypt.newProviderBuilder().provideTrustManager(true).build();
-                } catch (final UnsatisfiedLinkError e) {
-                    Assertions.fail("Conscrypt provider failed to be loaded: " + e.getMessage());
-                }
-            } else {
-                securityProvider = null;
-            }
-            if (securityProvider != null) {
-                Security.insertProviderAt(securityProvider, 1);
-            }
-        }
-
-        @Override
-        public void afterEach(final ExtensionContext context) throws Exception {
-            if (securityProvider != null) {
-                Security.removeProvider(securityProvider.getName());
-                securityProvider = null;
-            }
-        }
-
-    }
-
-    @RegisterExtension
-    @Order(1)
-    private final SecurityProviderResource securityProviderResource = new SecurityProviderResource();
-
-    private Http1TestServer server;
-
-    class ServerResource implements BeforeEachCallback, AfterEachCallback {
-
-        @Override
-        public void beforeEach(final ExtensionContext context) throws Exception {
-            final URL keyStoreURL = getClass().getResource("/test-server.p12");
-            final String storePassword = "nopassword";
-
-            server = new Http1TestServer(
-                    IOReactorConfig.custom()
-                            .setSoTimeout(TIMEOUT)
-                            .build(),
-                    SSLContextBuilder.create()
-                            .setProvider(securityProvider)
-                            .setKeyStoreType("pkcs12")
-                            .loadTrustMaterial(keyStoreURL, storePassword.toCharArray())
-                            .loadKeyMaterial(keyStoreURL, storePassword.toCharArray(), storePassword.toCharArray())
-                            .setSecureRandom(new SecureRandom())
-                            .build(),
-                    (endpoint, sslEngine) -> {
-                        if (protocolVersion != null) {
-                            sslEngine.setEnabledProtocols(new String[]{protocolVersion});
-                        }
-                    },
-                    null);
-        }
-
-        @Override
-        public void afterEach(final ExtensionContext context) throws Exception {
-            if (server != null) {
-                server.shutdown(TimeValue.ofSeconds(5));
-            }
-        }
-
-    }
-
-    @RegisterExtension
-    @Order(2)
-    private final ServerResource serverResource = new ServerResource();
-
-    private Http1TestClient client;
-
-    class ClientResource implements BeforeEachCallback, AfterEachCallback {
-
-        @Override
-        public void beforeEach(final ExtensionContext context) throws Exception {
-            final URL keyStoreURL = getClass().getResource("/test-client.p12");
-            final String storePassword = "nopassword";
-
-            client = new Http1TestClient(
-                    IOReactorConfig.custom()
-                            .setSoTimeout(TIMEOUT)
-                            .build(),
-                    SSLContextBuilder.create()
-                            .setProvider(securityProvider)
-                            .setKeyStoreType("pkcs12")
-                            .loadTrustMaterial(keyStoreURL, storePassword.toCharArray())
-                            .setSecureRandom(new SecureRandom())
-                            .build(),
-                    (endpoint, sslEngine) -> {
-                        if (protocolVersion != null) {
-                            sslEngine.setEnabledProtocols(new String[]{protocolVersion});
-                        }
-                    },
-                    null);
-        }
-
-        @Override
-        public void afterEach(final ExtensionContext context) throws Exception {
-            if (client != null) {
-                client.shutdown(TimeValue.ofSeconds(5));
-            }
-        }
-
-    }
-
-    @RegisterExtension
-    @Order(3)
-    private final ClientResource clientResource = new ClientResource();
-
-    private HttpHost target(final InetSocketAddress serverEndpoint) {
-        return new HttpHost("https", null, "localhost", serverEndpoint.getPort());
-    }
-
-    @Test
-    void testSimpleGet() throws Exception {
-        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
-        final InetSocketAddress serverEndpoint = server.start();
-
-        final HttpHost target = target(serverEndpoint);
-
-        client.start();
-        final Future<ClientSessionEndpoint> connectFuture = client.connect(target, TIMEOUT);
-        final ClientSessionEndpoint streamEndpoint = connectFuture.get();
-
-        for (int i = 0; i < REQ_NUM; i++) {
-            final BasicHttpRequest request = BasicRequestBuilder.get()
-                    .setHttpHost(target)
-                    .setPath("/hello")
-                    .build();
-            final Future<Message<HttpResponse, String>> future = streamEndpoint.execute(
-                    new BasicRequestProducer(request, null),
-                    new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
-            final Message<HttpResponse, String> result = future.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
-            Assertions.assertNotNull(result);
-            final HttpResponse response1 = result.getHead();
-            final String entity1 = result.getBody();
-            Assertions.assertNotNull(response1);
-            Assertions.assertEquals(200, response1.getCode());
-            Assertions.assertEquals("Hi there", entity1);
-        }
-    }
-
-    @Test
-    void testSimpleGetConnectionClose() throws Exception {
-        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
-        final InetSocketAddress serverEndpoint = server.start();
-
-        final HttpHost target = target(serverEndpoint);
-
-        client.start();
-        for (int i = 0; i < REQ_NUM; i++) {
-            final Future<ClientSessionEndpoint> connectFuture = client.connect(
-                    "localhost", serverEndpoint.getPort(), TIMEOUT);
-            try (final ClientSessionEndpoint streamEndpoint = connectFuture.get()) {
-                final Future<Message<HttpResponse, String>> future = streamEndpoint.execute(
-                        AsyncRequestBuilder.get()
-                                .setHttpHost(target)
-                                .setPath("/hello")
-                                .addHeader(HttpHeaders.CONNECTION, "close")
-                                .build(),
-                        new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
-                final Message<HttpResponse, String> result = future.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
-                Assertions.assertNotNull(result);
-                final HttpResponse response1 = result.getHead();
-                final String entity1 = result.getBody();
-                Assertions.assertNotNull(response1);
-                Assertions.assertEquals(200, response1.getCode());
-                Assertions.assertEquals("Hi there", entity1);
-            }
-        }
-    }
-
-    @Test
-    void testSimpleGetIdentityTransfer() throws Exception {
-        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
-        server.configure(new DefaultHttpProcessor(new RequestValidateHost()));
-        final InetSocketAddress serverEndpoint = server.start();
-
-        final HttpHost target = target(serverEndpoint);
-
-        client.start();
-
-        for (int i = 0; i < REQ_NUM; i++) {
-            final Future<ClientSessionEndpoint> connectFuture = client.connect(
-                    "localhost", serverEndpoint.getPort(), TIMEOUT);
-            try (final ClientSessionEndpoint streamEndpoint = connectFuture.get()) {
-                final BasicHttpRequest request = BasicRequestBuilder.get()
-                        .setHttpHost(target)
-                        .setPath("/hello")
-                        .build();
-                final Future<Message<HttpResponse, String>> future = streamEndpoint.execute(
-                        new BasicRequestProducer(request, null),
-                        new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
-                final Message<HttpResponse, String> result = future.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
-                Assertions.assertNotNull(result);
-                final HttpResponse response = result.getHead();
-                final String entity = result.getBody();
-                Assertions.assertNotNull(response);
-                Assertions.assertEquals(200, response.getCode());
-                Assertions.assertEquals("Hi there", entity);
-            }
-        }
-    }
-
-}