test(lifecycle,scanner): drop 47 no-op #[serial] markers (backlog#1846 T1) (#6213)

Second batch of the #[serial] sweep started in #6209. nextest is the
repository's authoritative runner and executes every test in its own
process, so serial_test's in-process mutex cannot serialize tests against
each other -- docs/testing/README.md documents this, and the mechanism
that actually serializes across the process boundary is a
.config/nextest.toml [test-groups] entry with max-threads = 1.

Unlike the first batch (e2e, process-isolated by construction), these are
in-crate unit tests that could genuinely share process state under the
`cargo test` fallback runner, where #[serial] IS still effective. Every
marker was therefore reviewed individually and removed only where the
test provably touches neither the process environment nor a process-global.

Removed (47, pure deletions, no test bodies touched):

  crates/lifecycle/src/core.rs   35
  crates/scanner/src/scanner.rs  12

The lifecycle removals are all validate_* / filter_rules_* /
has_active_rules_* / noncurrent_versions_expiration_limit_* tests that
build a local BucketLifecycleConfiguration and call a &self method
walking only that value. The scanner removals are pure duration
arithmetic (randomized_cycle_delay_for, initial_scanner_delay_for with an
explicit Some(secs), the bitrot-disabled early return of
scanner_clean_idle_max_interval) and background_heal_info_for_scan_complete
/ _for_scan_result field comparisons over locally built values.

Retained deliberately -- see the PR body for the full list and reasons:

  crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs  101 (all)
  crates/lifecycle/src/core.rs                                  44
  crates/scanner/src/scanner.rs                                 53

bucket_lifecycle_ops.rs keeps every marker: its test module caches a
process-wide `static STALE_MULTIPART_TEST_ENV: OnceLock<(Vec<PathBuf>,
Arc<ECStore>)>`, and its own reregister_env_local_disks helper documents
in-tree that sibling #[serial] tests reset and reshape the shared
local-disk registry for each other. That sharing is real, so the markers
stay.

