| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | /* | 
					
						
							| 
									
										
										
										
											2017-01-19 04:24:34 +08:00
										 |  |  |  * Minio Cloud Storage, (C) 2016, 2017 Minio, Inc. | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +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-12-18 05:43:26 +08:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 	"flag" | 
					
						
							|  |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2017-01-17 09:05:00 +08:00
										 |  |  | 	"reflect" | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 	"runtime" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/minio/cli" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestGetListenIPs(t *testing.T) { | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							| 
									
										
										
										
											2016-10-24 14:55:12 +08:00
										 |  |  | 		addr       string | 
					
						
							|  |  |  | 		port       string | 
					
						
							|  |  |  | 		shouldPass bool | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 	}{ | 
					
						
							| 
									
										
										
										
											2017-02-10 15:26:44 +08:00
										 |  |  | 		{"127.0.0.1", "9000", true}, | 
					
						
							| 
									
										
										
										
											2016-10-24 14:55:12 +08:00
										 |  |  | 		{"", "9000", true}, | 
					
						
							|  |  |  | 		{"", "", false}, | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	for _, test := range testCases { | 
					
						
							| 
									
										
										
										
											2016-10-24 14:55:12 +08:00
										 |  |  | 		var addr string | 
					
						
							|  |  |  | 		// Please keep this we need to do this because
 | 
					
						
							|  |  |  | 		// of odd https://play.golang.org/p/4dMPtM6Wdd
 | 
					
						
							|  |  |  | 		// implementation issue.
 | 
					
						
							|  |  |  | 		if test.port != "" { | 
					
						
							|  |  |  | 			addr = test.addr + ":" + test.port | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-11-10 02:50:14 +08:00
										 |  |  | 		hosts, port, err := getListenIPs(addr) | 
					
						
							| 
									
										
										
										
											2016-10-24 14:55:12 +08:00
										 |  |  | 		if !test.shouldPass && err == nil { | 
					
						
							|  |  |  | 			t.Fatalf("Test should fail but succeeded %s", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if test.shouldPass && err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Test should succeed but failed %s", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if test.shouldPass { | 
					
						
							|  |  |  | 			if port != test.port { | 
					
						
							|  |  |  | 				t.Errorf("Test expected %s, got %s", test.port, port) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if len(hosts) == 0 { | 
					
						
							|  |  |  | 				t.Errorf("Test unexpected value hosts cannot be empty %#v", test) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-12 05:59:51 +08:00
										 |  |  | // Tests get host port.
 | 
					
						
							|  |  |  | func TestGetHostPort(t *testing.T) { | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		addr string | 
					
						
							|  |  |  | 		err  error | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		// Test 1 - successful.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			addr: ":" + getFreePort(), | 
					
						
							|  |  |  | 			err:  nil, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Test 2 port empty.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			addr: ":0", | 
					
						
							|  |  |  | 			err:  errEmptyPort, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Test 3 port empty.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			addr: ":", | 
					
						
							|  |  |  | 			err:  errEmptyPort, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Test 4 invalid port.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			addr: "linux:linux", | 
					
						
							|  |  |  | 			err:  errors.New("strconv.ParseInt: parsing \"linux\": invalid syntax"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Test 5 port not present.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			addr: "hostname", | 
					
						
							|  |  |  | 			err:  errors.New("missing port in address hostname"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Validate all tests.
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		_, _, err := getHostPort(testCase.addr) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			if err.Error() != testCase.err.Error() { | 
					
						
							|  |  |  | 				t.Fatalf("Test %d: Error: %s", i+1, err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Tests finalize api endpoints.
 | 
					
						
							| 
									
										
										
										
											2017-01-11 08:43:48 +08:00
										 |  |  | func TestFinalizeAPIEndpoints(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		addr string | 
					
						
							|  |  |  | 	}{ | 
					
						
							| 
									
										
										
										
											2017-01-12 05:59:51 +08:00
										 |  |  | 		{":80"}, | 
					
						
							|  |  |  | 		{":80"}, | 
					
						
							| 
									
										
										
										
											2017-02-10 15:26:44 +08:00
										 |  |  | 		{"127.0.0.1:80"}, | 
					
						
							|  |  |  | 		{"127.0.0.1:80"}, | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, test := range testCases { | 
					
						
							| 
									
										
										
										
											2017-02-04 14:53:30 +08:00
										 |  |  | 		endPoints, err := finalizeAPIEndpoints(test.addr) | 
					
						
							| 
									
										
										
										
											2017-01-12 05:59:51 +08:00
										 |  |  | 		if err != nil && len(endPoints) <= 0 { | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 			t.Errorf("Test case %d returned with no API end points for %s", | 
					
						
							|  |  |  | 				i+1, test.addr) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Tests all the expected input disks for function checkSufficientDisks.
 | 
					
						
							|  |  |  | func TestCheckSufficientDisks(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-10-19 03:49:24 +08:00
										 |  |  | 	var xlDisks []string | 
					
						
							| 
									
										
										
										
											2017-01-19 04:24:34 +08:00
										 |  |  | 	if runtime.GOOS == globalWindowsOSName { | 
					
						
							| 
									
										
										
										
											2016-10-19 03:49:24 +08:00
										 |  |  | 		xlDisks = []string{ | 
					
						
							|  |  |  | 			"C:\\mnt\\backend1", | 
					
						
							|  |  |  | 			"C:\\mnt\\backend2", | 
					
						
							|  |  |  | 			"C:\\mnt\\backend3", | 
					
						
							|  |  |  | 			"C:\\mnt\\backend4", | 
					
						
							|  |  |  | 			"C:\\mnt\\backend5", | 
					
						
							|  |  |  | 			"C:\\mnt\\backend6", | 
					
						
							|  |  |  | 			"C:\\mnt\\backend7", | 
					
						
							|  |  |  | 			"C:\\mnt\\backend8", | 
					
						
							|  |  |  | 			"C:\\mnt\\backend9", | 
					
						
							|  |  |  | 			"C:\\mnt\\backend10", | 
					
						
							|  |  |  | 			"C:\\mnt\\backend11", | 
					
						
							|  |  |  | 			"C:\\mnt\\backend12", | 
					
						
							|  |  |  | 			"C:\\mnt\\backend13", | 
					
						
							|  |  |  | 			"C:\\mnt\\backend14", | 
					
						
							|  |  |  | 			"C:\\mnt\\backend15", | 
					
						
							|  |  |  | 			"C:\\mnt\\backend16", | 
					
						
							|  |  |  | 			"C:\\mnt\\backend17", | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		xlDisks = []string{ | 
					
						
							|  |  |  | 			"/mnt/backend1", | 
					
						
							|  |  |  | 			"/mnt/backend2", | 
					
						
							|  |  |  | 			"/mnt/backend3", | 
					
						
							|  |  |  | 			"/mnt/backend4", | 
					
						
							|  |  |  | 			"/mnt/backend5", | 
					
						
							|  |  |  | 			"/mnt/backend6", | 
					
						
							|  |  |  | 			"/mnt/backend7", | 
					
						
							|  |  |  | 			"/mnt/backend8", | 
					
						
							|  |  |  | 			"/mnt/backend9", | 
					
						
							|  |  |  | 			"/mnt/backend10", | 
					
						
							|  |  |  | 			"/mnt/backend11", | 
					
						
							|  |  |  | 			"/mnt/backend12", | 
					
						
							|  |  |  | 			"/mnt/backend13", | 
					
						
							|  |  |  | 			"/mnt/backend14", | 
					
						
							|  |  |  | 			"/mnt/backend15", | 
					
						
							|  |  |  | 			"/mnt/backend16", | 
					
						
							|  |  |  | 			"/mnt/backend17", | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// List of test cases fo sufficient disk verification.
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		disks       []string | 
					
						
							|  |  |  | 		expectedErr error | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		// Even number of disks '6'.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			xlDisks[0:6], | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Even number of disks '12'.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			xlDisks[0:12], | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Even number of disks '16'.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			xlDisks[0:16], | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Larger than maximum number of disks > 16.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2016-10-19 03:49:24 +08:00
										 |  |  | 			xlDisks, | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 			errXLMaxDisks, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Lesser than minimum number of disks < 6.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			xlDisks[0:3], | 
					
						
							|  |  |  | 			errXLMinDisks, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Odd number of disks, not divisible by '2'.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			append(xlDisks[0:10], xlDisks[11]), | 
					
						
							|  |  |  | 			errXLNumDisks, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Validates different variations of input disks.
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							| 
									
										
										
										
											2016-10-27 18:30:52 +08:00
										 |  |  | 		endpoints, err := parseStorageEndpoints(testCase.disks) | 
					
						
							| 
									
										
										
										
											2016-10-19 03:49:24 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Unexpected error %s", err) | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-10-19 03:49:24 +08:00
										 |  |  | 		if checkSufficientDisks(endpoints) != testCase.expectedErr { | 
					
						
							|  |  |  | 			t.Errorf("Test %d expected to pass for disks %s", i+1, testCase.disks) | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-17 09:05:00 +08:00
										 |  |  | // Tests initializing new object layer.
 | 
					
						
							|  |  |  | func TestNewObjectLayer(t *testing.T) { | 
					
						
							|  |  |  | 	// Tests for FS object layer.
 | 
					
						
							|  |  |  | 	nDisks := 1 | 
					
						
							|  |  |  | 	disks, err := getRandomDisks(nDisks) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal("Failed to create disks for the backend") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer removeRoots(disks) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	endpoints, err := parseStorageEndpoints(disks) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal("Unexpected parse error", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	obj, err := newObjectLayer(serverCmdConfig{ | 
					
						
							|  |  |  | 		serverAddr: ":9000", | 
					
						
							|  |  |  | 		endpoints:  endpoints, | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal("Unexpected object layer initialization error", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	_, ok := obj.(*fsObjects) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		t.Fatal("Unexpected object layer detected", reflect.TypeOf(obj)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Tests for XL object layer initialization.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Create temporary backend for the test server.
 | 
					
						
							|  |  |  | 	nDisks = 16 | 
					
						
							|  |  |  | 	disks, err = getRandomDisks(nDisks) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal("Failed to create disks for the backend") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer removeRoots(disks) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	endpoints, err = parseStorageEndpoints(disks) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal("Unexpected parse error", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	obj, err = newObjectLayer(serverCmdConfig{ | 
					
						
							|  |  |  | 		serverAddr: ":9000", | 
					
						
							|  |  |  | 		endpoints:  endpoints, | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal("Unexpected object layer initialization error", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_, ok = obj.(*xlObjects) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		t.Fatal("Unexpected object layer detected", reflect.TypeOf(obj)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Tests parsing various types of input endpoints and paths.
 | 
					
						
							| 
									
										
										
										
											2016-11-05 03:14:19 +08:00
										 |  |  | func TestParseStorageEndpoints(t *testing.T) { | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		globalMinioHost string | 
					
						
							|  |  |  | 		host            string | 
					
						
							|  |  |  | 		expectedErr     error | 
					
						
							|  |  |  | 	}{ | 
					
						
							| 
									
										
										
										
											2017-02-10 15:26:44 +08:00
										 |  |  | 		{"", "http://127.0.0.1/export", nil}, | 
					
						
							| 
									
										
										
										
											2016-12-18 05:43:26 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			"testhost", | 
					
						
							| 
									
										
										
										
											2017-02-10 15:26:44 +08:00
										 |  |  | 			"http://127.0.0.1/export", | 
					
						
							|  |  |  | 			errors.New("Invalid Argument 127.0.0.1, port mandatory when --address <host>:<port> is used"), | 
					
						
							| 
									
										
										
										
											2016-12-18 05:43:26 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"", | 
					
						
							| 
									
										
										
										
											2017-02-10 15:26:44 +08:00
										 |  |  | 			"http://127.0.0.1:9000/export", | 
					
						
							|  |  |  | 			errors.New("Invalid Argument 127.0.0.1:9000, port configurable using --address :<port>"), | 
					
						
							| 
									
										
										
										
											2016-12-18 05:43:26 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2017-02-10 15:26:44 +08:00
										 |  |  | 		{"testhost", "http://127.0.0.1:9000/export", nil}, | 
					
						
							| 
									
										
										
										
											2016-11-05 03:14:19 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	for i, test := range testCases { | 
					
						
							|  |  |  | 		globalMinioHost = test.globalMinioHost | 
					
						
							|  |  |  | 		_, err := parseStorageEndpoints([]string{test.host}) | 
					
						
							| 
									
										
										
										
											2016-12-18 05:43:26 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			if err.Error() != test.expectedErr.Error() { | 
					
						
							|  |  |  | 				t.Errorf("Test %d : got %v, expected %v", i+1, err, test.expectedErr) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-11-05 03:14:19 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Should be reset back to "" so that we don't affect other tests.
 | 
					
						
							|  |  |  | 	globalMinioHost = "" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-15 12:42:19 +08:00
										 |  |  | // Test check endpoints syntax function for syntax verification
 | 
					
						
							|  |  |  | // across various scenarios of inputs.
 | 
					
						
							| 
									
										
										
										
											2016-10-28 23:45:32 +08:00
										 |  |  | func TestCheckEndpointsSyntax(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-12-18 03:00:16 +08:00
										 |  |  | 	successCases := []string{ | 
					
						
							| 
									
										
										
										
											2016-10-28 23:45:32 +08:00
										 |  |  | 		"export", | 
					
						
							| 
									
										
										
										
											2016-12-18 03:00:16 +08:00
										 |  |  | 		"/export", | 
					
						
							| 
									
										
										
										
											2017-02-10 15:26:44 +08:00
										 |  |  | 		"http://127.0.0.1/export", | 
					
						
							|  |  |  | 		"https://127.0.0.1/export", | 
					
						
							| 
									
										
										
										
											2016-10-28 23:45:32 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-12-18 03:00:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	failureCases := []string{ | 
					
						
							|  |  |  | 		"/", | 
					
						
							| 
									
										
										
										
											2017-02-10 15:26:44 +08:00
										 |  |  | 		"http://127.0.0.1", | 
					
						
							|  |  |  | 		"http://127.0.0.1/", | 
					
						
							|  |  |  | 		"ftp://127.0.0.1/export", | 
					
						
							| 
									
										
										
										
											2016-12-18 03:00:16 +08:00
										 |  |  | 		"server:/export", | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-19 04:24:34 +08:00
										 |  |  | 	if runtime.GOOS == globalWindowsOSName { | 
					
						
							| 
									
										
										
										
											2016-12-18 03:00:16 +08:00
										 |  |  | 		successCases = append(successCases, | 
					
						
							|  |  |  | 			`\export`, | 
					
						
							|  |  |  | 			`D:\export`, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		failureCases = append(failureCases, | 
					
						
							|  |  |  | 			"D:", | 
					
						
							|  |  |  | 			`D:\`, | 
					
						
							|  |  |  | 			`\`, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, disk := range successCases { | 
					
						
							| 
									
										
										
										
											2016-10-28 23:45:32 +08:00
										 |  |  | 		eps, err := parseStorageEndpoints([]string{disk}) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2016-12-15 12:42:19 +08:00
										 |  |  | 			t.Fatalf("Unable to parse %s, error %s", disk, err) | 
					
						
							| 
									
										
										
										
											2016-10-28 23:45:32 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-12-15 12:42:19 +08:00
										 |  |  | 		if err = checkEndpointsSyntax(eps, []string{disk}); err != nil { | 
					
						
							| 
									
										
										
										
											2016-12-18 03:00:16 +08:00
										 |  |  | 			t.Errorf("expected: <nil>, got: %s", err) | 
					
						
							| 
									
										
										
										
											2016-12-15 12:42:19 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-12-18 03:00:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for _, disk := range failureCases { | 
					
						
							|  |  |  | 		eps, err := parseStorageEndpoints([]string{disk}) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Unable to parse %s, error %s", disk, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if err = checkEndpointsSyntax(eps, []string{disk}); err == nil { | 
					
						
							|  |  |  | 			t.Errorf("expected: <error>, got: <nil>") | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-10-28 23:45:32 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-15 12:42:19 +08:00
										 |  |  | // Tests check server syntax.
 | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | func TestCheckServerSyntax(t *testing.T) { | 
					
						
							|  |  |  | 	app := cli.NewApp() | 
					
						
							|  |  |  | 	app.Commands = []cli.Command{serverCmd} | 
					
						
							|  |  |  | 	serverFlagSet := flag.NewFlagSet("server", 0) | 
					
						
							| 
									
										
										
										
											2016-12-15 12:42:19 +08:00
										 |  |  | 	serverFlagSet.String("address", ":9000", "") | 
					
						
							| 
									
										
										
										
											2017-02-16 10:05:55 +08:00
										 |  |  | 	ctx := cli.NewContext(app, serverFlagSet, nil) | 
					
						
							| 
									
										
										
										
											2016-12-15 12:42:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 	disksGen := func(n int) []string { | 
					
						
							| 
									
										
										
										
											2016-10-06 03:48:07 +08:00
										 |  |  | 		disks, err := getRandomDisks(n) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Unable to initialie disks %s", err) | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		return disks | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	testCases := [][]string{ | 
					
						
							|  |  |  | 		disksGen(1), | 
					
						
							|  |  |  | 		disksGen(4), | 
					
						
							|  |  |  | 		disksGen(8), | 
					
						
							|  |  |  | 		disksGen(16), | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-12-15 12:42:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 03:48:07 +08:00
										 |  |  | 	for i, disks := range testCases { | 
					
						
							|  |  |  | 		err := serverFlagSet.Parse(disks) | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2016-10-06 03:48:07 +08:00
										 |  |  | 			t.Errorf("Test %d failed to parse arguments %s", i+1, disks) | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-10-06 03:48:07 +08:00
										 |  |  | 		defer removeRoots(disks) | 
					
						
							| 
									
										
										
										
											2016-12-15 12:42:19 +08:00
										 |  |  | 		checkServerSyntax(ctx) | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestIsDistributedSetup(t *testing.T) { | 
					
						
							|  |  |  | 	var testCases []struct { | 
					
						
							|  |  |  | 		disks  []string | 
					
						
							|  |  |  | 		result bool | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-01-19 04:24:34 +08:00
										 |  |  | 	if runtime.GOOS == globalWindowsOSName { | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 		testCases = []struct { | 
					
						
							|  |  |  | 			disks  []string | 
					
						
							|  |  |  | 			result bool | 
					
						
							|  |  |  | 		}{ | 
					
						
							| 
									
										
										
										
											2016-11-05 03:14:19 +08:00
										 |  |  | 			{[]string{`http://4.4.4.4/c:\mnt\disk1`, `http://4.4.4.4/c:\mnt\disk2`}, true}, | 
					
						
							|  |  |  | 			{[]string{`http://4.4.4.4/c:\mnt\disk1`, `http://127.0.0.1/c:\mnt\disk2`}, true}, | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 			{[]string{`c:\mnt\disk1`, `c:\mnt\disk2`}, false}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		testCases = []struct { | 
					
						
							|  |  |  | 			disks  []string | 
					
						
							|  |  |  | 			result bool | 
					
						
							|  |  |  | 		}{ | 
					
						
							| 
									
										
										
										
											2016-11-05 03:14:19 +08:00
										 |  |  | 			{[]string{"http://4.4.4.4/mnt/disk1", "http://4.4.4.4/mnt/disk2"}, true}, | 
					
						
							|  |  |  | 			{[]string{"http://4.4.4.4/mnt/disk1", "http://127.0.0.1/mnt/disk2"}, true}, | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 			{[]string{"/mnt/disk1", "/mnt/disk2"}, false}, | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-11-05 03:14:19 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	for i, test := range testCases { | 
					
						
							|  |  |  | 		endpoints, err := parseStorageEndpoints(test.disks) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Test %d: Unexpected error: %s", i+1, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		res := isDistributedSetup(endpoints) | 
					
						
							|  |  |  | 		if res != test.result { | 
					
						
							|  |  |  | 			t.Errorf("Test %d: expected result %t but received %t", i+1, test.result, res) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-05 03:14:19 +08:00
										 |  |  | 	// Test cases when globalMinioHost is set
 | 
					
						
							|  |  |  | 	globalMinioHost = "testhost" | 
					
						
							|  |  |  | 	testCases = []struct { | 
					
						
							|  |  |  | 		disks  []string | 
					
						
							|  |  |  | 		result bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{[]string{"http://127.0.0.1:9001/mnt/disk1", "http://127.0.0.1:9002/mnt/disk2", "http://127.0.0.1:9003/mnt/disk3", "http://127.0.0.1:9004/mnt/disk4"}, true}, | 
					
						
							|  |  |  | 		{[]string{"/mnt/disk1", "/mnt/disk2"}, false}, | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-11-05 03:14:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 	for i, test := range testCases { | 
					
						
							| 
									
										
										
										
											2016-10-27 18:30:52 +08:00
										 |  |  | 		endpoints, err := parseStorageEndpoints(test.disks) | 
					
						
							| 
									
										
										
										
											2016-10-19 03:49:24 +08:00
										 |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2016-11-05 03:14:19 +08:00
										 |  |  | 			t.Fatalf("Test %d: Unexpected error: %s", i+1, err) | 
					
						
							| 
									
										
										
										
											2016-10-19 03:49:24 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		res := isDistributedSetup(endpoints) | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 		if res != test.result { | 
					
						
							|  |  |  | 			t.Errorf("Test %d: expected result %t but received %t", i+1, test.result, res) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-11-05 03:14:19 +08:00
										 |  |  | 	// Reset so that we don't affect other tests.
 | 
					
						
							|  |  |  | 	globalMinioHost = "" | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-08 04:51:43 +08:00
										 |  |  | // Tests init server.
 | 
					
						
							|  |  |  | func TestInitServer(t *testing.T) { | 
					
						
							|  |  |  | 	app := cli.NewApp() | 
					
						
							|  |  |  | 	app.Commands = []cli.Command{serverCmd} | 
					
						
							|  |  |  | 	serverFlagSet := flag.NewFlagSet("server", 0) | 
					
						
							|  |  |  | 	serverFlagSet.String("address", ":9000", "") | 
					
						
							| 
									
										
										
										
											2017-02-16 10:05:55 +08:00
										 |  |  | 	ctx := cli.NewContext(app, serverFlagSet, nil) | 
					
						
							| 
									
										
										
										
											2017-02-08 04:51:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-19 04:24:34 +08:00
										 |  |  | 	root, err := newTestConfig(globalMinioDefaultRegion) | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal("Failed to set up test config") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer removeAll(root) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		envVar string | 
					
						
							|  |  |  | 		val    string | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{"MINIO_ACCESS_KEY", "abcd1"}, | 
					
						
							|  |  |  | 		{"MINIO_SECRET_KEY", "abcd12345"}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for i, test := range testCases { | 
					
						
							|  |  |  | 		tErr := os.Setenv(test.envVar, test.val) | 
					
						
							|  |  |  | 		if tErr != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Test %d failed with %v", i+1, tErr) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		initServerConfig(ctx) | 
					
						
							| 
									
										
										
										
											2017-02-08 04:51:43 +08:00
										 |  |  | 		os.Unsetenv(test.envVar) | 
					
						
							| 
									
										
										
										
											2016-09-29 02:19:07 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-12-14 03:18:31 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Tests isAnyEndpointLocal function with inputs such that it returns true and false respectively.
 | 
					
						
							|  |  |  | func TestIsAnyEndpointLocal(t *testing.T) { | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		disks  []string | 
					
						
							|  |  |  | 		result bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			disks: []string{"http://4.4.4.4/mnt/disk1", | 
					
						
							|  |  |  | 				"http://4.4.4.4/mnt/disk1"}, | 
					
						
							|  |  |  | 			result: false, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2017-02-10 15:26:44 +08:00
										 |  |  | 			disks: []string{"http://127.0.0.1/mnt/disk1", | 
					
						
							|  |  |  | 				"http://127.0.0.1/mnt/disk1"}, | 
					
						
							| 
									
										
										
										
											2016-12-14 03:18:31 +08:00
										 |  |  | 			result: true, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for i, test := range testCases { | 
					
						
							|  |  |  | 		endpoints, err := parseStorageEndpoints(test.disks) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Test %d - Failed to parse storage endpoints %v", i+1, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		actual := isAnyEndpointLocal(endpoints) | 
					
						
							|  |  |  | 		if actual != test.result { | 
					
						
							|  |  |  | 			t.Errorf("Test %d - Expected %v but received %v", i+1, test.result, actual) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |