| 
									
										
										
										
											2016-06-29 18:13:44 +08:00
										 |  |  | /* | 
					
						
							| 
									
										
										
										
											2019-04-10 02:39:42 +08:00
										 |  |  |  * MinIO Cloud Storage, (C) 2016, 2017 MinIO, Inc. | 
					
						
							| 
									
										
										
										
											2016-06-29 18:13:44 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  | package cmd | 
					
						
							| 
									
										
										
										
											2016-06-29 18:13:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2016-09-14 02:01:10 +08:00
										 |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2017-01-17 09:05:00 +08:00
										 |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2016-06-29 18:13:44 +08:00
										 |  |  | 	"path/filepath" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							| 
									
										
										
										
											2019-03-15 04:08:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/minio/minio/pkg/madmin" | 
					
						
							| 
									
										
										
										
											2016-06-29 18:13:44 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-26 05:47:58 +08:00
										 |  |  | // Tests for if parent directory is object
 | 
					
						
							|  |  |  | func TestFSParentDirIsObject(t *testing.T) { | 
					
						
							|  |  |  | 	obj, disk, err := prepareFS() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer os.RemoveAll(disk) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bucketName := "testbucket" | 
					
						
							|  |  |  | 	objectName := "object" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	if err = obj.MakeBucketWithLocation(context.Background(), bucketName, ""); err != nil { | 
					
						
							| 
									
										
										
										
											2017-09-26 05:47:58 +08:00
										 |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	objectContent := "12345" | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	objInfo, err := obj.PutObject(context.Background(), bucketName, objectName, | 
					
						
							| 
									
										
										
										
											2019-02-09 13:31:06 +08:00
										 |  |  | 		mustGetPutObjReader(t, bytes.NewReader([]byte(objectContent)), int64(len(objectContent)), "", ""), ObjectOptions{}) | 
					
						
							| 
									
										
										
										
											2017-09-26 05:47:58 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if objInfo.Name != objectName { | 
					
						
							|  |  |  | 		t.Fatalf("Unexpected object name returned got %s, expected %s", objInfo.Name, objectName) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 04:21:12 +08:00
										 |  |  | 	fs := obj.(*FSObjects) | 
					
						
							| 
									
										
										
										
											2017-09-26 05:47:58 +08:00
										 |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		parentIsObject bool | 
					
						
							|  |  |  | 		objectName     string | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		// parentIsObject is true if object is available.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			parentIsObject: true, | 
					
						
							|  |  |  | 			objectName:     objectName, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			parentIsObject: false, | 
					
						
							|  |  |  | 			objectName:     "", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			parentIsObject: false, | 
					
						
							|  |  |  | 			objectName:     ".", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Should not cause infinite loop.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			parentIsObject: false, | 
					
						
							| 
									
										
										
										
											2019-08-07 03:08:58 +08:00
										 |  |  | 			objectName:     SlashSeparator, | 
					
						
							| 
									
										
										
										
											2017-09-26 05:47:58 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			parentIsObject: false, | 
					
						
							|  |  |  | 			objectName:     "\\", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Should not cause infinite loop with double forward slash.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			parentIsObject: false, | 
					
						
							|  |  |  | 			objectName:     "//", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 		gotValue := fs.parentDirIsObject(context.Background(), bucketName, testCase.objectName) | 
					
						
							| 
									
										
										
										
											2017-09-26 05:47:58 +08:00
										 |  |  | 		if testCase.parentIsObject != gotValue { | 
					
						
							|  |  |  | 			t.Errorf("Test %d: Unexpected value returned got %t, expected %t", i+1, gotValue, testCase.parentIsObject) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-29 18:13:44 +08:00
										 |  |  | // TestNewFS - tests initialization of all input disks
 | 
					
						
							|  |  |  | // and constructs a valid `FS` object layer.
 | 
					
						
							|  |  |  | func TestNewFS(t *testing.T) { | 
					
						
							|  |  |  | 	// Do not attempt to create this path, the test validates
 | 
					
						
							| 
									
										
										
										
											2018-02-21 04:21:12 +08:00
										 |  |  | 	// so that NewFSObjectLayer initializes non existing paths
 | 
					
						
							| 
									
										
										
										
											2016-06-29 18:13:44 +08:00
										 |  |  | 	// and successfully returns initialized object layer.
 | 
					
						
							| 
									
										
										
										
											2016-12-16 14:25:05 +08:00
										 |  |  | 	disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix()) | 
					
						
							| 
									
										
										
										
											2017-08-13 10:25:43 +08:00
										 |  |  | 	defer os.RemoveAll(disk) | 
					
						
							| 
									
										
										
										
											2016-06-29 18:13:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 04:21:12 +08:00
										 |  |  | 	_, err := NewFSObjectLayer("") | 
					
						
							| 
									
										
										
										
											2016-10-06 03:48:07 +08:00
										 |  |  | 	if err != errInvalidArgument { | 
					
						
							|  |  |  | 		t.Errorf("Expecting error invalid argument, got %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-02-21 04:21:12 +08:00
										 |  |  | 	_, err = NewFSObjectLayer(disk) | 
					
						
							| 
									
										
										
										
											2016-10-06 03:48:07 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		errMsg := "Unable to recognize backend format, Disk is not in FS format." | 
					
						
							|  |  |  | 		if err.Error() == errMsg { | 
					
						
							|  |  |  | 			t.Errorf("Expecting %s, got %s", errMsg, err) | 
					
						
							| 
									
										
										
										
											2016-07-04 11:01:40 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-06-29 18:13:44 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-14 02:01:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-12 08:36:07 +08:00
										 |  |  | // TestFSShutdown - initialize a new FS object layer then calls
 | 
					
						
							|  |  |  | // Shutdown to check returned results
 | 
					
						
							| 
									
										
										
										
											2016-09-14 02:01:10 +08:00
										 |  |  | func TestFSShutdown(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-11-12 08:36:07 +08:00
										 |  |  | 	bucketName := "testbucket" | 
					
						
							|  |  |  | 	objectName := "object" | 
					
						
							| 
									
										
										
										
											2016-11-10 02:10:14 +08:00
										 |  |  | 	// Create and return an fsObject with its path in the disk
 | 
					
						
							| 
									
										
										
										
											2018-02-21 04:21:12 +08:00
										 |  |  | 	prepareTest := func() (*FSObjects, string) { | 
					
						
							| 
									
										
										
										
											2016-12-16 14:25:05 +08:00
										 |  |  | 		disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix()) | 
					
						
							| 
									
										
										
										
											2016-11-10 02:10:14 +08:00
										 |  |  | 		obj := initFSObjects(disk, t) | 
					
						
							| 
									
										
										
										
											2018-02-21 04:21:12 +08:00
										 |  |  | 		fs := obj.(*FSObjects) | 
					
						
							| 
									
										
										
										
											2018-08-15 12:41:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-10 02:10:14 +08:00
										 |  |  | 		objectContent := "12345" | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 		obj.MakeBucketWithLocation(context.Background(), bucketName, "") | 
					
						
							| 
									
										
										
										
											2019-02-09 13:31:06 +08:00
										 |  |  | 		obj.PutObject(context.Background(), bucketName, objectName, mustGetPutObjReader(t, bytes.NewReader([]byte(objectContent)), int64(len(objectContent)), "", ""), ObjectOptions{}) | 
					
						
							| 
									
										
										
										
											2016-11-10 02:10:14 +08:00
										 |  |  | 		return fs, disk | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-09-14 02:01:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 	// Test Shutdown with regular conditions
 | 
					
						
							| 
									
										
										
										
											2016-11-10 02:10:14 +08:00
										 |  |  | 	fs, disk := prepareTest() | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	if err := fs.Shutdown(context.Background()); err != nil { | 
					
						
							| 
									
										
										
										
											2016-09-14 02:01:10 +08:00
										 |  |  | 		t.Fatal("Cannot shutdown the FS object: ", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-08-13 10:25:43 +08:00
										 |  |  | 	os.RemoveAll(disk) | 
					
						
							| 
									
										
										
										
											2016-09-14 02:01:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-10 02:10:14 +08:00
										 |  |  | 	// Test Shutdown with faulty disk
 | 
					
						
							| 
									
										
										
										
											2017-02-08 04:51:23 +08:00
										 |  |  | 	fs, disk = prepareTest() | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	fs.DeleteObject(context.Background(), bucketName, objectName) | 
					
						
							| 
									
										
										
										
											2017-08-13 10:25:43 +08:00
										 |  |  | 	os.RemoveAll(disk) | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	if err := fs.Shutdown(context.Background()); err != nil { | 
					
						
							| 
									
										
										
										
											2017-02-08 04:51:23 +08:00
										 |  |  | 		t.Fatal("Got unexpected fs shutdown error: ", err) | 
					
						
							| 
									
										
										
										
											2016-12-02 05:59:06 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TestFSGetBucketInfo - test GetBucketInfo with healty and faulty disks
 | 
					
						
							|  |  |  | func TestFSGetBucketInfo(t *testing.T) { | 
					
						
							|  |  |  | 	// Prepare for testing
 | 
					
						
							| 
									
										
										
										
											2016-12-16 14:25:05 +08:00
										 |  |  | 	disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix()) | 
					
						
							| 
									
										
										
										
											2017-08-13 10:25:43 +08:00
										 |  |  | 	defer os.RemoveAll(disk) | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 03:48:07 +08:00
										 |  |  | 	obj := initFSObjects(disk, t) | 
					
						
							| 
									
										
										
										
											2018-02-21 04:21:12 +08:00
										 |  |  | 	fs := obj.(*FSObjects) | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 	bucketName := "bucket" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-24 11:27:33 +08:00
										 |  |  | 	err := obj.MakeBucketWithLocation(context.Background(), "a", "") | 
					
						
							|  |  |  | 	if !isSameType(err, BucketNameInvalid{}) { | 
					
						
							|  |  |  | 		t.Fatal("BucketNameInvalid error not returned") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = obj.MakeBucketWithLocation(context.Background(), bucketName, "") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Test with valid parameters
 | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	info, err := fs.GetBucketInfo(context.Background(), bucketName) | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if info.Name != bucketName { | 
					
						
							|  |  |  | 		t.Fatalf("wrong bucket name, expected: %s, found: %s", bucketName, info.Name) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-24 11:27:33 +08:00
										 |  |  | 	// Test with non-existent bucket
 | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	_, err = fs.GetBucketInfo(context.Background(), "a") | 
					
						
							| 
									
										
										
										
											2018-04-24 11:27:33 +08:00
										 |  |  | 	if !isSameType(err, BucketNotFound{}) { | 
					
						
							|  |  |  | 		t.Fatal("BucketNotFound error not returned") | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-17 09:05:00 +08:00
										 |  |  | 	// Check for buckets and should get disk not found.
 | 
					
						
							| 
									
										
										
										
											2018-06-05 09:35:41 +08:00
										 |  |  | 	os.RemoveAll(disk) | 
					
						
							| 
									
										
										
										
											2017-08-11 05:11:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-05 09:35:41 +08:00
										 |  |  | 	if _, err = fs.GetBucketInfo(context.Background(), bucketName); err != nil { | 
					
						
							|  |  |  | 		if !isSameType(err, BucketNotFound{}) { | 
					
						
							|  |  |  | 			t.Fatal("BucketNotFound error not returned") | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-10 08:46:46 +08:00
										 |  |  | func TestFSPutObject(t *testing.T) { | 
					
						
							|  |  |  | 	// Prepare for tests
 | 
					
						
							|  |  |  | 	disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix()) | 
					
						
							| 
									
										
										
										
											2017-08-13 10:25:43 +08:00
										 |  |  | 	defer os.RemoveAll(disk) | 
					
						
							| 
									
										
										
										
											2017-05-10 08:46:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	obj := initFSObjects(disk, t) | 
					
						
							|  |  |  | 	bucketName := "bucket" | 
					
						
							|  |  |  | 	objectName := "1/2/3/4/object" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	if err := obj.MakeBucketWithLocation(context.Background(), bucketName, ""); err != nil { | 
					
						
							| 
									
										
										
										
											2017-05-10 08:46:46 +08:00
										 |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-05-26 00:22:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// With a regular object.
 | 
					
						
							| 
									
										
										
										
											2019-02-09 13:31:06 +08:00
										 |  |  | 	_, err := obj.PutObject(context.Background(), bucketName+"non-existent", objectName, mustGetPutObjReader(t, bytes.NewReader([]byte("abcd")), int64(len("abcd")), "", ""), ObjectOptions{}) | 
					
						
							| 
									
										
										
										
											2017-05-26 00:22:43 +08:00
										 |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		t.Fatal("Unexpected should fail here, bucket doesn't exist") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-04-11 00:36:37 +08:00
										 |  |  | 	if _, ok := err.(BucketNotFound); !ok { | 
					
						
							| 
									
										
										
										
											2017-05-26 00:22:43 +08:00
										 |  |  | 		t.Fatalf("Expected error type BucketNotFound, got %#v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// With a directory object.
 | 
					
						
							| 
									
										
										
										
											2019-08-07 03:08:58 +08:00
										 |  |  | 	_, err = obj.PutObject(context.Background(), bucketName+"non-existent", objectName+SlashSeparator, mustGetPutObjReader(t, bytes.NewReader([]byte("abcd")), 0, "", ""), ObjectOptions{}) | 
					
						
							| 
									
										
										
										
											2017-05-26 00:22:43 +08:00
										 |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		t.Fatal("Unexpected should fail here, bucket doesn't exist") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-04-11 00:36:37 +08:00
										 |  |  | 	if _, ok := err.(BucketNotFound); !ok { | 
					
						
							| 
									
										
										
										
											2017-05-26 00:22:43 +08:00
										 |  |  | 		t.Fatalf("Expected error type BucketNotFound, got %#v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-09 13:31:06 +08:00
										 |  |  | 	_, err = obj.PutObject(context.Background(), bucketName, objectName, mustGetPutObjReader(t, bytes.NewReader([]byte("abcd")), int64(len("abcd")), "", ""), ObjectOptions{}) | 
					
						
							| 
									
										
										
										
											2017-05-10 08:46:46 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-02-09 13:31:06 +08:00
										 |  |  | 	_, err = obj.PutObject(context.Background(), bucketName, objectName+"/1", mustGetPutObjReader(t, bytes.NewReader([]byte("abcd")), int64(len("abcd")), "", ""), ObjectOptions{}) | 
					
						
							| 
									
										
										
										
											2017-05-10 08:46:46 +08:00
										 |  |  | 	if err == nil { | 
					
						
							| 
									
										
										
										
											2017-05-26 00:22:43 +08:00
										 |  |  | 		t.Fatal("Unexpected should fail here, backend corruption occurred") | 
					
						
							| 
									
										
										
										
											2017-05-10 08:46:46 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-03-21 04:06:53 +08:00
										 |  |  | 	if nerr, ok := err.(ParentIsObject); !ok { | 
					
						
							|  |  |  | 		t.Fatalf("Expected ParentIsObject, got %#v", err) | 
					
						
							| 
									
										
										
										
											2017-05-10 08:46:46 +08:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		if nerr.Bucket != "bucket" { | 
					
						
							|  |  |  | 			t.Fatalf("Expected 'bucket', got %s", nerr.Bucket) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if nerr.Object != "1/2/3/4/object/1" { | 
					
						
							|  |  |  | 			t.Fatalf("Expected '1/2/3/4/object/1', got %s", nerr.Object) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-09 13:31:06 +08:00
										 |  |  | 	_, err = obj.PutObject(context.Background(), bucketName, objectName+"/1/", mustGetPutObjReader(t, bytes.NewReader([]byte("abcd")), 0, "", ""), ObjectOptions{}) | 
					
						
							| 
									
										
										
										
											2017-05-10 08:46:46 +08:00
										 |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		t.Fatal("Unexpected should fail here, backned corruption occurred") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-03-21 04:06:53 +08:00
										 |  |  | 	if nerr, ok := err.(ParentIsObject); !ok { | 
					
						
							|  |  |  | 		t.Fatalf("Expected ParentIsObject, got %#v", err) | 
					
						
							| 
									
										
										
										
											2017-05-10 08:46:46 +08:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		if nerr.Bucket != "bucket" { | 
					
						
							|  |  |  | 			t.Fatalf("Expected 'bucket', got %s", nerr.Bucket) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if nerr.Object != "1/2/3/4/object/1/" { | 
					
						
							|  |  |  | 			t.Fatalf("Expected '1/2/3/4/object/1/', got %s", nerr.Object) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | // TestFSDeleteObject - test fs.DeleteObject() with healthy and corrupted disks
 | 
					
						
							|  |  |  | func TestFSDeleteObject(t *testing.T) { | 
					
						
							|  |  |  | 	// Prepare for tests
 | 
					
						
							| 
									
										
										
										
											2016-12-16 14:25:05 +08:00
										 |  |  | 	disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix()) | 
					
						
							| 
									
										
										
										
											2017-08-13 10:25:43 +08:00
										 |  |  | 	defer os.RemoveAll(disk) | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 03:48:07 +08:00
										 |  |  | 	obj := initFSObjects(disk, t) | 
					
						
							| 
									
										
										
										
											2018-02-21 04:21:12 +08:00
										 |  |  | 	fs := obj.(*FSObjects) | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 	bucketName := "bucket" | 
					
						
							|  |  |  | 	objectName := "object" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	obj.MakeBucketWithLocation(context.Background(), bucketName, "") | 
					
						
							| 
									
										
										
										
											2019-02-09 13:31:06 +08:00
										 |  |  | 	obj.PutObject(context.Background(), bucketName, objectName, mustGetPutObjReader(t, bytes.NewReader([]byte("abcd")), int64(len("abcd")), "", ""), ObjectOptions{}) | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Test with invalid bucket name
 | 
					
						
							| 
									
										
										
										
											2018-04-11 00:36:37 +08:00
										 |  |  | 	if err := fs.DeleteObject(context.Background(), "fo", objectName); !isSameType(err, BucketNameInvalid{}) { | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 		t.Fatal("Unexpected error: ", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-01-17 09:05:00 +08:00
										 |  |  | 	// Test with bucket does not exist
 | 
					
						
							| 
									
										
										
										
											2018-04-11 00:36:37 +08:00
										 |  |  | 	if err := fs.DeleteObject(context.Background(), "foobucket", "fooobject"); !isSameType(err, BucketNotFound{}) { | 
					
						
							| 
									
										
										
										
											2017-01-17 09:05:00 +08:00
										 |  |  | 		t.Fatal("Unexpected error: ", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 	// Test with invalid object name
 | 
					
						
							| 
									
										
										
										
											2020-02-12 11:38:02 +08:00
										 |  |  | 	if err := fs.DeleteObject(context.Background(), bucketName, "\\"); !isSameType(err, ObjectNotFound{}) { | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 		t.Fatal("Unexpected error: ", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-01-17 09:05:00 +08:00
										 |  |  | 	// Test with object does not exist.
 | 
					
						
							| 
									
										
										
										
											2018-04-11 00:36:37 +08:00
										 |  |  | 	if err := fs.DeleteObject(context.Background(), bucketName, "foooobject"); !isSameType(err, ObjectNotFound{}) { | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 		t.Fatal("Unexpected error: ", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Test with valid condition
 | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	if err := fs.DeleteObject(context.Background(), bucketName, objectName); err != nil { | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 		t.Fatal("Unexpected error: ", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-17 09:05:00 +08:00
										 |  |  | 	// Delete object should err disk not found.
 | 
					
						
							| 
									
										
										
										
											2018-06-05 09:35:41 +08:00
										 |  |  | 	os.RemoveAll(disk) | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	if err := fs.DeleteObject(context.Background(), bucketName, objectName); err != nil { | 
					
						
							| 
									
										
										
										
											2018-04-11 00:36:37 +08:00
										 |  |  | 		if !isSameType(err, BucketNotFound{}) { | 
					
						
							| 
									
										
										
										
											2017-01-17 09:05:00 +08:00
										 |  |  | 			t.Fatal("Unexpected error: ", err) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TestFSDeleteBucket - tests for fs DeleteBucket
 | 
					
						
							|  |  |  | func TestFSDeleteBucket(t *testing.T) { | 
					
						
							|  |  |  | 	// Prepare for testing
 | 
					
						
							| 
									
										
										
										
											2016-12-16 14:25:05 +08:00
										 |  |  | 	disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix()) | 
					
						
							| 
									
										
										
										
											2017-08-13 10:25:43 +08:00
										 |  |  | 	defer os.RemoveAll(disk) | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 03:48:07 +08:00
										 |  |  | 	obj := initFSObjects(disk, t) | 
					
						
							| 
									
										
										
										
											2018-02-21 04:21:12 +08:00
										 |  |  | 	fs := obj.(*FSObjects) | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 	bucketName := "bucket" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	err := obj.MakeBucketWithLocation(context.Background(), bucketName, "") | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal("Unexpected error: ", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Test with an invalid bucket name
 | 
					
						
							| 
									
										
										
										
											2018-04-24 11:27:33 +08:00
										 |  |  | 	if err = fs.DeleteBucket(context.Background(), "fo"); !isSameType(err, BucketNotFound{}) { | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 		t.Fatal("Unexpected error: ", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-04-24 11:27:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 	// Test with an inexistant bucket
 | 
					
						
							| 
									
										
										
										
											2018-04-11 00:36:37 +08:00
										 |  |  | 	if err = fs.DeleteBucket(context.Background(), "foobucket"); !isSameType(err, BucketNotFound{}) { | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 		t.Fatal("Unexpected error: ", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Test with a valid case
 | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	if err = fs.DeleteBucket(context.Background(), bucketName); err != nil { | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 		t.Fatal("Unexpected error: ", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	obj.MakeBucketWithLocation(context.Background(), bucketName, "") | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 05:11:57 +08:00
										 |  |  | 	// Delete bucket should get error disk not found.
 | 
					
						
							| 
									
										
										
										
											2018-06-05 09:35:41 +08:00
										 |  |  | 	os.RemoveAll(disk) | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	if err = fs.DeleteBucket(context.Background(), bucketName); err != nil { | 
					
						
							| 
									
										
										
										
											2018-04-11 00:36:37 +08:00
										 |  |  | 		if !isSameType(err, BucketNotFound{}) { | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 			t.Fatal("Unexpected error: ", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TestFSListBuckets - tests for fs ListBuckets
 | 
					
						
							|  |  |  | func TestFSListBuckets(t *testing.T) { | 
					
						
							|  |  |  | 	// Prepare for tests
 | 
					
						
							| 
									
										
										
										
											2016-12-16 14:25:05 +08:00
										 |  |  | 	disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix()) | 
					
						
							| 
									
										
										
										
											2017-08-13 10:25:43 +08:00
										 |  |  | 	defer os.RemoveAll(disk) | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 03:48:07 +08:00
										 |  |  | 	obj := initFSObjects(disk, t) | 
					
						
							| 
									
										
										
										
											2018-02-21 04:21:12 +08:00
										 |  |  | 	fs := obj.(*FSObjects) | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	bucketName := "bucket" | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	if err := obj.MakeBucketWithLocation(context.Background(), bucketName, ""); err != nil { | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 		t.Fatal("Unexpected error: ", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-06 06:16:43 +08:00
										 |  |  | 	GlobalServiceDoneCh <- struct{}{} | 
					
						
							| 
									
										
										
										
											2018-06-01 05:03:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 	// Create a bucket with invalid name
 | 
					
						
							| 
									
										
										
										
											2017-08-13 10:25:43 +08:00
										 |  |  | 	if err := os.MkdirAll(pathJoin(fs.fsPath, "vo^"), 0777); err != nil { | 
					
						
							| 
									
										
										
										
											2017-01-17 09:05:00 +08:00
										 |  |  | 		t.Fatal("Unexpected error: ", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	f, err := os.Create(pathJoin(fs.fsPath, "test")) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 		t.Fatal("Unexpected error: ", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-01-17 09:05:00 +08:00
										 |  |  | 	f.Close() | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-17 09:05:00 +08:00
										 |  |  | 	// Test list buckets to have only one entry.
 | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	buckets, err := fs.ListBuckets(context.Background()) | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal("Unexpected error: ", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if len(buckets) != 1 { | 
					
						
							| 
									
										
										
										
											2017-01-17 09:05:00 +08:00
										 |  |  | 		t.Fatal("ListBuckets not working properly", buckets) | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-17 09:05:00 +08:00
										 |  |  | 	// Test ListBuckets with disk not found.
 | 
					
						
							| 
									
										
										
										
											2018-06-05 09:35:41 +08:00
										 |  |  | 	os.RemoveAll(disk) | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	if _, err := fs.ListBuckets(context.Background()); err != nil { | 
					
						
							| 
									
										
										
										
											2018-04-11 00:36:37 +08:00
										 |  |  | 		if err != errDiskNotFound { | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 			t.Fatal("Unexpected error: ", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TestFSHealObject - tests for fs HealObject
 | 
					
						
							|  |  |  | func TestFSHealObject(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-12-16 14:25:05 +08:00
										 |  |  | 	disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix()) | 
					
						
							| 
									
										
										
										
											2017-08-13 10:25:43 +08:00
										 |  |  | 	defer os.RemoveAll(disk) | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 03:48:07 +08:00
										 |  |  | 	obj := initFSObjects(disk, t) | 
					
						
							| 
									
										
										
										
											2019-03-15 04:08:51 +08:00
										 |  |  | 	_, err := obj.HealObject(context.Background(), "bucket", "object", false, false, madmin.HealDeepScan) | 
					
						
							| 
									
										
										
										
											2018-04-11 00:36:37 +08:00
										 |  |  | 	if err == nil || !isSameType(err, NotImplemented{}) { | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 		t.Fatalf("Heal Object should return NotImplemented error ") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-14 08:35:09 +08:00
										 |  |  | // TestFSHealObjects - tests for fs HealObjects to return not implemented.
 | 
					
						
							|  |  |  | func TestFSHealObjects(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-12-16 14:25:05 +08:00
										 |  |  | 	disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix()) | 
					
						
							| 
									
										
										
										
											2017-08-13 10:25:43 +08:00
										 |  |  | 	defer os.RemoveAll(disk) | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 03:48:07 +08:00
										 |  |  | 	obj := initFSObjects(disk, t) | 
					
						
							| 
									
										
										
										
											2019-03-14 08:35:09 +08:00
										 |  |  | 	err := obj.HealObjects(context.Background(), "bucket", "prefix", nil) | 
					
						
							| 
									
										
										
										
											2018-04-11 00:36:37 +08:00
										 |  |  | 	if err == nil || !isSameType(err, NotImplemented{}) { | 
					
						
							| 
									
										
										
										
											2016-09-17 04:06:49 +08:00
										 |  |  | 		t.Fatalf("Heal Object should return NotImplemented error ") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-09-14 02:01:10 +08:00
										 |  |  | } |