k8s.io/kubernetes@v1.29.3/pkg/api/v1/endpoints/util_test.go (about) 1 /* 2 Copyright 2015 The Kubernetes Authors. 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 endpoints 18 19 import ( 20 "reflect" 21 "testing" 22 23 v1 "k8s.io/api/core/v1" 24 "k8s.io/apimachinery/pkg/types" 25 "k8s.io/apimachinery/pkg/util/dump" 26 ) 27 28 func podRef(uid string) *v1.ObjectReference { 29 ref := v1.ObjectReference{UID: types.UID(uid)} 30 return &ref 31 } 32 33 func TestPackSubsets(t *testing.T) { 34 // The downside of table-driven tests is that some things have to live outside the table. 35 fooObjRef := v1.ObjectReference{Name: "foo"} 36 barObjRef := v1.ObjectReference{Name: "bar"} 37 38 testCases := []struct { 39 name string 40 given []v1.EndpointSubset 41 expect []v1.EndpointSubset 42 }{ 43 { 44 name: "empty everything", 45 given: []v1.EndpointSubset{{Addresses: []v1.EndpointAddress{}, Ports: []v1.EndpointPort{}}}, 46 expect: []v1.EndpointSubset{}, 47 }, { 48 name: "empty addresses", 49 given: []v1.EndpointSubset{{Addresses: []v1.EndpointAddress{}, Ports: []v1.EndpointPort{{Port: 111}}}}, 50 expect: []v1.EndpointSubset{}, 51 }, { 52 name: "empty ports", 53 given: []v1.EndpointSubset{{Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, Ports: []v1.EndpointPort{}}}, 54 expect: []v1.EndpointSubset{{Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, Ports: nil}}, 55 }, { 56 name: "empty ports", 57 given: []v1.EndpointSubset{{NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, Ports: []v1.EndpointPort{}}}, 58 expect: []v1.EndpointSubset{{NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, Ports: nil}}, 59 }, { 60 name: "one set, one ip, one port", 61 given: []v1.EndpointSubset{{ 62 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 63 Ports: []v1.EndpointPort{{Port: 111}}, 64 }}, 65 expect: []v1.EndpointSubset{{ 66 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 67 Ports: []v1.EndpointPort{{Port: 111}}, 68 }}, 69 }, { 70 name: "one set, one ip, one port (IPv6)", 71 given: []v1.EndpointSubset{{ 72 Addresses: []v1.EndpointAddress{{IP: "beef::1:2:3:4"}}, 73 Ports: []v1.EndpointPort{{Port: 111}}, 74 }}, 75 expect: []v1.EndpointSubset{{ 76 Addresses: []v1.EndpointAddress{{IP: "beef::1:2:3:4"}}, 77 Ports: []v1.EndpointPort{{Port: 111}}, 78 }}, 79 }, { 80 name: "one set, one notReady ip, one port", 81 given: []v1.EndpointSubset{{ 82 NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 83 Ports: []v1.EndpointPort{{Port: 111}}, 84 }}, 85 expect: []v1.EndpointSubset{{ 86 NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 87 Ports: []v1.EndpointPort{{Port: 111}}, 88 }}, 89 }, { 90 name: "one set, one ip, one UID, one port", 91 given: []v1.EndpointSubset{{ 92 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, 93 Ports: []v1.EndpointPort{{Port: 111}}, 94 }}, 95 expect: []v1.EndpointSubset{{ 96 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, 97 Ports: []v1.EndpointPort{{Port: 111}}, 98 }}, 99 }, { 100 name: "one set, one notReady ip, one UID, one port", 101 given: []v1.EndpointSubset{{ 102 NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, 103 Ports: []v1.EndpointPort{{Port: 111}}, 104 }}, 105 expect: []v1.EndpointSubset{{ 106 NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, 107 Ports: []v1.EndpointPort{{Port: 111}}, 108 }}, 109 }, { 110 name: "one set, one ip, empty UID, one port", 111 given: []v1.EndpointSubset{{ 112 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("")}}, 113 Ports: []v1.EndpointPort{{Port: 111}}, 114 }}, 115 expect: []v1.EndpointSubset{{ 116 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("")}}, 117 Ports: []v1.EndpointPort{{Port: 111}}, 118 }}, 119 }, { 120 name: "one set, one notReady ip, empty UID, one port", 121 given: []v1.EndpointSubset{{ 122 NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("")}}, 123 Ports: []v1.EndpointPort{{Port: 111}}, 124 }}, 125 expect: []v1.EndpointSubset{{ 126 NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("")}}, 127 Ports: []v1.EndpointPort{{Port: 111}}, 128 }}, 129 }, { 130 name: "one set, two ips, one port", 131 given: []v1.EndpointSubset{{ 132 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}, {IP: "5.6.7.8"}}, 133 Ports: []v1.EndpointPort{{Port: 111}}, 134 }}, 135 expect: []v1.EndpointSubset{{ 136 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}, {IP: "5.6.7.8"}}, 137 Ports: []v1.EndpointPort{{Port: 111}}, 138 }}, 139 }, { 140 name: "one set, two mixed ips, one port", 141 given: []v1.EndpointSubset{{ 142 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 143 NotReadyAddresses: []v1.EndpointAddress{{IP: "5.6.7.8"}}, 144 Ports: []v1.EndpointPort{{Port: 111}}, 145 }}, 146 expect: []v1.EndpointSubset{{ 147 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 148 NotReadyAddresses: []v1.EndpointAddress{{IP: "5.6.7.8"}}, 149 Ports: []v1.EndpointPort{{Port: 111}}, 150 }}, 151 }, { 152 name: "one set, two duplicate ips, one port, notReady is covered by ready", 153 given: []v1.EndpointSubset{{ 154 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 155 NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 156 Ports: []v1.EndpointPort{{Port: 111}}, 157 }}, 158 expect: []v1.EndpointSubset{{ 159 NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 160 Ports: []v1.EndpointPort{{Port: 111}}, 161 }}, 162 }, { 163 name: "one set, one ip, two ports", 164 given: []v1.EndpointSubset{{ 165 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 166 Ports: []v1.EndpointPort{{Port: 111}, {Port: 222}}, 167 }}, 168 expect: []v1.EndpointSubset{{ 169 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 170 Ports: []v1.EndpointPort{{Port: 111}, {Port: 222}}, 171 }}, 172 }, { 173 name: "one set, dup ips, one port", 174 given: []v1.EndpointSubset{{ 175 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}, {IP: "1.2.3.4"}}, 176 Ports: []v1.EndpointPort{{Port: 111}}, 177 }}, 178 expect: []v1.EndpointSubset{{ 179 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 180 Ports: []v1.EndpointPort{{Port: 111}}, 181 }}, 182 }, { 183 name: "one set, dup ips, one port (IPv6)", 184 given: []v1.EndpointSubset{{ 185 Addresses: []v1.EndpointAddress{{IP: "beef::1"}, {IP: "beef::1"}}, 186 Ports: []v1.EndpointPort{{Port: 111}}, 187 }}, 188 expect: []v1.EndpointSubset{{ 189 Addresses: []v1.EndpointAddress{{IP: "beef::1"}}, 190 Ports: []v1.EndpointPort{{Port: 111}}, 191 }}, 192 }, { 193 name: "one set, dup ips with target-refs, one port", 194 given: []v1.EndpointSubset{{ 195 Addresses: []v1.EndpointAddress{ 196 {IP: "1.2.3.4", TargetRef: &fooObjRef}, 197 {IP: "1.2.3.4", TargetRef: &barObjRef}, 198 }, 199 Ports: []v1.EndpointPort{{Port: 111}}, 200 }}, 201 expect: []v1.EndpointSubset{{ 202 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: &fooObjRef}}, 203 Ports: []v1.EndpointPort{{Port: 111}}, 204 }}, 205 }, { 206 name: "one set, dup mixed ips with target-refs, one port", 207 given: []v1.EndpointSubset{{ 208 Addresses: []v1.EndpointAddress{ 209 {IP: "1.2.3.4", TargetRef: &fooObjRef}, 210 }, 211 NotReadyAddresses: []v1.EndpointAddress{ 212 {IP: "1.2.3.4", TargetRef: &barObjRef}, 213 }, 214 Ports: []v1.EndpointPort{{Port: 111}}, 215 }}, 216 expect: []v1.EndpointSubset{{ 217 // finding the same address twice is considered an error on input, only the first address+port 218 // reference is preserved 219 NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: &fooObjRef}}, 220 Ports: []v1.EndpointPort{{Port: 111}}, 221 }}, 222 }, { 223 name: "one set, one ip, dup ports", 224 given: []v1.EndpointSubset{{ 225 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 226 Ports: []v1.EndpointPort{{Port: 111}, {Port: 111}}, 227 }}, 228 expect: []v1.EndpointSubset{{ 229 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 230 Ports: []v1.EndpointPort{{Port: 111}}, 231 }}, 232 }, { 233 name: "two sets, dup ip, dup port", 234 given: []v1.EndpointSubset{{ 235 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 236 Ports: []v1.EndpointPort{{Port: 111}}, 237 }, { 238 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 239 Ports: []v1.EndpointPort{{Port: 111}}, 240 }}, 241 expect: []v1.EndpointSubset{{ 242 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 243 Ports: []v1.EndpointPort{{Port: 111}}, 244 }}, 245 }, { 246 name: "two sets, dup mixed ip, dup port", 247 given: []v1.EndpointSubset{{ 248 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 249 Ports: []v1.EndpointPort{{Port: 111}}, 250 }, { 251 NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 252 Ports: []v1.EndpointPort{{Port: 111}}, 253 }}, 254 expect: []v1.EndpointSubset{{ 255 NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 256 Ports: []v1.EndpointPort{{Port: 111}}, 257 }}, 258 }, { 259 name: "two sets, dup ip, two ports", 260 given: []v1.EndpointSubset{{ 261 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 262 Ports: []v1.EndpointPort{{Port: 111}}, 263 }, { 264 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 265 Ports: []v1.EndpointPort{{Port: 222}}, 266 }}, 267 expect: []v1.EndpointSubset{{ 268 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 269 Ports: []v1.EndpointPort{{Port: 111}, {Port: 222}}, 270 }}, 271 }, { 272 name: "two sets, dup ip, dup uids, two ports", 273 given: []v1.EndpointSubset{{ 274 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, 275 Ports: []v1.EndpointPort{{Port: 111}}, 276 }, { 277 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, 278 Ports: []v1.EndpointPort{{Port: 222}}, 279 }}, 280 expect: []v1.EndpointSubset{{ 281 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, 282 Ports: []v1.EndpointPort{{Port: 111}, {Port: 222}}, 283 }}, 284 }, { 285 name: "two sets, dup mixed ip, dup uids, two ports", 286 given: []v1.EndpointSubset{{ 287 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, 288 Ports: []v1.EndpointPort{{Port: 111}}, 289 }, { 290 NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, 291 Ports: []v1.EndpointPort{{Port: 222}}, 292 }}, 293 expect: []v1.EndpointSubset{{ 294 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, 295 Ports: []v1.EndpointPort{{Port: 111}}, 296 }, { 297 NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, 298 Ports: []v1.EndpointPort{{Port: 222}}, 299 }}, 300 }, { 301 name: "two sets, two ips, dup port", 302 given: []v1.EndpointSubset{{ 303 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 304 Ports: []v1.EndpointPort{{Port: 111}}, 305 }, { 306 Addresses: []v1.EndpointAddress{{IP: "5.6.7.8"}}, 307 Ports: []v1.EndpointPort{{Port: 111}}, 308 }}, 309 expect: []v1.EndpointSubset{{ 310 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}, {IP: "5.6.7.8"}}, 311 Ports: []v1.EndpointPort{{Port: 111}}, 312 }}, 313 }, { 314 name: "two set, dup ip, two uids, dup ports", 315 given: []v1.EndpointSubset{{ 316 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, 317 Ports: []v1.EndpointPort{{Port: 111}}, 318 }, { 319 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-2")}}, 320 Ports: []v1.EndpointPort{{Port: 111}}, 321 }}, 322 expect: []v1.EndpointSubset{{ 323 Addresses: []v1.EndpointAddress{ 324 {IP: "1.2.3.4", TargetRef: podRef("uid-1")}, 325 {IP: "1.2.3.4", TargetRef: podRef("uid-2")}, 326 }, 327 Ports: []v1.EndpointPort{{Port: 111}}, 328 }}, 329 }, { 330 name: "two set, dup ip, with and without uid, dup ports", 331 given: []v1.EndpointSubset{{ 332 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 333 Ports: []v1.EndpointPort{{Port: 111}}, 334 }, { 335 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-2")}}, 336 Ports: []v1.EndpointPort{{Port: 111}}, 337 }}, 338 expect: []v1.EndpointSubset{{ 339 Addresses: []v1.EndpointAddress{ 340 {IP: "1.2.3.4"}, 341 {IP: "1.2.3.4", TargetRef: podRef("uid-2")}, 342 }, 343 Ports: []v1.EndpointPort{{Port: 111}}, 344 }}, 345 }, { 346 name: "two sets, two ips, two dup ip with uid, dup port, wrong order", 347 given: []v1.EndpointSubset{{ 348 Addresses: []v1.EndpointAddress{{IP: "5.6.7.8"}}, 349 Ports: []v1.EndpointPort{{Port: 111}}, 350 }, { 351 Addresses: []v1.EndpointAddress{{IP: "5.6.7.8", TargetRef: podRef("uid-1")}}, 352 Ports: []v1.EndpointPort{{Port: 111}}, 353 }, { 354 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, 355 Ports: []v1.EndpointPort{{Port: 111}}, 356 }, { 357 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 358 Ports: []v1.EndpointPort{{Port: 111}}, 359 }}, 360 expect: []v1.EndpointSubset{{ 361 Addresses: []v1.EndpointAddress{ 362 {IP: "1.2.3.4"}, 363 {IP: "1.2.3.4", TargetRef: podRef("uid-1")}, 364 {IP: "5.6.7.8"}, 365 {IP: "5.6.7.8", TargetRef: podRef("uid-1")}, 366 }, 367 Ports: []v1.EndpointPort{{Port: 111}}, 368 }}, 369 }, { 370 name: "two sets, two mixed ips, two dup ip with uid, dup port, wrong order, ends up with split addresses", 371 given: []v1.EndpointSubset{{ 372 Addresses: []v1.EndpointAddress{{IP: "5.6.7.8"}}, 373 Ports: []v1.EndpointPort{{Port: 111}}, 374 }, { 375 NotReadyAddresses: []v1.EndpointAddress{{IP: "5.6.7.8", TargetRef: podRef("uid-1")}}, 376 Ports: []v1.EndpointPort{{Port: 111}}, 377 }, { 378 NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}}, 379 Ports: []v1.EndpointPort{{Port: 111}}, 380 }, { 381 NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 382 Ports: []v1.EndpointPort{{Port: 111}}, 383 }}, 384 expect: []v1.EndpointSubset{{ 385 Addresses: []v1.EndpointAddress{ 386 {IP: "5.6.7.8"}, 387 }, 388 NotReadyAddresses: []v1.EndpointAddress{ 389 {IP: "1.2.3.4"}, 390 {IP: "1.2.3.4", TargetRef: podRef("uid-1")}, 391 {IP: "5.6.7.8", TargetRef: podRef("uid-1")}, 392 }, 393 Ports: []v1.EndpointPort{{Port: 111}}, 394 }}, 395 }, { 396 name: "two sets, two ips, two ports", 397 given: []v1.EndpointSubset{{ 398 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 399 Ports: []v1.EndpointPort{{Port: 111}}, 400 }, { 401 Addresses: []v1.EndpointAddress{{IP: "5.6.7.8"}}, 402 Ports: []v1.EndpointPort{{Port: 222}}, 403 }}, 404 expect: []v1.EndpointSubset{{ 405 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 406 Ports: []v1.EndpointPort{{Port: 111}}, 407 }, { 408 Addresses: []v1.EndpointAddress{{IP: "5.6.7.8"}}, 409 Ports: []v1.EndpointPort{{Port: 222}}, 410 }}, 411 }, { 412 name: "four sets, three ips, three ports, jumbled", 413 given: []v1.EndpointSubset{{ 414 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 415 Ports: []v1.EndpointPort{{Port: 111}}, 416 }, { 417 Addresses: []v1.EndpointAddress{{IP: "1.2.3.5"}}, 418 Ports: []v1.EndpointPort{{Port: 222}}, 419 }, { 420 Addresses: []v1.EndpointAddress{{IP: "1.2.3.6"}}, 421 Ports: []v1.EndpointPort{{Port: 111}}, 422 }, { 423 Addresses: []v1.EndpointAddress{{IP: "1.2.3.5"}}, 424 Ports: []v1.EndpointPort{{Port: 333}}, 425 }}, 426 expect: []v1.EndpointSubset{{ 427 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}, {IP: "1.2.3.6"}}, 428 Ports: []v1.EndpointPort{{Port: 111}}, 429 }, { 430 Addresses: []v1.EndpointAddress{{IP: "1.2.3.5"}}, 431 Ports: []v1.EndpointPort{{Port: 222}, {Port: 333}}, 432 }}, 433 }, { 434 name: "four sets, three mixed ips, three ports, jumbled", 435 given: []v1.EndpointSubset{{ 436 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, 437 Ports: []v1.EndpointPort{{Port: 111}}, 438 }, { 439 NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.5"}}, 440 Ports: []v1.EndpointPort{{Port: 222}}, 441 }, { 442 Addresses: []v1.EndpointAddress{{IP: "1.2.3.6"}}, 443 Ports: []v1.EndpointPort{{Port: 111}}, 444 }, { 445 NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.5"}}, 446 Ports: []v1.EndpointPort{{Port: 333}}, 447 }}, 448 expect: []v1.EndpointSubset{{ 449 Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}, {IP: "1.2.3.6"}}, 450 Ports: []v1.EndpointPort{{Port: 111}}, 451 }, { 452 NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.5"}}, 453 Ports: []v1.EndpointPort{{Port: 222}, {Port: 333}}, 454 }}, 455 }, 456 } 457 458 for _, tc := range testCases { 459 result := RepackSubsets(tc.given) 460 if !reflect.DeepEqual(result, SortSubsets(tc.expect)) { 461 t.Errorf("case %q: expected %s, got %s", tc.name, dump.Pretty(SortSubsets(tc.expect)), dump.Pretty(result)) 462 } 463 } 464 }