Skip to content

Commit 4478b9d

Browse files
authored
test(retry): fix objects.compose tests (#1062)
* fix incorrect evaluation of idempotency for objects.compose (now generation, previously metageneration) * add mapping for non-idempotent objects.compose invocation * add CtxFunction to construct a ComposeRequest relative to the state * add ComposeRequest handling to state
1 parent 193a30a commit 4478b9d

File tree

5 files changed

+67
-15
lines changed

5 files changed

+67
-15
lines changed

google-cloud-storage/src/main/java/com/google/cloud/storage/NewRetryAlgorithmManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ public ExceptionHandler getForObjectsRewrite(RewriteRequest pb) {
284284
@Override
285285
public ExceptionHandler getForObjectsCompose(
286286
List<StorageObject> sources, StorageObject target, Map<StorageRpc.Option, ?> optionsMap) {
287-
return optionsMap.containsKey(StorageRpc.Option.IF_METAGENERATION_MATCH)
287+
return optionsMap.containsKey(StorageRpc.Option.IF_GENERATION_MATCH)
288288
? IDEMPOTENT_HANDLER
289289
: NON_IDEMPOTENT_HANDLER;
290290
}

google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/CtxFunctions.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import com.google.cloud.storage.BucketInfo;
3030
import com.google.cloud.storage.HmacKey;
3131
import com.google.cloud.storage.ServiceAccount;
32+
import com.google.cloud.storage.Storage.BlobTargetOption;
33+
import com.google.cloud.storage.Storage.ComposeRequest;
3234
import com.google.cloud.storage.conformance.retry.Functions.CtxFunction;
3335
import com.google.common.base.Joiner;
3436
import java.util.HashSet;
@@ -46,9 +48,35 @@
4648
*/
4749
final class CtxFunctions {
4850

49-
private static final class Util {
51+
static final class Util {
5052
private static final CtxFunction blobIdAndBlobInfo =
5153
(ctx, c) -> ctx.map(state -> state.with(BlobInfo.newBuilder(state.getBlobId()).build()));
54+
55+
static final CtxFunction composeRequest =
56+
(ctx, c) ->
57+
ctx.map(
58+
state -> {
59+
Blob blob = state.getBlob();
60+
String bucket = blob.getBucket();
61+
final BlobInfo target;
62+
if (c.isPreconditionsProvided()) {
63+
target = BlobInfo.newBuilder(BlobId.of(bucket, "blob-full", 0L)).build();
64+
} else {
65+
target = BlobInfo.newBuilder(BlobId.of(bucket, "blob-full")).build();
66+
}
67+
ComposeRequest.Builder builder =
68+
ComposeRequest.newBuilder()
69+
// source bucket is resolved from the target, as compose must be within
70+
// the same bucket
71+
.addSource(blob.getName(), blob.getGeneration())
72+
.addSource(blob.getName(), blob.getGeneration())
73+
.setTarget(target);
74+
if (c.isPreconditionsProvided()) {
75+
builder = builder.setTargetOptions(BlobTargetOption.generationMatch());
76+
}
77+
ComposeRequest r = builder.build();
78+
return state.with(r);
79+
});
5280
}
5381

5482
static final class Local {

google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/RpcMethodMappings.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import static com.google.cloud.storage.conformance.retry.CtxFunctions.ResourceSetup.defaultSetup;
2424
import static com.google.cloud.storage.conformance.retry.CtxFunctions.ResourceSetup.serviceAccount;
2525
import static com.google.common.base.Predicates.not;
26-
import static com.google.common.collect.Lists.newArrayList;
2726
import static com.google.common.truth.Truth.assertThat;
2827
import static org.junit.Assert.assertTrue;
2928

@@ -45,12 +44,12 @@
4544
import com.google.cloud.storage.Storage.BlobWriteOption;
4645
import com.google.cloud.storage.Storage.BucketSourceOption;
4746
import com.google.cloud.storage.Storage.BucketTargetOption;
48-
import com.google.cloud.storage.Storage.ComposeRequest;
4947
import com.google.cloud.storage.Storage.CopyRequest;
5048
import com.google.cloud.storage.Storage.SignUrlOption;
5149
import com.google.cloud.storage.Storage.UriScheme;
5250
import com.google.cloud.storage.conformance.retry.CtxFunctions.Local;
5351
import com.google.cloud.storage.conformance.retry.CtxFunctions.Rpc;
52+
import com.google.cloud.storage.conformance.retry.CtxFunctions.Util;
5453
import com.google.cloud.storage.conformance.retry.RpcMethod.storage.bucket_acl;
5554
import com.google.cloud.storage.conformance.retry.RpcMethod.storage.buckets;
5655
import com.google.cloud.storage.conformance.retry.RpcMethod.storage.default_object_acl;
@@ -1824,17 +1823,23 @@ private static void update(ArrayList<RpcMethodMapping> a) {}
18241823
private static void compose(ArrayList<RpcMethodMapping> a) {
18251824
a.add(
18261825
RpcMethodMapping.newBuilder(35, objects.compose)
1826+
.withApplicable(TestRetryConformance::isPreconditionsProvided)
1827+
.withSetup(defaultSetup.andThen(Util.composeRequest))
18271828
.withTest(
18281829
(ctx, c) ->
18291830
ctx.map(
18301831
state ->
1831-
state.with(
1832-
ctx.getStorage()
1833-
.compose(
1834-
ComposeRequest.of(
1835-
c.getBucketName(),
1836-
newArrayList("blob-part-1", "blob-part-2"),
1837-
"blob-full")))))
1832+
state.with(ctx.getStorage().compose(state.getComposeRequest()))))
1833+
.build());
1834+
a.add(
1835+
RpcMethodMapping.newBuilder(241, objects.compose)
1836+
.withApplicable(not(TestRetryConformance::isPreconditionsProvided))
1837+
.withSetup(defaultSetup.andThen(Util.composeRequest))
1838+
.withTest(
1839+
(ctx, c) ->
1840+
ctx.map(
1841+
state ->
1842+
state.with(ctx.getStorage().compose(state.getComposeRequest()))))
18381843
.build());
18391844
}
18401845

google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/State.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import com.google.cloud.storage.HmacKey;
3131
import com.google.cloud.storage.HmacKey.HmacKeyMetadata;
3232
import com.google.cloud.storage.ServiceAccount;
33+
import com.google.cloud.storage.Storage.ComposeRequest;
3334
import com.google.cloud.storage.conformance.retry.Functions.VoidFunction;
3435
import com.google.common.collect.ImmutableMap;
3536
import com.google.errorprone.annotations.Immutable;
@@ -75,6 +76,7 @@ final class State {
7576
new Key<>("testIamPermissionsResults");
7677
private static final Key<List<Acl>> KEY_ACLS = new Key<>("acls");
7778
private static final Key<byte[]> KEY_BYTES = new Key<>("bytes");
79+
private static final Key<ComposeRequest> KEY_COMPOSE_REQUEST = new Key<>("composeRequest");
7880

7981
private final ImmutableMap<Key<?>, Object> data;
8082

@@ -293,6 +295,18 @@ public <T> State consume(Page<T> page) {
293295
return newStateWith(KEY_LIST_OBJECTS, collect);
294296
}
295297

298+
public State with(ComposeRequest composeRequest) {
299+
return newStateWith(KEY_COMPOSE_REQUEST, composeRequest);
300+
}
301+
302+
public ComposeRequest getComposeRequest() {
303+
return getValue(KEY_COMPOSE_REQUEST);
304+
}
305+
306+
public boolean hasComposeRequest() {
307+
return hasValue(KEY_COMPOSE_REQUEST);
308+
}
309+
296310
private <T> T getValue(Key<T> key) {
297311
Object o = data.get(key);
298312
requireNonNull(o, () -> String.format("%s was not found in state", key.name));

google-cloud-storage/src/test/resources/com/google/cloud/storage/conformance/retry/testNamesWhichShouldSucceed.txt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ TestRetryConformance/1-[return-reset-connection_return-reset-connection]-storage
142142
TestRetryConformance/1-[return-reset-connection_return-reset-connection]-storage.serviceaccount.get-59
143143
TestRetryConformance/2-[return-503_return-503]-storage.buckets.patch-101
144144
TestRetryConformance/2-[return-503_return-503]-storage.buckets.patch-122
145+
TestRetryConformance/2-[return-503_return-503]-storage.objects.compose-35
145146
TestRetryConformance/2-[return-503_return-503]-storage.objects.delete-37
146147
TestRetryConformance/2-[return-503_return-503]-storage.objects.delete-38
147148
TestRetryConformance/2-[return-503_return-503]-storage.objects.delete-68
@@ -151,6 +152,7 @@ TestRetryConformance/2-[return-503_return-503]-storage.objects.patch-57
151152
TestRetryConformance/2-[return-503_return-503]-storage.objects.patch-80
152153
TestRetryConformance/2-[return-reset-connection_return-503]-storage.buckets.patch-101
153154
TestRetryConformance/2-[return-reset-connection_return-503]-storage.buckets.patch-122
155+
TestRetryConformance/2-[return-reset-connection_return-503]-storage.objects.compose-35
154156
TestRetryConformance/2-[return-reset-connection_return-503]-storage.objects.delete-37
155157
TestRetryConformance/2-[return-reset-connection_return-503]-storage.objects.delete-38
156158
TestRetryConformance/2-[return-reset-connection_return-503]-storage.objects.delete-68
@@ -160,6 +162,7 @@ TestRetryConformance/2-[return-reset-connection_return-503]-storage.objects.patc
160162
TestRetryConformance/2-[return-reset-connection_return-503]-storage.objects.patch-80
161163
TestRetryConformance/2-[return-reset-connection_return-reset-connection]-storage.buckets.patch-101
162164
TestRetryConformance/2-[return-reset-connection_return-reset-connection]-storage.buckets.patch-122
165+
TestRetryConformance/2-[return-reset-connection_return-reset-connection]-storage.objects.compose-35
163166
TestRetryConformance/2-[return-reset-connection_return-reset-connection]-storage.objects.delete-37
164167
TestRetryConformance/2-[return-reset-connection_return-reset-connection]-storage.objects.delete-38
165168
TestRetryConformance/2-[return-reset-connection_return-reset-connection]-storage.objects.delete-68
@@ -170,7 +173,7 @@ TestRetryConformance/2-[return-reset-connection_return-reset-connection]-storage
170173
TestRetryConformance/3-[return-503]-storage.buckets.patch-17
171174
TestRetryConformance/3-[return-503]-storage.buckets.setIamPolicy-18
172175
TestRetryConformance/3-[return-503]-storage.hmacKey.update-29
173-
TestRetryConformance/3-[return-503]-storage.objects.compose-35
176+
TestRetryConformance/3-[return-503]-storage.objects.compose-241
174177
TestRetryConformance/3-[return-503]-storage.objects.delete-36
175178
TestRetryConformance/3-[return-503]-storage.objects.delete-67
176179
TestRetryConformance/3-[return-503]-storage.objects.insert-108
@@ -195,7 +198,7 @@ TestRetryConformance/3-[return-503]-storage.objects.rewrite-86
195198
TestRetryConformance/3-[return-reset-connection]-storage.buckets.patch-17
196199
TestRetryConformance/3-[return-reset-connection]-storage.buckets.setIamPolicy-18
197200
TestRetryConformance/3-[return-reset-connection]-storage.hmacKey.update-29
198-
TestRetryConformance/3-[return-reset-connection]-storage.objects.compose-35
201+
TestRetryConformance/3-[return-reset-connection]-storage.objects.compose-241
199202
TestRetryConformance/3-[return-reset-connection]-storage.objects.insert-108
200203
TestRetryConformance/3-[return-reset-connection]-storage.objects.insert-109
201204
TestRetryConformance/3-[return-reset-connection]-storage.objects.insert-110
@@ -303,7 +306,7 @@ TestRetryConformance/5-[return-400]-storage.object_acl.list-33
303306
TestRetryConformance/5-[return-400]-storage.object_acl.list-65
304307
TestRetryConformance/5-[return-400]-storage.object_acl.patch-34
305308
TestRetryConformance/5-[return-400]-storage.object_acl.patch-66
306-
TestRetryConformance/5-[return-400]-storage.objects.compose-35
309+
TestRetryConformance/5-[return-400]-storage.objects.compose-241
307310
TestRetryConformance/5-[return-400]-storage.objects.delete-36
308311
TestRetryConformance/5-[return-400]-storage.objects.delete-67
309312
TestRetryConformance/5-[return-400]-storage.objects.get-107
@@ -396,7 +399,7 @@ TestRetryConformance/5-[return-401]-storage.object_acl.list-33
396399
TestRetryConformance/5-[return-401]-storage.object_acl.list-65
397400
TestRetryConformance/5-[return-401]-storage.object_acl.patch-34
398401
TestRetryConformance/5-[return-401]-storage.object_acl.patch-66
399-
TestRetryConformance/5-[return-401]-storage.objects.compose-35
402+
TestRetryConformance/5-[return-401]-storage.objects.compose-241
400403
TestRetryConformance/5-[return-401]-storage.objects.delete-36
401404
TestRetryConformance/5-[return-401]-storage.objects.delete-67
402405
TestRetryConformance/5-[return-401]-storage.objects.get-107
@@ -467,6 +470,7 @@ TestRetryConformance/6-[return-503_return-400]-storage.object_acl.get-31
467470
TestRetryConformance/6-[return-503_return-400]-storage.object_acl.get-63
468471
TestRetryConformance/6-[return-503_return-400]-storage.object_acl.list-33
469472
TestRetryConformance/6-[return-503_return-400]-storage.object_acl.list-65
473+
TestRetryConformance/6-[return-503_return-400]-storage.objects.compose-35
470474
TestRetryConformance/6-[return-503_return-400]-storage.objects.delete-37
471475
TestRetryConformance/6-[return-503_return-400]-storage.objects.delete-38
472476
TestRetryConformance/6-[return-503_return-400]-storage.objects.delete-68
@@ -523,6 +527,7 @@ TestRetryConformance/6-[return-reset-connection_return-401]-storage.object_acl.g
523527
TestRetryConformance/6-[return-reset-connection_return-401]-storage.object_acl.get-63
524528
TestRetryConformance/6-[return-reset-connection_return-401]-storage.object_acl.list-33
525529
TestRetryConformance/6-[return-reset-connection_return-401]-storage.object_acl.list-65
530+
TestRetryConformance/6-[return-reset-connection_return-401]-storage.objects.compose-35
526531
TestRetryConformance/6-[return-reset-connection_return-401]-storage.objects.delete-37
527532
TestRetryConformance/6-[return-reset-connection_return-401]-storage.objects.delete-38
528533
TestRetryConformance/6-[return-reset-connection_return-401]-storage.objects.delete-68

0 commit comments

Comments
 (0)