@@ -293,6 +293,82 @@ TEST_F(ObjectRewriteIntegrationTest, ComposeSimple) {
293293 EXPECT_EQ (meta->size () * 2 , composed_meta->size ());
294294}
295295
296+ TEST_F (ObjectRewriteIntegrationTest, ComposeDeleteSourceObjectsFalse) {
297+ auto client = MakeIntegrationTestClient ();
298+
299+ auto object_name1 = MakeRandomObjectName ();
300+ StatusOr<ObjectMetadata> meta1 = client.InsertObject (
301+ bucket_name_, object_name1, LoremIpsum (), IfGenerationMatch (0 ));
302+ ASSERT_STATUS_OK (meta1);
303+ ScheduleForDelete (*meta1);
304+
305+ auto object_name2 = MakeRandomObjectName ();
306+ StatusOr<ObjectMetadata> meta2 = client.InsertObject (
307+ bucket_name_, object_name2, LoremIpsum (), IfGenerationMatch (0 ));
308+ ASSERT_STATUS_OK (meta2);
309+ ScheduleForDelete (*meta2);
310+
311+ auto composed_object_name = MakeRandomObjectName ();
312+ std::vector<ComposeSourceObject> source_objects = {{object_name1, {}, {}},
313+ {object_name2, {}, {}}};
314+
315+ StatusOr<ObjectMetadata> composed_meta = client.ComposeObject (
316+ bucket_name_, source_objects, composed_object_name,
317+ WithObjectMetadata (ObjectMetadata ().set_content_type (" plain/text" )),
318+ DeleteSourceObjects (false ));
319+ ASSERT_STATUS_OK (composed_meta);
320+ ScheduleForDelete (*composed_meta);
321+
322+ EXPECT_EQ (meta1->size () + meta2->size (), composed_meta->size ());
323+
324+ auto check1 = client.GetObjectMetadata (bucket_name_, object_name1);
325+ EXPECT_STATUS_OK (check1) << " Source object 1 (" << object_name1
326+ << " ) should NOT have been deleted." ;
327+
328+ auto check2 = client.GetObjectMetadata (bucket_name_, object_name2);
329+ EXPECT_STATUS_OK (check2) << " Source object 2 (" << object_name2
330+ << " ) should NOT have been deleted." ;
331+ }
332+
333+ TEST_F (ObjectRewriteIntegrationTest, ComposeDeleteSourceObjectsTrue) {
334+ auto client = MakeIntegrationTestClient ();
335+
336+ auto object_name1 = MakeRandomObjectName ();
337+ StatusOr<ObjectMetadata> meta1 = client.InsertObject (
338+ bucket_name_, object_name1, LoremIpsum (), IfGenerationMatch (0 ));
339+ ASSERT_STATUS_OK (meta1);
340+ ScheduleForDelete (*meta1);
341+
342+ auto object_name2 = MakeRandomObjectName ();
343+ StatusOr<ObjectMetadata> meta2 = client.InsertObject (
344+ bucket_name_, object_name2, LoremIpsum (), IfGenerationMatch (0 ));
345+ ASSERT_STATUS_OK (meta2);
346+ ScheduleForDelete (*meta2);
347+
348+ auto composed_object_name = MakeRandomObjectName ();
349+ std::vector<ComposeSourceObject> source_objects = {{object_name1, {}, {}},
350+ {object_name2, {}, {}}};
351+
352+ StatusOr<ObjectMetadata> composed_meta = client.ComposeObject (
353+ bucket_name_, source_objects, composed_object_name,
354+ WithObjectMetadata (ObjectMetadata ().set_content_type (" plain/text" )),
355+ DeleteSourceObjects (true ));
356+ ASSERT_STATUS_OK (composed_meta);
357+ ScheduleForDelete (*composed_meta);
358+
359+ EXPECT_EQ (meta1->size () + meta2->size (), composed_meta->size ());
360+
361+ auto check1 = client.GetObjectMetadata (bucket_name_, object_name1);
362+ EXPECT_FALSE (check1.ok ());
363+ EXPECT_EQ (StatusCode::kNotFound , check1.status ().code ())
364+ << " Source object 1 (" << object_name1 << " ) should have been deleted." ;
365+
366+ auto check2 = client.GetObjectMetadata (bucket_name_, object_name2);
367+ EXPECT_FALSE (check2.ok ());
368+ EXPECT_EQ (StatusCode::kNotFound , check2.status ().code ())
369+ << " Source object 2 (" << object_name2 << " ) should have been deleted." ;
370+ }
371+
296372TEST_F (ObjectRewriteIntegrationTest, ComposedUsingEncryptedObject) {
297373 // TODO(#14385) - the emulator does not support this feature for gRPC.
298374 if (UsingEmulator () && UsingGrpc ()) GTEST_SKIP ();
0 commit comments