Fix S3 delete for non-empty directory markers (#8740)

* Fix S3 delete for non-empty directory markers

* Address review feedback on directory marker deletes

* Stabilize FUSE concurrent directory operations
This commit is contained in:
Chris Lu
2026-03-23 13:35:16 -07:00
committed by GitHub
parent b3b7033fe1
commit d5ee35c8df
13 changed files with 386 additions and 32 deletions

View File

@@ -99,6 +99,10 @@ func TestS3Integration(t *testing.T) {
testDeleteObject(t, cluster)
})
t.Run("DeleteDirectoryMarkerWithChildren", func(t *testing.T) {
testDeleteDirectoryMarkerWithChildren(t, cluster)
})
t.Run("DeleteBucket", func(t *testing.T) {
testDeleteBucket(t, cluster)
})
@@ -754,6 +758,47 @@ func testDeleteObject(t *testing.T, cluster *TestCluster) {
t.Logf("✓ Deleted object: %s/%s", bucketName, objectKey)
}
func testDeleteDirectoryMarkerWithChildren(t *testing.T, cluster *TestCluster) {
bucketName := createTestBucket(t, cluster, "test-delete-dir-marker-")
childKey := "test-content/file1.txt"
directoryMarkerKey := "test-content/"
_, err := cluster.s3Client.PutObject(&s3.PutObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(childKey),
Body: bytes.NewReader([]byte("child")),
})
require.NoError(t, err)
_, err = cluster.s3Client.PutObject(&s3.PutObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(directoryMarkerKey),
Body: bytes.NewReader(nil),
ContentType: aws.String("application/octet-stream"),
})
require.NoError(t, err)
_, err = cluster.s3Client.DeleteObject(&s3.DeleteObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(directoryMarkerKey),
})
require.NoError(t, err, "Deleting a directory marker should succeed even when children exist")
listResp, err := cluster.s3Client.ListObjectsV2(&s3.ListObjectsV2Input{
Bucket: aws.String(bucketName),
Prefix: aws.String("test-content/"),
})
require.NoError(t, err)
foundKeys := make(map[string]bool)
for _, obj := range listResp.Contents {
foundKeys[aws.StringValue(obj.Key)] = true
}
assert.True(t, foundKeys[childKey], "Child object should remain after deleting the directory marker")
assert.False(t, foundKeys[directoryMarkerKey], "Directory marker should no longer be listed after deletion")
}
func testDeleteBucket(t *testing.T, cluster *TestCluster) {
bucketName := "test-delete-bucket-" + randomString(8)