You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							114 lines
						
					
					
						
							4.2 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							114 lines
						
					
					
						
							4.2 KiB
						
					
					
				| package retention | |
| 
 | |
| import ( | |
| 	"context" | |
| 	"fmt" | |
| 	"testing" | |
| 	"time" | |
| 
 | |
| 	"github.com/aws/aws-sdk-go-v2/aws" | |
| 	"github.com/aws/aws-sdk-go-v2/service/s3" | |
| 	"github.com/stretchr/testify/require" | |
| ) | |
| 
 | |
| // TestReproduceObjectLockIssue reproduces the Object Lock header processing issue step by step | |
| func TestReproduceObjectLockIssue(t *testing.T) { | |
| 	client := getS3Client(t) | |
| 	bucketName := fmt.Sprintf("object-lock-test-%d", time.Now().UnixNano()) | |
| 
 | |
| 	t.Logf("=== Reproducing Object Lock Header Processing Issue ===") | |
| 	t.Logf("Bucket name: %s", bucketName) | |
| 
 | |
| 	// Step 1: Create bucket with Object Lock enabled header | |
| 	t.Logf("\n1. Creating bucket with ObjectLockEnabledForBucket=true") | |
| 	t.Logf("   This should send x-amz-bucket-object-lock-enabled: true header") | |
| 
 | |
| 	createResp, err := client.CreateBucket(context.TODO(), &s3.CreateBucketInput{ | |
| 		Bucket:                     aws.String(bucketName), | |
| 		ObjectLockEnabledForBucket: aws.Bool(true), // This sets the x-amz-bucket-object-lock-enabled header | |
| 	}) | |
| 
 | |
| 	if err != nil { | |
| 		t.Fatalf("Bucket creation failed: %v", err) | |
| 	} | |
| 	t.Logf("✅ Bucket created successfully") | |
| 	t.Logf("   Response: %+v", createResp) | |
| 
 | |
| 	// Step 2: Check if Object Lock is actually enabled | |
| 	t.Logf("\n2. Checking Object Lock configuration to verify it was enabled") | |
| 
 | |
| 	objectLockResp, err := client.GetObjectLockConfiguration(context.TODO(), &s3.GetObjectLockConfigurationInput{ | |
| 		Bucket: aws.String(bucketName), | |
| 	}) | |
| 
 | |
| 	if err != nil { | |
| 		t.Logf("❌ GetObjectLockConfiguration FAILED: %v", err) | |
| 		t.Logf("   This demonstrates the issue with header processing!") | |
| 		t.Logf("   S3 clients expect this call to succeed if Object Lock is supported") | |
| 		t.Logf("   When this fails, clients conclude that Object Lock is not supported") | |
| 
 | |
| 		// This failure demonstrates the bug - the bucket was created but Object Lock wasn't enabled | |
| 		t.Logf("\n🐛 BUG CONFIRMED:") | |
| 		t.Logf("   - Bucket creation with ObjectLockEnabledForBucket=true succeeded") | |
| 		t.Logf("   - But GetObjectLockConfiguration fails") | |
| 		t.Logf("   - This means the x-amz-bucket-object-lock-enabled header was ignored") | |
| 
 | |
| 	} else { | |
| 		t.Logf("✅ GetObjectLockConfiguration succeeded!") | |
| 		t.Logf("   Response: %+v", objectLockResp) | |
| 		t.Logf("   Object Lock is properly enabled - this is the expected behavior") | |
| 	} | |
| 
 | |
| 	// Step 3: Check versioning status (required for Object Lock) | |
| 	t.Logf("\n3. Checking bucket versioning status (required for Object Lock)") | |
| 
 | |
| 	versioningResp, err := client.GetBucketVersioning(context.TODO(), &s3.GetBucketVersioningInput{ | |
| 		Bucket: aws.String(bucketName), | |
| 	}) | |
| 	require.NoError(t, err) | |
| 
 | |
| 	t.Logf("   Versioning status: %v", versioningResp.Status) | |
| 	if versioningResp.Status != "Enabled" { | |
| 		t.Logf("   ⚠️  Versioning should be automatically enabled when Object Lock is enabled") | |
| 	} | |
| 
 | |
| 	// Cleanup | |
| 	t.Logf("\n4. Cleaning up test bucket") | |
| 	_, err = client.DeleteBucket(context.TODO(), &s3.DeleteBucketInput{ | |
| 		Bucket: aws.String(bucketName), | |
| 	}) | |
| 	if err != nil { | |
| 		t.Logf("   Warning: Failed to delete bucket: %v", err) | |
| 	} | |
| 
 | |
| 	t.Logf("\n=== Issue Reproduction Complete ===") | |
| 	t.Logf("Expected behavior after fix:") | |
| 	t.Logf("  - CreateBucket with ObjectLockEnabledForBucket=true should enable Object Lock") | |
| 	t.Logf("  - GetObjectLockConfiguration should return enabled configuration") | |
| 	t.Logf("  - Versioning should be automatically enabled") | |
| } | |
| 
 | |
| // TestNormalBucketCreationStillWorks tests that normal bucket creation still works | |
| func TestNormalBucketCreationStillWorks(t *testing.T) { | |
| 	client := getS3Client(t) | |
| 	bucketName := fmt.Sprintf("normal-test-%d", time.Now().UnixNano()) | |
| 
 | |
| 	t.Logf("=== Testing Normal Bucket Creation ===") | |
| 
 | |
| 	// Create bucket without Object Lock | |
| 	_, err := client.CreateBucket(context.TODO(), &s3.CreateBucketInput{ | |
| 		Bucket: aws.String(bucketName), | |
| 	}) | |
| 	require.NoError(t, err) | |
| 	t.Logf("✅ Normal bucket creation works") | |
| 
 | |
| 	// Object Lock should NOT be enabled | |
| 	_, err = client.GetObjectLockConfiguration(context.TODO(), &s3.GetObjectLockConfigurationInput{ | |
| 		Bucket: aws.String(bucketName), | |
| 	}) | |
| 	require.Error(t, err, "GetObjectLockConfiguration should fail for bucket without Object Lock") | |
| 	t.Logf("✅ GetObjectLockConfiguration correctly fails for normal bucket") | |
| 
 | |
| 	// Cleanup | |
| 	client.DeleteBucket(context.TODO(), &s3.DeleteBucketInput{Bucket: aws.String(bucketName)}) | |
| }
 |