Merge pull request #797 from versity/fix/getobjectattributes-mp

fix: Removed multipart upload part from GetObjectAttributes action
This commit is contained in:
Ben McClelland
2024-09-11 10:34:46 -07:00
committed by GitHub
3 changed files with 5 additions and 211 deletions

View File

@@ -24,7 +24,6 @@ import (
"fmt"
"io"
"io/fs"
"math"
"os"
"path/filepath"
"sort"
@@ -1951,63 +1950,15 @@ func (p *Posix) GetObjectAttributes(ctx context.Context, input *s3.GetObjectAttr
Bucket: input.Bucket,
Key: input.Key,
})
if err == nil {
return s3response.GetObjectAttributesResult{
ETag: data.ETag,
LastModified: data.LastModified,
ObjectSize: data.ContentLength,
StorageClass: data.StorageClass,
VersionId: data.VersionId,
}, nil
}
if !errors.Is(err, s3err.GetAPIError(s3err.ErrNoSuchKey)) {
return s3response.GetObjectAttributesResult{}, err
}
uploadId, _, err := p.retrieveUploadId(*input.Bucket, *input.Key)
if err != nil {
return s3response.GetObjectAttributesResult{}, err
return s3response.GetObjectAttributesResult{}, nil
}
resp, err := p.ListParts(ctx, &s3.ListPartsInput{
Bucket: input.Bucket,
Key: input.Key,
UploadId: &uploadId,
PartNumberMarker: input.PartNumberMarker,
MaxParts: input.MaxParts,
})
if err != nil {
return s3response.GetObjectAttributesResult{}, err
}
parts := []types.ObjectPart{}
for _, p := range resp.Parts {
if !(p.PartNumber > 0 && p.PartNumber <= math.MaxInt32) {
return s3response.GetObjectAttributesResult{},
s3err.GetAPIError(s3err.ErrInvalidPartNumber)
}
partNumber := int32(p.PartNumber)
size := p.Size
parts = append(parts, types.ObjectPart{
Size: &size,
PartNumber: &partNumber,
})
}
//TODO: handle PartsCount prop
//TODO: Maybe simply calling ListParts isn't a good option
return s3response.GetObjectAttributesResult{
ObjectParts: &s3response.ObjectParts{
IsTruncated: resp.IsTruncated,
MaxParts: resp.MaxParts,
PartNumberMarker: resp.PartNumberMarker,
NextPartNumberMarker: resp.NextPartNumberMarker,
Parts: parts,
},
StorageClass: types.StorageClassStandard,
ETag: data.ETag,
LastModified: data.LastModified,
ObjectSize: data.ContentLength,
StorageClass: data.StorageClass,
}, nil
}

View File

