From c48f34ba2943700173e82552629041f9bbfa7fac Mon Sep 17 00:00:00 2001 From: trinity-1686a Date: Sat, 22 Oct 2022 11:40:55 +0200 Subject: [PATCH] add test for concurent multipart upload and delete --- src/garage/tests/s3/multipart.rs | 156 +++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) diff --git a/src/garage/tests/s3/multipart.rs b/src/garage/tests/s3/multipart.rs index 895a2993..3b1b702e 100644 --- a/src/garage/tests/s3/multipart.rs +++ b/src/garage/tests/s3/multipart.rs @@ -413,3 +413,159 @@ async fn test_uploadpartcopy() { assert_eq!(real_obj.len(), exp_obj.len()); assert_eq!(real_obj, exp_obj); } + +#[tokio::test] +async fn test_concurent_multipart_delete() { + let ctx = common::context(); + let bucket = ctx.create_bucket("uploadpartdelete"); + + { + // put an object + let data = ByteStream::from_static(b"Hello world!"); + + ctx.client + .put_object() + .bucket(&bucket) + .key("a") + .body(data) + .send() + .await + .unwrap(); + } + + let u1 = vec![0xee; SZ_5MB]; + let u2 = vec![0x11; SZ_5MB]; + + // create a multipart upload for the same key + let up = ctx + .client + .create_multipart_upload() + .bucket(&bucket) + .key("a") + .send() + .await + .unwrap(); + let uid = up.upload_id.as_ref().unwrap(); + + assert!(up.upload_id.is_some()); + + { + // object still accessible + let res = ctx + .client + .get_object() + .bucket(&bucket) + .key("a") + .send() + .await + .unwrap(); + + assert_bytes_eq!(res.body, b"Hello world!"); + } + + let p1 = ctx + .client + .upload_part() + .bucket(&bucket) + .key("a") + .upload_id(uid) + .part_number(2) + .body(ByteStream::from(u1)) + .send() + .await + .unwrap(); + + { + // object still accessible + let res = ctx + .client + .get_object() + .bucket(&bucket) + .key("a") + .send() + .await + .unwrap(); + + assert_bytes_eq!(res.body, b"Hello world!"); + + // delete it + + ctx.client + .delete_object() + .bucket(&bucket) + .key("a") + .send() + .await + .unwrap(); + + assert!(ctx.client + .get_object() + .bucket(&bucket) + .key("a") + .send() + .await + .is_err()); + } + + let p2 = ctx + .client + .upload_part() + .bucket(&bucket) + .key("a") + .upload_id(uid) + .part_number(1) + .body(ByteStream::from(u2)) + .send() + .await + .unwrap(); + + let cmp = CompletedMultipartUpload::builder() + .parts( + CompletedPart::builder() + .part_number(1) + .e_tag(p2.e_tag.unwrap()) + .build(), + ) + .parts( + CompletedPart::builder() + .part_number(2) + .e_tag(p1.e_tag.unwrap()) + .build(), + ) + .build(); + + ctx.client + .complete_multipart_upload() + .bucket(&bucket) + .key("a") + .upload_id(uid) + .multipart_upload(cmp) + .send() + .await + .unwrap(); + + // The multipart upload must not appear anymore + assert!(ctx + .client + .list_parts() + .bucket(&bucket) + .key("a") + .upload_id(uid) + .send() + .await + .is_err()); + + { + // The object must appear as a regular object + let r = ctx + .client + .head_object() + .bucket(&bucket) + .key("a") + .send() + .await + .unwrap(); + + assert_eq!(r.content_length, (SZ_5MB * 2) as i64); + } +}