Skip to content

Commit feb4e06

Browse files
authored
Add CRT HTTP/2 stability tests and JMH benchmarks (#6723)
* Add stability tests and JMH tests # Conflicts: # services/kinesis/src/it/java/software/amazon/awssdk/services/kinesis/AbstractTestCase.java * Fix tests * Fix checkstyle errors * Address feedback
1 parent ff7a475 commit feb4e06

File tree

13 files changed

+603
-317
lines changed

13 files changed

+603
-317
lines changed

http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/AwsCrtAsyncHttpClientSpiVerificationTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ public void requestFailed_connectionTimeout_shouldWrapException() {
127127
SdkHttpRequest request = createRequest(uri);
128128
RecordingResponseHandler recorder = new RecordingResponseHandler();
129129
client.execute(AsyncExecuteRequest.builder().request(request).requestContentPublisher(createProvider("")).responseHandler(recorder).build());
130-
assertThatThrownBy(() -> recorder.completeFuture().get(5, TimeUnit.SECONDS)).hasCauseInstanceOf(ConnectException.class);
130+
assertThatThrownBy(() -> recorder.completeFuture().get(5, TimeUnit.SECONDS)).hasCauseInstanceOf(IOException.class)
131+
.hasMessageContaining("socket");
131132
}
132133
}
133134

http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/AwsCrtHttpClientSpiVerificationTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,8 @@ public void requestFailed_connectionTimeout_shouldWrapException() {
9494
HttpExecuteRequest.Builder executeRequestBuilder = HttpExecuteRequest.builder();
9595
executeRequestBuilder.request(request);
9696
ExecutableHttpRequest executableRequest = client.prepareRequest(executeRequestBuilder.build());
97-
9897
assertThatThrownBy(() -> executableRequest.call()).isInstanceOf(IOException.class)
99-
.hasMessageContaining("operation timed out");
98+
.hasMessageContaining("socket");
10099
}
101100
}
102101

services/kinesis/src/it/java/software/amazon/awssdk/services/kinesis/AbstractTestCase.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import software.amazon.awssdk.awscore.util.AwsHostNameUtils;
2727
import software.amazon.awssdk.http.nio.netty.internal.utils.NettyUtils;
2828
import software.amazon.awssdk.regions.Region;
29-
import software.amazon.awssdk.retries.DefaultRetryStrategy;
3029
import software.amazon.awssdk.testutils.service.AwsTestBase;
3130

3231
public class AbstractTestCase extends AwsTestBase {

test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/BenchmarkRunner.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@
3939
import org.openjdk.jmh.runner.options.OptionsBuilder;
4040
import software.amazon.awssdk.benchmark.apicall.MetricsEnabledBenchmark;
4141
import software.amazon.awssdk.benchmark.apicall.httpclient.async.AwsCrtClientBenchmark;
42+
import software.amazon.awssdk.benchmark.apicall.httpclient.async.AwsCrtH2ClientBenchmark;
4243
import software.amazon.awssdk.benchmark.apicall.httpclient.async.NettyHttpClientH1Benchmark;
43-
import software.amazon.awssdk.benchmark.apicall.httpclient.async.NettyHttpClientH2Benchmark;
44+
import software.amazon.awssdk.benchmark.apicall.httpclient.async.NettyHttpClientH2PriorKnowledgeBenchmark;
4445
import software.amazon.awssdk.benchmark.apicall.httpclient.sync.ApacheHttpClientBenchmark;
4546
import software.amazon.awssdk.benchmark.apicall.httpclient.sync.CrtHttpClientBenchmark;
4647
import software.amazon.awssdk.benchmark.apicall.httpclient.sync.UrlConnectionHttpClientBenchmark;
@@ -73,9 +74,10 @@ public class BenchmarkRunner {
7374
QueryProtocolBenchmark.class.getSimpleName(), XmlProtocolBenchmark.class.getSimpleName());
7475

7576
private static final List<String> ASYNC_BENCHMARKS = Arrays.asList(
76-
NettyHttpClientH2Benchmark.class.getSimpleName(),
77+
NettyHttpClientH2PriorKnowledgeBenchmark.class.getSimpleName(),
7778
NettyHttpClientH1Benchmark.class.getSimpleName(),
78-
AwsCrtClientBenchmark.class.getSimpleName());
79+
AwsCrtClientBenchmark.class.getSimpleName(),
80+
AwsCrtH2ClientBenchmark.class.getSimpleName());
7981

