| 
									
										
										
										
											2016-10-20 10:59:48 +08:00
										 |  |  | /* | 
					
						
							| 
									
										
										
										
											2017-01-19 04:24:34 +08:00
										 |  |  |  * Minio Cloud Storage, (C) 2016, 2017 Minio, Inc. | 
					
						
							| 
									
										
										
										
											2016-10-20 10:59:48 +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. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package cmd | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2016-10-27 18:30:52 +08:00
										 |  |  | 	"runtime" | 
					
						
							| 
									
										
										
										
											2016-10-20 10:59:48 +08:00
										 |  |  | 	"sync" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestHouseKeeping(t *testing.T) { | 
					
						
							|  |  |  | 	fsDirs, err := getRandomDisks(8) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("Failed to create disks for storage layer <ERROR> %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer removeRoots(fsDirs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	noSpaceDirs, err := getRandomDisks(8) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("Failed to create disks for storage layer <ERROR> %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer removeRoots(noSpaceDirs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	properStorage := []StorageAPI{} | 
					
						
							| 
									
										
										
										
											2016-10-27 18:30:52 +08:00
										 |  |  | 	for _, fsDir := range fsDirs { | 
					
						
							|  |  |  | 		var sd StorageAPI | 
					
						
							|  |  |  | 		sd, err = newPosix(fsDir) | 
					
						
							| 
									
										
										
										
											2016-10-20 10:59:48 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Failed to create a local disk-based storage layer <ERROR> %v", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		properStorage = append(properStorage, sd) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	noSpaceBackend := []StorageAPI{} | 
					
						
							| 
									
										
										
										
											2016-10-27 18:30:52 +08:00
										 |  |  | 	for _, noSpaceDir := range noSpaceDirs { | 
					
						
							|  |  |  | 		sd, err := newPosix(noSpaceDir) | 
					
						
							| 
									
										
										
										
											2016-10-20 10:59:48 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Failed to create a local disk-based storage layer <ERROR> %v", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		noSpaceBackend = append(noSpaceBackend, sd) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	noSpaceStorage := prepareNErroredDisks(noSpaceBackend, 5, errDiskFull, t) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Create .minio.sys/tmp directory on all disks.
 | 
					
						
							|  |  |  | 	wg := sync.WaitGroup{} | 
					
						
							|  |  |  | 	errs := make([]error, len(properStorage)) | 
					
						
							|  |  |  | 	for i, store := range properStorage { | 
					
						
							|  |  |  | 		wg.Add(1) | 
					
						
							|  |  |  | 		go func(index int, store StorageAPI) { | 
					
						
							|  |  |  | 			defer wg.Done() | 
					
						
							|  |  |  | 			errs[index] = store.MakeVol(minioMetaBucket) | 
					
						
							|  |  |  | 			if errs[index] != nil { | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-11-21 06:25:43 +08:00
										 |  |  | 			errs[index] = store.MakeVol(minioMetaTmpBucket) | 
					
						
							| 
									
										
										
										
											2016-10-20 10:59:48 +08:00
										 |  |  | 			if errs[index] != nil { | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-11-21 06:25:43 +08:00
										 |  |  | 			errs[index] = store.AppendFile(minioMetaTmpBucket, "hello.txt", []byte("hello")) | 
					
						
							| 
									
										
										
										
											2016-10-20 10:59:48 +08:00
										 |  |  | 		}(i, store) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	wg.Wait() | 
					
						
							|  |  |  | 	for i := range errs { | 
					
						
							|  |  |  | 		if errs[i] != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Failed to create .minio.sys/tmp directory on disk %v <ERROR> %v", | 
					
						
							|  |  |  | 				properStorage[i], errs[i]) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	nilDiskStorage := []StorageAPI{nil, nil, nil, nil, nil, nil, nil, nil} | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		store       []StorageAPI | 
					
						
							|  |  |  | 		expectedErr error | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{properStorage, nil}, | 
					
						
							|  |  |  | 		{noSpaceStorage, StorageFull{}}, | 
					
						
							|  |  |  | 		{nilDiskStorage, nil}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for i, test := range testCases { | 
					
						
							|  |  |  | 		actualErr := errorCause(houseKeeping(test.store)) | 
					
						
							|  |  |  | 		if actualErr != test.expectedErr { | 
					
						
							|  |  |  | 			t.Errorf("Test %d - actual error is %#v, expected error was %#v", | 
					
						
							|  |  |  | 				i+1, actualErr, test.expectedErr) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-10-27 18:30:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 04:08:56 +08:00
										 |  |  | // Test getPath() - the path that needs to be passed to newPosix()
 | 
					
						
							| 
									
										
										
										
											2016-10-27 18:30:52 +08:00
										 |  |  | func TestGetPath(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-11-05 03:14:19 +08:00
										 |  |  | 	globalMinioHost = "" | 
					
						
							| 
									
										
										
										
											2016-10-27 18:30:52 +08:00
										 |  |  | 	var testCases []struct { | 
					
						
							| 
									
										
										
										
											2016-10-29 04:08:56 +08:00
										 |  |  | 		epStr string | 
					
						
							|  |  |  | 		path  string | 
					
						
							| 
									
										
										
										
											2016-10-27 18:30:52 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-01-19 04:24:34 +08:00
										 |  |  | 	if runtime.GOOS == globalWindowsOSName { | 
					
						
							| 
									
										
										
										
											2016-10-27 18:30:52 +08:00
										 |  |  | 		testCases = []struct { | 
					
						
							| 
									
										
										
										
											2016-10-29 04:08:56 +08:00
										 |  |  | 			epStr string | 
					
						
							|  |  |  | 			path  string | 
					
						
							| 
									
										
										
										
											2016-10-27 18:30:52 +08:00
										 |  |  | 		}{ | 
					
						
							| 
									
										
										
										
											2016-10-29 04:08:56 +08:00
										 |  |  | 			{"\\export", "\\export"}, | 
					
						
							|  |  |  | 			{"D:\\export", "d:\\export"}, | 
					
						
							|  |  |  | 			{"D:\\", "d:\\"}, | 
					
						
							|  |  |  | 			{"D:", "d:"}, | 
					
						
							|  |  |  | 			{"\\", "\\"}, | 
					
						
							| 
									
										
										
										
											2017-02-10 15:26:44 +08:00
										 |  |  | 			{"http://127.0.0.1/d:/export", "d:/export"}, | 
					
						
							|  |  |  | 			{"https://127.0.0.1/d:/export", "d:/export"}, | 
					
						
							| 
									
										
										
										
											2016-10-27 18:30:52 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		testCases = []struct { | 
					
						
							| 
									
										
										
										
											2016-10-29 04:08:56 +08:00
										 |  |  | 			epStr string | 
					
						
							|  |  |  | 			path  string | 
					
						
							| 
									
										
										
										
											2016-10-27 18:30:52 +08:00
										 |  |  | 		}{ | 
					
						
							| 
									
										
										
										
											2016-10-29 04:08:56 +08:00
										 |  |  | 			{"/export", "/export"}, | 
					
						
							| 
									
										
										
										
											2017-02-10 15:26:44 +08:00
										 |  |  | 			{"http://127.0.0.1/export", "/export"}, | 
					
						
							|  |  |  | 			{"https://127.0.0.1/export", "/export"}, | 
					
						
							| 
									
										
										
										
											2016-10-27 18:30:52 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-10-29 04:08:56 +08:00
										 |  |  | 	testCasesCommon := []struct { | 
					
						
							|  |  |  | 		epStr string | 
					
						
							|  |  |  | 		path  string | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{"export", "export"}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	testCases = append(testCases, testCasesCommon...) | 
					
						
							|  |  |  | 	for i, test := range testCases { | 
					
						
							|  |  |  | 		eps, err := parseStorageEndpoints([]string{test.epStr}) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Errorf("Test %d: %s - %s", i+1, test.epStr, err) | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		path := getPath(eps[0]) | 
					
						
							|  |  |  | 		if path != test.path { | 
					
						
							|  |  |  | 			t.Errorf("Test %d: For endpoing %s, getPath() failed, got: %s, expected: %s,", i+1, test.epStr, path, test.path) | 
					
						
							| 
									
										
										
										
											2016-10-27 18:30:52 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |