test(scanner): align scoped maintenance oracle (#7404)

Keep the production scoped scanner test from mutating an unselected bucket during the dirty-only cycle. That cycle intentionally reuses the clean baseline, while the later Deep and full maintenance cycles still mutate cold storage and prove a full walk refreshes it.

Co-authored-by: zhi22915 <qiuzgang@gmail.com>
This commit is contained in:
houseme
2026-09-07 22:14:29 +08:00
committed by GitHub
parent f20a575994
commit bc0f608431
+14 -9
View File
@@ -365,14 +365,16 @@ async fn scoped_scan_production_entry_preserves_deep_and_full_maintenance_work()
.enumerate() .enumerate()
{ {
if index > 0 { if index > 0 {
let mutated_bucket = if index == 1 { "hot-bucket" } else { "cold-bucket" };
let mut reader = ScannerPutObjReader::from_vec(b"maintenance".to_vec()); let mut reader = ScannerPutObjReader::from_vec(b"maintenance".to_vec());
store.pools[0].disk_set[0] store.pools[0].disk_set[0]
.put_object("cold-bucket", &format!("added-{index}"), &mut reader, &ScannerObjectOptions::default()) .put_object(mutated_bucket, &format!("added-{index}"), &mut reader, &ScannerObjectOptions::default())
.await .await
.expect("cold bucket mutation should persist"); .expect("maintenance object should persist");
wait_for_namespace_commit_tails(store.as_ref()).await; wait_for_namespace_commit_tails(store.as_ref()).await;
// Only the hot bucket is in the usage hint. The cold result must // Only the hot bucket is in the dirty-usage hint. The ordinary
// come from this cycle's storage walk, not its previous baseline. // dirty cycle exercises scoped reuse; the following maintenance
// cycles mutate cold storage and must still walk it.
record_dirty_usage_bucket("hot-bucket"); record_dirty_usage_bucket("hot-bucket");
} }
let requested_scope = if explicit_scope { let requested_scope = if explicit_scope {
@@ -425,11 +427,14 @@ async fn scoped_scan_production_entry_preserves_deep_and_full_maintenance_work()
} }
let mut snapshot = receiver.recv().await.expect("cycle should publish a snapshot"); let mut snapshot = receiver.recv().await.expect("cycle should publish a snapshot");
assert!(snapshot.usage_snapshot_complete, "cycle {cycle}"); assert!(snapshot.usage_snapshot_complete, "cycle {cycle}");
assert_eq!( let expected_hot_count = if index >= 1 { 2 } else { 1 };
snapshot.buckets_usage["cold-bucket"].objects_count, let expected_cold_count = if index >= 2 {
u64::try_from(index + 1).expect("count should fit") u64::try_from(index).expect("count should fit")
); } else {
assert_eq!(snapshot.buckets_usage["hot-bucket"].objects_count, 1); 1
};
assert_eq!(snapshot.buckets_usage["cold-bucket"].objects_count, expected_cold_count);
assert_eq!(snapshot.buckets_usage["hot-bucket"].objects_count, expected_hot_count);
assert_eq!(snapshot.scanner_cycle, Some(cycle)); assert_eq!(snapshot.scanner_cycle, Some(cycle));
assert_eq!(snapshot.scanner_epoch, Some(11)); assert_eq!(snapshot.scanner_epoch, Some(11));
snapshot.usage_snapshot_converged = Some(true); snapshot.usage_snapshot_converged = Some(true);