storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/endpoint_test.go (about) 1 /* 2 * MinIO Cloud Storage, (C) 2017,2018,2019 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 17 package cmd 18 19 import ( 20 "fmt" 21 "net" 22 "net/url" 23 "path/filepath" 24 "reflect" 25 "strings" 26 "testing" 27 28 "github.com/minio/minio-go/v7/pkg/set" 29 ) 30 31 func TestNewEndpoint(t *testing.T) { 32 u2, _ := url.Parse("https://example.org/path") 33 u4, _ := url.Parse("http://192.168.253.200/path") 34 rootSlashFoo, _ := filepath.Abs("/foo") 35 testCases := []struct { 36 arg string 37 expectedEndpoint Endpoint 38 expectedType EndpointType 39 expectedErr error 40 }{ 41 {"/foo", Endpoint{URL: &url.URL{Path: rootSlashFoo}, IsLocal: true}, PathEndpointType, nil}, 42 {"https://example.org/path", Endpoint{URL: u2, IsLocal: false}, URLEndpointType, nil}, 43 {"http://192.168.253.200/path", Endpoint{URL: u4, IsLocal: false}, URLEndpointType, nil}, 44 {"", Endpoint{}, -1, fmt.Errorf("empty or root endpoint is not supported")}, 45 {SlashSeparator, Endpoint{}, -1, fmt.Errorf("empty or root endpoint is not supported")}, 46 {`\`, Endpoint{}, -1, fmt.Errorf("empty or root endpoint is not supported")}, 47 {"c://foo", Endpoint{}, -1, fmt.Errorf("invalid URL endpoint format")}, 48 {"ftp://foo", Endpoint{}, -1, fmt.Errorf("invalid URL endpoint format")}, 49 {"http://server/path?location", Endpoint{}, -1, fmt.Errorf("invalid URL endpoint format")}, 50 {"http://:/path", Endpoint{}, -1, fmt.Errorf("invalid URL endpoint format: invalid port number")}, 51 {"http://:8080/path", Endpoint{}, -1, fmt.Errorf("invalid URL endpoint format: empty host name")}, 52 {"http://server:/path", Endpoint{}, -1, fmt.Errorf("invalid URL endpoint format: invalid port number")}, 53 {"https://93.184.216.34:808080/path", Endpoint{}, -1, fmt.Errorf("invalid URL endpoint format: port number must be between 1 to 65535")}, 54 {"http://server:8080//", Endpoint{}, -1, fmt.Errorf("empty or root path is not supported in URL endpoint")}, 55 {"http://server:8080/", Endpoint{}, -1, fmt.Errorf("empty or root path is not supported in URL endpoint")}, 56 {"192.168.1.210:9000", Endpoint{}, -1, fmt.Errorf("invalid URL endpoint format: missing scheme http or https")}, 57 } 58 59 for i, test := range testCases { 60 t.Run(fmt.Sprint("case-", i), func(t *testing.T) { 61 endpoint, err := NewEndpoint(test.arg) 62 if err == nil { 63 err = endpoint.UpdateIsLocal() 64 } 65 66 if test.expectedErr == nil { 67 if err != nil { 68 t.Errorf("error: expected = <nil>, got = %v", err) 69 } 70 } else if err == nil { 71 t.Errorf("error: expected = %v, got = <nil>", test.expectedErr) 72 } else if test.expectedErr.Error() != err.Error() { 73 t.Errorf("error: expected = %v, got = %v", test.expectedErr, err) 74 } 75 76 if err == nil { 77 if (test.expectedEndpoint.URL == nil) != (endpoint.URL == nil) { 78 t.Errorf("endpoint url: expected = %#v, got = %#v", test.expectedEndpoint.URL, endpoint.URL) 79 return 80 } else if test.expectedEndpoint.URL.String() != endpoint.URL.String() { 81 t.Errorf("endpoint url: expected = %#v, got = %#v", test.expectedEndpoint.URL.String(), endpoint.URL.String()) 82 return 83 } 84 if !reflect.DeepEqual(test.expectedEndpoint, endpoint) { 85 t.Errorf("endpoint: expected = %#v, got = %#v", test.expectedEndpoint, endpoint) 86 } 87 } 88 89 if err == nil && test.expectedType != endpoint.Type() { 90 t.Errorf("type: expected = %+v, got = %+v", test.expectedType, endpoint.Type()) 91 } 92 }) 93 } 94 } 95 96 func TestNewEndpoints(t *testing.T) { 97 testCases := []struct { 98 args []string 99 expectedErr error 100 }{ 101 {[]string{"/d1", "/d2", "/d3", "/d4"}, nil}, 102 {[]string{"http://localhost/d1", "http://localhost/d2", "http://localhost/d3", "http://localhost/d4"}, nil}, 103 {[]string{"http://example.org/d1", "http://example.com/d1", "http://example.net/d1", "http://example.edu/d1"}, nil}, 104 {[]string{"http://localhost/d1", "http://localhost/d2", "http://example.org/d1", "http://example.org/d2"}, nil}, 105 {[]string{"https://localhost:9000/d1", "https://localhost:9001/d2", "https://localhost:9002/d3", "https://localhost:9003/d4"}, nil}, 106 // // It is valid WRT endpoint list that same path is expected with different port on same server. 107 {[]string{"https://127.0.0.1:9000/d1", "https://127.0.0.1:9001/d1", "https://127.0.0.1:9002/d1", "https://127.0.0.1:9003/d1"}, nil}, 108 {[]string{"d1", "d2", "d3", "d1"}, fmt.Errorf("duplicate endpoints found")}, 109 {[]string{"d1", "d2", "d3", "./d1"}, fmt.Errorf("duplicate endpoints found")}, 110 {[]string{"http://localhost/d1", "http://localhost/d2", "http://localhost/d1", "http://localhost/d4"}, fmt.Errorf("duplicate endpoints found")}, 111 {[]string{"ftp://server/d1", "http://server/d2", "http://server/d3", "http://server/d4"}, fmt.Errorf("'ftp://server/d1': invalid URL endpoint format")}, 112 {[]string{"d1", "http://localhost/d2", "d3", "d4"}, fmt.Errorf("mixed style endpoints are not supported")}, 113 {[]string{"http://example.org/d1", "https://example.com/d1", "http://example.net/d1", "https://example.edut/d1"}, fmt.Errorf("mixed scheme is not supported")}, 114 {[]string{"192.168.1.210:9000/tmp/dir0", "192.168.1.210:9000/tmp/dir1", "192.168.1.210:9000/tmp/dir2", "192.168.110:9000/tmp/dir3"}, fmt.Errorf("'192.168.1.210:9000/tmp/dir0': invalid URL endpoint format: missing scheme http or https")}, 115 } 116 117 for _, testCase := range testCases { 118 _, err := NewEndpoints(testCase.args...) 119 if testCase.expectedErr == nil { 120 if err != nil { 121 t.Fatalf("error: expected = <nil>, got = %v", err) 122 } 123 } else if err == nil { 124 t.Fatalf("error: expected = %v, got = <nil>", testCase.expectedErr) 125 } else if testCase.expectedErr.Error() != err.Error() { 126 t.Fatalf("error: expected = %v, got = %v", testCase.expectedErr, err) 127 } 128 } 129 } 130 131 func TestCreateEndpoints(t *testing.T) { 132 // Filter ipList by IPs those do not start with '127.'. 133 nonLoopBackIPs := localIP4.FuncMatch(func(ip string, matchString string) bool { 134 return !net.ParseIP(ip).IsLoopback() 135 }, "") 136 if len(nonLoopBackIPs) == 0 { 137 t.Fatalf("No non-loop back IP address found for this host") 138 } 139 nonLoopBackIP := nonLoopBackIPs.ToSlice()[0] 140 141 mustAbs := func(s string) string { 142 s, err := filepath.Abs(s) 143 if err != nil { 144 t.Fatal(err) 145 } 146 return s 147 } 148 getExpectedEndpoints := func(args []string, prefix string) ([]*url.URL, []bool) { 149 var URLs []*url.URL 150 var localFlags []bool 151 for _, arg := range args { 152 u, _ := url.Parse(arg) 153 URLs = append(URLs, u) 154 localFlags = append(localFlags, strings.HasPrefix(arg, prefix)) 155 } 156 157 return URLs, localFlags 158 } 159 160 case1Endpoint1 := "http://" + nonLoopBackIP + "/d1" 161 case1Endpoint2 := "http://" + nonLoopBackIP + "/d2" 162 args := []string{ 163 "http://" + nonLoopBackIP + ":10000/d1", 164 "http://" + nonLoopBackIP + ":10000/d2", 165 "http://example.org:10000/d3", 166 "http://example.com:10000/d4", 167 } 168 case1URLs, case1LocalFlags := getExpectedEndpoints(args, "http://"+nonLoopBackIP+":10000/") 169 170 case2Endpoint1 := "http://" + nonLoopBackIP + "/d1" 171 case2Endpoint2 := "http://" + nonLoopBackIP + ":9000/d2" 172 args = []string{ 173 "http://" + nonLoopBackIP + ":10000/d1", 174 "http://" + nonLoopBackIP + ":9000/d2", 175 "http://example.org:10000/d3", 176 "http://example.com:10000/d4", 177 } 178 case2URLs, case2LocalFlags := getExpectedEndpoints(args, "http://"+nonLoopBackIP+":10000/") 179 180 case3Endpoint1 := "http://" + nonLoopBackIP + "/d1" 181 args = []string{ 182 "http://" + nonLoopBackIP + ":80/d1", 183 "http://example.org:9000/d2", 184 "http://example.com:80/d3", 185 "http://example.net:80/d4", 186 } 187 case3URLs, case3LocalFlags := getExpectedEndpoints(args, "http://"+nonLoopBackIP+":80/") 188 189 case4Endpoint1 := "http://" + nonLoopBackIP + "/d1" 190 args = []string{ 191 "http://" + nonLoopBackIP + ":9000/d1", 192 "http://example.org:9000/d2", 193 "http://example.com:9000/d3", 194 "http://example.net:9000/d4", 195 } 196 case4URLs, case4LocalFlags := getExpectedEndpoints(args, "http://"+nonLoopBackIP+":9000/") 197 198 case5Endpoint1 := "http://" + nonLoopBackIP + ":9000/d1" 199 case5Endpoint2 := "http://" + nonLoopBackIP + ":9001/d2" 200 case5Endpoint3 := "http://" + nonLoopBackIP + ":9002/d3" 201 case5Endpoint4 := "http://" + nonLoopBackIP + ":9003/d4" 202 args = []string{ 203 case5Endpoint1, 204 case5Endpoint2, 205 case5Endpoint3, 206 case5Endpoint4, 207 } 208 case5URLs, case5LocalFlags := getExpectedEndpoints(args, "http://"+nonLoopBackIP+":9000/") 209 210 case6Endpoint := "http://" + nonLoopBackIP + ":9003/d4" 211 args = []string{ 212 "http://localhost:9000/d1", 213 "http://localhost:9001/d2", 214 "http://127.0.0.1:9002/d3", 215 case6Endpoint, 216 } 217 case6URLs, case6LocalFlags := getExpectedEndpoints(args, "http://"+nonLoopBackIP+":9003/") 218 219 testCases := []struct { 220 serverAddr string 221 args [][]string 222 expectedServerAddr string 223 expectedEndpoints Endpoints 224 expectedSetupType SetupType 225 expectedErr error 226 }{ 227 {"localhost", [][]string{}, "", Endpoints{}, -1, fmt.Errorf("address localhost: missing port in address")}, 228 229 // FS Setup 230 {"localhost:9000", [][]string{{"http://localhost/d1"}}, "", Endpoints{}, -1, fmt.Errorf("use path style endpoint for FS setup")}, 231 {":443", [][]string{{"/d1"}}, ":443", Endpoints{Endpoint{URL: &url.URL{Path: mustAbs("/d1")}, IsLocal: true}}, FSSetupType, nil}, 232 {"localhost:10000", [][]string{{"/d1"}}, "localhost:10000", Endpoints{Endpoint{URL: &url.URL{Path: mustAbs("/d1")}, IsLocal: true}}, FSSetupType, nil}, 233 {"localhost:9000", [][]string{{"https://127.0.0.1:9000/d1", "https://localhost:9001/d1", "https://example.com/d1", "https://example.com/d2"}}, "", Endpoints{}, -1, fmt.Errorf("path '/d1' can not be served by different port on same address")}, 234 235 // Erasure Setup with PathEndpointType 236 {":1234", [][]string{{"/d1", "/d2", "/d3", "/d4"}}, ":1234", 237 Endpoints{ 238 Endpoint{URL: &url.URL{Path: mustAbs("/d1")}, IsLocal: true}, 239 Endpoint{URL: &url.URL{Path: mustAbs("/d2")}, IsLocal: true}, 240 Endpoint{URL: &url.URL{Path: mustAbs("/d3")}, IsLocal: true}, 241 Endpoint{URL: &url.URL{Path: mustAbs("/d4")}, IsLocal: true}, 242 }, ErasureSetupType, nil}, 243 // DistErasure Setup with URLEndpointType 244 {":9000", [][]string{{"http://localhost/d1", "http://localhost/d2", "http://localhost/d3", "http://localhost/d4"}}, ":9000", Endpoints{ 245 Endpoint{URL: &url.URL{Scheme: "http", Host: "localhost", Path: "/d1"}, IsLocal: true}, 246 Endpoint{URL: &url.URL{Scheme: "http", Host: "localhost", Path: "/d2"}, IsLocal: true}, 247 Endpoint{URL: &url.URL{Scheme: "http", Host: "localhost", Path: "/d3"}, IsLocal: true}, 248 Endpoint{URL: &url.URL{Scheme: "http", Host: "localhost", Path: "/d4"}, IsLocal: true}, 249 }, ErasureSetupType, nil}, 250 // DistErasure Setup with URLEndpointType having mixed naming to local host. 251 {"127.0.0.1:10000", [][]string{{"http://localhost/d1", "http://localhost/d2", "http://127.0.0.1/d3", "http://127.0.0.1/d4"}}, "", Endpoints{}, -1, fmt.Errorf("all local endpoints should not have different hostnames/ips")}, 252 253 {":9001", [][]string{{"http://10.0.0.1:9000/export", "http://10.0.0.2:9000/export", "http://" + nonLoopBackIP + ":9001/export", "http://10.0.0.2:9001/export"}}, "", Endpoints{}, -1, fmt.Errorf("path '/export' can not be served by different port on same address")}, 254 255 {":9000", [][]string{{"http://127.0.0.1:9000/export", "http://" + nonLoopBackIP + ":9000/export", "http://10.0.0.1:9000/export", "http://10.0.0.2:9000/export"}}, "", Endpoints{}, -1, fmt.Errorf("path '/export' cannot be served by different address on same server")}, 256 257 // DistErasure type 258 {"127.0.0.1:10000", [][]string{{case1Endpoint1, case1Endpoint2, "http://example.org/d3", "http://example.com/d4"}}, "127.0.0.1:10000", Endpoints{ 259 Endpoint{URL: case1URLs[0], IsLocal: case1LocalFlags[0]}, 260 Endpoint{URL: case1URLs[1], IsLocal: case1LocalFlags[1]}, 261 Endpoint{URL: case1URLs[2], IsLocal: case1LocalFlags[2]}, 262 Endpoint{URL: case1URLs[3], IsLocal: case1LocalFlags[3]}, 263 }, DistErasureSetupType, nil}, 264 265 {"127.0.0.1:10000", [][]string{{case2Endpoint1, case2Endpoint2, "http://example.org/d3", "http://example.com/d4"}}, "127.0.0.1:10000", Endpoints{ 266 Endpoint{URL: case2URLs[0], IsLocal: case2LocalFlags[0]}, 267 Endpoint{URL: case2URLs[1], IsLocal: case2LocalFlags[1]}, 268 Endpoint{URL: case2URLs[2], IsLocal: case2LocalFlags[2]}, 269 Endpoint{URL: case2URLs[3], IsLocal: case2LocalFlags[3]}, 270 }, DistErasureSetupType, nil}, 271 272 {":80", [][]string{{case3Endpoint1, "http://example.org:9000/d2", "http://example.com/d3", "http://example.net/d4"}}, ":80", Endpoints{ 273 Endpoint{URL: case3URLs[0], IsLocal: case3LocalFlags[0]}, 274 Endpoint{URL: case3URLs[1], IsLocal: case3LocalFlags[1]}, 275 Endpoint{URL: case3URLs[2], IsLocal: case3LocalFlags[2]}, 276 Endpoint{URL: case3URLs[3], IsLocal: case3LocalFlags[3]}, 277 }, DistErasureSetupType, nil}, 278 279 {":9000", [][]string{{case4Endpoint1, "http://example.org/d2", "http://example.com/d3", "http://example.net/d4"}}, ":9000", Endpoints{ 280 Endpoint{URL: case4URLs[0], IsLocal: case4LocalFlags[0]}, 281 Endpoint{URL: case4URLs[1], IsLocal: case4LocalFlags[1]}, 282 Endpoint{URL: case4URLs[2], IsLocal: case4LocalFlags[2]}, 283 Endpoint{URL: case4URLs[3], IsLocal: case4LocalFlags[3]}, 284 }, DistErasureSetupType, nil}, 285 286 {":9000", [][]string{{case5Endpoint1, case5Endpoint2, case5Endpoint3, case5Endpoint4}}, ":9000", Endpoints{ 287 Endpoint{URL: case5URLs[0], IsLocal: case5LocalFlags[0]}, 288 Endpoint{URL: case5URLs[1], IsLocal: case5LocalFlags[1]}, 289 Endpoint{URL: case5URLs[2], IsLocal: case5LocalFlags[2]}, 290 Endpoint{URL: case5URLs[3], IsLocal: case5LocalFlags[3]}, 291 }, DistErasureSetupType, nil}, 292 293 // DistErasure Setup using only local host. 294 {":9003", [][]string{{"http://localhost:9000/d1", "http://localhost:9001/d2", "http://127.0.0.1:9002/d3", case6Endpoint}}, ":9003", Endpoints{ 295 Endpoint{URL: case6URLs[0], IsLocal: case6LocalFlags[0]}, 296 Endpoint{URL: case6URLs[1], IsLocal: case6LocalFlags[1]}, 297 Endpoint{URL: case6URLs[2], IsLocal: case6LocalFlags[2]}, 298 Endpoint{URL: case6URLs[3], IsLocal: case6LocalFlags[3]}, 299 }, DistErasureSetupType, nil}, 300 } 301 302 for _, testCase := range testCases { 303 testCase := testCase 304 t.Run("", func(t *testing.T) { 305 endpoints, setupType, err := CreateEndpoints(testCase.serverAddr, false, testCase.args...) 306 if err == nil && testCase.expectedErr != nil { 307 t.Errorf("error: expected = %v, got = <nil>", testCase.expectedErr) 308 } 309 if err == nil { 310 if setupType != testCase.expectedSetupType { 311 t.Errorf("setupType: expected = %v, got = %v", testCase.expectedSetupType, setupType) 312 } 313 if len(endpoints) != len(testCase.expectedEndpoints) { 314 t.Errorf("endpoints: expected = %d, got = %d", len(testCase.expectedEndpoints), 315 len(endpoints)) 316 } else { 317 for i, endpoint := range endpoints { 318 if testCase.expectedEndpoints[i].String() != endpoint.String() { 319 t.Errorf("endpoints: expected = %s, got = %s", 320 testCase.expectedEndpoints[i], 321 endpoint) 322 } 323 } 324 } 325 } 326 if err != nil && testCase.expectedErr == nil { 327 t.Errorf("error: expected = <nil>, got = %v, testCase: %v", err, testCase) 328 } 329 }) 330 } 331 } 332 333 // Tests get local peer functionality, local peer is supposed to only return one entry per minio service. 334 // So it means that if you have say localhost:9000 and localhost:9001 as endpointArgs then localhost:9001 335 // is considered a remote service from localhost:9000 perspective. 336 func TestGetLocalPeer(t *testing.T) { 337 testCases := []struct { 338 endpointArgs []string 339 expectedResult string 340 }{ 341 {[]string{"/d1", "/d2", "d3", "d4"}, "127.0.0.1:9000"}, 342 {[]string{"http://localhost:9000/d1", "http://localhost:9000/d2", "http://example.org:9000/d3", "http://example.com:9000/d4"}, 343 "localhost:9000"}, 344 {[]string{"http://localhost:9000/d1", "http://example.org:9000/d2", "http://example.com:9000/d3", "http://example.net:9000/d4"}, 345 "localhost:9000"}, 346 {[]string{"http://localhost:9000/d1", "http://localhost:9001/d2", "http://localhost:9002/d3", "http://localhost:9003/d4"}, 347 "localhost:9000"}, 348 } 349 350 for i, testCase := range testCases { 351 zendpoints := mustGetPoolEndpoints(testCase.endpointArgs...) 352 if !zendpoints[0].Endpoints[0].IsLocal { 353 if err := zendpoints[0].Endpoints.UpdateIsLocal(false); err != nil { 354 t.Fatalf("error: expected = <nil>, got = %v", err) 355 } 356 } 357 localPeer := GetLocalPeer(zendpoints, "", "9000") 358 if localPeer != testCase.expectedResult { 359 t.Fatalf("Test %d: expected: %v, got: %v", i+1, testCase.expectedResult, localPeer) 360 } 361 } 362 } 363 364 func TestGetRemotePeers(t *testing.T) { 365 tempGlobalMinioPort := globalMinioPort 366 defer func() { 367 globalMinioPort = tempGlobalMinioPort 368 }() 369 globalMinioPort = "9000" 370 371 testCases := []struct { 372 endpointArgs []string 373 expectedResult []string 374 expectedLocal string 375 }{ 376 {[]string{"/d1", "/d2", "d3", "d4"}, []string{}, ""}, 377 {[]string{"http://localhost:9000/d1", "http://localhost:9000/d2", "http://example.org:9000/d3", "http://example.com:9000/d4"}, []string{"example.com:9000", "example.org:9000", "localhost:9000"}, "localhost:9000"}, 378 {[]string{"http://localhost:9000/d1", "http://localhost:10000/d2", "http://example.org:9000/d3", "http://example.com:9000/d4"}, []string{"example.com:9000", "example.org:9000", "localhost:10000", "localhost:9000"}, "localhost:9000"}, 379 {[]string{"http://localhost:9000/d1", "http://example.org:9000/d2", "http://example.com:9000/d3", "http://example.net:9000/d4"}, []string{"example.com:9000", "example.net:9000", "example.org:9000", "localhost:9000"}, "localhost:9000"}, 380 {[]string{"http://localhost:9000/d1", "http://localhost:9001/d2", "http://localhost:9002/d3", "http://localhost:9003/d4"}, []string{"localhost:9000", "localhost:9001", "localhost:9002", "localhost:9003"}, "localhost:9000"}, 381 } 382 383 for _, testCase := range testCases { 384 zendpoints := mustGetPoolEndpoints(testCase.endpointArgs...) 385 if !zendpoints[0].Endpoints[0].IsLocal { 386 if err := zendpoints[0].Endpoints.UpdateIsLocal(false); err != nil { 387 t.Errorf("error: expected = <nil>, got = %v", err) 388 } 389 } 390 remotePeers, local := zendpoints.peers() 391 if !reflect.DeepEqual(remotePeers, testCase.expectedResult) { 392 t.Errorf("expected: %v, got: %v", testCase.expectedResult, remotePeers) 393 } 394 if local != testCase.expectedLocal { 395 t.Errorf("expected: %v, got: %v", testCase.expectedLocal, local) 396 } 397 } 398 } 399 400 func TestUpdateDomainIPs(t *testing.T) { 401 tempGlobalMinioPort := globalMinioPort 402 defer func() { 403 globalMinioPort = tempGlobalMinioPort 404 }() 405 globalMinioPort = "9000" 406 407 tempGlobalDomainIPs := globalDomainIPs 408 defer func() { 409 globalDomainIPs = tempGlobalDomainIPs 410 }() 411 412 ipv4TestCases := []struct { 413 endPoints set.StringSet 414 expectedResult set.StringSet 415 }{ 416 {set.NewStringSet(), set.NewStringSet()}, 417 {set.CreateStringSet("localhost"), set.NewStringSet()}, 418 {set.CreateStringSet("localhost", "10.0.0.1"), set.CreateStringSet("10.0.0.1:9000")}, 419 {set.CreateStringSet("localhost:9001", "10.0.0.1"), set.CreateStringSet("10.0.0.1:9000")}, 420 {set.CreateStringSet("localhost", "10.0.0.1:9001"), set.CreateStringSet("10.0.0.1:9001")}, 421 {set.CreateStringSet("localhost:9000", "10.0.0.1:9001"), set.CreateStringSet("10.0.0.1:9001")}, 422 423 {set.CreateStringSet("10.0.0.1", "10.0.0.2"), set.CreateStringSet("10.0.0.1:9000", "10.0.0.2:9000")}, 424 {set.CreateStringSet("10.0.0.1:9001", "10.0.0.2"), set.CreateStringSet("10.0.0.1:9001", "10.0.0.2:9000")}, 425 {set.CreateStringSet("10.0.0.1", "10.0.0.2:9002"), set.CreateStringSet("10.0.0.1:9000", "10.0.0.2:9002")}, 426 {set.CreateStringSet("10.0.0.1:9001", "10.0.0.2:9002"), set.CreateStringSet("10.0.0.1:9001", "10.0.0.2:9002")}, 427 } 428 429 for _, testCase := range ipv4TestCases { 430 globalDomainIPs = nil 431 432 updateDomainIPs(testCase.endPoints) 433 434 if !testCase.expectedResult.Equals(globalDomainIPs) { 435 t.Fatalf("error: expected = %s, got = %s", testCase.expectedResult, globalDomainIPs) 436 } 437 } 438 }