github.com/imran-kn/cilium-fork@v1.6.9/pkg/k8s/endpoints_test.go (about) 1 // Copyright 2018-2019 Authors of Cilium 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // +build !privileged_tests 16 17 package k8s 18 19 import ( 20 "testing" 21 22 "github.com/cilium/cilium/pkg/checker" 23 "github.com/cilium/cilium/pkg/k8s/types" 24 "github.com/cilium/cilium/pkg/loadbalancer" 25 "github.com/cilium/cilium/pkg/service" 26 27 "gopkg.in/check.v1" 28 "k8s.io/api/core/v1" 29 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 30 ) 31 32 func TestEndpoints_DeepEqual(t *testing.T) { 33 type fields struct { 34 svcEP *Endpoints 35 } 36 type args struct { 37 o *Endpoints 38 } 39 tests := []struct { 40 name string 41 fields fields 42 args args 43 want bool 44 }{ 45 46 { 47 name: "both equal", 48 fields: fields{ 49 svcEP: &Endpoints{ 50 Backends: map[string]service.PortConfiguration{ 51 "172.20.0.1": map[string]*loadbalancer.L4Addr{ 52 "foo": { 53 Protocol: loadbalancer.NONE, 54 Port: 1, 55 }, 56 }, 57 }, 58 }, 59 }, 60 args: args{ 61 o: &Endpoints{ 62 Backends: map[string]service.PortConfiguration{ 63 "172.20.0.1": map[string]*loadbalancer.L4Addr{ 64 "foo": { 65 Protocol: loadbalancer.NONE, 66 Port: 1, 67 }, 68 }, 69 }, 70 }, 71 }, 72 want: true, 73 }, 74 { 75 name: "different BE IPs", 76 fields: fields{ 77 svcEP: &Endpoints{ 78 Backends: map[string]service.PortConfiguration{ 79 "172.20.0.1": map[string]*loadbalancer.L4Addr{ 80 "foo": { 81 Protocol: loadbalancer.NONE, 82 Port: 1, 83 }, 84 }, 85 }, 86 }, 87 }, 88 args: args{ 89 o: &Endpoints{ 90 Backends: map[string]service.PortConfiguration{ 91 "172.20.0.2": map[string]*loadbalancer.L4Addr{ 92 "foo": { 93 Protocol: loadbalancer.NONE, 94 Port: 1, 95 }, 96 }, 97 }, 98 }, 99 }, 100 want: false, 101 }, 102 { 103 name: "ports different name", 104 fields: fields{ 105 svcEP: &Endpoints{ 106 Backends: map[string]service.PortConfiguration{ 107 "172.20.0.1": map[string]*loadbalancer.L4Addr{ 108 "foo": { 109 Protocol: loadbalancer.NONE, 110 Port: 1, 111 }, 112 }, 113 }, 114 }, 115 }, 116 args: args{ 117 o: &Endpoints{ 118 Backends: map[string]service.PortConfiguration{ 119 "172.20.0.1": map[string]*loadbalancer.L4Addr{ 120 "foz": { 121 Protocol: loadbalancer.NONE, 122 Port: 1, 123 }, 124 }, 125 }, 126 }, 127 }, 128 want: false, 129 }, 130 { 131 name: "ports different content", 132 fields: fields{ 133 svcEP: &Endpoints{ 134 Backends: map[string]service.PortConfiguration{ 135 "172.20.0.1": map[string]*loadbalancer.L4Addr{ 136 "foo": { 137 Protocol: loadbalancer.NONE, 138 Port: 1, 139 }, 140 }, 141 }, 142 }, 143 }, 144 args: args{ 145 o: &Endpoints{ 146 Backends: map[string]service.PortConfiguration{ 147 "172.20.0.1": map[string]*loadbalancer.L4Addr{ 148 "foo": { 149 Protocol: loadbalancer.NONE, 150 Port: 2, 151 }, 152 }, 153 }, 154 }, 155 }, 156 want: false, 157 }, 158 { 159 name: "ports different one is bigger", 160 fields: fields{ 161 svcEP: &Endpoints{ 162 Backends: map[string]service.PortConfiguration{ 163 "172.20.0.1": map[string]*loadbalancer.L4Addr{ 164 "foo": { 165 Protocol: loadbalancer.NONE, 166 Port: 1, 167 }, 168 }, 169 }, 170 }, 171 }, 172 args: args{ 173 o: &Endpoints{ 174 Backends: map[string]service.PortConfiguration{ 175 "172.20.0.1": map[string]*loadbalancer.L4Addr{ 176 "foo": { 177 Protocol: loadbalancer.NONE, 178 Port: 1, 179 }, 180 "baz": { 181 Protocol: loadbalancer.NONE, 182 Port: 2, 183 }, 184 }, 185 }, 186 }, 187 }, 188 want: false, 189 }, 190 { 191 name: "ports different one is nil", 192 fields: fields{}, 193 args: args{ 194 o: &Endpoints{ 195 Backends: map[string]service.PortConfiguration{ 196 "172.20.0.1": map[string]*loadbalancer.L4Addr{ 197 "foo": { 198 Protocol: loadbalancer.NONE, 199 Port: 1, 200 }, 201 }, 202 }, 203 }, 204 }, 205 want: false, 206 }, 207 { 208 name: "both nil", 209 args: args{}, 210 want: true, 211 }, 212 } 213 for _, tt := range tests { 214 t.Run(tt.name, func(t *testing.T) { 215 if got := tt.fields.svcEP.DeepEquals(tt.args.o); got != tt.want { 216 t.Errorf("Endpoints.DeepEqual() = %v, want %v", got, tt.want) 217 } 218 }) 219 } 220 } 221 222 func (s *K8sSuite) Test_parseK8sEPv1(c *check.C) { 223 type args struct { 224 eps *types.Endpoints 225 } 226 tests := []struct { 227 name string 228 setupArgs func() args 229 setupWanted func() *Endpoints 230 }{ 231 { 232 name: "empty endpoint", 233 setupArgs: func() args { 234 return args{ 235 eps: &types.Endpoints{ 236 Endpoints: &v1.Endpoints{ 237 ObjectMeta: metav1.ObjectMeta{ 238 Name: "foo", 239 Namespace: "bar", 240 }, 241 }, 242 }, 243 } 244 }, 245 setupWanted: func() *Endpoints { 246 return newEndpoints() 247 }, 248 }, 249 { 250 name: "endpoint with an address and port", 251 setupArgs: func() args { 252 return args{ 253 eps: &types.Endpoints{ 254 Endpoints: &v1.Endpoints{ 255 ObjectMeta: metav1.ObjectMeta{ 256 Name: "foo", 257 Namespace: "bar", 258 }, 259 Subsets: []v1.EndpointSubset{ 260 { 261 Addresses: []v1.EndpointAddress{ 262 { 263 IP: "172.0.0.1", 264 }, 265 }, 266 Ports: []v1.EndpointPort{ 267 { 268 Name: "http-test-svc", 269 Port: 8080, 270 Protocol: v1.ProtocolTCP, 271 }, 272 }, 273 }, 274 }, 275 }, 276 }, 277 } 278 }, 279 setupWanted: func() *Endpoints { 280 svcEP := newEndpoints() 281 svcEP.Backends["172.0.0.1"] = service.PortConfiguration{ 282 "http-test-svc": loadbalancer.NewL4Addr(loadbalancer.TCP, 8080), 283 } 284 return svcEP 285 }, 286 }, 287 { 288 name: "endpoint with an address and 2 ports", 289 setupArgs: func() args { 290 return args{ 291 eps: &types.Endpoints{ 292 Endpoints: &v1.Endpoints{ 293 ObjectMeta: metav1.ObjectMeta{ 294 Name: "foo", 295 Namespace: "bar", 296 }, 297 Subsets: []v1.EndpointSubset{ 298 { 299 Addresses: []v1.EndpointAddress{ 300 { 301 IP: "172.0.0.1", 302 }, 303 }, 304 Ports: []v1.EndpointPort{ 305 { 306 Name: "http-test-svc", 307 Port: 8080, 308 Protocol: v1.ProtocolTCP, 309 }, 310 { 311 Name: "http-test-svc-2", 312 Port: 8081, 313 Protocol: v1.ProtocolTCP, 314 }, 315 }, 316 }, 317 }, 318 }, 319 }, 320 } 321 }, 322 setupWanted: func() *Endpoints { 323 svcEP := newEndpoints() 324 svcEP.Backends["172.0.0.1"] = service.PortConfiguration{ 325 "http-test-svc": loadbalancer.NewL4Addr(loadbalancer.TCP, 8080), 326 "http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081), 327 } 328 return svcEP 329 }, 330 }, 331 { 332 name: "endpoint with 2 addresses and 2 ports", 333 setupArgs: func() args { 334 return args{ 335 eps: &types.Endpoints{ 336 Endpoints: &v1.Endpoints{ 337 ObjectMeta: metav1.ObjectMeta{ 338 Name: "foo", 339 Namespace: "bar", 340 }, 341 Subsets: []v1.EndpointSubset{ 342 { 343 Addresses: []v1.EndpointAddress{ 344 { 345 IP: "172.0.0.1", 346 }, 347 { 348 IP: "172.0.0.2", 349 }, 350 }, 351 Ports: []v1.EndpointPort{ 352 { 353 Name: "http-test-svc", 354 Port: 8080, 355 Protocol: v1.ProtocolTCP, 356 }, 357 { 358 Name: "http-test-svc-2", 359 Port: 8081, 360 Protocol: v1.ProtocolTCP, 361 }, 362 }, 363 }, 364 }, 365 }, 366 }, 367 } 368 }, 369 setupWanted: func() *Endpoints { 370 svcEP := newEndpoints() 371 svcEP.Backends["172.0.0.1"] = service.PortConfiguration{ 372 "http-test-svc": loadbalancer.NewL4Addr(loadbalancer.TCP, 8080), 373 "http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081), 374 } 375 svcEP.Backends["172.0.0.2"] = service.PortConfiguration{ 376 "http-test-svc": loadbalancer.NewL4Addr(loadbalancer.TCP, 8080), 377 "http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081), 378 } 379 return svcEP 380 }, 381 }, 382 { 383 name: "endpoint with 2 addresses, 1 address not ready and 2 ports", 384 setupArgs: func() args { 385 return args{ 386 eps: &types.Endpoints{ 387 Endpoints: &v1.Endpoints{ 388 ObjectMeta: metav1.ObjectMeta{ 389 Name: "foo", 390 Namespace: "bar", 391 }, 392 Subsets: []v1.EndpointSubset{ 393 { 394 NotReadyAddresses: []v1.EndpointAddress{ 395 { 396 IP: "172.0.0.3", 397 }, 398 }, 399 Addresses: []v1.EndpointAddress{ 400 { 401 IP: "172.0.0.1", 402 }, 403 { 404 IP: "172.0.0.2", 405 }, 406 }, 407 Ports: []v1.EndpointPort{ 408 { 409 Name: "http-test-svc", 410 Port: 8080, 411 Protocol: v1.ProtocolTCP, 412 }, 413 { 414 Name: "http-test-svc-2", 415 Port: 8081, 416 Protocol: v1.ProtocolTCP, 417 }, 418 }, 419 }, 420 }, 421 }, 422 }, 423 } 424 }, 425 setupWanted: func() *Endpoints { 426 svcEP := newEndpoints() 427 svcEP.Backends["172.0.0.1"] = service.PortConfiguration{ 428 "http-test-svc": loadbalancer.NewL4Addr(loadbalancer.TCP, 8080), 429 "http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081), 430 } 431 svcEP.Backends["172.0.0.2"] = service.PortConfiguration{ 432 "http-test-svc": loadbalancer.NewL4Addr(loadbalancer.TCP, 8080), 433 "http-test-svc-2": loadbalancer.NewL4Addr(loadbalancer.TCP, 8081), 434 } 435 return svcEP 436 }, 437 }, 438 } 439 for _, tt := range tests { 440 args := tt.setupArgs() 441 want := tt.setupWanted() 442 _, got := ParseEndpoints(args.eps) 443 c.Assert(got, checker.DeepEquals, want, check.Commentf("Test name: %q", tt.name)) 444 } 445 } 446 447 func (s *K8sSuite) TestEndpointsString(c *check.C) { 448 endpoints := &types.Endpoints{ 449 Endpoints: &v1.Endpoints{ 450 ObjectMeta: metav1.ObjectMeta{ 451 Name: "foo", 452 Namespace: "bar", 453 }, 454 Subsets: []v1.EndpointSubset{ 455 { 456 Addresses: []v1.EndpointAddress{ 457 { 458 IP: "172.0.0.2", 459 }, 460 { 461 IP: "172.0.0.1", 462 }, 463 }, 464 Ports: []v1.EndpointPort{ 465 { 466 Name: "http-test-svc-2", 467 Port: 8081, 468 Protocol: v1.ProtocolTCP, 469 }, 470 { 471 Name: "http-test-svc", 472 Port: 8080, 473 Protocol: v1.ProtocolTCP, 474 }, 475 }, 476 }, 477 }, 478 }, 479 } 480 481 _, ep := ParseEndpoints(endpoints) 482 c.Assert(ep.String(), check.Equals, "172.0.0.1:8080/TCP,172.0.0.1:8081/TCP,172.0.0.2:8080/TCP,172.0.0.2:8081/TCP") 483 }