mirror of
https://github.com/rustfs/rustfs.git
synced 2026-09-04 11:15:39 +00:00
test(ilm): activate ignored ILM integration tests via serial CI lane (#4682)
Implements ilm-1 from the ILM test-strategy plan: the 33 #[ignore]d ILM integration tests (14 in crates/scanner/tests/lifecycle_integration_test.rs, 19 in rustfs/src/app/lifecycle_transition_api_test.rs) never ran anywhere. This adds a dedicated serialized CI job and repairs the app-layer suite, activating 29 of them. - ci.yml: new test-ilm-integration-serial job running the two ILM test surfaces with 'cargo nextest run -j1 --run-ignored ignored-only'. The tests share process-global singletons and fixed ports (9002/9003); serial_test's #[serial] does not serialize across nextest's process-per-test boundary, so -j1 is the serialization mechanism. - app suite repair: the 19 app tests rotted after the InstanceContext migration (usecases resolve the store via AppContext; the test env never installed one, so every store-touching call failed with InternalError 'Not init'). Add a test-only install_test_app_context helper behind the sanctioned context/runtime_sources boundaries and switch the tests from without_context() to from_global(). All 19 now pass. - delete test_lifecycle_transition_basic (+3 orphaned helpers): required an external MinIO at localhost:9000 and slept 1200s; superseded by the mock-tier tests in the same file. - fix a timing flake: poll free-version metadata removal instead of asserting a single read right after remote-object absence. - 3 scanner tests fail on main for product reasons (multipart restore UnexpectedEof; noncurrent transition/expiry after immediate compensation transition on versioned buckets); they keep #[ignore] with a backlog reference and are excluded from the lane by name. Lane: 29 tests, ~43s test time, green twice locally. Refs rustfs/backlog#1148 (ilm-1), rustfs/backlog#1155.
This commit is contained in:
@@ -183,6 +183,45 @@ jobs:
|
|||||||
- name: Run rebalance/decommission migration proofs
|
- name: Run rebalance/decommission migration proofs
|
||||||
run: ./scripts/check_migration_gate_count.sh
|
run: ./scripts/check_migration_gate_count.sh
|
||||||
|
|
||||||
|
# Dedicated serial lane for the ILM / lifecycle integration tests. These tests
|
||||||
|
# drive the object layer through process-global singletons (the GLOBAL_ENV
|
||||||
|
# ECStore, the global tier-config manager, background-expiry workers) and bind
|
||||||
|
# fixed ports (9002 for the scanner suite, 9003 for the app suite), so they are
|
||||||
|
# marked #[ignore] to keep them out of the default parallel `cargo nextest run
|
||||||
|
# --all` pass. Run them here explicitly with `--run-ignored ignored-only` and
|
||||||
|
# `-j1` so no two of them share global state or race for a port at once.
|
||||||
|
# serial_test's #[serial] does NOT serialize across nextest's process-per-test
|
||||||
|
# boundary (see .config/nextest.toml); `-j1` is what actually serializes them.
|
||||||
|
# See rustfs/backlog#1148 (ilm-1) and #1155.
|
||||||
|
test-ilm-integration-serial:
|
||||||
|
name: ILM Integration (serial)
|
||||||
|
if: github.event_name != 'pull_request' || github.event.action != 'closed'
|
||||||
|
runs-on: sm-standard-4
|
||||||
|
timeout-minutes: 45
|
||||||
|
env:
|
||||||
|
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||||
|
|
||||||
|
- name: Setup Rust environment
|
||||||
|
uses: ./.github/actions/setup
|
||||||
|
with:
|
||||||
|
rust-version: stable
|
||||||
|
cache-shared-key: ci-ilm-serial
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
cache-save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||||
|
|
||||||
|
# Three scanner tests fail on main independently of this lane (restore of
|
||||||
|
# a transitioned multipart object, noncurrent transition/expiry after an
|
||||||
|
# immediate compensation transition); they keep #[ignore] with a backlog
|
||||||
|
# reference and are excluded here by name until fixed (rustfs/backlog#1148).
|
||||||
|
- name: Run ignored ILM integration tests serially
|
||||||
|
run: |
|
||||||
|
cargo nextest run -j1 --run-ignored ignored-only \
|
||||||
|
-p rustfs-scanner -p rustfs \
|
||||||
|
-E '(binary(lifecycle_integration_test) or (package(rustfs) and test(lifecycle_transition_api_test))) and not (test(test_transition_and_restore_flows) or test(test_noncurrent_expiry_still_works_after_immediate_compensation_transition) or test(test_noncurrent_transition_still_works_after_immediate_compensation_transition))'
|
||||||
|
|
||||||
test-and-lint-rio-v2:
|
test-and-lint-rio-v2:
|
||||||
name: Test and Lint (rio-v2)
|
name: Test and Lint (rio-v2)
|
||||||
if: github.event_name != 'pull_request' || github.event.action != 'closed'
|
if: github.event_name != 'pull_request' || github.event.action != 'closed'
|
||||||
|
|||||||
@@ -320,11 +320,6 @@ async fn set_bucket_lifecycle_delmarker_expiration(bucket_name: &str, days: i64)
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
async fn set_bucket_lifecycle_transition(bucket_name: &str) -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
set_bucket_lifecycle_transition_with_tier(bucket_name, "COLDTIER44").await
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
async fn set_bucket_lifecycle_transition_with_tier(
|
async fn set_bucket_lifecycle_transition_with_tier(
|
||||||
bucket_name: &str,
|
bucket_name: &str,
|
||||||
@@ -364,67 +359,6 @@ async fn set_bucket_lifecycle_transition_with_tier(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test helper: Create a test tier
|
|
||||||
#[allow(dead_code)]
|
|
||||||
async fn create_test_tier(server: u32) {
|
|
||||||
let args = TierConfig {
|
|
||||||
version: "v1".to_string(),
|
|
||||||
tier_type: TierType::MinIO,
|
|
||||||
name: "COLDTIER44".to_string(),
|
|
||||||
s3: None,
|
|
||||||
aliyun: None,
|
|
||||||
tencent: None,
|
|
||||||
huaweicloud: None,
|
|
||||||
azure: None,
|
|
||||||
gcs: None,
|
|
||||||
r2: None,
|
|
||||||
rustfs: None,
|
|
||||||
minio: if server == 1 {
|
|
||||||
Some(TierMinIO {
|
|
||||||
access_key: "minioadmin".to_string(),
|
|
||||||
secret_key: "minioadmin".to_string(),
|
|
||||||
bucket: "hello".to_string(),
|
|
||||||
endpoint: "http://127.0.0.1:9000".to_string(),
|
|
||||||
prefix: format!("mypre{}/", uuid::Uuid::new_v4()),
|
|
||||||
region: "".to_string(),
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
} else if server == 2 {
|
|
||||||
let test_compatible_server = std::env::var("TEST_MINIO_SERVER").unwrap_or_else(|_| "localhost:9000".to_string());
|
|
||||||
Some(TierMinIO {
|
|
||||||
access_key: "minioadmin".to_string(),
|
|
||||||
secret_key: "minioadmin".to_string(),
|
|
||||||
bucket: "mblock2".to_string(),
|
|
||||||
endpoint: format!("http://{}", test_compatible_server),
|
|
||||||
prefix: format!("mypre{}/", uuid::Uuid::new_v4()),
|
|
||||||
region: "".to_string(),
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Some(TierMinIO {
|
|
||||||
access_key: "minioadmin".to_string(),
|
|
||||||
secret_key: "minioadmin".to_string(),
|
|
||||||
bucket: "mblock2".to_string(),
|
|
||||||
endpoint: "http://127.0.0.1:9020".to_string(),
|
|
||||||
prefix: format!("mypre{}/", uuid::Uuid::new_v4()),
|
|
||||||
region: "".to_string(),
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
};
|
|
||||||
let tier_config_mgr_handle = get_global_tier_config_mgr();
|
|
||||||
let mut tier_config_mgr = tier_config_mgr_handle.write().await;
|
|
||||||
if let Err(err) = tier_config_mgr.add(args, false).await {
|
|
||||||
println!("tier_config_mgr add failed, e: {err:?}");
|
|
||||||
panic!("tier add failed. {err}");
|
|
||||||
}
|
|
||||||
if let Err(e) = tier_config_mgr.save().await {
|
|
||||||
println!("tier_config_mgr save failed, e: {e:?}");
|
|
||||||
panic!("tier save failed");
|
|
||||||
}
|
|
||||||
println!("Created test tier: COLDTIER44");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test helper: Check if object exists
|
/// Test helper: Check if object exists
|
||||||
async fn object_exists(ecstore: &Arc<ECStore>, bucket: &str, object: &str) -> bool {
|
async fn object_exists(ecstore: &Arc<ECStore>, bucket: &str, object: &str) -> bool {
|
||||||
match (**ecstore).get_object_info(bucket, object, &ObjectOptions::default()).await {
|
match (**ecstore).get_object_info(bucket, object, &ObjectOptions::default()).await {
|
||||||
@@ -445,18 +379,6 @@ async fn object_is_delete_marker(ecstore: &Arc<ECStore>, bucket: &str, object: &
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test helper: Check if object exists
|
|
||||||
#[allow(dead_code)]
|
|
||||||
async fn object_is_transitioned(ecstore: &Arc<ECStore>, bucket: &str, object: &str) -> bool {
|
|
||||||
if let Ok(oi) = (**ecstore).get_object_info(bucket, object, &ObjectOptions::default()).await {
|
|
||||||
println!("oi: {oi:?}");
|
|
||||||
!oi.transitioned_object.status.is_empty()
|
|
||||||
} else {
|
|
||||||
println!("object_is_transitioned is error");
|
|
||||||
panic!("object_is_transitioned is error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
async fn wait_for_object_absence(ecstore: &Arc<ECStore>, bucket: &str, object: &str, timeout: Duration) -> bool {
|
async fn wait_for_object_absence(ecstore: &Arc<ECStore>, bucket: &str, object: &str, timeout: Duration) -> bool {
|
||||||
let deadline = tokio::time::Instant::now() + timeout;
|
let deadline = tokio::time::Instant::now() + timeout;
|
||||||
@@ -517,6 +439,24 @@ async fn free_version_count(disk_path: &Path, bucket: &str, object: &str) -> usi
|
|||||||
.len()
|
.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The free-version metadata removal lands asynchronously after the remote
|
||||||
|
/// object disappears, so poll instead of asserting a single read.
|
||||||
|
async fn wait_for_free_version_absence(disk_path: &Path, bucket: &str, object: &str, timeout: Duration) -> bool {
|
||||||
|
let deadline = tokio::time::Instant::now() + timeout;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if free_version_count(disk_path, bucket, object).await == 0 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if tokio::time::Instant::now() >= deadline {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
tokio::time::sleep(Duration::from_millis(50)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn object_version_count(ecstore: &Arc<ECStore>, bucket: &str, object: &str) -> usize {
|
async fn object_version_count(ecstore: &Arc<ECStore>, bucket: &str, object: &str) -> usize {
|
||||||
let mut marker = None;
|
let mut marker = None;
|
||||||
let mut version_marker = None;
|
let mut version_marker = None;
|
||||||
@@ -829,98 +769,7 @@ mod serial_tests {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore]
|
#[ignore = "FAILING on main: excluded from the serial ILM lane pending a fix, see rustfs/backlog#1148 (ilm-1 partial)"]
|
||||||
async fn test_lifecycle_transition_basic() {
|
|
||||||
let (_disk_paths, ecstore) = setup_test_env().await;
|
|
||||||
|
|
||||||
create_test_tier(2).await;
|
|
||||||
|
|
||||||
// Create test bucket and object
|
|
||||||
let suffix = uuid::Uuid::new_v4().simple().to_string();
|
|
||||||
let bucket_name = format!("test-lc-transition-{}", &suffix[..8]);
|
|
||||||
let object_name = "test/object.txt"; // Match the lifecycle rule prefix "test/"
|
|
||||||
let test_data = b"Hello, this is test data for lifecycle expiry!";
|
|
||||||
|
|
||||||
create_test_lock_bucket(&ecstore, bucket_name.as_str()).await;
|
|
||||||
upload_test_object(
|
|
||||||
&ecstore,
|
|
||||||
bucket_name.as_str(),
|
|
||||||
object_name,
|
|
||||||
b"Hello, this is test data for lifecycle expiry 1111-11111111-1111 !",
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
//create_test_bucket(&ecstore, bucket_name.as_str()).await;
|
|
||||||
upload_test_object(&ecstore, bucket_name.as_str(), object_name, test_data).await;
|
|
||||||
|
|
||||||
// Verify object exists initially
|
|
||||||
assert!(object_exists(&ecstore, bucket_name.as_str(), object_name).await);
|
|
||||||
println!("✅ Object exists before lifecycle processing");
|
|
||||||
|
|
||||||
// Set lifecycle configuration with very short expiry (0 days = immediate expiry)
|
|
||||||
set_bucket_lifecycle_transition(bucket_name.as_str())
|
|
||||||
.await
|
|
||||||
.expect("Failed to set lifecycle configuration");
|
|
||||||
println!("✅ Lifecycle configuration set for bucket: {bucket_name}");
|
|
||||||
|
|
||||||
// Verify lifecycle configuration was set
|
|
||||||
match get_bucket_metadata(bucket_name.as_str()).await {
|
|
||||||
Ok(bucket_meta) => {
|
|
||||||
assert!(bucket_meta.lifecycle_config.is_some());
|
|
||||||
println!("✅ Bucket metadata retrieved successfully");
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
println!("❌ Error retrieving bucket metadata: {e:?}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let ctx = CancellationToken::new();
|
|
||||||
|
|
||||||
// Start scanner
|
|
||||||
init_data_scanner(ctx.clone(), ecstore.clone()).await;
|
|
||||||
println!("✅ Scanner started");
|
|
||||||
|
|
||||||
// Wait for scanner to process lifecycle rules
|
|
||||||
tokio::time::sleep(Duration::from_secs(1200)).await;
|
|
||||||
|
|
||||||
// Check if object has been expired (deleted)
|
|
||||||
let check_result = object_is_transitioned(&ecstore, &bucket_name, object_name).await;
|
|
||||||
println!("Object exists after lifecycle processing: {check_result}");
|
|
||||||
|
|
||||||
if check_result {
|
|
||||||
println!("✅ Object was transitioned by lifecycle processing");
|
|
||||||
// Let's try to get object info to see its details
|
|
||||||
match ecstore
|
|
||||||
.get_object_info(bucket_name.as_str(), object_name, &ObjectOptions::default())
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(obj_info) => {
|
|
||||||
println!(
|
|
||||||
"Object info: name={}, size={}, mod_time={:?}",
|
|
||||||
obj_info.name, obj_info.size, obj_info.mod_time
|
|
||||||
);
|
|
||||||
println!("Object info: transitioned_object={:?}", obj_info.transitioned_object);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
println!("Error getting object info: {e:?}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
println!("❌ Object was not transitioned by lifecycle processing");
|
|
||||||
}
|
|
||||||
|
|
||||||
assert!(check_result);
|
|
||||||
println!("✅ Object successfully transitioned");
|
|
||||||
|
|
||||||
// Stop scanner
|
|
||||||
ctx.cancel();
|
|
||||||
println!("✅ Scanner stopped");
|
|
||||||
|
|
||||||
println!("Lifecycle transition basic test completed");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
|
||||||
#[serial]
|
|
||||||
#[ignore = "requires isolated global object layer state"]
|
|
||||||
async fn test_transition_and_restore_flows() {
|
async fn test_transition_and_restore_flows() {
|
||||||
let (_disk_paths, ecstore) = setup_test_env().await;
|
let (_disk_paths, ecstore) = setup_test_env().await;
|
||||||
|
|
||||||
@@ -1229,7 +1078,7 @@ mod serial_tests {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn test_scanner_enqueues_free_version_cleanup_for_stale_transitioned_object() {
|
async fn test_scanner_enqueues_free_version_cleanup_for_stale_transitioned_object() {
|
||||||
let (disk_paths, ecstore) = setup_isolated_test_env(false).await;
|
let (disk_paths, ecstore) = setup_isolated_test_env(false).await;
|
||||||
|
|
||||||
@@ -1276,9 +1125,8 @@ mod serial_tests {
|
|||||||
wait_for_remote_absence(&backend, &stale_remote_object, TRANSITION_WAIT_TIMEOUT).await,
|
wait_for_remote_absence(&backend, &stale_remote_object, TRANSITION_WAIT_TIMEOUT).await,
|
||||||
"scanner should enqueue stale free-version cleanup for the transitioned remote object"
|
"scanner should enqueue stale free-version cleanup for the transitioned remote object"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert!(
|
||||||
free_version_count(&disk_paths[0], bucket_name.as_str(), object_name).await,
|
wait_for_free_version_absence(&disk_paths[0], bucket_name.as_str(), object_name, TRANSITION_WAIT_TIMEOUT).await,
|
||||||
0,
|
|
||||||
"free-version metadata should be removed after scanner-triggered cleanup"
|
"free-version metadata should be removed after scanner-triggered cleanup"
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
@@ -1289,7 +1137,7 @@ mod serial_tests {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn test_scanner_cleanup_still_works_after_immediate_compensation_transition() {
|
async fn test_scanner_cleanup_still_works_after_immediate_compensation_transition() {
|
||||||
let (disk_paths, ecstore) = setup_isolated_test_env(false).await;
|
let (disk_paths, ecstore) = setup_isolated_test_env(false).await;
|
||||||
|
|
||||||
@@ -1337,16 +1185,15 @@ mod serial_tests {
|
|||||||
wait_for_remote_absence(&backend, &stale_remote_object, TRANSITION_WAIT_TIMEOUT).await,
|
wait_for_remote_absence(&backend, &stale_remote_object, TRANSITION_WAIT_TIMEOUT).await,
|
||||||
"scanner should clean stale remote object even after immediate compensation transitioned it"
|
"scanner should clean stale remote object even after immediate compensation transitioned it"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert!(
|
||||||
free_version_count(&disk_paths[0], bucket_name.as_str(), object_name).await,
|
wait_for_free_version_absence(&disk_paths[0], bucket_name.as_str(), object_name, TRANSITION_WAIT_TIMEOUT).await,
|
||||||
0,
|
|
||||||
"free-version metadata should be removed after scanner cleanup"
|
"free-version metadata should be removed after scanner cleanup"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn test_existing_object_backfill_is_idempotent_after_immediate_compensation_transition() {
|
async fn test_existing_object_backfill_is_idempotent_after_immediate_compensation_transition() {
|
||||||
let (_disk_paths, ecstore) = setup_isolated_test_env(false).await;
|
let (_disk_paths, ecstore) = setup_isolated_test_env(false).await;
|
||||||
|
|
||||||
@@ -1389,7 +1236,7 @@ mod serial_tests {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "FAILING on main: excluded from the serial ILM lane pending a fix, see rustfs/backlog#1148 (ilm-1 partial)"]
|
||||||
async fn test_noncurrent_expiry_still_works_after_immediate_compensation_transition() {
|
async fn test_noncurrent_expiry_still_works_after_immediate_compensation_transition() {
|
||||||
let (disk_paths, ecstore) = setup_isolated_test_env(true).await;
|
let (disk_paths, ecstore) = setup_isolated_test_env(true).await;
|
||||||
|
|
||||||
@@ -1473,7 +1320,7 @@ mod serial_tests {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "FAILING on main: excluded from the serial ILM lane pending a fix, see rustfs/backlog#1148 (ilm-1 partial)"]
|
||||||
async fn test_noncurrent_transition_still_works_after_immediate_compensation_transition() {
|
async fn test_noncurrent_transition_still_works_after_immediate_compensation_transition() {
|
||||||
let (disk_paths, ecstore) = setup_isolated_test_env(true).await;
|
let (disk_paths, ecstore) = setup_isolated_test_env(true).await;
|
||||||
|
|
||||||
@@ -1556,7 +1403,7 @@ mod serial_tests {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn test_modeled_versioned_delete_creates_delete_marker_after_immediate_compensation_transition() {
|
async fn test_modeled_versioned_delete_creates_delete_marker_after_immediate_compensation_transition() {
|
||||||
let (_disk_paths, ecstore) = setup_isolated_test_env(true).await;
|
let (_disk_paths, ecstore) = setup_isolated_test_env(true).await;
|
||||||
|
|
||||||
@@ -1604,7 +1451,7 @@ mod serial_tests {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn test_modeled_delete_marker_cleanup_after_immediate_compensation_transition() {
|
async fn test_modeled_delete_marker_cleanup_after_immediate_compensation_transition() {
|
||||||
let (disk_paths, ecstore) = setup_isolated_test_env(true).await;
|
let (disk_paths, ecstore) = setup_isolated_test_env(true).await;
|
||||||
|
|
||||||
@@ -1681,7 +1528,7 @@ mod serial_tests {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn test_scanner_expires_zero_day_current_version() {
|
async fn test_scanner_expires_zero_day_current_version() {
|
||||||
let (disk_paths, ecstore) = setup_isolated_test_env(false).await;
|
let (disk_paths, ecstore) = setup_isolated_test_env(false).await;
|
||||||
|
|
||||||
@@ -1708,7 +1555,7 @@ mod serial_tests {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn test_put_object_immediately_enqueues_zero_day_current_expiry() {
|
async fn test_put_object_immediately_enqueues_zero_day_current_expiry() {
|
||||||
let (_disk_paths, ecstore) = setup_isolated_test_env(true).await;
|
let (_disk_paths, ecstore) = setup_isolated_test_env(true).await;
|
||||||
|
|
||||||
@@ -1746,7 +1593,7 @@ mod serial_tests {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn test_scanner_expires_zero_day_noncurrent_version() {
|
async fn test_scanner_expires_zero_day_noncurrent_version() {
|
||||||
let (disk_paths, ecstore) = setup_isolated_test_env(false).await;
|
let (disk_paths, ecstore) = setup_isolated_test_env(false).await;
|
||||||
|
|
||||||
@@ -1813,7 +1660,7 @@ mod serial_tests {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn test_put_object_immediately_enqueues_zero_day_noncurrent_expiry() {
|
async fn test_put_object_immediately_enqueues_zero_day_noncurrent_expiry() {
|
||||||
let (_disk_paths, ecstore) = setup_isolated_test_env(true).await;
|
let (_disk_paths, ecstore) = setup_isolated_test_env(true).await;
|
||||||
|
|
||||||
@@ -1898,7 +1745,7 @@ mod serial_tests {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn test_background_scanner_expires_zero_day_current_version_for_exact_key_prefix() {
|
async fn test_background_scanner_expires_zero_day_current_version_for_exact_key_prefix() {
|
||||||
let (_disk_paths, ecstore) = setup_isolated_test_env(true).await;
|
let (_disk_paths, ecstore) = setup_isolated_test_env(true).await;
|
||||||
|
|
||||||
|
|||||||
@@ -369,3 +369,17 @@ pub fn publish_global_app_context(context: Arc<AppContext>) -> Arc<AppContext> {
|
|||||||
pub fn get_global_app_context() -> Option<Arc<AppContext>> {
|
pub fn get_global_app_context() -> Option<Arc<AppContext>> {
|
||||||
APP_CONTEXT_SINGLETON.get().cloned()
|
APP_CONTEXT_SINGLETON.get().cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Test-only: initialize IAM around the given store, build a
|
||||||
|
/// default-interface context, and publish it as the process-global context so
|
||||||
|
/// usecases constructed via `from_global()` resolve this store
|
||||||
|
/// (rustfs/backlog#1148 ilm-1).
|
||||||
|
#[cfg(test)]
|
||||||
|
pub async fn install_test_app_context(object_store: Arc<ECStore>) {
|
||||||
|
let iam = rustfs_iam::init_iam_sys(object_store.clone())
|
||||||
|
.await
|
||||||
|
.expect("init IAM system for test AppContext");
|
||||||
|
let kms = Arc::new(KmsServiceManager::new());
|
||||||
|
let context = AppContext::with_default_interfaces(object_store, iam, kms);
|
||||||
|
publish_global_app_context(Arc::new(context));
|
||||||
|
}
|
||||||
|
|||||||
@@ -137,6 +137,12 @@ async fn setup_test_env() -> (Vec<PathBuf>, Arc<ECStore>) {
|
|||||||
|
|
||||||
lifecycle::bucket_lifecycle_ops::init_background_expiry(ecstore.clone()).await;
|
lifecycle::bucket_lifecycle_ops::init_background_expiry(ecstore.clone()).await;
|
||||||
|
|
||||||
|
// The usecases resolve the object store through the ambient AppContext
|
||||||
|
// since the backlog#1052 InstanceContext migration; without one installed
|
||||||
|
// every store-touching usecase call fails with InternalError "Not init".
|
||||||
|
// Publish a default-interface context wrapping this test store.
|
||||||
|
crate::app::runtime_sources::install_test_app_context(ecstore.clone()).await;
|
||||||
|
|
||||||
let _ = GLOBAL_ENV.set((disk_paths.clone(), ecstore.clone()));
|
let _ = GLOBAL_ENV.set((disk_paths.clone(), ecstore.clone()));
|
||||||
|
|
||||||
(disk_paths, ecstore)
|
(disk_paths, ecstore)
|
||||||
@@ -538,11 +544,11 @@ async fn live_object_version_count(ecstore: &Arc<ECStore>, bucket: &str, object:
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn put_object_if_none_match_existing_object_returns_precondition_failed() {
|
async fn put_object_if_none_match_existing_object_returns_precondition_failed() {
|
||||||
let (_disk_paths, ecstore) = setup_test_env().await;
|
let (_disk_paths, ecstore) = setup_test_env().await;
|
||||||
let fs = FS::new();
|
let fs = FS::new();
|
||||||
let usecase = DefaultObjectUsecase::without_context();
|
let usecase = DefaultObjectUsecase::from_global();
|
||||||
|
|
||||||
let bucket = format!("test-put-if-none-match-{}", &Uuid::new_v4().simple().to_string()[..8]);
|
let bucket = format!("test-put-if-none-match-{}", &Uuid::new_v4().simple().to_string()[..8]);
|
||||||
let object = "test/object.txt";
|
let object = "test/object.txt";
|
||||||
@@ -591,10 +597,10 @@ async fn put_object_if_none_match_existing_object_returns_precondition_failed()
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn copy_object_if_none_match_existing_destination_returns_precondition_failed() {
|
async fn copy_object_if_none_match_existing_destination_returns_precondition_failed() {
|
||||||
let (_disk_paths, ecstore) = setup_test_env().await;
|
let (_disk_paths, ecstore) = setup_test_env().await;
|
||||||
let usecase = DefaultObjectUsecase::without_context();
|
let usecase = DefaultObjectUsecase::from_global();
|
||||||
|
|
||||||
let src_bucket = format!("test-copy-if-none-match-src-{}", &Uuid::new_v4().simple().to_string()[..8]);
|
let src_bucket = format!("test-copy-if-none-match-src-{}", &Uuid::new_v4().simple().to_string()[..8]);
|
||||||
let dst_bucket = format!("test-copy-if-none-match-dst-{}", &Uuid::new_v4().simple().to_string()[..8]);
|
let dst_bucket = format!("test-copy-if-none-match-dst-{}", &Uuid::new_v4().simple().to_string()[..8]);
|
||||||
@@ -640,11 +646,11 @@ async fn copy_object_if_none_match_existing_destination_returns_precondition_fai
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn copy_object_allows_new_version_for_locked_destination_but_blocks_explicit_overwrite() {
|
async fn copy_object_allows_new_version_for_locked_destination_but_blocks_explicit_overwrite() {
|
||||||
let (_disk_paths, ecstore) = setup_test_env().await;
|
let (_disk_paths, ecstore) = setup_test_env().await;
|
||||||
let fs = FS::new();
|
let fs = FS::new();
|
||||||
let usecase = DefaultObjectUsecase::without_context();
|
let usecase = DefaultObjectUsecase::from_global();
|
||||||
|
|
||||||
let bucket = format!("test-copy-object-lock-{}", &Uuid::new_v4().simple().to_string()[..8]);
|
let bucket = format!("test-copy-object-lock-{}", &Uuid::new_v4().simple().to_string()[..8]);
|
||||||
let src_object = "test/source.txt";
|
let src_object = "test/source.txt";
|
||||||
@@ -728,7 +734,7 @@ async fn copy_object_allows_new_version_for_locked_destination_but_blocks_explic
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn concurrent_reverse_copy_object_does_not_deadlock_with_reader_locks() {
|
async fn concurrent_reverse_copy_object_does_not_deadlock_with_reader_locks() {
|
||||||
temp_env::async_with_vars([(ENV_OBJECT_LOCK_OPTIMIZATION_ENABLE, Some("false"))], async {
|
temp_env::async_with_vars([(ENV_OBJECT_LOCK_OPTIMIZATION_ENABLE, Some("false"))], async {
|
||||||
let (_disk_paths, ecstore) = setup_test_env().await;
|
let (_disk_paths, ecstore) = setup_test_env().await;
|
||||||
@@ -768,13 +774,13 @@ async fn concurrent_reverse_copy_object_does_not_deadlock_with_reader_locks() {
|
|||||||
let start_a = start.clone();
|
let start_a = start.clone();
|
||||||
let a_to_b = tokio::spawn(async move {
|
let a_to_b = tokio::spawn(async move {
|
||||||
start_a.wait().await;
|
start_a.wait().await;
|
||||||
let usecase = DefaultObjectUsecase::without_context();
|
let usecase = DefaultObjectUsecase::from_global();
|
||||||
Box::pin(usecase.execute_copy_object(build_request(a_to_b_input, Method::PUT))).await
|
Box::pin(usecase.execute_copy_object(build_request(a_to_b_input, Method::PUT))).await
|
||||||
});
|
});
|
||||||
let start_b = start.clone();
|
let start_b = start.clone();
|
||||||
let b_to_a = tokio::spawn(async move {
|
let b_to_a = tokio::spawn(async move {
|
||||||
start_b.wait().await;
|
start_b.wait().await;
|
||||||
let usecase = DefaultObjectUsecase::without_context();
|
let usecase = DefaultObjectUsecase::from_global();
|
||||||
Box::pin(usecase.execute_copy_object(build_request(b_to_a_input, Method::PUT))).await
|
Box::pin(usecase.execute_copy_object(build_request(b_to_a_input, Method::PUT))).await
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -809,11 +815,11 @@ async fn concurrent_reverse_copy_object_does_not_deadlock_with_reader_locks() {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn put_and_copy_object_transition_immediately_via_usecases() {
|
async fn put_and_copy_object_transition_immediately_via_usecases() {
|
||||||
let (_disk_paths, ecstore) = setup_test_env().await;
|
let (_disk_paths, ecstore) = setup_test_env().await;
|
||||||
let fs = FS::new();
|
let fs = FS::new();
|
||||||
let usecase = DefaultObjectUsecase::without_context();
|
let usecase = DefaultObjectUsecase::from_global();
|
||||||
|
|
||||||
let tier_name = format!("COLDTIER{}", &Uuid::new_v4().simple().to_string()[..8]).to_uppercase();
|
let tier_name = format!("COLDTIER{}", &Uuid::new_v4().simple().to_string()[..8]).to_uppercase();
|
||||||
let backend = register_mock_tier(&tier_name).await;
|
let backend = register_mock_tier(&tier_name).await;
|
||||||
@@ -886,10 +892,10 @@ async fn put_and_copy_object_transition_immediately_via_usecases() {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn complete_multipart_upload_transitions_immediately_via_usecase() {
|
async fn complete_multipart_upload_transitions_immediately_via_usecase() {
|
||||||
let (_disk_paths, ecstore) = setup_test_env().await;
|
let (_disk_paths, ecstore) = setup_test_env().await;
|
||||||
let usecase = DefaultMultipartUsecase::without_context();
|
let usecase = DefaultMultipartUsecase::from_global();
|
||||||
|
|
||||||
let tier_name = format!("COLDTIER{}", &Uuid::new_v4().simple().to_string()[..8]).to_uppercase();
|
let tier_name = format!("COLDTIER{}", &Uuid::new_v4().simple().to_string()[..8]).to_uppercase();
|
||||||
let backend = register_mock_tier(&tier_name).await;
|
let backend = register_mock_tier(&tier_name).await;
|
||||||
@@ -943,7 +949,7 @@ async fn complete_multipart_upload_transitions_immediately_via_usecase() {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn get_transitioned_object_uses_remote_codec_fallback_path() {
|
async fn get_transitioned_object_uses_remote_codec_fallback_path() {
|
||||||
with_get_codec_streaming_remote_probe_env(|| async {
|
with_get_codec_streaming_remote_probe_env(|| async {
|
||||||
let (_disk_paths, ecstore) = setup_test_env().await;
|
let (_disk_paths, ecstore) = setup_test_env().await;
|
||||||
@@ -1003,10 +1009,10 @@ async fn get_transitioned_object_uses_remote_codec_fallback_path() {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn delete_transitioned_object_removes_remote_tier_copy_via_usecase() {
|
async fn delete_transitioned_object_removes_remote_tier_copy_via_usecase() {
|
||||||
let (_disk_paths, ecstore) = setup_test_env().await;
|
let (_disk_paths, ecstore) = setup_test_env().await;
|
||||||
let usecase = DefaultObjectUsecase::without_context();
|
let usecase = DefaultObjectUsecase::from_global();
|
||||||
|
|
||||||
let tier_name = format!("COLDTIER{}", &Uuid::new_v4().simple().to_string()[..8]).to_uppercase();
|
let tier_name = format!("COLDTIER{}", &Uuid::new_v4().simple().to_string()[..8]).to_uppercase();
|
||||||
let backend = register_mock_tier(&tier_name).await;
|
let backend = register_mock_tier(&tier_name).await;
|
||||||
@@ -1059,7 +1065,7 @@ async fn delete_transitioned_object_removes_remote_tier_copy_via_usecase() {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn lifecycle_transition_marks_dirty_disks_for_capacity_manager() {
|
async fn lifecycle_transition_marks_dirty_disks_for_capacity_manager() {
|
||||||
let (disk_paths, ecstore) = setup_test_env().await;
|
let (disk_paths, ecstore) = setup_test_env().await;
|
||||||
let manager = create_isolated_manager(HybridStrategyConfig::default());
|
let manager = create_isolated_manager(HybridStrategyConfig::default());
|
||||||
@@ -1102,7 +1108,7 @@ async fn lifecycle_transition_marks_dirty_disks_for_capacity_manager() {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn immediate_transition_timeout_eventually_completes_via_compensation() {
|
async fn immediate_transition_timeout_eventually_completes_via_compensation() {
|
||||||
let (_disk_paths, ecstore) = setup_test_env().await;
|
let (_disk_paths, ecstore) = setup_test_env().await;
|
||||||
let tier_name = format!("COLDTIER{}", &Uuid::new_v4().simple().to_string()[..8]).to_uppercase();
|
let tier_name = format!("COLDTIER{}", &Uuid::new_v4().simple().to_string()[..8]).to_uppercase();
|
||||||
@@ -1133,10 +1139,10 @@ async fn immediate_transition_timeout_eventually_completes_via_compensation() {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn compensation_driven_copy_still_completes_transition() {
|
async fn compensation_driven_copy_still_completes_transition() {
|
||||||
let (_disk_paths, ecstore) = setup_test_env().await;
|
let (_disk_paths, ecstore) = setup_test_env().await;
|
||||||
let usecase = DefaultObjectUsecase::without_context();
|
let usecase = DefaultObjectUsecase::from_global();
|
||||||
|
|
||||||
let tier_name = format!("COLDTIER{}", &Uuid::new_v4().simple().to_string()[..8]).to_uppercase();
|
let tier_name = format!("COLDTIER{}", &Uuid::new_v4().simple().to_string()[..8]).to_uppercase();
|
||||||
let backend = register_mock_tier(&tier_name).await;
|
let backend = register_mock_tier(&tier_name).await;
|
||||||
@@ -1183,10 +1189,10 @@ async fn compensation_driven_copy_still_completes_transition() {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn compensation_driven_complete_multipart_upload_still_transitions() {
|
async fn compensation_driven_complete_multipart_upload_still_transitions() {
|
||||||
let (_disk_paths, ecstore) = setup_test_env().await;
|
let (_disk_paths, ecstore) = setup_test_env().await;
|
||||||
let usecase = DefaultMultipartUsecase::without_context();
|
let usecase = DefaultMultipartUsecase::from_global();
|
||||||
|
|
||||||
let tier_name = format!("COLDTIER{}", &Uuid::new_v4().simple().to_string()[..8]).to_uppercase();
|
let tier_name = format!("COLDTIER{}", &Uuid::new_v4().simple().to_string()[..8]).to_uppercase();
|
||||||
let backend = register_mock_tier(&tier_name).await;
|
let backend = register_mock_tier(&tier_name).await;
|
||||||
@@ -1243,10 +1249,10 @@ async fn compensation_driven_complete_multipart_upload_still_transitions() {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn compensation_driven_transition_still_cleans_remote_tier_on_delete() {
|
async fn compensation_driven_transition_still_cleans_remote_tier_on_delete() {
|
||||||
let (_disk_paths, ecstore) = setup_test_env().await;
|
let (_disk_paths, ecstore) = setup_test_env().await;
|
||||||
let usecase = DefaultObjectUsecase::without_context();
|
let usecase = DefaultObjectUsecase::from_global();
|
||||||
|
|
||||||
let tier_name = format!("COLDTIER{}", &Uuid::new_v4().simple().to_string()[..8]).to_uppercase();
|
let tier_name = format!("COLDTIER{}", &Uuid::new_v4().simple().to_string()[..8]).to_uppercase();
|
||||||
let backend = register_mock_tier(&tier_name).await;
|
let backend = register_mock_tier(&tier_name).await;
|
||||||
@@ -1299,10 +1305,10 @@ async fn compensation_driven_transition_still_cleans_remote_tier_on_delete() {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn compensation_driven_versioned_delete_still_creates_delete_marker() {
|
async fn compensation_driven_versioned_delete_still_creates_delete_marker() {
|
||||||
let (_disk_paths, ecstore) = setup_test_env().await;
|
let (_disk_paths, ecstore) = setup_test_env().await;
|
||||||
let usecase = DefaultObjectUsecase::without_context();
|
let usecase = DefaultObjectUsecase::from_global();
|
||||||
|
|
||||||
let tier_name = format!("COLDTIER{}", &Uuid::new_v4().simple().to_string()[..8]).to_uppercase();
|
let tier_name = format!("COLDTIER{}", &Uuid::new_v4().simple().to_string()[..8]).to_uppercase();
|
||||||
let backend = register_mock_tier(&tier_name).await;
|
let backend = register_mock_tier(&tier_name).await;
|
||||||
@@ -1353,11 +1359,11 @@ async fn compensation_driven_versioned_delete_still_creates_delete_marker() {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn compensation_driven_delete_marker_still_honors_lifecycle_cleanup() {
|
async fn compensation_driven_delete_marker_still_honors_lifecycle_cleanup() {
|
||||||
let (_disk_paths, ecstore) = setup_test_env().await;
|
let (_disk_paths, ecstore) = setup_test_env().await;
|
||||||
let usecase = DefaultObjectUsecase::without_context();
|
let usecase = DefaultObjectUsecase::from_global();
|
||||||
let bucket_usecase = DefaultBucketUsecase::without_context();
|
let bucket_usecase = DefaultBucketUsecase::from_global();
|
||||||
|
|
||||||
let tier_name = format!("COLDTIER{}", &Uuid::new_v4().simple().to_string()[..8]).to_uppercase();
|
let tier_name = format!("COLDTIER{}", &Uuid::new_v4().simple().to_string()[..8]).to_uppercase();
|
||||||
let backend = register_mock_tier(&tier_name).await;
|
let backend = register_mock_tier(&tier_name).await;
|
||||||
@@ -1430,10 +1436,10 @@ async fn compensation_driven_delete_marker_still_honors_lifecycle_cleanup() {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn put_bucket_lifecycle_configuration_expires_existing_objects() {
|
async fn put_bucket_lifecycle_configuration_expires_existing_objects() {
|
||||||
let (_disk_paths, ecstore) = setup_test_env().await;
|
let (_disk_paths, ecstore) = setup_test_env().await;
|
||||||
let usecase = DefaultBucketUsecase::without_context();
|
let usecase = DefaultBucketUsecase::from_global();
|
||||||
|
|
||||||
let bucket = format!("test-api-expire-existing-{}", &Uuid::new_v4().simple().to_string()[..8]);
|
let bucket = format!("test-api-expire-existing-{}", &Uuid::new_v4().simple().to_string()[..8]);
|
||||||
let object = "test/existing.txt";
|
let object = "test/existing.txt";
|
||||||
@@ -1464,10 +1470,10 @@ async fn put_bucket_lifecycle_configuration_expires_existing_objects() {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn put_bucket_lifecycle_configuration_allows_expired_delete_marker_on_object_lock_bucket() {
|
async fn put_bucket_lifecycle_configuration_allows_expired_delete_marker_on_object_lock_bucket() {
|
||||||
let (_disk_paths, ecstore) = setup_test_env().await;
|
let (_disk_paths, ecstore) = setup_test_env().await;
|
||||||
let usecase = DefaultBucketUsecase::without_context();
|
let usecase = DefaultBucketUsecase::from_global();
|
||||||
|
|
||||||
let bucket = format!("test-lock-expired-del-marker-{}", &Uuid::new_v4().simple().to_string()[..8]);
|
let bucket = format!("test-lock-expired-del-marker-{}", &Uuid::new_v4().simple().to_string()[..8]);
|
||||||
create_test_bucket(&ecstore, bucket.as_str()).await;
|
create_test_bucket(&ecstore, bucket.as_str()).await;
|
||||||
@@ -1492,10 +1498,10 @@ async fn put_bucket_lifecycle_configuration_allows_expired_delete_marker_on_obje
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn put_bucket_lifecycle_configuration_rejects_del_marker_expiration_on_object_lock_bucket() {
|
async fn put_bucket_lifecycle_configuration_rejects_del_marker_expiration_on_object_lock_bucket() {
|
||||||
let (_disk_paths, ecstore) = setup_test_env().await;
|
let (_disk_paths, ecstore) = setup_test_env().await;
|
||||||
let usecase = DefaultBucketUsecase::without_context();
|
let usecase = DefaultBucketUsecase::from_global();
|
||||||
|
|
||||||
let bucket = format!("test-lock-del-marker-exp-{}", &Uuid::new_v4().simple().to_string()[..8]);
|
let bucket = format!("test-lock-del-marker-exp-{}", &Uuid::new_v4().simple().to_string()[..8]);
|
||||||
create_test_bucket(&ecstore, bucket.as_str()).await;
|
create_test_bucket(&ecstore, bucket.as_str()).await;
|
||||||
@@ -1528,10 +1534,10 @@ async fn put_bucket_lifecycle_configuration_rejects_del_marker_expiration_on_obj
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore = "requires isolated global object layer state"]
|
#[ignore = "global-state ILM integration test: runs serialized in the CI ILM Integration (serial) lane, see ci.yml test-ilm-integration-serial and rustfs/backlog#1148 (ilm-1)"]
|
||||||
async fn put_bucket_lifecycle_configuration_rejects_zero_day_del_marker_expiration_on_object_lock_bucket() {
|
async fn put_bucket_lifecycle_configuration_rejects_zero_day_del_marker_expiration_on_object_lock_bucket() {
|
||||||
let (_disk_paths, ecstore) = setup_test_env().await;
|
let (_disk_paths, ecstore) = setup_test_env().await;
|
||||||
let usecase = DefaultBucketUsecase::without_context();
|
let usecase = DefaultBucketUsecase::from_global();
|
||||||
|
|
||||||
let bucket = format!("test-lock-del-marker-exp0-{}", &Uuid::new_v4().simple().to_string()[..8]);
|
let bucket = format!("test-lock-del-marker-exp0-{}", &Uuid::new_v4().simple().to_string()[..8]);
|
||||||
create_test_bucket(&ecstore, bucket.as_str()).await;
|
create_test_bucket(&ecstore, bucket.as_str()).await;
|
||||||
|
|||||||
@@ -63,3 +63,9 @@ pub(crate) fn current_expiry_state_handle() -> Arc<RwLock<ExpiryState>> {
|
|||||||
pub(crate) fn current_tier_config_handle() -> Arc<RwLock<TierConfigMgr>> {
|
pub(crate) fn current_tier_config_handle() -> Arc<RwLock<TierConfigMgr>> {
|
||||||
root_runtime_sources::current_tier_config_handle().unwrap_or_else(TierConfigMgr::new)
|
root_runtime_sources::current_tier_config_handle().unwrap_or_else(TierConfigMgr::new)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Test-only: publish a default-interface `AppContext` around the given store
|
||||||
|
/// so usecases constructed via `from_global()` resolve this store
|
||||||
|
/// (rustfs/backlog#1148 ilm-1).
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) use crate::runtime_sources::install_test_app_context;
|
||||||
|
|||||||
@@ -55,6 +55,9 @@ pub(crate) fn set_test_outbound_tls_generation(generation: u64) {
|
|||||||
context::set_test_outbound_tls_generation(generation);
|
context::set_test_outbound_tls_generation(generation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) use context::install_test_app_context;
|
||||||
|
|
||||||
pub(crate) fn current_app_context() -> Option<Arc<AppContext>> {
|
pub(crate) fn current_app_context() -> Option<Arc<AppContext>> {
|
||||||
context::get_global_app_context()
|
context::get_global_app_context()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user