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); }