Object layer tests revamp for individual execution (#2134)

This commit is contained in:
karthic rao 2016-07-08 03:35:51 +05:30 committed by Harshavardhana
parent 282044d454
commit 2c837128ef
8 changed files with 525 additions and 279 deletions

View File

@ -316,7 +316,7 @@ func TestPutBucketPolicyHandler(t *testing.T) {
// testPutBucketPolicyHandler - Test for Bucket policy end point. // testPutBucketPolicyHandler - Test for Bucket policy end point.
// TODO: Add exhaustive cases with various combination of statement fields. // TODO: Add exhaustive cases with various combination of statement fields.
func testPutBucketPolicyHandler(obj ObjectLayer, instanceType string, t *testing.T) { func testPutBucketPolicyHandler(obj ObjectLayer, instanceType string, t TestErrHandler) {
// get random bucket name. // get random bucket name.
bucketName := getRandomBucketName() bucketName := getRandomBucketName()
// Create bucket. // Create bucket.
@ -411,7 +411,7 @@ func TestGetBucketPolicyHandler(t *testing.T) {
// testGetBucketPolicyHandler - Test for end point which fetches the access policy json of the given bucket. // testGetBucketPolicyHandler - Test for end point which fetches the access policy json of the given bucket.
// TODO: Add exhaustive cases with various combination of statement fields. // TODO: Add exhaustive cases with various combination of statement fields.
func testGetBucketPolicyHandler(obj ObjectLayer, instanceType string, t *testing.T) { func testGetBucketPolicyHandler(obj ObjectLayer, instanceType string, t TestErrHandler) {
// get random bucket name. // get random bucket name.
bucketName := getRandomBucketName() bucketName := getRandomBucketName()
// Create bucket. // Create bucket.
@ -550,7 +550,7 @@ func TestDeleteBucketPolicyHandler(t *testing.T) {
// testDeleteBucketPolicyHandler - Test for Delete bucket policy end point. // testDeleteBucketPolicyHandler - Test for Delete bucket policy end point.
// TODO: Add exhaustive cases with various combination of statement fields. // TODO: Add exhaustive cases with various combination of statement fields.
func testDeleteBucketPolicyHandler(obj ObjectLayer, instanceType string, t *testing.T) { func testDeleteBucketPolicyHandler(obj ObjectLayer, instanceType string, t TestErrHandler) {
// get random bucket name. // get random bucket name.
bucketName := getRandomBucketName() bucketName := getRandomBucketName()
// Create bucket. // Create bucket.

View File

@ -27,7 +27,7 @@ func TestGetObjectInfo(t *testing.T) {
} }
// Testing GetObjectInfo(). // Testing GetObjectInfo().
func testGetObjectInfo(obj ObjectLayer, instanceType string, t *testing.T) { func testGetObjectInfo(obj ObjectLayer, instanceType string, t TestErrHandler) {
// This bucket is used for testing getObjectInfo operations. // This bucket is used for testing getObjectInfo operations.
err := obj.MakeBucket("test-getobjectinfo") err := obj.MakeBucket("test-getobjectinfo")
if err != nil { if err != nil {

View File

@ -32,7 +32,7 @@ func TestListObjects(t *testing.T) {
} }
// Unit test for ListObjects in general. // Unit test for ListObjects in general.
func testListObjects(obj ObjectLayer, instanceType string, t *testing.T) { func testListObjects(obj ObjectLayer, instanceType string, t TestErrHandler) {
// This bucket is used for testing ListObject operations. // This bucket is used for testing ListObject operations.
err := obj.MakeBucket("test-bucket-list-object") err := obj.MakeBucket("test-bucket-list-object")

View File

@ -31,7 +31,7 @@ func TestObjectNewMultipartUpload(t *testing.T) {
} }
// Tests validate creation of new multipart upload instance. // Tests validate creation of new multipart upload instance.
func testObjectNewMultipartUpload(obj ObjectLayer, instanceType string, t *testing.T) { func testObjectNewMultipartUpload(obj ObjectLayer, instanceType string, t TestErrHandler) {
bucket := "minio-bucket" bucket := "minio-bucket"
object := "minio-object" object := "minio-object"
@ -75,7 +75,7 @@ func TestObjectAPIIsUploadIDExists(t *testing.T) {
} }
// Tests validates the validator for existence of uploadID. // Tests validates the validator for existence of uploadID.
func testObjectAPIIsUploadIDExists(obj ObjectLayer, instanceType string, t *testing.T) { func testObjectAPIIsUploadIDExists(obj ObjectLayer, instanceType string, t TestErrHandler) {
bucket := "minio-bucket" bucket := "minio-bucket"
object := "minio-object" object := "minio-object"
@ -185,7 +185,7 @@ func TestObjectAPIPutObjectPart(t *testing.T) {
} }
// Tests validate correctness of PutObjectPart. // Tests validate correctness of PutObjectPart.
func testObjectAPIPutObjectPart(obj ObjectLayer, instanceType string, t *testing.T) { func testObjectAPIPutObjectPart(obj ObjectLayer, instanceType string, t TestErrHandler) {
// Generating cases for which the PutObjectPart fails. // Generating cases for which the PutObjectPart fails.
bucket := "minio-bucket" bucket := "minio-bucket"
object := "minio-object" object := "minio-object"
@ -310,7 +310,7 @@ func TestListMultipartUploads(t *testing.T) {
} }
// testListMultipartUploads - Tests validate listing of multipart uploads. // testListMultipartUploads - Tests validate listing of multipart uploads.
func testListMultipartUploads(obj ObjectLayer, instanceType string, t *testing.T) { func testListMultipartUploads(obj ObjectLayer, instanceType string, t TestErrHandler) {
bucketNames := []string{"minio-bucket", "minio-2-bucket", "minio-3-bucket"} bucketNames := []string{"minio-bucket", "minio-2-bucket", "minio-3-bucket"}
objectNames := []string{"minio-object-1.txt", "minio-object.txt", "neymar-1.jpeg", "neymar.jpeg", "parrot-1.png", "parrot.png"} objectNames := []string{"minio-object-1.txt", "minio-object.txt", "neymar-1.jpeg", "neymar.jpeg", "parrot-1.png", "parrot.png"}
@ -1453,7 +1453,7 @@ func TestListObjectParts(t *testing.T) {
} }
// testListMultipartUploads - Tests validate listing of multipart uploads. // testListMultipartUploads - Tests validate listing of multipart uploads.
func testListObjectParts(obj ObjectLayer, instanceType string, t *testing.T) { func testListObjectParts(obj ObjectLayer, instanceType string, t TestErrHandler) {
bucketNames := []string{"minio-bucket", "minio-2-bucket"} bucketNames := []string{"minio-bucket", "minio-2-bucket"}
objectNames := []string{"minio-object-1.txt"} objectNames := []string{"minio-object-1.txt"}
@ -1689,7 +1689,7 @@ func TestObjectCompleteMultipartUpload(t *testing.T) {
} }
// Tests validate CompleteMultipart functionality. // Tests validate CompleteMultipart functionality.
func testObjectCompleteMultipartUpload(obj ObjectLayer, instanceType string, t *testing.T) { func testObjectCompleteMultipartUpload(obj ObjectLayer, instanceType string, t TestErrHandler) {
// Calculates MD5 sum of the given byte array. // Calculates MD5 sum of the given byte array.
findMD5 := func(toBeHashed []byte) string { findMD5 := func(toBeHashed []byte) string {
hasher := md5.New() hasher := md5.New()

View File

@ -33,7 +33,7 @@ func TestObjectAPIPutObject(t *testing.T) {
} }
// Tests validate correctness of PutObject. // Tests validate correctness of PutObject.
func testObjectAPIPutObject(obj ObjectLayer, instanceType string, t *testing.T) { func testObjectAPIPutObject(obj ObjectLayer, instanceType string, t TestErrHandler) {
// Generating cases for which the PutObject fails. // Generating cases for which the PutObject fails.
bucket := "minio-bucket" bucket := "minio-bucket"
object := "minio-object" object := "minio-object"

View File

@ -1,69 +0,0 @@
/*
* Minio Cloud Storage, (C) 2015, 2016 Minio, Inc.
*
* 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.
*/
package main
import . "gopkg.in/check.v1"
type ObjectLayerAPISuite struct{}
var _ = Suite(&ObjectLayerAPISuite{})
// TestFSAPISuite - Calls object layer suite tests with FS backend.
func (s *ObjectLayerAPISuite) TestFSAPISuite(c *C) {
// Initialize name space lock.
initNSLock()
// function which creates a temp FS backend and executes the object layer suite test.
execObjectLayerSuiteTestFS := func(objSuiteTest objSuiteTestType) {
// create temp object layer backend.
// returns the disk and FS object layer.
objLayer, fsDisk, err := makeTestBackend("FS")
c.Check(err, IsNil)
// remove the disks.
defer removeRoots(fsDisk)
// execute the object layer suite tests.
objSuiteTest(c, objLayer)
}
// APITestSuite contains set of all object layer suite test.
// These set of test functions are called here.
APITestSuite(c, execObjectLayerSuiteTestFS)
}
// type for object layer suites tests.
type objSuiteTestType func(c *C, obj ObjectLayer)
// TestXLAPISuite - Calls object layer suite tests with XL backend.
func (s *ObjectLayerAPISuite) TestXLAPISuite(c *C) {
// Initialize name space lock.
initNSLock()
// function which creates a temp XL backend and executes the object layer suite test.
execObjectLayerSuiteTestXL := func(objSuiteTest objSuiteTestType) {
// create temp object layer backend.
// returns the disk and XL object layer.
objLayer, erasureDisks, err := makeTestBackend("XL")
c.Check(err, IsNil)
// remove the disks.
defer removeRoots(erasureDisks)
// execute the object layer suite tests.
objSuiteTest(c, objLayer)
}
// APITestSuite contains set of all object layer suite test.
// These set of test functions are called here.
APITestSuite(c, execObjectLayerSuiteTestXL)
}

View File

@ -24,7 +24,7 @@ import (
"math/rand" "math/rand"
"strconv" "strconv"
"gopkg.in/check.v1" . "gopkg.in/check.v1"
) )
// Return pointer to testOneByteReadEOF{} // Return pointer to testOneByteReadEOF{}
@ -68,44 +68,38 @@ func (r *testOneByteReadNoEOF) Read(p []byte) (n int, err error) {
return n, nil return n, nil
} }
// APITestSuite - collection of API tests. type ObjectLayerAPISuite struct{}
func APITestSuite(c *check.C, execObjLayerSuiteTest func(objSuiteTest objSuiteTestType)) {
// List containing collection of all tests. var _ = Suite(&ObjectLayerAPISuite{})
testFuncList := []func(c *check.C, obj ObjectLayer){
testMakeBucket, // Wrapper for calling testMakeBucket for both XL and FS.
testMultipartObjectCreation, func (s *ObjectLayerAPISuite) TestMakeBucket(c *C) {
testPaging, ExecObjectLayerTest(c, testMakeBucket)
testObjectOverwriteWorks,
testNonExistantBucketOperations,
testBucketRecreateFails,
testPutObject,
testPutObjectInSubdir,
testListBuckets,
testListBucketsOrder,
testListObjectsTestsForNonExistantBucket,
testNonExistantObjectInBucket,
testGetDirectoryReturnsObjectNotFound,
testContentType,
testMultipartObjectAbort,
}
// iterate over list of tests and execute them.
for _, testFunc := range testFuncList {
execObjLayerSuiteTest(testFunc)
}
} }
// Tests validate bucket creation. // Tests validate bucket creation.
func testMakeBucket(c *check.C, obj ObjectLayer) { func testMakeBucket(obj ObjectLayer, instanceType string, c TestErrHandler) {
err := obj.MakeBucket("bucket-unknown") err := obj.MakeBucket("bucket-unknown")
c.Assert(err, check.IsNil) if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
}
// Wrapper for calling testMultipartObjectCreation for both XL and FS.
func (s *ObjectLayerAPISuite) TestMultipartObjectCreation(c *C) {
ExecObjectLayerTest(c, testMultipartObjectCreation)
} }
// Tests validate creation of part files during Multipart operation. // Tests validate creation of part files during Multipart operation.
func testMultipartObjectCreation(c *check.C, obj ObjectLayer) { func testMultipartObjectCreation(obj ObjectLayer, instanceType string, c TestErrHandler) {
err := obj.MakeBucket("bucket") err := obj.MakeBucket("bucket")
c.Assert(err, check.IsNil) if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
uploadID, err := obj.NewMultipartUpload("bucket", "key", nil) uploadID, err := obj.NewMultipartUpload("bucket", "key", nil)
c.Assert(err, check.IsNil) if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
// Create a byte array of 5MB. // Create a byte array of 5MB.
data := bytes.Repeat([]byte("0123456789abcdef"), 5*1024*1024/16) data := bytes.Repeat([]byte("0123456789abcdef"), 5*1024*1024/16)
completedParts := completeMultipartUpload{} completedParts := completeMultipartUpload{}
@ -116,21 +110,38 @@ func testMultipartObjectCreation(c *check.C, obj ObjectLayer) {
var calculatedMD5sum string var calculatedMD5sum string
calculatedMD5sum, err = obj.PutObjectPart("bucket", "key", uploadID, i, int64(len(data)), bytes.NewBuffer(data), expectedMD5Sumhex) calculatedMD5sum, err = obj.PutObjectPart("bucket", "key", uploadID, i, int64(len(data)), bytes.NewBuffer(data), expectedMD5Sumhex)
c.Assert(err, check.IsNil) if err != nil {
c.Assert(calculatedMD5sum, check.Equals, expectedMD5Sumhex) c.Errorf("%s: <ERROR> %s", instanceType, err)
}
if calculatedMD5sum != expectedMD5Sumhex {
c.Errorf("MD5 Mismatch")
}
completedParts.Parts = append(completedParts.Parts, completePart{PartNumber: i, ETag: calculatedMD5sum}) completedParts.Parts = append(completedParts.Parts, completePart{PartNumber: i, ETag: calculatedMD5sum})
} }
md5Sum, err := obj.CompleteMultipartUpload("bucket", "key", uploadID, completedParts.Parts) md5Sum, err := obj.CompleteMultipartUpload("bucket", "key", uploadID, completedParts.Parts)
c.Assert(err, check.IsNil) if err != nil {
c.Assert(md5Sum, check.Equals, "7d364cb728ce42a74a96d22949beefb2-10") c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
if md5Sum != "7d364cb728ce42a74a96d22949beefb2-10" {
c.Errorf("Md5 mismtch")
}
}
// Wrapper for calling testMultipartObjectAbort for both XL and FS.
func (s *ObjectLayerAPISuite) TestMultipartObjectAbort(c *C) {
ExecObjectLayerTest(c, testMultipartObjectAbort)
} }
// Tests validate abortion of Multipart operation. // Tests validate abortion of Multipart operation.
func testMultipartObjectAbort(c *check.C, obj ObjectLayer) { func testMultipartObjectAbort(obj ObjectLayer, instanceType string, c TestErrHandler) {
err := obj.MakeBucket("bucket") err := obj.MakeBucket("bucket")
c.Assert(err, check.IsNil) if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
uploadID, err := obj.NewMultipartUpload("bucket", "key", nil) uploadID, err := obj.NewMultipartUpload("bucket", "key", nil)
c.Assert(err, check.IsNil) if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
parts := make(map[int]string) parts := make(map[int]string)
metadata := make(map[string]string) metadata := make(map[string]string)
@ -148,19 +159,32 @@ func testMultipartObjectAbort(c *check.C, obj ObjectLayer) {
metadata["md5"] = expectedMD5Sumhex metadata["md5"] = expectedMD5Sumhex
var calculatedMD5sum string var calculatedMD5sum string
calculatedMD5sum, err = obj.PutObjectPart("bucket", "key", uploadID, i, int64(len(randomString)), bytes.NewBufferString(randomString), expectedMD5Sumhex) calculatedMD5sum, err = obj.PutObjectPart("bucket", "key", uploadID, i, int64(len(randomString)), bytes.NewBufferString(randomString), expectedMD5Sumhex)
c.Assert(err, check.IsNil) if err != nil {
c.Assert(calculatedMD5sum, check.Equals, expectedMD5Sumhex) c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
if calculatedMD5sum != expectedMD5Sumhex {
c.Errorf("Md5 Mismatch")
}
parts[i] = expectedMD5Sumhex parts[i] = expectedMD5Sumhex
} }
err = obj.AbortMultipartUpload("bucket", "key", uploadID) err = obj.AbortMultipartUpload("bucket", "key", uploadID)
c.Assert(err, check.IsNil) if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
}
// Wrapper for calling testMultipleObjectCreation for both XL and FS.
func (s *ObjectLayerAPISuite) TestMultipleObjectCreation(c *C) {
ExecObjectLayerTest(c, testMultipleObjectCreation)
} }
// Tests validate object creation. // Tests validate object creation.
func testMultipleObjectCreation(c *check.C, obj ObjectLayer) { func testMultipleObjectCreation(obj ObjectLayer, instanceType string, c TestErrHandler) {
objects := make(map[string][]byte) objects := make(map[string][]byte)
err := obj.MakeBucket("bucket") err := obj.MakeBucket("bucket")
c.Assert(err, check.IsNil) if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
randomPerm := rand.Perm(100) randomPerm := rand.Perm(100)
randomString := "" randomString := ""
@ -178,307 +202,598 @@ func testMultipleObjectCreation(c *check.C, obj ObjectLayer) {
metadata["md5Sum"] = expectedMD5Sumhex metadata["md5Sum"] = expectedMD5Sumhex
var md5Sum string var md5Sum string
md5Sum, err = obj.PutObject("bucket", key, int64(len(randomString)), bytes.NewBufferString(randomString), metadata) md5Sum, err = obj.PutObject("bucket", key, int64(len(randomString)), bytes.NewBufferString(randomString), metadata)
c.Assert(err, check.IsNil) if err != nil {
c.Assert(md5Sum, check.Equals, expectedMD5Sumhex) c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
if md5Sum != expectedMD5Sumhex {
c.Errorf("Md5 Mismatch")
}
} }
for key, value := range objects { for key, value := range objects {
var byteBuffer bytes.Buffer var byteBuffer bytes.Buffer
err = obj.GetObject("bucket", key, 0, int64(len(value)), &byteBuffer) err = obj.GetObject("bucket", key, 0, int64(len(value)), &byteBuffer)
c.Assert(err, check.IsNil) if err != nil {
c.Assert(byteBuffer.Bytes(), check.DeepEquals, value) c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
if !bytes.Equal(byteBuffer.Bytes(), value) {
c.Errorf("%s: Mismatch of GetObject data with the expected one.", instanceType)
}
objInfo, err := obj.GetObjectInfo("bucket", key) objInfo, err := obj.GetObjectInfo("bucket", key)
c.Assert(err, check.IsNil) if err != nil {
c.Assert(objInfo.Size, check.Equals, int64(len(value))) c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
if objInfo.Size != int64(len(value)) {
c.Errorf("%s: Size mismatch of the GetObject data.", instanceType)
}
} }
} }
// Wrapper for calling TestPaging for both XL and FS.
func (s *ObjectLayerAPISuite) TestPaging(c *C) {
ExecObjectLayerTest(c, testPaging)
}
// Tests validate creation of objects and the order of listing using various filters for ListObjects operation. // Tests validate creation of objects and the order of listing using various filters for ListObjects operation.
func testPaging(c *check.C, obj ObjectLayer) { func testPaging(obj ObjectLayer, instanceType string, c TestErrHandler) {
obj.MakeBucket("bucket") obj.MakeBucket("bucket")
result, err := obj.ListObjects("bucket", "", "", "", 0) result, err := obj.ListObjects("bucket", "", "", "", 0)
c.Assert(err, check.IsNil) if err != nil {
c.Assert(len(result.Objects), check.Equals, 0) c.Fatalf("%s: <ERROR> %s", instanceType, err)
c.Assert(result.IsTruncated, check.Equals, false) }
if len(result.Objects) != 0 {
c.Errorf("%s: Number of objects in the result different from expected value.", instanceType)
}
if result.IsTruncated != false {
c.Errorf("%s: Expected IsTruncated to be `false`, but instead found it to be `%v`", instanceType, result.IsTruncated)
}
uploadContent := "The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed."
// check before paging occurs. // check before paging occurs.
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
key := "obj" + strconv.Itoa(i) key := "obj" + strconv.Itoa(i)
_, err = obj.PutObject("bucket", key, int64(len("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed.")), bytes.NewBufferString("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed."), nil) _, err = obj.PutObject("bucket", key, int64(len(uploadContent)), bytes.NewBufferString(uploadContent), nil)
c.Assert(err, check.IsNil) if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
result, err = obj.ListObjects("bucket", "", "", "", 5) result, err = obj.ListObjects("bucket", "", "", "", 5)
c.Assert(err, check.IsNil) if err != nil {
c.Assert(len(result.Objects), check.Equals, i+1) c.Fatalf("%s: <ERROR> %s", instanceType, err)
c.Assert(result.IsTruncated, check.Equals, false) }
if len(result.Objects) != i+1 {
c.Errorf("%s: Expected length of objects to be %d, instead found to be %d", instanceType, len(result.Objects), i+1)
}
if result.IsTruncated != false {
c.Errorf("%s: Expected IsTruncated to be `false`, but instead found it to be `%v`", instanceType, result.IsTruncated)
}
} }
// check after paging occurs pages work. // check after paging occurs pages work.
for i := 6; i <= 10; i++ { for i := 6; i <= 10; i++ {
key := "obj" + strconv.Itoa(i) key := "obj" + strconv.Itoa(i)
_, err = obj.PutObject("bucket", key, int64(len("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed.")), bytes.NewBufferString("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed."), nil) _, err = obj.PutObject("bucket", key, int64(len(uploadContent)), bytes.NewBufferString(uploadContent), nil)
c.Assert(err, check.IsNil) if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
result, err = obj.ListObjects("bucket", "obj", "", "", 5) result, err = obj.ListObjects("bucket", "obj", "", "", 5)
c.Assert(err, check.IsNil) if err != nil {
c.Assert(len(result.Objects), check.Equals, 5) c.Fatalf("%s: <ERROR> %s", instanceType, err)
c.Assert(result.IsTruncated, check.Equals, true) }
if len(result.Objects) != 5 {
c.Errorf("%s: Expected length of objects to be %d, instead found to be %d", instanceType, 5, len(result.Objects))
}
if result.IsTruncated != true {
c.Errorf("%s: Expected IsTruncated to be `true`, but instead found it to be `%v`", instanceType, result.IsTruncated)
}
} }
// check paging with prefix at end returns less objects. // check paging with prefix at end returns less objects.
{ {
_, err = obj.PutObject("bucket", "newPrefix", int64(len("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed.")), bytes.NewBufferString("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed."), nil) _, err = obj.PutObject("bucket", "newPrefix", int64(len(uploadContent)), bytes.NewBufferString(uploadContent), nil)
c.Assert(err, check.IsNil) if err != nil {
_, err = obj.PutObject("bucket", "newPrefix2", int64(len("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed.")), bytes.NewBufferString("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed."), nil) c.Fatalf("%s: <ERROR> %s", instanceType, err)
c.Assert(err, check.IsNil) }
_, err = obj.PutObject("bucket", "newPrefix2", int64(len(uploadContent)), bytes.NewBufferString(uploadContent), nil)
if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
result, err = obj.ListObjects("bucket", "new", "", "", 5) result, err = obj.ListObjects("bucket", "new", "", "", 5)
c.Assert(err, check.IsNil) if err != nil {
c.Assert(len(result.Objects), check.Equals, 2) c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
if len(result.Objects) != 2 {
c.Errorf("%s: Expected length of objects to be %d, instead found to be %d", instanceType, 2, len(result.Objects))
}
} }
// check ordering of pages. // check ordering of pages.
{ {
result, err = obj.ListObjects("bucket", "", "", "", 1000) result, err = obj.ListObjects("bucket", "", "", "", 1000)
c.Assert(err, check.IsNil) if err != nil {
c.Assert(result.Objects[0].Name, check.Equals, "newPrefix") c.Fatalf("%s: <ERROR> %s", instanceType, err)
c.Assert(result.Objects[1].Name, check.Equals, "newPrefix2") }
c.Assert(result.Objects[2].Name, check.Equals, "obj0") if result.Objects[0].Name != "newPrefix" {
c.Assert(result.Objects[3].Name, check.Equals, "obj1") c.Errorf("%s: Expected the object name to be `%s`, but instead found `%s`", instanceType, "newPrefix", result.Objects[0].Name)
c.Assert(result.Objects[4].Name, check.Equals, "obj10") }
if result.Objects[1].Name != "newPrefix2" {
c.Errorf("%s: Expected the object name to be `%s`, but instead found `%s`", instanceType, "newPrefix", result.Objects[1].Name)
}
if result.Objects[2].Name != "obj0" {
c.Errorf("%s: Expected the object name to be `%s`, but instead found `%s`", instanceType, "newPrefix", result.Objects[2].Name)
}
if result.Objects[3].Name != "obj1" {
c.Errorf("%s: Expected the object name to be `%s`, but instead found `%s`", instanceType, "newPrefix", result.Objects[3].Name)
}
if result.Objects[4].Name != "obj10" {
c.Errorf("%s: Expected the object name to be `%s`, but instead found `%s`", instanceType, "newPrefix", result.Objects[4].Name)
}
} }
// check delimited results with delimiter and prefix. // check delimited results with delimiter and prefix.
{ {
_, err = obj.PutObject("bucket", "this/is/delimited", int64(len("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed.")), bytes.NewBufferString("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed."), nil) _, err = obj.PutObject("bucket", "this/is/delimited", int64(len(uploadContent)), bytes.NewBufferString(uploadContent), nil)
c.Assert(err, check.IsNil) if err != nil {
_, err = obj.PutObject("bucket", "this/is/also/a/delimited/file", int64(len("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed.")), bytes.NewBufferString("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed."), nil) c.Fatalf("%s: <ERROR> %s", instanceType, err)
c.Assert(err, check.IsNil) }
_, err = obj.PutObject("bucket", "this/is/also/a/delimited/file", int64(len(uploadContent)), bytes.NewBufferString(uploadContent), nil)
if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
result, err = obj.ListObjects("bucket", "this/is/", "", "/", 10) result, err = obj.ListObjects("bucket", "this/is/", "", "/", 10)
c.Assert(err, check.IsNil) if err != nil {
c.Assert(len(result.Objects), check.Equals, 1) c.Fatalf("%s: <ERROR> %s", instanceType, err)
c.Assert(result.Prefixes[0], check.Equals, "this/is/also/") }
if len(result.Objects) != 1 {
c.Errorf("%s: Expected the number of objects in the result to be %d, but instead found %d", instanceType, 1, len(result.Objects))
}
if result.Prefixes[0] != "this/is/also/" {
c.Errorf("%s: Expected prefix to be `%s`, but instead found `%s`", instanceType, "this/is/also/", result.Prefixes[0])
}
} }
// check delimited results with delimiter without prefix. // check delimited results with delimiter without prefix.
{ {
result, err = obj.ListObjects("bucket", "", "", "/", 1000) result, err = obj.ListObjects("bucket", "", "", "/", 1000)
c.Assert(err, check.IsNil) if err != nil {
c.Assert(result.Objects[0].Name, check.Equals, "newPrefix") c.Fatalf("%s: <ERROR> %s", instanceType, err)
c.Assert(result.Objects[1].Name, check.Equals, "newPrefix2") }
c.Assert(result.Objects[2].Name, check.Equals, "obj0")
c.Assert(result.Objects[3].Name, check.Equals, "obj1") if result.Objects[0].Name != "newPrefix" {
c.Assert(result.Objects[4].Name, check.Equals, "obj10") c.Errorf("%s: Expected the object name to be `%s`, but instead found `%s`", instanceType, "newPrefix", result.Objects[0].Name)
c.Assert(result.Prefixes[0], check.Equals, "this/") }
if result.Objects[1].Name != "newPrefix2" {
c.Errorf("%s: Expected the object name to be `%s`, but instead found `%s`", instanceType, "newPrefix", result.Objects[1].Name)
}
if result.Objects[2].Name != "obj0" {
c.Errorf("%s: Expected the object name to be `%s`, but instead found `%s`", instanceType, "newPrefix", result.Objects[2].Name)
}
if result.Objects[3].Name != "obj1" {
c.Errorf("%s: Expected the object name to be `%s`, but instead found `%s`", instanceType, "newPrefix", result.Objects[3].Name)
}
if result.Objects[4].Name != "obj10" {
c.Errorf("%s: Expected the object name to be `%s`, but instead found `%s`", instanceType, "newPrefix", result.Objects[4].Name)
}
if result.Prefixes[0] != "this/" {
c.Errorf("%s: Expected the prefix to be `%s`, but instead found `%s`", instanceType, "this/", result.Prefixes[0])
}
} }
// check results with Marker. // check results with Marker.
{ {
result, err = obj.ListObjects("bucket", "", "newPrefix", "", 3) result, err = obj.ListObjects("bucket", "", "newPrefix", "", 3)
c.Assert(err, check.IsNil) if err != nil {
c.Assert(result.Objects[0].Name, check.Equals, "newPrefix2") c.Fatalf("%s: <ERROR> %s", instanceType, err)
c.Assert(result.Objects[1].Name, check.Equals, "obj0") }
c.Assert(result.Objects[2].Name, check.Equals, "obj1") if result.Objects[0].Name != "newPrefix2" {
c.Errorf("%s: Expected the object name to be `%s`, but instead found `%s`", instanceType, "newPrefix2", result.Objects[0].Name)
}
if result.Objects[1].Name != "obj0" {
c.Errorf("%s: Expected the object name to be `%s`, but instead found `%s`", instanceType, "obj0", result.Objects[1].Name)
}
if result.Objects[2].Name != "obj1" {
c.Errorf("%s: Expected the object name to be `%s`, but instead found `%s`", instanceType, "obj1", result.Objects[2].Name)
}
} }
// check ordering of results with prefix. // check ordering of results with prefix.
{ {
result, err = obj.ListObjects("bucket", "obj", "", "", 1000) result, err = obj.ListObjects("bucket", "obj", "", "", 1000)
c.Assert(err, check.IsNil) if err != nil {
c.Assert(result.Objects[0].Name, check.Equals, "obj0") c.Fatalf("%s: <ERROR> %s", instanceType, err)
c.Assert(result.Objects[1].Name, check.Equals, "obj1") }
c.Assert(result.Objects[2].Name, check.Equals, "obj10") if result.Objects[0].Name != "obj0" {
c.Assert(result.Objects[3].Name, check.Equals, "obj2") c.Errorf("%s: Expected the object name to be `%s`, but instead found `%s`", instanceType, "obj0", result.Objects[0].Name)
c.Assert(result.Objects[4].Name, check.Equals, "obj3") }
if result.Objects[1].Name != "obj1" {
c.Errorf("%s: Expected the object name to be `%s`, but instead found `%s`", instanceType, "obj1", result.Objects[1].Name)
}
if result.Objects[2].Name != "obj10" {
c.Errorf("%s: Expected the object name to be `%s`, but instead found `%s`", instanceType, "obj10", result.Objects[2].Name)
}
if result.Objects[3].Name != "obj2" {
c.Errorf("%s: Expected the object name to be `%s`, but instead found `%s`", instanceType, "obj2", result.Objects[3].Name)
}
if result.Objects[4].Name != "obj3" {
c.Errorf("%s: Expected the object name to be `%s`, but instead found `%s`", instanceType, "obj3", result.Objects[4].Name)
}
} }
// check ordering of results with prefix and no paging. // check ordering of results with prefix and no paging.
{ {
result, err = obj.ListObjects("bucket", "new", "", "", 5) result, err = obj.ListObjects("bucket", "new", "", "", 5)
c.Assert(err, check.IsNil) if err != nil {
c.Assert(result.Objects[0].Name, check.Equals, "newPrefix") c.Fatalf("%s: <ERROR> %s", instanceType, err)
c.Assert(result.Objects[1].Name, check.Equals, "newPrefix2") }
if result.Objects[0].Name != "newPrefix" {
c.Errorf("%s: Expected the object name to be `%s`, but instead found `%s`", instanceType, "newPrefix", result.Objects[0].Name)
}
if result.Objects[1].Name != "newPrefix2" {
c.Errorf("%s: Expected the object name to be `%s`, but instead found `%s`", instanceType, "newPrefix2", result.Objects[0].Name)
}
} }
} }
// Wrapper for calling testObjectOverwriteWorks for both XL and FS.
func (s *ObjectLayerAPISuite) TestObjectOverwriteWorks(c *C) {
ExecObjectLayerTest(c, testObjectOverwriteWorks)
}
// Tests validate overwriting of an existing object. // Tests validate overwriting of an existing object.
func testObjectOverwriteWorks(c *check.C, obj ObjectLayer) { func testObjectOverwriteWorks(obj ObjectLayer, instanceType string, c TestErrHandler) {
err := obj.MakeBucket("bucket") err := obj.MakeBucket("bucket")
c.Assert(err, check.IsNil) if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
_, err = obj.PutObject("bucket", "object", int64(len("The list of parts was not in ascending order. The parts list must be specified in order by part number.")), bytes.NewBufferString("The list of parts was not in ascending order. The parts list must be specified in order by part number."), nil) _, err = obj.PutObject("bucket", "object", int64(len("The list of parts was not in ascending order. The parts list must be specified in order by part number.")), bytes.NewBufferString("The list of parts was not in ascending order. The parts list must be specified in order by part number."), nil)
c.Assert(err, check.IsNil) if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
length := int64(len("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed.")) uploadContent := "The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed."
_, err = obj.PutObject("bucket", "object", length, bytes.NewBufferString("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed."), nil) length := int64(len(uploadContent))
c.Assert(err, check.IsNil) _, err = obj.PutObject("bucket", "object", length, bytes.NewBufferString(uploadContent), nil)
if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
var bytesBuffer bytes.Buffer var bytesBuffer bytes.Buffer
err = obj.GetObject("bucket", "object", 0, length, &bytesBuffer) err = obj.GetObject("bucket", "object", 0, length, &bytesBuffer)
c.Assert(err, check.IsNil) if err != nil {
c.Assert(string(bytesBuffer.Bytes()), check.Equals, "The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed.") c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
if string(bytesBuffer.Bytes()) != "The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed." {
c.Errorf("%s: Invalid upload ID error mismatch.", instanceType)
}
}
// Wrapper for calling testNonExistantBucketOperations for both XL and FS.
func (s *ObjectLayerAPISuite) TestNonExistantBucketOperations(c *C) {
ExecObjectLayerTest(c, testNonExistantBucketOperations)
} }
// Tests validate that bucket operation on non-existent bucket fails. // Tests validate that bucket operation on non-existent bucket fails.
func testNonExistantBucketOperations(c *check.C, obj ObjectLayer) { func testNonExistantBucketOperations(obj ObjectLayer, instanceType string, c TestErrHandler) {
_, err := obj.PutObject("bucket1", "object", int64(len("one")), bytes.NewBufferString("one"), nil) _, err := obj.PutObject("bucket1", "object", int64(len("one")), bytes.NewBufferString("one"), nil)
c.Assert(err, check.Not(check.IsNil)) if err == nil {
c.Assert(err.Error(), check.Equals, "Bucket not found: bucket1") c.Fatal("Expected error but found nil")
}
if err.Error() != "Bucket not found: bucket1" {
c.Errorf("%s: Expected the error msg to be `%s`, but instead found `%s`", instanceType, "Bucket not found: bucket1", err.Error())
}
}
// Wrapper for calling testBucketRecreateFails for both XL and FS.
func (s *ObjectLayerAPISuite) TestBucketRecreateFails(c *C) {
ExecObjectLayerTest(c, testBucketRecreateFails)
} }
// Tests validate that recreation of the bucket fails. // Tests validate that recreation of the bucket fails.
func testBucketRecreateFails(c *check.C, obj ObjectLayer) { func testBucketRecreateFails(obj ObjectLayer, instanceType string, c TestErrHandler) {
err := obj.MakeBucket("string") err := obj.MakeBucket("string")
c.Assert(err, check.IsNil) if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
err = obj.MakeBucket("string") err = obj.MakeBucket("string")
c.Assert(err, check.Not(check.IsNil)) if err == nil {
c.Assert(err.Error(), check.Equals, "Bucket exists: string") c.Fatalf("%s: Expected error but found nil.", instanceType)
}
if err.Error() != "Bucket exists: string" {
c.Errorf("%s: Expected the error message to be `%s`, but instead found `%s`", instanceType, "Bucket exists: string", err.Error())
}
}
// Wrapper for calling testPutObject for both XL and FS.
func (s *ObjectLayerAPISuite) TestPutObject(c *C) {
ExecObjectLayerTest(c, testPutObject)
} }
// Tests validate PutObject without prefix. // Tests validate PutObject without prefix.
func testPutObject(c *check.C, obj ObjectLayer) { func testPutObject(obj ObjectLayer, instanceType string, c TestErrHandler) {
content := []byte("testcontent") content := []byte("testcontent")
length := int64(len(content)) length := int64(len(content))
readerEOF := newTestReaderEOF(content) readerEOF := newTestReaderEOF(content)
readerNoEOF := newTestReaderNoEOF(content) readerNoEOF := newTestReaderNoEOF(content)
err := obj.MakeBucket("bucket") err := obj.MakeBucket("bucket")
c.Assert(err, check.IsNil) if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
var bytesBuffer1 bytes.Buffer var bytesBuffer1 bytes.Buffer
_, err = obj.PutObject("bucket", "object", length, readerEOF, nil) _, err = obj.PutObject("bucket", "object", length, readerEOF, nil)
c.Assert(err, check.IsNil) if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
err = obj.GetObject("bucket", "object", 0, length, &bytesBuffer1) err = obj.GetObject("bucket", "object", 0, length, &bytesBuffer1)
c.Assert(err, check.IsNil) if err != nil {
c.Assert(len(bytesBuffer1.Bytes()), check.Equals, len(content)) c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
if len(bytesBuffer1.Bytes()) != len(content) {
c.Errorf("%s: Expected content length to be `%d`, but instead found `%d`", instanceType, len(content), len(bytesBuffer1.Bytes()))
}
var bytesBuffer2 bytes.Buffer var bytesBuffer2 bytes.Buffer
_, err = obj.PutObject("bucket", "object", length, readerNoEOF, nil) _, err = obj.PutObject("bucket", "object", length, readerNoEOF, nil)
c.Assert(err, check.IsNil) if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
err = obj.GetObject("bucket", "object", 0, length, &bytesBuffer2) err = obj.GetObject("bucket", "object", 0, length, &bytesBuffer2)
c.Assert(err, check.IsNil) if err != nil {
c.Assert(len(bytesBuffer2.Bytes()), check.Equals, len(content)) c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
if len(bytesBuffer2.Bytes()) != len(content) {
c.Errorf("%s: Expected content length to be `%d`, but instead found `%d`", instanceType, len(content), len(bytesBuffer2.Bytes()))
}
}
// Wrapper for calling testPutObjectInSubdir for both XL and FS.
func (s *ObjectLayerAPISuite) TestPutObjectInSubdir(c *C) {
ExecObjectLayerTest(c, testPutObjectInSubdir)
} }
// Tests validate PutObject with subdirectory prefix. // Tests validate PutObject with subdirectory prefix.
func testPutObjectInSubdir(c *check.C, obj ObjectLayer) { func testPutObjectInSubdir(obj ObjectLayer, instanceType string, c TestErrHandler) {
err := obj.MakeBucket("bucket") err := obj.MakeBucket("bucket")
c.Assert(err, check.IsNil) if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
length := int64(len("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed.")) uploadContent := `The specified multipart upload does not exist. The upload ID might be invalid, or the multipart
_, err = obj.PutObject("bucket", "dir1/dir2/object", length, bytes.NewBufferString("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed."), nil) upload might have been aborted or completed.`
c.Assert(err, check.IsNil) length := int64(len(uploadContent))
_, err = obj.PutObject("bucket", "dir1/dir2/object", length, bytes.NewBufferString(uploadContent), nil)
if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
var bytesBuffer bytes.Buffer var bytesBuffer bytes.Buffer
err = obj.GetObject("bucket", "dir1/dir2/object", 0, length, &bytesBuffer) err = obj.GetObject("bucket", "dir1/dir2/object", 0, length, &bytesBuffer)
c.Assert(err, check.IsNil) if err != nil {
c.Assert(len(bytesBuffer.Bytes()), check.Equals, len("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed.")) c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
if len(bytesBuffer.Bytes()) != len(uploadContent) {
c.Errorf("%s: Expected length of downloaded data to be `%d`, but instead found `%d`",
instanceType, len(uploadContent), len(bytesBuffer.Bytes()))
}
}
// Wrapper for calling testListBuckets for both XL and FS.
func (s *ObjectLayerAPISuite) TestListBuckets(c *C) {
ExecObjectLayerTest(c, testListBuckets)
} }
// Tests validate ListBuckets. // Tests validate ListBuckets.
func testListBuckets(c *check.C, obj ObjectLayer) { func testListBuckets(obj ObjectLayer, instanceType string, c TestErrHandler) {
// test empty list. // test empty list.
buckets, err := obj.ListBuckets() buckets, err := obj.ListBuckets()
c.Assert(err, check.IsNil) if err != nil {
c.Assert(len(buckets), check.Equals, 0) c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
if len(buckets) != 0 {
c.Errorf("%s: Expected number of bucket to be `%d`, but instead found `%d`", instanceType, 0, len(buckets))
}
// add one and test exists. // add one and test exists.
err = obj.MakeBucket("bucket1") err = obj.MakeBucket("bucket1")
c.Assert(err, check.IsNil) if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
buckets, err = obj.ListBuckets() buckets, err = obj.ListBuckets()
c.Assert(len(buckets), check.Equals, 1) if err != nil {
c.Assert(err, check.IsNil) c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
if len(buckets) != 1 {
c.Errorf("%s: Expected number of bucket to be `%d`, but instead found `%d`", instanceType, 1, len(buckets))
}
// add two and test exists. // add two and test exists.
err = obj.MakeBucket("bucket2") err = obj.MakeBucket("bucket2")
c.Assert(err, check.IsNil) if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
buckets, err = obj.ListBuckets() buckets, err = obj.ListBuckets()
c.Assert(len(buckets), check.Equals, 2) if err != nil {
c.Assert(err, check.IsNil) c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
if len(buckets) != 2 {
c.Errorf("%s: Expected number of bucket to be `%d`, but instead found `%d`", instanceType, 2, len(buckets))
}
// add three and test exists + prefix. // add three and test exists + prefix.
err = obj.MakeBucket("bucket22") err = obj.MakeBucket("bucket22")
buckets, err = obj.ListBuckets() buckets, err = obj.ListBuckets()
c.Assert(len(buckets), check.Equals, 3) if err != nil {
c.Assert(err, check.IsNil) c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
if len(buckets) != 3 {
c.Errorf("%s: Expected number of bucket to be `%d`, but instead found `%d`", instanceType, 3, len(buckets))
}
}
// Wrapper for calling testListBucketsOrder for both XL and FS.
func (s *ObjectLayerAPISuite) TestListBucketsOrder(c *C) {
ExecObjectLayerTest(c, testListBucketsOrder)
} }
// Tests validate the order of result of ListBuckets. // Tests validate the order of result of ListBuckets.
func testListBucketsOrder(c *check.C, obj ObjectLayer) { func testListBucketsOrder(obj ObjectLayer, instanceType string, c TestErrHandler) {
// if implementation contains a map, order of map keys will vary. // if implementation contains a map, order of map keys will vary.
// this ensures they return in the same order each time. // this ensures they return in the same order each time.
// add one and test exists. // add one and test exists.
err := obj.MakeBucket("bucket1") err := obj.MakeBucket("bucket1")
c.Assert(err, check.IsNil) if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
err = obj.MakeBucket("bucket2") err = obj.MakeBucket("bucket2")
c.Assert(err, check.IsNil) if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
buckets, err := obj.ListBuckets() buckets, err := obj.ListBuckets()
c.Assert(err, check.IsNil) if err != nil {
c.Assert(len(buckets), check.Equals, 2) c.Fatalf("%s: <ERROR> %s", instanceType, err)
c.Assert(buckets[0].Name, check.Equals, "bucket1") }
c.Assert(buckets[1].Name, check.Equals, "bucket2") if len(buckets) != 2 {
} c.Errorf("%s: Expected number of bucket to be `%d`, but instead found `%d`", instanceType, 2, len(buckets))
}
// Tests validate that ListObjects operation on a non-existent bucket fails as expected. if buckets[0].Name != "bucket1" {
func testListObjectsTestsForNonExistantBucket(c *check.C, obj ObjectLayer) { c.Errorf("%s: Expected bucket name to be `%s`, but instead found `%s`", instanceType, "bucket1", buckets[0].Name)
result, err := obj.ListObjects("bucket", "", "", "", 1000) }
c.Assert(err, check.Not(check.IsNil)) if buckets[1].Name != "bucket2" {
c.Assert(result.IsTruncated, check.Equals, false) c.Errorf("%s: Expected bucket name to be `%s`, but instead found `%s`", instanceType, "bucket2", buckets[1].Name)
c.Assert(len(result.Objects), check.Equals, 0)
c.Assert(err.Error(), check.Equals, "Bucket not found: bucket")
}
// Tests validate that GetObject fails on a non-existent bucket as expected.
func testNonExistantObjectInBucket(c *check.C, obj ObjectLayer) {
err := obj.MakeBucket("bucket")
c.Assert(err, check.IsNil)
_, err = obj.GetObjectInfo("bucket", "dir1")
c.Assert(err, check.Not(check.IsNil))
switch err := err.(type) {
case ObjectNotFound:
c.Assert(err, check.ErrorMatches, "Object not found: bucket#dir1")
default:
c.Assert(err, check.Equals, "fails")
} }
} }
// Tests validate that GetObject on an existing directory fails as expected. // Wrapper for calling testListObjectsTestsForNonExistantBucket for both XL and FS.
func testGetDirectoryReturnsObjectNotFound(c *check.C, obj ObjectLayer) { func (s *ObjectLayerAPISuite) TestListObjectsTestsForNonExistantBucket(c *C) {
err := obj.MakeBucket("bucket") ExecObjectLayerTest(c, testListObjectsTestsForNonExistantBucket)
c.Assert(err, check.IsNil) }
_, err = obj.PutObject("bucket", "dir1/dir3/object", int64(len("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed.")), bytes.NewBufferString("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."), nil) // Tests validate that ListObjects operation on a non-existent bucket fails as expected.
c.Assert(err, check.IsNil) func testListObjectsTestsForNonExistantBucket(obj ObjectLayer, instanceType string, c TestErrHandler) {
result, err := obj.ListObjects("bucket", "", "", "", 1000)
if err == nil {
c.Fatalf("%s: Expected error but found nil.", instanceType)
}
if len(result.Objects) != 0 {
c.Fatalf("%s: Expected number of objects in the result to be `%d`, but instead found `%d`", instanceType, 0, len(result.Objects))
}
if result.IsTruncated != false {
c.Fatalf("%s: Expected IsTruncated to be `false`, but instead found it to be `%v`", instanceType, result.IsTruncated)
}
if err.Error() != "Bucket not found: bucket" {
c.Errorf("%s: Expected the error msg to be `%s`, but instead found `%s`", instanceType, "Bucket not found: bucket", err.Error())
}
}
// Wrapper for calling testNonExistantObjectInBucket for both XL and FS.
func (s *ObjectLayerAPISuite) TestNonExistantObjectInBucket(c *C) {
ExecObjectLayerTest(c, testNonExistantObjectInBucket)
}
// Tests validate that GetObject fails on a non-existent bucket as expected.
func testNonExistantObjectInBucket(obj ObjectLayer, instanceType string, c TestErrHandler) {
err := obj.MakeBucket("bucket")
if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
_, err = obj.GetObjectInfo("bucket", "dir1")
if err == nil {
c.Fatalf("%s: Expected error but found nil", instanceType)
}
switch err := err.(type) {
case ObjectNotFound:
if err.Error() != "Object not found: bucket#dir1" {
c.Errorf("%s: Expected the Error message to be `%s`, but instead found `%s`", instanceType, "Object not found: bucket#dir1", err.Error())
}
default:
if err.Error() != "fails" {
c.Errorf("%s: Expected the Error message to be `%s`, but instead found it to be `%s`", instanceType, "fails", err.Error())
}
}
}
// Wrapper for calling testGetDirectoryReturnsObjectNotFound for both XL and FS.
func (s *ObjectLayerAPISuite) TestGetDirectoryReturnsObjectNotFound(c *C) {
ExecObjectLayerTest(c, testGetDirectoryReturnsObjectNotFound)
}
// Tests validate that GetObject on an existing directory fails as expected.
func testGetDirectoryReturnsObjectNotFound(obj ObjectLayer, instanceType string, c TestErrHandler) {
err := obj.MakeBucket("bucket")
if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
_, err = obj.PutObject("bucket", "dir1/dir3/object",
int64(len("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed.")),
bytes.NewBufferString("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."), nil)
if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
_, err = obj.GetObjectInfo("bucket", "dir1") _, err = obj.GetObjectInfo("bucket", "dir1")
switch err := err.(type) { switch err := err.(type) {
case ObjectNotFound: case ObjectNotFound:
c.Assert(err.Bucket, check.Equals, "bucket") if err.Bucket != "bucket" {
c.Assert(err.Object, check.Equals, "dir1") c.Errorf("%s: Expected the bucket name in the error message to be `%s`, but instead found `%s`", instanceType, "bucket", err.Bucket)
}
if err.Object != "dir1" {
c.Errorf("%s: Expected the object name in the error message to be `%s`, but instead found `%s`", instanceType, "dir1", err.Object)
}
default: default:
// force a failure with a line number. if err.Error() != "ObjectNotFound" {
c.Assert(err, check.Equals, "ObjectNotFound") c.Errorf("%s: Expected the error message to be `%s`, but instead found `%s`", instanceType, "ObjectNotFound", err.Error())
}
} }
_, err = obj.GetObjectInfo("bucket", "dir1/") _, err = obj.GetObjectInfo("bucket", "dir1/")
switch err := err.(type) { switch err := err.(type) {
case ObjectNameInvalid: case ObjectNameInvalid:
c.Assert(err.Bucket, check.Equals, "bucket") if err.Bucket != "bucket" {
c.Assert(err.Object, check.Equals, "dir1/") c.Errorf("%s: Expected the bucket name in the error message to be `%s`, but instead found `%s`", instanceType, "bucket", err.Bucket)
}
if err.Object != "dir1/" {
c.Errorf("%s: Expected the object name in the error message to be `%s`, but instead found `%s`", instanceType, "dir1/", err.Object)
}
default: default:
// force a failure with a line number. // force a failure with a line number.
c.Assert(err, check.Equals, "ObjectNotFound") if err.Error() != "ObjectNotFound" {
c.Errorf("%s: Expected the error message to be `%s`, but instead found `%s`", instanceType, "ObjectNotFound", err.Error())
}
} }
} }
// Test content-type // Wrapper for calling testContentType for both XL and FS.
func testContentType(c *check.C, obj ObjectLayer) { func (s *ObjectLayerAPISuite) TestContentType(c *C) {
err := obj.MakeBucket("bucket") ExecObjectLayerTest(c, testContentType)
c.Assert(err, check.IsNil) }
// Test empty. // Test content-type.
_, err = obj.PutObject("bucket", "minio.png", int64(len("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed.")), bytes.NewBufferString("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed."), nil) func testContentType(obj ObjectLayer, instanceType string, c TestErrHandler) {
c.Assert(err, check.IsNil) err := obj.MakeBucket("bucket")
objInfo, err := obj.GetObjectInfo("bucket", "minio.png") if err != nil {
c.Assert(err, check.IsNil) c.Fatalf("%s: <ERROR> %s", instanceType, err)
c.Assert(objInfo.ContentType, check.Equals, "image/png") }
uploadContent := "The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed."
// Test empty.
_, err = obj.PutObject("bucket", "minio.png", int64(len(uploadContent)), bytes.NewBufferString(uploadContent), nil)
if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
objInfo, err := obj.GetObjectInfo("bucket", "minio.png")
if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
if objInfo.ContentType != "image/png" {
c.Errorf("%s: Expected Content type to be `%s`, but instead found `%s`", instanceType, "image/png", objInfo.ContentType)
}
} }

View File

@ -601,14 +601,14 @@ func removeDiskN(disks []string, n int) {
} }
// Regular object test type. // Regular object test type.
type objTestType func(obj ObjectLayer, instanceType string, t *testing.T) type objTestType func(obj ObjectLayer, instanceType string, t TestErrHandler)
// Special object test type for disk not found situations. // Special object test type for disk not found situations.
type objTestDiskNotFoundType func(obj ObjectLayer, instanceType string, dirs []string, t *testing.T) type objTestDiskNotFoundType func(obj ObjectLayer, instanceType string, dirs []string, t *testing.T)
// ExecObjectLayerTest - executes object layer tests. // ExecObjectLayerTest - executes object layer tests.
// Creates single node and XL ObjectLayer instance and runs test for both the layers. // Creates single node and XL ObjectLayer instance and runs test for both the layers.
func ExecObjectLayerTest(t *testing.T, objTest objTestType) { func ExecObjectLayerTest(t TestErrHandler, objTest objTestType) {
objLayer, fsDir, err := getSingleNodeObjectLayer() objLayer, fsDir, err := getSingleNodeObjectLayer()
if err != nil { if err != nil {
t.Fatalf("Initialization of object layer failed for single node setup: %s", err) t.Fatalf("Initialization of object layer failed for single node setup: %s", err)