From ce5d5883530c680e778bda08ea13d76ebdeaadb6 Mon Sep 17 00:00:00 2001 From: BenWhitehead Date: Mon, 6 Jan 2025 18:57:42 +0000 Subject: [PATCH] test: update ITObjectTest to be parallel friendly Reduced wall time from ~2m to ~50 seconds Add a versioned bucket type available for injection with `@BucketFixture(VERSIONED)` rather than needing to create multiple times per test. --- .../google/cloud/storage/it/ITObjectTest.java | 356 ++++++++++-------- .../it/runner/annotations/BucketType.java | 4 +- .../it/runner/registry/BackendResources.java | 18 + 3 files changed, 218 insertions(+), 160 deletions(-) diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITObjectTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITObjectTest.java index 7a88da5e48..fbfa24bbd1 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITObjectTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITObjectTest.java @@ -62,6 +62,7 @@ import com.google.cloud.storage.it.runner.annotations.CrossRun; import com.google.cloud.storage.it.runner.annotations.CrossRun.Exclude; import com.google.cloud.storage.it.runner.annotations.Inject; +import com.google.cloud.storage.it.runner.annotations.ParallelFriendly; import com.google.cloud.storage.it.runner.registry.Generator; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -90,6 +91,7 @@ import java.util.Random; import java.util.Set; import java.util.concurrent.ExecutionException; +import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -101,6 +103,7 @@ @CrossRun( transports = {Transport.HTTP, Transport.GRPC}, backends = {Backend.PROD}) +@ParallelFriendly public class ITObjectTest { private static final String CONTENT_TYPE = "text/plain"; @@ -129,6 +132,10 @@ public class ITObjectTest { @BucketFixture(BucketType.REQUESTER_PAYS) public BucketInfo requesterPaysBucket; + @Inject + @BucketFixture(BucketType.VERSIONED) + public BucketInfo versionedBucket; + @Inject public Storage storage; @Test @@ -319,7 +326,7 @@ public void testGetBlobFail() { @Test public void testGetBlobFailNonExistingGeneration() { - String blobName = "test-get-blob-fail-non-existing-generation"; + String blobName = generator.randomObjectName(); BlobInfo blob = BlobInfo.newBuilder(bucket, blobName).build(); Blob remoteBlob = storage.create(blob); assertNotNull(remoteBlob); @@ -422,98 +429,132 @@ public void testListBlobRequesterPays() throws InterruptedException { @Test public void testListBlobsVersioned() throws ExecutionException, InterruptedException { - String bucketName = generator.randomBucketName(); - Bucket bucket = - storage.create(BucketInfo.newBuilder(bucketName).setVersioningEnabled(true).build()); - try { - String[] blobNames = {"test-list-blobs-versioned-blob1", "test-list-blobs-versioned-blob2"}; - BlobInfo blob1 = - BlobInfo.newBuilder(bucket, blobNames[0]).setContentType(CONTENT_TYPE).build(); - BlobInfo blob2 = - BlobInfo.newBuilder(bucket, blobNames[1]).setContentType(CONTENT_TYPE).build(); - Blob remoteBlob1 = storage.create(blob1); - Blob remoteBlob2 = storage.create(blob2); - Blob remoteBlob3 = storage.create(blob2); - assertNotNull(remoteBlob1); - assertNotNull(remoteBlob2); - assertNotNull(remoteBlob3); - Page page = + String bucketName = versionedBucket.getName(); + String baseName = generator.randomObjectName(); + String[] blobNames = {baseName + "-blob1", baseName + "-blob2"}; + BlobInfo blob1 = + BlobInfo.newBuilder(versionedBucket, blobNames[0]).setContentType(CONTENT_TYPE).build(); + BlobInfo blob2 = + BlobInfo.newBuilder(versionedBucket, blobNames[1]).setContentType(CONTENT_TYPE).build(); + Blob remoteBlob1 = storage.create(blob1); + Blob remoteBlob2 = storage.create(blob2); + Blob remoteBlob3 = storage.create(blob2); + assertNotNull(remoteBlob1); + assertNotNull(remoteBlob2); + assertNotNull(remoteBlob3); + Page page = + storage.list( + bucketName, BlobListOption.prefix(baseName + "-blob"), BlobListOption.versions(true)); + // https://cloud.google.com/storage/docs/consistency#strongly_consistent_operations + // enabling versioning on an existing bucket seems to have some backpressure on when new + // versions can safely be made, but listing is not eventually consistent. + + // TODO: make hermetic + // Listing blobs is eventually consistent, we loop until the list is of the expected size. The + // test fails if timeout is reached. + while (Iterators.size(page.iterateAll().iterator()) != 3) { + Thread.sleep(500); + page = storage.list( - bucketName, - BlobListOption.prefix("test-list-blobs-versioned-blob"), - BlobListOption.versions(true)); - // https://cloud.google.com/storage/docs/consistency#strongly_consistent_operations - // enabling versioning on an existing bucket seems to have some backpressure on when new - // versions can safely be made, but listing is not eventually consistent. - - // TODO: make hermetic - // Listing blobs is eventually consistent, we loop until the list is of the expected size. The - // test fails if timeout is reached. - while (Iterators.size(page.iterateAll().iterator()) != 3) { - Thread.sleep(500); - page = - storage.list( - bucketName, - BlobListOption.prefix("test-list-blobs-versioned-blob"), - BlobListOption.versions(true)); - } - Set blobSet = ImmutableSet.of(blobNames[0], blobNames[1]); - Iterator iterator = page.iterateAll().iterator(); - while (iterator.hasNext()) { - Blob remoteBlob = iterator.next(); - assertEquals(bucketName, remoteBlob.getBucket()); - assertTrue(blobSet.contains(remoteBlob.getName())); - assertNotNull(remoteBlob.getGeneration()); - } - } finally { - BucketCleaner.doCleanup(bucketName, storage); + bucketName, BlobListOption.prefix(baseName + "-blob"), BlobListOption.versions(true)); + } + Set blobSet = ImmutableSet.of(blobNames[0], blobNames[1]); + Iterator iterator = page.iterateAll().iterator(); + while (iterator.hasNext()) { + Blob remoteBlob = iterator.next(); + assertEquals(bucketName, remoteBlob.getBucket()); + assertTrue(blobSet.contains(remoteBlob.getName())); + assertNotNull(remoteBlob.getGeneration()); } } @Test - public void testListBlobsWithOffset() throws ExecutionException, InterruptedException { - String bucketName = generator.randomBucketName(); - Bucket bucket = - storage.create(BucketInfo.newBuilder(bucketName).setVersioningEnabled(true).build()); - try { - List blobNames = - ImmutableList.of("startOffset_blob1", "startOffset_blob2", "blob3_endOffset"); - BlobInfo blob1 = - BlobInfo.newBuilder(bucket, blobNames.get(0)).setContentType(CONTENT_TYPE).build(); - BlobInfo blob2 = - BlobInfo.newBuilder(bucket, blobNames.get(1)).setContentType(CONTENT_TYPE).build(); - BlobInfo blob3 = - BlobInfo.newBuilder(bucket, blobNames.get(2)).setContentType(CONTENT_TYPE).build(); - - Blob remoteBlob1 = storage.create(blob1); - Blob remoteBlob2 = storage.create(blob2); - Blob remoteBlob3 = storage.create(blob3); - assertNotNull(remoteBlob1); - assertNotNull(remoteBlob2); - assertNotNull(remoteBlob3); - - // Listing blobs without BlobListOptions. - Page page1 = storage.list(bucketName); - assertEquals(3, Iterators.size(page1.iterateAll().iterator())); - - // Listing blobs with startOffset. - Page page2 = storage.list(bucketName, BlobListOption.startOffset("startOffset")); - assertEquals(2, Iterators.size(page2.iterateAll().iterator())); - - // Listing blobs with endOffset. - Page page3 = storage.list(bucketName, BlobListOption.endOffset("endOffset")); - assertEquals(1, Iterators.size(page3.iterateAll().iterator())); - - // Listing blobs with startOffset and endOffset. - Page page4 = - storage.list( - bucketName, - BlobListOption.startOffset("startOffset"), - BlobListOption.endOffset("endOffset")); - assertEquals(0, Iterators.size(page4.iterateAll().iterator())); - } finally { - BucketCleaner.doCleanup(bucketName, storage); - } + public void testListBlobsWithOffset() throws Exception { + String bucketName = bucket.getName(); + String baseName = generator.randomObjectName(); + + List blobs = + IntStream.rangeClosed(0, 2) + .mapToObj(i -> baseName + "-" + i) + .map(n -> BlobInfo.newBuilder(bucket, n).build()) + .map(info -> storage.create(info, BlobTargetOption.doesNotExist())) + .map(BlobInfo::getBlobId) + .collect(Collectors.toList()); + + assertAll( + () -> { + // Listing blobs without BlobListOptions. + Page page1 = storage.list(bucketName, BlobListOption.prefix(baseName)); + assertThat( + page1 + .streamAll() + .map(BlobInfo::getBlobId) + .map(BlobId::toGsUtilUriWithGeneration) + .collect(Collectors.toList())) + .isEqualTo( + blobs.stream() + .map(BlobId::toGsUtilUriWithGeneration) + .collect(Collectors.toList())); + }, + () -> { + // Listing blobs starting from 1. + Page page2 = + storage.list( + bucketName, + BlobListOption.prefix(baseName), + BlobListOption.startOffset(blobs.get(1).getName())); + assertThat( + page2 + .streamAll() + .map(BlobInfo::getBlobId) + .map(BlobId::toGsUtilUriWithGeneration) + .collect(Collectors.toList())) + .isEqualTo( + blobs.stream() + .skip(1) + .map(BlobId::toGsUtilUriWithGeneration) + .collect(Collectors.toList())); + }, + () -> { + // Listing blobs until 2. + Page page3 = + storage.list( + bucketName, + BlobListOption.prefix(baseName), + BlobListOption.endOffset(blobs.get(2).getName())); + assertThat( + page3 + .streamAll() + .map(BlobInfo::getBlobId) + .map(BlobId::toGsUtilUriWithGeneration) + .collect(Collectors.toList())) + .isEqualTo( + blobs.stream() + .limit(2) + .map(BlobId::toGsUtilUriWithGeneration) + .collect(Collectors.toList())); + }, + () -> { + // Listing blobs with startOffset and endOffset. + Page page4 = + storage.list( + bucketName, + BlobListOption.prefix(baseName), + BlobListOption.startOffset(blobs.get(1).getName()), + BlobListOption.endOffset(blobs.get(2).getName())); + assertThat( + page4 + .streamAll() + .map(BlobInfo::getBlobId) + .map(BlobId::toGsUtilUriWithGeneration) + .collect(Collectors.toList())) + .isEqualTo( + blobs.stream() + .skip(1) + .limit(1) + .map(BlobId::toGsUtilUriWithGeneration) + .collect(Collectors.toList())); + }); } @Test @@ -546,7 +587,7 @@ public void testListBlobsCurrentDirectoryIncludesBothObjectsAndSyntheticDirector ImmutableSet actual = blobs.stream() .map(Blob::asBlobInfo) - .map(info -> PackagePrivateMethodWorkarounds.noAcl(info)) + .map(PackagePrivateMethodWorkarounds::noAcl) .collect(ImmutableSet.toImmutableSet()); // obj1Gen1 is "in subdirectory" and we don't expect to receive it as a result when listing @@ -564,54 +605,47 @@ public void testListBlobsCurrentDirectoryIncludesBothObjectsAndSyntheticDirector @Test // When gRPC support is added for matchGlob, enable this test for gRPC. public void testListBlobsWithMatchGlob() throws Exception { - BucketInfo bucketInfo = BucketInfo.newBuilder(generator.randomBucketName()).build(); - try (TemporaryBucket tempBucket = - TemporaryBucket.newBuilder().setBucketInfo(bucketInfo).setStorage(storage).build()) { - BucketInfo bucket = tempBucket.getBucket(); - assertNotNull(storage.create(BlobInfo.newBuilder(bucket, "foo/bar").build())); - assertNotNull(storage.create(BlobInfo.newBuilder(bucket, "foo/baz").build())); - assertNotNull(storage.create(BlobInfo.newBuilder(bucket, "foo/foobar").build())); - assertNotNull(storage.create(BlobInfo.newBuilder(bucket, "foobar").build())); - - Page page1 = storage.list(bucket.getName(), BlobListOption.matchGlob("foo*bar")); - Page page2 = storage.list(bucket.getName(), BlobListOption.matchGlob("foo**bar")); - Page page3 = storage.list(bucket.getName(), BlobListOption.matchGlob("**/foobar")); - Page page4 = storage.list(bucket.getName(), BlobListOption.matchGlob("*/ba[rz]")); - Page page5 = storage.list(bucket.getName(), BlobListOption.matchGlob("*/ba[!a-y]")); - Page page6 = - storage.list(bucket.getName(), BlobListOption.matchGlob("**/{foobar,baz}")); - Page page7 = - storage.list(bucket.getName(), BlobListOption.matchGlob("foo/{foo*,*baz}")); - assertAll( - () -> - assertThat(Iterables.transform(page1.iterateAll(), blob -> blob.getName())) - .containsExactly("foobar") - .inOrder(), - () -> - assertThat(Iterables.transform(page2.iterateAll(), blob -> blob.getName())) - .containsExactly("foo/bar", "foo/foobar", "foobar") - .inOrder(), - () -> - assertThat(Iterables.transform(page3.iterateAll(), blob -> blob.getName())) - .containsExactly("foo/foobar", "foobar") - .inOrder(), - () -> - assertThat(Iterables.transform(page4.iterateAll(), blob -> blob.getName())) - .containsExactly("foo/bar", "foo/baz") - .inOrder(), - () -> - assertThat(Iterables.transform(page5.iterateAll(), blob -> blob.getName())) - .containsExactly("foo/baz") - .inOrder(), - () -> - assertThat(Iterables.transform(page6.iterateAll(), blob -> blob.getName())) - .containsExactly("foo/baz", "foo/foobar", "foobar") - .inOrder(), - () -> - assertThat(Iterables.transform(page7.iterateAll(), blob -> blob.getName())) - .containsExactly("foo/baz", "foo/foobar") - .inOrder()); - } + assertNotNull(storage.create(BlobInfo.newBuilder(bucket, "foo/bar").build())); + assertNotNull(storage.create(BlobInfo.newBuilder(bucket, "foo/baz").build())); + assertNotNull(storage.create(BlobInfo.newBuilder(bucket, "foo/foobar").build())); + assertNotNull(storage.create(BlobInfo.newBuilder(bucket, "foobar").build())); + + Page page1 = storage.list(bucket.getName(), BlobListOption.matchGlob("foo*bar")); + Page page2 = storage.list(bucket.getName(), BlobListOption.matchGlob("foo**bar")); + Page page3 = storage.list(bucket.getName(), BlobListOption.matchGlob("**/foobar")); + Page page4 = storage.list(bucket.getName(), BlobListOption.matchGlob("*/ba[rz]")); + Page page5 = storage.list(bucket.getName(), BlobListOption.matchGlob("*/ba[!a-y]")); + Page page6 = storage.list(bucket.getName(), BlobListOption.matchGlob("**/{foobar,baz}")); + Page page7 = storage.list(bucket.getName(), BlobListOption.matchGlob("foo/{foo*,*baz}")); + assertAll( + () -> + assertThat(Iterables.transform(page1.iterateAll(), BlobInfo::getName)) + .containsExactly("foobar") + .inOrder(), + () -> + assertThat(Iterables.transform(page2.iterateAll(), BlobInfo::getName)) + .containsExactly("foo/bar", "foo/foobar", "foobar") + .inOrder(), + () -> + assertThat(Iterables.transform(page3.iterateAll(), BlobInfo::getName)) + .containsExactly("foo/foobar", "foobar") + .inOrder(), + () -> + assertThat(Iterables.transform(page4.iterateAll(), BlobInfo::getName)) + .containsExactly("foo/bar", "foo/baz") + .inOrder(), + () -> + assertThat(Iterables.transform(page5.iterateAll(), BlobInfo::getName)) + .containsExactly("foo/baz") + .inOrder(), + () -> + assertThat(Iterables.transform(page6.iterateAll(), BlobInfo::getName)) + .containsExactly("foo/baz", "foo/foobar", "foobar") + .inOrder(), + () -> + assertThat(Iterables.transform(page7.iterateAll(), BlobInfo::getName)) + .containsExactly("foo/baz", "foo/foobar") + .inOrder()); } @Test @@ -623,7 +657,7 @@ public void testListBlobsMultiplePages() { .mapToObj(i -> String.format("%s/%2d", basePath, i)) .map(name -> BlobInfo.newBuilder(bucket, name).build()) .map(info -> storage.create(info, BlobTargetOption.doesNotExist())) - .map(info1 -> PackagePrivateMethodWorkarounds.noAcl(info1)) + .map(PackagePrivateMethodWorkarounds::noAcl) .collect(ImmutableList.toImmutableList()); Page page = @@ -631,7 +665,7 @@ public void testListBlobsMultiplePages() { ImmutableList actual = ImmutableList.copyOf(page.iterateAll()).stream() - .map(info -> PackagePrivateMethodWorkarounds.noAcl(info)) + .map(PackagePrivateMethodWorkarounds::noAcl) .collect(ImmutableList.toImmutableList()); try { @@ -644,7 +678,7 @@ public void testListBlobsMultiplePages() { @Test public void testUpdateBlob() { - String blobName = "test-update-blob"; + String blobName = generator.randomObjectName(); BlobInfo blob = BlobInfo.newBuilder(bucket, blobName).build(); Blob remoteBlob = storage.create(blob); assertNotNull(remoteBlob); @@ -657,7 +691,7 @@ public void testUpdateBlob() { @Test public void testUpdateBlobReplaceMetadata() { - String blobName = "test-update-blob-replace-metadata"; + String blobName = generator.randomObjectName(); ImmutableMap metadata = ImmutableMap.of("k1", "a"); ImmutableMap newMetadata = ImmutableMap.of("k2", "b"); BlobInfo blob = @@ -678,7 +712,7 @@ public void testUpdateBlobReplaceMetadata() { @Test public void testUpdateBlobMergeMetadata() { - String blobName = "test-update-blob-merge-metadata"; + String blobName = generator.randomObjectName(); ImmutableMap metadata = ImmutableMap.of("k1", "a"); ImmutableMap newMetadata = ImmutableMap.of("k2", "b"); ImmutableMap expectedMetadata = ImmutableMap.of("k1", "a", "k2", "b"); @@ -699,7 +733,7 @@ public void testUpdateBlobMergeMetadata() { @Test public void testUpdateBlobUnsetMetadata() { - String blobName = "test-update-blob-unset-metadata"; + String blobName = generator.randomObjectName(); ImmutableMap metadata = ImmutableMap.of("k1", "a", "k2", "b"); Map newMetadata = new HashMap<>(); newMetadata.put("k1", "a"); @@ -721,7 +755,7 @@ public void testUpdateBlobUnsetMetadata() { @Test public void testUpdateBlobFail() { - String blobName = "test-update-blob-fail"; + String blobName = generator.randomObjectName(); BlobInfo blob = BlobInfo.newBuilder(bucket, blobName).build(); Blob remoteBlob = storage.create(blob); assertNotNull(remoteBlob); @@ -737,13 +771,13 @@ public void testUpdateBlobFail() { @Test public void testDeleteNonExistingBlob() { - String blobName = "test-delete-non-existing-blob"; + String blobName = generator.randomObjectName(); assertFalse(storage.delete(bucket.getName(), blobName)); } @Test public void testDeleteBlobNonExistingGeneration() { - String blobName = "test-delete-blob-non-existing-generation"; + String blobName = generator.randomObjectName(); BlobInfo blob = BlobInfo.newBuilder(bucket, blobName).build(); assertNotNull(storage.create(blob)); try { @@ -756,7 +790,7 @@ public void testDeleteBlobNonExistingGeneration() { @Test public void testDeleteBlobFail() { - String blobName = "test-delete-blob-fail"; + String blobName = generator.randomObjectName(); BlobInfo blob = BlobInfo.newBuilder(bucket, blobName).build(); Blob remoteBlob = storage.create(blob); assertNotNull(remoteBlob); @@ -771,15 +805,16 @@ public void testDeleteBlobFail() { @Test public void testComposeBlob() { - String sourceBlobName1 = "test-compose-blob-source-1"; - String sourceBlobName2 = "test-compose-blob-source-2"; + String baseName = generator.randomObjectName(); + String sourceBlobName1 = baseName + "-1"; + String sourceBlobName2 = baseName + "-2"; BlobInfo sourceBlob1 = BlobInfo.newBuilder(bucket, sourceBlobName1).build(); BlobInfo sourceBlob2 = BlobInfo.newBuilder(bucket, sourceBlobName2).build(); Blob remoteSourceBlob1 = storage.create(sourceBlob1, BLOB_BYTE_CONTENT); Blob remoteSourceBlob2 = storage.create(sourceBlob2, BLOB_BYTE_CONTENT); assertNotNull(remoteSourceBlob1); assertNotNull(remoteSourceBlob2); - String targetBlobName = "test-compose-blob-target"; + String targetBlobName = baseName + "-target"; BlobInfo targetBlob = BlobInfo.newBuilder(bucket, targetBlobName).build(); ComposeRequest req = ComposeRequest.of(ImmutableList.of(sourceBlobName1, sourceBlobName2), targetBlob); @@ -796,15 +831,16 @@ public void testComposeBlob() { @Test public void testComposeBlobWithContentType() { - String sourceBlobName1 = "test-compose-blob-with-content-type-source-1"; - String sourceBlobName2 = "test-compose-blob-with-content-type-source-2"; + String baseName = generator.randomObjectName(); + String sourceBlobName1 = baseName + "-source-1"; + String sourceBlobName2 = baseName + "-source-2"; BlobInfo sourceBlob1 = BlobInfo.newBuilder(bucket, sourceBlobName1).build(); BlobInfo sourceBlob2 = BlobInfo.newBuilder(bucket, sourceBlobName2).build(); Blob remoteSourceBlob1 = storage.create(sourceBlob1, BLOB_BYTE_CONTENT); Blob remoteSourceBlob2 = storage.create(sourceBlob2, BLOB_BYTE_CONTENT); assertNotNull(remoteSourceBlob1); assertNotNull(remoteSourceBlob2); - String targetBlobName = "test-compose-blob-with-content-type-target"; + String targetBlobName = baseName + "-target"; BlobInfo targetBlob = BlobInfo.newBuilder(bucket, targetBlobName).setContentType(CONTENT_TYPE).build(); ComposeRequest req = @@ -823,15 +859,16 @@ public void testComposeBlobWithContentType() { @Test public void testComposeBlobFail() { - String sourceBlobName1 = "test-compose-blob-fail-source-1"; - String sourceBlobName2 = "test-compose-blob-fail-source-2"; + String baseName = generator.randomObjectName(); + String sourceBlobName1 = baseName + "-source-1"; + String sourceBlobName2 = baseName + "-source-2"; BlobInfo sourceBlob1 = BlobInfo.newBuilder(bucket, sourceBlobName1).build(); BlobInfo sourceBlob2 = BlobInfo.newBuilder(bucket, sourceBlobName2).build(); Blob remoteSourceBlob1 = storage.create(sourceBlob1); Blob remoteSourceBlob2 = storage.create(sourceBlob2); assertNotNull(remoteSourceBlob1); assertNotNull(remoteSourceBlob2); - String targetBlobName = "test-compose-blob-fail-target"; + String targetBlobName = baseName + "-target"; BlobInfo targetBlob = BlobInfo.newBuilder(bucket, targetBlobName).build(); ComposeRequest req = ComposeRequest.newBuilder() @@ -1035,11 +1072,12 @@ public void testCopyBlobNoContentType() { @Exclude(transports = Transport.GRPC) public void testCopyBlobFail() { - String sourceBlobName = "test-copy-blob-source-fail"; + String baseName = generator.randomObjectName(); + String sourceBlobName = baseName + "-source-fail"; BlobId source = BlobId.of(bucket.getName(), sourceBlobName, -1L); Blob remoteSourceBlob = storage.create(BlobInfo.newBuilder(source).build(), BLOB_BYTE_CONTENT); assertNotNull(remoteSourceBlob); - String targetBlobName = "test-copy-blob-target-fail"; + String targetBlobName = baseName + "-target-fail"; BlobInfo target = BlobInfo.newBuilder(bucket, targetBlobName).setContentType(CONTENT_TYPE).build(); CopyRequest req = @@ -1070,7 +1108,7 @@ public void testCopyBlobFail() { @Test public void testReadAndWriteChannelWithEncryptionKey() throws IOException { - String blobName = "test-read-write-channel-with-customer-key-blob"; + String blobName = generator.randomObjectName(); BlobInfo blob = BlobInfo.newBuilder(bucket, blobName).build(); byte[] stringBytes; try (WriteChannel writer = storage.writer(blob, BlobWriteOption.encryptionKey(BASE64_KEY))) { diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/annotations/BucketType.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/annotations/BucketType.java index c333523573..6a7a8251d7 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/annotations/BucketType.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/annotations/BucketType.java @@ -23,5 +23,7 @@ public enum BucketType { /** A bucket created using all GCS defaults except that it has requester_pays enabled. */ REQUESTER_PAYS, /** A bucket created with Hierarchical Namespace enabled */ - HNS + HNS, + /** A bucket created using all GCS default except that object versioning is enabled */ + VERSIONED } diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/BackendResources.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/BackendResources.java index 237a5c67e7..a00d4e616e 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/BackendResources.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/BackendResources.java @@ -114,6 +114,8 @@ static BackendResources of(Backend backend) { case TEST_BENCH: optionsBuilder = StorageOptions.grpc() + .setGrpcInterceptorProvider( + GrpcPlainRequestLoggingInterceptor.getInterceptorProvider()) .setCredentials(NoCredentials.getInstance()) .setHost(Registry.getInstance().testBench().getGRPCBaseUri()) .setProjectId("test-project-id"); @@ -190,6 +192,17 @@ static BackendResources of(Backend backend) { storageJson.get().getStorage(), ctrl.get().getCtrl()); }); + TestRunScopedInstance bucketVersioned = + TestRunScopedInstance.of( + "BUCKET_VERSIONED_" + backend.name(), + () -> { + String bucketName = String.format("java-storage-grpc-v-%s", UUID.randomUUID()); + protectedBucketNames.add(bucketName); + return new BucketInfoShim( + BucketInfo.newBuilder(bucketName).setVersioningEnabled(true).build(), + storageJson.get().getStorage(), + ctrl.get().getCtrl()); + }); TestRunScopedInstance bucketHns = TestRunScopedInstance.of( "BUCKET_HNS_" + backend.name(), @@ -246,6 +259,11 @@ static BackendResources of(Backend backend) { BucketInfo.class, bucketHns, backendIs(backend).and(bucketTypeIs(BucketType.HNS))), + RegistryEntry.of( + 62, + BucketInfo.class, + bucketVersioned, + backendIs(backend).and(bucketTypeIs(BucketType.VERSIONED))), RegistryEntry.of( 70, BucketInfo.class, bucket, backendIs(backend).and(isDefaultBucket())), RegistryEntry.of(