fix(ci): restore checks and multipart migration retries (#8196)

* fix(ci): restore multipart lint and full E2E membership checks

* fix(ecstore): preserve multipart completion identity during migration
This commit is contained in:
Chris
2026-09-28 21:22:49 +08:00
committed by GitHub
parent 2648776be7
commit 4a91c75152
4 changed files with 31 additions and 16 deletions
+2 -2
View File
@@ -1,2 +1,2 @@
sha256-darwin=9e9687ded961aa4e619a15def6e1ee0a5153be05423d009ee7a58126624c83e7
sha256-linux=364666693c2bf258997643c9d87e07e7b7501e58175f190d201d53c81946eb20
sha256-darwin=a6aee967387226b6e6937a0e625db53048c8b2f502636820a09c6ad791341b44
sha256-linux=6b8b8f3dbdd63414fc969716ae3d7c2ec71712395630bae8bd419de2f32195b3
+12
View File
@@ -2321,6 +2321,18 @@ mod decommission_lock_order_tests {
.expect("the multipart target must publish before capacity progress save");
assert!(published.is_multipart(), "published target must retain multipart identity");
assert_eq!(published.version_id.map(|version| version.to_string()), Some(source_version.clone()));
for prefix in [
rustfs_utils::http::RUSTFS_INTERNAL_PREFIX,
rustfs_utils::http::MINIO_INTERNAL_PREFIX,
] {
assert_eq!(
published
.user_defined
.get(&format!("{prefix}{}", rustfs_utils::http::SUFFIX_MULTIPART_UPLOAD_ID)),
Some(&source_upload.upload_id),
"migration must preserve the source completion identity under both internal prefixes"
);
}
let mut published_reader = lossy_store.pools[2]
.get_object_reader(
&bucket,
+15 -12
View File
@@ -3108,7 +3108,9 @@ impl crate::storage_api_contracts::multipart::MultipartOperations for SetDisks {
// on the object is what lets a retried CompleteMultipartUpload return this
// version instead of NoSuchUpload. insert_str writes both internal prefixes;
// a later conflicting pair fails closed in the replay matcher.
if !upload_id.is_empty() {
// Internal migration must preserve the source completion identity rather
// than replace it (or invent one) with the temporary transfer upload id.
if !opts.data_movement && !upload_id.is_empty() {
insert_str(&mut fi.metadata, rustfs_utils::http::SUFFIX_MULTIPART_UPLOAD_ID, upload_id.to_owned());
}
@@ -5115,6 +5117,10 @@ mod tests {
)
.await
.expect("completed data movement object should be readable");
assert!(
!rustfs_utils::http::contains_key_str(&completed.user_defined, rustfs_utils::http::SUFFIX_MULTIPART_UPLOAD_ID),
"migration of a source without a completion identity must not invent one"
);
assert!(!rustfs_utils::http::contains_key_str(
&completed.user_defined,
rustfs_utils::http::SUFFIX_DATA_MOVEMENT_UPLOAD
@@ -8822,10 +8828,9 @@ mod tests {
..Default::default()
}];
assert_eq!(
assert!(
completed_multipart_upload_matches(&metadata, &parts, false, upload_id, &requested, "bucket", "object")
.expect("quoted ETag must match the stored part"),
true
.expect("quoted ETag must match the stored part")
);
let wrong_etag = vec![CompletePart {
part_num: 1,
@@ -8836,15 +8841,13 @@ mod tests {
completed_multipart_upload_matches(&metadata, &parts, false, upload_id, &wrong_etag, "bucket", "object"),
Err(StorageError::InvalidPart(1, _, _))
));
assert_eq!(
completed_multipart_upload_matches(&metadata, &parts, false, "other-upload", &requested, "bucket", "object")
.expect("a different upload id is not this completion"),
false
assert!(
!completed_multipart_upload_matches(&metadata, &parts, false, "other-upload", &requested, "bucket", "object")
.expect("a different upload id is not this completion")
);
assert_eq!(
completed_multipart_upload_matches(&metadata, &parts, true, upload_id, &requested, "bucket", "object")
.expect("a delete marker is not the completed object"),
false
assert!(
!completed_multipart_upload_matches(&metadata, &parts, true, upload_id, &requested, "bucket", "object")
.expect("a delete marker is not the completed object")
);
metadata.insert(
+2 -2
View File
@@ -891,8 +891,8 @@ impl DefaultMultipartUsecase {
key: Some(key.clone()),
e_tag: obj_info.etag.clone().map(|etag| to_s3s_etag(&etag)),
location: Some(location),
server_side_encryption: server_side_encryption.clone(),
ssekms_key_id: ssekms_key_id.clone(),
server_side_encryption,
ssekms_key_id,
checksum_crc32,
checksum_crc32c,
checksum_sha1,