Skip to content

Conversation

bentsku
Copy link
Contributor

@bentsku bentsku commented Apr 1, 2023

So following #8021, #7983 and #7545, I've investigated and made a list of all S3 operations with a different root node name than the specs. Basically, 41 of 44 operations returning an XML body do not follow the specs. Here's the list:
❌: wrong name, 🟠: fixed by patches, ✅: right from the specs

Operation Spec shape Root tag
CompleteMultipartUpload CompleteMultipartUploadOutput CompleteMultipartUploadResult
CopyObject CopyObjectOutput CopyObjectResult
CreateMultipartUpload CreateMultipartUploadOutput InitiateMultipartUploadResult
🟠 DeleteObjects DeleteObjectsOutput DeleteResult
GetBucketAccelerateConfiguration GetBucketAccelerateConfigurationOutput AccelerateConfiguration
GetBucketAcl GetBucketAclOutput AccessControlPolicy
GetBucketAnalyticsConfiguration GetBucketAnalyticsConfigurationOutput AnalyticsConfiguration
GetBucketCors GetBucketCorsOutput CORSConfiguration
GetBucketEncryption GetBucketEncryptionOutput ServerSideEncryptionConfiguration
GetBucketIntelligentTieringConfiguration GetBucketIntelligentTieringConfigurationOutput IntelligentTieringConfiguration
GetBucketInventoryConfiguration GetBucketInventoryConfigurationOutput InventoryConfiguration
GetBucketLifecycle GetBucketLifecycleOutput LifecycleConfiguration
GetBucketLifecycleConfiguration GetBucketLifecycleConfigurationOutput LifecycleConfiguration
- GetBucketLocation GetBucketLocationOutput LocationConstraint
GetBucketLogging GetBucketLoggingOutput BucketLoggingStatus
GetBucketMetricsConfiguration GetBucketMetricsConfigurationOutput MetricsConfiguration
GetBucketNotification NotificationConfigurationDeprecated NotificationConfiguration
GetBucketNotificationConfiguration NotificationConfiguration NotificationConfiguration
GetBucketOwnershipControls GetBucketOwnershipControlsOutput OwnershipControls
GetBucketPolicyStatus GetBucketPolicyStatusOutput PolicyStatus
GetBucketReplication GetBucketReplicationOutput ReplicationConfiguration
GetBucketRequestPayment GetBucketRequestPaymentOutput RequestPaymentConfiguration
🟠 GetBucketTagging GetBucketTaggingOutput Tagging
GetBucketVersioning GetBucketVersioningOutput VersioningConfiguration
GetBucketWebsite GetBucketWebsiteOutput WebsiteConfiguration
GetObjectAcl GetObjectAclOutput AccessControlPolicy
GetObjectAttributes GetObjectAttributesOutput GetObjectAttributesOutput
GetObjectLegalHold GetObjectLegalHoldOutput LegalHold
GetObjectLockConfiguration GetObjectLockConfigurationOutput ObjectLockConfiguration
GetObjectRetention GetObjectRetentionOutput Retention
🟠 GetObjectTagging GetObjectTaggingOutput Tagging
GetPublicAccessBlock GetPublicAccessBlockOutput PublicAccessBlockConfiguration
ListBucketAnalyticsConfigurations ListBucketAnalyticsConfigurationsOutput ListBucketAnalyticsConfigurationResult
ListBucketIntelligentTieringConfigurations ListBucketIntelligentTieringConfigurationsOutput ListBucketIntelligentTieringConfigurationsOutput
ListBucketInventoryConfigurations ListBucketInventoryConfigurationsOutput ListInventoryConfigurationsResult
ListBucketMetricsConfigurations ListBucketMetricsConfigurationsOutput ListMetricsConfigurationsResult
🟠 ListBuckets ListBucketsOutput ListAllMyBucketsResult
🟠 ListMultipartUploads ListMultipartUploadsOutput ListMultipartUploadsResult
🟠 ListObjects ListObjectsOutput ListBucketResult
🟠 ListObjectsV2 ListObjectsV2Output ListBucketResult
ListObjectVersions ListObjectVersionsOutput ListVersionsResult
ListParts ListPartsOutput ListPartsResult
- SelectObjectContent SelectObjectContentOutput Payload
UploadPartCopy UploadPartCopyOutput CopyPartResult

Note: I've removed GetBucketLocation as it's a special case with no root node wrapper, and SelectObjectContent as it's a streaming response.

This PR implements a fix by directly renaming the root node while still taking advantages of the specs. Previously, modifying the specs would also have effects on the parser where, for example, the shape would already exists (see GetBucketTagging and GetObjectTagging, both returns a root node with Tagging name but the shape is different). Now we can still differentiate for each operations.

Now, the issue is systematic testing of those operations. I'm confident the new root node names are the right ones, but it would be nice to have replicable tests against AWS. We already have a test in place (tests.integration.s3.test_s3.TestS3.test_response_structure) testing some operations (and we can see that removing the patches didn't make the test fail as the new serializer part is now taking care of it).
However, as 41 of 44 operations needs to be tested for their XML response, this makes it a bit difficult as you would need to setup the resources to be able to query them afterwards (ex. GetBucketCorsConfiguration would need a configuration to be able to be queried).

would fix #8030

@coveralls
Copy link

Coverage Status

Coverage: 81.871% (+0.008%) from 81.863% when pulling d6dddff on fix-s3-root-tag into 4e02891 on master.

@bentsku bentsku self-assigned this Apr 1, 2023
@bentsku bentsku added the aws:s3 Amazon Simple Storage Service label Apr 1, 2023
@github-actions
Copy link

github-actions bot commented Apr 1, 2023

LocalStack integration with Pro

1 869 tests  ±0   1 678 ✔️ ±0   1h 32m 49s ⏱️ + 2m 51s
       1 suites ±0      191 💤 ±0 
       1 files   ±0          0 ±0 

Results for commit d6dddff. ± Comparison against base commit 4e02891.

Copy link
Member

@thrau thrau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a much better solution than patching all this in the spec 👍, thanks for digging in to this. And also I like that we scraped this from the docs, so should be pretty confident now that it's correct.

maybe we could add a couple of regression unit tests to the serializer to make sure the XML is serialized as expected. unless we have some already :-)

@bentsku
Copy link
Contributor Author

bentsku commented Apr 2, 2023

I'll look for the unit tests for the serializer! We have one integration test testing previously patched operations:
ListBuckets, ListMultipartUploads, ListObjects, ListObjectsV2, GetBucketTagging and GetObjectTagging. If the serializer suddenly stops fixing the root node tag, this test will fail.

We could have a test using the specs + the dict from the serializer with the right node names and check if the serializer is returning the right name for the operation? I'm not sure how I'd construct this unit test, I'll have a look tomorrow!

Copy link
Member

@alexrashed alexrashed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great investigation and thanks for jumping on this! The fix is looking great. 🚀 🦸🏽
I wonder how other clients (like the Java SDK) handle this in a generalized way (but we can take a closer look in the next few weeks).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
aws:s3 Amazon Simple Storage Service
Projects
None yet
Development

Successfully merging this pull request may close these issues.

bug: CreateMultipartUpload should return InitiateMultipartUploadResult element
4 participants