mirror of
https://github.com/rustfs/rustfs.git
synced 2026-10-12 23:52:45 +00:00
* fix: repair s3s footprint ratchet violation, clippy warnings, and stack overflow - Replace s3_error! macro with S3Error::with_message in ecfs.rs to keep s3s footprint ratchet at baseline (1586) after retention validation refactor - Remove redundant clone on Copy type in list_objects.rs (clippy::redundant_clone) - Remove clone_on_copy calls in access.rs test (clippy::clone_on_copy) - Use manual thread with 8MB stack for heal_concurrent_delete_test to fix stack overflow on macOS (consistent with sibling tests in same file) * test: align CI assertions with version authorization rules
This commit is contained in:
@@ -740,7 +740,7 @@ async fn test_bucket_tags_opa_contract() -> TestResult {
|
||||
.version_id(version)
|
||||
.send()
|
||||
.await?;
|
||||
opa.expect_bucket_tags("s3:GetObject", source, Some("finance")).await?;
|
||||
opa.expect_bucket_tags("s3:GetObjectVersion", source, Some("finance")).await?;
|
||||
client.list_objects_v2().bucket(source).send().await?;
|
||||
opa.expect_bucket_tags("s3:ListBucket", source, Some("finance")).await?;
|
||||
client.list_object_versions().bucket(source).send().await?;
|
||||
|
||||
@@ -9221,7 +9221,7 @@ mod test {
|
||||
};
|
||||
let snapshot = PersistentListMetadataObject::from_object_info(&object);
|
||||
assert!(snapshot.to_object_info("bucket").etag.is_none());
|
||||
let mut old_snapshot = snapshot.clone();
|
||||
let mut old_snapshot = snapshot;
|
||||
old_snapshot.etag = object.etag.clone();
|
||||
let old_contents = format!(
|
||||
"# rustfs-listobjects-key-only-v2\n{}\n",
|
||||
|
||||
@@ -563,9 +563,31 @@ fn admin_root_completes_after_unversioned_delete() {
|
||||
run_delete_case(DeleteCase::Unversioned);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
|
||||
#[test]
|
||||
#[serial]
|
||||
async fn admin_root_rejects_recreated_bucket_before_successor_repair() {
|
||||
fn admin_root_rejects_recreated_bucket_before_successor_repair() {
|
||||
// Incarnation-bound repairs use a spawned owner; retain the server's stack
|
||||
// budget for the whole scenario. block_on alone would poll that future on
|
||||
// libtest's smaller calling-thread stack.
|
||||
let stack_size = 8 * 1024 * 1024;
|
||||
std::thread::Builder::new()
|
||||
.name("heal-concurrent-delete".to_owned())
|
||||
.stack_size(stack_size)
|
||||
.spawn(move || {
|
||||
let runtime = tokio::runtime::Builder::new_multi_thread()
|
||||
.worker_threads(4)
|
||||
.thread_stack_size(stack_size)
|
||||
.enable_all()
|
||||
.build()
|
||||
.expect("concurrent delete runtime");
|
||||
runtime.block_on(recreated_bucket_repair());
|
||||
})
|
||||
.expect("concurrent delete scenario thread starts")
|
||||
.join()
|
||||
.expect("concurrent delete scenario must not panic");
|
||||
}
|
||||
|
||||
async fn recreated_bucket_repair() {
|
||||
let directory = tempfile::tempdir().expect("recreated bucket fixture");
|
||||
let env = TestECStoreEnv::builder().base_dir(directory.path()).build().await;
|
||||
env.make_bucket(BUCKET, false).await;
|
||||
|
||||
@@ -964,7 +964,11 @@ async fn copy_object_allows_new_version_for_locked_destination_but_blocks_explic
|
||||
.await
|
||||
.expect_err("explicit CopyObject overwrite of a locked version should be blocked");
|
||||
|
||||
assert_eq!(err.code(), &s3s::S3ErrorCode::AccessDenied);
|
||||
assert_eq!(err.code(), &s3s::S3ErrorCode::InvalidArgument);
|
||||
assert_eq!(
|
||||
err.message(),
|
||||
Some("Invalid argument: A destination versionId requires replication authorization")
|
||||
);
|
||||
assert_eq!(read_object_bytes(&ecstore, bucket.as_str(), dst_object).await, source_payload);
|
||||
assert_eq!(live_object_version_count(&ecstore, bucket.as_str(), dst_object).await, 2);
|
||||
}
|
||||
|
||||
@@ -4343,15 +4343,8 @@ mod tests {
|
||||
(S3Action::DeleteObjectTaggingAction, S3Action::DeleteObjectVersionTaggingAction),
|
||||
] {
|
||||
for version in [None, Some("null"), Some("0194e0f1-0000-7000-8000-000000000000")] {
|
||||
let action = versioned_tagging_action(current.clone(), version);
|
||||
assert_eq!(
|
||||
action,
|
||||
Action::S3Action(if version.is_some() {
|
||||
versioned.clone()
|
||||
} else {
|
||||
current.clone()
|
||||
})
|
||||
);
|
||||
let action = versioned_tagging_action(current, version);
|
||||
assert_eq!(action, Action::S3Action(if version.is_some() { versioned } else { current }));
|
||||
let args = Args {
|
||||
account: "writer",
|
||||
groups: &groups,
|
||||
|
||||
@@ -415,7 +415,12 @@ pub(crate) fn object_lock_retention_from_metadata(metadata: &HashMap<String, Str
|
||||
date.checked_to_offset(time::UtcOffset::UTC)
|
||||
.filter(|date| (0..=9999).contains(&date.year()))
|
||||
.map(Timestamp::from)
|
||||
.ok_or_else(|| s3_error!(InternalError, "Stored retention date is outside the supported UTC range"))
|
||||
.ok_or_else(|| {
|
||||
S3Error::with_message(
|
||||
S3ErrorCode::InternalError,
|
||||
"Stored retention date is outside the supported UTC range".to_string(),
|
||||
)
|
||||
})
|
||||
})
|
||||
.transpose()?;
|
||||
Ok(ObjectLockRetention { mode, retain_until_date })
|
||||
|
||||
Reference in New Issue
Block a user