From 3c11f7e298a6db8cc7ebb4a34423433f7a44f0b2 Mon Sep 17 00:00:00 2001 From: chrislu Date: Mon, 3 Nov 2025 14:19:55 -0800 Subject: [PATCH] refactor --- .../s3_bucket_delete_with_lock_test.go | 113 +++++++----------- 1 file changed, 42 insertions(+), 71 deletions(-) diff --git a/test/s3/retention/s3_bucket_delete_with_lock_test.go b/test/s3/retention/s3_bucket_delete_with_lock_test.go index 04687e0a8..cb3d034b1 100644 --- a/test/s3/retention/s3_bucket_delete_with_lock_test.go +++ b/test/s3/retention/s3_bucket_delete_with_lock_test.go @@ -23,83 +23,54 @@ func TestBucketDeletionWithObjectLock(t *testing.T) { // Create bucket with object lock enabled createBucketWithObjectLock(t, client, bucketName) - // Test 1: Bucket deletion with active compliance retention should fail - t.Run("CannotDeleteBucketWithComplianceRetention", func(t *testing.T) { - key := "test-compliance-retention" - content := "test content for compliance retention" - retainUntilDate := time.Now().Add(10 * time.Second) // 10 seconds in future - - // Upload object with compliance retention - _, err := client.PutObject(context.Background(), &s3.PutObjectInput{ - Bucket: aws.String(bucketName), - Key: aws.String(key), - Body: strings.NewReader(content), - ObjectLockMode: types.ObjectLockModeCompliance, - ObjectLockRetainUntilDate: aws.Time(retainUntilDate), - }) - require.NoError(t, err, "PutObject with compliance retention should succeed") - - // Try to delete bucket - should fail because object has active retention - _, err = client.DeleteBucket(context.Background(), &s3.DeleteBucketInput{ - Bucket: aws.String(bucketName), - }) - require.Error(t, err, "DeleteBucket should fail when objects have active retention") - assert.Contains(t, err.Error(), "BucketNotEmpty", "Error should be BucketNotEmpty") - t.Logf("Expected error: %v", err) - - // Wait for retention to expire with dynamic sleep based on actual retention time - t.Logf("Waiting for compliance retention to expire...") - time.Sleep(time.Until(retainUntilDate) + time.Second) - - // Delete the object - _, err = client.DeleteObject(context.Background(), &s3.DeleteObjectInput{ - Bucket: aws.String(bucketName), - Key: aws.String(key), - }) - require.NoError(t, err, "DeleteObject should succeed after retention expires") - - // Clean up versions - deleteAllObjectVersions(t, client, bucketName) - }) + // Table-driven test for retention modes + retentionTestCases := []struct { + name string + lockMode types.ObjectLockMode + }{ + {name: "ComplianceRetention", lockMode: types.ObjectLockModeCompliance}, + {name: "GovernanceRetention", lockMode: types.ObjectLockModeGovernance}, + } - // Test 2: Bucket deletion with active governance retention should fail - t.Run("CannotDeleteBucketWithGovernanceRetention", func(t *testing.T) { - key := "test-governance-retention" - content := "test content for governance retention" - retainUntilDate := time.Now().Add(10 * time.Second) // 10 seconds in future + for _, tc := range retentionTestCases { + t.Run(fmt.Sprintf("CannotDeleteBucketWith%s", tc.name), func(t *testing.T) { + key := fmt.Sprintf("test-%s", strings.ToLower(strings.ReplaceAll(tc.name, "Retention", "-retention"))) + content := fmt.Sprintf("test content for %s", strings.ToLower(tc.name)) + retainUntilDate := time.Now().Add(10 * time.Second) // 10 seconds in future + + // Upload object with retention + _, err := client.PutObject(context.Background(), &s3.PutObjectInput{ + Bucket: aws.String(bucketName), + Key: aws.String(key), + Body: strings.NewReader(content), + ObjectLockMode: tc.lockMode, + ObjectLockRetainUntilDate: aws.Time(retainUntilDate), + }) + require.NoError(t, err, "PutObject with %s should succeed", tc.name) - // Upload object with governance retention - _, err := client.PutObject(context.Background(), &s3.PutObjectInput{ - Bucket: aws.String(bucketName), - Key: aws.String(key), - Body: strings.NewReader(content), - ObjectLockMode: types.ObjectLockModeGovernance, - ObjectLockRetainUntilDate: aws.Time(retainUntilDate), - }) - require.NoError(t, err, "PutObject with governance retention should succeed") + // Try to delete bucket - should fail because object has active retention + _, err = client.DeleteBucket(context.Background(), &s3.DeleteBucketInput{ + Bucket: aws.String(bucketName), + }) + require.Error(t, err, "DeleteBucket should fail when objects have active retention") + assert.Contains(t, err.Error(), "BucketNotEmpty", "Error should be BucketNotEmpty") + t.Logf("Expected error: %v", err) - // Try to delete bucket - should fail because object has active retention - _, err = client.DeleteBucket(context.Background(), &s3.DeleteBucketInput{ - Bucket: aws.String(bucketName), - }) - require.Error(t, err, "DeleteBucket should fail when objects have active retention") - assert.Contains(t, err.Error(), "BucketNotEmpty", "Error should be BucketNotEmpty") - t.Logf("Expected error: %v", err) + // Wait for retention to expire with dynamic sleep based on actual retention time + t.Logf("Waiting for %s to expire...", tc.name) + time.Sleep(time.Until(retainUntilDate) + time.Second) - // Wait for retention to expire with dynamic sleep based on actual retention time - t.Logf("Waiting for governance retention to expire...") - time.Sleep(time.Until(retainUntilDate) + time.Second) + // Delete the object + _, err = client.DeleteObject(context.Background(), &s3.DeleteObjectInput{ + Bucket: aws.String(bucketName), + Key: aws.String(key), + }) + require.NoError(t, err, "DeleteObject should succeed after retention expires") - // Delete the object - _, err = client.DeleteObject(context.Background(), &s3.DeleteObjectInput{ - Bucket: aws.String(bucketName), - Key: aws.String(key), + // Clean up versions + deleteAllObjectVersions(t, client, bucketName) }) - require.NoError(t, err, "DeleteObject should succeed after retention expires") - - // Clean up versions - deleteAllObjectVersions(t, client, bucketName) - }) + } // Test 3: Bucket deletion with legal hold should fail t.Run("CannotDeleteBucketWithLegalHold", func(t *testing.T) {