@@ -152,8 +152,6 @@ func TestGetObjectAttributes(s *S3Conf) {
GetObjectAttributes_non_existing_bucket(s)
GetObjectAttributes_non_existing_object(s)
GetObjectAttributes_existing_object(s)
GetObjectAttributes_multipart_upload(s)
GetObjectAttributes_multipart_upload_truncated(s)
}
func TestGetObject(s *S3Conf) {
@@ -604,8 +602,6 @@ func GetIntTests() IntTests {
"GetObjectAttributes_non_existing_bucket": GetObjectAttributes_non_existing_bucket,
"GetObjectAttributes_non_existing_object": GetObjectAttributes_non_existing_object,
"GetObjectAttributes_existing_object": GetObjectAttributes_existing_object,
"GetObjectAttributes_multipart_upload": GetObjectAttributes_multipart_upload,
"GetObjectAttributes_multipart_upload_truncated": GetObjectAttributes_multipart_upload_truncated,
"GetObject_non_existing_key": GetObject_non_existing_key,
"GetObject_invalid_ranges": GetObject_invalid_ranges,
"GetObject_with_meta": GetObject_with_meta,

View File

@@ -3193,159 +3193,6 @@ func GetObjectAttributes_existing_object(s *S3Conf) error {
})
}
func GetObjectAttributes_multipart_upload(s *S3Conf) error {
testName := "GetObjectAttributes_multipart_upload"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
obj := "my-obj"
out, err := createMp(s3client, bucket, obj)
if err != nil {
return err
}
parts, err := uploadParts(s3client, 5*1024*1024, 5, bucket, obj, *out.UploadId)
if err != nil {
return err
}
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
resp, err := s3client.GetObjectAttributes(ctx, &s3.GetObjectAttributesInput{
Bucket: &bucket,
Key: &obj,
ObjectAttributes: []types.ObjectAttributes{
types.ObjectAttributesObjectParts,
types.ObjectAttributesStorageClass,
},
})
cancel()
if err != nil {
return err
}
if resp.ObjectParts == nil {
return fmt.Errorf("expected non nil object parts")
}
if resp.StorageClass != types.StorageClassStandard {
return fmt.Errorf("expected the storage class to be %v, instead got %v", types.StorageClassStandard, resp.StorageClass)
}
for i, p := range resp.ObjectParts.Parts {
if *p.PartNumber != *parts[i].PartNumber {
return fmt.Errorf("expected part number to be %v, instead got %v", *parts[i].PartNumber, *p.PartNumber)
}
if *p.Size != *parts[i].Size {
return fmt.Errorf("expected part size to be %v, instead got %v", *parts[i].Size, *p.Size)
}
}
return nil
})
}
func GetObjectAttributes_multipart_upload_truncated(s *S3Conf) error {
testName := "GetObjectAttributes_multipart_upload_truncated"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
obj := "my-obj"
out, err := createMp(s3client, bucket, obj)
if err != nil {
return err
}
parts, err := uploadParts(s3client, 5*1024*1024, 5, bucket, obj, *out.UploadId)
if err != nil {
return err
}
maxParts := int32(3)
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
resp, err := s3client.GetObjectAttributes(ctx, &s3.GetObjectAttributesInput{
Bucket: &bucket,
Key: &obj,
ObjectAttributes: []types.ObjectAttributes{
types.ObjectAttributesObjectParts,
},
MaxParts: &maxParts,
})
cancel()
if err != nil {
return err
}
if resp.ObjectParts == nil {
return fmt.Errorf("expected non nil object parts")
}
if resp.ObjectParts.IsTruncated == nil {
return fmt.Errorf("expected non nil isTruncated")
}
if !*resp.ObjectParts.IsTruncated {
return fmt.Errorf("expected object parts to be truncated")
}
if resp.ObjectParts.MaxParts == nil {
return fmt.Errorf("expected non nil max-parts")
}
if *resp.ObjectParts.MaxParts != maxParts {
return fmt.Errorf("expected max-parts to be %v, instead got %v", maxParts, *resp.ObjectParts.MaxParts)
}
if resp.ObjectParts.NextPartNumberMarker == nil {
return fmt.Errorf("expected non nil NextPartNumberMarker")
}
if *resp.ObjectParts.NextPartNumberMarker != fmt.Sprint(*parts[2].PartNumber) {
return fmt.Errorf("expected NextPartNumberMarker to be %v, instead got %v", fmt.Sprint(*parts[2].PartNumber), *resp.ObjectParts.NextPartNumberMarker)
}
if len(resp.ObjectParts.Parts) != int(maxParts) {
return fmt.Errorf("expected length of parts to be %v, instead got %v", maxParts, len(resp.ObjectParts.Parts))
}
for i, p := range resp.ObjectParts.Parts {
if *p.PartNumber != *parts[i].PartNumber {
return fmt.Errorf("expected part number to be %v, instead got %v", *parts[i].PartNumber, *p.PartNumber)
}
if *p.Size != *parts[i].Size {
return fmt.Errorf("expected part size to be %v, instead got %v", *parts[i].Size, *p.Size)
}
}
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
resp, err = s3client.GetObjectAttributes(ctx, &s3.GetObjectAttributesInput{
Bucket: &bucket,
Key: &obj,
ObjectAttributes: []types.ObjectAttributes{
types.ObjectAttributesObjectParts,
},
PartNumberMarker: resp.ObjectParts.NextPartNumberMarker,
})
cancel()
if err != nil {
return err
}
if resp.ObjectParts == nil {
return fmt.Errorf("expected non nil object parts")
}
if resp.ObjectParts.IsTruncated == nil {
return fmt.Errorf("expected non nil isTruncated")
}
if *resp.ObjectParts.IsTruncated {
return fmt.Errorf("expected object parts to not be truncated")
}
if len(resp.ObjectParts.Parts) != len(parts)-int(maxParts) {
return fmt.Errorf("expected length of parts to be %v, instead got %v", len(parts)-int(maxParts), len(resp.ObjectParts.Parts))
}
for i, p := range resp.ObjectParts.Parts {
if *p.PartNumber != *parts[i+int(maxParts)].PartNumber {
return fmt.Errorf("expected part number to be %v, instead got %v", *parts[i+int(maxParts)].PartNumber, *p.PartNumber)
}
if *p.Size != *parts[i+int(maxParts)].Size {
return fmt.Errorf("expected part size to be %v, instead got %v", *parts[i+int(maxParts)].Size, *p.Size)
}
}
return nil
})
}
func GetObject_non_existing_key(s *S3Conf) error {
testName := "GetObject_non_existing_key"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {