From 528e22c15006365f9a49d3d63d77f282807d7b48 Mon Sep 17 00:00:00 2001 From: overtrue Date: Sun, 23 Aug 2026 04:47:38 +0800 Subject: [PATCH] test(e2e): fail incomplete conditional PUT races --- .../e2e_test/src/cluster_concurrency_test.rs | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/crates/e2e_test/src/cluster_concurrency_test.rs b/crates/e2e_test/src/cluster_concurrency_test.rs index cc2f2cddc..c793c96c0 100644 --- a/crates/e2e_test/src/cluster_concurrency_test.rs +++ b/crates/e2e_test/src/cluster_concurrency_test.rs @@ -22,10 +22,9 @@ use tracing::{info, warn}; const BUCKET: &str = "conditional-put-race-bucket"; -async fn cleanup_object(client: &Client, key: &str) { - if let Err(e) = client.delete_object().bucket(BUCKET).key(key).send().await { - warn!("Failed to delete object '{}' from bucket '{}' during cleanup: {:?}", key, BUCKET, e); - } +async fn cleanup_object(client: &Client, key: &str) -> Result<(), Box> { + client.delete_object().bucket(BUCKET).key(key).send().await?; + Ok(()) } async fn conditional_put( @@ -71,14 +70,13 @@ async fn run_race_iteration( test_key: &str, iteration: usize, ) -> Result> { - cleanup_object(&clients[0], test_key).await; + cleanup_object(&clients[0], test_key).await?; tokio::time::sleep(tokio::time::Duration::from_millis(100)).await; - let head_result = clients[0].head_object().bucket(BUCKET).key(test_key).send().await; - - if head_result.is_ok() { - warn!("Warning: Object still exists after cleanup, skipping iteration {}", iteration); - return Ok(0); + match clients[0].head_object().bucket(BUCKET).key(test_key).send().await { + Ok(_) => return Err(format!("object still exists after cleanup in iteration {iteration}").into()), + Err(error) if error.as_service_error().is_some_and(|error| error.is_not_found()) => {} + Err(error) => return Err(format!("failed to verify cleanup in iteration {iteration}: {error:?}").into()), } info!("\n=== Iteration {} ===", iteration); @@ -120,14 +118,16 @@ async fn run_race_iteration( info!("Result: {} out of {} succeeded", success_count, clients.len()); + if had_error { + return Err("one or more conditional PUTs failed unexpectedly".into()); + } + if success_count > 1 { info!(">>> RACE CONDITION DETECTED!"); } else if success_count == 1 { info!(">>> Correct behavior: exactly 1 writer succeeded."); - } else if had_error { - return Err("all conditional PUTs failed (e.g. cluster/bucket not ready)".into()); } else { - info!(">>> Unexpected: no writers succeeded."); + return Err("no conditional PUT succeeded".into()); } Ok(success_count) @@ -167,7 +167,7 @@ async fn test_conditional_put_race_cluster() -> Result<(), Box Result<(), Box Result<(), Box Result<(), Box Result<(), Box