mirror of
https://github.com/rustfs/rustfs.git
synced 2026-09-07 20:46:11 +00:00
test(scanner): cover scoped ack loss confirmation (#7393)
Add a scoped dirty-usage ACK confirmation fixture for transport failures after the send attempt. The test confirms that same-instance clean activity can reconcile a lost response, while peer restart and concurrent dirty usage stay pending. Co-authored-by: zhi22915 <qiuzgang@gmail.com>
This commit is contained in:
@@ -7609,6 +7609,81 @@ async fn scanner_cycle_confirms_lost_remote_ack_from_activity_snapshot() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn scanner_cycle_confirms_lost_scoped_ack_only_after_same_instance_clean_activity() {
|
||||||
|
let acknowledgement = ScannerDirtyUsageAcknowledgement {
|
||||||
|
host: "node-2".to_string(),
|
||||||
|
instance_id: "epoch-a".to_string(),
|
||||||
|
kind: ScannerDirtyUsageAcknowledgementKind::Scoped {
|
||||||
|
owner_id: Uuid::from_u128(0x11111111111111111111111111111111).to_string(),
|
||||||
|
entries: vec![crate::storage_api::EcstoreScannerScopedDirtyUsageAckEntry {
|
||||||
|
bucket: "photos".to_string(),
|
||||||
|
bucket_incarnation: Uuid::from_u128(0x22222222222222222222222222222222),
|
||||||
|
generation: 5,
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let attempted_send = Arc::new(AtomicBool::new(false));
|
||||||
|
let attempted_send_for_ack = Arc::clone(&attempted_send);
|
||||||
|
let cleared_activity = BTreeMap::from([("node-2".to_string(), scanner_node_activity("epoch-a", 7, 3))]);
|
||||||
|
let response_lost = remote_dirty_usage_acknowledgement_pending(
|
||||||
|
8,
|
||||||
|
1,
|
||||||
|
std::slice::from_ref(&acknowledgement),
|
||||||
|
async move {
|
||||||
|
attempted_send_for_ack.store(true, Ordering::SeqCst);
|
||||||
|
Err::<bool, _>(std::io::Error::other("scoped ACK transport failed after peer send"))
|
||||||
|
},
|
||||||
|
|| async { Ok(cleared_activity) },
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert!(
|
||||||
|
attempted_send.load(Ordering::SeqCst),
|
||||||
|
"the confirmation oracle must run only after the scoped ACK send was attempted"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
scanner_cycle_outcome_with_pending_maintenance(ScannerCycleOutcome::Completed, response_lost),
|
||||||
|
ScannerCycleOutcome::Completed,
|
||||||
|
"a same-instance clean activity snapshot confirms a lost scoped ACK response"
|
||||||
|
);
|
||||||
|
|
||||||
|
let restarted_activity = BTreeMap::from([("node-2".to_string(), scanner_node_activity("epoch-b", 7, 3))]);
|
||||||
|
let peer_restarted = remote_dirty_usage_acknowledgement_pending(
|
||||||
|
8,
|
||||||
|
1,
|
||||||
|
std::slice::from_ref(&acknowledgement),
|
||||||
|
std::future::ready(Err::<bool, _>(std::io::Error::other(
|
||||||
|
"scoped ACK transport failed before peer restart was observed",
|
||||||
|
))),
|
||||||
|
|| async { Ok(restarted_activity) },
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert_eq!(
|
||||||
|
scanner_cycle_outcome_with_pending_maintenance(ScannerCycleOutcome::Completed, peer_restarted),
|
||||||
|
ScannerCycleOutcome::CompletedWithPendingMaintenance,
|
||||||
|
"a restarted peer cannot prove the scoped ACK reached the old scanner instance"
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut written_activity = scanner_node_activity("epoch-a", 7, 3);
|
||||||
|
written_activity.dirty_usage_generation = 6;
|
||||||
|
written_activity.dirty_usage_pending = true;
|
||||||
|
let concurrent_write = remote_dirty_usage_acknowledgement_pending(
|
||||||
|
8,
|
||||||
|
1,
|
||||||
|
&[acknowledgement],
|
||||||
|
std::future::ready(Err::<bool, _>(std::io::Error::other(
|
||||||
|
"scoped ACK transport failed before a concurrent write was observed",
|
||||||
|
))),
|
||||||
|
|| async { Ok(BTreeMap::from([("node-2".to_string(), written_activity)])) },
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert_eq!(
|
||||||
|
scanner_cycle_outcome_with_pending_maintenance(ScannerCycleOutcome::Completed, concurrent_write),
|
||||||
|
ScannerCycleOutcome::CompletedWithPendingMaintenance,
|
||||||
|
"a same-instance concurrent write after scoped ACK send keeps maintenance pending"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[serial]
|
#[serial]
|
||||||
fn finalizing_an_already_durable_enum_without_proof_keeps_dirty_pending() {
|
fn finalizing_an_already_durable_enum_without_proof_keeps_dirty_pending() {
|
||||||
|
|||||||
Reference in New Issue
Block a user