diff --git a/test/s3-benchmarks/.scripts/benchmark b/test/s3-benchmarks/.scripts/benchmark
index 4fb56f0d4435..5eaa2182d035 100755
--- a/test/s3-benchmarks/.scripts/benchmark
+++ b/test/s3-benchmarks/.scripts/benchmark
@@ -64,7 +64,7 @@ if [ ! -d result ]; then
fi
sizes_str="1B 8MB+1 8MB-1 128MB 4GB 30GB"
-versions_str="v1 v2 CRT"
+versions_str="v1 v2 CRT java"
sizes=( $sizes_str )
versions=( $versions_str )
diff --git a/test/s3-benchmarks/.scripts/create_benchmark_files b/test/s3-benchmarks/.scripts/create_benchmark_files
index a43725314cf2..20f196a6bd82 100755
--- a/test/s3-benchmarks/.scripts/create_benchmark_files
+++ b/test/s3-benchmarks/.scripts/create_benchmark_files
@@ -1,14 +1,13 @@
-head -c 1B /dev/shm/1B
-head -c 8388607B /dev/shm/8MB-1
-head -c 8388609B /dev/shm/8MB+1
-head -c 128M /dev/shm/128MB
-head -c 4B /dev/shm/4GB
-head -c 30GB /dev/shm/30GB
-
-head -c 1B /1B
-head -c 8388607B /8MB-1
-head -c 8388609B /8MB+1
-head -c 128M /128MB
-head -c 4B /4GB
-head -c 30GB /30GB
+head -c 1 /dev/shm/1B
+head -c $((8*1024*1024-1)) /dev/shm/8MB-1
+head -c $((8*1024*1024+1)) /dev/shm/8MB+1
+head -c $((128*1024*1024)) /dev/shm/128MB
+head -c $((4*1024*1024*1024)) /dev/shm/4GB
+head -c $((30*1024*1024*1024)) /dev/shm/30GB
+head -c 1 /1B
+head -c $((8*1024*1024-1)) /8MB-1
+head -c $((8*1024*1024+1)) /8MB+1
+head -c $((128*1024*1024)) /128MB
+head -c $((4*1024*1024*1024)) /4GB
+head -c $((30*1024*1024*1024)) /30GB
diff --git a/test/s3-benchmarks/README.md b/test/s3-benchmarks/README.md
index 74a7436ba92b..5f0dc4bc6443 100755
--- a/test/s3-benchmarks/README.md
+++ b/test/s3-benchmarks/README.md
@@ -1,7 +1,6 @@
# S3 Benchmark Harness
-
-This module contains performance tests for `S3AsyncClient` and
+This module contains performance tests for `S3AsyncClient` and
`S3TransferManager`
## How to run
@@ -17,6 +16,31 @@ java -jar s3-benchmarks.jar --bucket=bucket --key=key -file=/path/to/destionfile
java -jar s3-benchmarks.jar --bucket=bucket --key=key -file=/path/to/sourcefile/ --operation=upload --partSizeInMB=20 --maxThroughput=100.0
```
+## Command line arguments
+
+### Benchmark version
+
+The `--version` command line option is used to determine which component is under test:
+
+- `--version=crt` : Indicate to run the benchmark for the CRT's S3Client
+- `--version=java` : Indicate to run the benchmark for the java based S3 Async Client (`MultipartS3AsyncClient` class)
+- `--version=v2`: SDK v2 transfer manager (using `S3CrtAsyncClient` to delegate requests)
+- `--version=v1`: SDK v1 transfer manager (using `AmazonS3Client` to delegate requests)
+
+### Operation
+
+The `--operation` command line argument determine which transfer operation is used
+
+|operation|supported version|
+|---|-------|
+|download | v1 v2 java crt |
+|upload | v1 v2 java crt |
+|download_directory | v1 v2 |
+|upload_directory | v1 v2 |
+|copy | v1 v2 java |
+
+> All command line argument can be found in the `BenchmarkRunner` class.
+
# Benchmark scripts Automation
From the `.script` folder, use one of the `benchamrk` scripts to run a test suite.
diff --git a/test/s3-benchmarks/pom.xml b/test/s3-benchmarks/pom.xml
index 366bfa81ff6a..7fd6893e58d4 100644
--- a/test/s3-benchmarks/pom.xml
+++ b/test/s3-benchmarks/pom.xml
@@ -87,6 +87,16 @@
log4j-slf4j-impl
compile
+
+ software.amazon.awssdk
+ netty-nio-client
+ ${awsjavasdk.version}
+
+
+ software.amazon.awssdk
+ aws-crt-client
+ ${awsjavasdk.version}
+
diff --git a/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/BaseJavaS3ClientBenchmark.java b/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/BaseJavaS3ClientBenchmark.java
new file mode 100644
index 000000000000..cf8e71246be8
--- /dev/null
+++ b/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/BaseJavaS3ClientBenchmark.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file 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.
+ */
+
+package software.amazon.awssdk.s3benchmarks;
+
+import static software.amazon.awssdk.s3benchmarks.BenchmarkUtils.BENCHMARK_ITERATIONS;
+import static software.amazon.awssdk.s3benchmarks.BenchmarkUtils.DEFAULT_TIMEOUT;
+import static software.amazon.awssdk.s3benchmarks.BenchmarkUtils.printOutResult;
+import static software.amazon.awssdk.transfer.s3.SizeConstant.MB;
+
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.List;
+import software.amazon.awssdk.http.async.SdkAsyncHttpClient;
+import software.amazon.awssdk.http.crt.AwsCrtAsyncHttpClient;
+import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient;
+import software.amazon.awssdk.services.s3.S3AsyncClient;
+import software.amazon.awssdk.services.s3.S3Client;
+import software.amazon.awssdk.services.s3.model.ChecksumAlgorithm;
+import software.amazon.awssdk.utils.Logger;
+import software.amazon.awssdk.utils.Validate;
+
+public abstract class BaseJavaS3ClientBenchmark implements TransferManagerBenchmark {
+ private static final Logger logger = Logger.loggerFor(BaseJavaS3ClientBenchmark.class);
+
+ protected final S3Client s3Client;
+
+ protected final S3AsyncClient s3AsyncClient;
+ protected final String bucket;
+ protected final String key;
+ protected final Duration timeout;
+ private final ChecksumAlgorithm checksumAlgorithm;
+ private final int iteration;
+
+ protected BaseJavaS3ClientBenchmark(TransferManagerBenchmarkConfig config) {
+ this.bucket = Validate.paramNotNull(config.bucket(), "bucket");
+ this.key = Validate.paramNotNull(config.key(), "key");
+ this.timeout = Validate.getOrDefault(config.timeout(), () -> DEFAULT_TIMEOUT);
+ this.iteration = Validate.getOrDefault(config.iteration(), () -> BENCHMARK_ITERATIONS);
+ this.checksumAlgorithm = config.checksumAlgorithm();
+
+ this.s3Client = S3Client.create();
+
+ long partSizeInMb = Validate.paramNotNull(config.partSizeInMb(), "partSize");
+ long readBufferInMb = Validate.paramNotNull(config.readBufferSizeInMb(), "readBufferSizeInMb");
+ Validate.mutuallyExclusive("cannot use forceCrtHttpClient and connectionAcquisitionTimeoutInSec",
+ config.forceCrtHttpClient(), config.connectionAcquisitionTimeoutInSec());
+ this.s3AsyncClient = S3AsyncClient.builder()
+ .multipartEnabled(true)
+ .multipartConfiguration(c -> c.minimumPartSizeInBytes(partSizeInMb * MB)
+ .thresholdInBytes(partSizeInMb * 2 * MB)
+ .apiCallBufferSizeInBytes(readBufferInMb * MB))
+ .httpClientBuilder(httpClient(config))
+ .build();
+ }
+
+ private SdkAsyncHttpClient.Builder httpClient(TransferManagerBenchmarkConfig config) {
+ if (config.forceCrtHttpClient()) {
+ logger.info(() -> "Using CRT HTTP client");
+ AwsCrtAsyncHttpClient.Builder builder = AwsCrtAsyncHttpClient.builder();
+ if (config.readBufferSizeInMb() != null) {
+ builder.readBufferSizeInBytes(config.readBufferSizeInMb() * MB);
+ }
+ if (config.maxConcurrency() != null) {
+ builder.maxConcurrency(config.maxConcurrency());
+ }
+ return builder;
+ }
+ NettyNioAsyncHttpClient.Builder builder = NettyNioAsyncHttpClient.builder();
+ if (config.connectionAcquisitionTimeoutInSec() != null) {
+ Duration connAcqTimeout = Duration.ofSeconds(config.connectionAcquisitionTimeoutInSec());
+ builder.connectionAcquisitionTimeout(connAcqTimeout);
+ }
+ if (config.maxConcurrency() != null) {
+ builder.maxConcurrency(config.maxConcurrency());
+ }
+ return builder;
+ }
+
+ protected abstract void sendOneRequest(List latencies) throws Exception;
+
+ protected abstract long contentLength() throws Exception;
+
+ @Override
+ public void run() {
+ try {
+ warmUp();
+ doRunBenchmark();
+ } catch (Exception e) {
+ logger.error(() -> "Exception occurred", e);
+ } finally {
+ cleanup();
+ }
+ }
+
+ private void cleanup() {
+ s3Client.close();
+ s3AsyncClient.close();
+ }
+
+ private void warmUp() throws Exception {
+ logger.info(() -> "Starting to warm up");
+ for (int i = 0; i < 3; i++) {
+ sendOneRequest(new ArrayList<>());
+ Thread.sleep(500);
+ }
+ logger.info(() -> "Ending warm up");
+ }
+
+ private void doRunBenchmark() throws Exception {
+ List metrics = new ArrayList<>();
+ for (int i = 0; i < iteration; i++) {
+ sendOneRequest(metrics);
+ }
+ printOutResult(metrics, "S3 Async client", contentLength());
+ }
+
+}
diff --git a/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/BaseTransferManagerBenchmark.java b/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/BaseTransferManagerBenchmark.java
index c4370033c678..d40680bca028 100644
--- a/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/BaseTransferManagerBenchmark.java
+++ b/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/BaseTransferManagerBenchmark.java
@@ -34,6 +34,7 @@
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.S3Client;
+import software.amazon.awssdk.services.s3.S3CrtAsyncClientBuilder;
import software.amazon.awssdk.services.s3.internal.crt.S3CrtAsyncClient;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
@@ -61,15 +62,18 @@ public abstract class BaseTransferManagerBenchmark implements TransferManagerBen
logger.info(() -> "Benchmark config: " + config);
Long partSizeInMb = config.partSizeInMb() == null ? null : config.partSizeInMb() * MB;
Long readBufferSizeInMb = config.readBufferSizeInMb() == null ? null : config.readBufferSizeInMb() * MB;
- s3 = S3CrtAsyncClient.builder()
- .targetThroughputInGbps(config.targetThroughput())
- .minimumPartSizeInBytes(partSizeInMb)
- .initialReadBufferSizeInBytes(readBufferSizeInMb)
- .targetThroughputInGbps(config.targetThroughput() == null ?
- Double.valueOf(100.0) : config.targetThroughput())
- .build();
- s3Sync = S3Client.builder()
- .build();
+ S3CrtAsyncClientBuilder builder = S3CrtAsyncClient.builder()
+ .targetThroughputInGbps(config.targetThroughput())
+ .minimumPartSizeInBytes(partSizeInMb)
+ .initialReadBufferSizeInBytes(readBufferSizeInMb)
+ .targetThroughputInGbps(config.targetThroughput() == null ?
+ Double.valueOf(100.0) :
+ config.targetThroughput());
+ if (config.maxConcurrency() != null) {
+ builder.maxConcurrency(config.maxConcurrency());
+ }
+ s3 = builder.build();
+ s3Sync = S3Client.builder().build();
transferManager = S3TransferManager.builder()
.s3Client(s3)
.build();
diff --git a/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/BenchmarkRunner.java b/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/BenchmarkRunner.java
index 6f1dfaecc707..d83fc87026ae 100644
--- a/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/BenchmarkRunner.java
+++ b/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/BenchmarkRunner.java
@@ -45,6 +45,11 @@ public final class BenchmarkRunner {
private static final String TIMEOUT = "timeoutInMin";
+ private static final String CONN_ACQ_TIMEOUT_IN_SEC = "connAcqTimeoutInSec";
+
+ private static final String FORCE_CRT_HTTP_CLIENT = "crtHttp";
+ private static final String MAX_CONCURRENCY = "maxConcurrency";
+
private static final Map>
OPERATION_TO_BENCHMARK_V1 = new EnumMap<>(TransferManagerOperation.class);
private static final Map>
@@ -83,8 +88,8 @@ public static void main(String... args) throws org.apache.commons.cli.ParseExcep
options.addOption(null, CHECKSUM_ALGORITHM, true, "The checksum algorithm to use");
options.addOption(null, ITERATION, true, "The number of iterations");
options.addOption(null, READ_BUFFER_IN_MB, true, "Read buffer size in MB");
- options.addOption(null, VERSION, true, "The major version of the transfer manager to run test: v1 | v2 | crt, default: "
- + "v2");
+ options.addOption(null, VERSION, true, "The major version of the transfer manager to run test: "
+ + "v1 | v2 | crt | java, default: v2");
options.addOption(null, PREFIX, true, "S3 Prefix used in downloadDirectory and uploadDirectory");
options.addOption(null, CONTENT_LENGTH, true, "Content length to upload from memory. Used only in the "
@@ -93,6 +98,12 @@ public static void main(String... args) throws org.apache.commons.cli.ParseExcep
options.addOption(null, TIMEOUT, true, "Amount of minute to wait before a single operation "
+ "times out and is cancelled. Optional, defaults to 10 minutes if no specified");
+ options.addOption(null, CONN_ACQ_TIMEOUT_IN_SEC, true, "Timeout for acquiring an already-established"
+ + " connection from a connection pool to a remote service.");
+ options.addOption(null, FORCE_CRT_HTTP_CLIENT, true,
+ "Force the CRT http client to be used in JavaBased benchmarks");
+ options.addOption(null, MAX_CONCURRENCY, true,
+ "The Maximum number of allowed concurrent requests. For HTTP/1.1 this is the same as max connections.");
CommandLine cmd = parser.parse(options, args);
TransferManagerBenchmarkConfig config = parseConfig(cmd);
@@ -114,11 +125,22 @@ public static void main(String... args) throws org.apache.commons.cli.ParseExcep
if (operation == TransferManagerOperation.DOWNLOAD) {
benchmark = new CrtS3ClientDownloadBenchmark(config);
break;
- } else if (operation == TransferManagerOperation.UPLOAD) {
+ }
+ if (operation == TransferManagerOperation.UPLOAD) {
benchmark = new CrtS3ClientUploadBenchmark(config);
break;
}
throw new UnsupportedOperationException();
+ case JAVA:
+ if (operation == TransferManagerOperation.UPLOAD) {
+ benchmark = new JavaS3ClientUploadBenchmark(config);
+ break;
+ }
+ if (operation == TransferManagerOperation.COPY) {
+ benchmark = new JavaS3ClientCopyBenchmark(config);
+ break;
+ }
+ throw new UnsupportedOperationException("Java based s3 client benchmark only support upload and copy");
default:
throw new UnsupportedOperationException();
}
@@ -158,6 +180,15 @@ private static TransferManagerBenchmarkConfig parseConfig(CommandLine cmd) {
Duration timeout = cmd.getOptionValue(TIMEOUT) == null ? null :
Duration.ofMinutes(Long.parseLong(cmd.getOptionValue(TIMEOUT)));
+ Long connAcqTimeoutInSec = cmd.getOptionValue(CONN_ACQ_TIMEOUT_IN_SEC) == null ? null :
+ Long.parseLong(cmd.getOptionValue(CONN_ACQ_TIMEOUT_IN_SEC));
+
+ Boolean forceCrtHttpClient = cmd.getOptionValue(FORCE_CRT_HTTP_CLIENT) != null
+ && Boolean.parseBoolean(cmd.getOptionValue(FORCE_CRT_HTTP_CLIENT));
+
+ Integer maxConcurrency = cmd.getOptionValue(MAX_CONCURRENCY) == null ? null :
+ Integer.parseInt(cmd.getOptionValue(MAX_CONCURRENCY));
+
return TransferManagerBenchmarkConfig.builder()
.key(key)
.bucket(bucket)
@@ -171,6 +202,9 @@ private static TransferManagerBenchmarkConfig parseConfig(CommandLine cmd) {
.prefix(prefix)
.contentLengthInMb(contentLengthInMb)
.timeout(timeout)
+ .connectionAcquisitionTimeoutInSec(connAcqTimeoutInSec)
+ .forceCrtHttpClient(forceCrtHttpClient)
+ .maxConcurrency(maxConcurrency)
.build();
}
@@ -185,6 +219,7 @@ public enum TransferManagerOperation {
private enum SdkVersion {
V1,
V2,
- CRT
+ CRT,
+ JAVA
}
}
diff --git a/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/JavaS3ClientCopyBenchmark.java b/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/JavaS3ClientCopyBenchmark.java
new file mode 100644
index 000000000000..a2798a0e9cfd
--- /dev/null
+++ b/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/JavaS3ClientCopyBenchmark.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file 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.
+ */
+
+package software.amazon.awssdk.s3benchmarks;
+
+import static software.amazon.awssdk.s3benchmarks.BenchmarkUtils.COPY_SUFFIX;
+
+import java.util.List;
+import software.amazon.awssdk.utils.Logger;
+
+public class JavaS3ClientCopyBenchmark extends BaseJavaS3ClientBenchmark {
+ private static final Logger log = Logger.loggerFor(JavaS3ClientCopyBenchmark.class);
+
+ public JavaS3ClientCopyBenchmark(TransferManagerBenchmarkConfig config) {
+ super(config);
+ }
+
+ @Override
+ protected void sendOneRequest(List latencies) throws Exception {
+ log.info(() -> "Starting copy");
+ Double latency = runWithTime(s3AsyncClient.copyObject(
+ req -> req.sourceKey(key).sourceBucket(bucket)
+ .destinationBucket(bucket).destinationKey(key + COPY_SUFFIX)
+ )::join).latency();
+ latencies.add(latency);
+ }
+
+ @Override
+ protected long contentLength() throws Exception {
+ return s3Client.headObject(b -> b.bucket(bucket).key(key)).contentLength();
+ }
+}
diff --git a/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/JavaS3ClientUploadBenchmark.java b/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/JavaS3ClientUploadBenchmark.java
new file mode 100644
index 000000000000..07aec5448a46
--- /dev/null
+++ b/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/JavaS3ClientUploadBenchmark.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file 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.
+ */
+
+package software.amazon.awssdk.s3benchmarks;
+
+import static software.amazon.awssdk.transfer.s3.SizeConstant.MB;
+
+import java.nio.ByteBuffer;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import software.amazon.awssdk.core.async.AsyncRequestBody;
+import software.amazon.awssdk.services.s3.model.ChecksumAlgorithm;
+import software.amazon.awssdk.services.s3.model.PutObjectResponse;
+import software.amazon.awssdk.utils.async.SimplePublisher;
+
+public class JavaS3ClientUploadBenchmark extends BaseJavaS3ClientBenchmark {
+
+ private final String filePath;
+ private final Long contentLengthInMb;
+ private final Long partSizeInMb;
+ private final ChecksumAlgorithm checksumAlgorithm;
+
+ public JavaS3ClientUploadBenchmark(TransferManagerBenchmarkConfig config) {
+ super(config);
+ this.filePath = config.filePath();
+ this.contentLengthInMb = config.contentLengthInMb();
+ this.partSizeInMb = config.partSizeInMb();
+ this.checksumAlgorithm = config.checksumAlgorithm();
+ }
+
+ @Override
+ protected void sendOneRequest(List latencies) throws Exception {
+ if (filePath == null) {
+ double latency = uploadFromMemory();
+ latencies.add(latency);
+ return;
+ }
+ Double latency = runWithTime(
+ s3AsyncClient.putObject(req -> req.key(key).bucket(bucket).checksumAlgorithm(checksumAlgorithm),
+ Paths.get(filePath))::join).latency();
+ latencies.add(latency);
+ }
+
+ private double uploadFromMemory() throws Exception {
+ if (contentLengthInMb == null) {
+ throw new UnsupportedOperationException("Java upload benchmark - contentLengthInMb required for upload from memory");
+ }
+ long partSizeInBytes = partSizeInMb * MB;
+ // upload using known content length
+ SimplePublisher publisher = new SimplePublisher<>();
+ byte[] bytes = new byte[(int) partSizeInBytes];
+ Thread uploadThread = Executors.defaultThreadFactory().newThread(() -> {
+ long remaining = contentLengthInMb * MB;
+ while (remaining > 0) {
+ publisher.send(ByteBuffer.wrap(bytes));
+ remaining -= partSizeInBytes;
+ }
+ publisher.complete();
+ });
+ CompletableFuture responseFuture =
+ s3AsyncClient.putObject(r -> r.bucket(bucket)
+ .key(key)
+ .contentLength(contentLengthInMb * MB)
+ .checksumAlgorithm(checksumAlgorithm),
+ AsyncRequestBody.fromPublisher(publisher));
+ uploadThread.start();
+ long start = System.currentTimeMillis();
+ responseFuture.get(timeout.getSeconds(), TimeUnit.SECONDS);
+ long end = System.currentTimeMillis();
+ return (end - start) / 1000.0;
+ }
+
+ @Override
+ protected long contentLength() throws Exception {
+ return filePath != null
+ ? Files.size(Paths.get(filePath))
+ : contentLengthInMb * MB;
+ }
+}
diff --git a/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/TransferManagerBenchmark.java b/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/TransferManagerBenchmark.java
index 89f3362bc658..c182934f4e3f 100644
--- a/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/TransferManagerBenchmark.java
+++ b/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/TransferManagerBenchmark.java
@@ -15,6 +15,8 @@
package software.amazon.awssdk.s3benchmarks;
+import java.util.function.Supplier;
+
/**
* Factory to create the benchmark
*/
@@ -66,4 +68,29 @@ static TransferManagerBenchmark v1Copy(TransferManagerBenchmarkConfig config) {
return new V1TransferManagerCopyBenchmark(config);
}
+ default TimedResult runWithTime(Supplier toRun) {
+ long start = System.currentTimeMillis();
+ T result = toRun.get();
+ long end = System.currentTimeMillis();
+ return new TimedResult<>(result, (end - start) / 1000.0);
+ }
+
+ final class TimedResult {
+ private final Double latency;
+ private final T result;
+
+ public TimedResult(T result, Double latency) {
+ this.result = result;
+ this.latency = latency;
+ }
+
+ public Double latency() {
+ return latency;
+ }
+
+ public T result() {
+ return result;
+ }
+
+ }
}
diff --git a/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/TransferManagerBenchmarkConfig.java b/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/TransferManagerBenchmarkConfig.java
index b0a6f85a38c2..a3750f472498 100644
--- a/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/TransferManagerBenchmarkConfig.java
+++ b/test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/TransferManagerBenchmarkConfig.java
@@ -17,6 +17,7 @@
import java.time.Duration;
import software.amazon.awssdk.services.s3.model.ChecksumAlgorithm;
+import software.amazon.awssdk.utils.ToString;
public final class TransferManagerBenchmarkConfig {
private final String filePath;
@@ -28,6 +29,10 @@ public final class TransferManagerBenchmarkConfig {
private final Integer iteration;
private final Long contentLengthInMb;
private final Duration timeout;
+ private final Long memoryUsageInMb;
+ private final Long connectionAcquisitionTimeoutInSec;
+ private final Boolean forceCrtHttpClient;
+ private final Integer maxConcurrency;
private final Long readBufferSizeInMb;
private final BenchmarkRunner.TransferManagerOperation operation;
@@ -46,6 +51,10 @@ private TransferManagerBenchmarkConfig(Builder builder) {
this.prefix = builder.prefix;
this.contentLengthInMb = builder.contentLengthInMb;
this.timeout = builder.timeout;
+ this.memoryUsageInMb = builder.memoryUsage;
+ this.connectionAcquisitionTimeoutInSec = builder.connectionAcquisitionTimeoutInSec;
+ this.forceCrtHttpClient = builder.forceCrtHttpClient;
+ this.maxConcurrency = builder.maxConcurrency;
}
public String filePath() {
@@ -96,25 +105,46 @@ public Duration timeout() {
return this.timeout;
}
+ public Long memoryUsageInMb() {
+ return this.memoryUsageInMb;
+ }
+
+ public Long connectionAcquisitionTimeoutInSec() {
+ return this.connectionAcquisitionTimeoutInSec;
+ }
+
+ public boolean forceCrtHttpClient() {
+ return this.forceCrtHttpClient;
+ }
+
+ public Integer maxConcurrency() {
+ return this.maxConcurrency;
+ }
+
public static Builder builder() {
return new Builder();
}
@Override
public String toString() {
- return "{" +
- "filePath: '" + filePath + '\'' +
- ", bucket: '" + bucket + '\'' +
- ", key: '" + key + '\'' +
- ", targetThroughput: " + targetThroughput +
- ", partSizeInMb: " + partSizeInMb +
- ", checksumAlgorithm: " + checksumAlgorithm +
- ", iteration: " + iteration +
- ", readBufferSizeInMb: " + readBufferSizeInMb +
- ", operation: " + operation +
- ", contentLengthInMb: " + contentLengthInMb +
- ", timeout:" + timeout +
- '}';
+ return ToString.builder("TransferManagerBenchmarkConfig")
+ .add("filePath", filePath)
+ .add("bucket", bucket)
+ .add("key", key)
+ .add("targetThroughput", targetThroughput)
+ .add("partSizeInMb", partSizeInMb)
+ .add("checksumAlgorithm", checksumAlgorithm)
+ .add("iteration", iteration)
+ .add("contentLengthInMb", contentLengthInMb)
+ .add("timeout", timeout)
+ .add("memoryUsageInMb", memoryUsageInMb)
+ .add("connectionAcquisitionTimeoutInSec", connectionAcquisitionTimeoutInSec)
+ .add("forceCrtHttpClient", forceCrtHttpClient)
+ .add("maxConcurrency", maxConcurrency)
+ .add("readBufferSizeInMb", readBufferSizeInMb)
+ .add("operation", operation)
+ .add("prefix", prefix)
+ .build();
}
static final class Builder {
@@ -126,6 +156,10 @@ static final class Builder {
private Double targetThroughput;
private Long partSizeInMb;
private Long contentLengthInMb;
+ private Long memoryUsage;
+ private Long connectionAcquisitionTimeoutInSec;
+ private Boolean forceCrtHttpClient;
+ private Integer maxConcurrency;
private Integer iteration;
private BenchmarkRunner.TransferManagerOperation operation;
@@ -193,6 +227,26 @@ public Builder timeout(Duration timeout) {
return this;
}
+ public Builder memoryUsageInMb(Long memoryUsage) {
+ this.memoryUsage = memoryUsage;
+ return this;
+ }
+
+ public Builder connectionAcquisitionTimeoutInSec(Long connectionAcquisitionTimeoutInSec) {
+ this.connectionAcquisitionTimeoutInSec = connectionAcquisitionTimeoutInSec;
+ return this;
+ }
+
+ public Builder forceCrtHttpClient(Boolean forceCrtHttpClient) {
+ this.forceCrtHttpClient = forceCrtHttpClient;
+ return this;
+ }
+
+ public Builder maxConcurrency(Integer maxConcurrency) {
+ this.maxConcurrency = maxConcurrency;
+ return this;
+ }
+
public TransferManagerBenchmarkConfig build() {
return new TransferManagerBenchmarkConfig(this);
}