8082
private static final List<String> SYNC_BENCHMARKS = Arrays.asList(
8183
ApacheHttpClientBenchmark.class.getSimpleName(),
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.awssdk.benchmark.apicall.httpclient.async;
17+
18+
import static software.amazon.awssdk.benchmark.utils.BenchmarkConstant.CONCURRENT_CALLS;
19+
import static software.amazon.awssdk.benchmark.utils.BenchmarkUtils.awaitCountdownLatchUninterruptibly;
20+
import static software.amazon.awssdk.benchmark.utils.BenchmarkUtils.countDownUponCompletion;
21+
22+
import java.util.concurrent.CountDownLatch;
23+
import java.util.concurrent.TimeUnit;
24+
import org.openjdk.jmh.annotations.Benchmark;
25+
import org.openjdk.jmh.annotations.BenchmarkMode;
26+
import org.openjdk.jmh.annotations.Fork;
27+
import org.openjdk.jmh.annotations.Level;
28+
import org.openjdk.jmh.annotations.Measurement;
29+
import org.openjdk.jmh.annotations.Mode;
30+
import org.openjdk.jmh.annotations.OperationsPerInvocation;
31+
import org.openjdk.jmh.annotations.Scope;
32+
import org.openjdk.jmh.annotations.Setup;
33+
import org.openjdk.jmh.annotations.State;
34+
import org.openjdk.jmh.annotations.TearDown;
35+
import org.openjdk.jmh.annotations.Warmup;
36+
import org.openjdk.jmh.infra.Blackhole;
37+
import org.openjdk.jmh.profile.StackProfiler;
38+
import org.openjdk.jmh.runner.Runner;
39+
import org.openjdk.jmh.runner.options.Options;
40+
import org.openjdk.jmh.runner.options.OptionsBuilder;
41+
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
42+
import software.amazon.awssdk.benchmark.apicall.httpclient.SdkHttpClientBenchmark;
43+
import software.amazon.awssdk.benchmark.utils.MockH2Server;
44+
import software.amazon.awssdk.http.Protocol;
45+
import software.amazon.awssdk.http.SdkHttpConfigurationOption;
46+
import software.amazon.awssdk.http.async.SdkAsyncHttpClient;
47+
import software.amazon.awssdk.http.crt.AwsCrtAsyncHttpClient;
48+
import software.amazon.awssdk.regions.Region;
49+
import software.amazon.awssdk.services.protocolrestjson.ProtocolRestJsonAsyncClient;
50+
import software.amazon.awssdk.utils.AttributeMap;
51+
52+
/**
53+
* Benchmark for CRT HTTP client with HTTP/2 over TLS.
54+
*/
55+
@State(Scope.Benchmark)
56+
@Warmup(iterations = 3, time = 15, timeUnit = TimeUnit.SECONDS)
57+
@Measurement(iterations = 5, time = 10, timeUnit = TimeUnit.SECONDS)
58+
@Fork(2)
59+
@BenchmarkMode(Mode.Throughput)
60+
public class AwsCrtH2ClientBenchmark implements SdkHttpClientBenchmark {
61+
62+
private MockH2Server mockServer;
63+
private SdkAsyncHttpClient sdkHttpClient;
64+
private ProtocolRestJsonAsyncClient client;
65+
66+
@Setup(Level.Trial)
67+
public void setup() throws Exception {
68+
mockServer = new MockH2Server(true);
69+
mockServer.start();
70+
71+
sdkHttpClient = AwsCrtAsyncHttpClient.builder()
72+
.buildWithDefaults(
73+
AttributeMap.builder()
74+
.put(SdkHttpConfigurationOption.TRUST_ALL_CERTIFICATES, true)
75+
.put(SdkHttpConfigurationOption.PROTOCOL,
76+
Protocol.HTTP2)
77+
.build());
78+
79+
client = ProtocolRestJsonAsyncClient.builder()
80+
.credentialsProvider(() -> AwsBasicCredentials.create("foo", "bar"))
81+
.endpointOverride(mockServer.getHttpsUri())
82+
.httpClient(sdkHttpClient)
83+
.region(Region.US_EAST_1)
84+
.build();
85+
86+
client.allTypes().join();
87+
}
88+
89+
@TearDown(Level.Trial)
90+
public void tearDown() throws Exception {
91+
mockServer.stop();
92+
client.close();
93+
sdkHttpClient.close();
94+
}
95+
96+
@Override
97+
@Benchmark
98+
@OperationsPerInvocation(CONCURRENT_CALLS)
99+
public void concurrentApiCall(Blackhole blackhole) {
100+
CountDownLatch countDownLatch = new CountDownLatch(CONCURRENT_CALLS);
101+
for (int i = 0; i < CONCURRENT_CALLS; i++) {
102+
countDownUponCompletion(blackhole, client.allTypes(), countDownLatch);
103+
}
104+
awaitCountdownLatchUninterruptibly(countDownLatch, 10, TimeUnit.SECONDS);
105+
}
106+
107+
@Override
108+
@Benchmark
109+
public void sequentialApiCall(Blackhole blackhole) {
110+
CountDownLatch countDownLatch = new CountDownLatch(1);
111+
countDownUponCompletion(blackhole, client.allTypes(), countDownLatch);
112+
awaitCountdownLatchUninterruptibly(countDownLatch, 1, TimeUnit.SECONDS);
113+
}
114+
115+
public static void main(String... args) throws Exception {
116+
Options opt = new OptionsBuilder()
117+
.include(AwsCrtH2ClientBenchmark.class.getSimpleName())
118+
.addProfiler(StackProfiler.class)
119+
.build();
120+
new Runner(opt).run();
121+
}
122+
}

test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/httpclient/async/NettyHttpClientAlpnBenchmark.java renamed to test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/httpclient/async/NettyHttpClientH2AlpnBenchmark.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.openjdk.jmh.runner.Runner;
3939
import org.openjdk.jmh.runner.options.Options;
4040
import org.openjdk.jmh.runner.options.OptionsBuilder;
41+
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
4142
import software.amazon.awssdk.benchmark.utils.MockH2Server;
4243
import software.amazon.awssdk.http.Protocol;
4344
import software.amazon.awssdk.http.ProtocolNegotiation;
@@ -54,7 +55,7 @@
5455
@Measurement(iterations = 5, time = 10, timeUnit = TimeUnit.SECONDS)
5556
@Fork(2) // To reduce difference between each run
5657
@BenchmarkMode(Mode.Throughput)
57-
public class NettyHttpClientAlpnBenchmark extends BaseNettyBenchmark {
58+
public class NettyHttpClientH2AlpnBenchmark extends BaseNettyBenchmark {
5859

5960
private MockH2Server mockServer;
6061
private SdkAsyncHttpClient sdkHttpClient;
@@ -76,6 +77,7 @@ public void setup() throws Exception {
7677
.protocolNegotiation(ProtocolNegotiation.ALPN)
7778
.buildWithDefaults(trustAllTlsAttributeMapBuilder().build());
7879
client = ProtocolRestJsonAsyncClient.builder()
80+
.credentialsProvider(() -> AwsBasicCredentials.create("foo", "bar"))
7981
.endpointOverride(mockServer.getHttpsUri())
8082
.httpClient(sdkHttpClient)
8183
.region(Region.US_EAST_1)
@@ -94,7 +96,7 @@ public void tearDown() throws Exception {
9496

9597
public static void main(String... args) throws Exception {
9698
Options opt = new OptionsBuilder()
97-
.include(NettyHttpClientH2Benchmark.class.getSimpleName())
99+
.include(NettyHttpClientH2PriorKnowledgeBenchmark.class.getSimpleName())
98100
.build();
99101
Collection<RunResult> run = new Runner(opt).run();
100102
}

test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/httpclient/async/NettyHttpClientH2Benchmark.java renamed to test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/httpclient/async/NettyHttpClientH2PriorKnowledgeBenchmark.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.openjdk.jmh.runner.Runner;
3939
import org.openjdk.jmh.runner.options.Options;
4040
import org.openjdk.jmh.runner.options.OptionsBuilder;
41+
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
4142
import software.amazon.awssdk.benchmark.utils.MockH2Server;
4243
import software.amazon.awssdk.http.Protocol;
4344
import software.amazon.awssdk.http.async.SdkAsyncHttpClient;
@@ -53,7 +54,7 @@
5354
@Measurement(iterations = 5, time = 10, timeUnit = TimeUnit.SECONDS)
5455
@Fork(2) // To reduce difference between each run
5556
@BenchmarkMode(Mode.Throughput)
56-
public class NettyHttpClientH2Benchmark extends BaseNettyBenchmark {
57+
public class NettyHttpClientH2PriorKnowledgeBenchmark extends BaseNettyBenchmark {
5758

5859
private MockH2Server mockServer;
5960
private SdkAsyncHttpClient sdkHttpClient;
@@ -74,6 +75,7 @@ public void setup() throws Exception {
7475
.protocol(Protocol.HTTP2)
7576
.buildWithDefaults(trustAllTlsAttributeMapBuilder().build());
7677
client = ProtocolRestJsonAsyncClient.builder()
78+
.credentialsProvider(() -> AwsBasicCredentials.create("foo", "bar"))
7779
.endpointOverride(mockServer.getHttpsUri())
7880
.httpClient(sdkHttpClient)
7981
.region(Region.US_EAST_1)
@@ -92,7 +94,7 @@ public void tearDown() throws Exception {
9294

9395
public static void main(String... args) throws Exception {
9496
Options opt = new OptionsBuilder()
95-
.include(NettyHttpClientH2Benchmark.class.getSimpleName())
97+
.include(NettyHttpClientH2PriorKnowledgeBenchmark.class.getSimpleName())
9698
.build();
9799
Collection<RunResult> run = new Runner(opt).run();
98100
}

0 commit comments

Comments
 (0)