mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-27 16:48:58 +00:00
@@ -67,6 +67,22 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn suspend_versioning(client: &Client, bucket: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
let versioning_config = VersioningConfiguration::builder()
|
||||
.status(BucketVersioningStatus::Suspended)
|
||||
.build();
|
||||
|
||||
client
|
||||
.put_bucket_versioning()
|
||||
.bucket(bucket)
|
||||
.versioning_configuration(versioning_config)
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
info!("✅ Versioning suspended for bucket {}", bucket);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test 1: PutObject should return version_id when versioning is enabled
|
||||
/// This directly addresses the Veeam issue from #1066
|
||||
#[tokio::test]
|
||||
@@ -437,4 +453,49 @@ mod tests {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test 7: PutObject should return "null" version_id when versioning is Suspended
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn test_put_object_returns_null_version_id_with_suspended_versioning() {
|
||||
init_logging();
|
||||
info!("🧪 TEST: PutObject returns null version_id with versioning suspended");
|
||||
|
||||
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 = create_s3_client(&env);
|
||||
let bucket = "test-suspended-version-id";
|
||||
|
||||
create_bucket(&client, bucket).await.expect("Failed to create bucket");
|
||||
suspend_versioning(&client, bucket)
|
||||
.await
|
||||
.expect("Failed to suspend versioning");
|
||||
|
||||
let key = "test-file-suspended.txt";
|
||||
let content = b"Test content for suspended version ID test";
|
||||
|
||||
info!("📤 Uploading object to suspended versioning bucket");
|
||||
let result = client
|
||||
.put_object()
|
||||
.bucket(bucket)
|
||||
.key(key)
|
||||
.body(ByteStream::from_static(content))
|
||||
.send()
|
||||
.await;
|
||||
|
||||
assert!(result.is_ok(), "PutObject failed: {:?}", result.err());
|
||||
let output = result.unwrap();
|
||||
|
||||
info!("📥 PutObject response - version_id: {:?}", output.version_id);
|
||||
|
||||
// When suspended, version_id must be "null"
|
||||
assert_eq!(
|
||||
output.version_id.as_deref(),
|
||||
Some("null"),
|
||||
"❌ FAILED: version_id should be 'null' when versioning is suspended"
|
||||
);
|
||||
|
||||
info!("✅ PASSED: PutObject correctly returns 'null' version_id");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,10 +36,7 @@ impl VersioningApi for VersioningConfiguration {
|
||||
return true;
|
||||
}
|
||||
|
||||
if let Some(exclude_folders) = self.exclude_folders
|
||||
&& exclude_folders
|
||||
&& prefix.ends_with('/')
|
||||
{
|
||||
if self.exclude_folders.unwrap_or(false) && prefix.ends_with('/') {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -4859,7 +4859,10 @@ impl S3 for FS {
|
||||
let manager = get_concurrency_manager();
|
||||
let put_bucket = bucket.clone();
|
||||
let put_key = key.clone();
|
||||
let put_version = obj_info.version_id.map(|v| v.to_string());
|
||||
let mut put_version = obj_info.version_id.map(|v| v.to_string());
|
||||
if opts.version_suspended && obj_info.version_id.is_none_or(|v| v.is_nil()) {
|
||||
put_version = Some("null".to_string());
|
||||
}
|
||||
|
||||
helper = helper.object(obj_info.clone());
|
||||
if let Some(version_id) = &put_version {
|
||||
|
||||
Reference in New Issue
Block a user