diff --git a/backend/posix/posix.go b/backend/posix/posix.go index 94a49092..de6083ed 100644 --- a/backend/posix/posix.go +++ b/backend/posix/posix.go @@ -1420,7 +1420,7 @@ func (p *Posix) CompleteMultipartUpload(ctx context.Context, input *s3.CompleteM } // ChecksumType should be the same as specified on CreateMultipartUpload - if checksums.Type != input.ChecksumType { + if input.ChecksumType != "" && checksums.Type != input.ChecksumType { checksumType := checksums.Type if checksumType == "" { checksumType = types.ChecksumType("null") diff --git a/tests/integration/group-tests.go b/tests/integration/group-tests.go index f377d195..84b46e21 100644 --- a/tests/integration/group-tests.go +++ b/tests/integration/group-tests.go @@ -413,6 +413,7 @@ func TestCompleteMultipartUpload(s *S3Conf) { CompleteMultipartUpload_should_verify_the_final_checksum(s) CompleteMultipartUpload_checksum_type_mismatch(s) CompleteMultipartUpload_should_ignore_the_final_checksum(s) + CompleteMultipartUpload_should_succeed_without_final_checksum_type(s) } CompleteMultipartUpload_success(s) if !s.azureTests { @@ -1000,6 +1001,7 @@ func GetIntTests() IntTests { "CompleteMultipartUpload_should_verify_the_final_checksum": CompleteMultipartUpload_should_verify_the_final_checksum, "CompleteMultipartUpload_checksum_type_mismatch": CompleteMultipartUpload_checksum_type_mismatch, "CompleteMultipartUpload_should_ignore_the_final_checksum": CompleteMultipartUpload_should_ignore_the_final_checksum, + "CompleteMultipartUpload_should_succeed_without_final_checksum_type": CompleteMultipartUpload_should_succeed_without_final_checksum_type, "CompleteMultipartUpload_success": CompleteMultipartUpload_success, "CompleteMultipartUpload_racey_success": CompleteMultipartUpload_racey_success, "PutBucketAcl_non_existing_bucket": PutBucketAcl_non_existing_bucket, diff --git a/tests/integration/tests.go b/tests/integration/tests.go index cecf0a80..59f7bbf0 100644 --- a/tests/integration/tests.go +++ b/tests/integration/tests.go @@ -9554,6 +9554,54 @@ func CompleteMultipartUpload_should_ignore_the_final_checksum(s *S3Conf) error { }) } +func CompleteMultipartUpload_should_succeed_without_final_checksum_type(s *S3Conf) error { + testName := "CompleteMultipartUpload_should_succeed_without_final_checksum_type" + return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { + obj := "my-obj" + mp, err := createMp(s3client, bucket, obj, withChecksum(types.ChecksumAlgorithmCrc64nvme), withChecksumType(types.ChecksumTypeFullObject)) + if err != nil { + return err + } + + parts, _, err := uploadParts(s3client, 20*1024*1024, 4, bucket, obj, *mp.UploadId, withChecksum(types.ChecksumAlgorithmCrc64nvme)) + if err != nil { + return err + } + + cParts := []types.CompletedPart{} + for _, el := range parts { + cParts = append(cParts, types.CompletedPart{ + ETag: el.ETag, + PartNumber: el.PartNumber, + ChecksumCRC64NVME: el.ChecksumCRC64NVME, + }) + } + + ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) + res, err := s3client.CompleteMultipartUpload(ctx, &s3.CompleteMultipartUploadInput{ + Bucket: &bucket, + Key: &obj, + UploadId: mp.UploadId, + MultipartUpload: &types.CompletedMultipartUpload{ + Parts: cParts, + }, + }) + cancel() + if err != nil { + return err + } + + if res.ChecksumType != types.ChecksumTypeFullObject { + return fmt.Errorf("expected the final checksum type to be %v, instead got %v", types.ChecksumTypeFullObject, res.ChecksumType) + } + if getString(res.ChecksumCRC64NVME) == "" { + return fmt.Errorf("expected non empty crc64nvme checksum") + } + + return nil + }) +} + func CompleteMultipartUpload_small_upload_size(s *S3Conf) error { testName := "CompleteMultipartUpload_small_upload_size" return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {