You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

616 lines
26 KiB

  1. /*
  2. * Minio Cloud Storage, (C) 2016 Minio, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package cmd
  17. import (
  18. "bytes"
  19. "fmt"
  20. "io"
  21. "os"
  22. "runtime"
  23. "strings"
  24. "testing"
  25. )
  26. // Wrapper for calling GetObject tests for both XL multiple disks and single node setup.
  27. func TestGetObject(t *testing.T) {
  28. ExecObjectLayerTest(t, testGetObject)
  29. }
  30. // ObjectLayer.GetObject is called with series of cases for valid and erroneous inputs and the result is validated.
  31. func testGetObject(obj ObjectLayer, instanceType string, t TestErrHandler) {
  32. // Setup for the tests.
  33. bucketName := getRandomBucketName()
  34. objectName := "test-object"
  35. // create bucket.
  36. err := obj.MakeBucket(bucketName)
  37. // Stop the test if creation of the bucket fails.
  38. if err != nil {
  39. t.Fatalf("%s : %s", instanceType, err.Error())
  40. }
  41. // set of byte data for PutObject.
  42. // object has to be created before running tests for GetObject.
  43. // this is required even to assert the GetObject data,
  44. // since dataInserted === dataFetched back is a primary criteria for any object storage this assertion is critical.
  45. bytesData := []struct {
  46. byteData []byte
  47. }{
  48. {generateBytesData(6 * 1024 * 1024)},
  49. }
  50. // set of inputs for uploading the objects before tests for downloading is done.
  51. putObjectInputs := []struct {
  52. bucketName string
  53. objectName string
  54. contentLength int64
  55. textData []byte
  56. metaData map[string]string
  57. }{
  58. // case - 1.
  59. {bucketName, objectName, int64(len(bytesData[0].byteData)), bytesData[0].byteData, make(map[string]string)},
  60. }
  61. sha256sum := ""
  62. // iterate through the above set of inputs and upkoad the object.
  63. for i, input := range putObjectInputs {
  64. // uploading the object.
  65. _, err = obj.PutObject(input.bucketName, input.objectName, input.contentLength, bytes.NewBuffer(input.textData), input.metaData, sha256sum)
  66. // if object upload fails stop the test.
  67. if err != nil {
  68. t.Fatalf("Put Object case %d: Error uploading object: <ERROR> %v", i+1, err)
  69. }
  70. }
  71. // set of empty buffers used to fill GetObject data.
  72. buffers := []*bytes.Buffer{
  73. new(bytes.Buffer),
  74. new(bytes.Buffer),
  75. }
  76. // test cases with set of inputs
  77. testCases := []struct {
  78. bucketName string
  79. objectName string
  80. startOffset int64
  81. length int64
  82. // data obtained/fetched from GetObject.
  83. getObjectData *bytes.Buffer
  84. // writer which governs the write into the `getObjectData`.
  85. writer io.Writer
  86. // flag indicating whether the test for given ase should pass.
  87. shouldPass bool
  88. // expected Result.
  89. expectedData []byte
  90. err error
  91. }{
  92. // Test case 1-4.
  93. // Cases with invalid bucket names.
  94. {".test", "obj", 0, 0, nil, nil, false, []byte(""), fmt.Errorf("%s", "Bucket name invalid: .test")},
  95. {"------", "obj", 0, 0, nil, nil, false, []byte(""), fmt.Errorf("%s", "Bucket name invalid: ------")},
  96. {"$this-is-not-valid-too", "obj", 0, 0, nil, nil, false,
  97. []byte(""), fmt.Errorf("%s", "Bucket name invalid: $this-is-not-valid-too")},
  98. {"a", "obj", 0, 0, nil, nil, false, []byte(""), fmt.Errorf("%s", "Bucket name invalid: a")},
  99. // Test case - 5.
  100. // Case with invalid object names.
  101. {bucketName, "", 0, 0, nil, nil, false, []byte(""), fmt.Errorf("%s", "Object name invalid: "+bucketName+"#")},
  102. // Test case - 6.
  103. // Valid object and bucket names but non-existent bucket.
  104. // {"abc", "def", 0, 0, nil, nil, false, []byte(""), fmt.Errorf("%s", "Bucket not found: abc")},
  105. // A custom writer is sent as an argument.
  106. // Its designed to return a EOF error after reading `n` bytes, where `n` is the argument when initializing the EOF writer.
  107. // This is to simulate the case of cache not filling up completly, since the EOFWriter doesn't allow the write to complete,
  108. // the cache gets filled up with partial data. The following up test case will read the object completly, tests the
  109. // purging of the cache during the incomplete write.
  110. // Test case - 7.
  111. {bucketName, objectName, 0, int64(len(bytesData[0].byteData)), buffers[0], NewEOFWriter(buffers[0], 100), false, []byte{}, io.EOF},
  112. // Test case with start offset set to 0 and length set to size of the object.
  113. // Fetching the entire object.
  114. // Test case - 8.
  115. {bucketName, objectName, 0, int64(len(bytesData[0].byteData)), buffers[1], buffers[1], true, bytesData[0].byteData, nil},
  116. // Test case with content-range 1 to objectSize .
  117. // Test case - 9.
  118. {bucketName, objectName, 1, int64(len(bytesData[0].byteData) - 1), buffers[1], buffers[1], true, bytesData[0].byteData[1:], nil},
  119. // Test case with content-range 100 to objectSize - 100.
  120. // Test case - 10.
  121. {bucketName, objectName, 100, int64(len(bytesData[0].byteData) - 200), buffers[1], buffers[1], true,
  122. bytesData[0].byteData[100 : len(bytesData[0].byteData)-100], nil},
  123. // Test case with offset greater than the size of the object
  124. // Test case - 11.
  125. {bucketName, objectName, int64(len(bytesData[0].byteData) + 1), int64(len(bytesData[0].byteData)), buffers[0],
  126. NewEOFWriter(buffers[0], 100), false, []byte{},
  127. InvalidRange{int64(len(bytesData[0].byteData) + 1), int64(len(bytesData[0].byteData)), int64(len(bytesData[0].byteData))}},
  128. // Test case with offset greater than the size of the object.
  129. // Test case - 12.
  130. {bucketName, objectName, -1, int64(len(bytesData[0].byteData)), buffers[0], new(bytes.Buffer), false, []byte{}, errUnexpected},
  131. // Test case length parameter is more than the object size.
  132. // Test case - 13.
  133. {bucketName, objectName, 0, int64(len(bytesData[0].byteData) + 1), buffers[1], buffers[1], false, bytesData[0].byteData,
  134. InvalidRange{0, int64(len(bytesData[0].byteData) + 1), int64(len(bytesData[0].byteData))}},
  135. // Test case with `length` parameter set to a negative value.
  136. // Test case - 14.
  137. {bucketName, objectName, 0, int64(-1), buffers[1], buffers[1], false, bytesData[0].byteData, errUnexpected},
  138. // Test case with offset + length > objectSize parameter set to a negative value.
  139. // Test case - 15.
  140. {bucketName, objectName, 2, int64(len(bytesData[0].byteData)), buffers[1], buffers[1], false, bytesData[0].byteData,
  141. InvalidRange{2, int64(len(bytesData[0].byteData)), int64(len(bytesData[0].byteData))}},
  142. // Test case with the writer set to nil.
  143. // Test case - 16.
  144. {bucketName, objectName, 0, int64(len(bytesData[0].byteData)), buffers[1], nil, false, bytesData[0].byteData, errUnexpected},
  145. }
  146. for i, testCase := range testCases {
  147. err = obj.GetObject(testCase.bucketName, testCase.objectName, testCase.startOffset, testCase.length, testCase.writer)
  148. if err != nil && testCase.shouldPass {
  149. t.Errorf("Test %d: %s: Expected to pass, but failed with: <ERROR> %s", i+1, instanceType, err.Error())
  150. }
  151. if err == nil && !testCase.shouldPass {
  152. t.Errorf("Test %d: %s: Expected to fail with <ERROR> \"%s\", but passed instead.", i+1, instanceType, testCase.err.Error())
  153. }
  154. // Failed as expected, but does it fail for the expected reason.
  155. if err != nil && !testCase.shouldPass {
  156. if !strings.Contains(err.Error(), testCase.err.Error()) {
  157. 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())
  158. }
  159. }
  160. // Since there are cases for which GetObject fails, this is
  161. // necessary. Test passes as expected, but the output values
  162. // are verified for correctness here.
  163. if err == nil && testCase.shouldPass {
  164. if !bytes.Equal(testCase.expectedData, testCase.getObjectData.Bytes()) {
  165. t.Errorf("Test %d: %s: Data Mismatch: Expected data and the fetched data from GetObject doesn't match.", i+1, instanceType)
  166. }
  167. // empty the buffer so that it can be used to further cases.
  168. testCase.getObjectData.Reset()
  169. }
  170. }
  171. }
  172. // Wrapper for calling GetObject with permission denied expected
  173. func TestGetObjectPermissionDenied(t *testing.T) {
  174. // Windows doesn't support Chmod under golang
  175. if runtime.GOOS != "windows" {
  176. ExecObjectLayerDiskAlteredTest(t, testGetObjectPermissionDenied)
  177. }
  178. }
  179. // Test GetObject when we are allowed to access some dirs and objects
  180. func testGetObjectPermissionDenied(obj ObjectLayer, instanceType string, disks []string, t *testing.T) {
  181. // Setup for the tests.
  182. bucketName := getRandomBucketName()
  183. // create bucket.
  184. err := obj.MakeBucket(bucketName)
  185. // Stop the test if creation of the bucket fails.
  186. if err != nil {
  187. t.Fatalf("%s : %s", instanceType, err.Error())
  188. }
  189. bytesData := []struct {
  190. byteData []byte
  191. }{
  192. {generateBytesData(6 * 1024 * 1024)},
  193. }
  194. // set of inputs for uploading the objects before tests for downloading is done.
  195. putObjectInputs := []struct {
  196. bucketName string
  197. objectName string
  198. contentLength int64
  199. textData []byte
  200. metaData map[string]string
  201. }{
  202. {bucketName, "test-object1", int64(len(bytesData[0].byteData)), bytesData[0].byteData, make(map[string]string)},
  203. {bucketName, "test-object2", int64(len(bytesData[0].byteData)), bytesData[0].byteData, make(map[string]string)},
  204. {bucketName, "dir/test-object3", int64(len(bytesData[0].byteData)), bytesData[0].byteData, make(map[string]string)},
  205. }
  206. sha256sum := ""
  207. // iterate through the above set of inputs and upkoad the object.
  208. for i, input := range putObjectInputs {
  209. // uploading the object.
  210. _, err = obj.PutObject(input.bucketName, input.objectName, input.contentLength, bytes.NewBuffer(input.textData), input.metaData, sha256sum)
  211. // if object upload fails stop the test.
  212. if err != nil {
  213. t.Fatalf("Put Object case %d: Error uploading object: <ERROR> %v", i+1, err)
  214. }
  215. }
  216. // set of empty buffers used to fill GetObject data.
  217. buffers := []*bytes.Buffer{
  218. new(bytes.Buffer),
  219. }
  220. // test cases with set of inputs
  221. testCases := []struct {
  222. bucketName string
  223. objectName string
  224. chmodPath string
  225. startOffset int64
  226. length int64
  227. // data obtained/fetched from GetObject.
  228. getObjectData *bytes.Buffer
  229. // writer which governs the write into the `getObjectData`.
  230. writer io.Writer
  231. // flag indicating whether the test for given ase should pass.
  232. shouldPass bool
  233. // expected Result.
  234. expectedData []byte
  235. err error
  236. }{
  237. // Test 1 - chmod 000 bucket/test-object1
  238. {bucketName, "test-object1", "test-object1", 0, int64(len(bytesData[0].byteData)), buffers[0], buffers[0], false, bytesData[0].byteData, PrefixAccessDenied{Bucket: bucketName, Object: "test-object1"}},
  239. // Test 2 - chmod 000 bucket/dir/
  240. {bucketName, "dir/test-object2", "dir", 0, int64(len(bytesData[0].byteData)), buffers[0], buffers[0], false, bytesData[0].byteData, PrefixAccessDenied{Bucket: bucketName, Object: "dir/test-object2"}},
  241. // Test 3 - chmod 000 bucket/
  242. {bucketName, "test-object3", "", 0, int64(len(bytesData[0].byteData)), buffers[0], buffers[0], false, bytesData[0].byteData, PrefixAccessDenied{Bucket: bucketName, Object: "test-object3"}},
  243. }
  244. for i, testCase := range testCases {
  245. for _, d := range disks {
  246. err = os.Chmod(d+"/"+testCase.bucketName+"/"+testCase.chmodPath, 0)
  247. if err != nil {
  248. t.Fatalf("Test %d, Unable to chmod: %v", i+1, err)
  249. }
  250. }
  251. err = obj.GetObject(testCase.bucketName, testCase.objectName, testCase.startOffset, testCase.length, testCase.writer)
  252. if err != nil && testCase.shouldPass {
  253. t.Errorf("Test %d: %s: Expected to pass, but failed with: <ERROR> %s", i+1, instanceType, err.Error())
  254. }
  255. if err == nil && !testCase.shouldPass {
  256. t.Errorf("Test %d: %s: Expected to fail with <ERROR> \"%s\", but passed instead.", i+1, instanceType, testCase.err.Error())
  257. }
  258. // Failed as expected, but does it fail for the expected reason.
  259. if err != nil && !testCase.shouldPass {
  260. if !strings.Contains(err.Error(), testCase.err.Error()) {
  261. 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())
  262. }
  263. }
  264. // Since there are cases for which GetObject fails, this is
  265. // necessary. Test passes as expected, but the output values
  266. // are verified for correctness here.
  267. if err == nil && testCase.shouldPass {
  268. if !bytes.Equal(testCase.expectedData, testCase.getObjectData.Bytes()) {
  269. t.Errorf("Test %d: %s: Data Mismatch: Expected data and the fetched data from GetObject doesn't match.", i+1, instanceType)
  270. }
  271. // empty the buffer so that it can be used to further cases.
  272. testCase.getObjectData.Reset()
  273. }
  274. }
  275. }
  276. // Wrapper for calling GetObject tests for both XL multiple disks and single node setup.
  277. func TestGetObjectDiskNotFound(t *testing.T) {
  278. ExecObjectLayerDiskAlteredTest(t, testGetObjectDiskNotFound)
  279. }
  280. // ObjectLayer.GetObject is called with series of cases for valid and erroneous inputs and the result is validated.
  281. // Before the Get Object call XL disks are moved so that the quorum just holds.
  282. func testGetObjectDiskNotFound(obj ObjectLayer, instanceType string, disks []string, t *testing.T) {
  283. // Setup for the tests.
  284. bucketName := getRandomBucketName()
  285. objectName := "test-object"
  286. // create bucket.
  287. err := obj.MakeBucket(bucketName)
  288. // Stop the test if creation of the bucket fails.
  289. if err != nil {
  290. t.Fatalf("%s : %s", instanceType, err.Error())
  291. }
  292. // set of byte data for PutObject.
  293. // object has to be created before running tests for GetObject.
  294. // this is required even to assert the GetObject data,
  295. // since dataInserted === dataFetched back is a primary criteria for any object storage this assertion is critical.
  296. bytesData := []struct {
  297. byteData []byte
  298. }{
  299. {generateBytesData(6 * 1024 * 1024)},
  300. }
  301. // set of inputs for uploading the objects before tests for downloading is done.
  302. putObjectInputs := []struct {
  303. bucketName string
  304. objectName string
  305. contentLength int64
  306. textData []byte
  307. metaData map[string]string
  308. }{
  309. // case - 1.
  310. {bucketName, objectName, int64(len(bytesData[0].byteData)), bytesData[0].byteData, make(map[string]string)},
  311. }
  312. sha256sum := ""
  313. // iterate through the above set of inputs and upkoad the object.
  314. for i, input := range putObjectInputs {
  315. // uploading the object.
  316. _, err = obj.PutObject(input.bucketName, input.objectName, input.contentLength, bytes.NewBuffer(input.textData), input.metaData, sha256sum)
  317. // if object upload fails stop the test.
  318. if err != nil {
  319. t.Fatalf("Put Object case %d: Error uploading object: <ERROR> %v", i+1, err)
  320. }
  321. }
  322. // Take 8 disks down before GetObject is called, one more we loose quorum on 16 disk node.
  323. for _, disk := range disks[:8] {
  324. removeAll(disk)
  325. }
  326. // set of empty buffers used to fill GetObject data.
  327. buffers := []*bytes.Buffer{
  328. new(bytes.Buffer),
  329. new(bytes.Buffer),
  330. }
  331. // test cases with set of inputs
  332. testCases := []struct {
  333. bucketName string
  334. objectName string
  335. startOffset int64
  336. length int64
  337. // data obtained/fetched from GetObject.
  338. getObjectData *bytes.Buffer
  339. // writer which governs the write into the `getObjectData`.
  340. writer io.Writer
  341. // flag indicating whether the test for given ase should pass.
  342. shouldPass bool
  343. // expected Result.
  344. expectedData []byte
  345. err error
  346. }{
  347. // Test case 1-4.
  348. // Cases with invalid bucket names.
  349. {".test", "obj", 0, 0, nil, nil, false, []byte(""), fmt.Errorf("%s", "Bucket name invalid: .test")},
  350. {"------", "obj", 0, 0, nil, nil, false, []byte(""), fmt.Errorf("%s", "Bucket name invalid: ------")},
  351. {"$this-is-not-valid-too", "obj", 0, 0, nil, nil, false,
  352. []byte(""), fmt.Errorf("%s", "Bucket name invalid: $this-is-not-valid-too")},
  353. {"a", "obj", 0, 0, nil, nil, false, []byte(""), fmt.Errorf("%s", "Bucket name invalid: a")},
  354. // Test case - 5.
  355. // Case with invalid object names.
  356. {bucketName, "", 0, 0, nil, nil, false, []byte(""), fmt.Errorf("%s", "Object name invalid: "+bucketName+"#")},
  357. // Test case - 6.
  358. // Valid object and bucket names but non-existent bucket.
  359. // {"abc", "def", 0, 0, nil, nil, false, []byte(""), fmt.Errorf("%s", "Bucket not found: abc")},
  360. // A custom writer is sent as an argument.
  361. // Its designed to return a EOF error after reading `n` bytes, where `n` is the argument when initializing the EOF writer.
  362. // This is to simulate the case of cache not filling up completly, since the EOFWriter doesn't allow the write to complete,
  363. // the cache gets filled up with partial data. The following up test case will read the object completly, tests the
  364. // purging of the cache during the incomplete write.
  365. // Test case - 7.
  366. {bucketName, objectName, 0, int64(len(bytesData[0].byteData)), buffers[0], NewEOFWriter(buffers[0], 100), false, []byte{}, io.EOF},
  367. // Test case with start offset set to 0 and length set to size of the object.
  368. // Fetching the entire object.
  369. // Test case - 8.
  370. {bucketName, objectName, 0, int64(len(bytesData[0].byteData)), buffers[1], buffers[1], true, bytesData[0].byteData, nil},
  371. // Test case with content-range 1 to objectSize .
  372. // Test case - 9.
  373. {bucketName, objectName, 1, int64(len(bytesData[0].byteData) - 1), buffers[1], buffers[1], true, bytesData[0].byteData[1:], nil},
  374. // Test case with content-range 100 to objectSize - 100.
  375. // Test case - 10.
  376. {bucketName, objectName, 100, int64(len(bytesData[0].byteData) - 200), buffers[1], buffers[1], true,
  377. bytesData[0].byteData[100 : len(bytesData[0].byteData)-100], nil},
  378. // Test case with offset greater than the size of the object
  379. // Test case - 11.
  380. {bucketName, objectName, int64(len(bytesData[0].byteData) + 1), int64(len(bytesData[0].byteData)), buffers[0],
  381. NewEOFWriter(buffers[0], 100), false, []byte{},
  382. InvalidRange{int64(len(bytesData[0].byteData) + 1), int64(len(bytesData[0].byteData)), int64(len(bytesData[0].byteData))}},
  383. // Test case with offset greater than the size of the object.
  384. // Test case - 12.
  385. {bucketName, objectName, -1, int64(len(bytesData[0].byteData)), buffers[0], new(bytes.Buffer), false, []byte{}, errUnexpected},
  386. // Test case length parameter is more than the object size.
  387. // Test case - 13.
  388. {bucketName, objectName, 0, int64(len(bytesData[0].byteData) + 1), buffers[1], buffers[1], false, bytesData[0].byteData,
  389. InvalidRange{0, int64(len(bytesData[0].byteData) + 1), int64(len(bytesData[0].byteData))}},
  390. // Test case with `length` parameter set to a negative value.
  391. // Test case - 14.
  392. {bucketName, objectName, 0, int64(-1), buffers[1], buffers[1], false, bytesData[0].byteData, errUnexpected},
  393. // Test case with offset + length > objectSize parameter set to a negative value.
  394. // Test case - 15.
  395. {bucketName, objectName, 2, int64(len(bytesData[0].byteData)), buffers[1], buffers[1], false, bytesData[0].byteData,
  396. InvalidRange{2, int64(len(bytesData[0].byteData)), int64(len(bytesData[0].byteData))}},
  397. // Test case with the writer set to nil.
  398. // Test case - 16.
  399. {bucketName, objectName, 0, int64(len(bytesData[0].byteData)), buffers[1], nil, false, bytesData[0].byteData, errUnexpected},
  400. }
  401. for i, testCase := range testCases {
  402. err = obj.GetObject(testCase.bucketName, testCase.objectName, testCase.startOffset, testCase.length, testCase.writer)
  403. if err != nil && testCase.shouldPass {
  404. t.Errorf("Test %d: %s: Expected to pass, but failed with: <ERROR> %s", i+1, instanceType, err.Error())
  405. }
  406. if err == nil && !testCase.shouldPass {
  407. t.Errorf("Test %d: %s: Expected to fail with <ERROR> \"%s\", but passed instead.", i+1, instanceType, testCase.err.Error())
  408. }
  409. // Failed as expected, but does it fail for the expected reason.
  410. if err != nil && !testCase.shouldPass {
  411. if !strings.Contains(err.Error(), testCase.err.Error()) {
  412. 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())
  413. }
  414. }
  415. // Since there are cases for which GetObject fails, this is
  416. // necessary. Test passes as expected, but the output values
  417. // are verified for correctness here.
  418. if err == nil && testCase.shouldPass {
  419. if !bytes.Equal(testCase.expectedData, testCase.getObjectData.Bytes()) {
  420. t.Errorf("Test %d: %s: Data Mismatch: Expected data and the fetched data from GetObject doesn't match.", i+1, instanceType)
  421. }
  422. // empty the buffer so that it can be used to further cases.
  423. testCase.getObjectData.Reset()
  424. }
  425. }
  426. }
  427. // Benchmarks for ObjectLayer.GetObject().
  428. // The intent is to benchmark GetObject for various sizes ranging from few bytes to 100MB.
  429. // Also each of these Benchmarks are run both XL and FS backends.
  430. // BenchmarkGetObjectVerySmallFS - Benchmark FS.GetObject() for object size of 10 bytes.
  431. func BenchmarkGetObjectVerySmallFS(b *testing.B) {
  432. benchmarkGetObject(b, "FS", 10)
  433. }
  434. // BenchmarkGetObjectVerySmallXL - Benchmark XL.GetObject() for object size of 10 bytes.
  435. func BenchmarkGetObjectVerySmallXL(b *testing.B) {
  436. benchmarkGetObject(b, "XL", 10)
  437. }
  438. // BenchmarkGetObject10KbFS - Benchmark FS.GetObject() for object size of 10KB.
  439. func BenchmarkGetObject10KbFS(b *testing.B) {
  440. benchmarkGetObject(b, "FS", 10*1024)
  441. }
  442. // BenchmarkGetObject10KbXL - Benchmark XL.GetObject() for object size of 10KB.
  443. func BenchmarkGetObject10KbXL(b *testing.B) {
  444. benchmarkGetObject(b, "XL", 10*1024)
  445. }
  446. // BenchmarkGetObject100KbFS - Benchmark FS.GetObject() for object size of 100KB.
  447. func BenchmarkGetObject100KbFS(b *testing.B) {
  448. benchmarkGetObject(b, "FS", 100*1024)
  449. }
  450. // BenchmarkGetObject100KbXL - Benchmark XL.GetObject() for object size of 100KB.
  451. func BenchmarkGetObject100KbXL(b *testing.B) {
  452. benchmarkGetObject(b, "XL", 100*1024)
  453. }
  454. // BenchmarkGetObject1MbFS - Benchmark FS.GetObject() for object size of 1MB.
  455. func BenchmarkGetObject1MbFS(b *testing.B) {
  456. benchmarkGetObject(b, "FS", 1024*1024)
  457. }
  458. // BenchmarkGetObject1MbXL - Benchmark XL.GetObject() for object size of 1MB.
  459. func BenchmarkGetObject1MbXL(b *testing.B) {
  460. benchmarkGetObject(b, "XL", 1024*1024)
  461. }
  462. // BenchmarkGetObject5MbFS - Benchmark FS.GetObject() for object size of 5MB.
  463. func BenchmarkGetObject5MbFS(b *testing.B) {
  464. benchmarkGetObject(b, "FS", 5*1024*1024)
  465. }
  466. // BenchmarkGetObject5MbXL - Benchmark XL.GetObject() for object size of 5MB.
  467. func BenchmarkGetObject5MbXL(b *testing.B) {
  468. benchmarkGetObject(b, "XL", 5*1024*1024)
  469. }
  470. // BenchmarkGetObject10MbFS - Benchmark FS.GetObject() for object size of 10MB.
  471. func BenchmarkGetObject10MbFS(b *testing.B) {
  472. benchmarkGetObject(b, "FS", 10*1024*1024)
  473. }
  474. // BenchmarkGetObject10MbXL - Benchmark XL.GetObject() for object size of 10MB.
  475. func BenchmarkGetObject10MbXL(b *testing.B) {
  476. benchmarkGetObject(b, "XL", 10*1024*1024)
  477. }
  478. // BenchmarkGetObject25MbFS - Benchmark FS.GetObject() for object size of 25MB.
  479. func BenchmarkGetObject25MbFS(b *testing.B) {
  480. benchmarkGetObject(b, "FS", 25*1024*1024)
  481. }
  482. // BenchmarkGetObject25MbXL - Benchmark XL.GetObject() for object size of 25MB.
  483. func BenchmarkGetObject25MbXL(b *testing.B) {
  484. benchmarkGetObject(b, "XL", 25*1024*1024)
  485. }
  486. // BenchmarkGetObject50MbFS - Benchmark FS.GetObject() for object size of 50MB.
  487. func BenchmarkGetObject50MbFS(b *testing.B) {
  488. benchmarkGetObject(b, "FS", 50*1024*1024)
  489. }
  490. // BenchmarkGetObject50MbXL - Benchmark XL.GetObject() for object size of 50MB.
  491. func BenchmarkGetObject50MbXL(b *testing.B) {
  492. benchmarkGetObject(b, "XL", 50*1024*1024)
  493. }
  494. // parallel benchmarks for ObjectLayer.GetObject() .
  495. // BenchmarkGetObjectParallelVerySmallFS - Benchmark FS.GetObject() for object size of 10 bytes.
  496. func BenchmarkGetObjectParallelVerySmallFS(b *testing.B) {
  497. benchmarkGetObjectParallel(b, "FS", 10)
  498. }
  499. // BenchmarkGetObjectParallelVerySmallXL - Benchmark XL.GetObject() for object size of 10 bytes.
  500. func BenchmarkGetObjectParallelVerySmallXL(b *testing.B) {
  501. benchmarkGetObjectParallel(b, "XL", 10)
  502. }
  503. // BenchmarkGetObjectParallel10KbFS - Benchmark FS.GetObject() for object size of 10KB.
  504. func BenchmarkGetObjectParallel10KbFS(b *testing.B) {
  505. benchmarkGetObjectParallel(b, "FS", 10*1024)
  506. }
  507. // BenchmarkGetObjectParallel10KbXL - Benchmark XL.GetObject() for object size of 10KB.
  508. func BenchmarkGetObjectParallel10KbXL(b *testing.B) {
  509. benchmarkGetObjectParallel(b, "XL", 10*1024)
  510. }
  511. // BenchmarkGetObjectParallel100KbFS - Benchmark FS.GetObject() for object size of 100KB.
  512. func BenchmarkGetObjectParallel100KbFS(b *testing.B) {
  513. benchmarkGetObjectParallel(b, "FS", 100*1024)
  514. }
  515. // BenchmarkGetObjectParallel100KbXL - Benchmark XL.GetObject() for object size of 100KB.
  516. func BenchmarkGetObjectParallel100KbXL(b *testing.B) {
  517. benchmarkGetObjectParallel(b, "XL", 100*1024)
  518. }
  519. // BenchmarkGetObjectParallel1MbFS - Benchmark FS.GetObject() for object size of 1MB.
  520. func BenchmarkGetObjectParallel1MbFS(b *testing.B) {
  521. benchmarkGetObjectParallel(b, "FS", 1024*1024)
  522. }
  523. // BenchmarkGetObjectParallel1MbXL - Benchmark XL.GetObject() for object size of 1MB.
  524. func BenchmarkGetObjectParallel1MbXL(b *testing.B) {
  525. benchmarkGetObjectParallel(b, "XL", 1024*1024)
  526. }
  527. // BenchmarkGetObjectParallel5MbFS - Benchmark FS.GetObject() for object size of 5MB.
  528. func BenchmarkGetObjectParallel5MbFS(b *testing.B) {
  529. benchmarkGetObjectParallel(b, "FS", 5*1024*1024)
  530. }
  531. // BenchmarkGetObjectParallel5MbXL - Benchmark XL.GetObject() for object size of 5MB.
  532. func BenchmarkGetObjectParallel5MbXL(b *testing.B) {
  533. benchmarkGetObjectParallel(b, "XL", 5*1024*1024)
  534. }
  535. // BenchmarkGetObjectParallel10MbFS - Benchmark FS.GetObject() for object size of 10MB.
  536. func BenchmarkGetObjectParallel10MbFS(b *testing.B) {
  537. benchmarkGetObjectParallel(b, "FS", 10*1024*1024)
  538. }
  539. // BenchmarkGetObjectParallel10MbXL - Benchmark XL.GetObject() for object size of 10MB.
  540. func BenchmarkGetObjectParallel10MbXL(b *testing.B) {
  541. benchmarkGetObjectParallel(b, "XL", 10*1024*1024)
  542. }
  543. // BenchmarkGetObjectParallel25MbFS - Benchmark FS.GetObject() for object size of 25MB.
  544. func BenchmarkGetObjectParallel25MbFS(b *testing.B) {
  545. benchmarkGetObjectParallel(b, "FS", 25*1024*1024)
  546. }
  547. // BenchmarkGetObjectParallel25MbXL - Benchmark XL.GetObject() for object size of 25MB.
  548. func BenchmarkGetObjectParallel25MbXL(b *testing.B) {
  549. benchmarkGetObjectParallel(b, "XL", 25*1024*1024)
  550. }
  551. // BenchmarkGetObjectParallel50MbFS - Benchmark FS.GetObject() for object size of 50MB.
  552. func BenchmarkGetObjectParallel50MbFS(b *testing.B) {
  553. benchmarkGetObjectParallel(b, "FS", 50*1024*1024)
  554. }
  555. // BenchmarkGetObjectParallel50MbXL - Benchmark XL.GetObject() for object size of 50MB.
  556. func BenchmarkGetObjectParallel50MbXL(b *testing.B) {
  557. benchmarkGetObjectParallel(b, "XL", 50*1024*1024)
  558. }