diff --git a/object_store/src/aws/mod.rs b/object_store/src/aws/mod.rs index a7f9264a6815..7f449c49963c 100644 --- a/object_store/src/aws/mod.rs +++ b/object_store/src/aws/mod.rs @@ -570,6 +570,7 @@ mod tests { rename_and_copy(&integration).await; stream_get(&integration).await; multipart(&integration, &integration).await; + multipart_race_condition(&integration, true).await; signing(&integration).await; s3_encryption(&integration).await; put_get_attributes(&integration).await; diff --git a/object_store/src/azure/mod.rs b/object_store/src/azure/mod.rs index 469f15b2d9d1..81b6667bc058 100644 --- a/object_store/src/azure/mod.rs +++ b/object_store/src/azure/mod.rs @@ -314,7 +314,7 @@ mod tests { stream_get(&integration).await; put_opts(&integration, true).await; multipart(&integration, &integration).await; - multipart_race_condition(&integration).await; + multipart_race_condition(&integration, false).await; signing(&integration).await; let validate = !integration.client.config().disable_tagging; diff --git a/object_store/src/gcp/mod.rs b/object_store/src/gcp/mod.rs index 039ec46b68c2..5199135ba6b0 100644 --- a/object_store/src/gcp/mod.rs +++ b/object_store/src/gcp/mod.rs @@ -297,6 +297,7 @@ mod test { // https://github.com/fsouza/fake-gcs-server/issues/852 stream_get(&integration).await; multipart(&integration, &integration).await; + multipart_race_condition(&integration, true).await; // Fake GCS server doesn't currently honor preconditions get_opts(&integration).await; put_opts(&integration, true).await; diff --git a/object_store/src/integration.rs b/object_store/src/integration.rs index 863b03ab9b02..1a4907b97422 100644 --- a/object_store/src/integration.rs +++ b/object_store/src/integration.rs @@ -1113,7 +1113,7 @@ async fn delete_fixtures(storage: &DynObjectStore) { } /// Tests a race condition where 2 threads are performing multipart writes to the same path -pub async fn multipart_race_condition(storage: &dyn ObjectStore) { +pub async fn multipart_race_condition(storage: &dyn ObjectStore, last_writer_wins: bool) { let path = Path::from("test_multipart_race_condition"); let mut multipart_upload_1 = storage.put_multipart(&path).await.unwrap(); @@ -1165,9 +1165,14 @@ pub async fn multipart_race_condition(storage: &dyn ObjectStore) { .unwrap(); multipart_upload_1.complete().await.unwrap(); - let err = multipart_upload_2.complete().await.unwrap_err(); - assert!(matches!(err, crate::Error::Generic { .. }), "{err}"); + if last_writer_wins { + multipart_upload_2.complete().await.unwrap(); + } else { + let err = multipart_upload_2.complete().await.unwrap_err(); + + assert!(matches!(err, crate::Error::Generic { .. }), "{err}"); + } let get_result = storage.get(&path).await.unwrap(); let bytes = get_result.bytes().await.unwrap();