2015-10-16 20:26:01 +02:00
/ *
2019-04-09 20:39:42 +02:00
* MinIO Cloud Storage , ( C ) 2015 , 2016 , 2017 MinIO , Inc .
2015-10-16 20:26:01 +02:00
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
2016-08-19 01:23:42 +02:00
package cmd
2015-10-16 20:26:01 +02:00
import (
"bytes"
2018-03-15 21:27:16 +01:00
"context"
2016-06-09 07:00:31 +02:00
"io"
2015-10-16 20:26:01 +02:00
"math/rand"
"strconv"
2017-10-10 11:14:42 +02:00
"testing"
2015-10-16 20:26:01 +02:00
2016-11-23 03:18:22 +01:00
humanize "github.com/dustin/go-humanize"
2015-10-16 20:26:01 +02:00
)
2016-06-09 07:00:31 +02:00
// Return pointer to testOneByteReadEOF{}
func newTestReaderEOF ( data [ ] byte ) io . Reader {
return & testOneByteReadEOF { false , data }
}
// OneByteReadEOF - implements io.Reader which returns 1 byte along with io.EOF error.
type testOneByteReadEOF struct {
eof bool
data [ ] byte
}
func ( r * testOneByteReadEOF ) Read ( p [ ] byte ) ( n int , err error ) {
if r . eof {
return 0 , io . EOF
}
n = copy ( p , r . data )
r . eof = true
return n , io . EOF
}
// Return pointer to testOneByteReadNoEOF{}
func newTestReaderNoEOF ( data [ ] byte ) io . Reader {
return & testOneByteReadNoEOF { false , data }
}
// testOneByteReadNoEOF - implements io.Reader which returns 1 byte and nil error, but
// returns io.EOF on the next Read().
type testOneByteReadNoEOF struct {
eof bool
data [ ] byte
}
func ( r * testOneByteReadNoEOF ) Read ( p [ ] byte ) ( n int , err error ) {
if r . eof {
return 0 , io . EOF
}
n = copy ( p , r . data )
r . eof = true
return n , nil
}
2016-07-08 00:05:51 +02:00
type ObjectLayerAPISuite struct { }
2020-06-13 05:04:01 +02:00
// Wrapper for calling testMakeBucket for both Erasure and FS.
2017-10-10 11:14:42 +02:00
func ( s * ObjectLayerAPISuite ) TestMakeBucket ( t * testing . T ) {
ExecObjectLayerTest ( t , testMakeBucket )
2015-10-16 20:26:01 +02:00
}
2016-04-28 04:28:13 +02:00
// Tests validate bucket creation.
2017-10-10 11:14:42 +02:00
func testMakeBucket ( obj ObjectLayer , instanceType string , t TestErrHandler ) {
2020-06-13 05:04:01 +02:00
err := obj . MakeBucketWithLocation ( context . Background ( ) , "bucket-unknown" , BucketOptions { } )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
}
2020-06-13 05:04:01 +02:00
// Wrapper for calling testMultipartObjectCreation for both Erasure and FS.
2017-10-10 11:14:42 +02:00
func ( s * ObjectLayerAPISuite ) TestMultipartObjectCreation ( t * testing . T ) {
ExecObjectLayerTest ( t , testMultipartObjectCreation )
2015-10-16 20:26:01 +02:00
}
2016-04-28 04:28:13 +02:00
// Tests validate creation of part files during Multipart operation.
2017-10-10 11:14:42 +02:00
func testMultipartObjectCreation ( obj ObjectLayer , instanceType string , t TestErrHandler ) {
2018-09-10 18:42:43 +02:00
var opts ObjectOptions
2020-06-13 05:04:01 +02:00
err := obj . MakeBucketWithLocation ( context . Background ( ) , "bucket" , BucketOptions { } )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2019-02-09 06:31:06 +01:00
uploadID , err := obj . NewMultipartUpload ( context . Background ( ) , "bucket" , "key" , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2016-11-23 03:18:22 +01:00
// Create a byte array of 5MiB.
data := bytes . Repeat ( [ ] byte ( "0123456789abcdef" ) , 5 * humanize . MiByte / 16 )
2017-11-14 09:25:10 +01:00
completedParts := CompleteMultipartUpload { }
2015-10-16 20:26:01 +02:00
for i := 1 ; i <= 10 ; i ++ {
2017-05-14 21:05:51 +02:00
expectedETaghex := getMD5Hash ( data )
2015-10-16 20:26:01 +02:00
2017-01-31 18:38:34 +01:00
var calcPartInfo PartInfo
2018-11-15 02:36:41 +01:00
calcPartInfo , err = obj . PutObjectPart ( context . Background ( ) , "bucket" , "key" , uploadID , i , mustGetPutObjReader ( t , bytes . NewBuffer ( data ) , int64 ( len ( data ) ) , expectedETaghex , "" ) , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2017-05-14 21:05:51 +02:00
if calcPartInfo . ETag != expectedETaghex {
2017-10-10 11:14:42 +02:00
t . Errorf ( "MD5 Mismatch" )
2016-07-08 00:05:51 +02:00
}
2017-11-14 09:25:10 +01:00
completedParts . Parts = append ( completedParts . Parts , CompletePart {
2017-01-31 18:38:34 +01:00
PartNumber : i ,
ETag : calcPartInfo . ETag ,
} )
2015-10-16 20:26:01 +02:00
}
2018-11-15 02:36:41 +01:00
objInfo , err := obj . CompleteMultipartUpload ( context . Background ( ) , "bucket" , "key" , uploadID , completedParts . Parts , ObjectOptions { } )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2017-05-14 21:05:51 +02:00
if objInfo . ETag != "7d364cb728ce42a74a96d22949beefb2-10" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "Md5 mismtch" )
2016-07-08 00:05:51 +02:00
}
}
2020-06-13 05:04:01 +02:00
// Wrapper for calling testMultipartObjectAbort for both Erasure and FS.
2017-10-10 11:14:42 +02:00
func ( s * ObjectLayerAPISuite ) TestMultipartObjectAbort ( t * testing . T ) {
ExecObjectLayerTest ( t , testMultipartObjectAbort )
2015-10-16 20:26:01 +02:00
}
2016-04-28 04:28:13 +02:00
// Tests validate abortion of Multipart operation.
2017-10-10 11:14:42 +02:00
func testMultipartObjectAbort ( obj ObjectLayer , instanceType string , t TestErrHandler ) {
2018-09-10 18:42:43 +02:00
var opts ObjectOptions
2020-06-13 05:04:01 +02:00
err := obj . MakeBucketWithLocation ( context . Background ( ) , "bucket" , BucketOptions { } )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2019-02-09 06:31:06 +01:00
uploadID , err := obj . NewMultipartUpload ( context . Background ( ) , "bucket" , "key" , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
parts := make ( map [ int ] string )
objectAPI: Fix object API interface, remove unnecessary structs.
ObjectAPI changes.
```
ListObjects(bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsInfo, *probe.Error)
ListMultipartUploads(bucket, objectPrefix, keyMarker, uploadIDMarker, delimiter string, maxUploads int) (ListMultipartsInfo, *probe.Error)
ListObjectParts(bucket, object, uploadID string, partNumberMarker, maxParts int) (ListPartsInfo, *probe.Error)
CompleteMultipartUpload(bucket string, object string, uploadID string, parts []completePart) (ObjectInfo, *probe.Error)
```
2016-04-03 10:34:20 +02:00
metadata := make ( map [ string ] string )
2015-10-16 20:26:01 +02:00
for i := 1 ; i <= 10 ; i ++ {
randomPerm := rand . Perm ( 10 )
randomString := ""
for _ , num := range randomPerm {
randomString = randomString + strconv . Itoa ( num )
}
2017-05-14 21:05:51 +02:00
expectedETaghex := getMD5Hash ( [ ] byte ( randomString ) )
2015-10-16 20:26:01 +02:00
2017-05-14 21:05:51 +02:00
metadata [ "md5" ] = expectedETaghex
2017-01-31 18:38:34 +01:00
var calcPartInfo PartInfo
2018-11-15 02:36:41 +01:00
calcPartInfo , err = obj . PutObjectPart ( context . Background ( ) , "bucket" , "key" , uploadID , i , mustGetPutObjReader ( t , bytes . NewBufferString ( randomString ) , int64 ( len ( randomString ) ) , expectedETaghex , "" ) , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2017-05-14 21:05:51 +02:00
if calcPartInfo . ETag != expectedETaghex {
2017-10-10 11:14:42 +02:00
t . Errorf ( "Md5 Mismatch" )
2016-07-08 00:05:51 +02:00
}
2017-05-14 21:05:51 +02:00
parts [ i ] = expectedETaghex
2015-10-16 20:26:01 +02:00
}
2018-03-15 21:27:16 +01:00
err = obj . AbortMultipartUpload ( context . Background ( ) , "bucket" , "key" , uploadID )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
}
2020-06-13 05:04:01 +02:00
// Wrapper for calling testMultipleObjectCreation for both Erasure and FS.
2017-10-10 11:14:42 +02:00
func ( s * ObjectLayerAPISuite ) TestMultipleObjectCreation ( t * testing . T ) {
ExecObjectLayerTest ( t , testMultipleObjectCreation )
2015-10-16 20:26:01 +02:00
}
2016-04-28 04:28:13 +02:00
// Tests validate object creation.
2017-10-10 11:14:42 +02:00
func testMultipleObjectCreation ( obj ObjectLayer , instanceType string , t TestErrHandler ) {
2015-10-16 20:26:01 +02:00
objects := make ( map [ string ] [ ] byte )
2018-09-10 18:42:43 +02:00
var opts ObjectOptions
2020-06-13 05:04:01 +02:00
err := obj . MakeBucketWithLocation ( context . Background ( ) , "bucket" , BucketOptions { } )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
for i := 0 ; i < 10 ; i ++ {
2016-04-23 03:16:02 +02:00
randomPerm := rand . Perm ( 100 )
2015-10-16 20:26:01 +02:00
randomString := ""
for _ , num := range randomPerm {
randomString = randomString + strconv . Itoa ( num )
}
2017-05-14 21:05:51 +02:00
expectedETaghex := getMD5Hash ( [ ] byte ( randomString ) )
2015-10-16 20:26:01 +02:00
key := "obj" + strconv . Itoa ( i )
objects [ key ] = [ ] byte ( randomString )
fs: Break fs package to top-level and introduce ObjectAPI interface.
ObjectAPI interface brings in changes needed for XL ObjectAPI layer.
The new interface for any ObjectAPI layer is as below
```
// ObjectAPI interface.
type ObjectAPI interface {
// Bucket resource API.
DeleteBucket(bucket string) *probe.Error
ListBuckets() ([]BucketInfo, *probe.Error)
MakeBucket(bucket string) *probe.Error
GetBucketInfo(bucket string) (BucketInfo, *probe.Error)
// Bucket query API.
ListObjects(bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsResult, *probe.Error)
ListMultipartUploads(bucket string, resources BucketMultipartResourcesMetadata) (BucketMultipartResourcesMetadata, *probe.Error)
// Object resource API.
GetObject(bucket, object string, startOffset int64) (io.ReadCloser, *probe.Error)
GetObjectInfo(bucket, object string) (ObjectInfo, *probe.Error)
PutObject(bucket string, object string, size int64, data io.Reader, metadata map[string]string) (ObjectInfo, *probe.Error)
DeleteObject(bucket, object string) *probe.Error
// Object query API.
NewMultipartUpload(bucket, object string) (string, *probe.Error)
PutObjectPart(bucket, object, uploadID string, partID int, size int64, data io.Reader, md5Hex string) (string, *probe.Error)
ListObjectParts(bucket, object string, resources ObjectResourcesMetadata) (ObjectResourcesMetadata, *probe.Error)
CompleteMultipartUpload(bucket string, object string, uploadID string, parts []CompletePart) (ObjectInfo, *probe.Error)
AbortMultipartUpload(bucket, object, uploadID string) *probe.Error
}
```
2016-03-31 01:15:28 +02:00
metadata := make ( map [ string ] string )
2017-05-14 21:05:51 +02:00
metadata [ "etag" ] = expectedETaghex
2016-09-02 21:18:35 +02:00
var objInfo ObjectInfo
2019-02-09 06:31:06 +01:00
objInfo , err = obj . PutObject ( context . Background ( ) , "bucket" , key , mustGetPutObjReader ( t , bytes . NewBufferString ( randomString ) , int64 ( len ( randomString ) ) , metadata [ "etag" ] , "" ) , ObjectOptions { UserDefined : metadata } )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2017-05-14 21:05:51 +02:00
if objInfo . ETag != expectedETaghex {
2017-10-10 11:14:42 +02:00
t . Errorf ( "Md5 Mismatch" )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
}
for key , value := range objects {
var byteBuffer bytes . Buffer
2018-09-10 18:42:43 +02:00
err = obj . GetObject ( context . Background ( ) , "bucket" , key , 0 , int64 ( len ( value ) ) , & byteBuffer , "" , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if ! bytes . Equal ( byteBuffer . Bytes ( ) , value ) {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Mismatch of GetObject data with the expected one." , instanceType )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
2018-09-10 18:42:43 +02:00
objInfo , err := obj . GetObjectInfo ( context . Background ( ) , "bucket" , key , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if objInfo . Size != int64 ( len ( value ) ) {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Size mismatch of the GetObject data." , instanceType )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
}
}
2020-06-13 05:04:01 +02:00
// Wrapper for calling TestPaging for both Erasure and FS.
2017-10-10 11:14:42 +02:00
func ( s * ObjectLayerAPISuite ) TestPaging ( t * testing . T ) {
ExecObjectLayerTest ( t , testPaging )
2016-07-08 00:05:51 +02:00
}
2016-04-28 04:28:13 +02:00
// Tests validate creation of objects and the order of listing using various filters for ListObjects operation.
2017-10-10 11:14:42 +02:00
func testPaging ( obj ObjectLayer , instanceType string , t TestErrHandler ) {
2020-06-13 05:04:01 +02:00
obj . MakeBucketWithLocation ( context . Background ( ) , "bucket" , BucketOptions { } )
2018-03-15 21:27:16 +01:00
result , err := obj . ListObjects ( context . Background ( ) , "bucket" , "" , "" , "" , 0 )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if len ( result . Objects ) != 0 {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Number of objects in the result different from expected value." , instanceType )
2016-07-08 00:05:51 +02:00
}
2017-03-08 19:00:47 +01:00
if result . IsTruncated {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected IsTruncated to be `false`, but instead found it to be `%v`" , instanceType , result . IsTruncated )
2016-07-08 00:05:51 +02:00
}
uploadContent := "The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed."
2018-09-10 18:42:43 +02:00
var opts ObjectOptions
2016-04-28 04:28:13 +02:00
// check before paging occurs.
2015-10-16 20:26:01 +02:00
for i := 0 ; i < 5 ; i ++ {
key := "obj" + strconv . Itoa ( i )
2019-02-09 06:31:06 +01:00
_ , err = obj . PutObject ( context . Background ( ) , "bucket" , key , mustGetPutObjReader ( t , bytes . NewBufferString ( uploadContent ) , int64 ( len ( uploadContent ) ) , "" , "" ) , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2016-04-26 19:35:39 +02:00
2018-03-15 21:27:16 +01:00
result , err = obj . ListObjects ( context . Background ( ) , "bucket" , "" , "" , "" , 5 )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if len ( result . Objects ) != i + 1 {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected length of objects to be %d, instead found to be %d" , instanceType , len ( result . Objects ) , i + 1 )
2016-07-08 00:05:51 +02:00
}
2017-03-08 19:00:47 +01:00
if result . IsTruncated {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected IsTruncated to be `false`, but instead found it to be `%v`" , instanceType , result . IsTruncated )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
}
2016-07-08 00:05:51 +02:00
2016-04-28 04:28:13 +02:00
// check after paging occurs pages work.
2015-10-16 20:26:01 +02:00
for i := 6 ; i <= 10 ; i ++ {
key := "obj" + strconv . Itoa ( i )
2019-02-09 06:31:06 +01:00
_ , err = obj . PutObject ( context . Background ( ) , "bucket" , key , mustGetPutObjReader ( t , bytes . NewBufferString ( uploadContent ) , int64 ( len ( uploadContent ) ) , "" , "" ) , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2018-03-15 21:27:16 +01:00
result , err = obj . ListObjects ( context . Background ( ) , "bucket" , "obj" , "" , "" , 5 )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if len ( result . Objects ) != 5 {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected length of objects to be %d, instead found to be %d" , instanceType , 5 , len ( result . Objects ) )
2016-07-08 00:05:51 +02:00
}
2017-03-08 19:00:47 +01:00
if ! result . IsTruncated {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected IsTruncated to be `true`, but instead found it to be `%v`" , instanceType , result . IsTruncated )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
}
2016-04-28 04:28:13 +02:00
// check paging with prefix at end returns less objects.
2015-10-16 20:26:01 +02:00
{
2019-02-09 06:31:06 +01:00
_ , err = obj . PutObject ( context . Background ( ) , "bucket" , "newPrefix" , mustGetPutObjReader ( t , bytes . NewBufferString ( uploadContent ) , int64 ( len ( uploadContent ) ) , "" , "" ) , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2019-02-09 06:31:06 +01:00
_ , err = obj . PutObject ( context . Background ( ) , "bucket" , "newPrefix2" , mustGetPutObjReader ( t , bytes . NewBufferString ( uploadContent ) , int64 ( len ( uploadContent ) ) , "" , "" ) , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2018-03-15 21:27:16 +01:00
result , err = obj . ListObjects ( context . Background ( ) , "bucket" , "new" , "" , "" , 5 )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if len ( result . Objects ) != 2 {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected length of objects to be %d, instead found to be %d" , instanceType , 2 , len ( result . Objects ) )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
}
2016-04-28 04:28:13 +02:00
// check ordering of pages.
2015-10-16 20:26:01 +02:00
{
2018-03-15 21:27:16 +01:00
result , err = obj . ListObjects ( context . Background ( ) , "bucket" , "" , "" , "" , 1000 )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if result . Objects [ 0 ] . Name != "newPrefix" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the object name to be `%s`, but instead found `%s`" , instanceType , "newPrefix" , result . Objects [ 0 ] . Name )
2016-07-08 00:05:51 +02:00
}
if result . Objects [ 1 ] . Name != "newPrefix2" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the object name to be `%s`, but instead found `%s`" , instanceType , "newPrefix" , result . Objects [ 1 ] . Name )
2016-07-08 00:05:51 +02:00
}
if result . Objects [ 2 ] . Name != "obj0" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the object name to be `%s`, but instead found `%s`" , instanceType , "newPrefix" , result . Objects [ 2 ] . Name )
2016-07-08 00:05:51 +02:00
}
if result . Objects [ 3 ] . Name != "obj1" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the object name to be `%s`, but instead found `%s`" , instanceType , "newPrefix" , result . Objects [ 3 ] . Name )
2016-07-08 00:05:51 +02:00
}
if result . Objects [ 4 ] . Name != "obj10" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the object name to be `%s`, but instead found `%s`" , instanceType , "newPrefix" , result . Objects [ 4 ] . Name )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
}
2016-04-28 04:28:13 +02:00
// check delimited results with delimiter and prefix.
2015-10-16 20:26:01 +02:00
{
2019-02-09 06:31:06 +01:00
_ , err = obj . PutObject ( context . Background ( ) , "bucket" , "this/is/delimited" , mustGetPutObjReader ( t , bytes . NewBufferString ( uploadContent ) , int64 ( len ( uploadContent ) ) , "" , "" ) , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2019-02-09 06:31:06 +01:00
_ , err = obj . PutObject ( context . Background ( ) , "bucket" , "this/is/also/a/delimited/file" , mustGetPutObjReader ( t , bytes . NewBufferString ( uploadContent ) , int64 ( len ( uploadContent ) ) , "" , "" ) , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2019-08-06 21:08:58 +02:00
result , err = obj . ListObjects ( context . Background ( ) , "bucket" , "this/is/" , "" , SlashSeparator , 10 )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if len ( result . Objects ) != 1 {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the number of objects in the result to be %d, but instead found %d" , instanceType , 1 , len ( result . Objects ) )
2016-07-08 00:05:51 +02:00
}
if result . Prefixes [ 0 ] != "this/is/also/" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected prefix to be `%s`, but instead found `%s`" , instanceType , "this/is/also/" , result . Prefixes [ 0 ] )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
}
2016-04-28 04:28:13 +02:00
// check delimited results with delimiter without prefix.
2015-10-16 20:26:01 +02:00
{
2019-08-06 21:08:58 +02:00
result , err = obj . ListObjects ( context . Background ( ) , "bucket" , "" , "" , SlashSeparator , 1000 )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if result . Objects [ 0 ] . Name != "newPrefix" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the object name to be `%s`, but instead found `%s`" , instanceType , "newPrefix" , result . Objects [ 0 ] . Name )
2016-07-08 00:05:51 +02:00
}
if result . Objects [ 1 ] . Name != "newPrefix2" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the object name to be `%s`, but instead found `%s`" , instanceType , "newPrefix" , result . Objects [ 1 ] . Name )
2016-07-08 00:05:51 +02:00
}
if result . Objects [ 2 ] . Name != "obj0" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the object name to be `%s`, but instead found `%s`" , instanceType , "newPrefix" , result . Objects [ 2 ] . Name )
2016-07-08 00:05:51 +02:00
}
if result . Objects [ 3 ] . Name != "obj1" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the object name to be `%s`, but instead found `%s`" , instanceType , "newPrefix" , result . Objects [ 3 ] . Name )
2016-07-08 00:05:51 +02:00
}
if result . Objects [ 4 ] . Name != "obj10" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the object name to be `%s`, but instead found `%s`" , instanceType , "newPrefix" , result . Objects [ 4 ] . Name )
2016-07-08 00:05:51 +02:00
}
if result . Prefixes [ 0 ] != "this/" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the prefix to be `%s`, but instead found `%s`" , instanceType , "this/" , result . Prefixes [ 0 ] )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
}
2016-04-28 04:28:13 +02:00
// check results with Marker.
2015-10-16 20:26:01 +02:00
{
2016-04-26 19:35:39 +02:00
2018-03-15 21:27:16 +01:00
result , err = obj . ListObjects ( context . Background ( ) , "bucket" , "" , "newPrefix" , "" , 3 )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if result . Objects [ 0 ] . Name != "newPrefix2" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the object name to be `%s`, but instead found `%s`" , instanceType , "newPrefix2" , result . Objects [ 0 ] . Name )
2016-07-08 00:05:51 +02:00
}
if result . Objects [ 1 ] . Name != "obj0" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the object name to be `%s`, but instead found `%s`" , instanceType , "obj0" , result . Objects [ 1 ] . Name )
2016-07-08 00:05:51 +02:00
}
if result . Objects [ 2 ] . Name != "obj1" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the object name to be `%s`, but instead found `%s`" , instanceType , "obj1" , result . Objects [ 2 ] . Name )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
}
2016-04-28 04:28:13 +02:00
// check ordering of results with prefix.
2015-10-16 20:26:01 +02:00
{
2018-03-15 21:27:16 +01:00
result , err = obj . ListObjects ( context . Background ( ) , "bucket" , "obj" , "" , "" , 1000 )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if result . Objects [ 0 ] . Name != "obj0" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the object name to be `%s`, but instead found `%s`" , instanceType , "obj0" , result . Objects [ 0 ] . Name )
2016-07-08 00:05:51 +02:00
}
if result . Objects [ 1 ] . Name != "obj1" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the object name to be `%s`, but instead found `%s`" , instanceType , "obj1" , result . Objects [ 1 ] . Name )
2016-07-08 00:05:51 +02:00
}
if result . Objects [ 2 ] . Name != "obj10" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the object name to be `%s`, but instead found `%s`" , instanceType , "obj10" , result . Objects [ 2 ] . Name )
2016-07-08 00:05:51 +02:00
}
if result . Objects [ 3 ] . Name != "obj2" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the object name to be `%s`, but instead found `%s`" , instanceType , "obj2" , result . Objects [ 3 ] . Name )
2016-07-08 00:05:51 +02:00
}
if result . Objects [ 4 ] . Name != "obj3" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the object name to be `%s`, but instead found `%s`" , instanceType , "obj3" , result . Objects [ 4 ] . Name )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
}
2016-04-28 04:28:13 +02:00
// check ordering of results with prefix and no paging.
2015-10-16 20:26:01 +02:00
{
2018-03-15 21:27:16 +01:00
result , err = obj . ListObjects ( context . Background ( ) , "bucket" , "new" , "" , "" , 5 )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if result . Objects [ 0 ] . Name != "newPrefix" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the object name to be `%s`, but instead found `%s`" , instanceType , "newPrefix" , result . Objects [ 0 ] . Name )
2016-07-08 00:05:51 +02:00
}
if result . Objects [ 1 ] . Name != "newPrefix2" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the object name to be `%s`, but instead found `%s`" , instanceType , "newPrefix2" , result . Objects [ 0 ] . Name )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
}
}
2020-06-13 05:04:01 +02:00
// Wrapper for calling testObjectOverwriteWorks for both Erasure and FS.
2017-10-10 11:14:42 +02:00
func ( s * ObjectLayerAPISuite ) TestObjectOverwriteWorks ( t * testing . T ) {
ExecObjectLayerTest ( t , testObjectOverwriteWorks )
2016-07-08 00:05:51 +02:00
}
2016-04-28 04:28:13 +02:00
// Tests validate overwriting of an existing object.
2017-10-10 11:14:42 +02:00
func testObjectOverwriteWorks ( obj ObjectLayer , instanceType string , t TestErrHandler ) {
2020-06-13 05:04:01 +02:00
err := obj . MakeBucketWithLocation ( context . Background ( ) , "bucket" , BucketOptions { } )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
2018-09-10 18:42:43 +02:00
var opts ObjectOptions
2017-09-19 21:40:27 +02:00
uploadContent := "The list of parts was not in ascending order. The parts list must be specified in order by part number."
length := int64 ( len ( uploadContent ) )
2019-02-09 06:31:06 +01:00
_ , err = obj . PutObject ( context . Background ( ) , "bucket" , "object" , mustGetPutObjReader ( t , bytes . NewBufferString ( uploadContent ) , length , "" , "" ) , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
2017-09-19 21:40:27 +02:00
uploadContent = "The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed."
length = int64 ( len ( uploadContent ) )
2019-02-09 06:31:06 +01:00
_ , err = obj . PutObject ( context . Background ( ) , "bucket" , "object" , mustGetPutObjReader ( t , bytes . NewBufferString ( uploadContent ) , length , "" , "" ) , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
var bytesBuffer bytes . Buffer
2018-09-10 18:42:43 +02:00
err = obj . GetObject ( context . Background ( ) , "bucket" , "object" , 0 , length , & bytesBuffer , "" , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2019-02-13 13:59:36 +01:00
if bytesBuffer . String ( ) != "The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed." {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Invalid upload ID error mismatch." , instanceType )
2016-07-08 00:05:51 +02:00
}
}
2020-06-13 05:04:01 +02:00
// Wrapper for calling testNonExistantBucketOperations for both Erasure and FS.
2017-10-10 11:14:42 +02:00
func ( s * ObjectLayerAPISuite ) TestNonExistantBucketOperations ( t * testing . T ) {
ExecObjectLayerTest ( t , testNonExistantBucketOperations )
2015-10-16 20:26:01 +02:00
}
2016-04-28 04:28:13 +02:00
// Tests validate that bucket operation on non-existent bucket fails.
2017-10-10 11:14:42 +02:00
func testNonExistantBucketOperations ( obj ObjectLayer , instanceType string , t TestErrHandler ) {
2018-09-10 18:42:43 +02:00
var opts ObjectOptions
2019-02-09 06:31:06 +01:00
_ , err := obj . PutObject ( context . Background ( ) , "bucket1" , "object" , mustGetPutObjReader ( t , bytes . NewBufferString ( "one" ) , int64 ( len ( "one" ) ) , "" , "" ) , opts )
2016-07-08 00:05:51 +02:00
if err == nil {
2017-10-10 11:14:42 +02:00
t . Fatal ( "Expected error but found nil" )
2016-07-08 00:05:51 +02:00
}
if err . Error ( ) != "Bucket not found: bucket1" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the error msg to be `%s`, but instead found `%s`" , instanceType , "Bucket not found: bucket1" , err . Error ( ) )
2016-07-08 00:05:51 +02:00
}
}
2020-06-13 05:04:01 +02:00
// Wrapper for calling testBucketRecreateFails for both Erasure and FS.
2017-10-10 11:14:42 +02:00
func ( s * ObjectLayerAPISuite ) TestBucketRecreateFails ( t * testing . T ) {
ExecObjectLayerTest ( t , testBucketRecreateFails )
2015-10-16 20:26:01 +02:00
}
2016-04-28 04:28:13 +02:00
// Tests validate that recreation of the bucket fails.
2017-10-10 11:14:42 +02:00
func testBucketRecreateFails ( obj ObjectLayer , instanceType string , t TestErrHandler ) {
2020-06-13 05:04:01 +02:00
err := obj . MakeBucketWithLocation ( context . Background ( ) , "string" , BucketOptions { } )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2020-06-13 05:04:01 +02:00
err = obj . MakeBucketWithLocation ( context . Background ( ) , "string" , BucketOptions { } )
2016-07-08 00:05:51 +02:00
if err == nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: Expected error but found nil." , instanceType )
2016-07-08 00:05:51 +02:00
}
if err . Error ( ) != "Bucket exists: string" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the error message to be `%s`, but instead found `%s`" , instanceType , "Bucket exists: string" , err . Error ( ) )
2016-07-08 00:05:51 +02:00
}
}
2020-06-13 05:04:01 +02:00
// Wrapper for calling testPutObject for both Erasure and FS.
2017-10-10 11:14:42 +02:00
func ( s * ObjectLayerAPISuite ) TestPutObject ( t * testing . T ) {
ExecObjectLayerTest ( t , testPutObject )
2015-10-16 20:26:01 +02:00
}
2016-06-09 07:00:31 +02:00
// Tests validate PutObject without prefix.
2017-10-10 11:14:42 +02:00
func testPutObject ( obj ObjectLayer , instanceType string , t TestErrHandler ) {
2016-06-09 07:00:31 +02:00
content := [ ] byte ( "testcontent" )
length := int64 ( len ( content ) )
readerEOF := newTestReaderEOF ( content )
readerNoEOF := newTestReaderNoEOF ( content )
2020-06-13 05:04:01 +02:00
err := obj . MakeBucketWithLocation ( context . Background ( ) , "bucket" , BucketOptions { } )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2016-06-09 07:00:31 +02:00
var bytesBuffer1 bytes . Buffer
2018-09-10 18:42:43 +02:00
var opts ObjectOptions
2019-02-09 06:31:06 +01:00
_ , err = obj . PutObject ( context . Background ( ) , "bucket" , "object" , mustGetPutObjReader ( t , readerEOF , length , "" , "" ) , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2018-09-10 18:42:43 +02:00
err = obj . GetObject ( context . Background ( ) , "bucket" , "object" , 0 , length , & bytesBuffer1 , "" , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if len ( bytesBuffer1 . Bytes ( ) ) != len ( content ) {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected content length to be `%d`, but instead found `%d`" , instanceType , len ( content ) , len ( bytesBuffer1 . Bytes ( ) ) )
2016-07-08 00:05:51 +02:00
}
2016-06-09 07:00:31 +02:00
var bytesBuffer2 bytes . Buffer
2019-02-09 06:31:06 +01:00
_ , err = obj . PutObject ( context . Background ( ) , "bucket" , "object" , mustGetPutObjReader ( t , readerNoEOF , length , "" , "" ) , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2018-09-10 18:42:43 +02:00
err = obj . GetObject ( context . Background ( ) , "bucket" , "object" , 0 , length , & bytesBuffer2 , "" , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if len ( bytesBuffer2 . Bytes ( ) ) != len ( content ) {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected content length to be `%d`, but instead found `%d`" , instanceType , len ( content ) , len ( bytesBuffer2 . Bytes ( ) ) )
2016-07-08 00:05:51 +02:00
}
}
2020-06-13 05:04:01 +02:00
// Wrapper for calling testPutObjectInSubdir for both Erasure and FS.
2017-10-10 11:14:42 +02:00
func ( s * ObjectLayerAPISuite ) TestPutObjectInSubdir ( t * testing . T ) {
ExecObjectLayerTest ( t , testPutObjectInSubdir )
2016-06-09 07:00:31 +02:00
}
2016-04-28 04:28:13 +02:00
// Tests validate PutObject with subdirectory prefix.
2017-10-10 11:14:42 +02:00
func testPutObjectInSubdir ( obj ObjectLayer , instanceType string , t TestErrHandler ) {
2020-06-13 05:04:01 +02:00
err := obj . MakeBucketWithLocation ( context . Background ( ) , "bucket" , BucketOptions { } )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
2018-09-10 18:42:43 +02:00
var opts ObjectOptions
2016-07-08 00:05:51 +02:00
uploadContent := ` The specified multipart upload does not exist . The upload ID might be invalid , or the multipart
upload might have been aborted or completed . `
length := int64 ( len ( uploadContent ) )
2019-02-09 06:31:06 +01:00
_ , err = obj . PutObject ( context . Background ( ) , "bucket" , "dir1/dir2/object" , mustGetPutObjReader ( t , bytes . NewBufferString ( uploadContent ) , length , "" , "" ) , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
var bytesBuffer bytes . Buffer
2018-09-10 18:42:43 +02:00
err = obj . GetObject ( context . Background ( ) , "bucket" , "dir1/dir2/object" , 0 , length , & bytesBuffer , "" , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if len ( bytesBuffer . Bytes ( ) ) != len ( uploadContent ) {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected length of downloaded data to be `%d`, but instead found `%d`" ,
2016-07-08 00:05:51 +02:00
instanceType , len ( uploadContent ) , len ( bytesBuffer . Bytes ( ) ) )
}
}
2020-06-13 05:04:01 +02:00
// Wrapper for calling testListBuckets for both Erasure and FS.
2017-10-10 11:14:42 +02:00
func ( s * ObjectLayerAPISuite ) TestListBuckets ( t * testing . T ) {
ExecObjectLayerTest ( t , testListBuckets )
2015-10-16 20:26:01 +02:00
}
2016-04-28 04:28:13 +02:00
// Tests validate ListBuckets.
2017-10-10 11:14:42 +02:00
func testListBuckets ( obj ObjectLayer , instanceType string , t TestErrHandler ) {
2016-04-28 04:28:13 +02:00
// test empty list.
2018-03-15 21:27:16 +01:00
buckets , err := obj . ListBuckets ( context . Background ( ) )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if len ( buckets ) != 0 {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected number of bucket to be `%d`, but instead found `%d`" , instanceType , 0 , len ( buckets ) )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
2016-04-28 04:28:13 +02:00
// add one and test exists.
2020-06-13 05:04:01 +02:00
err = obj . MakeBucketWithLocation ( context . Background ( ) , "bucket1" , BucketOptions { } )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
2018-03-15 21:27:16 +01:00
buckets , err = obj . ListBuckets ( context . Background ( ) )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if len ( buckets ) != 1 {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected number of bucket to be `%d`, but instead found `%d`" , instanceType , 1 , len ( buckets ) )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
2016-04-28 04:28:13 +02:00
// add two and test exists.
2020-06-13 05:04:01 +02:00
err = obj . MakeBucketWithLocation ( context . Background ( ) , "bucket2" , BucketOptions { } )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
2018-03-15 21:27:16 +01:00
buckets , err = obj . ListBuckets ( context . Background ( ) )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if len ( buckets ) != 2 {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected number of bucket to be `%d`, but instead found `%d`" , instanceType , 2 , len ( buckets ) )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
2016-04-28 04:28:13 +02:00
// add three and test exists + prefix.
2020-06-13 05:04:01 +02:00
err = obj . MakeBucketWithLocation ( context . Background ( ) , "bucket22" , BucketOptions { } )
2016-09-02 08:10:50 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-09-02 08:10:50 +02:00
}
2015-10-16 20:26:01 +02:00
2018-03-15 21:27:16 +01:00
buckets , err = obj . ListBuckets ( context . Background ( ) )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if len ( buckets ) != 3 {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected number of bucket to be `%d`, but instead found `%d`" , instanceType , 3 , len ( buckets ) )
2016-07-08 00:05:51 +02:00
}
}
2020-06-13 05:04:01 +02:00
// Wrapper for calling testListBucketsOrder for both Erasure and FS.
2017-10-10 11:14:42 +02:00
func ( s * ObjectLayerAPISuite ) TestListBucketsOrder ( t * testing . T ) {
ExecObjectLayerTest ( t , testListBucketsOrder )
2015-10-16 20:26:01 +02:00
}
2016-04-28 04:28:13 +02:00
// Tests validate the order of result of ListBuckets.
2017-10-10 11:14:42 +02:00
func testListBucketsOrder ( obj ObjectLayer , instanceType string , t TestErrHandler ) {
2015-10-16 20:26:01 +02:00
// if implementation contains a map, order of map keys will vary.
2016-04-28 04:28:13 +02:00
// this ensures they return in the same order each time.
2016-06-28 13:21:52 +02:00
// add one and test exists.
2020-06-13 05:04:01 +02:00
err := obj . MakeBucketWithLocation ( context . Background ( ) , "bucket1" , BucketOptions { } )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2020-06-13 05:04:01 +02:00
err = obj . MakeBucketWithLocation ( context . Background ( ) , "bucket2" , BucketOptions { } )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2018-03-15 21:27:16 +01:00
buckets , err := obj . ListBuckets ( context . Background ( ) )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if len ( buckets ) != 2 {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected number of bucket to be `%d`, but instead found `%d`" , instanceType , 2 , len ( buckets ) )
2016-07-08 00:05:51 +02:00
}
if buckets [ 0 ] . Name != "bucket1" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected bucket name to be `%s`, but instead found `%s`" , instanceType , "bucket1" , buckets [ 0 ] . Name )
2016-07-08 00:05:51 +02:00
}
if buckets [ 1 ] . Name != "bucket2" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected bucket name to be `%s`, but instead found `%s`" , instanceType , "bucket2" , buckets [ 1 ] . Name )
2016-07-08 00:05:51 +02:00
}
}
2020-06-13 05:04:01 +02:00
// Wrapper for calling testListObjectsTestsForNonExistantBucket for both Erasure and FS.
2017-10-10 11:14:42 +02:00
func ( s * ObjectLayerAPISuite ) TestListObjectsTestsForNonExistantBucket ( t * testing . T ) {
ExecObjectLayerTest ( t , testListObjectsTestsForNonExistantBucket )
2015-10-16 20:26:01 +02:00
}
2016-04-28 04:28:13 +02:00
// Tests validate that ListObjects operation on a non-existent bucket fails as expected.
2017-10-10 11:14:42 +02:00
func testListObjectsTestsForNonExistantBucket ( obj ObjectLayer , instanceType string , t TestErrHandler ) {
2018-03-15 21:27:16 +01:00
result , err := obj . ListObjects ( context . Background ( ) , "bucket" , "" , "" , "" , 1000 )
2016-07-08 00:05:51 +02:00
if err == nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: Expected error but found nil." , instanceType )
2016-07-08 00:05:51 +02:00
}
if len ( result . Objects ) != 0 {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: Expected number of objects in the result to be `%d`, but instead found `%d`" , instanceType , 0 , len ( result . Objects ) )
2016-07-08 00:05:51 +02:00
}
2017-03-08 19:00:47 +01:00
if result . IsTruncated {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: Expected IsTruncated to be `false`, but instead found it to be `%v`" , instanceType , result . IsTruncated )
2016-07-08 00:05:51 +02:00
}
if err . Error ( ) != "Bucket not found: bucket" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the error msg to be `%s`, but instead found `%s`" , instanceType , "Bucket not found: bucket" , err . Error ( ) )
2016-07-08 00:05:51 +02:00
}
}
2020-06-13 05:04:01 +02:00
// Wrapper for calling testNonExistantObjectInBucket for both Erasure and FS.
2017-10-10 11:14:42 +02:00
func ( s * ObjectLayerAPISuite ) TestNonExistantObjectInBucket ( t * testing . T ) {
ExecObjectLayerTest ( t , testNonExistantObjectInBucket )
2015-10-16 20:26:01 +02:00
}
2016-04-28 04:28:13 +02:00
// Tests validate that GetObject fails on a non-existent bucket as expected.
2017-10-10 11:14:42 +02:00
func testNonExistantObjectInBucket ( obj ObjectLayer , instanceType string , t TestErrHandler ) {
2020-06-13 05:04:01 +02:00
err := obj . MakeBucketWithLocation ( context . Background ( ) , "bucket" , BucketOptions { } )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
2018-09-10 18:42:43 +02:00
_ , err = obj . GetObjectInfo ( context . Background ( ) , "bucket" , "dir1" , ObjectOptions { } )
2016-07-08 00:05:51 +02:00
if err == nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: Expected error but found nil" , instanceType )
2016-07-08 00:05:51 +02:00
}
2016-11-17 01:42:23 +01:00
if isErrObjectNotFound ( err ) {
2016-07-08 00:05:51 +02:00
if err . Error ( ) != "Object not found: bucket#dir1" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the Error message to be `%s`, but instead found `%s`" , instanceType , "Object not found: bucket#dir1" , err . Error ( ) )
2016-07-08 00:05:51 +02:00
}
2016-11-17 01:42:23 +01:00
} else {
2016-07-08 00:05:51 +02:00
if err . Error ( ) != "fails" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected the Error message to be `%s`, but instead found it to be `%s`" , instanceType , "fails" , err . Error ( ) )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
}
}
2020-06-13 05:04:01 +02:00
// Wrapper for calling testGetDirectoryReturnsObjectNotFound for both Erasure and FS.
2017-10-10 11:14:42 +02:00
func ( s * ObjectLayerAPISuite ) TestGetDirectoryReturnsObjectNotFound ( t * testing . T ) {
ExecObjectLayerTest ( t , testGetDirectoryReturnsObjectNotFound )
2016-07-08 00:05:51 +02:00
}
2016-04-28 04:28:13 +02:00
// Tests validate that GetObject on an existing directory fails as expected.
2017-10-10 11:14:42 +02:00
func testGetDirectoryReturnsObjectNotFound ( obj ObjectLayer , instanceType string , t TestErrHandler ) {
2017-03-14 06:20:46 +01:00
bucketName := "bucket"
2020-06-13 05:04:01 +02:00
err := obj . MakeBucketWithLocation ( context . Background ( ) , bucketName , BucketOptions { } )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2017-09-19 21:40:27 +02:00
content := "One or more of the specified parts could not be found. The part might not have been uploaded, or the specified entity tag might not have matched the part's entity tag."
length := int64 ( len ( content ) )
2018-09-10 18:42:43 +02:00
var opts ObjectOptions
2019-02-09 06:31:06 +01:00
_ , err = obj . PutObject ( context . Background ( ) , bucketName , "dir1/dir3/object" , mustGetPutObjReader ( t , bytes . NewBufferString ( content ) , length , "" , "" ) , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
2017-05-10 02:46:46 +02:00
testCases := [ ] struct {
dir string
err error
} {
{
dir : "dir1/" ,
err : ObjectNotFound { Bucket : bucketName , Object : "dir1/" } ,
} ,
{
dir : "dir1/dir3/" ,
err : ObjectNotFound { Bucket : bucketName , Object : "dir1/dir3/" } ,
} ,
}
for i , testCase := range testCases {
2018-09-10 18:42:43 +02:00
_ , expectedErr := obj . GetObjectInfo ( context . Background ( ) , bucketName , testCase . dir , opts )
2018-04-10 18:36:37 +02:00
if expectedErr != nil && expectedErr . Error ( ) != testCase . err . Error ( ) {
t . Errorf ( "Test %d, %s: Expected error %s, got %s" , i + 1 , instanceType , testCase . err , expectedErr )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
}
}
2020-06-13 05:04:01 +02:00
// Wrapper for calling testContentType for both Erasure and FS.
2017-10-10 11:14:42 +02:00
func ( s * ObjectLayerAPISuite ) TestContentType ( t * testing . T ) {
ExecObjectLayerTest ( t , testContentType )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
2016-07-08 00:05:51 +02:00
// Test content-type.
2017-10-10 11:14:42 +02:00
func testContentType ( obj ObjectLayer , instanceType string , t TestErrHandler ) {
2020-06-13 05:04:01 +02:00
err := obj . MakeBucketWithLocation ( context . Background ( ) , "bucket" , BucketOptions { } )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2018-09-10 18:42:43 +02:00
var opts ObjectOptions
2016-07-08 00:05:51 +02:00
uploadContent := "The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed."
2016-04-28 04:28:13 +02:00
// Test empty.
2019-02-09 06:31:06 +01:00
_ , err = obj . PutObject ( context . Background ( ) , "bucket" , "minio.png" , mustGetPutObjReader ( t , bytes . NewBufferString ( uploadContent ) , int64 ( len ( uploadContent ) ) , "" , "" ) , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
2018-09-10 18:42:43 +02:00
objInfo , err := obj . GetObjectInfo ( context . Background ( ) , "bucket" , "minio.png" , opts )
2016-07-08 00:05:51 +02:00
if err != nil {
2017-10-10 11:14:42 +02:00
t . Fatalf ( "%s: <ERROR> %s" , instanceType , err )
2016-07-08 00:05:51 +02:00
}
if objInfo . ContentType != "image/png" {
2017-10-10 11:14:42 +02:00
t . Errorf ( "%s: Expected Content type to be `%s`, but instead found `%s`" , instanceType , "image/png" , objInfo . ContentType )
2016-07-08 00:05:51 +02:00
}
2015-10-16 20:26:01 +02:00
}