fix(storage): stabilize main regressions (#6525)

This commit is contained in:
Zhengchao An
2026-08-24 20:26:03 +08:00
committed by GitHub
parent a8be4f2695
commit c1c6a1e23f
7 changed files with 198 additions and 70 deletions
-7
View File
@@ -12582,13 +12582,6 @@ mod tests {
.await
.expect("conditional writer task should finish")
.expect("matching conditional replace should commit");
assert!(
set_disks
.local_lock_manager_for_test()
.get_lock_info(&ObjectKey::new(bucket, object))
.is_none(),
"conditional replace should release the object lock after commit"
);
let contender = set_disks
.new_ns_lock(bucket, object)
.await
+25 -12
View File
@@ -5519,7 +5519,7 @@ mod tests {
assert_eq!(body, vec![0x54; 4096], "the retry's generation must be the one served");
}
#[tokio::test(start_paused = true)]
#[tokio::test]
#[serial]
async fn put_object_part_fences_part_lock_loss_before_rename() {
let target = Arc::new(std::sync::RwLock::new(None));
@@ -5533,10 +5533,14 @@ mod tests {
let bucket = "multipart-put-part-part-lock-loss-bucket";
let object = "object";
make_bucket_on_all(&disk_stores, bucket).await;
let upload = set_disks
.new_multipart_upload(bucket, object, &ObjectOptions::default())
.await
.expect("multipart upload should be created");
let upload = temp_env::async_with_vars([(ENV_RUSTFS_PUT_RENAME_EARLY_ACK_ENABLE, Some("false"))], async {
set_disks
.new_multipart_upload(bucket, object, &ObjectOptions::default())
.await
})
.await
.expect("multipart upload should be created");
tokio::time::pause();
let upload_id = upload.upload_id;
let upload_id_path = SetDisks::get_upload_id_dir(bucket, object, &upload_id);
let part_lock_path = format!("{upload_id_path}/part.1");
@@ -5584,7 +5588,7 @@ mod tests {
assert!(listed.parts.is_empty(), "part lock loss before rename must not publish the part");
}
#[tokio::test(start_paused = true)]
#[tokio::test]
#[serial]
async fn put_object_part_fences_upload_lock_loss_before_rename() {
let target = Arc::new(std::sync::RwLock::new(None));
@@ -5598,10 +5602,14 @@ mod tests {
let bucket = "multipart-put-part-lock-loss-bucket";
let object = "object";
make_bucket_on_all(&disk_stores, bucket).await;
let upload = set_disks
.new_multipart_upload(bucket, object, &ObjectOptions::default())
.await
.expect("multipart upload should be created");
let upload = temp_env::async_with_vars([(ENV_RUSTFS_PUT_RENAME_EARLY_ACK_ENABLE, Some("false"))], async {
set_disks
.new_multipart_upload(bucket, object, &ObjectOptions::default())
.await
})
.await
.expect("multipart upload should be created");
tokio::time::pause();
let upload_id = upload.upload_id;
let upload_id_path = SetDisks::get_upload_id_dir(bucket, object, &upload_id);
*target.write().expect("lock-loss target should be writable") =
@@ -6375,7 +6383,7 @@ mod tests {
.expect("failed completion must leave the upload retryable");
}
#[tokio::test(start_paused = true)]
#[tokio::test]
#[serial]
async fn complete_fences_upload_lock_loss_before_commit() {
temp_env::async_with_vars([(crate::object_api::ENV_RUSTFS_ENCRYPTED_RANGE_SEEK, Some("true"))], async {
@@ -6394,7 +6402,12 @@ mod tests {
user_defined: HashMap::from([(SSEC_ALGORITHM_HEADER.to_string(), "AES256".to_string())]),
..Default::default()
};
let (upload_id, parts) = stage_upload_with_create_opts(&set_disks, bucket, object, &[0x44; 4096], &create_opts).await;
let (upload_id, parts) =
temp_env::async_with_vars([(ENV_RUSTFS_PUT_RENAME_EARLY_ACK_ENABLE, Some("false"))], async {
stage_upload_with_create_opts(&set_disks, bucket, object, &[0x44; 4096], &create_opts).await
})
.await;
tokio::time::pause();
let upload_id_path = SetDisks::get_upload_id_dir(bucket, object, &upload_id);
*target.write().expect("lock-loss target should be writable") =
Some(rustfs_lock::ObjectKey::new(RUSTFS_META_MULTIPART_BUCKET, upload_id_path.clone()));
+68 -13
View File
@@ -9106,6 +9106,7 @@ mod inline_put_commit_path_tests {
}
#[tokio::test]
#[serial]
async fn ec_8_4_default_budget_keeps_large_inline_candidate_out_of_xl_meta() {
let (_temp_dirs, disk_stores, set_disks) = hermetic_set_disks(12).await;
set_disks.set_test_storage_class_config(
@@ -9117,10 +9118,15 @@ mod inline_put_commit_path_tests {
make_bucket(&disk_stores, bucket).await;
let mut reader = PutObjReader::from_vec(payload.clone());
set_disks
.put_object(bucket, object, &mut reader, &ObjectOptions::default())
.await
.expect("EC8+4 PUT should commit through the non-inline path");
temp_env::async_with_vars(
[(
crate::set_disk::core::io_primitives::ENV_RUSTFS_PUT_RENAME_EARLY_ACK_ENABLE,
Some("false"),
)],
set_disks.put_object(bucket, object, &mut reader, &ObjectOptions::default()),
)
.await
.expect("EC8+4 PUT should commit through the non-inline path");
for (disk_index, disk) in disk_stores.iter().enumerate() {
let file_info = disk
@@ -9146,6 +9152,7 @@ mod inline_put_commit_path_tests {
}
#[tokio::test]
#[serial]
async fn ec_8_4_versioned_budget_reaches_put_placement_decision() {
let (_temp_dirs, disk_stores, set_disks) = hermetic_set_disks(12).await;
set_disks.set_test_storage_class_config(
@@ -9161,10 +9168,15 @@ mod inline_put_commit_path_tests {
..Default::default()
};
let mut reader = PutObjReader::from_vec(payload.clone());
set_disks
.put_object(bucket, object, &mut reader, &options)
.await
.expect("versioned EC8+4 PUT should use the reduced inline budget");
temp_env::async_with_vars(
[(
crate::set_disk::core::io_primitives::ENV_RUSTFS_PUT_RENAME_EARLY_ACK_ENABLE,
Some("false"),
)],
set_disks.put_object(bucket, object, &mut reader, &options),
)
.await
.expect("versioned EC8+4 PUT should use the reduced inline budget");
for (disk_index, disk) in disk_stores.iter().enumerate() {
let file_info = disk
@@ -11933,7 +11945,14 @@ mod transition_upload_integrity_tests {
let bucket = "restore-finalize-acquired-lock-lost-bucket";
let object = "object.bin";
let operation_id = Uuid::new_v4();
let restored = write_committed_restore(&set_disks, &disk_stores, bucket, object, operation_id).await;
let restored = temp_env::async_with_vars(
[(
crate::set_disk::core::io_primitives::ENV_RUSTFS_PUT_RENAME_EARLY_ACK_ENABLE,
Some("false"),
)],
async { write_committed_restore(&set_disks, &disk_stores, bucket, object, operation_id).await },
)
.await;
let _setup_type_guard = SetupTypeGuard::switch_to(SetupType::DistErasure).await;
let barrier = RestoreFinalizeBarrier::install(bucket, object);
let finalize_set = Arc::clone(&set_disks);
@@ -12669,7 +12688,14 @@ mod transition_upload_integrity_tests {
let bucket = "data-movement-cleanup-lock-lost";
let object = "object.bin";
let payload = b"lost data movement cleanup lock must preserve the source".repeat(1024);
write_source(&set_disks, &disk_stores, bucket, object, &payload).await;
temp_env::async_with_vars(
[(
crate::set_disk::core::io_primitives::ENV_RUSTFS_PUT_RENAME_EARLY_ACK_ENABLE,
Some("false"),
)],
async { write_source(&set_disks, &disk_stores, bucket, object, &payload).await },
)
.await;
let expected = set_disks
.load_file_info_versions_exact(bucket, object)
.await
@@ -12722,7 +12748,14 @@ mod transition_upload_integrity_tests {
let bucket = "data-movement-cleanup-bucket-fence-lost";
let object = "object.bin";
let payload = b"lost bucket fence must preserve the source".repeat(1024);
write_source(&set_disks, &disk_stores, bucket, object, &payload).await;
temp_env::async_with_vars(
[(
crate::set_disk::core::io_primitives::ENV_RUSTFS_PUT_RENAME_EARLY_ACK_ENABLE,
Some("false"),
)],
async { write_source(&set_disks, &disk_stores, bucket, object, &payload).await },
)
.await;
let expected = set_disks
.load_file_info_versions_exact(bucket, object)
.await
@@ -12871,7 +12904,14 @@ mod transition_upload_integrity_tests {
let bucket = "transition-lock-lost-bucket";
let object = "object.bin";
let payload = b"lost transition commit lock must clean the remote candidate".repeat(1024);
let original = write_source(&set_disks, &disk_stores, bucket, object, &payload).await;
let original = temp_env::async_with_vars(
[(
crate::set_disk::core::io_primitives::ENV_RUSTFS_PUT_RENAME_EARLY_ACK_ENABLE,
Some("false"),
)],
async { write_source(&set_disks, &disk_stores, bucket, object, &payload).await },
)
.await;
let tier_name = format!("COLDTIER{}", &Uuid::new_v4().simple().to_string()[..8]).to_uppercase();
let backend = register_mock_tier(&runtime_sources::global_tier_config_mgr(), &tier_name).await;
let _setup_type_guard = SetupTypeGuard::switch_to(SetupType::DistErasure).await;
@@ -13314,7 +13354,14 @@ mod transition_upload_integrity_tests {
let (_temp_dirs, disk_stores, set_disks) = hermetic_set_disks_with_lockers(4, 0, 2, lockers).await;
let bucket = "tagging-lock-lost-bucket";
let object = "object.bin";
write_source(&set_disks, &disk_stores, bucket, object, b"tagging source").await;
temp_env::async_with_vars(
[(
crate::set_disk::core::io_primitives::ENV_RUSTFS_PUT_RENAME_EARLY_ACK_ENABLE,
Some("false"),
)],
async { write_source(&set_disks, &disk_stores, bucket, object, b"tagging source").await },
)
.await;
let _setup_type_guard = SetupTypeGuard::switch_to(SetupType::DistErasure).await;
let barrier = ObjectTaggingCommitBarrier::install(bucket, object);
@@ -13806,6 +13853,10 @@ mod heterogeneous_pool_put_tests {
[
(rustfs_config::ENV_OBJECT_TRANSACTION_FENCING_WRITE, Some("true")),
(rustfs_config::ENV_OBJECT_TRANSACTION_FENCING_FLEET_CONFIRMED, Some("true")),
(
crate::set_disk::core::io_primitives::ENV_RUSTFS_PUT_RENAME_EARLY_ACK_ENABLE,
Some("false"),
),
],
async {
let mut first_reader = PutObjReader::from_vec(large_payload(0x11));
@@ -13869,6 +13920,10 @@ mod heterogeneous_pool_put_tests {
[
(rustfs_config::ENV_OBJECT_TRANSACTION_FENCING_WRITE, Some("true")),
(rustfs_config::ENV_OBJECT_TRANSACTION_FENCING_FLEET_CONFIRMED, Some("true")),
(
crate::set_disk::core::io_primitives::ENV_RUSTFS_PUT_RENAME_EARLY_ACK_ENABLE,
Some("false"),
),
],
async {
let mut first_reader = PutObjReader::from_vec(large_payload(0x31));