mirror of https://github.com/minio/minio.git
				
				
				
			
		
			
	
	
		
			501 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Go
		
	
	
	
		
		
			
		
	
	
			501 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Go
		
	
	
	
|  | /* | ||
|  |  * 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" | ||
|  | 	"fmt" | ||
|  | 	"io" | ||
|  | 	"strings" | ||
|  | 	"testing" | ||
|  | ) | ||
|  | 
 | ||
|  | // Wrapper for calling GetObject tests for both XL multiple disks and single node setup.
 | ||
|  | func TestGetObject(t *testing.T) { | ||
|  | 	ExecObjectLayerTest(t, testGetObject) | ||
|  | } | ||
|  | 
 | ||
|  | // ObjectLayer.GetObject is called with series of cases for valid and erroneous inputs and the result is validated.
 | ||
|  | func testGetObject(obj ObjectLayer, instanceType string, t TestErrHandler) { | ||
|  | 	// Setup for the tests.
 | ||
|  | 	bucketName := getRandomBucketName() | ||
|  | 	objectName := "test-object" | ||
|  | 	// create bucket.
 | ||
|  | 	err := obj.MakeBucket(bucketName) | ||
|  | 	// Stop the test if creation of the bucket fails.
 | ||
|  | 	if err != nil { | ||
|  | 		t.Fatalf("%s : %s", instanceType, err.Error()) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// set of byte data for PutObject.
 | ||
|  | 	// object has to be inserted before running tests for GetObject.
 | ||
|  | 	// this is required even to assert the GetObject data,
 | ||
|  | 	// since dataInserted === dataFetched back is a primary criteria for any object storage this assertion is critical.
 | ||
|  | 	bytesData := []struct { | ||
|  | 		byteData []byte | ||
|  | 	}{ | ||
|  | 		{generateBytesData(6 * 1024 * 1024)}, | ||
|  | 	} | ||
|  | 	// set of inputs for uploading the objects before tests for downloading is done.
 | ||
|  | 	putObjectInputs := []struct { | ||
|  | 		bucketName    string | ||
|  | 		objectName    string | ||
|  | 		contentLength int64 | ||
|  | 		textData      []byte | ||
|  | 		metaData      map[string]string | ||
|  | 	}{ | ||
|  | 		// case - 1.
 | ||
|  | 		{bucketName, objectName, int64(len(bytesData[0].byteData)), bytesData[0].byteData, make(map[string]string)}, | ||
|  | 	} | ||
|  | 	// iterate through the above set of inputs and upkoad the object.
 | ||
|  | 	for i, input := range putObjectInputs { | ||
|  | 		// uploading the object.
 | ||
|  | 		_, err = obj.PutObject(input.bucketName, input.objectName, input.contentLength, bytes.NewBuffer(input.textData), input.metaData) | ||
|  | 		// if object upload fails stop the test.
 | ||
|  | 		if err != nil { | ||
|  | 			t.Fatalf("Put Object case %d:  Error uploading object: <ERROR> %v", i+1, err) | ||
|  | 		} | ||
|  | 	} | ||
|  | 	// set of empty buffers used to fill GetObject data.
 | ||
|  | 	buffers := []*bytes.Buffer{ | ||
|  | 		new(bytes.Buffer), | ||
|  | 		new(bytes.Buffer), | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// test cases with set of inputs
 | ||
|  | 	testCases := []struct { | ||
|  | 		bucketName  string | ||
|  | 		objectName  string | ||
|  | 		startOffset int64 | ||
|  | 		length      int64 | ||
|  | 		// data obtained/fetched from GetObject.
 | ||
|  | 		getObjectData *bytes.Buffer | ||
|  | 		// writer which governs the write into the `getObjectData`.
 | ||
|  | 		writer io.Writer | ||
|  | 		// flag indicating whether the test for given ase should pass.
 | ||
|  | 		shouldPass bool | ||
|  | 		// expected Result.
 | ||
|  | 		expectedData []byte | ||
|  | 		err          error | ||
|  | 	}{ | ||
|  | 		// Test case 1-4.
 | ||
|  | 		// Cases with invalid bucket names.
 | ||
|  | 		{".test", "obj", 0, 0, nil, nil, false, []byte(""), fmt.Errorf("%s", "Bucket name invalid: .test")}, | ||
|  | 		{"------", "obj", 0, 0, nil, nil, false, []byte(""), fmt.Errorf("%s", "Bucket name invalid: ------")}, | ||
|  | 		{"$this-is-not-valid-too", "obj", 0, 0, nil, nil, false, | ||
|  | 			[]byte(""), fmt.Errorf("%s", "Bucket name invalid: $this-is-not-valid-too")}, | ||
|  | 		{"a", "obj", 0, 0, nil, nil, false, []byte(""), fmt.Errorf("%s", "Bucket name invalid: a")}, | ||
|  | 		// Test case - 5.
 | ||
|  | 		// Case with invalid object names.
 | ||
|  | 		{bucketName, "", 0, 0, nil, nil, false, []byte(""), fmt.Errorf("%s", "Object name invalid: "+bucketName+"#")}, | ||
|  | 		// Test case - 6.
 | ||
|  | 		// 	Valid object and bucket names but non-existent bucket.
 | ||
|  | 		//	{"abc", "def", 0, 0, nil, nil, false, []byte(""), fmt.Errorf("%s", "Bucket not found: abc")},
 | ||
|  | 		// A custom writer is sent as an argument.
 | ||
|  | 		// Its designed to return a EOF error after reading `n` bytes, where `n` is the argument when initializing the EOF writer.
 | ||
|  | 		// This is to simulate the case of cache not filling up completly, since the EOFWriter doesn't allow the write to complete,
 | ||
|  | 		// the cache gets filled up with partial data. The following up test case will read the object completly, tests the
 | ||
|  | 		// purging of the cache during the incomplete write.
 | ||
|  | 		//	Test case - 7.
 | ||
|  | 		{bucketName, objectName, 0, int64(len(bytesData[0].byteData)), buffers[0], NewEOFWriter(buffers[0], 100), false, []byte{}, io.EOF}, | ||
|  | 		// Test case with start offset set to 0 and length set to size of the object.
 | ||
|  | 		// Fetching the entire object.
 | ||
|  | 		// 	Test case - 8.
 | ||
|  | 		{bucketName, objectName, 0, int64(len(bytesData[0].byteData)), buffers[1], buffers[1], true, bytesData[0].byteData, nil}, | ||
|  | 		// Test case with content-range 1 to objectSize .
 | ||
|  | 		// Test case - 9.
 | ||
|  | 		{bucketName, objectName, 1, int64(len(bytesData[0].byteData) - 1), buffers[1], buffers[1], true, bytesData[0].byteData[1:], nil}, | ||
|  | 		// Test case with content-range 100 to objectSize - 100.
 | ||
|  | 		// Test case - 10.
 | ||
|  | 		{bucketName, objectName, 100, int64(len(bytesData[0].byteData) - 200), buffers[1], buffers[1], true, | ||
|  | 			bytesData[0].byteData[100 : len(bytesData[0].byteData)-100], nil}, | ||
|  | 		// Test case with offset greater than the size of the object
 | ||
|  | 		// Test case - 11.
 | ||
|  | 		{bucketName, objectName, int64(len(bytesData[0].byteData) + 1), int64(len(bytesData[0].byteData)), buffers[0], | ||
|  | 			NewEOFWriter(buffers[0], 100), false, []byte{}, | ||
|  | 			InvalidRange{int64(len(bytesData[0].byteData) + 1), int64(len(bytesData[0].byteData)), int64(len(bytesData[0].byteData))}}, | ||
|  | 		// Test case with offset greater than the size of the object.
 | ||
|  | 		// Test case - 12.
 | ||
|  | 		{bucketName, objectName, -1, int64(len(bytesData[0].byteData)), buffers[0], new(bytes.Buffer), false, []byte{}, errUnexpected}, | ||
|  | 		// Test case length parameter is more than the object size.
 | ||
|  | 		// Test case - 13.
 | ||
|  | 		{bucketName, objectName, 0, int64(len(bytesData[0].byteData) + 1), buffers[1], buffers[1], false, bytesData[0].byteData, | ||
|  | 			InvalidRange{0, int64(len(bytesData[0].byteData) + 1), int64(len(bytesData[0].byteData))}}, | ||
|  | 		// Test case with `length` parameter set to a negative value.
 | ||
|  | 		// Test case - 14.
 | ||
|  | 		{bucketName, objectName, 0, int64(-1), buffers[1], buffers[1], false, bytesData[0].byteData, errUnexpected}, | ||
|  | 		// Test case with offset + length > objectSize parameter set to a negative value.
 | ||
|  | 		// Test case - 15.
 | ||
|  | 		{bucketName, objectName, 2, int64(len(bytesData[0].byteData)), buffers[1], buffers[1], false, bytesData[0].byteData, | ||
|  | 			InvalidRange{2, int64(len(bytesData[0].byteData)), int64(len(bytesData[0].byteData))}}, | ||
|  | 		// Test case with the writer set to nil.
 | ||
|  | 		// Test case - 16.
 | ||
|  | 		{bucketName, objectName, 0, int64(len(bytesData[0].byteData)), buffers[1], nil, false, bytesData[0].byteData, errUnexpected}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for i, testCase := range testCases { | ||
|  | 		err = obj.GetObject(testCase.bucketName, testCase.objectName, testCase.startOffset, testCase.length, testCase.writer) | ||
|  | 		if err != nil && testCase.shouldPass { | ||
|  | 			t.Errorf("Test %d: %s:  Expected to pass, but failed with: <ERROR> %s", i+1, instanceType, err.Error()) | ||
|  | 		} | ||
|  | 		if err == nil && !testCase.shouldPass { | ||
|  | 			t.Errorf("Test %d: %s: Expected to fail with <ERROR> \"%s\", but passed instead.", i+1, instanceType, testCase.err.Error()) | ||
|  | 		} | ||
|  | 		// Failed as expected, but does it fail for the expected reason.
 | ||
|  | 		if err != nil && !testCase.shouldPass { | ||
|  | 			if !strings.Contains(err.Error(), testCase.err.Error()) { | ||
|  | 				t.Errorf("Test %d: %s: Expected to fail with error \"%s\", but instead failed with error \"%s\" instead.", i+1, instanceType, testCase.err.Error(), err.Error()) | ||
|  | 			} | ||
|  | 		} | ||
|  | 		// Since there are cases for which GetObject fails, this is
 | ||
|  | 		// necessary. Test passes as expected, but the output values
 | ||
|  | 		// are verified for correctness here.
 | ||
|  | 		if err == nil && testCase.shouldPass { | ||
|  | 			if !bytes.Equal(testCase.expectedData, testCase.getObjectData.Bytes()) { | ||
|  | 				t.Errorf("Test %d: %s: Data Mismatch: Expected data and the fetched data from GetObject doesn't match.", i+1, instanceType) | ||
|  | 			} | ||
|  | 			// empty the buffer so that it can be used to further cases.
 | ||
|  | 			testCase.getObjectData.Reset() | ||
|  | 		} | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | // Wrapper for calling GetObject tests for both XL multiple disks and single node setup.
 | ||
|  | func TestGetObjectDiskNotFound(t *testing.T) { | ||
|  | 	ExecObjectLayerDiskNotFoundTest(t, testGetObjectDiskNotFound) | ||
|  | } | ||
|  | 
 | ||
|  | // ObjectLayer.GetObject is called with series of cases for valid and erroneous inputs and the result is validated.
 | ||
|  | // Before the Get Object call XL disks are moved so that the quorum just holds.
 | ||
|  | func testGetObjectDiskNotFound(obj ObjectLayer, instanceType string, disks []string, t *testing.T) { | ||
|  | 	// Setup for the tests.
 | ||
|  | 	bucketName := getRandomBucketName() | ||
|  | 	objectName := "test-object" | ||
|  | 	// create bucket.
 | ||
|  | 	err := obj.MakeBucket(bucketName) | ||
|  | 	// Stop the test if creation of the bucket fails.
 | ||
|  | 	if err != nil { | ||
|  | 		t.Fatalf("%s : %s", instanceType, err.Error()) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// set of byte data for PutObject.
 | ||
|  | 	// object has to be inserted before running tests for GetObject.
 | ||
|  | 	// this is required even to assert the GetObject data,
 | ||
|  | 	// since dataInserted === dataFetched back is a primary criteria for any object storage this assertion is critical.
 | ||
|  | 	bytesData := []struct { | ||
|  | 		byteData []byte | ||
|  | 	}{ | ||
|  | 		{generateBytesData(6 * 1024 * 1024)}, | ||
|  | 	} | ||
|  | 	// set of inputs for uploading the objects before tests for downloading is done.
 | ||
|  | 	putObjectInputs := []struct { | ||
|  | 		bucketName    string | ||
|  | 		objectName    string | ||
|  | 		contentLength int64 | ||
|  | 		textData      []byte | ||
|  | 		metaData      map[string]string | ||
|  | 	}{ | ||
|  | 		// case - 1.
 | ||
|  | 		{bucketName, objectName, int64(len(bytesData[0].byteData)), bytesData[0].byteData, make(map[string]string)}, | ||
|  | 	} | ||
|  | 	// iterate through the above set of inputs and upkoad the object.
 | ||
|  | 	for i, input := range putObjectInputs { | ||
|  | 		// uploading the object.
 | ||
|  | 		_, err = obj.PutObject(input.bucketName, input.objectName, input.contentLength, bytes.NewBuffer(input.textData), input.metaData) | ||
|  | 		// if object upload fails stop the test.
 | ||
|  | 		if err != nil { | ||
|  | 			t.Fatalf("Put Object case %d:  Error uploading object: <ERROR> %v", i+1, err) | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Take 8 disks down before GetObject is called, one more we loose quorum on 16 disk node.
 | ||
|  | 	for _, disk := range disks[:8] { | ||
|  | 		removeAll(disk) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// set of empty buffers used to fill GetObject data.
 | ||
|  | 	buffers := []*bytes.Buffer{ | ||
|  | 		new(bytes.Buffer), | ||
|  | 		new(bytes.Buffer), | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// test cases with set of inputs
 | ||
|  | 	testCases := []struct { | ||
|  | 		bucketName  string | ||
|  | 		objectName  string | ||
|  | 		startOffset int64 | ||
|  | 		length      int64 | ||
|  | 		// data obtained/fetched from GetObject.
 | ||
|  | 		getObjectData *bytes.Buffer | ||
|  | 		// writer which governs the write into the `getObjectData`.
 | ||
|  | 		writer io.Writer | ||
|  | 		// flag indicating whether the test for given ase should pass.
 | ||
|  | 		shouldPass bool | ||
|  | 		// expected Result.
 | ||
|  | 		expectedData []byte | ||
|  | 		err          error | ||
|  | 	}{ | ||
|  | 		// Test case 1-4.
 | ||
|  | 		// Cases with invalid bucket names.
 | ||
|  | 		{".test", "obj", 0, 0, nil, nil, false, []byte(""), fmt.Errorf("%s", "Bucket name invalid: .test")}, | ||
|  | 		{"------", "obj", 0, 0, nil, nil, false, []byte(""), fmt.Errorf("%s", "Bucket name invalid: ------")}, | ||
|  | 		{"$this-is-not-valid-too", "obj", 0, 0, nil, nil, false, | ||
|  | 			[]byte(""), fmt.Errorf("%s", "Bucket name invalid: $this-is-not-valid-too")}, | ||
|  | 		{"a", "obj", 0, 0, nil, nil, false, []byte(""), fmt.Errorf("%s", "Bucket name invalid: a")}, | ||
|  | 		// Test case - 5.
 | ||
|  | 		// Case with invalid object names.
 | ||
|  | 		{bucketName, "", 0, 0, nil, nil, false, []byte(""), fmt.Errorf("%s", "Object name invalid: "+bucketName+"#")}, | ||
|  | 		// Test case - 6.
 | ||
|  | 		// 	Valid object and bucket names but non-existent bucket.
 | ||
|  | 		//	{"abc", "def", 0, 0, nil, nil, false, []byte(""), fmt.Errorf("%s", "Bucket not found: abc")},
 | ||
|  | 		// A custom writer is sent as an argument.
 | ||
|  | 		// Its designed to return a EOF error after reading `n` bytes, where `n` is the argument when initializing the EOF writer.
 | ||
|  | 		// This is to simulate the case of cache not filling up completly, since the EOFWriter doesn't allow the write to complete,
 | ||
|  | 		// the cache gets filled up with partial data. The following up test case will read the object completly, tests the
 | ||
|  | 		// purging of the cache during the incomplete write.
 | ||
|  | 		//	Test case - 7.
 | ||
|  | 		{bucketName, objectName, 0, int64(len(bytesData[0].byteData)), buffers[0], NewEOFWriter(buffers[0], 100), false, []byte{}, io.EOF}, | ||
|  | 		// Test case with start offset set to 0 and length set to size of the object.
 | ||
|  | 		// Fetching the entire object.
 | ||
|  | 		// 	Test case - 8.
 | ||
|  | 		{bucketName, objectName, 0, int64(len(bytesData[0].byteData)), buffers[1], buffers[1], true, bytesData[0].byteData, nil}, | ||
|  | 		// Test case with content-range 1 to objectSize .
 | ||
|  | 		// Test case - 9.
 | ||
|  | 		{bucketName, objectName, 1, int64(len(bytesData[0].byteData) - 1), buffers[1], buffers[1], true, bytesData[0].byteData[1:], nil}, | ||
|  | 		// Test case with content-range 100 to objectSize - 100.
 | ||
|  | 		// Test case - 10.
 | ||
|  | 		{bucketName, objectName, 100, int64(len(bytesData[0].byteData) - 200), buffers[1], buffers[1], true, | ||
|  | 			bytesData[0].byteData[100 : len(bytesData[0].byteData)-100], nil}, | ||
|  | 		// Test case with offset greater than the size of the object
 | ||
|  | 		// Test case - 11.
 | ||
|  | 		{bucketName, objectName, int64(len(bytesData[0].byteData) + 1), int64(len(bytesData[0].byteData)), buffers[0], | ||
|  | 			NewEOFWriter(buffers[0], 100), false, []byte{}, | ||
|  | 			InvalidRange{int64(len(bytesData[0].byteData) + 1), int64(len(bytesData[0].byteData)), int64(len(bytesData[0].byteData))}}, | ||
|  | 		// Test case with offset greater than the size of the object.
 | ||
|  | 		// Test case - 12.
 | ||
|  | 		{bucketName, objectName, -1, int64(len(bytesData[0].byteData)), buffers[0], new(bytes.Buffer), false, []byte{}, errUnexpected}, | ||
|  | 		// Test case length parameter is more than the object size.
 | ||
|  | 		// Test case - 13.
 | ||
|  | 		{bucketName, objectName, 0, int64(len(bytesData[0].byteData) + 1), buffers[1], buffers[1], false, bytesData[0].byteData, | ||
|  | 			InvalidRange{0, int64(len(bytesData[0].byteData) + 1), int64(len(bytesData[0].byteData))}}, | ||
|  | 		// Test case with `length` parameter set to a negative value.
 | ||
|  | 		// Test case - 14.
 | ||
|  | 		{bucketName, objectName, 0, int64(-1), buffers[1], buffers[1], false, bytesData[0].byteData, errUnexpected}, | ||
|  | 		// Test case with offset + length > objectSize parameter set to a negative value.
 | ||
|  | 		// Test case - 15.
 | ||
|  | 		{bucketName, objectName, 2, int64(len(bytesData[0].byteData)), buffers[1], buffers[1], false, bytesData[0].byteData, | ||
|  | 			InvalidRange{2, int64(len(bytesData[0].byteData)), int64(len(bytesData[0].byteData))}}, | ||
|  | 		// Test case with the writer set to nil.
 | ||
|  | 		// Test case - 16.
 | ||
|  | 		{bucketName, objectName, 0, int64(len(bytesData[0].byteData)), buffers[1], nil, false, bytesData[0].byteData, errUnexpected}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for i, testCase := range testCases { | ||
|  | 		err = obj.GetObject(testCase.bucketName, testCase.objectName, testCase.startOffset, testCase.length, testCase.writer) | ||
|  | 		if err != nil && testCase.shouldPass { | ||
|  | 			t.Errorf("Test %d: %s:  Expected to pass, but failed with: <ERROR> %s", i+1, instanceType, err.Error()) | ||
|  | 		} | ||
|  | 		if err == nil && !testCase.shouldPass { | ||
|  | 			t.Errorf("Test %d: %s: Expected to fail with <ERROR> \"%s\", but passed instead.", i+1, instanceType, testCase.err.Error()) | ||
|  | 		} | ||
|  | 		// Failed as expected, but does it fail for the expected reason.
 | ||
|  | 		if err != nil && !testCase.shouldPass { | ||
|  | 			if !strings.Contains(err.Error(), testCase.err.Error()) { | ||
|  | 				t.Errorf("Test %d: %s: Expected to fail with error \"%s\", but instead failed with error \"%s\" instead.", i+1, instanceType, testCase.err.Error(), err.Error()) | ||
|  | 			} | ||
|  | 		} | ||
|  | 		// Since there are cases for which GetObject fails, this is
 | ||
|  | 		// necessary. Test passes as expected, but the output values
 | ||
|  | 		// are verified for correctness here.
 | ||
|  | 		if err == nil && testCase.shouldPass { | ||
|  | 			if !bytes.Equal(testCase.expectedData, testCase.getObjectData.Bytes()) { | ||
|  | 				t.Errorf("Test %d: %s: Data Mismatch: Expected data and the fetched data from GetObject doesn't match.", i+1, instanceType) | ||
|  | 			} | ||
|  | 			// empty the buffer so that it can be used to further cases.
 | ||
|  | 			testCase.getObjectData.Reset() | ||
|  | 		} | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | // Benchmarks for ObjectLayer.GetObject().
 | ||
|  | // The intent is to benchmark GetObject for various sizes ranging from few bytes to 100MB.
 | ||
|  | // Also each of these Benchmarks are run both XL and FS backends.
 | ||
|  | 
 | ||
|  | // BenchmarkGetObjectVerySmallFS - Benchmark FS.GetObject() for object size of 10 bytes.
 | ||
|  | func BenchmarkGetObjectVerySmallFS(b *testing.B) { | ||
|  | 	benchmarkGetObject(b, "FS", 10) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObjectVerySmallXL - Benchmark XL.GetObject() for object size of 10 bytes.
 | ||
|  | func BenchmarkGetObjectVerySmallXL(b *testing.B) { | ||
|  | 	benchmarkGetObject(b, "XL", 10) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObject10KbFS - Benchmark FS.GetObject() for object size of 10KB.
 | ||
|  | func BenchmarkGetObject10KbFS(b *testing.B) { | ||
|  | 	benchmarkGetObject(b, "FS", 10*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObject10KbXL - Benchmark XL.GetObject() for object size of 10KB.
 | ||
|  | func BenchmarkGetObject10KbXL(b *testing.B) { | ||
|  | 	benchmarkGetObject(b, "XL", 10*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObject100KbFS - Benchmark FS.GetObject() for object size of 100KB.
 | ||
|  | func BenchmarkGetObject100KbFS(b *testing.B) { | ||
|  | 	benchmarkGetObject(b, "FS", 100*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObject100KbXL - Benchmark XL.GetObject() for object size of 100KB.
 | ||
|  | func BenchmarkGetObject100KbXL(b *testing.B) { | ||
|  | 	benchmarkGetObject(b, "XL", 100*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObject1MbFS - Benchmark FS.GetObject() for object size of 1MB.
 | ||
|  | func BenchmarkGetObject1MbFS(b *testing.B) { | ||
|  | 	benchmarkGetObject(b, "FS", 1024*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObject1MbXL - Benchmark XL.GetObject() for object size of 1MB.
 | ||
|  | func BenchmarkGetObject1MbXL(b *testing.B) { | ||
|  | 	benchmarkGetObject(b, "XL", 1024*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObject5MbFS - Benchmark FS.GetObject() for object size of 5MB.
 | ||
|  | func BenchmarkGetObject5MbFS(b *testing.B) { | ||
|  | 	benchmarkGetObject(b, "FS", 5*1024*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObject5MbXL - Benchmark XL.GetObject() for object size of 5MB.
 | ||
|  | func BenchmarkGetObject5MbXL(b *testing.B) { | ||
|  | 	benchmarkGetObject(b, "XL", 5*1024*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObject10MbFS - Benchmark FS.GetObject() for object size of 10MB.
 | ||
|  | func BenchmarkGetObject10MbFS(b *testing.B) { | ||
|  | 	benchmarkGetObject(b, "FS", 10*1024*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObject10MbXL - Benchmark XL.GetObject() for object size of 10MB.
 | ||
|  | func BenchmarkGetObject10MbXL(b *testing.B) { | ||
|  | 	benchmarkGetObject(b, "XL", 10*1024*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObject25MbFS - Benchmark FS.GetObject() for object size of 25MB.
 | ||
|  | func BenchmarkGetObject25MbFS(b *testing.B) { | ||
|  | 	benchmarkGetObject(b, "FS", 25*1024*1024) | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObject25MbXL - Benchmark XL.GetObject() for object size of 25MB.
 | ||
|  | func BenchmarkGetObject25MbXL(b *testing.B) { | ||
|  | 	benchmarkGetObject(b, "XL", 25*1024*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObject50MbFS - Benchmark FS.GetObject() for object size of 50MB.
 | ||
|  | func BenchmarkGetObject50MbFS(b *testing.B) { | ||
|  | 	benchmarkGetObject(b, "FS", 50*1024*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObject50MbXL - Benchmark XL.GetObject() for object size of 50MB.
 | ||
|  | func BenchmarkGetObject50MbXL(b *testing.B) { | ||
|  | 	benchmarkGetObject(b, "XL", 50*1024*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // parallel benchmarks for ObjectLayer.GetObject() .
 | ||
|  | 
 | ||
|  | // BenchmarkGetObjectParallelVerySmallFS - Benchmark FS.GetObject() for object size of 10 bytes.
 | ||
|  | func BenchmarkGetObjectParallelVerySmallFS(b *testing.B) { | ||
|  | 	benchmarkGetObjectParallel(b, "FS", 10) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObjectParallelVerySmallXL - Benchmark XL.GetObject() for object size of 10 bytes.
 | ||
|  | func BenchmarkGetObjectParallelVerySmallXL(b *testing.B) { | ||
|  | 	benchmarkGetObjectParallel(b, "XL", 10) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObjectParallel10KbFS - Benchmark FS.GetObject() for object size of 10KB.
 | ||
|  | func BenchmarkGetObjectParallel10KbFS(b *testing.B) { | ||
|  | 	benchmarkGetObjectParallel(b, "FS", 10*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObjectParallel10KbXL - Benchmark XL.GetObject() for object size of 10KB.
 | ||
|  | func BenchmarkGetObjectParallel10KbXL(b *testing.B) { | ||
|  | 	benchmarkGetObjectParallel(b, "XL", 10*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObjectParallel100KbFS - Benchmark FS.GetObject() for object size of 100KB.
 | ||
|  | func BenchmarkGetObjectParallel100KbFS(b *testing.B) { | ||
|  | 	benchmarkGetObjectParallel(b, "FS", 100*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObjectParallel100KbXL - Benchmark XL.GetObject() for object size of 100KB.
 | ||
|  | func BenchmarkGetObjectParallel100KbXL(b *testing.B) { | ||
|  | 	benchmarkGetObjectParallel(b, "XL", 100*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObjectParallel1MbFS - Benchmark FS.GetObject() for object size of 1MB.
 | ||
|  | func BenchmarkGetObjectParallel1MbFS(b *testing.B) { | ||
|  | 	benchmarkGetObjectParallel(b, "FS", 1024*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObjectParallel1MbXL - Benchmark XL.GetObject() for object size of 1MB.
 | ||
|  | func BenchmarkGetObjectParallel1MbXL(b *testing.B) { | ||
|  | 	benchmarkGetObjectParallel(b, "XL", 1024*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObjectParallel5MbFS - Benchmark FS.GetObject() for object size of 5MB.
 | ||
|  | func BenchmarkGetObjectParallel5MbFS(b *testing.B) { | ||
|  | 	benchmarkGetObjectParallel(b, "FS", 5*1024*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObjectParallel5MbXL - Benchmark XL.GetObject() for object size of 5MB.
 | ||
|  | func BenchmarkGetObjectParallel5MbXL(b *testing.B) { | ||
|  | 	benchmarkGetObjectParallel(b, "XL", 5*1024*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObjectParallel10MbFS - Benchmark FS.GetObject() for object size of 10MB.
 | ||
|  | func BenchmarkGetObjectParallel10MbFS(b *testing.B) { | ||
|  | 	benchmarkGetObjectParallel(b, "FS", 10*1024*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObjectParallel10MbXL - Benchmark XL.GetObject() for object size of 10MB.
 | ||
|  | func BenchmarkGetObjectParallel10MbXL(b *testing.B) { | ||
|  | 	benchmarkGetObjectParallel(b, "XL", 10*1024*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObjectParallel25MbFS - Benchmark FS.GetObject() for object size of 25MB.
 | ||
|  | func BenchmarkGetObjectParallel25MbFS(b *testing.B) { | ||
|  | 	benchmarkGetObjectParallel(b, "FS", 25*1024*1024) | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObjectParallel25MbXL - Benchmark XL.GetObject() for object size of 25MB.
 | ||
|  | func BenchmarkGetObjectParallel25MbXL(b *testing.B) { | ||
|  | 	benchmarkGetObjectParallel(b, "XL", 25*1024*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObjectParallel50MbFS - Benchmark FS.GetObject() for object size of 50MB.
 | ||
|  | func BenchmarkGetObjectParallel50MbFS(b *testing.B) { | ||
|  | 	benchmarkGetObjectParallel(b, "FS", 50*1024*1024) | ||
|  | } | ||
|  | 
 | ||
|  | // BenchmarkGetObjectParallel50MbXL - Benchmark XL.GetObject() for object size of 50MB.
 | ||
|  | func BenchmarkGetObjectParallel50MbXL(b *testing.B) { | ||
|  | 	benchmarkGetObjectParallel(b, "XL", 50*1024*1024) | ||
|  | } |