mirror of
				https://github.com/minio/minio.git
				synced 2025-10-28 23:35:01 -04:00 
			
		
		
		
	tests: Implemented more tests for fs-v1*.go (#2686)
This commit is contained in:
		
							parent
							
								
									7d37dea449
								
							
						
					
					
						commit
						b89a1cd482
					
				| @ -17,7 +17,9 @@ | ||||
| package cmd | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"testing" | ||||
| ) | ||||
| 
 | ||||
| @ -64,3 +66,93 @@ func TestHasExtendedHeader(t *testing.T) { | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // TestReadFsMetadata - readFSMetadata testing with a healthy and faulty disk | ||||
| func TestReadFSMetadata(t *testing.T) { | ||||
| 	disk := filepath.Join(os.TempDir(), "minio-"+nextSuffix()) | ||||
| 	defer removeAll(disk) | ||||
| 	obj, err := newFSObjects(disk) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Unexpected err: ", err) | ||||
| 	} | ||||
| 	fs := obj.(fsObjects) | ||||
| 
 | ||||
| 	bucketName := "bucket" | ||||
| 	objectName := "object" | ||||
| 
 | ||||
| 	if err = obj.MakeBucket(bucketName); err != nil { | ||||
| 		t.Fatal("Unexpected err: ", err) | ||||
| 	} | ||||
| 	if _, err = obj.PutObject(bucketName, objectName, int64(len("abcd")), bytes.NewReader([]byte("abcd")), | ||||
| 		map[string]string{"X-Amz-Meta-AppId": "a"}); err != nil { | ||||
| 		t.Fatal("Unexpected err: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Construct the full path of fs.json | ||||
| 	fsPath := "buckets/" + bucketName + "/" + objectName + "/fs.json" | ||||
| 
 | ||||
| 	// Regular fs metadata reading, no errors expected | ||||
| 	if _, err = readFSMetadata(fs.storage, ".minio.sys", fsPath); err != nil { | ||||
| 		t.Fatal("Unexpected error ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Corrupted fs.json | ||||
| 	if err = fs.storage.AppendFile(".minio.sys", fsPath, []byte{'a'}); err != nil { | ||||
| 		t.Fatal("Unexpected error ", err) | ||||
| 	} | ||||
| 	if _, err = readFSMetadata(fs.storage, ".minio.sys", fsPath); err == nil { | ||||
| 		t.Fatal("Should fail", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Test with corrupted disk | ||||
| 	fsStorage := fs.storage.(*posix) | ||||
| 	naughty := newNaughtyDisk(fsStorage, nil, errFaultyDisk) | ||||
| 	fs.storage = naughty | ||||
| 	if _, err = readFSMetadata(fs.storage, ".minio.sys", fsPath); errorCause(err) != errFaultyDisk { | ||||
| 		t.Fatal("Should fail", err) | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| // TestWriteFsMetadata - tests of writeFSMetadata with healthy and faulty disks | ||||
| func TestWriteFSMetadata(t *testing.T) { | ||||
| 	disk := filepath.Join(os.TempDir(), "minio-"+nextSuffix()) | ||||
| 	defer removeAll(disk) | ||||
| 	obj, err := newFSObjects(disk) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Unexpected err: ", err) | ||||
| 	} | ||||
| 	fs := obj.(fsObjects) | ||||
| 
 | ||||
| 	bucketName := "bucket" | ||||
| 	objectName := "object" | ||||
| 
 | ||||
| 	if err = obj.MakeBucket(bucketName); err != nil { | ||||
| 		t.Fatal("Unexpected err: ", err) | ||||
| 	} | ||||
| 	if _, err = obj.PutObject(bucketName, objectName, int64(len("abcd")), bytes.NewReader([]byte("abcd")), | ||||
| 		map[string]string{"X-Amz-Meta-AppId": "a"}); err != nil { | ||||
| 		t.Fatal("Unexpected err: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Construct the complete path of fs.json | ||||
| 	fsPath := "buckets/" + bucketName + "/" + objectName + "/fs.json" | ||||
| 
 | ||||
| 	// Fs metadata reading, no errors expected (healthy disk) | ||||
| 	fsMeta, err := readFSMetadata(fs.storage, ".minio.sys", fsPath) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Unexpected error ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Reading metadata with a corrupted disk | ||||
| 	fsStorage := fs.storage.(*posix) | ||||
| 	for i := 1; i <= 2; i++ { | ||||
| 		naughty := newNaughtyDisk(fsStorage, map[int]error{i: errFaultyDisk, i + 1: errFaultyDisk}, nil) | ||||
| 		fs.storage = naughty | ||||
| 		if err = writeFSMetadata(fs.storage, ".minio.sys", fsPath, fsMeta); errorCause(err) != errFaultyDisk { | ||||
| 			t.Fatal("Unexpected error", i, err) | ||||
| 
 | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
|  | ||||
							
								
								
									
										165
									
								
								cmd/fs-v1-multipart-common_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								cmd/fs-v1-multipart-common_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,165 @@ | ||||
| /* | ||||
|  * Minio Cloud Storage, (C) 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 cmd | ||||
| 
 | ||||
| import ( | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"testing" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| // TestFSIsBucketExist - complete test of isBucketExist | ||||
| func TestFSIsBucketExist(t *testing.T) { | ||||
| 	// Prepare for testing | ||||
| 	disk := filepath.Join(os.TempDir(), "minio-"+nextSuffix()) | ||||
| 	defer removeAll(disk) | ||||
| 	obj, err := newFSObjects(disk) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Cannot create a new FS object: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	fs := obj.(fsObjects) | ||||
| 	bucketName := "bucket" | ||||
| 
 | ||||
| 	if err := obj.MakeBucket(bucketName); err != nil { | ||||
| 		t.Fatal("Cannot create bucket, err: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Test with a valid bucket | ||||
| 	if found := fs.isBucketExist(bucketName); !found { | ||||
| 		t.Fatal("isBucketExist should true") | ||||
| 	} | ||||
| 
 | ||||
| 	// Test with a inexistant bucket | ||||
| 	if found := fs.isBucketExist("foo"); found { | ||||
| 		t.Fatal("isBucketExist should false") | ||||
| 	} | ||||
| 
 | ||||
| 	// Using a faulty disk | ||||
| 	fsStorage := fs.storage.(*posix) | ||||
| 	naughty := newNaughtyDisk(fsStorage, nil, errFaultyDisk) | ||||
| 	fs.storage = naughty | ||||
| 	if found := fs.isBucketExist(bucketName); found { | ||||
| 		t.Fatal("isBucketExist should return false because it is wired to a corrupted disk") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // TestFSIsUploadExists - complete test with valid and invalid cases | ||||
| func TestFSIsUploadExists(t *testing.T) { | ||||
| 	// Prepare for testing | ||||
| 	disk := filepath.Join(os.TempDir(), "minio-"+nextSuffix()) | ||||
| 	defer removeAll(disk) | ||||
| 	obj, err := newFSObjects(disk) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Cannot create a new FS object: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	fs := obj.(fsObjects) | ||||
| 
 | ||||
| 	bucketName := "bucket" | ||||
| 	objectName := "object" | ||||
| 
 | ||||
| 	obj.MakeBucket(bucketName) | ||||
| 	uploadID, err := obj.NewMultipartUpload(bucketName, objectName, nil) | ||||
| 
 | ||||
| 	// Test with valid upload id | ||||
| 	if exists := fs.isUploadIDExists(bucketName, objectName, uploadID); !exists { | ||||
| 		t.Fatal("Wrong result, expected: ", exists) | ||||
| 	} | ||||
| 
 | ||||
| 	// Test with inexistant bucket/object names | ||||
| 	if exists := fs.isUploadIDExists("bucketfoo", "objectfoo", uploadID); exists { | ||||
| 		t.Fatal("Wrong result, expected: ", !exists) | ||||
| 	} | ||||
| 
 | ||||
| 	// Test with inexistant upload ID | ||||
| 	if exists := fs.isUploadIDExists(bucketName, objectName, uploadID+"-ff"); exists { | ||||
| 		t.Fatal("Wrong result, expected: ", !exists) | ||||
| 	} | ||||
| 
 | ||||
| 	// isUploadIdExists with a faulty disk should return false | ||||
| 	fsStorage := fs.storage.(*posix) | ||||
| 	naughty := newNaughtyDisk(fsStorage, nil, errFaultyDisk) | ||||
| 	fs.storage = naughty | ||||
| 	if exists := fs.isUploadIDExists(bucketName, objectName, uploadID); exists { | ||||
| 		t.Fatal("Wrong result, expected: ", !exists) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // TestFSWriteUploadJSON - tests for writeUploadJSON for FS | ||||
| func TestFSWriteUploadJSON(t *testing.T) { | ||||
| 	// Prepare for tests | ||||
| 	disk := filepath.Join(os.TempDir(), "minio-"+nextSuffix()) | ||||
| 	defer removeAll(disk) | ||||
| 	obj, err := newFSObjects(disk) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Unexpected err: ", err) | ||||
| 	} | ||||
| 	fs := obj.(fsObjects) | ||||
| 
 | ||||
| 	bucketName := "bucket" | ||||
| 	objectName := "object" | ||||
| 
 | ||||
| 	obj.MakeBucket(bucketName) | ||||
| 	uploadID, err := obj.NewMultipartUpload(bucketName, objectName, nil) | ||||
| 
 | ||||
| 	if err := fs.writeUploadJSON(bucketName, objectName, uploadID, time.Now()); err != nil { | ||||
| 		t.Fatal("Unexpected err: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// isUploadIdExists with a faulty disk should return false | ||||
| 	fsStorage := fs.storage.(*posix) | ||||
| 	for i := 1; i <= 3; i++ { | ||||
| 		naughty := newNaughtyDisk(fsStorage, map[int]error{i: errFaultyDisk}, nil) | ||||
| 		fs.storage = naughty | ||||
| 		if err := fs.writeUploadJSON(bucketName, objectName, uploadID, time.Now()); errorCause(err) != errFaultyDisk { | ||||
| 			t.Fatal("Unexpected err: ", err) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // TestFSUpdateUploadsJSON - tests for updateUploadsJSON for FS | ||||
| func TestFSUpdateUploadsJSON(t *testing.T) { | ||||
| 	// Prepare for tests | ||||
| 	disk := filepath.Join(os.TempDir(), "minio-"+nextSuffix()) | ||||
| 	defer removeAll(disk) | ||||
| 	obj, err := newFSObjects(disk) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Unexpected err: ", err) | ||||
| 	} | ||||
| 	fs := obj.(fsObjects) | ||||
| 
 | ||||
| 	bucketName := "bucket" | ||||
| 	objectName := "object" | ||||
| 
 | ||||
| 	obj.MakeBucket(bucketName) | ||||
| 
 | ||||
| 	if err := fs.updateUploadsJSON(bucketName, objectName, uploadsV1{}); err != nil { | ||||
| 		t.Fatal("Unexpected err: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// isUploadIdExists with a faulty disk should return false | ||||
| 	fsStorage := fs.storage.(*posix) | ||||
| 	for i := 1; i <= 2; i++ { | ||||
| 		naughty := newNaughtyDisk(fsStorage, map[int]error{i: errFaultyDisk}, nil) | ||||
| 		fs.storage = naughty | ||||
| 		if err := fs.updateUploadsJSON(bucketName, objectName, uploadsV1{}); errorCause(err) != errFaultyDisk { | ||||
| 			t.Fatal("Unexpected err: ", err) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										226
									
								
								cmd/fs-v1-multipart_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										226
									
								
								cmd/fs-v1-multipart_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,226 @@ | ||||
| /* | ||||
|  * Minio Cloud Storage, (C) 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 cmd | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"crypto/md5" | ||||
| 	"encoding/hex" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"reflect" | ||||
| 	"testing" | ||||
| ) | ||||
| 
 | ||||
| // TestNewMultipartUploadFaultyDisk - test NewMultipartUpload with faulty disks | ||||
| func TestNewMultipartUploadFaultyDisk(t *testing.T) { | ||||
| 	// Prepare for tests | ||||
| 	disk := filepath.Join(os.TempDir(), "minio-"+nextSuffix()) | ||||
| 	defer removeAll(disk) | ||||
| 	obj, err := newFSObjects(disk) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Cannot create a new FS object: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	fs := obj.(fsObjects) | ||||
| 	bucketName := "bucket" | ||||
| 	objectName := "object" | ||||
| 
 | ||||
| 	if err := obj.MakeBucket(bucketName); err != nil { | ||||
| 		t.Fatal("Cannot create bucket, err: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Test with faulty disk | ||||
| 	fsStorage := fs.storage.(*posix) | ||||
| 	for i := 1; i <= 5; i++ { | ||||
| 		// Faulty disk generates errFaultyDisk at 'i' storage api call number | ||||
| 		fs.storage = newNaughtyDisk(fsStorage, map[int]error{i: errFaultyDisk}, nil) | ||||
| 		if _, err := fs.NewMultipartUpload(bucketName, objectName, map[string]string{"X-Amz-Meta-xid": "3f"}); errorCause(err) != errFaultyDisk { | ||||
| 			switch i { | ||||
| 			case 1: | ||||
| 				if !isSameType(errorCause(err), BucketNotFound{}) { | ||||
| 					t.Fatal("Unexpected error ", err) | ||||
| 				} | ||||
| 			default: | ||||
| 				t.Fatal("Unexpected error ", err) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // TestPutObjectPartFaultyDisk - test PutObjectPart with faulty disks | ||||
| func TestPutObjectPartFaultyDisk(t *testing.T) { | ||||
| 	// Prepare for tests | ||||
| 	disk := filepath.Join(os.TempDir(), "minio-"+nextSuffix()) | ||||
| 	defer removeAll(disk) | ||||
| 	obj, err := newFSObjects(disk) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Cannot create a new FS object: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	fs := obj.(fsObjects) | ||||
| 	bucketName := "bucket" | ||||
| 	objectName := "object" | ||||
| 	data := []byte("12345") | ||||
| 	dataLen := int64(len(data)) | ||||
| 
 | ||||
| 	if err = obj.MakeBucket(bucketName); err != nil { | ||||
| 		t.Fatal("Cannot create bucket, err: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	uploadID, err := fs.NewMultipartUpload(bucketName, objectName, map[string]string{"X-Amz-Meta-xid": "3f"}) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Unexpected error ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	md5Writer := md5.New() | ||||
| 	md5Writer.Write(data) | ||||
| 	md5Hex := hex.EncodeToString(md5Writer.Sum(nil)) | ||||
| 
 | ||||
| 	// Test with faulty disk | ||||
| 	fsStorage := fs.storage.(*posix) | ||||
| 	for i := 1; i <= 7; i++ { | ||||
| 		// Faulty disk generates errFaultyDisk at 'i' storage api call number | ||||
| 		fs.storage = newNaughtyDisk(fsStorage, map[int]error{i: errFaultyDisk}, nil) | ||||
| 		if _, err := fs.PutObjectPart(bucketName, objectName, uploadID, 1, dataLen, bytes.NewReader(data), md5Hex); errorCause(err) != errFaultyDisk { | ||||
| 			switch i { | ||||
| 			case 1: | ||||
| 				if !isSameType(errorCause(err), BucketNotFound{}) { | ||||
| 					t.Fatal("Unexpected error ", err) | ||||
| 				} | ||||
| 			case 2, 4: | ||||
| 				if !isSameType(errorCause(err), InvalidUploadID{}) { | ||||
| 					t.Fatal("Unexpected error ", err) | ||||
| 				} | ||||
| 			default: | ||||
| 				t.Fatal("Unexpected error ", i, err, reflect.TypeOf(errorCause(err)), reflect.TypeOf(errFaultyDisk)) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // TestCompleteMultipartUploadFaultyDisk - test CompleteMultipartUpload with faulty disks | ||||
| func TestCompleteMultipartUploadFaultyDisk(t *testing.T) { | ||||
| 	// Prepare for tests | ||||
| 	disk := filepath.Join(os.TempDir(), "minio-"+nextSuffix()) | ||||
| 	defer removeAll(disk) | ||||
| 	obj, err := newFSObjects(disk) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Cannot create a new FS object: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	fs := obj.(fsObjects) | ||||
| 	bucketName := "bucket" | ||||
| 	objectName := "object" | ||||
| 	data := []byte("12345") | ||||
| 
 | ||||
| 	if err = obj.MakeBucket(bucketName); err != nil { | ||||
| 		t.Fatal("Cannot create bucket, err: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	uploadID, err := fs.NewMultipartUpload(bucketName, objectName, map[string]string{"X-Amz-Meta-xid": "3f"}) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Unexpected error ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	md5Writer := md5.New() | ||||
| 	md5Writer.Write(data) | ||||
| 	md5Hex := hex.EncodeToString(md5Writer.Sum(nil)) | ||||
| 
 | ||||
| 	if _, err := fs.PutObjectPart(bucketName, objectName, uploadID, 1, 5, bytes.NewReader(data), md5Hex); err != nil { | ||||
| 		t.Fatal("Unexpected error ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	parts := []completePart{{PartNumber: 1, ETag: md5Hex}} | ||||
| 
 | ||||
| 	fsStorage := fs.storage.(*posix) | ||||
| 	for i := 1; i <= 3; i++ { | ||||
| 		// Faulty disk generates errFaultyDisk at 'i' storage api call number | ||||
| 		fs.storage = newNaughtyDisk(fsStorage, map[int]error{i: errFaultyDisk}, nil) | ||||
| 		if _, err := fs.CompleteMultipartUpload(bucketName, objectName, uploadID, parts); errorCause(err) != errFaultyDisk { | ||||
| 			switch i { | ||||
| 			case 1: | ||||
| 				if !isSameType(errorCause(err), BucketNotFound{}) { | ||||
| 					t.Fatal("Unexpected error ", err) | ||||
| 				} | ||||
| 			case 2: | ||||
| 				if !isSameType(errorCause(err), InvalidUploadID{}) { | ||||
| 					t.Fatal("Unexpected error ", err) | ||||
| 				} | ||||
| 			default: | ||||
| 				t.Fatal("Unexpected error ", i, err, reflect.TypeOf(errorCause(err)), reflect.TypeOf(errFaultyDisk)) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // TestListMultipartUploadsFaultyDisk - test ListMultipartUploads with faulty disks | ||||
| func TestListMultipartUploadsFaultyDisk(t *testing.T) { | ||||
| 	// Prepare for tests | ||||
| 	disk := filepath.Join(os.TempDir(), "minio-"+nextSuffix()) | ||||
| 	defer removeAll(disk) | ||||
| 	obj, err := newFSObjects(disk) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Cannot create a new FS object: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	fs := obj.(fsObjects) | ||||
| 	bucketName := "bucket" | ||||
| 	objectName := "object" | ||||
| 	data := []byte("12345") | ||||
| 
 | ||||
| 	if err = obj.MakeBucket(bucketName); err != nil { | ||||
| 		t.Fatal("Cannot create bucket, err: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	uploadID, err := fs.NewMultipartUpload(bucketName, objectName, map[string]string{"X-Amz-Meta-xid": "3f"}) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Unexpected error ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	md5Writer := md5.New() | ||||
| 	md5Writer.Write(data) | ||||
| 	md5Hex := hex.EncodeToString(md5Writer.Sum(nil)) | ||||
| 
 | ||||
| 	if _, err := fs.PutObjectPart(bucketName, objectName, uploadID, 1, 5, bytes.NewReader(data), md5Hex); err != nil { | ||||
| 		t.Fatal("Unexpected error ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	fsStorage := fs.storage.(*posix) | ||||
| 	for i := 1; i <= 4; i++ { | ||||
| 		// Faulty disk generates errFaultyDisk at 'i' storage api call number | ||||
| 		fs.storage = newNaughtyDisk(fsStorage, map[int]error{i: errFaultyDisk}, nil) | ||||
| 		if _, err := fs.ListMultipartUploads(bucketName, objectName, "", "", "", 1000); errorCause(err) != errFaultyDisk { | ||||
| 			switch i { | ||||
| 			case 1: | ||||
| 				if !isSameType(errorCause(err), BucketNotFound{}) { | ||||
| 					t.Fatal("Unexpected error ", err) | ||||
| 				} | ||||
| 			case 2: | ||||
| 				if !isSameType(errorCause(err), InvalidUploadID{}) { | ||||
| 					t.Fatal("Unexpected error ", err) | ||||
| 				} | ||||
| 			case 3: | ||||
| 				if errorCause(err) != errFileNotFound { | ||||
| 					t.Fatal("Unexpected error ", err) | ||||
| 				} | ||||
| 			default: | ||||
| 				t.Fatal("Unexpected error ", i, err, reflect.TypeOf(errorCause(err)), reflect.TypeOf(errFaultyDisk)) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										16
									
								
								cmd/fs-v1.go
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								cmd/fs-v1.go
									
									
									
									
									
								
							| @ -505,20 +505,6 @@ func (fs fsObjects) DeleteObject(bucket, object string) error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // Checks whether bucket exists. | ||||
| func isBucketExist(storage StorageAPI, bucketName string) bool { | ||||
| 	// Check whether bucket exists. | ||||
| 	_, err := storage.StatVol(bucketName) | ||||
| 	if err != nil { | ||||
| 		if err == errVolumeNotFound { | ||||
| 			return false | ||||
| 		} | ||||
| 		errorIf(err, "Stat failed on bucket "+bucketName+".") | ||||
| 		return false | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| // ListObjects - list all objects at prefix upto maxKeys., optionally delimited by '/'. Maintains the list pool | ||||
| // state for future re-entrant list requests. | ||||
| func (fs fsObjects) ListObjects(bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsInfo, error) { | ||||
| @ -551,7 +537,7 @@ func (fs fsObjects) ListObjects(bucket, prefix, marker, delimiter string, maxKey | ||||
| 		return ListObjectsInfo{}, traceError(BucketNameInvalid{Bucket: bucket}) | ||||
| 	} | ||||
| 	// Verify if bucket exists. | ||||
| 	if !isBucketExist(fs.storage, bucket) { | ||||
| 	if !fs.isBucketExist(bucket) { | ||||
| 		return ListObjectsInfo{}, traceError(BucketNotFound{Bucket: bucket}) | ||||
| 	} | ||||
| 	if !IsValidObjectPrefix(prefix) { | ||||
|  | ||||
| @ -68,8 +68,9 @@ func TestNewFS(t *testing.T) { | ||||
| // TestFSShutdown - initialize a new FS object layer then calls Shutdown | ||||
| // to check returned results | ||||
| func TestFSShutdown(t *testing.T) { | ||||
| 	// Create an FS object and shutdown it. No errors expected | ||||
| 	// Prepare for tests | ||||
| 	disk := filepath.Join(os.TempDir(), "minio-"+nextSuffix()) | ||||
| 	defer removeAll(disk) | ||||
| 	obj, err := newFSObjects(disk) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Cannot create a new FS object: ", err) | ||||
| @ -85,18 +86,249 @@ func TestFSShutdown(t *testing.T) { | ||||
| 	obj.MakeBucket(bucketName) | ||||
| 	obj.PutObject(bucketName, objectName, int64(len(objectContent)), bytes.NewReader([]byte(objectContent)), nil) | ||||
| 
 | ||||
| 	// Test Shutdown with regular conditions | ||||
| 	if err := fs.Shutdown(); err != nil { | ||||
| 		t.Fatal("Cannot shutdown the FS object: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Create an FS and program errors with disks when shutdown is called | ||||
| 	// Test Shutdown with faulty disks | ||||
| 	for i := 1; i <= 5; i++ { | ||||
| 		naughty := newNaughtyDisk(fsStorage, map[int]error{i: errFaultyDisk}, nil) | ||||
| 		fs.storage = naughty | ||||
| 		fs.storage = newNaughtyDisk(fsStorage, map[int]error{i: errFaultyDisk}, nil) | ||||
| 		if err := fs.Shutdown(); errorCause(err) != errFaultyDisk { | ||||
| 			t.Fatal(i, ", Got unexpected fs shutdown error: ", err) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	removeAll(disk) | ||||
| } | ||||
| 
 | ||||
| // TestFSLoadFormatFS - test loadFormatFS with healty and faulty disks | ||||
| func TestFSLoadFormatFS(t *testing.T) { | ||||
| 	// Prepare for testing | ||||
| 	disk := filepath.Join(os.TempDir(), "minio-"+nextSuffix()) | ||||
| 	defer removeAll(disk) | ||||
| 
 | ||||
| 	obj, err := newFSObjects(disk) | ||||
| 	fs := obj.(fsObjects) | ||||
| 
 | ||||
| 	// Regular format loading | ||||
| 	_, err = loadFormatFS(fs.storage) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Should not fail here", err) | ||||
| 	} | ||||
| 	// Loading corrupted format file | ||||
| 	fs.storage.AppendFile(minioMetaBucket, fsFormatJSONFile, []byte{'b'}) | ||||
| 	_, err = loadFormatFS(fs.storage) | ||||
| 	if err == nil { | ||||
| 		t.Fatal("Should return an error here") | ||||
| 	} | ||||
| 	// Loading format file from faulty disk | ||||
| 	fsStorage := fs.storage.(*posix) | ||||
| 	fs.storage = newNaughtyDisk(fsStorage, nil, errFaultyDisk) | ||||
| 	_, err = loadFormatFS(fs.storage) | ||||
| 	if err != errFaultyDisk { | ||||
| 		t.Fatal("Should return faulty disk error") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // TestFSGetBucketInfo - test GetBucketInfo with healty and faulty disks | ||||
| func TestFSGetBucketInfo(t *testing.T) { | ||||
| 	// Prepare for testing | ||||
| 	disk := filepath.Join(os.TempDir(), "minio-"+nextSuffix()) | ||||
| 	defer removeAll(disk) | ||||
| 
 | ||||
| 	obj, err := newFSObjects(disk) | ||||
| 	fs := obj.(fsObjects) | ||||
| 	bucketName := "bucket" | ||||
| 
 | ||||
| 	obj.MakeBucket(bucketName) | ||||
| 
 | ||||
| 	// Test with valid parameters | ||||
| 	info, err := fs.GetBucketInfo(bucketName) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	if info.Name != bucketName { | ||||
| 		t.Fatalf("wrong bucket name, expected: %s, found: %s", bucketName, info.Name) | ||||
| 	} | ||||
| 
 | ||||
| 	// Test with inexistant bucket | ||||
| 	_, err = fs.GetBucketInfo("a") | ||||
| 	if !isSameType(errorCause(err), BucketNameInvalid{}) { | ||||
| 		t.Fatal("BucketNameInvalid error not returned") | ||||
| 	} | ||||
| 
 | ||||
| 	// Loading format file from faulty disk | ||||
| 	fsStorage := fs.storage.(*posix) | ||||
| 	fs.storage = newNaughtyDisk(fsStorage, nil, errFaultyDisk) | ||||
| 	_, err = fs.GetBucketInfo(bucketName) | ||||
| 	if errorCause(err) != errFaultyDisk { | ||||
| 		t.Fatal("errFaultyDisk error not returned") | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| // TestFSDeleteObject - test fs.DeleteObject() with healthy and corrupted disks | ||||
| func TestFSDeleteObject(t *testing.T) { | ||||
| 	// Prepare for tests | ||||
| 	disk := filepath.Join(os.TempDir(), "minio-"+nextSuffix()) | ||||
| 	defer removeAll(disk) | ||||
| 
 | ||||
| 	obj, _ := newFSObjects(disk) | ||||
| 	fs := obj.(fsObjects) | ||||
| 	bucketName := "bucket" | ||||
| 	objectName := "object" | ||||
| 
 | ||||
| 	obj.MakeBucket(bucketName) | ||||
| 	obj.PutObject(bucketName, objectName, int64(len("abcd")), bytes.NewReader([]byte("abcd")), nil) | ||||
| 
 | ||||
| 	// Test with invalid bucket name | ||||
| 	if err := fs.DeleteObject("fo", objectName); !isSameType(errorCause(err), BucketNameInvalid{}) { | ||||
| 		t.Fatal("Unexpected error: ", err) | ||||
| 	} | ||||
| 	// Test with invalid object name | ||||
| 	if err := fs.DeleteObject(bucketName, "^"); !isSameType(errorCause(err), ObjectNameInvalid{}) { | ||||
| 		t.Fatal("Unexpected error: ", err) | ||||
| 	} | ||||
| 	// Test with inexist bucket/object | ||||
| 	if err := fs.DeleteObject("foobucket", "fooobject"); !isSameType(errorCause(err), BucketNotFound{}) { | ||||
| 		t.Fatal("Unexpected error: ", err) | ||||
| 	} | ||||
| 	// Test with valid condition | ||||
| 	if err := fs.DeleteObject(bucketName, objectName); err != nil { | ||||
| 		t.Fatal("Unexpected error: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Loading format file from faulty disk | ||||
| 	fsStorage := fs.storage.(*posix) | ||||
| 	fs.storage = newNaughtyDisk(fsStorage, nil, errFaultyDisk) | ||||
| 	if err := fs.DeleteObject(bucketName, objectName); errorCause(err) != errFaultyDisk { | ||||
| 		t.Fatal("Unexpected error: ", err) | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| // TestFSDeleteBucket - tests for fs DeleteBucket | ||||
| func TestFSDeleteBucket(t *testing.T) { | ||||
| 	// Prepare for testing | ||||
| 	disk := filepath.Join(os.TempDir(), "minio-"+nextSuffix()) | ||||
| 	defer removeAll(disk) | ||||
| 
 | ||||
| 	obj, _ := newFSObjects(disk) | ||||
| 	fs := obj.(fsObjects) | ||||
| 	bucketName := "bucket" | ||||
| 
 | ||||
| 	err := obj.MakeBucket(bucketName) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Unexpected error: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Test with an invalid bucket name | ||||
| 	if err := fs.DeleteBucket("fo"); !isSameType(errorCause(err), BucketNameInvalid{}) { | ||||
| 		t.Fatal("Unexpected error: ", err) | ||||
| 	} | ||||
| 	// Test with an inexistant bucket | ||||
| 	if err := fs.DeleteBucket("foobucket"); !isSameType(errorCause(err), BucketNotFound{}) { | ||||
| 		t.Fatal("Unexpected error: ", err) | ||||
| 	} | ||||
| 	// Test with a valid case | ||||
| 	if err := fs.DeleteBucket(bucketName); err != nil { | ||||
| 		t.Fatal("Unexpected error: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	obj.MakeBucket(bucketName) | ||||
| 
 | ||||
| 	// Loading format file from faulty disk | ||||
| 	fsStorage := fs.storage.(*posix) | ||||
| 	for i := 1; i <= 2; i++ { | ||||
| 		fs.storage = newNaughtyDisk(fsStorage, map[int]error{i: errFaultyDisk}, nil) | ||||
| 		if err := fs.DeleteBucket(bucketName); errorCause(err) != errFaultyDisk { | ||||
| 			t.Fatal("Unexpected error: ", err) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| // TestFSListBuckets - tests for fs ListBuckets | ||||
| func TestFSListBuckets(t *testing.T) { | ||||
| 	// Prepare for tests | ||||
| 	disk := filepath.Join(os.TempDir(), "minio-"+nextSuffix()) | ||||
| 	defer removeAll(disk) | ||||
| 
 | ||||
| 	obj, _ := newFSObjects(disk) | ||||
| 	fs := obj.(fsObjects) | ||||
| 
 | ||||
| 	bucketName := "bucket" | ||||
| 
 | ||||
| 	if err := obj.MakeBucket(bucketName); err != nil { | ||||
| 		t.Fatal("Unexpected error: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Create a bucket with invalid name | ||||
| 	if err := fs.storage.MakeVol("vo^"); err != nil { | ||||
| 		t.Fatal("Unexpected error: ", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Test | ||||
| 	buckets, err := fs.ListBuckets() | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Unexpected error: ", err) | ||||
| 	} | ||||
| 	if len(buckets) != 1 { | ||||
| 		t.Fatal("ListBuckets not working properly") | ||||
| 	} | ||||
| 
 | ||||
| 	// Test ListBuckets with faulty disks | ||||
| 	fsStorage := fs.storage.(*posix) | ||||
| 	for i := 1; i <= 2; i++ { | ||||
| 		fs.storage = newNaughtyDisk(fsStorage, nil, errFaultyDisk) | ||||
| 		if _, err := fs.ListBuckets(); errorCause(err) != errFaultyDisk { | ||||
| 			t.Fatal("Unexpected error: ", err) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| // TestFSHealObject - tests for fs HealObject | ||||
| func TestFSHealObject(t *testing.T) { | ||||
| 	disk := filepath.Join(os.TempDir(), "minio-"+nextSuffix()) | ||||
| 	defer removeAll(disk) | ||||
| 
 | ||||
| 	obj, err := newFSObjects(disk) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Cannot create a new FS object: ", err) | ||||
| 	} | ||||
| 	err = obj.HealObject("bucket", "object") | ||||
| 	if err == nil || !isSameType(errorCause(err), NotImplemented{}) { | ||||
| 		t.Fatalf("Heal Object should return NotImplemented error ") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // TestFSListObjectHeal - tests for fs ListObjectHeals | ||||
| func TestFSListObjectsHeal(t *testing.T) { | ||||
| 	disk := filepath.Join(os.TempDir(), "minio-"+nextSuffix()) | ||||
| 	defer removeAll(disk) | ||||
| 
 | ||||
| 	obj, err := newFSObjects(disk) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Cannot create a new FS object: ", err) | ||||
| 	} | ||||
| 	_, err = obj.ListObjectsHeal("bucket", "prefix", "marker", "delimiter", 1000) | ||||
| 	if err == nil || !isSameType(errorCause(err), NotImplemented{}) { | ||||
| 		t.Fatalf("Heal Object should return NotImplemented error ") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // TestFSHealDiskMetadata - tests for fs HealDiskMetadata | ||||
| func TestFSHealDiskMetadata(t *testing.T) { | ||||
| 	disk := filepath.Join(os.TempDir(), "minio-"+nextSuffix()) | ||||
| 	defer removeAll(disk) | ||||
| 
 | ||||
| 	obj, err := newFSObjects(disk) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Cannot create a new FS object: ", err) | ||||
| 	} | ||||
| 	err = obj.HealDiskMetadata() | ||||
| 	if err == nil || !isSameType(errorCause(err), NotImplemented{}) { | ||||
| 		t.Fatalf("Heal Object should return NotImplemented error ") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -16,7 +16,10 @@ | ||||
| 
 | ||||
| package cmd | ||||
| 
 | ||||
| import "github.com/minio/minio/pkg/disk" | ||||
| import ( | ||||
| 	"github.com/minio/minio/pkg/disk" | ||||
| 	"sync" | ||||
| ) | ||||
| 
 | ||||
| // naughtyDisk wraps a POSIX disk and returns programmed errors | ||||
| // specified by the developer. The purpose is to simulate errors | ||||
| @ -31,6 +34,8 @@ type naughtyDisk struct { | ||||
| 	defaultErr error | ||||
| 	// The current API call number | ||||
| 	callNR int | ||||
| 	// Data protection | ||||
| 	mu sync.Mutex | ||||
| } | ||||
| 
 | ||||
| func newNaughtyDisk(d *posix, errs map[int]error, defaultErr error) *naughtyDisk { | ||||
| @ -38,6 +43,8 @@ func newNaughtyDisk(d *posix, errs map[int]error, defaultErr error) *naughtyDisk | ||||
| } | ||||
| 
 | ||||
| func (d *naughtyDisk) calcError() (err error) { | ||||
| 	d.mu.Lock() | ||||
| 	defer d.mu.Unlock() | ||||
| 	d.callNR++ | ||||
| 	if err, ok := d.errors[d.callNR]; ok { | ||||
| 		return err | ||||
|  | ||||
| @ -437,7 +437,7 @@ func testListObjects(obj ObjectLayer, instanceType string, t TestErrHandler) { | ||||
| 		{"test-bucket-list-object", "asia", "europe-object", "", 0, ListObjectsInfo{}, fmt.Errorf("Invalid combination of marker '%s' and prefix '%s'", "europe-object", "asia"), false}, | ||||
| 		// Setting a non-existing directory to be prefix (12-13). | ||||
| 		{"empty-bucket", "europe/france/", "", "", 1, ListObjectsInfo{}, nil, true}, | ||||
| 		{"empty-bucket", "europe/tunisia/", "", "", 1, ListObjectsInfo{}, nil, true}, | ||||
| 		{"empty-bucket", "africa/tunisia/", "", "", 1, ListObjectsInfo{}, nil, true}, | ||||
| 		// Testing on empty bucket, that is, bucket without any objects in it (14). | ||||
| 		{"empty-bucket", "", "", "", 0, ListObjectsInfo{}, nil, true}, | ||||
| 		// Setting maxKeys to negative value (15-16). | ||||
| @ -512,6 +512,9 @@ func testListObjects(obj ObjectLayer, instanceType string, t TestErrHandler) { | ||||
| 		{"test-bucket-list-object", "", "Asia/India/Karnataka/Bangalore/Koramangala/pics", "/", 10, resultCases[29], nil, true}, | ||||
| 		// Test with prefix and delimiter set to '/'. (60) | ||||
| 		{"test-bucket-list-object", "/", "", "/", 10, resultCases[30], nil, true}, | ||||
| 
 | ||||
| 		// Test with invalid prefix (61) | ||||
| 		{"test-bucket-list-object", "^", "", "/", 10, resultCases[30], ObjectNameInvalid{Bucket: "test-bucket-list-object", Object: "^"}, false}, | ||||
| 	} | ||||
| 
 | ||||
| 	for i, testCase := range testCases { | ||||
|  | ||||
| @ -36,9 +36,14 @@ func testObjectNewMultipartUpload(obj ObjectLayer, instanceType string, t TestEr | ||||
| 	bucket := "minio-bucket" | ||||
| 	object := "minio-object" | ||||
| 
 | ||||
| 	_, err := obj.NewMultipartUpload("--", object, nil) | ||||
| 	if err == nil { | ||||
| 		t.Fatalf("%s: Expected to fail since bucket name is invalid.", instanceType) | ||||
| 	} | ||||
| 
 | ||||
| 	errMsg := "Bucket not found: minio-bucket" | ||||
| 	// opearation expected to fail since the bucket on which NewMultipartUpload is being initiated doesn't exist. | ||||
| 	_, err := obj.NewMultipartUpload(bucket, object, nil) | ||||
| 	_, err = obj.NewMultipartUpload(bucket, object, nil) | ||||
| 	if err == nil { | ||||
| 		t.Fatalf("%s: Expected to fail since the NewMultipartUpload is intialized on a non-existent bucket.", instanceType) | ||||
| 	} | ||||
| @ -53,6 +58,11 @@ func testObjectNewMultipartUpload(obj ObjectLayer, instanceType string, t TestEr | ||||
| 		t.Fatalf("%s : %s", instanceType, err.Error()) | ||||
| 	} | ||||
| 
 | ||||
| 	_, err = obj.NewMultipartUpload(bucket, "^", nil) | ||||
| 	if err == nil { | ||||
| 		t.Fatalf("%s: Expected to fail since object name is invalid.", instanceType) | ||||
| 	} | ||||
| 
 | ||||
| 	uploadID, err := obj.NewMultipartUpload(bucket, object, nil) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%s : %s", instanceType, err.Error()) | ||||
| @ -69,6 +79,53 @@ func testObjectNewMultipartUpload(obj ObjectLayer, instanceType string, t TestEr | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Wrapper for calling AbortMultipartUpload tests for both XL multiple disks and single node setup. | ||||
| func TestObjectAbortMultipartUpload(t *testing.T) { | ||||
| 	ExecObjectLayerTest(t, testObjectAbortMultipartUpload) | ||||
| } | ||||
| 
 | ||||
| // Tests validate creation of abort multipart upload instance. | ||||
| func testObjectAbortMultipartUpload(obj ObjectLayer, instanceType string, t TestErrHandler) { | ||||
| 
 | ||||
| 	bucket := "minio-bucket" | ||||
| 	object := "minio-object" | ||||
| 
 | ||||
| 	// Create bucket before intiating NewMultipartUpload. | ||||
| 	err := obj.MakeBucket(bucket) | ||||
| 	if err != nil { | ||||
| 		// failed to create newbucket, abort. | ||||
| 		t.Fatalf("%s : %s", instanceType, err.Error()) | ||||
| 	} | ||||
| 
 | ||||
| 	uploadID, err := obj.NewMultipartUpload(bucket, object, nil) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("%s : %s", instanceType, err.Error()) | ||||
| 	} | ||||
| 
 | ||||
| 	abortTestCases := []struct { | ||||
| 		bucketName      string | ||||
| 		objName         string | ||||
| 		uploadID        string | ||||
| 		expectedErrType error | ||||
| 	}{ | ||||
| 		{"--", object, uploadID, BucketNameInvalid{}}, | ||||
| 		{bucket, "^", uploadID, ObjectNameInvalid{}}, | ||||
| 		{"foo", object, uploadID, BucketNotFound{}}, | ||||
| 		{bucket, object, "foo-foo", InvalidUploadID{}}, | ||||
| 		{bucket, object, uploadID, nil}, | ||||
| 	} | ||||
| 	// Iterating over creatPartCases to generate multipart chunks. | ||||
| 	for i, testCase := range abortTestCases { | ||||
| 		err = obj.AbortMultipartUpload(testCase.bucketName, testCase.objName, testCase.uploadID) | ||||
| 		if testCase.expectedErrType == nil && err != nil { | ||||
| 			t.Errorf("Test %d, unexpected err is received: %v, expected:%v\n", i+1, err, testCase.expectedErrType) | ||||
| 		} | ||||
| 		if testCase.expectedErrType != nil && !isSameType(errorCause(err), testCase.expectedErrType) { | ||||
| 			t.Errorf("Test %d, unexpected err is received: %v, expected:%v\n", i+1, err, testCase.expectedErrType) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Wrapper for calling isUploadIDExists tests for both XL multiple disks and single node setup. | ||||
| func TestObjectAPIIsUploadIDExists(t *testing.T) { | ||||
| 	ExecObjectLayerTest(t, testObjectAPIIsUploadIDExists) | ||||
| @ -1716,7 +1773,7 @@ func testObjectCompleteMultipartUpload(obj ObjectLayer, instanceType string, t T | ||||
| 		t.Fatalf("%s : %s", instanceType, err) | ||||
| 	} | ||||
| 	// Initiate Multipart Upload on the above created bucket. | ||||
| 	uploadID, err = obj.NewMultipartUpload(bucketNames[0], objectNames[0], nil) | ||||
| 	uploadID, err = obj.NewMultipartUpload(bucketNames[0], objectNames[0], map[string]string{"X-Amz-Meta-Id": "id"}) | ||||
| 	if err != nil { | ||||
| 		// Failed to create NewMultipartUpload, abort. | ||||
| 		t.Fatalf("%s : %s", instanceType, err) | ||||
| @ -1849,6 +1906,7 @@ func testObjectCompleteMultipartUpload(obj ObjectLayer, instanceType string, t T | ||||
| 		// the case above successfully completes CompleteMultipartUpload, the remaining Parts will be flushed. | ||||
| 		// Expecting to fail with Invalid UploadID. | ||||
| 		{bucketNames[0], objectNames[0], uploadIDs[0], inputParts[4].parts, "", InvalidUploadID{UploadID: uploadIDs[0]}, false}, | ||||
| 		// Expecting to fail due to bad | ||||
| 	} | ||||
| 
 | ||||
| 	for i, testCase := range testCases { | ||||
|  | ||||
| @ -148,6 +148,10 @@ func testObjectAPIPutObject(obj ObjectLayer, instanceType string, t TestErrHandl | ||||
| 		{bucket, object, data, nil, int64(len(data) - 1), md5Hex(data[:len(data)-1]), nil}, | ||||
| 		{bucket, object, nilBytes, nil, int64(len(nilBytes) + 1), md5Hex(nilBytes), IncompleteBody{}}, | ||||
| 		{bucket, object, fiveMBBytes, nil, int64(0), md5Hex(fiveMBBytes), nil}, | ||||
| 
 | ||||
| 		// Test case 29 | ||||
| 		// valid data with X-Amz-Meta- meta | ||||
| 		{bucket, object, data, map[string]string{"X-Amz-Meta-AppID": "a42"}, int64(len(data)), md5Hex(data), nil}, | ||||
| 	} | ||||
| 
 | ||||
| 	for i, testCase := range testCases { | ||||
|  | ||||
| @ -30,6 +30,7 @@ import ( | ||||
| 	"net/http/httptest" | ||||
| 	"net/url" | ||||
| 	"os" | ||||
| 	"reflect" | ||||
| 	"regexp" | ||||
| 	"sort" | ||||
| 	"strconv" | ||||
| @ -127,6 +128,11 @@ func nextSuffix() string { | ||||
| 	return strconv.Itoa(int(1e9 + r%1e9))[1:] | ||||
| } | ||||
| 
 | ||||
| // isSameType - compares two object types via reflect.TypeOf | ||||
| func isSameType(obj1, obj2 interface{}) bool { | ||||
| 	return reflect.TypeOf(obj1) == reflect.TypeOf(obj2) | ||||
| } | ||||
| 
 | ||||
| // TestServer encapsulates an instantiation of a Minio instance with a temporary backend. | ||||
| // Example usage: | ||||
| //   s := StartTestServer(t,"XL") | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user