mirror of
https://github.com/minio/minio.git
synced 2024-12-24 06:05:55 -05:00
Add public data-types for easier external loading (#5170)
This change brings public data-types such that we can ask projects to implement gateway projects externally than maintaining in our repo. All publicly exported structs are maintained in object-api-datatypes.go completePart --> CompletePart uploadMetadata --> MultipartInfo All other exported errors are at object-api-errors.go
This commit is contained in:
parent
7d3eaf79ff
commit
a4d6195244
@ -359,15 +359,15 @@ func initFormatFS(fsPath string) (rlk *lock.RLockedFile, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Return if the part info in uploadedParts and completeParts are same.
|
||||
func isPartsSame(uploadedParts []objectPartInfo, completeParts []completePart) bool {
|
||||
if len(uploadedParts) != len(completeParts) {
|
||||
// Return if the part info in uploadedParts and CompleteParts are same.
|
||||
func isPartsSame(uploadedParts []objectPartInfo, CompleteParts []CompletePart) bool {
|
||||
if len(uploadedParts) != len(CompleteParts) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := range completeParts {
|
||||
if uploadedParts[i].Number != completeParts[i].PartNumber ||
|
||||
uploadedParts[i].ETag != completeParts[i].ETag {
|
||||
for i := range CompleteParts {
|
||||
if uploadedParts[i].Number != CompleteParts[i].PartNumber ||
|
||||
uploadedParts[i].ETag != CompleteParts[i].ETag {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -110,8 +110,8 @@ func (fs fsObjects) addUploadID(bucket, object, uploadID string, initiated time.
|
||||
}
|
||||
|
||||
// listMultipartUploadIDs - list all the upload ids from a marker up to 'count'.
|
||||
func (fs fsObjects) listMultipartUploadIDs(bucketName, objectName, uploadIDMarker string, count int) ([]uploadMetadata, bool, error) {
|
||||
var uploads []uploadMetadata
|
||||
func (fs fsObjects) listMultipartUploadIDs(bucketName, objectName, uploadIDMarker string, count int) ([]MultipartInfo, bool, error) {
|
||||
var uploads []MultipartInfo
|
||||
|
||||
// Hold the lock so that two parallel complete-multipart-uploads
|
||||
// do not leave a stale uploads.json behind.
|
||||
@ -149,7 +149,7 @@ func (fs fsObjects) listMultipartUploadIDs(bucketName, objectName, uploadIDMarke
|
||||
}
|
||||
|
||||
for index < len(uploadIDs.Uploads) {
|
||||
uploads = append(uploads, uploadMetadata{
|
||||
uploads = append(uploads, MultipartInfo{
|
||||
Object: objectName,
|
||||
UploadID: uploadIDs.Uploads[index].UploadID,
|
||||
Initiated: uploadIDs.Uploads[index].Initiated,
|
||||
@ -191,7 +191,7 @@ func (fs fsObjects) listMultipartUploadsCleanup(bucket, prefix, keyMarker, uploa
|
||||
multipartMarkerPath = pathJoin(bucket, keyMarker)
|
||||
}
|
||||
|
||||
var uploads []uploadMetadata
|
||||
var uploads []MultipartInfo
|
||||
var err error
|
||||
var eof bool
|
||||
|
||||
@ -244,7 +244,7 @@ func (fs fsObjects) listMultipartUploadsCleanup(bucket, prefix, keyMarker, uploa
|
||||
|
||||
entry := strings.TrimPrefix(walkResult.entry, retainSlash(bucket))
|
||||
if hasSuffix(walkResult.entry, slashSeparator) {
|
||||
uploads = append(uploads, uploadMetadata{
|
||||
uploads = append(uploads, MultipartInfo{
|
||||
Object: entry,
|
||||
})
|
||||
maxUploads--
|
||||
@ -257,7 +257,7 @@ func (fs fsObjects) listMultipartUploadsCleanup(bucket, prefix, keyMarker, uploa
|
||||
continue
|
||||
}
|
||||
|
||||
var tmpUploads []uploadMetadata
|
||||
var tmpUploads []MultipartInfo
|
||||
var end bool
|
||||
uploadIDMarker = ""
|
||||
|
||||
@ -713,7 +713,7 @@ func (fs fsObjects) ListObjectParts(bucket, object, uploadID string, partNumberM
|
||||
// md5sums of all the parts.
|
||||
//
|
||||
// Implements S3 compatible Complete multipart API.
|
||||
func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, uploadID string, parts []completePart) (oi ObjectInfo, e error) {
|
||||
func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, uploadID string, parts []CompletePart) (oi ObjectInfo, e error) {
|
||||
if err := checkCompleteMultipartArgs(bucket, object, fs); err != nil {
|
||||
return oi, err
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ func TestCompleteMultipartUploadFaultyDisk(t *testing.T) {
|
||||
t.Fatal("Unexpected error ", err)
|
||||
}
|
||||
|
||||
parts := []completePart{{PartNumber: 1, ETag: md5Hex}}
|
||||
parts := []CompletePart{{PartNumber: 1, ETag: md5Hex}}
|
||||
|
||||
fs.fsPath = filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
|
||||
if _, err := fs.CompleteMultipartUpload(bucketName, objectName, uploadID, parts); err != nil {
|
||||
@ -253,7 +253,7 @@ func TestCompleteMultipartUpload(t *testing.T) {
|
||||
t.Fatal("Unexpected error ", err)
|
||||
}
|
||||
|
||||
parts := []completePart{{PartNumber: 1, ETag: md5Hex}}
|
||||
parts := []CompletePart{{PartNumber: 1, ETag: md5Hex}}
|
||||
|
||||
if _, err := fs.CompleteMultipartUpload(bucketName, objectName, uploadID, parts); err != nil {
|
||||
t.Fatal("Unexpected error ", err)
|
||||
|
@ -756,7 +756,7 @@ func (a *azureObjects) AbortMultipartUpload(bucket, object, uploadID string) (er
|
||||
}
|
||||
|
||||
// CompleteMultipartUpload - Use Azure equivalent PutBlockList.
|
||||
func (a *azureObjects) CompleteMultipartUpload(bucket, object, uploadID string, uploadedParts []completePart) (objInfo ObjectInfo, err error) {
|
||||
func (a *azureObjects) CompleteMultipartUpload(bucket, object, uploadID string, uploadedParts []CompletePart) (objInfo ObjectInfo, err error) {
|
||||
metadataObject := getAzureMetadataObjectName(object, uploadID)
|
||||
if err = a.checkUploadIDExists(bucket, object, uploadID); err != nil {
|
||||
return objInfo, err
|
||||
|
@ -566,7 +566,7 @@ func (l *b2Objects) ListMultipartUploads(bucket string, prefix string, keyMarker
|
||||
lmi.NextUploadIDMarker = nextMarker
|
||||
}
|
||||
for _, largeFile := range largeFiles {
|
||||
lmi.Uploads = append(lmi.Uploads, uploadMetadata{
|
||||
lmi.Uploads = append(lmi.Uploads, MultipartInfo{
|
||||
Object: largeFile.Name,
|
||||
UploadID: largeFile.ID,
|
||||
Initiated: largeFile.Timestamp,
|
||||
@ -673,7 +673,7 @@ func (l *b2Objects) AbortMultipartUpload(bucket string, object string, uploadID
|
||||
}
|
||||
|
||||
// CompleteMultipartUpload completes ongoing multipart upload and finalizes object, uses B2's LargeFile upload API.
|
||||
func (l *b2Objects) CompleteMultipartUpload(bucket string, object string, uploadID string, uploadedParts []completePart) (oi ObjectInfo, err error) {
|
||||
func (l *b2Objects) CompleteMultipartUpload(bucket string, object string, uploadID string, uploadedParts []CompletePart) (oi ObjectInfo, err error) {
|
||||
bkt, err := l.Bucket(bucket)
|
||||
if err != nil {
|
||||
return oi, err
|
||||
|
@ -1015,7 +1015,7 @@ func (l *gcsGateway) AbortMultipartUpload(bucket string, key string, uploadID st
|
||||
// to the number of components you can compose per second. This rate counts both the
|
||||
// components being appended to a composite object as well as the components being
|
||||
// copied when the composite object of which they are a part is copied.
|
||||
func (l *gcsGateway) CompleteMultipartUpload(bucket string, key string, uploadID string, uploadedParts []completePart) (ObjectInfo, error) {
|
||||
func (l *gcsGateway) CompleteMultipartUpload(bucket string, key string, uploadID string, uploadedParts []CompletePart) (ObjectInfo, error) {
|
||||
meta := gcsMultipartMetaName(uploadID)
|
||||
object := l.client.Bucket(bucket).Object(meta)
|
||||
|
||||
|
@ -447,9 +447,9 @@ func (l *s3Objects) DeleteObject(bucket string, object string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// fromMinioClientUploadMetadata converts ObjectMultipartInfo to uploadMetadata
|
||||
func fromMinioClientUploadMetadata(omi minio.ObjectMultipartInfo) uploadMetadata {
|
||||
return uploadMetadata{
|
||||
// fromMinioClientMultipartInfo converts ObjectMultipartInfo to MultipartInfo
|
||||
func fromMinioClientMultipartInfo(omi minio.ObjectMultipartInfo) MultipartInfo {
|
||||
return MultipartInfo{
|
||||
Object: omi.Key,
|
||||
UploadID: omi.UploadID,
|
||||
Initiated: omi.Initiated,
|
||||
@ -458,10 +458,10 @@ func fromMinioClientUploadMetadata(omi minio.ObjectMultipartInfo) uploadMetadata
|
||||
|
||||
// fromMinioClientListMultipartsInfo converts minio ListMultipartUploadsResult to ListMultipartsInfo
|
||||
func fromMinioClientListMultipartsInfo(lmur minio.ListMultipartUploadsResult) ListMultipartsInfo {
|
||||
uploads := make([]uploadMetadata, len(lmur.Uploads))
|
||||
uploads := make([]MultipartInfo, len(lmur.Uploads))
|
||||
|
||||
for i, um := range lmur.Uploads {
|
||||
uploads[i] = fromMinioClientUploadMetadata(um)
|
||||
uploads[i] = fromMinioClientMultipartInfo(um)
|
||||
}
|
||||
|
||||
commonPrefixes := make([]string, len(lmur.CommonPrefixes))
|
||||
@ -585,16 +585,16 @@ func (l *s3Objects) AbortMultipartUpload(bucket string, object string, uploadID
|
||||
return s3ToObjectError(traceError(err), bucket, object)
|
||||
}
|
||||
|
||||
// toMinioClientCompletePart converts completePart to minio CompletePart
|
||||
func toMinioClientCompletePart(part completePart) minio.CompletePart {
|
||||
// toMinioClientCompletePart converts CompletePart to minio CompletePart
|
||||
func toMinioClientCompletePart(part CompletePart) minio.CompletePart {
|
||||
return minio.CompletePart{
|
||||
ETag: part.ETag,
|
||||
PartNumber: part.PartNumber,
|
||||
}
|
||||
}
|
||||
|
||||
// toMinioClientCompleteParts converts []completePart to minio []CompletePart
|
||||
func toMinioClientCompleteParts(parts []completePart) []minio.CompletePart {
|
||||
// toMinioClientCompleteParts converts []CompletePart to minio []CompletePart
|
||||
func toMinioClientCompleteParts(parts []CompletePart) []minio.CompletePart {
|
||||
mparts := make([]minio.CompletePart, len(parts))
|
||||
for i, part := range parts {
|
||||
mparts[i] = toMinioClientCompletePart(part)
|
||||
@ -603,7 +603,7 @@ func toMinioClientCompleteParts(parts []completePart) []minio.CompletePart {
|
||||
}
|
||||
|
||||
// CompleteMultipartUpload completes ongoing multipart upload and finalizes object
|
||||
func (l *s3Objects) CompleteMultipartUpload(bucket string, object string, uploadID string, uploadedParts []completePart) (oi ObjectInfo, e error) {
|
||||
func (l *s3Objects) CompleteMultipartUpload(bucket string, object string, uploadID string, uploadedParts []CompletePart) (oi ObjectInfo, e error) {
|
||||
err := l.Client.CompleteMultipartUpload(bucket, object, uploadID, toMinioClientCompleteParts(uploadedParts))
|
||||
if err != nil {
|
||||
return oi, s3ToObjectError(traceError(err), bucket, object)
|
||||
|
@ -181,7 +181,7 @@ type ListMultipartsInfo struct {
|
||||
IsTruncated bool
|
||||
|
||||
// List of all pending uploads.
|
||||
Uploads []uploadMetadata
|
||||
Uploads []MultipartInfo
|
||||
|
||||
// When a prefix is provided in the request, The result contains only keys
|
||||
// starting with the specified prefix.
|
||||
@ -261,8 +261,8 @@ type PartInfo struct {
|
||||
Size int64
|
||||
}
|
||||
|
||||
// uploadMetadata - represents metadata in progress multipart upload.
|
||||
type uploadMetadata struct {
|
||||
// MultipartInfo - represents metadata in progress multipart upload.
|
||||
type MultipartInfo struct {
|
||||
// Object name for which the multipart upload was initiated.
|
||||
Object string
|
||||
|
||||
@ -277,8 +277,9 @@ type uploadMetadata struct {
|
||||
HealUploadInfo *HealObjectInfo `xml:"HealUploadInfo,omitempty"`
|
||||
}
|
||||
|
||||
// completePart - completed part container.
|
||||
type completePart struct {
|
||||
// CompletePart - represents the part that was completed, this is sent by the client
|
||||
// during CompleteMultipartUpload request.
|
||||
type CompletePart struct {
|
||||
// Part number identifying the part. This is a positive integer between 1 and
|
||||
// 10,000
|
||||
PartNumber int
|
||||
@ -287,14 +288,15 @@ type completePart struct {
|
||||
ETag string
|
||||
}
|
||||
|
||||
// completedParts - is a collection satisfying sort.Interface.
|
||||
type completedParts []completePart
|
||||
// CompletedParts - is a collection satisfying sort.Interface.
|
||||
type CompletedParts []CompletePart
|
||||
|
||||
func (a completedParts) Len() int { return len(a) }
|
||||
func (a completedParts) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a completedParts) Less(i, j int) bool { return a[i].PartNumber < a[j].PartNumber }
|
||||
func (a CompletedParts) Len() int { return len(a) }
|
||||
func (a CompletedParts) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a CompletedParts) Less(i, j int) bool { return a[i].PartNumber < a[j].PartNumber }
|
||||
|
||||
// completeMultipartUpload - represents input fields for completing multipart upload.
|
||||
type completeMultipartUpload struct {
|
||||
Parts []completePart `xml:"Part"`
|
||||
// CompleteMultipartUpload - represents list of parts which are completed, this is sent by the
|
||||
// client during CompleteMultipartUpload request.
|
||||
type CompleteMultipartUpload struct {
|
||||
Parts []CompletePart `xml:"Part"`
|
||||
}
|
||||
|
@ -263,13 +263,13 @@ func (e IncompleteBody) Error() string {
|
||||
|
||||
// InvalidRange - invalid range typed error.
|
||||
type InvalidRange struct {
|
||||
offsetBegin int64
|
||||
offsetEnd int64
|
||||
resourceSize int64
|
||||
OffsetBegin int64
|
||||
OffsetEnd int64
|
||||
ResourceSize int64
|
||||
}
|
||||
|
||||
func (e InvalidRange) Error() string {
|
||||
return fmt.Sprintf("The requested range \"bytes %d-%d/%d\" is not satisfiable.", e.offsetBegin, e.offsetEnd, e.resourceSize)
|
||||
return fmt.Sprintf("The requested range \"bytes %d-%d/%d\" is not satisfiable.", e.OffsetBegin, e.OffsetEnd, e.ResourceSize)
|
||||
}
|
||||
|
||||
// ObjectTooLarge error returned when the size of the object > max object size allowed (5G) per request.
|
||||
@ -375,7 +375,7 @@ func (e UnsupportedMetadata) Error() string {
|
||||
return "Unsupported headers in Metadata"
|
||||
}
|
||||
|
||||
// Check if error type is IncompleteBody.
|
||||
// isErrIncompleteBody - Check if error type is IncompleteBody.
|
||||
func isErrIncompleteBody(err error) bool {
|
||||
err = errorCause(err)
|
||||
switch err.(type) {
|
||||
@ -385,7 +385,7 @@ func isErrIncompleteBody(err error) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if error type is BucketPolicyNotFound.
|
||||
// isErrBucketPolicyNotFound - Check if error type is BucketPolicyNotFound.
|
||||
func isErrBucketPolicyNotFound(err error) bool {
|
||||
err = errorCause(err)
|
||||
switch err.(type) {
|
||||
@ -395,7 +395,7 @@ func isErrBucketPolicyNotFound(err error) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if error type is ObjectNotFound.
|
||||
// isErrObjectNotFound - Check if error type is ObjectNotFound.
|
||||
func isErrObjectNotFound(err error) bool {
|
||||
err = errorCause(err)
|
||||
switch err.(type) {
|
||||
|
@ -49,7 +49,7 @@ type ObjectLayer interface {
|
||||
PutObjectPart(bucket, object, uploadID string, partID int, data *hash.Reader) (info PartInfo, err error)
|
||||
ListObjectParts(bucket, object, uploadID string, partNumberMarker int, maxParts int) (result ListPartsInfo, err error)
|
||||
AbortMultipartUpload(bucket, object, uploadID string) error
|
||||
CompleteMultipartUpload(bucket, object, uploadID string, uploadedParts []completePart) (objInfo ObjectInfo, err error)
|
||||
CompleteMultipartUpload(bucket, object, uploadID string, uploadedParts []CompletePart) (objInfo ObjectInfo, err error)
|
||||
|
||||
// Healing operations.
|
||||
HealBucket(bucket string) error
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Minio Cloud Storage, (C) 2016 Minio, Inc.
|
||||
* Minio Cloud Storage, (C) 2016, 2017 Minio, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -161,8 +161,8 @@ func writeUploadJSON(u *uploadsV1, uploadsPath, tmpPath string, disk StorageAPI)
|
||||
}
|
||||
|
||||
// listMultipartUploadIDs - list all the upload ids from a marker up to 'count'.
|
||||
func listMultipartUploadIDs(bucketName, objectName, uploadIDMarker string, count int, disk StorageAPI) ([]uploadMetadata, bool, error) {
|
||||
var uploads []uploadMetadata
|
||||
func listMultipartUploadIDs(bucketName, objectName, uploadIDMarker string, count int, disk StorageAPI) ([]MultipartInfo, bool, error) {
|
||||
var uploads []MultipartInfo
|
||||
// Read `uploads.json`.
|
||||
uploadsJSON, err := readUploadsJSON(bucketName, objectName, disk)
|
||||
if err != nil {
|
||||
@ -179,7 +179,7 @@ func listMultipartUploadIDs(bucketName, objectName, uploadIDMarker string, count
|
||||
}
|
||||
}
|
||||
for index < len(uploadsJSON.Uploads) {
|
||||
uploads = append(uploads, uploadMetadata{
|
||||
uploads = append(uploads, MultipartInfo{
|
||||
Object: objectName,
|
||||
UploadID: uploadsJSON.Uploads[index].UploadID,
|
||||
Initiated: uploadsJSON.Uploads[index].Initiated,
|
||||
|
@ -499,7 +499,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
// ListMultipartUploads doesn't list the parts.
|
||||
{
|
||||
MaxUploads: 100,
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[0],
|
||||
UploadID: uploadIDs[0],
|
||||
@ -515,7 +515,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
KeyMarker: "minio-object-1.txt",
|
||||
},
|
||||
// listMultipartResults - 3.
|
||||
// `KeyMarker` is set, no uploadMetadata expected.
|
||||
// `KeyMarker` is set, no MultipartInfo expected.
|
||||
// ListMultipartUploads doesn't list the parts.
|
||||
// `Maxupload` value is asserted.
|
||||
{
|
||||
@ -523,7 +523,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
KeyMarker: "orange",
|
||||
},
|
||||
// listMultipartResults - 4.
|
||||
// `KeyMarker` is set, no uploadMetadata expected.
|
||||
// `KeyMarker` is set, no MultipartInfo expected.
|
||||
// Maxupload value is asserted.
|
||||
{
|
||||
MaxUploads: 1,
|
||||
@ -531,12 +531,12 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
},
|
||||
// listMultipartResults - 5.
|
||||
// `KeyMarker` is set. It contains part of the objectname as `KeyPrefix`.
|
||||
// Expecting the result to contain one uploadMetadata entry and Istruncated to be false.
|
||||
// Expecting the result to contain one MultipartInfo entry and Istruncated to be false.
|
||||
{
|
||||
MaxUploads: 10,
|
||||
KeyMarker: "min",
|
||||
IsTruncated: false,
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[0],
|
||||
UploadID: uploadIDs[0],
|
||||
@ -546,12 +546,12 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
// listMultipartResults - 6.
|
||||
// `KeyMarker` is set. It contains part of the objectname as `KeyPrefix`.
|
||||
// `MaxUploads` is set equal to the number of meta data entries in the result, the result contains only one entry.
|
||||
// Expecting the result to contain one uploadMetadata entry and IsTruncated to be false.
|
||||
// Expecting the result to contain one MultipartInfo entry and IsTruncated to be false.
|
||||
{
|
||||
MaxUploads: 1,
|
||||
KeyMarker: "min",
|
||||
IsTruncated: false,
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[0],
|
||||
UploadID: uploadIDs[0],
|
||||
@ -561,7 +561,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
// listMultipartResults - 7.
|
||||
// `KeyMarker` is set. It contains part of the objectname as `KeyPrefix`.
|
||||
// Testing for the case with `MaxUploads` set to 0.
|
||||
// Expecting the result to contain no uploadMetadata entry since `MaxUploads` is set to 0.
|
||||
// Expecting the result to contain no MultipartInfo entry since `MaxUploads` is set to 0.
|
||||
// Expecting `IsTruncated` to be true.
|
||||
{
|
||||
MaxUploads: 0,
|
||||
@ -571,7 +571,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
// listMultipartResults - 8.
|
||||
// `KeyMarker` is set. It contains part of the objectname as KeyPrefix.
|
||||
// Testing for the case with `MaxUploads` set to 0.
|
||||
// Expecting the result to contain no uploadMetadata entry since `MaxUploads` is set to 0.
|
||||
// Expecting the result to contain no MultipartInfo entry since `MaxUploads` is set to 0.
|
||||
// Expecting `isTruncated` to be true.
|
||||
{
|
||||
MaxUploads: 0,
|
||||
@ -581,12 +581,12 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
// listMultipartResults - 9.
|
||||
// `KeyMarker` is set. It contains part of the objectname as KeyPrefix.
|
||||
// `KeyMarker` is set equal to the object name in the result.
|
||||
// Expecting the result to contain one uploadMetadata entry and IsTruncated to be false.
|
||||
// Expecting the result to contain one MultipartInfo entry and IsTruncated to be false.
|
||||
{
|
||||
MaxUploads: 2,
|
||||
KeyMarker: "minio-object",
|
||||
IsTruncated: false,
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[0],
|
||||
UploadID: uploadIDs[0],
|
||||
@ -596,12 +596,12 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
// listMultipartResults - 10.
|
||||
// Prefix is set. It is set equal to the object name.
|
||||
// MaxUploads is set more than number of meta data entries in the result.
|
||||
// Expecting the result to contain one uploadMetadata entry and IsTruncated to be false.
|
||||
// Expecting the result to contain one MultipartInfo entry and IsTruncated to be false.
|
||||
{
|
||||
MaxUploads: 2,
|
||||
Prefix: "minio-object-1.txt",
|
||||
IsTruncated: false,
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[0],
|
||||
UploadID: uploadIDs[0],
|
||||
@ -611,12 +611,12 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
// listMultipartResults - 11.
|
||||
// Setting `Prefix` to contain the object name as its prefix.
|
||||
// MaxUploads is set more than number of meta data entries in the result.
|
||||
// Expecting the result to contain one uploadMetadata entry and IsTruncated to be false.
|
||||
// Expecting the result to contain one MultipartInfo entry and IsTruncated to be false.
|
||||
{
|
||||
MaxUploads: 2,
|
||||
Prefix: "min",
|
||||
IsTruncated: false,
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[0],
|
||||
UploadID: uploadIDs[0],
|
||||
@ -626,12 +626,12 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
// listMultipartResults - 12.
|
||||
// Setting `Prefix` to contain the object name as its prefix.
|
||||
// MaxUploads is set equal to number of meta data entries in the result.
|
||||
// Expecting the result to contain one uploadMetadata entry and IsTruncated to be false.
|
||||
// Expecting the result to contain one MultipartInfo entry and IsTruncated to be false.
|
||||
{
|
||||
MaxUploads: 1,
|
||||
Prefix: "min",
|
||||
IsTruncated: false,
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[0],
|
||||
UploadID: uploadIDs[0],
|
||||
@ -659,13 +659,13 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
// listMultipartResults - 15.
|
||||
// Setting `Delimiter`.
|
||||
// MaxUploads is set more than number of meta data entries in the result.
|
||||
// Expecting the result to contain one uploadMetadata entry and IsTruncated to be false.
|
||||
// Expecting the result to contain one MultipartInfo entry and IsTruncated to be false.
|
||||
{
|
||||
MaxUploads: 2,
|
||||
Delimiter: "/",
|
||||
Prefix: "",
|
||||
IsTruncated: false,
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[0],
|
||||
UploadID: uploadIDs[0],
|
||||
@ -677,7 +677,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
// Will be used to list on bucketNames[1].
|
||||
{
|
||||
MaxUploads: 100,
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[0],
|
||||
UploadID: uploadIDs[1],
|
||||
@ -703,7 +703,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
KeyMarker: "minio-object-1.txt",
|
||||
UploadIDMarker: uploadIDs[1],
|
||||
IsTruncated: false,
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[0],
|
||||
UploadID: uploadIDs[2],
|
||||
@ -725,7 +725,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
KeyMarker: "minio-object-1.txt",
|
||||
UploadIDMarker: uploadIDs[2],
|
||||
IsTruncated: false,
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[0],
|
||||
UploadID: uploadIDs[3],
|
||||
@ -734,7 +734,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
},
|
||||
// listMultipartResults - 19.
|
||||
// Testing for listing of 3 uploadID's for a given object, setting maxKeys to be 2.
|
||||
// There are 3 uploadMetadata in the result (uploadIDs[1-3]), it should be truncated to 2.
|
||||
// There are 3 MultipartInfo in the result (uploadIDs[1-3]), it should be truncated to 2.
|
||||
// Since there is only single object for bucketNames[1], the NextKeyMarker is set to its name.
|
||||
// The last entry in the result, uploadIDs[2], that is should be set as NextUploadIDMarker.
|
||||
// Will be used to list on bucketNames[1].
|
||||
@ -743,7 +743,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
IsTruncated: true,
|
||||
NextKeyMarker: objectNames[0],
|
||||
NextUploadIDMarker: uploadIDs[2],
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[0],
|
||||
UploadID: uploadIDs[1],
|
||||
@ -756,7 +756,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
},
|
||||
// listMultipartResults - 20.
|
||||
// Testing for listing of 3 uploadID's for a given object, setting maxKeys to be 1.
|
||||
// There are 3 uploadMetadata in the result (uploadIDs[1-3]), it should be truncated to 1.
|
||||
// There are 3 MultipartInfo in the result (uploadIDs[1-3]), it should be truncated to 1.
|
||||
// The last entry in the result, uploadIDs[1], that is should be set as NextUploadIDMarker.
|
||||
// Will be used to list on bucketNames[1].
|
||||
{
|
||||
@ -764,7 +764,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
IsTruncated: true,
|
||||
NextKeyMarker: objectNames[0],
|
||||
NextUploadIDMarker: uploadIDs[1],
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[0],
|
||||
UploadID: uploadIDs[1],
|
||||
@ -773,13 +773,13 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
},
|
||||
// listMultipartResults - 21.
|
||||
// Testing for listing of 3 uploadID's for a given object, setting maxKeys to be 3.
|
||||
// There are 3 uploadMetadata in the result (uploadIDs[1-3]), hence no truncation is expected.
|
||||
// Since all the uploadMetadata is listed, expecting no values for NextUploadIDMarker and NextKeyMarker.
|
||||
// There are 3 MultipartInfo in the result (uploadIDs[1-3]), hence no truncation is expected.
|
||||
// Since all the MultipartInfo is listed, expecting no values for NextUploadIDMarker and NextKeyMarker.
|
||||
// Will be used to list on bucketNames[1].
|
||||
{
|
||||
MaxUploads: 3,
|
||||
IsTruncated: false,
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[0],
|
||||
UploadID: uploadIDs[1],
|
||||
@ -801,7 +801,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
MaxUploads: 10,
|
||||
IsTruncated: false,
|
||||
Prefix: "min",
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[0],
|
||||
UploadID: uploadIDs[1],
|
||||
@ -844,7 +844,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
IsTruncated: false,
|
||||
Prefix: "min",
|
||||
UploadIDMarker: uploadIDs[1],
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[0],
|
||||
UploadID: uploadIDs[2],
|
||||
@ -863,7 +863,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
MaxUploads: 100,
|
||||
IsTruncated: false,
|
||||
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[0],
|
||||
UploadID: uploadIDs[4],
|
||||
@ -896,7 +896,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
MaxUploads: 100,
|
||||
IsTruncated: false,
|
||||
Prefix: "min",
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[0],
|
||||
UploadID: uploadIDs[4],
|
||||
@ -913,7 +913,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
MaxUploads: 100,
|
||||
IsTruncated: false,
|
||||
Prefix: "ney",
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[2],
|
||||
UploadID: uploadIDs[6],
|
||||
@ -930,7 +930,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
MaxUploads: 100,
|
||||
IsTruncated: false,
|
||||
Prefix: "parrot",
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[4],
|
||||
UploadID: uploadIDs[8],
|
||||
@ -948,7 +948,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
MaxUploads: 100,
|
||||
IsTruncated: false,
|
||||
Prefix: "neymar.jpeg",
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[3],
|
||||
UploadID: uploadIDs[7],
|
||||
@ -965,7 +965,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
IsTruncated: true,
|
||||
NextUploadIDMarker: uploadIDs[6],
|
||||
NextKeyMarker: objectNames[2],
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[0],
|
||||
UploadID: uploadIDs[4],
|
||||
@ -987,7 +987,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
{
|
||||
MaxUploads: 6,
|
||||
IsTruncated: false,
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[0],
|
||||
UploadID: uploadIDs[4],
|
||||
@ -1020,7 +1020,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
MaxUploads: 10,
|
||||
IsTruncated: false,
|
||||
UploadIDMarker: uploadIDs[6],
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[3],
|
||||
UploadID: uploadIDs[7],
|
||||
@ -1041,7 +1041,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
MaxUploads: 10,
|
||||
IsTruncated: false,
|
||||
KeyMarker: objectNames[3],
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[4],
|
||||
UploadID: uploadIDs[8],
|
||||
@ -1054,7 +1054,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
},
|
||||
// listMultipartResults - 35.
|
||||
// Checking listing with `Prefix` and `KeyMarker`.
|
||||
// No upload uploadMetadata in the result expected since KeyMarker is set to last Key in the result.
|
||||
// No upload MultipartInfo in the result expected since KeyMarker is set to last Key in the result.
|
||||
{
|
||||
MaxUploads: 10,
|
||||
IsTruncated: false,
|
||||
@ -1068,7 +1068,7 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
IsTruncated: false,
|
||||
Prefix: "minio",
|
||||
UploadIDMarker: uploadIDs[4],
|
||||
Uploads: []uploadMetadata{
|
||||
Uploads: []MultipartInfo{
|
||||
{
|
||||
Object: objectNames[1],
|
||||
UploadID: uploadIDs[5],
|
||||
@ -1160,11 +1160,11 @@ func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHan
|
||||
{bucketNames[1], "", "minio-object-1.txt", uploadIDs[1], "", 100, listMultipartResults[16], nil, true},
|
||||
{bucketNames[1], "", "minio-object-1.txt", uploadIDs[2], "", 100, listMultipartResults[17], nil, true},
|
||||
// Test cases with multiple uploadID listing for a given object (Test number 31-32).
|
||||
// MaxKeys set to values lesser than the number of entries in the uploadMetadata.
|
||||
// MaxKeys set to values lesser than the number of entries in the MultipartInfo.
|
||||
// IsTruncated is expected to be true.
|
||||
{bucketNames[1], "", "", "", "", 2, listMultipartResults[18], nil, true},
|
||||
{bucketNames[1], "", "", "", "", 1, listMultipartResults[19], nil, true},
|
||||
// MaxKeys set to the value which is equal to no of entries in the uploadMetadata (Test number 33).
|
||||
// MaxKeys set to the value which is equal to no of entries in the MultipartInfo (Test number 33).
|
||||
// In case of bucketNames[1], there are 3 entries.
|
||||
// Since all available entries are listed, IsTruncated is expected to be false
|
||||
// and NextMarkers are expected to empty.
|
||||
@ -1836,19 +1836,19 @@ func testObjectCompleteMultipartUpload(obj ObjectLayer, instanceType string, t T
|
||||
}
|
||||
// Parts to be sent as input for CompleteMultipartUpload.
|
||||
inputParts := []struct {
|
||||
parts []completePart
|
||||
parts []CompletePart
|
||||
}{
|
||||
// inputParts - 0.
|
||||
// Case for replicating ETag mismatch.
|
||||
{
|
||||
[]completePart{
|
||||
[]CompletePart{
|
||||
{ETag: "abcd", PartNumber: 1},
|
||||
},
|
||||
},
|
||||
// inputParts - 1.
|
||||
// should error out with part too small.
|
||||
{
|
||||
[]completePart{
|
||||
[]CompletePart{
|
||||
{ETag: "e2fc714c4727ee9395f324cd2e7f331f", PartNumber: 1},
|
||||
{ETag: "1f7690ebdd9b4caf8fab49ca1757bf27", PartNumber: 2},
|
||||
},
|
||||
@ -1856,7 +1856,7 @@ func testObjectCompleteMultipartUpload(obj ObjectLayer, instanceType string, t T
|
||||
// inputParts - 2.
|
||||
// Case with invalid Part number.
|
||||
{
|
||||
[]completePart{
|
||||
[]CompletePart{
|
||||
{ETag: "e2fc714c4727ee9395f324cd2e7f331f", PartNumber: 10},
|
||||
},
|
||||
},
|
||||
@ -1864,7 +1864,7 @@ func testObjectCompleteMultipartUpload(obj ObjectLayer, instanceType string, t T
|
||||
// Case with valid part.
|
||||
// Part size greater than 5MB.
|
||||
{
|
||||
[]completePart{
|
||||
[]CompletePart{
|
||||
{ETag: validPartMD5, PartNumber: 5},
|
||||
},
|
||||
},
|
||||
@ -1872,7 +1872,7 @@ func testObjectCompleteMultipartUpload(obj ObjectLayer, instanceType string, t T
|
||||
// Used to verify that the other remaining parts are deleted after
|
||||
// a successful call to CompleteMultipartUpload.
|
||||
{
|
||||
[]completePart{
|
||||
[]CompletePart{
|
||||
{ETag: validPartMD5, PartNumber: 6},
|
||||
},
|
||||
},
|
||||
@ -1887,7 +1887,7 @@ func testObjectCompleteMultipartUpload(obj ObjectLayer, instanceType string, t T
|
||||
bucket string
|
||||
object string
|
||||
uploadID string
|
||||
parts []completePart
|
||||
parts []CompletePart
|
||||
// Expected output of CompleteMultipartUpload.
|
||||
expectedS3MD5 string
|
||||
expectedErr error
|
||||
@ -1895,28 +1895,28 @@ func testObjectCompleteMultipartUpload(obj ObjectLayer, instanceType string, t T
|
||||
shouldPass bool
|
||||
}{
|
||||
// Test cases with invalid bucket names (Test number 1-4).
|
||||
{".test", "", "", []completePart{}, "", BucketNameInvalid{Bucket: ".test"}, false},
|
||||
{"Test", "", "", []completePart{}, "", BucketNameInvalid{Bucket: "Test"}, false},
|
||||
{"---", "", "", []completePart{}, "", BucketNameInvalid{Bucket: "---"}, false},
|
||||
{"ad", "", "", []completePart{}, "", BucketNameInvalid{Bucket: "ad"}, false},
|
||||
{".test", "", "", []CompletePart{}, "", BucketNameInvalid{Bucket: ".test"}, false},
|
||||
{"Test", "", "", []CompletePart{}, "", BucketNameInvalid{Bucket: "Test"}, false},
|
||||
{"---", "", "", []CompletePart{}, "", BucketNameInvalid{Bucket: "---"}, false},
|
||||
{"ad", "", "", []CompletePart{}, "", BucketNameInvalid{Bucket: "ad"}, false},
|
||||
// Test cases for listing uploadID with single part.
|
||||
// Valid bucket names, but they donot exist (Test number 5-7).
|
||||
{"volatile-bucket-1", "", "", []completePart{}, "", BucketNotFound{Bucket: "volatile-bucket-1"}, false},
|
||||
{"volatile-bucket-2", "", "", []completePart{}, "", BucketNotFound{Bucket: "volatile-bucket-2"}, false},
|
||||
{"volatile-bucket-3", "", "", []completePart{}, "", BucketNotFound{Bucket: "volatile-bucket-3"}, false},
|
||||
{"volatile-bucket-1", "", "", []CompletePart{}, "", BucketNotFound{Bucket: "volatile-bucket-1"}, false},
|
||||
{"volatile-bucket-2", "", "", []CompletePart{}, "", BucketNotFound{Bucket: "volatile-bucket-2"}, false},
|
||||
{"volatile-bucket-3", "", "", []CompletePart{}, "", BucketNotFound{Bucket: "volatile-bucket-3"}, false},
|
||||
// Test case for Asserting for invalid objectName (Test number 8).
|
||||
{bucketNames[0], "", "", []completePart{}, "", ObjectNameInvalid{Bucket: bucketNames[0]}, false},
|
||||
{bucketNames[0], "", "", []CompletePart{}, "", ObjectNameInvalid{Bucket: bucketNames[0]}, false},
|
||||
// Asserting for Invalid UploadID (Test number 9).
|
||||
{bucketNames[0], objectNames[0], "abc", []completePart{}, "", InvalidUploadID{UploadID: "abc"}, false},
|
||||
{bucketNames[0], objectNames[0], "abc", []CompletePart{}, "", InvalidUploadID{UploadID: "abc"}, false},
|
||||
// Test case with invalid Part Etag (Test number 10-11).
|
||||
{bucketNames[0], objectNames[0], uploadIDs[0], []completePart{{ETag: "abc"}}, "", fmt.Errorf("encoding/hex: odd length hex string"), false},
|
||||
{bucketNames[0], objectNames[0], uploadIDs[0], []completePart{{ETag: "abcz"}}, "", fmt.Errorf("encoding/hex: invalid byte: U+007A 'z'"), false},
|
||||
{bucketNames[0], objectNames[0], uploadIDs[0], []CompletePart{{ETag: "abc"}}, "", fmt.Errorf("encoding/hex: odd length hex string"), false},
|
||||
{bucketNames[0], objectNames[0], uploadIDs[0], []CompletePart{{ETag: "abcz"}}, "", fmt.Errorf("encoding/hex: invalid byte: U+007A 'z'"), false},
|
||||
// Part number 0 doesn't exist, expecting InvalidPart error (Test number 12).
|
||||
{bucketNames[0], objectNames[0], uploadIDs[0], []completePart{{ETag: "abcd", PartNumber: 0}}, "", InvalidPart{}, false},
|
||||
{bucketNames[0], objectNames[0], uploadIDs[0], []CompletePart{{ETag: "abcd", PartNumber: 0}}, "", InvalidPart{}, false},
|
||||
// // Upload and PartNumber exists, But a deliberate ETag mismatch is introduced (Test number 13).
|
||||
{bucketNames[0], objectNames[0], uploadIDs[0], inputParts[0].parts, "", InvalidPart{}, false},
|
||||
// Test case with non existent object name (Test number 14).
|
||||
{bucketNames[0], "my-object", uploadIDs[0], []completePart{{ETag: "abcd", PartNumber: 1}}, "", InvalidUploadID{UploadID: uploadIDs[0]}, false},
|
||||
{bucketNames[0], "my-object", uploadIDs[0], []CompletePart{{ETag: "abcd", PartNumber: 1}}, "", InvalidUploadID{UploadID: uploadIDs[0]}, false},
|
||||
// Testing for Part being too small (Test number 15).
|
||||
{bucketNames[0], objectNames[0], uploadIDs[0], inputParts[1].parts, "", PartTooSmall{PartNumber: 1}, false},
|
||||
// TestCase with invalid Part Number (Test number 16).
|
||||
@ -1924,7 +1924,7 @@ func testObjectCompleteMultipartUpload(obj ObjectLayer, instanceType string, t T
|
||||
{bucketNames[0], objectNames[0], uploadIDs[0], inputParts[2].parts, "", InvalidPart{}, false},
|
||||
// Test case with unsorted parts (Test number 17).
|
||||
{bucketNames[0], objectNames[0], uploadIDs[0], inputParts[3].parts, s3MD5, nil, true},
|
||||
// The other parts will be flushed after a successful completePart (Test number 18).
|
||||
// The other parts will be flushed after a successful CompletePart (Test number 18).
|
||||
// the case above successfully completes CompleteMultipartUpload, the remaining Parts will be flushed.
|
||||
// Expecting to fail with Invalid UploadID.
|
||||
{bucketNames[0], objectNames[0], uploadIDs[0], inputParts[4].parts, "", InvalidUploadID{UploadID: uploadIDs[0]}, false},
|
||||
|
@ -381,7 +381,7 @@ func testObjectAPIMultipartPutObjectStaleFiles(obj ObjectLayer, instanceType str
|
||||
}
|
||||
|
||||
// Complete multipart.
|
||||
parts := []completePart{
|
||||
parts := []CompletePart{
|
||||
{ETag: etag1, PartNumber: 1},
|
||||
{ETag: etag2, PartNumber: 2},
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ func mustGetUUID() string {
|
||||
}
|
||||
|
||||
// Create an s3 compatible MD5sum for complete multipart transaction.
|
||||
func getCompleteMultipartMD5(parts []completePart) (string, error) {
|
||||
func getCompleteMultipartMD5(parts []CompletePart) (string, error) {
|
||||
var finalMD5Bytes []byte
|
||||
for _, part := range parts {
|
||||
md5Bytes, err := hex.DecodeString(part.ETag)
|
||||
|
@ -132,18 +132,18 @@ func TestIsValidObjectName(t *testing.T) {
|
||||
// Tests getCompleteMultipartMD5
|
||||
func TestGetCompleteMultipartMD5(t *testing.T) {
|
||||
testCases := []struct {
|
||||
parts []completePart
|
||||
parts []CompletePart
|
||||
expectedResult string
|
||||
expectedErr string
|
||||
}{
|
||||
// Wrong MD5 hash string
|
||||
{[]completePart{{ETag: "wrong-md5-hash-string"}}, "", "encoding/hex: odd length hex string"},
|
||||
{[]CompletePart{{ETag: "wrong-md5-hash-string"}}, "", "encoding/hex: odd length hex string"},
|
||||
|
||||
// Single completePart with valid MD5 hash string.
|
||||
{[]completePart{{ETag: "cf1f738a5924e645913c984e0fe3d708"}}, "10dc1617fbcf0bd0858048cb96e6bd77-1", ""},
|
||||
// Single CompletePart with valid MD5 hash string.
|
||||
{[]CompletePart{{ETag: "cf1f738a5924e645913c984e0fe3d708"}}, "10dc1617fbcf0bd0858048cb96e6bd77-1", ""},
|
||||
|
||||
// Multiple completePart with valid MD5 hash string.
|
||||
{[]completePart{{ETag: "cf1f738a5924e645913c984e0fe3d708"}, {ETag: "9ccbc9a80eee7fb6fdd22441db2aedbd"}}, "0239a86b5266bb624f0ac60ba2aed6c8-2", ""},
|
||||
// Multiple CompletePart with valid MD5 hash string.
|
||||
{[]CompletePart{{ETag: "cf1f738a5924e645913c984e0fe3d708"}, {ETag: "9ccbc9a80eee7fb6fdd22441db2aedbd"}}, "0239a86b5266bb624f0ac60ba2aed6c8-2", ""},
|
||||
}
|
||||
|
||||
for i, test := range testCases {
|
||||
|
@ -1026,7 +1026,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite
|
||||
writeErrorResponse(w, ErrInternalError, r.URL)
|
||||
return
|
||||
}
|
||||
complMultipartUpload := &completeMultipartUpload{}
|
||||
complMultipartUpload := &CompleteMultipartUpload{}
|
||||
if err = xml.Unmarshal(completeMultipartBytes, complMultipartUpload); err != nil {
|
||||
errorIf(err, "Unable to parse complete multipart upload XML.")
|
||||
writeErrorResponse(w, ErrMalformedXML, r.URL)
|
||||
@ -1036,13 +1036,13 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite
|
||||
writeErrorResponse(w, ErrMalformedXML, r.URL)
|
||||
return
|
||||
}
|
||||
if !sort.IsSorted(completedParts(complMultipartUpload.Parts)) {
|
||||
if !sort.IsSorted(CompletedParts(complMultipartUpload.Parts)) {
|
||||
writeErrorResponse(w, ErrInvalidPartOrder, r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
// Complete parts.
|
||||
var completeParts []completePart
|
||||
var completeParts []CompletePart
|
||||
for _, part := range complMultipartUpload.Parts {
|
||||
part.ETag = canonicalizeETag(part.ETag)
|
||||
completeParts = append(completeParts, part)
|
||||
|
@ -1078,7 +1078,7 @@ func testAPICopyObjectPartHandlerSanity(obj ObjectLayer, instanceType, bucketNam
|
||||
|
||||
a := 0
|
||||
b := globalMinPartSize - 1
|
||||
var parts []completePart
|
||||
var parts []CompletePart
|
||||
for partNumber := 1; partNumber <= 2; partNumber++ {
|
||||
// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
|
||||
rec := httptest.NewRecorder()
|
||||
@ -1109,7 +1109,7 @@ func testAPICopyObjectPartHandlerSanity(obj ObjectLayer, instanceType, bucketNam
|
||||
t.Fatalf("Test failed to decode XML response: <ERROR> %v", err)
|
||||
}
|
||||
|
||||
parts = append(parts, completePart{
|
||||
parts = append(parts, CompletePart{
|
||||
PartNumber: partNumber,
|
||||
ETag: canonicalizeETag(resp.ETag),
|
||||
})
|
||||
@ -2162,19 +2162,19 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s
|
||||
}
|
||||
// Parts to be sent as input for CompleteMultipartUpload.
|
||||
inputParts := []struct {
|
||||
parts []completePart
|
||||
parts []CompletePart
|
||||
}{
|
||||
// inputParts - 0.
|
||||
// Case for replicating ETag mismatch.
|
||||
{
|
||||
[]completePart{
|
||||
[]CompletePart{
|
||||
{ETag: "abcd", PartNumber: 1},
|
||||
},
|
||||
},
|
||||
// inputParts - 1.
|
||||
// should error out with part too small.
|
||||
{
|
||||
[]completePart{
|
||||
[]CompletePart{
|
||||
{ETag: "e2fc714c4727ee9395f324cd2e7f331f", PartNumber: 1},
|
||||
{ETag: "1f7690ebdd9b4caf8fab49ca1757bf27", PartNumber: 2},
|
||||
},
|
||||
@ -2182,7 +2182,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s
|
||||
// inputParts - 2.
|
||||
// Case with invalid Part number.
|
||||
{
|
||||
[]completePart{
|
||||
[]CompletePart{
|
||||
{ETag: "e2fc714c4727ee9395f324cd2e7f331f", PartNumber: 10},
|
||||
},
|
||||
},
|
||||
@ -2190,7 +2190,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s
|
||||
// Case with valid parts,but parts are unsorted.
|
||||
// Part size greater than 5 MiB.
|
||||
{
|
||||
[]completePart{
|
||||
[]CompletePart{
|
||||
{ETag: validPartMD5, PartNumber: 6},
|
||||
{ETag: validPartMD5, PartNumber: 5},
|
||||
},
|
||||
@ -2199,7 +2199,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s
|
||||
// Case with valid part.
|
||||
// Part size greater than 5 MiB.
|
||||
{
|
||||
[]completePart{
|
||||
[]CompletePart{
|
||||
{ETag: validPartMD5, PartNumber: 5},
|
||||
{ETag: validPartMD5, PartNumber: 6},
|
||||
},
|
||||
@ -2209,7 +2209,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s
|
||||
// Used for the case of testing for anonymous API request.
|
||||
// Part size greater than 5 MiB.
|
||||
{
|
||||
[]completePart{
|
||||
[]CompletePart{
|
||||
{ETag: validPartMD5, PartNumber: 1},
|
||||
{ETag: validPartMD5, PartNumber: 2},
|
||||
},
|
||||
@ -2230,7 +2230,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s
|
||||
bucket string
|
||||
object string
|
||||
uploadID string
|
||||
parts []completePart
|
||||
parts []CompletePart
|
||||
accessKey string
|
||||
secretKey string
|
||||
// Expected output of CompleteMultipartUpload.
|
||||
@ -2253,13 +2253,13 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s
|
||||
expectedRespStatus: http.StatusBadRequest,
|
||||
},
|
||||
// Test case - 2.
|
||||
// No parts specified in completePart{}.
|
||||
// No parts specified in CompletePart{}.
|
||||
// Should return ErrMalformedXML in the response body.
|
||||
{
|
||||
bucket: bucketName,
|
||||
object: objectName,
|
||||
uploadID: uploadIDs[0],
|
||||
parts: []completePart{},
|
||||
parts: []CompletePart{},
|
||||
accessKey: credentials.AccessKey,
|
||||
secretKey: credentials.SecretKey,
|
||||
|
||||
@ -2361,14 +2361,14 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s
|
||||
var req *http.Request
|
||||
var completeBytes, actualContent []byte
|
||||
// Complete multipart upload parts.
|
||||
completeUploads := &completeMultipartUpload{
|
||||
completeUploads := &CompleteMultipartUpload{
|
||||
Parts: testCase.parts,
|
||||
}
|
||||
completeBytes, err = xml.Marshal(completeUploads)
|
||||
if err != nil {
|
||||
t.Fatalf("Error XML encoding of parts: <ERROR> %s.", err)
|
||||
}
|
||||
// Indicating that all parts are uploaded and initiating completeMultipartUpload.
|
||||
// Indicating that all parts are uploaded and initiating CompleteMultipartUpload.
|
||||
req, err = newTestSignedRequestV4("POST", getCompleteMultipartUploadURL("", bucketName, objectName, testCase.uploadID),
|
||||
int64(len(completeBytes)), bytes.NewReader(completeBytes), testCase.accessKey, testCase.secretKey)
|
||||
if err != nil {
|
||||
@ -2400,7 +2400,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s
|
||||
// Testing for anonymous API request.
|
||||
var completeBytes []byte
|
||||
// Complete multipart upload parts.
|
||||
completeUploads := &completeMultipartUpload{
|
||||
completeUploads := &CompleteMultipartUpload{
|
||||
Parts: inputParts[5].parts,
|
||||
}
|
||||
completeBytes, err = xml.Marshal(completeUploads)
|
||||
@ -2426,7 +2426,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s
|
||||
// There is no need to use an existing bucket or valid input for creating the request,
|
||||
// since the `objectLayer==nil` check is performed before any other checks inside the handlers.
|
||||
// The only aim is to generate an HTTP request in a way that the relevant/registered end point is evoked/called.
|
||||
// Indicating that all parts are uploaded and initiating completeMultipartUpload.
|
||||
// Indicating that all parts are uploaded and initiating CompleteMultipartUpload.
|
||||
nilBucket := "dummy-bucket"
|
||||
nilObject := "dummy-object"
|
||||
|
||||
|
@ -99,7 +99,7 @@ func testMultipartObjectCreation(obj ObjectLayer, instanceType string, t TestErr
|
||||
}
|
||||
// Create a byte array of 5MiB.
|
||||
data := bytes.Repeat([]byte("0123456789abcdef"), 5*humanize.MiByte/16)
|
||||
completedParts := completeMultipartUpload{}
|
||||
completedParts := CompleteMultipartUpload{}
|
||||
for i := 1; i <= 10; i++ {
|
||||
expectedETaghex := getMD5Hash(data)
|
||||
|
||||
@ -111,7 +111,7 @@ func testMultipartObjectCreation(obj ObjectLayer, instanceType string, t TestErr
|
||||
if calcPartInfo.ETag != expectedETaghex {
|
||||
t.Errorf("MD5 Mismatch")
|
||||
}
|
||||
completedParts.Parts = append(completedParts.Parts, completePart{
|
||||
completedParts.Parts = append(completedParts.Parts, CompletePart{
|
||||
PartNumber: i,
|
||||
ETag: calcPartInfo.ETag,
|
||||
})
|
||||
|
@ -2730,8 +2730,8 @@ func (s *TestSuiteCommon) TestObjectMultipart(c *check) {
|
||||
c.Assert(response2.StatusCode, http.StatusOK)
|
||||
|
||||
// Complete multipart upload
|
||||
completeUploads := &completeMultipartUpload{
|
||||
Parts: []completePart{
|
||||
completeUploads := &CompleteMultipartUpload{
|
||||
Parts: []CompletePart{
|
||||
{
|
||||
PartNumber: 1,
|
||||
ETag: response1.Header.Get("ETag"),
|
||||
@ -2745,7 +2745,7 @@ func (s *TestSuiteCommon) TestObjectMultipart(c *check) {
|
||||
|
||||
completeBytes, err := xml.Marshal(completeUploads)
|
||||
c.Assert(err, nil)
|
||||
// Indicating that all parts are uploaded and initiating completeMultipartUpload.
|
||||
// Indicating that all parts are uploaded and initiating CompleteMultipartUpload.
|
||||
request, err = newTestSignedRequest("POST", getCompleteMultipartUploadURL(s.endPoint, bucketName, objectName, uploadID),
|
||||
int64(len(completeBytes)), bytes.NewReader(completeBytes), s.accessKey, s.secretKey, s.signer)
|
||||
c.Assert(err, nil)
|
||||
@ -2754,7 +2754,7 @@ func (s *TestSuiteCommon) TestObjectMultipart(c *check) {
|
||||
c.Assert(err, nil)
|
||||
// verify whether complete multipart was successful.
|
||||
c.Assert(response.StatusCode, http.StatusOK)
|
||||
var parts []completePart
|
||||
var parts []CompletePart
|
||||
for _, part := range completeUploads.Parts {
|
||||
part.ETag = canonicalizeETag(part.ETag)
|
||||
parts = append(parts, part)
|
||||
|
@ -489,13 +489,13 @@ func TestHealObjectXL(t *testing.T) {
|
||||
t.Fatalf("Failed to create a multipart upload - %v", err)
|
||||
}
|
||||
|
||||
var uploadedParts []completePart
|
||||
var uploadedParts []CompletePart
|
||||
for _, partID := range []int{2, 1} {
|
||||
pInfo, err1 := obj.PutObjectPart(bucket, object, uploadID, partID, mustGetHashReader(t, bytes.NewReader(data), int64(len(data)), "", ""))
|
||||
if err1 != nil {
|
||||
t.Fatalf("Failed to upload a part - %v", err1)
|
||||
}
|
||||
uploadedParts = append(uploadedParts, completePart{
|
||||
uploadedParts = append(uploadedParts, CompletePart{
|
||||
PartNumber: pInfo.PartNumber,
|
||||
ETag: pInfo.ETag,
|
||||
})
|
||||
|
@ -222,7 +222,7 @@ func (xl xlObjects) ListUploadsHeal(bucket, prefix, marker, uploadIDMarker,
|
||||
|
||||
// Fetches list of multipart uploadIDs given bucket, keyMarker, uploadIDMarker.
|
||||
func fetchMultipartUploadIDs(bucket, keyMarker, uploadIDMarker string,
|
||||
maxUploads int, disks []StorageAPI) (uploads []uploadMetadata, end bool,
|
||||
maxUploads int, disks []StorageAPI) (uploads []MultipartInfo, end bool,
|
||||
err error) {
|
||||
|
||||
// Hold a read lock on keyMarker path.
|
||||
@ -261,7 +261,7 @@ func (xl xlObjects) listMultipartUploadsHeal(bucket, prefix, keyMarker,
|
||||
|
||||
recursive := delimiter != slashSeparator
|
||||
|
||||
var uploads []uploadMetadata
|
||||
var uploads []MultipartInfo
|
||||
var err error
|
||||
// List all upload ids for the given keyMarker, starting from
|
||||
// uploadIDMarker.
|
||||
@ -332,7 +332,7 @@ func (xl xlObjects) listMultipartUploadsHeal(bucket, prefix, keyMarker,
|
||||
retainSlash(bucket))
|
||||
// Skip entries that are not object directory.
|
||||
if hasSuffix(walkResult.entry, slashSeparator) {
|
||||
uploads = append(uploads, uploadMetadata{
|
||||
uploads = append(uploads, MultipartInfo{
|
||||
Object: entry,
|
||||
})
|
||||
uploadsLeft--
|
||||
@ -344,7 +344,7 @@ func (xl xlObjects) listMultipartUploadsHeal(bucket, prefix, keyMarker,
|
||||
|
||||
// For an object entry we get all its pending
|
||||
// uploadIDs.
|
||||
var newUploads []uploadMetadata
|
||||
var newUploads []MultipartInfo
|
||||
var end bool
|
||||
uploadIDMarker = ""
|
||||
newUploads, end, err = fetchMultipartUploadIDs(bucket, entry, uploadIDMarker,
|
||||
|
@ -297,7 +297,7 @@ func (xl xlObjects) listMultipartUploads(bucket, prefix, keyMarker, uploadIDMark
|
||||
if keyMarker != "" {
|
||||
multipartMarkerPath = pathJoin(bucket, keyMarker)
|
||||
}
|
||||
var uploads []uploadMetadata
|
||||
var uploads []MultipartInfo
|
||||
var err error
|
||||
var eof bool
|
||||
// List all upload ids for the keyMarker starting from
|
||||
@ -356,7 +356,7 @@ func (xl xlObjects) listMultipartUploads(bucket, prefix, keyMarker, uploadIDMark
|
||||
// For an entry looking like a directory, store and
|
||||
// continue the loop not need to fetch uploads.
|
||||
if hasSuffix(walkResult.entry, slashSeparator) {
|
||||
uploads = append(uploads, uploadMetadata{
|
||||
uploads = append(uploads, MultipartInfo{
|
||||
Object: entry,
|
||||
})
|
||||
maxUploads--
|
||||
@ -366,7 +366,7 @@ func (xl xlObjects) listMultipartUploads(bucket, prefix, keyMarker, uploadIDMark
|
||||
}
|
||||
continue
|
||||
}
|
||||
var newUploads []uploadMetadata
|
||||
var newUploads []MultipartInfo
|
||||
var end bool
|
||||
uploadIDMarker = ""
|
||||
|
||||
@ -832,7 +832,7 @@ func (xl xlObjects) ListObjectParts(bucket, object, uploadID string, partNumberM
|
||||
// md5sums of all the parts.
|
||||
//
|
||||
// Implements S3 compatible Complete multipart API.
|
||||
func (xl xlObjects) CompleteMultipartUpload(bucket string, object string, uploadID string, parts []completePart) (oi ObjectInfo, e error) {
|
||||
func (xl xlObjects) CompleteMultipartUpload(bucket string, object string, uploadID string, parts []CompletePart) (oi ObjectInfo, e error) {
|
||||
if err := checkCompleteMultipartArgs(bucket, object, xl); err != nil {
|
||||
return oi, err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user