diff --git a/modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3RepositoryThirdPartyTests.java b/modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3RepositoryThirdPartyTests.java index b8fea485c6276..1b4ab7de0c2ff 100644 --- a/modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3RepositoryThirdPartyTests.java +++ b/modules/repository-s3/src/internalClusterTest/java/org/elasticsearch/repositories/s3/S3RepositoryThirdPartyTests.java @@ -7,6 +7,8 @@ */ package org.elasticsearch.repositories.s3; +import com.amazonaws.AmazonClientException; +import com.amazonaws.services.s3.model.AmazonS3Exception; import com.amazonaws.services.s3.model.GetObjectRequest; import com.amazonaws.services.s3.model.InitiateMultipartUploadRequest; import com.amazonaws.services.s3.model.ListMultipartUploadsRequest; @@ -31,6 +33,7 @@ import org.elasticsearch.plugins.PluginsService; import org.elasticsearch.repositories.AbstractThirdPartyRepositoryTestCase; import org.elasticsearch.repositories.RepositoriesService; +import org.elasticsearch.rest.RestStatus; import org.elasticsearch.test.ClusterServiceUtils; import org.elasticsearch.test.fixtures.minio.MinioTestContainer; import org.elasticsearch.test.fixtures.testcontainers.TestContainersThreadFilter; @@ -50,6 +53,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.lessThanOrEqualTo; import static org.hamcrest.Matchers.not; @@ -222,4 +226,21 @@ List listMultipartUploads() { } } + public void testReadFromPositionLargerThanBlobLength() { + final var blobName = randomIdentifier(); + final var blobBytes = randomBytesReference(randomIntBetween(100, 2_000)); + + final var repository = getRepository(); + executeOnBlobStore(repository, blobStore -> { + blobStore.writeBlob(randomPurpose(), blobName, blobBytes, true); + return null; + }); + + long position = randomLongBetween(blobBytes.length(), Long.MAX_VALUE - 1L); + long length = randomLongBetween(1L, Long.MAX_VALUE - position); + var exception = expectThrows(AmazonClientException.class, () -> readBlob(repository, blobName, position, length)); + + assertThat(exception, instanceOf(AmazonS3Exception.class)); + assertThat(((AmazonS3Exception) exception).getStatusCode(), equalTo(RestStatus.REQUESTED_RANGE_NOT_SATISFIED.getStatus())); + } } diff --git a/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java b/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java index dfd2ae2b9f318..7cdeaeedfdeaf 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java @@ -35,7 +35,6 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.Locale; import java.util.Set; import java.util.concurrent.Executor; @@ -282,7 +281,7 @@ public void testReadFromPositionWithLength() { } } - private static T executeOnBlobStore(BlobStoreRepository repository, CheckedFunction fn) { + protected static T executeOnBlobStore(BlobStoreRepository repository, CheckedFunction fn) { final var future = new PlainActionFuture(); repository.threadPool().generic().execute(ActionRunnable.supply(future, () -> { var blobContainer = repository.blobStore().blobContainer(repository.basePath()); @@ -291,7 +290,7 @@ private static T executeOnBlobStore(BlobStoreRepository repository, CheckedF return future.actionGet(); } - private static BytesReference readBlob(BlobStoreRepository repository, String blobName, long position, long length) { + protected static BytesReference readBlob(BlobStoreRepository repository, String blobName, long position, long length) { return executeOnBlobStore(repository, blobContainer -> { try (var input = blobContainer.readBlob(randomPurpose(), blobName, position, length); var output = new BytesStreamOutput()) { Streams.copy(input, output);