From a30b8c2320eaaa17f5888d90a2050027233aee30 Mon Sep 17 00:00:00 2001 From: niksis02 Date: Fri, 21 Feb 2025 00:20:49 +0400 Subject: [PATCH] fix: Adds removeParents in DeleteObject in case of deleting an object in nested directories --- backend/posix/posix.go | 3 ++- tests/integration/group-tests.go | 2 ++ tests/integration/tests.go | 45 ++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/backend/posix/posix.go b/backend/posix/posix.go index 80f8b2e3..92437383 100644 --- a/backend/posix/posix.go +++ b/backend/posix/posix.go @@ -3042,7 +3042,6 @@ func (p *Posix) DeleteObject(ctx context.Context, input *s3.DeleteObjectInput) ( // if the specified VersionId is the same as in the latest version, // remove the latest version, find the latest version from the versioning // directory and move to the place of the deleted object, to make it the latest - isDelMarker, err := p.isObjDeleteMarker(bucket, object) if err != nil { return nil, err @@ -3054,6 +3053,7 @@ func (p *Posix) DeleteObject(ctx context.Context, input *s3.DeleteObjectInput) ( ents, err := os.ReadDir(versionPath) if errors.Is(err, fs.ErrNotExist) { + p.removeParents(bucket, object) return &s3.DeleteObjectOutput{ DeleteMarker: &isDelMarker, VersionId: input.VersionId, @@ -3064,6 +3064,7 @@ func (p *Posix) DeleteObject(ctx context.Context, input *s3.DeleteObjectInput) ( } if len(ents) == 0 { + p.removeParents(bucket, object) return &s3.DeleteObjectOutput{ DeleteMarker: &isDelMarker, VersionId: input.VersionId, diff --git a/tests/integration/group-tests.go b/tests/integration/group-tests.go index f2b79376..de171175 100644 --- a/tests/integration/group-tests.go +++ b/tests/integration/group-tests.go @@ -688,6 +688,7 @@ func TestVersioning(s *S3Conf) { Versioning_DeleteObject_non_existing_object(s) Versioning_DeleteObject_delete_a_delete_marker(s) Versioning_Delete_null_versionId_object(s) + Versioning_DeleteObject_nested_dir_object(s) Versioning_DeleteObject_suspended(s) Versioning_DeleteObjects_success(s) Versioning_DeleteObjects_delete_deleteMarkers(s) @@ -1146,6 +1147,7 @@ func GetIntTests() IntTests { "Versioning_DeleteObject_non_existing_object": Versioning_DeleteObject_non_existing_object, "Versioning_DeleteObject_delete_a_delete_marker": Versioning_DeleteObject_delete_a_delete_marker, "Versioning_Delete_null_versionId_object": Versioning_Delete_null_versionId_object, + "Versioning_DeleteObject_nested_dir_object": Versioning_DeleteObject_nested_dir_object, "Versioning_DeleteObject_suspended": Versioning_DeleteObject_suspended, "Versioning_DeleteObjects_success": Versioning_DeleteObjects_success, "Versioning_DeleteObjects_delete_deleteMarkers": Versioning_DeleteObjects_delete_deleteMarkers, diff --git a/tests/integration/tests.go b/tests/integration/tests.go index 74bf7388..22b47e11 100644 --- a/tests/integration/tests.go +++ b/tests/integration/tests.go @@ -14799,6 +14799,51 @@ func Versioning_Delete_null_versionId_object(s *S3Conf) error { }) } +func Versioning_DeleteObject_nested_dir_object(s *S3Conf) error { + testName := "Versioning_DeleteObject_nested_dir_object" + return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { + obj := "foo/bar/baz" + out, err := putObjectWithData(1000, &s3.PutObjectInput{ + Bucket: &bucket, + Key: &obj, + }, s3client) + if err != nil { + return err + } + + ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) + res, err := s3client.DeleteObject(ctx, &s3.DeleteObjectInput{ + Bucket: &bucket, + Key: &obj, + VersionId: out.res.VersionId, + }) + cancel() + if err != nil { + return err + } + + if getString(res.VersionId) != getString(out.res.VersionId) { + return fmt.Errorf("expected the versionId to be %v, instead got %v", getString(out.res.VersionId), getString(res.VersionId)) + } + + ctx, cancel = context.WithTimeout(context.Background(), shortTimeout) + _, err = s3client.DeleteBucket(ctx, &s3.DeleteBucketInput{ + Bucket: &bucket, + }) + cancel() + if err != nil { + return err + } + + // Then create the bucket back to not get error on teardown + if err := setup(s, bucket); err != nil { + return err + } + + return nil + }, withLock()) +} + func Versioning_DeleteObject_suspended(s *S3Conf) error { testName := "Versioning_DeleteObject_suspended" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {