Skip to content

Commit

Permalink
miniogw: set ListParts continuation token correctly
Browse files Browse the repository at this point in the history
Previously ListParts made no effort to set the NextPartNumberMarker
continuation token correctly.  It's easy, it just the last part number
seen!

https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html

Closes #53

Change-Id: I5fa7a2c07abb99ec0dd51963abdaac6b1ef83927
  • Loading branch information
wthorp authored and amwolff committed Feb 15, 2022
1 parent 744daea commit b17c44b
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 8 deletions.
15 changes: 7 additions & 8 deletions miniogw/multipart.go
Expand Up @@ -8,7 +8,6 @@ import (
"errors"
"fmt"
"math"
"sort"

"github.com/zeebo/errs"

Expand Down Expand Up @@ -246,17 +245,17 @@ func (layer *gatewayLayer) ListObjectParts(ctx context.Context, bucket, object,
if list.Err() != nil {
return result, convertMultipartError(list.Err(), bucket, object, uploadID)
}

sort.Slice(parts, func(i, k int) bool {
return parts[i].PartNumber < parts[k].PartNumber
})
nextPartNumberMarker := partNumberMarker
if len(parts) > 0 {
nextPartNumberMarker = parts[len(parts)-1].PartNumber
}
return minio.ListPartsInfo{
Bucket: bucket,
Object: object,
UploadID: uploadID,
StorageClass: "", // TODO
PartNumberMarker: partNumberMarker, // Part number after which listing begins.
NextPartNumberMarker: partNumberMarker, // TODO Next part number marker to be used if list is truncated
StorageClass: storageclass.STANDARD,
PartNumberMarker: partNumberMarker, // Part number after which listing begins.
NextPartNumberMarker: nextPartNumberMarker, // NextPartNum is really more like last part num.
MaxParts: maxParts,
IsTruncated: more,
Parts: parts,
Expand Down
34 changes: 34 additions & 0 deletions testsuite/miniogw/gateway_test.go
Expand Up @@ -2910,6 +2910,40 @@ func TestListObjectParts(t *testing.T) {
assert.WithinDuration(t, now, listParts.Parts[i].LastModified, 5*time.Second)
assert.Equal(t, minioReaders[i].MD5CurrentHexString(), listParts.Parts[i].ETag)
}

// try batch of two
listParts, err = layer.ListObjectParts(ctx, testBucket, testFile, uploadID, 0, 2, minio.ObjectOptions{})
require.NoError(t, err)
require.Equal(t, testBucket, listParts.Bucket)
require.Equal(t, testFile, listParts.Object)
require.Equal(t, uploadID, listParts.UploadID)
require.Equal(t, 0, listParts.PartNumberMarker)
require.Equal(t, 0+2, listParts.NextPartNumberMarker)
require.Len(t, listParts.Parts, 2)
for i := 0; i < 2; i++ {
assert.Equal(t, i+1, listParts.Parts[i].PartNumber)
assert.Equal(t, minioReaders[i].Size(), listParts.Parts[i].Size)
assert.Equal(t, minioReaders[i].ActualSize(), listParts.Parts[i].ActualSize)
assert.WithinDuration(t, now, listParts.Parts[i].LastModified, 5*time.Second)
assert.Equal(t, minioReaders[i].MD5CurrentHexString(), listParts.Parts[i].ETag)
}

// try batch of remaining
listParts, err = layer.ListObjectParts(ctx, testBucket, testFile, uploadID, 2, 1000, minio.ObjectOptions{})
require.NoError(t, err)
require.Equal(t, testBucket, listParts.Bucket)
require.Equal(t, testFile, listParts.Object)
require.Equal(t, uploadID, listParts.UploadID)
require.Equal(t, 2, listParts.PartNumberMarker)
require.Equal(t, totalPartsCount, listParts.NextPartNumberMarker)
require.Len(t, listParts.Parts, totalPartsCount-2)
for i := 0; i < totalPartsCount-2; i++ {
assert.Equal(t, i+1+2, listParts.Parts[i].PartNumber)
assert.Equal(t, minioReaders[i].Size(), listParts.Parts[i].Size)
assert.Equal(t, minioReaders[i].ActualSize(), listParts.Parts[i].ActualSize)
assert.WithinDuration(t, now, listParts.Parts[i].LastModified, 5*time.Second)
assert.Equal(t, minioReaders[i].MD5CurrentHexString(), listParts.Parts[i].ETag)
}
})
}

Expand Down

0 comments on commit b17c44b

Please sign in to comment.