mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-07 13:53:12 +00:00
50ddec3ffc
Co-authored-by: cxymds <Cxymds@qq.com>
145 lines
4.8 KiB
Rust
145 lines
4.8 KiB
Rust
// Copyright 2024 RustFS Team
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
//! CopyObject metadata replacement regression tests.
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use crate::common::{RustFSTestEnvironment, init_logging};
|
|
use aws_sdk_s3::primitives::ByteStream;
|
|
use aws_sdk_s3::types::MetadataDirective;
|
|
use serial_test::serial;
|
|
use tracing::info;
|
|
|
|
#[tokio::test]
|
|
#[serial]
|
|
async fn test_self_copy_replace_metadata_preserves_readable_object() {
|
|
init_logging();
|
|
info!("Issue #2789: self-copy metadata replacement must preserve object data");
|
|
|
|
let mut env = RustFSTestEnvironment::new().await.expect("Failed to create test environment");
|
|
env.start_rustfs_server(vec![]).await.expect("Failed to start RustFS");
|
|
|
|
let client = env.create_s3_client();
|
|
let bucket = "self-copy-metadata-replace-test";
|
|
let key = "assets/chunk-2F3R7JUG.js";
|
|
let content = b"console.log('metadata replacement should keep object data readable');";
|
|
|
|
client
|
|
.create_bucket()
|
|
.bucket(bucket)
|
|
.send()
|
|
.await
|
|
.expect("Failed to create bucket");
|
|
|
|
client
|
|
.put_object()
|
|
.bucket(bucket)
|
|
.key(key)
|
|
.content_type("text/javascript; charset=utf-8")
|
|
.metadata("mtime", "1777992333")
|
|
.metadata("stale", "must-be-removed")
|
|
.body(ByteStream::from_static(content))
|
|
.send()
|
|
.await
|
|
.expect("PUT failed");
|
|
|
|
client
|
|
.copy_object()
|
|
.bucket(bucket)
|
|
.key(key)
|
|
.copy_source(format!("{bucket}/{key}"))
|
|
.metadata_directive(MetadataDirective::Replace)
|
|
.content_type("text/javascript; charset=utf-8")
|
|
.metadata("mtime", "1777992348")
|
|
.send()
|
|
.await
|
|
.expect("self CopyObject with metadata replacement failed");
|
|
|
|
let head_resp = client
|
|
.head_object()
|
|
.bucket(bucket)
|
|
.key(key)
|
|
.send()
|
|
.await
|
|
.expect("HEAD failed after self-copy");
|
|
assert_eq!(head_resp.content_length(), Some(content.len() as i64));
|
|
assert_eq!(
|
|
head_resp.metadata().and_then(|metadata| metadata.get("mtime")),
|
|
Some(&"1777992348".to_string()),
|
|
"HEAD should return replaced metadata"
|
|
);
|
|
assert_eq!(
|
|
head_resp.metadata().and_then(|metadata| metadata.get("stale")),
|
|
None,
|
|
"HEAD should not return metadata omitted by REPLACE"
|
|
);
|
|
|
|
let get_resp = client
|
|
.get_object()
|
|
.bucket(bucket)
|
|
.key(key)
|
|
.send()
|
|
.await
|
|
.expect("GET failed after self-copy");
|
|
let body = get_resp
|
|
.body
|
|
.collect()
|
|
.await
|
|
.expect("Failed to collect GET body")
|
|
.into_bytes();
|
|
assert_eq!(body.as_ref(), content, "self-copy metadata replacement must not drop object data");
|
|
|
|
client
|
|
.copy_object()
|
|
.bucket(bucket)
|
|
.key(key)
|
|
.copy_source(format!("{bucket}/{key}"))
|
|
.metadata_directive(MetadataDirective::Replace)
|
|
.send()
|
|
.await
|
|
.expect("self CopyObject with empty metadata replacement failed");
|
|
|
|
let empty_head_resp = client
|
|
.head_object()
|
|
.bucket(bucket)
|
|
.key(key)
|
|
.send()
|
|
.await
|
|
.expect("HEAD failed after empty metadata replacement");
|
|
assert_eq!(
|
|
empty_head_resp.metadata().and_then(|metadata| metadata.get("mtime")),
|
|
None,
|
|
"HEAD should not return metadata omitted by empty REPLACE"
|
|
);
|
|
|
|
let empty_get_resp = client
|
|
.get_object()
|
|
.bucket(bucket)
|
|
.key(key)
|
|
.send()
|
|
.await
|
|
.expect("GET failed after empty metadata replacement");
|
|
let empty_body = empty_get_resp
|
|
.body
|
|
.collect()
|
|
.await
|
|
.expect("Failed to collect GET body after empty metadata replacement")
|
|
.into_bytes();
|
|
assert_eq!(empty_body.as_ref(), content, "empty metadata replacement must not drop object data");
|
|
|
|
env.stop_server();
|
|
}
|
|
}
|