View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.hc.core5.benchmark;
28  
29  import java.io.IOException;
30  import java.net.InetSocketAddress;
31  import java.util.concurrent.Future;
32  import java.util.stream.Stream;
33  
34  import org.apache.hc.core5.http.EntityDetails;
35  import org.apache.hc.core5.http.HttpException;
36  import org.apache.hc.core5.http.HttpRequest;
37  import org.apache.hc.core5.http.HttpStatus;
38  import org.apache.hc.core5.http.HttpVersion;
39  import org.apache.hc.core5.http.Message;
40  import org.apache.hc.core5.http.Method;
41  import org.apache.hc.core5.http.URIScheme;
42  import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
43  import org.apache.hc.core5.http.nio.AsyncRequestConsumer;
44  import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
45  import org.apache.hc.core5.http.nio.entity.DiscardingEntityConsumer;
46  import org.apache.hc.core5.http.nio.support.AsyncResponseBuilder;
47  import org.apache.hc.core5.http.nio.support.BasicRequestConsumer;
48  import org.apache.hc.core5.http.protocol.HttpContext;
49  import org.apache.hc.core5.http2.HttpVersionPolicy;
50  import org.apache.hc.core5.http2.impl.nio.bootstrap.H2ServerBootstrap;
51  import org.apache.hc.core5.io.CloseMode;
52  import org.apache.hc.core5.net.URIBuilder;
53  import org.apache.hc.core5.reactor.ListenerEndpoint;
54  import org.junit.jupiter.api.AfterEach;
55  import org.junit.jupiter.api.Assertions;
56  import org.junit.jupiter.params.ParameterizedTest;
57  import org.junit.jupiter.params.provider.Arguments;
58  import org.junit.jupiter.params.provider.MethodSource;
59  
60  public class BenchmarkToolTest {
61  
62      public static Stream<Arguments> protocols() {
63          return Stream.of(
64                  Arguments.of(HttpVersionPolicy.NEGOTIATE),
65                  Arguments.of(HttpVersionPolicy.FORCE_HTTP_2)
66          );
67      }
68  
69      private HttpAsyncServer server;
70      private InetSocketAddress address;
71  
72      public void setup(final HttpVersionPolicy versionPolicy) throws Exception {
73          server = H2ServerBootstrap.bootstrap()
74                  .register("/", new AsyncServerRequestHandler<Message<HttpRequest, Void>>() {
75  
76                      @Override
77                      public AsyncRequestConsumer<Message<HttpRequest, Void>> prepare(
78                              final HttpRequest request,
79                              final EntityDetails entityDetails,
80                              final HttpContext context) throws HttpException {
81                          return new BasicRequestConsumer<>(entityDetails != null ? new DiscardingEntityConsumer<>() : null);
82                      }
83  
84                      @Override
85                      public void handle(
86                              final Message<HttpRequest, Void> requestObject,
87                              final ResponseTrigger responseTrigger,
88                              final HttpContext context) throws HttpException, IOException {
89                          responseTrigger.submitResponse(
90                                  AsyncResponseBuilder.create(HttpStatus.SC_OK)
91                                          .setEntity("0123456789ABCDEF")
92                                          .build(),
93                                  context);
94                      }
95  
96                  })
97                  .setVersionPolicy(versionPolicy)
98                  .create();
99          server.start();
100         final Future<ListenerEndpoint> future = server.listen(new InetSocketAddress(0), URIScheme.HTTP);
101         final ListenerEndpoint listener = future.get();
102         address = (InetSocketAddress) listener.getAddress();
103     }
104 
105     @AfterEach
106     public void shutdown() throws Exception {
107         if (server != null) {
108             server.close(CloseMode.IMMEDIATE);
109         }
110     }
111 
112 
113     @ParameterizedTest(name = "{0}")
114     @MethodSource("protocols")
115     public void testBasics(final HttpVersionPolicy versionPolicy) throws Exception {
116         setup(versionPolicy);
117         final BenchmarkConfig config = BenchmarkConfig.custom()
118                 .setKeepAlive(true)
119                 .setMethod(Method.POST.name())
120                 .setPayloadText("0123456789ABCDEF")
121                 .setUri(new URIBuilder()
122                         .setScheme(URIScheme.HTTP.id)
123                         .setHost("localhost")
124                         .setPort(address .getPort())
125                         .build())
126                 .setConcurrencyLevel(3)
127                 .setForceHttp2(versionPolicy == HttpVersionPolicy.FORCE_HTTP_2)
128                 .setRequests(100)
129                 .build();
130         final HttpBenchmark httpBenchmark = new HttpBenchmark(config);
131         final Results results = httpBenchmark.execute();
132         Assertions.assertNotNull(results);
133         Assertions.assertEquals(100, results.getSuccessCount());
134         Assertions.assertEquals(0, results.getFailureCount());
135         Assertions.assertEquals(16, results.getContentLength());
136         Assertions.assertEquals(3, results.getConcurrencyLevel());
137         Assertions.assertEquals(100 * 16, results.getTotalContentBytesRecvd());
138         if (versionPolicy == HttpVersionPolicy.FORCE_HTTP_2) {
139             Assertions.assertEquals(HttpVersion.HTTP_2, results.getProtocolVersion());
140         }
141     }
142 
143 }