No test was renamed, added, or deleted; no reserved migration-gate name
substring is affected; no .config/nextest.toml entry references any of
the 47 removed tests.
This commit is contained in:
Zhengchao An
2026-08-18 18:28:13 +08:00
committed by GitHub
parent a38743caf5
commit 9852e53b4c
2 changed files with 0 additions and 47 deletions
-35
View File
@@ -1199,7 +1199,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_rejects_zero_expiration_days() { async fn validate_rejects_zero_expiration_days() {
// S3 compatibility: Expiration.Days must be a positive integer (>= 1). AWS and // S3 compatibility: Expiration.Days must be a positive integer (>= 1). AWS and
// the ceph s3-tests `test_lifecycle_expiration_days0` case reject Days == 0 with // the ceph s3-tests `test_lifecycle_expiration_days0` case reject Days == 0 with
@@ -1233,7 +1232,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_rejects_negative_expiration_days() { async fn validate_rejects_negative_expiration_days() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -1263,7 +1261,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_accepts_positive_expiration_days() { async fn validate_accepts_positive_expiration_days() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -1290,7 +1287,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_accepts_one_day_boundary_values() { async fn validate_accepts_one_day_boundary_values() {
// Pin the exact >= 1 boundary: a value of 1 is the smallest legal positive // Pin the exact >= 1 boundary: a value of 1 is the smallest legal positive
// integer and must be accepted for every day-count field tightened for S3 // integer and must be accepted for every day-count field tightened for S3
@@ -1325,7 +1321,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn has_active_rules_accepts_zero_day_expiration() { async fn has_active_rules_accepts_zero_day_expiration() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -1350,7 +1345,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_rejects_zero_noncurrent_expiration_days() { async fn validate_rejects_zero_noncurrent_expiration_days() {
// S3 compatibility: NoncurrentVersionExpiration.NoncurrentDays must be a positive // S3 compatibility: NoncurrentVersionExpiration.NoncurrentDays must be a positive
// integer (>= 1); AWS rejects 0 with InvalidArgument. // integer (>= 1); AWS rejects 0 with InvalidArgument.
@@ -1382,7 +1376,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_rejects_negative_noncurrent_expiration_days() { async fn validate_rejects_negative_noncurrent_expiration_days() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -1412,7 +1405,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_accepts_abort_incomplete_multipart_upload_only_rule() { async fn validate_accepts_abort_incomplete_multipart_upload_only_rule() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -1438,7 +1430,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_rejects_zero_abort_incomplete_multipart_upload_days() { async fn validate_rejects_zero_abort_incomplete_multipart_upload_days() {
// S3 compatibility: AbortIncompleteMultipartUpload.DaysAfterInitiation must be a // S3 compatibility: AbortIncompleteMultipartUpload.DaysAfterInitiation must be a
// positive integer (>= 1); AWS rejects 0 with InvalidArgument. // positive integer (>= 1); AWS rejects 0 with InvalidArgument.
@@ -1469,7 +1460,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_rejects_missing_abort_incomplete_multipart_upload_days() { async fn validate_rejects_missing_abort_incomplete_multipart_upload_days() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -1495,7 +1485,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_rejects_negative_abort_incomplete_multipart_upload_days() { async fn validate_rejects_negative_abort_incomplete_multipart_upload_days() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -1556,7 +1545,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_rejects_non_midnight_expiration_date() { async fn validate_rejects_non_midnight_expiration_date() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -1638,7 +1626,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_accepts_multiple_rules_without_ids() { async fn validate_accepts_multiple_rules_without_ids() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -1682,7 +1669,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_rejects_rule_id_too_long() { async fn validate_rejects_rule_id_too_long() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -1709,7 +1695,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_rejects_duplicate_rule_ids() { async fn validate_rejects_duplicate_rule_ids() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -1752,7 +1737,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_rejects_transition_without_storage_class() { async fn validate_rejects_transition_without_storage_class() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -1780,7 +1764,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_rejects_transition_without_date_or_days() { async fn validate_rejects_transition_without_date_or_days() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -1808,7 +1791,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_rejects_noncurrent_transition_without_days() { async fn validate_rejects_noncurrent_transition_without_days() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -2365,7 +2347,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn noncurrent_versions_expiration_limit_returns_configured_limits() { async fn noncurrent_versions_expiration_limit_returns_configured_limits() {
let lc = Arc::new(BucketLifecycleConfiguration { let lc = Arc::new(BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -2456,7 +2437,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_rejects_invalid_status_case_sensitive() { async fn validate_rejects_invalid_status_case_sensitive() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -2483,7 +2463,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn filter_rules_respects_filter_prefix() { async fn filter_rules_respects_filter_prefix() {
let filter = LifecycleRuleFilter { let filter = LifecycleRuleFilter {
prefix: Some("prefix".to_string()), prefix: Some("prefix".to_string()),
@@ -2528,7 +2507,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn filter_rules_respects_filter_and_prefix() { async fn filter_rules_respects_filter_and_prefix() {
let and = s3s::dto::LifecycleRuleAndOperator { let and = s3s::dto::LifecycleRuleAndOperator {
prefix: Some("prefix".to_string()), prefix: Some("prefix".to_string()),
@@ -2578,7 +2556,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn filter_rules_respects_filter_tag() { async fn filter_rules_respects_filter_tag() {
let filter = LifecycleRuleFilter { let filter = LifecycleRuleFilter {
tag: Some(s3s::dto::Tag { tag: Some(s3s::dto::Tag {
@@ -2632,7 +2609,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn filter_rules_respects_filter_and_tags() { async fn filter_rules_respects_filter_and_tags() {
let filter = LifecycleRuleFilter { let filter = LifecycleRuleFilter {
and: Some(s3s::dto::LifecycleRuleAndOperator { and: Some(s3s::dto::LifecycleRuleAndOperator {
@@ -3086,7 +3062,6 @@ mod tests {
// --- TASK-002 tests: Object Lock + ExpiredObjectDeleteMarker compatibility --- // --- TASK-002 tests: Object Lock + ExpiredObjectDeleteMarker compatibility ---
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_allows_expired_object_delete_marker_on_locked_bucket() { async fn validate_allows_expired_object_delete_marker_on_locked_bucket() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -3118,7 +3093,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_allows_expired_object_delete_marker_on_unlocked_bucket() { async fn validate_allows_expired_object_delete_marker_on_unlocked_bucket() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -3146,7 +3120,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_allows_non_delete_marker_expiration_on_locked_bucket() { async fn validate_allows_non_delete_marker_expiration_on_locked_bucket() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -3179,7 +3152,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_rejects_del_marker_expiration_on_locked_bucket() { async fn validate_rejects_del_marker_expiration_on_locked_bucket() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -3210,7 +3182,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_rejects_zero_day_del_marker_expiration_on_locked_bucket() { async fn validate_rejects_zero_day_del_marker_expiration_on_locked_bucket() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -3594,7 +3565,6 @@ mod tests {
// --- TASK-007 tests: Legacy Prefix/Filter conflict --- // --- TASK-007 tests: Legacy Prefix/Filter conflict ---
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_rejects_prefix_and_filter_both_present() { async fn validate_rejects_prefix_and_filter_both_present() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -3623,7 +3593,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_allows_prefix_without_filter() { async fn validate_allows_prefix_without_filter() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -3650,7 +3619,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_allows_filter_without_prefix() { async fn validate_allows_filter_without_prefix() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -3680,7 +3648,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_allows_empty_prefix_with_filter() { async fn validate_allows_empty_prefix_with_filter() {
// Empty prefix should be treated as "not set" // Empty prefix should be treated as "not set"
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
@@ -3713,7 +3680,6 @@ mod tests {
// --- TASK-004 tests: ExpiredObjectAllVersions --- // --- TASK-004 tests: ExpiredObjectAllVersions ---
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_rejects_expired_object_all_versions_on_locked_bucket() { async fn validate_rejects_expired_object_all_versions_on_locked_bucket() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
@@ -3745,7 +3711,6 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
#[serial]
async fn validate_allows_expired_object_all_versions_on_unlocked_bucket() { async fn validate_allows_expired_object_all_versions_on_unlocked_bucket() {
let lc = BucketLifecycleConfiguration { let lc = BucketLifecycleConfiguration {
expiry_updated_at: None, expiry_updated_at: None,
-12
View File
@@ -4574,7 +4574,6 @@ mod tests {
} }
#[test] #[test]
#[serial]
fn test_randomized_cycle_delay_keeps_configured_start_delay() { fn test_randomized_cycle_delay_keeps_configured_start_delay() {
// 120s with ±10% jitter should stay clearly above the historic 30s cap. // 120s with ±10% jitter should stay clearly above the historic 30s cap.
let delay = randomized_cycle_delay_for(Duration::from_secs(120)); let delay = randomized_cycle_delay_for(Duration::from_secs(120));
@@ -4593,7 +4592,6 @@ mod tests {
} }
#[test] #[test]
#[serial]
fn test_initial_scanner_delay_uses_configured_start_delay() { fn test_initial_scanner_delay_uses_configured_start_delay() {
let delay = initial_scanner_delay_for(Some(120)); let delay = initial_scanner_delay_for(Some(120));
assert!(delay >= Duration::from_secs(108)); assert!(delay >= Duration::from_secs(108));
@@ -4613,14 +4611,12 @@ mod tests {
} }
#[test] #[test]
#[serial]
fn test_initial_scanner_delay_skips_for_cold_usage_cache_with_buckets() { fn test_initial_scanner_delay_skips_for_cold_usage_cache_with_buckets() {
let delay = initial_scanner_delay_for_startup(Some(120), true, true, false); let delay = initial_scanner_delay_for_startup(Some(120), true, true, false);
assert_eq!(delay, Duration::ZERO); assert_eq!(delay, Duration::ZERO);
} }
#[test] #[test]
#[serial]
fn test_initial_scanner_delay_keeps_configured_delay_for_warm_usage_cache_no_replication() { fn test_initial_scanner_delay_keeps_configured_delay_for_warm_usage_cache_no_replication() {
let delay = initial_scanner_delay_for_startup(Some(120), false, true, false); let delay = initial_scanner_delay_for_startup(Some(120), false, true, false);
assert!(delay >= Duration::from_secs(108)); assert!(delay >= Duration::from_secs(108));
@@ -4628,14 +4624,12 @@ mod tests {
} }
#[test] #[test]
#[serial]
fn test_initial_scanner_delay_skips_for_cold_usage_cache_without_buckets() { fn test_initial_scanner_delay_skips_for_cold_usage_cache_without_buckets() {
let delay = initial_scanner_delay_for_startup(Some(120), true, false, false); let delay = initial_scanner_delay_for_startup(Some(120), true, false, false);
assert_eq!(delay, Duration::ZERO); assert_eq!(delay, Duration::ZERO);
} }
#[test] #[test]
#[serial]
fn test_initial_scanner_delay_skips_for_active_replication_warm_cache() { fn test_initial_scanner_delay_skips_for_active_replication_warm_cache() {
// Warm cache + active replication rules → skip startup delay so that FAILED-status objects // Warm cache + active replication rules → skip startup delay so that FAILED-status objects
// from a crash are healed on the first cycle, not after a 27-33 min sleep. // from a crash are healed on the first cycle, not after a 27-33 min sleep.
@@ -4644,7 +4638,6 @@ mod tests {
} }
#[test] #[test]
#[serial]
fn test_initial_scanner_delay_keeps_delay_for_replication_without_buckets() { fn test_initial_scanner_delay_keeps_delay_for_replication_without_buckets() {
// Active replication but no buckets → no objects to scan, keep normal delay. // Active replication but no buckets → no objects to scan, keep normal delay.
let delay = initial_scanner_delay_for_startup(Some(120), false, false, true); let delay = initial_scanner_delay_for_startup(Some(120), false, false, true);
@@ -7399,7 +7392,6 @@ mod tests {
} }
#[test] #[test]
#[serial]
fn clean_idle_cap_allows_policy_max_when_bitrot_is_disabled() { fn clean_idle_cap_allows_policy_max_when_bitrot_is_disabled() {
let config = ScannerRuntimeConfig { let config = ScannerRuntimeConfig {
bitrot_cycle: None, bitrot_cycle: None,
@@ -7515,7 +7507,6 @@ mod tests {
} }
#[test] #[test]
#[serial]
fn test_randomized_cycle_delay_handles_small_start_delay() { fn test_randomized_cycle_delay_handles_small_start_delay() {
// 0 is treated as minimum 1 second before jitter, with lower bound preserved. // 0 is treated as minimum 1 second before jitter, with lower bound preserved.
let delay = randomized_cycle_delay_for(Duration::from_secs(0)); let delay = randomized_cycle_delay_for(Duration::from_secs(0));
@@ -8174,7 +8165,6 @@ mod tests {
} }
#[test] #[test]
#[serial]
fn test_background_heal_info_for_scan_complete_marks_deep_idle() { fn test_background_heal_info_for_scan_complete_marks_deep_idle() {
let started_at = Utc::now(); let started_at = Utc::now();
let info = BackgroundHealInfo { let info = BackgroundHealInfo {
@@ -8192,7 +8182,6 @@ mod tests {
} }
#[test] #[test]
#[serial]
fn test_background_heal_info_for_scan_complete_leaves_normal_scan_unchanged() { fn test_background_heal_info_for_scan_complete_leaves_normal_scan_unchanged() {
let info = BackgroundHealInfo { let info = BackgroundHealInfo {
bitrot_start_time: Some(Utc::now()), bitrot_start_time: Some(Utc::now()),
@@ -8204,7 +8193,6 @@ mod tests {
} }
#[test] #[test]
#[serial]
fn test_background_heal_info_for_failed_scan_preserves_deep_mode() { fn test_background_heal_info_for_failed_scan_preserves_deep_mode() {
let info = BackgroundHealInfo { let info = BackgroundHealInfo {
bitrot_start_time: Some(Utc::now()), bitrot_start_time: Some(Utc::now()),