| 
									
										
										
										
											2021-04-19 03:41:13 +08:00
										 |  |  | // Copyright (c) 2015-2021 MinIO, Inc.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This file is part of MinIO Object Storage stack
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This program is free software: you can redistribute it and/or modify
 | 
					
						
							|  |  |  | // it under the terms of the GNU Affero General Public License as published by
 | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or
 | 
					
						
							|  |  |  | // (at your option) any later version.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					
						
							|  |  |  | // GNU Affero General Public License for more details.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU Affero General Public License
 | 
					
						
							|  |  |  | // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | package cmd | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2017-05-17 12:13:29 +08:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"net" | 
					
						
							| 
									
										
										
										
											2017-04-13 00:22:35 +08:00
										 |  |  | 	"reflect" | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 	"runtime" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-15 00:38:05 +08:00
										 |  |  | 	"github.com/minio/minio-go/v7/pkg/set" | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestMustSplitHostPort(t *testing.T) { | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		hostPort     string | 
					
						
							|  |  |  | 		expectedHost string | 
					
						
							|  |  |  | 		expectedPort string | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{":54321", "", "54321"}, | 
					
						
							|  |  |  | 		{"server:54321", "server", "54321"}, | 
					
						
							|  |  |  | 		{":0", "", "0"}, | 
					
						
							| 
									
										
										
										
											2019-11-27 03:42:10 +08:00
										 |  |  | 		{"server:https", "server", "443"}, | 
					
						
							|  |  |  | 		{"server:http", "server", "80"}, | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, testCase := range testCases { | 
					
						
							|  |  |  | 		host, port := mustSplitHostPort(testCase.hostPort) | 
					
						
							|  |  |  | 		if testCase.expectedHost != host { | 
					
						
							|  |  |  | 			t.Fatalf("host: expected = %v, got = %v", testCase.expectedHost, host) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if testCase.expectedPort != port { | 
					
						
							|  |  |  | 			t.Fatalf("port: expected = %v, got = %v", testCase.expectedPort, port) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-13 00:22:35 +08:00
										 |  |  | func TestSortIPs(t *testing.T) { | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		ipList       []string | 
					
						
							|  |  |  | 		sortedIPList []string | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		// Default case of two ips one with higher octet moves
 | 
					
						
							|  |  |  | 		// to the beginning of the list.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			ipList:       []string{"127.0.0.1", "10.0.0.13"}, | 
					
						
							|  |  |  | 			sortedIPList: []string{"10.0.0.13", "127.0.0.1"}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// With multiple types of octet, chooses a higher octet.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			ipList:       []string{"127.0.0.1", "172.0.21.1", "192.168.1.106"}, | 
					
						
							|  |  |  | 			sortedIPList: []string{"192.168.1.106", "172.0.21.1", "127.0.0.1"}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// With different ip along with localhost.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			ipList:       []string{"127.0.0.1", "192.168.1.106"}, | 
					
						
							|  |  |  | 			sortedIPList: []string{"192.168.1.106", "127.0.0.1"}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// With a list of only one element nothing to sort.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			ipList:       []string{"hostname"}, | 
					
						
							|  |  |  | 			sortedIPList: []string{"hostname"}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// With a list of only one element nothing to sort.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			ipList:       []string{"127.0.0.1"}, | 
					
						
							|  |  |  | 			sortedIPList: []string{"127.0.0.1"}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Non parsable ip is assumed to be hostame and gets preserved
 | 
					
						
							|  |  |  | 		// as the left most elements, regardless of IP based sorting.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			ipList:       []string{"hostname", "127.0.0.1", "192.168.1.106"}, | 
					
						
							|  |  |  | 			sortedIPList: []string{"hostname", "192.168.1.106", "127.0.0.1"}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Non parsable ip is assumed to be hostname, with a mixed input of ip and hostname.
 | 
					
						
							|  |  |  | 		// gets preserved and moved into left most elements, regardless of
 | 
					
						
							|  |  |  | 		// IP based sorting.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			ipList:       []string{"hostname1", "10.0.0.13", "hostname2", "127.0.0.1", "192.168.1.106"}, | 
					
						
							|  |  |  | 			sortedIPList: []string{"hostname1", "hostname2", "192.168.1.106", "10.0.0.13", "127.0.0.1"}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// With same higher octets, preferentially move the localhost.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			ipList:       []string{"127.0.0.1", "10.0.0.1", "192.168.0.1"}, | 
					
						
							|  |  |  | 			sortedIPList: []string{"10.0.0.1", "192.168.0.1", "127.0.0.1"}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		gotIPList := sortIPs(testCase.ipList) | 
					
						
							|  |  |  | 		if !reflect.DeepEqual(testCase.sortedIPList, gotIPList) { | 
					
						
							|  |  |  | 			t.Errorf("Test %d: Expected %s, got %s", i+1, testCase.sortedIPList, gotIPList) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | func TestMustGetLocalIP4(t *testing.T) { | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		expectedIPList set.StringSet | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{set.CreateStringSet("127.0.0.1")}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, testCase := range testCases { | 
					
						
							|  |  |  | 		ipList := mustGetLocalIP4() | 
					
						
							|  |  |  | 		if testCase.expectedIPList != nil && testCase.expectedIPList.Intersection(ipList).IsEmpty() { | 
					
						
							|  |  |  | 			t.Fatalf("host: expected = %v, got = %v", testCase.expectedIPList, ipList) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestGetHostIP(t *testing.T) { | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		host           string | 
					
						
							|  |  |  | 		expectedIPList set.StringSet | 
					
						
							|  |  |  | 		expectedErr    error | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{"localhost", set.CreateStringSet("127.0.0.1"), nil}, | 
					
						
							|  |  |  | 		{"example.org", set.CreateStringSet("93.184.216.34"), nil}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, testCase := range testCases { | 
					
						
							| 
									
										
										
										
											2018-12-14 15:37:46 +08:00
										 |  |  | 		ipList, err := getHostIP(testCase.host) | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 		if testCase.expectedErr == nil { | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				t.Fatalf("error: expected = <nil>, got = %v", err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else if err == nil { | 
					
						
							|  |  |  | 			t.Fatalf("error: expected = %v, got = <nil>", testCase.expectedErr) | 
					
						
							|  |  |  | 		} else if testCase.expectedErr.Error() != err.Error() { | 
					
						
							|  |  |  | 			t.Fatalf("error: expected = %v, got = %v", testCase.expectedErr, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if testCase.expectedIPList != nil && testCase.expectedIPList.Intersection(ipList).IsEmpty() { | 
					
						
							|  |  |  | 			t.Fatalf("host: expected = %v, got = %v", testCase.expectedIPList, ipList) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Tests finalize api endpoints.
 | 
					
						
							|  |  |  | func TestGetAPIEndpoints(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2018-12-14 15:37:46 +08:00
										 |  |  | 	host, port := globalMinioHost, globalMinioAddr | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		globalMinioHost, globalMinioAddr = host, port | 
					
						
							|  |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 	testCases := []struct { | 
					
						
							| 
									
										
										
										
											2018-12-14 15:37:46 +08:00
										 |  |  | 		host, port     string | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 		expectedResult string | 
					
						
							|  |  |  | 	}{ | 
					
						
							| 
									
										
										
										
											2018-12-14 15:37:46 +08:00
										 |  |  | 		{"", "80", "http://127.0.0.1:80"}, | 
					
						
							|  |  |  | 		{"127.0.0.1", "80", "http://127.0.0.1:80"}, | 
					
						
							|  |  |  | 		{"localhost", "80", "http://localhost:80"}, | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							| 
									
										
										
										
											2018-12-14 15:37:46 +08:00
										 |  |  | 		globalMinioHost, globalMinioPort = testCase.host, testCase.port | 
					
						
							|  |  |  | 		apiEndpoints := getAPIEndpoints() | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 		apiEndpointSet := set.CreateStringSet(apiEndpoints...) | 
					
						
							|  |  |  | 		if !apiEndpointSet.Contains(testCase.expectedResult) { | 
					
						
							|  |  |  | 			t.Fatalf("test %d: expected: Found, got: Not Found", i+1) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-10 17:14:42 +08:00
										 |  |  | // Ask the kernel for a free open port.
 | 
					
						
							|  |  |  | func getFreePort() string { | 
					
						
							|  |  |  | 	addr, err := net.ResolveTCPAddr("tcp", "localhost:0") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		panic(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	l, err := net.ListenTCP("tcp", addr) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		panic(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer l.Close() | 
					
						
							|  |  |  | 	return fmt.Sprintf("%d", l.Addr().(*net.TCPAddr).Port) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | // Tests for port availability logic written for server startup sequence.
 | 
					
						
							|  |  |  | func TestCheckPortAvailability(t *testing.T) { | 
					
						
							|  |  |  | 	// Make a port is not available.
 | 
					
						
							|  |  |  | 	port := getFreePort() | 
					
						
							|  |  |  | 	listener, err := net.Listen("tcp", net.JoinHostPort("", port)) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("Unable to listen on port %v", port) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer listener.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							| 
									
										
										
										
											2019-06-25 06:02:40 +08:00
										 |  |  | 		host        string | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 		port        string | 
					
						
							|  |  |  | 		expectedErr error | 
					
						
							|  |  |  | 	}{ | 
					
						
							| 
									
										
										
										
											2019-06-25 06:02:40 +08:00
										 |  |  | 		{"", port, fmt.Errorf("listen tcp :%v: bind: address already in use", port)}, | 
					
						
							|  |  |  | 		{"127.0.0.1", port, fmt.Errorf("listen tcp 127.0.0.1:%v: bind: address already in use", port)}, | 
					
						
							|  |  |  | 		{"", getFreePort(), nil}, | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, testCase := range testCases { | 
					
						
							| 
									
										
										
										
											2019-10-02 01:42:18 +08:00
										 |  |  | 		// On MS Windows and Mac, skip checking error case due to https://github.com/golang/go/issues/7598
 | 
					
						
							| 
									
										
										
										
											2020-09-01 01:19:25 +08:00
										 |  |  | 		if (runtime.GOOS == globalWindowsOSName || runtime.GOOS == globalMacOSName || runtime.GOOS == "solaris") && testCase.expectedErr != nil { | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-25 06:02:40 +08:00
										 |  |  | 		err := checkPortAvailability(testCase.host, testCase.port) | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 		if testCase.expectedErr == nil { | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				t.Fatalf("error: expected = <nil>, got = %v", err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else if err == nil { | 
					
						
							|  |  |  | 			t.Fatalf("error: expected = %v, got = <nil>", testCase.expectedErr) | 
					
						
							|  |  |  | 		} else if testCase.expectedErr.Error() != err.Error() { | 
					
						
							|  |  |  | 			t.Fatalf("error: expected = %v, got = %v", testCase.expectedErr, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestCheckLocalServerAddr(t *testing.T) { | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		serverAddr  string | 
					
						
							|  |  |  | 		expectedErr error | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{":54321", nil}, | 
					
						
							|  |  |  | 		{"localhost:54321", nil}, | 
					
						
							| 
									
										
										
										
											2017-05-24 03:07:39 +08:00
										 |  |  | 		{"0.0.0.0:9000", nil}, | 
					
						
							| 
									
										
										
										
											2019-11-27 03:42:10 +08:00
										 |  |  | 		{":0", nil}, | 
					
						
							|  |  |  | 		{"localhost", nil}, | 
					
						
							|  |  |  | 		{"", fmt.Errorf("invalid argument")}, | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 		{"example.org:54321", fmt.Errorf("host in server address should be this server")}, | 
					
						
							| 
									
										
										
										
											2019-11-27 03:42:10 +08:00
										 |  |  | 		{":-10", fmt.Errorf("port must be between 0 to 65535")}, | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, testCase := range testCases { | 
					
						
							| 
									
										
										
										
											2019-11-27 03:42:10 +08:00
										 |  |  | 		testCase := testCase | 
					
						
							|  |  |  | 		t.Run("", func(t *testing.T) { | 
					
						
							|  |  |  | 			err := CheckLocalServerAddr(testCase.serverAddr) | 
					
						
							|  |  |  | 			if testCase.expectedErr == nil { | 
					
						
							|  |  |  | 				if err != nil { | 
					
						
							|  |  |  | 					t.Errorf("error: expected = <nil>, got = %v", err) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else if err == nil { | 
					
						
							|  |  |  | 				t.Errorf("error: expected = %v, got = <nil>", testCase.expectedErr) | 
					
						
							|  |  |  | 			} else if testCase.expectedErr.Error() != err.Error() { | 
					
						
							|  |  |  | 				t.Errorf("error: expected = %v, got = %v", testCase.expectedErr, err) | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-11-27 03:42:10 +08:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-05-17 12:13:29 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestExtractHostPort(t *testing.T) { | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		addr        string | 
					
						
							|  |  |  | 		host        string | 
					
						
							|  |  |  | 		port        string | 
					
						
							|  |  |  | 		expectedErr error | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{"", "", "", errors.New("unable to process empty address")}, | 
					
						
							|  |  |  | 		{"localhost:9000", "localhost", "9000", nil}, | 
					
						
							|  |  |  | 		{"http://:9000/", "", "9000", nil}, | 
					
						
							|  |  |  | 		{"http://8.8.8.8:9000/", "8.8.8.8", "9000", nil}, | 
					
						
							|  |  |  | 		{"https://facebook.com:9000/", "facebook.com", "9000", nil}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		host, port, err := extractHostPort(testCase.addr) | 
					
						
							| 
									
										
										
										
											2020-08-25 03:11:20 +08:00
										 |  |  | 		if testCase.expectedErr == nil && err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Test %d: should succeed but failed with err: %v", i+1, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if testCase.expectedErr != nil && err == nil { | 
					
						
							|  |  |  | 			t.Fatalf("Test %d:, should fail but succeeded.", i+1) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if err == nil { | 
					
						
							| 
									
										
										
										
											2017-05-17 12:13:29 +08:00
										 |  |  | 			if host != testCase.host { | 
					
						
							|  |  |  | 				t.Fatalf("Test %d: expected: %v, found: %v", i+1, testCase.host, host) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if port != testCase.port { | 
					
						
							|  |  |  | 				t.Fatalf("Test %d: expected: %v, found: %v", i+1, testCase.port, port) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-08-25 03:11:20 +08:00
										 |  |  | 		if testCase.expectedErr != nil && err != nil { | 
					
						
							| 
									
										
										
										
											2017-05-17 12:13:29 +08:00
										 |  |  | 			if testCase.expectedErr.Error() != err.Error() { | 
					
						
							|  |  |  | 				t.Fatalf("Test %d: failed with different error, expected: '%v', found:'%v'.", i+1, testCase.expectedErr, err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestSameLocalAddrs(t *testing.T) { | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		addr1       string | 
					
						
							|  |  |  | 		addr2       string | 
					
						
							|  |  |  | 		sameAddr    bool | 
					
						
							|  |  |  | 		expectedErr error | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{"", "", false, errors.New("unable to process empty address")}, | 
					
						
							|  |  |  | 		{":9000", ":9000", true, nil}, | 
					
						
							|  |  |  | 		{"localhost:9000", ":9000", true, nil}, | 
					
						
							|  |  |  | 		{"localhost:9000", "http://localhost:9000", true, nil}, | 
					
						
							| 
									
										
										
										
											2017-08-07 02:27:33 +08:00
										 |  |  | 		{"http://localhost:9000", ":9000", true, nil}, | 
					
						
							|  |  |  | 		{"http://localhost:9000", "http://localhost:9000", true, nil}, | 
					
						
							|  |  |  | 		{"http://8.8.8.8:9000", "http://localhost:9000", false, nil}, | 
					
						
							| 
									
										
										
										
											2017-05-17 12:13:29 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-27 03:42:10 +08:00
										 |  |  | 	for _, testCase := range testCases { | 
					
						
							|  |  |  | 		testCase := testCase | 
					
						
							|  |  |  | 		t.Run("", func(t *testing.T) { | 
					
						
							|  |  |  | 			sameAddr, err := sameLocalAddrs(testCase.addr1, testCase.addr2) | 
					
						
							|  |  |  | 			if testCase.expectedErr != nil && err == nil { | 
					
						
							|  |  |  | 				t.Errorf("should fail but succeeded") | 
					
						
							| 
									
										
										
										
											2017-05-17 12:13:29 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-11-27 03:42:10 +08:00
										 |  |  | 			if testCase.expectedErr == nil && err != nil { | 
					
						
							|  |  |  | 				t.Errorf("should succeed but failed with %v", err) | 
					
						
							| 
									
										
										
										
											2017-05-17 12:13:29 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-11-27 03:42:10 +08:00
										 |  |  | 			if err == nil { | 
					
						
							|  |  |  | 				if sameAddr != testCase.sameAddr { | 
					
						
							|  |  |  | 					t.Errorf("expected: %v, found: %v", testCase.sameAddr, sameAddr) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				if err.Error() != testCase.expectedErr.Error() { | 
					
						
							|  |  |  | 					t.Errorf("failed with different error, expected: '%v', found:'%v'.", | 
					
						
							|  |  |  | 						testCase.expectedErr, err) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2017-05-17 12:13:29 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-12-14 15:37:46 +08:00
										 |  |  | func TestIsHostIP(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2017-08-11 07:54:19 +08:00
										 |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		args           string | 
					
						
							|  |  |  | 		expectedResult bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{"localhost", false}, | 
					
						
							|  |  |  | 		{"localhost:9000", false}, | 
					
						
							|  |  |  | 		{"example.com", false}, | 
					
						
							|  |  |  | 		{"http://192.168.1.0", false}, | 
					
						
							|  |  |  | 		{"http://192.168.1.0:9000", false}, | 
					
						
							|  |  |  | 		{"192.168.1.0", true}, | 
					
						
							| 
									
										
										
										
											2018-12-14 15:37:46 +08:00
										 |  |  | 		{"[2001:3984:3989::20%eth0]:9000", true}, | 
					
						
							| 
									
										
										
										
											2017-08-11 07:54:19 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, testCase := range testCases { | 
					
						
							| 
									
										
										
										
											2018-12-14 15:37:46 +08:00
										 |  |  | 		ret := isHostIP(testCase.args) | 
					
						
							| 
									
										
										
										
											2017-08-11 07:54:19 +08:00
										 |  |  | 		if testCase.expectedResult != ret { | 
					
						
							|  |  |  | 			t.Fatalf("expected: %v , got: %v", testCase.expectedResult, ret) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |