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 2018/09/17 13:29:03 UTC

[2/3] httpcomponents-core git commit: Added support for HTTP/2 transport to the internal HTTP benchmark

Added support for HTTP/2 transport to the internal HTTP benchmark


Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/commit/4a9d69c6
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/tree/4a9d69c6
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/diff/4a9d69c6

Branch: refs/heads/master
Commit: 4a9d69c6fbf3645c23f25aae75bfcc0c4aa94f5e
Parents: 3c54538
Author: Oleg Kalnichevski <ol...@apache.org>
Authored: Mon Sep 17 13:55:25 2018 +0200
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Mon Sep 17 15:25:24 2018 +0200

----------------------------------------------------------------------
 .../hc/core5/benchmark/BenchmarkConfig.java     | 16 ++++
 .../hc/core5/benchmark/BenchmarkWorker.java     |  3 +-
 .../hc/core5/benchmark/CommandLineUtils.java    |  8 ++
 .../hc/core5/benchmark/HttpBenchmark.java       | 33 +++++---
 .../hc/core5/benchmark/ResultFormatter.java     | 33 ++++----
 .../org/apache/hc/core5/benchmark/Results.java  |  9 +++
 .../org/apache/hc/core5/benchmark/Stats.java    | 19 ++++-
 .../hc/core5/benchmark/BenchmarkToolTest.java   | 83 ++++++++++++++++----
 .../hc/core5/benchmark/ResultFormatterTest.java |  5 +-
 9 files changed, 161 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/4a9d69c6/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/BenchmarkConfig.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/BenchmarkConfig.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/BenchmarkConfig.java
index 25f303d..68a037b 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/BenchmarkConfig.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/BenchmarkConfig.java
@@ -55,6 +55,7 @@ public class BenchmarkConfig {
     private final boolean useAcceptGZip;
     private final String payloadText;
     private final String soapAction;
+    private final boolean forceHttp2;
     private final boolean disableSSLVerification;
     private final String trustStorePath;
     private final String identityStorePath;
@@ -78,6 +79,7 @@ public class BenchmarkConfig {
                             final boolean useAcceptGZip,
                             final String payloadText,
                             final String soapAction,
+                            final boolean forceHttp2,
                             final boolean disableSSLVerification,
                             final String trustStorePath,
                             final String identityStorePath,
@@ -100,6 +102,7 @@ public class BenchmarkConfig {
         this.useAcceptGZip = useAcceptGZip;
         this.payloadText = payloadText;
         this.soapAction = soapAction;
+        this.forceHttp2 = forceHttp2;
         this.disableSSLVerification = disableSSLVerification;
         this.trustStorePath = trustStorePath;
         this.identityStorePath = identityStorePath;
@@ -171,6 +174,10 @@ public class BenchmarkConfig {
         return soapAction;
     }
 
+    public boolean isForceHttp2() {
+        return forceHttp2;
+    }
+
     public boolean isDisableSSLVerification() {
         return disableSSLVerification;
     }
@@ -215,6 +222,7 @@ public class BenchmarkConfig {
                 ", useAcceptGZip=" + useAcceptGZip +
                 ", payloadText='" + payloadText + '\'' +
                 ", soapAction='" + soapAction + '\'' +
+                ", forceHttp2=" + forceHttp2+
                 ", disableSSLVerification=" + disableSSLVerification +
                 ", trustStorePath='" + trustStorePath + '\'' +
                 ", identityStorePath='" + identityStorePath + '\'' +
@@ -247,6 +255,7 @@ public class BenchmarkConfig {
                 .setUseAcceptGZip(config.isUseAcceptGZip())
                 .setPayloadText(config.getPayloadText())
                 .setSoapAction(config.getSoapAction())
+                .setForceHttp2(config.isForceHttp2())
                 .setDisableSSLVerification(config.isDisableSSLVerification())
                 .setTrustStorePath(config.getTrustStorePath())
                 .setIdentityStorePath(config.getIdentityStorePath())
@@ -275,6 +284,7 @@ public class BenchmarkConfig {
         private boolean useAcceptGZip;
         private String payloadText;
         private String soapAction;
+        private boolean forceHttp2;
         private boolean disableSSLVerification;
         private String trustStorePath;
         private String identityStorePath;
@@ -376,6 +386,11 @@ public class BenchmarkConfig {
             return this;
         }
 
+        public Builder setForceHttp2(final boolean forceHttp2) {
+            this.forceHttp2 = forceHttp2;
+            return this;
+        }
+
         public Builder setDisableSSLVerification(final boolean disableSSLVerification) {
             this.disableSSLVerification = disableSSLVerification;
             return this;
@@ -420,6 +435,7 @@ public class BenchmarkConfig {
                     useAcceptGZip,
                     payloadText,
                     soapAction,
+                    forceHttp2,
                     disableSSLVerification,
                     trustStorePath,
                     identityStorePath,

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/4a9d69c6/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/BenchmarkWorker.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/BenchmarkWorker.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/BenchmarkWorker.java
index 53ccde7..7e68691 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/BenchmarkWorker.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/BenchmarkWorker.java
@@ -107,7 +107,7 @@ class BenchmarkWorker implements ResourceHolder {
                 }
             }
         }
-        if (!config.isKeepAlive()) {
+        if (!config.isKeepAlive() && !config.isForceHttp2()) {
             request.addHeader(new BasicHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE));
         }
         if (config.isUseAcceptGZip()) {
@@ -193,6 +193,7 @@ class BenchmarkWorker implements ResourceHolder {
                     final FutureCallback<Void> resultCallback) throws HttpException, IOException {
                 status = response.getCode();
                 resultCallbackRef.set(resultCallback);
+                stats.setVersion(response.getVersion());
                 final Header serverHeader = response.getFirstHeader(HttpHeaders.SERVER);
                 if (serverHeader != null) {
                     stats.setServerName(serverHeader.getValue());

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/4a9d69c6/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/CommandLineUtils.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/CommandLineUtils.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/CommandLineUtils.java
index 6037219..731cf38 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/CommandLineUtils.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/CommandLineUtils.java
@@ -106,6 +106,9 @@ public class CommandLineUtils {
         final Option gopt = new Option("g", false, "Accept GZip. Default is false");
         gopt.setRequired(false);
 
+        final Option http2opt = new Option("2", false, "Force HTTP/2");
+        gopt.setRequired(false);
+
         final Option hopt = new Option("h", false, "Display usage information");
         nopt.setRequired(false);
 
@@ -127,6 +130,7 @@ public class CommandLineUtils {
         options.addOption(uopt);
         options.addOption(xopt);
         options.addOption(gopt);
+        options.addOption(http2opt);
 
         options.addOption(hopt);
         return options;
@@ -222,6 +226,10 @@ public class CommandLineUtils {
             builder.setUseAcceptGZip(true);
         }
 
+        if (cmd.hasOption('2')) {
+            builder.setForceHttp2(true);
+        }
+
         final String[] cmdargs = cmd.getArgs();
         if (cmdargs.length > 0) {
             try {

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/4a9d69c6/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/HttpBenchmark.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/HttpBenchmark.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/HttpBenchmark.java
index 2599205..68e8705 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/HttpBenchmark.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/HttpBenchmark.java
@@ -53,16 +53,17 @@ import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.HttpVersion;
 import org.apache.hc.core5.http.impl.Http1StreamListener;
-import org.apache.hc.core5.http.impl.bootstrap.AsyncRequesterBootstrap;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
 import org.apache.hc.core5.http.nio.ssl.BasicClientTlsStrategy;
 import org.apache.hc.core5.http.protocol.HttpCoreContext;
 import org.apache.hc.core5.http.protocol.HttpProcessorBuilder;
-import org.apache.hc.core5.http.protocol.RequestConnControl;
-import org.apache.hc.core5.http.protocol.RequestContent;
 import org.apache.hc.core5.http.protocol.RequestExpectContinue;
-import org.apache.hc.core5.http.protocol.RequestTargetHost;
 import org.apache.hc.core5.http.protocol.RequestUserAgent;
+import org.apache.hc.core5.http2.HttpVersionPolicy;
+import org.apache.hc.core5.http2.impl.nio.bootstrap.H2RequesterBootstrap;
+import org.apache.hc.core5.http2.protocol.H2RequestConnControl;
+import org.apache.hc.core5.http2.protocol.H2RequestContent;
+import org.apache.hc.core5.http2.protocol.H2RequestTargetHost;
 import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.reactor.Command;
 import org.apache.hc.core5.reactor.IOReactorConfig;
@@ -100,6 +101,7 @@ public class HttpBenchmark {
 
         final HttpBenchmark httpBenchmark = new HttpBenchmark(config);
         final Results results = httpBenchmark.execute();
+        System.out.println();
         ResultFormatter.print(System.out, results);
     }
 
@@ -111,10 +113,10 @@ public class HttpBenchmark {
     public Results execute() throws Exception {
         final HttpProcessorBuilder builder = HttpProcessorBuilder.create()
                 .addAll(
-                        new RequestContent(),
-                        new RequestTargetHost(),
-                        new RequestConnControl(),
-                        new RequestUserAgent("HttpCore-AB/1.1"));
+                        new H2RequestContent(),
+                        new H2RequestTargetHost(),
+                        new H2RequestConnControl(),
+                        new RequestUserAgent("HttpCore-AB/5.0"));
         if (this.config.isUseExpectContinue()) {
             builder.add(new RequestExpectContinue());
         }
@@ -149,10 +151,22 @@ public class HttpBenchmark {
             sslContext = SSLContexts.createSystemDefault();
         }
 
+        final HttpVersionPolicy versionPolicy;
+        if (config.isForceHttp2()) {
+            versionPolicy = HttpVersionPolicy.FORCE_HTTP_2;
+        } else {
+            if (sslContext != null) {
+                versionPolicy = HttpVersionPolicy.NEGOTIATE;
+            } else {
+                versionPolicy = HttpVersionPolicy.FORCE_HTTP_1;
+            }
+        }
+
         final Stats stats = new Stats();
-        try (final HttpAsyncRequester requester = AsyncRequesterBootstrap.bootstrap()
+        try (final HttpAsyncRequester requester = H2RequesterBootstrap.bootstrap()
                 .setHttpProcessor(builder.build())
                 .setTlsStrategy(new BasicClientTlsStrategy(sslContext))
+                .setVersionPolicy(versionPolicy)
                 .setIOSessionDecorator(new Decorator<IOSession>() {
 
                     @Override
@@ -372,6 +386,7 @@ public class HttpBenchmark {
 
         return new Results(
                 stats.getServerName(),
+                stats.getVersion(),
                 host.getHostName(),
                 host.getPort() > 0 ? host.getPort() : host.getSchemeName().equalsIgnoreCase("https") ? 443 : 80,
                 requestUri.toASCIIString(),

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/4a9d69c6/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/ResultFormatter.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/ResultFormatter.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/ResultFormatter.java
index ec2305c..34d41ff 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/ResultFormatter.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/ResultFormatter.java
@@ -49,25 +49,26 @@ public class ResultFormatter {
     }
 
     public static void print(final PrintStream printStream, final Results results) {
-        printStream.println("\nServer Software:\t\t" + results.getServerName());
-        printStream.println( "Server Hostname:\t\t" + results.getHostName());
-        printStream.println( "Server Port:\t\t\t" + results.getHostPort());
-        printStream.println( "Document Path:\t\t\t" + results.getDocumentPath());
-        printStream.println( "Document Length:\t\t" + results.getContentLength() + " bytes\n");
-        printStream.println( "Concurrency Level:\t\t" + results.getConcurrencyLevel());
-        printStream.println( "Time taken for tests:\t" + nf6.format((double) results.getTotalTimeMillis() / 1000) + " seconds");
-        printStream.println( "Complete requests:\t\t" + results.getSuccessCount());
-        printStream.println( "Failed requests:\t\t" + results.getFailureCount());
-        printStream.println( "Kept alive:\t\t\t\t" + results.getKeepAliveCount());
-        printStream.println( "Total transferred:\t\t" + results.getTotalBytesRcvd() + " bytes");
-        printStream.println( "Content transferred:\t" + results.getTotalContentBytesRecvd() + " bytes");
-        printStream.println( "Requests per second:\t" + nf2.format(
+        printStream.println("Server Software:\t\t" + results.getServerName());
+        printStream.println("Protocol version:\t\t" + results.getProtocolVersion());
+        printStream.println("Server Hostname:\t\t" + results.getHostName());
+        printStream.println("Server Port:\t\t\t" + results.getHostPort());
+        printStream.println("Document Path:\t\t\t" + results.getDocumentPath());
+        printStream.println("Document Length:\t\t" + results.getContentLength() + " bytes\n");
+        printStream.println("Concurrency Level:\t\t" + results.getConcurrencyLevel());
+        printStream.println("Time taken for tests:\t" + nf6.format((double) results.getTotalTimeMillis() / 1000) + " seconds");
+        printStream.println("Complete requests:\t\t" + results.getSuccessCount());
+        printStream.println("Failed requests:\t\t" + results.getFailureCount());
+        printStream.println("Kept alive:\t\t\t\t" + results.getKeepAliveCount());
+        printStream.println("Total transferred:\t\t" + results.getTotalBytesRcvd() + " bytes");
+        printStream.println("Content transferred:\t" + results.getTotalContentBytesRecvd() + " bytes");
+        printStream.println("Requests per second:\t" + nf2.format(
                 results.getSuccessCount() / ((double) results.getTotalTimeMillis() / 1000)) + " [#/sec] (mean)");
-        printStream.println( "Time per request:\t\t" + nf3.format(
+        printStream.println("Time per request:\t\t" + nf3.format(
                 (double) results.getTotalTimeMillis() * results.getConcurrencyLevel() / results.getSuccessCount()) + " [ms] (mean)");
-        printStream.println( "Time per request:\t\t" + nf3.format(
+        printStream.println("Time per request:\t\t" + nf3.format(
                 (double) results.getTotalTimeMillis() / results.getSuccessCount()) + " [ms] (mean, across all concurrent requests)");
-        printStream.println( "Transfer rate:\t\t\t" +
+        printStream.println("Transfer rate:\t\t\t" +
             nf2.format((double) results.getTotalBytesRcvd() / 1024 / ((double) results.getTotalTimeMillis() / 1000)) + " [Kbytes/sec] received");
     }
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/4a9d69c6/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/Results.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/Results.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/Results.java
index addcf5f..61e0530 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/Results.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/Results.java
@@ -26,6 +26,8 @@
  */
 package org.apache.hc.core5.benchmark;
 
+import org.apache.hc.core5.http.ProtocolVersion;
+
 /**
  * Benchmark results
  *
@@ -34,6 +36,7 @@ package org.apache.hc.core5.benchmark;
 public final class Results {
 
     private final String serverName;
+    private final ProtocolVersion protocolVersion;
     private final String hostName;
     private final int hostPort;
     private final String documentPath;
@@ -49,6 +52,7 @@ public final class Results {
 
     public Results(
             final String serverName,
+            final ProtocolVersion protocolVersion,
             final String hostName,
             final int hostPort,
             final String documentPath,
@@ -62,6 +66,7 @@ public final class Results {
             final long totalBytesSent,
             final long totalContentBytesRecvd) {
         this.serverName = serverName;
+        this.protocolVersion = protocolVersion;
         this.hostName = hostName;
         this.hostPort = hostPort;
         this.documentPath = documentPath;
@@ -80,6 +85,10 @@ public final class Results {
         return serverName;
     }
 
+    public ProtocolVersion getProtocolVersion() {
+        return protocolVersion;
+    }
+
     public String getHostName() {
         return hostName;
     }

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/4a9d69c6/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/Stats.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/Stats.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/Stats.java
index 86d7f1c..60acb57 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/Stats.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/Stats.java
@@ -30,6 +30,8 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
 
+import org.apache.hc.core5.http.ProtocolVersion;
+
 /**
  * Statistics for an {@link HttpBenchmark HttpBenchmark}.
  *
@@ -40,11 +42,12 @@ public class Stats {
     private final AtomicInteger successCount = new AtomicInteger();
     private final AtomicInteger failureCount = new AtomicInteger();
     private final AtomicInteger keepAliveCount = new AtomicInteger();
-    private final AtomicReference<String> serverName = new AtomicReference<>();
     private final AtomicLong totalBytesRecv = new AtomicLong();
     private final AtomicLong totalBytesSent = new AtomicLong();
     private final AtomicLong contentLength = new AtomicLong();
     private final AtomicLong totalContentLength = new AtomicLong();
+    private final AtomicReference<String> serverNameRef = new AtomicReference<>();
+    private final AtomicReference<ProtocolVersion> versionRef = new AtomicReference<>();
 
     public void incSuccessCount() {
         this.successCount.incrementAndGet();
@@ -103,11 +106,19 @@ public class Stats {
     }
 
     public void setServerName(final String serverName) {
-        this.serverName.set(serverName);
+        this.serverNameRef.set(serverName);
     }
 
     public String getServerName() {
-        return this.serverName.get();
+        return this.serverNameRef.get();
+    }
+
+    public ProtocolVersion getVersion() {
+        return versionRef.get();
+    }
+
+    public void setVersion(final ProtocolVersion version) {
+        this.versionRef.set(version);
     }
 
     @Override
@@ -116,7 +127,7 @@ public class Stats {
                 "successCount=" + successCount +
                 ", failureCount=" + failureCount +
                 ", keepAliveCount=" + keepAliveCount +
-                ", serverName=" + serverName +
+                ", serverName=" + serverNameRef.get() +
                 ", totalBytesRecv=" + totalBytesRecv +
                 ", totalBytesSent=" + totalBytesSent +
                 ", contentLength=" + contentLength +

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/4a9d69c6/httpcore5-testing/src/test/java/org/apache/hc/core5/benchmark/BenchmarkToolTest.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/benchmark/BenchmarkToolTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/benchmark/BenchmarkToolTest.java
index 235fc79..7743cd1 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/benchmark/BenchmarkToolTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/benchmark/BenchmarkToolTest.java
@@ -27,43 +27,86 @@
 package org.apache.hc.core5.benchmark;
 
 import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.concurrent.Future;
 
-import org.apache.hc.core5.http.ClassicHttpRequest;
-import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.EntityDetails;
 import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
-import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
-import org.apache.hc.core5.http.io.HttpRequestHandler;
-import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.http.HttpVersion;
+import org.apache.hc.core5.http.Message;
+import org.apache.hc.core5.http.URIScheme;
+import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
+import org.apache.hc.core5.http.nio.AsyncRequestConsumer;
+import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
+import org.apache.hc.core5.http.nio.BasicRequestConsumer;
+import org.apache.hc.core5.http.nio.BasicResponseProducer;
+import org.apache.hc.core5.http.nio.entity.NoopEntityConsumer;
 import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.http2.HttpVersionPolicy;
+import org.apache.hc.core5.http2.impl.nio.bootstrap.H2ServerBootstrap;
 import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.net.URIBuilder;
+import org.apache.hc.core5.reactor.ListenerEndpoint;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
 
+@RunWith(Parameterized.class)
 public class BenchmarkToolTest {
 
-    private HttpServer server;
+    @Parameterized.Parameters(name = "{0}")
+    public static Collection<Object[]> protocols() {
+        return Arrays.asList(new Object[][]{
+                { HttpVersionPolicy.NEGOTIATE },
+                { HttpVersionPolicy.FORCE_HTTP_2 }
+        });
+    }
+
+    private final HttpVersionPolicy versionPolicy;
+    private HttpAsyncServer server;
+    private InetSocketAddress address;
+
+    public BenchmarkToolTest(final HttpVersionPolicy versionPolicy) {
+        this.versionPolicy = versionPolicy;
+    }
 
     @Before
     public void setup() throws Exception {
-        server = ServerBootstrap.bootstrap()
-                .register("/", new HttpRequestHandler() {
+        server = H2ServerBootstrap.bootstrap()
+                .register("/", new AsyncServerRequestHandler<Message<HttpRequest, Void>>() {
+
+                    @Override
+                    public AsyncRequestConsumer<Message<HttpRequest, Void>> prepare(
+                            final HttpRequest request,
+                            final EntityDetails entityDetails,
+                            final HttpContext context) throws HttpException {
+                        return new BasicRequestConsumer<>(entityDetails != null ? new NoopEntityConsumer() : null);
+                    }
+
                     @Override
                     public void handle(
-                            final ClassicHttpRequest request,
-                            final ClassicHttpResponse response,
+                            final Message<HttpRequest, Void> requestObject,
+                            final ResponseTrigger responseTrigger,
                             final HttpContext context) throws HttpException, IOException {
-                        response.setCode(HttpStatus.SC_OK);
-                        response.setEntity(new StringEntity("0123456789ABCDEF", ContentType.TEXT_PLAIN));
+                        responseTrigger.submitResponse(
+                                new BasicResponseProducer(HttpStatus.SC_OK, "0123456789ABCDEF", ContentType.TEXT_PLAIN), context);
                     }
+
                 })
+                .setVersionPolicy(versionPolicy)
                 .create();
         server.start();
+        final Future<ListenerEndpoint> future = server.listen(new InetSocketAddress(0));
+        final ListenerEndpoint listener = future.get();
+        address = (InetSocketAddress) listener.getAddress();
     }
 
     @After
@@ -77,22 +120,28 @@ public class BenchmarkToolTest {
     public void testBasics() throws Exception {
         final BenchmarkConfig config = BenchmarkConfig.custom()
                 .setKeepAlive(true)
-                .setMethod("GET")
+                .setMethod("POST")
+                .setPayloadText("0123456789ABCDEF")
                 .setUri(new URIBuilder()
+                        .setScheme(URIScheme.HTTP.id)
                         .setHost("localhost")
-                        .setPort(server.getLocalPort())
+                        .setPort(address .getPort())
                         .build())
                 .setConcurrencyLevel(3)
+                .setForceHttp2(versionPolicy == HttpVersionPolicy.FORCE_HTTP_2)
                 .setRequests(100)
                 .build();
         final HttpBenchmark httpBenchmark = new HttpBenchmark(config);
         final Results results = httpBenchmark.execute();
         Assert.assertNotNull(results);
-        Assert.assertEquals(16, results.getContentLength());
-        Assert.assertEquals(3, results.getConcurrencyLevel());
         Assert.assertEquals(100, results.getSuccessCount());
         Assert.assertEquals(0, results.getFailureCount());
+        Assert.assertEquals(16, results.getContentLength());
+        Assert.assertEquals(3, results.getConcurrencyLevel());
         Assert.assertEquals(100 * 16, results.getTotalContentBytesRecvd());
+        if (versionPolicy == HttpVersionPolicy.FORCE_HTTP_2) {
+            Assert.assertEquals(HttpVersion.HTTP_2, results.getProtocolVersion());
+        }
     }
 
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/4a9d69c6/httpcore5-testing/src/test/java/org/apache/hc/core5/benchmark/ResultFormatterTest.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/benchmark/ResultFormatterTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/benchmark/ResultFormatterTest.java
index b83bc39..023f81b 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/benchmark/ResultFormatterTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/benchmark/ResultFormatterTest.java
@@ -30,6 +30,7 @@ import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
 import java.nio.charset.StandardCharsets;
 
+import org.apache.hc.core5.http.HttpVersion;
 import org.hamcrest.CoreMatchers;
 import org.junit.Assert;
 import org.junit.Test;
@@ -40,6 +41,7 @@ public class ResultFormatterTest {
     public void testBasics() throws Exception {
         final Results results = new Results(
                 "TestServer/1.1",
+                HttpVersion.HTTP_1_1,
                 "localhost",
                 8080,
                 "/index.html",
@@ -56,7 +58,8 @@ public class ResultFormatterTest {
         ResultFormatter.print(new PrintStream(buf, true, StandardCharsets.US_ASCII.name()), results);
         Assert.assertThat(new String(buf.toByteArray(), StandardCharsets.US_ASCII).replace("\r\n", "\n"),
                 CoreMatchers.equalTo(
-                "\nServer Software:\t\tTestServer/1.1\n" +
+                "Server Software:\t\tTestServer/1.1\n" +
+                        "Protocol version:\t\tHTTP/1.1\n" +
                         "Server Hostname:\t\tlocalhost\n" +
                         "Server Port:\t\t\t8080\n" +
                         "Document Path:\t\t\t/index.html\n" +