fix: return null versionId when suspended (#1066) (#1709)

This commit is contained in:
loverustfs
2026-02-04 09:22:52 +08:00
committed by GitHub
parent 174e12bf66
commit a4563f7b41
3 changed files with 66 additions and 5 deletions
@@ -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");
}
}
+1 -4
View File
@@ -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;
}
+4 -1
View File
@@ -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 {