github.com/cilium/cilium@v1.16.2/pkg/ipam/cidrset/cidr_set_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 // Copyright The Kubernetes Authors. 4 5 package cidrset 6 7 import ( 8 "math/big" 9 "net" 10 "reflect" 11 "testing" 12 ) 13 14 func TestCIDRSetFullyAllocated(t *testing.T) { 15 cases := []struct { 16 clusterCIDRStr string 17 subNetMaskSize int 18 expectedCIDR string 19 description string 20 }{ 21 { 22 clusterCIDRStr: "127.123.234.0/30", 23 subNetMaskSize: 30, 24 expectedCIDR: "127.123.234.0/30", 25 description: "Fully allocated CIDR with IPv4", 26 }, 27 { 28 clusterCIDRStr: "beef:1234::/30", 29 subNetMaskSize: 30, 30 expectedCIDR: "beef:1234::/30", 31 description: "Fully allocated CIDR with IPv6", 32 }, 33 } 34 for _, tc := range cases { 35 _, clusterCIDR, _ := net.ParseCIDR(tc.clusterCIDRStr) 36 a, err := NewCIDRSet(clusterCIDR, tc.subNetMaskSize) 37 if err != nil { 38 t.Fatalf("unexpected error: %v for %v", err, tc.description) 39 } 40 p, err := a.AllocateNext() 41 if err != nil { 42 t.Fatalf("unexpected error: %v for %v", err, tc.description) 43 } 44 if p.String() != tc.expectedCIDR { 45 t.Fatalf("unexpected allocated cidr: %v, expecting %v for %v", 46 p.String(), tc.expectedCIDR, tc.description) 47 } 48 49 _, err = a.AllocateNext() 50 if err == nil { 51 t.Fatalf("expected error because of fully-allocated range for %v", tc.description) 52 } 53 54 a.Release(p) 55 56 p, err = a.AllocateNext() 57 if err != nil { 58 t.Fatalf("unexpected error: %v for %v", err, tc.description) 59 } 60 if p.String() != tc.expectedCIDR { 61 t.Fatalf("unexpected allocated cidr: %v, expecting %v for %v", 62 p.String(), tc.expectedCIDR, tc.description) 63 } 64 _, err = a.AllocateNext() 65 if err == nil { 66 t.Fatalf("expected error because of fully-allocated range for %v", tc.description) 67 } 68 } 69 } 70 71 func TestIndexToCIDRBlock(t *testing.T) { 72 cases := []struct { 73 clusterCIDRStr string 74 subnetMaskSize int 75 index int 76 CIDRBlock string 77 description string 78 }{ 79 { 80 clusterCIDRStr: "127.123.3.0/16", 81 subnetMaskSize: 24, 82 index: 0, 83 CIDRBlock: "127.123.0.0/24", 84 description: "1st IP address indexed with IPv4", 85 }, 86 { 87 clusterCIDRStr: "127.123.0.0/16", 88 subnetMaskSize: 24, 89 index: 15, 90 CIDRBlock: "127.123.15.0/24", 91 description: "16th IP address indexed with IPv4", 92 }, 93 { 94 clusterCIDRStr: "192.168.5.219/28", 95 subnetMaskSize: 32, 96 index: 5, 97 CIDRBlock: "192.168.5.213/32", 98 description: "5th IP address indexed with IPv4", 99 }, 100 { 101 clusterCIDRStr: "2001:0db8:1234:3::/48", 102 subnetMaskSize: 64, 103 index: 0, 104 CIDRBlock: "2001:db8:1234::/64", 105 description: "1st IP address indexed with IPv6 /64", 106 }, 107 { 108 clusterCIDRStr: "2001:0db8:1234::/48", 109 subnetMaskSize: 64, 110 index: 15, 111 CIDRBlock: "2001:db8:1234:f::/64", 112 description: "16th IP address indexed with IPv6 /64", 113 }, 114 { 115 clusterCIDRStr: "2001:0db8:85a3::8a2e:0370:7334/50", 116 subnetMaskSize: 63, 117 index: 6425, 118 CIDRBlock: "2001:db8:85a3:3232::/63", 119 description: "6426th IP address indexed with IPv6 /63", 120 }, 121 { 122 clusterCIDRStr: "2001:0db8::/32", 123 subnetMaskSize: 48, 124 index: 0, 125 CIDRBlock: "2001:db8::/48", 126 description: "1st IP address indexed with IPv6 /48", 127 }, 128 { 129 clusterCIDRStr: "2001:0db8::/32", 130 subnetMaskSize: 48, 131 index: 15, 132 CIDRBlock: "2001:db8:f::/48", 133 description: "16th IP address indexed with IPv6 /48", 134 }, 135 { 136 clusterCIDRStr: "2001:0db8:85a3::8a2e:0370:7334/32", 137 subnetMaskSize: 48, 138 index: 6425, 139 CIDRBlock: "2001:db8:1919::/48", 140 description: "6426th IP address indexed with IPv6 /48", 141 }, 142 { 143 clusterCIDRStr: "2001:0db8:1234:ff00::/56", 144 subnetMaskSize: 72, 145 index: 0, 146 CIDRBlock: "2001:db8:1234:ff00::/72", 147 description: "1st IP address indexed with IPv6 /72", 148 }, 149 { 150 clusterCIDRStr: "2001:0db8:1234:ff00::/56", 151 subnetMaskSize: 72, 152 index: 15, 153 CIDRBlock: "2001:db8:1234:ff00:f00::/72", 154 description: "16th IP address indexed with IPv6 /72", 155 }, 156 { 157 clusterCIDRStr: "2001:0db8:1234:ff00::0370:7334/56", 158 subnetMaskSize: 72, 159 index: 6425, 160 CIDRBlock: "2001:db8:1234:ff19:1900::/72", 161 description: "6426th IP address indexed with IPv6 /72", 162 }, 163 { 164 clusterCIDRStr: "2001:0db8:1234:0:1234::/80", 165 subnetMaskSize: 96, 166 index: 0, 167 CIDRBlock: "2001:db8:1234:0:1234::/96", 168 description: "1st IP address indexed with IPv6 /96", 169 }, 170 { 171 clusterCIDRStr: "2001:0db8:1234:0:1234::/80", 172 subnetMaskSize: 96, 173 index: 15, 174 CIDRBlock: "2001:db8:1234:0:1234:f::/96", 175 description: "16th IP address indexed with IPv6 /96", 176 }, 177 { 178 clusterCIDRStr: "2001:0db8:1234:ff00::0370:7334/80", 179 subnetMaskSize: 96, 180 index: 6425, 181 CIDRBlock: "2001:db8:1234:ff00:0:1919::/96", 182 description: "6426th IP address indexed with IPv6 /96", 183 }, 184 } 185 for _, tc := range cases { 186 _, clusterCIDR, _ := net.ParseCIDR(tc.clusterCIDRStr) 187 a, err := NewCIDRSet(clusterCIDR, tc.subnetMaskSize) 188 if err != nil { 189 t.Fatalf("error for %v ", tc.description) 190 } 191 cidr := a.indexToCIDRBlock(tc.index) 192 if cidr.String() != tc.CIDRBlock { 193 t.Fatalf("error for %v index %d %s", tc.description, tc.index, cidr.String()) 194 } 195 } 196 } 197 198 func TestCIDRSet_RandomishAllocation(t *testing.T) { 199 cases := []struct { 200 clusterCIDRStr string 201 description string 202 }{ 203 { 204 clusterCIDRStr: "127.123.234.0/16", 205 description: "RandomishAllocation with IPv4", 206 }, 207 { 208 clusterCIDRStr: "beef:1234::/16", 209 description: "RandomishAllocation with IPv6", 210 }, 211 } 212 for _, tc := range cases { 213 _, clusterCIDR, _ := net.ParseCIDR(tc.clusterCIDRStr) 214 a, err := NewCIDRSet(clusterCIDR, 24) 215 if err != nil { 216 t.Fatalf("Error allocating CIDRSet for %v", tc.description) 217 } 218 // allocate all the CIDRs 219 var cidrs []*net.IPNet 220 221 for i := 0; i < 256; i++ { 222 if c, err := a.AllocateNext(); err == nil { 223 cidrs = append(cidrs, c) 224 } else { 225 t.Fatalf("unexpected error: %v for %v", err, tc.description) 226 } 227 } 228 229 //var err error 230 _, err = a.AllocateNext() 231 if err == nil { 232 t.Fatalf("expected error because of fully-allocated range for %v", tc.description) 233 } 234 // release them all 235 for i := 0; i < len(cidrs); i++ { 236 a.Release(cidrs[i]) 237 } 238 239 // allocate the CIDRs again 240 var rcidrs []*net.IPNet 241 for i := 0; i < 256; i++ { 242 if c, err := a.AllocateNext(); err == nil { 243 rcidrs = append(rcidrs, c) 244 } else { 245 t.Fatalf("unexpected error: %d, %v for %v", i, err, tc.description) 246 } 247 } 248 _, err = a.AllocateNext() 249 if err == nil { 250 t.Fatalf("expected error because of fully-allocated range for %v", tc.description) 251 } 252 253 if !reflect.DeepEqual(cidrs, rcidrs) { 254 t.Fatalf("expected re-allocated cidrs are the same collection for %v", tc.description) 255 } 256 } 257 } 258 259 func TestCIDRSet_AllocationOccupied(t *testing.T) { 260 cases := []struct { 261 clusterCIDRStr string 262 description string 263 }{ 264 { 265 clusterCIDRStr: "127.123.234.0/16", 266 description: "AllocationOccupied with IPv4", 267 }, 268 { 269 clusterCIDRStr: "beef:1234::/16", 270 description: "AllocationOccupied with IPv6", 271 }, 272 } 273 for _, tc := range cases { 274 _, clusterCIDR, _ := net.ParseCIDR(tc.clusterCIDRStr) 275 a, err := NewCIDRSet(clusterCIDR, 24) 276 if err != nil { 277 t.Fatalf("Error allocating CIDRSet for %v", tc.description) 278 } 279 // allocate all the CIDRs 280 var cidrs []*net.IPNet 281 var numCIDRs = 256 282 283 for i := 0; i < numCIDRs; i++ { 284 if c, err := a.AllocateNext(); err == nil { 285 cidrs = append(cidrs, c) 286 } else { 287 t.Fatalf("unexpected error: %v for %v", err, tc.description) 288 } 289 } 290 291 //var err error 292 _, err = a.AllocateNext() 293 if err == nil { 294 t.Fatalf("expected error because of fully-allocated range for %v", tc.description) 295 } 296 // release them all 297 for i := 0; i < len(cidrs); i++ { 298 a.Release(cidrs[i]) 299 } 300 // occupy the last 128 CIDRs 301 for i := numCIDRs / 2; i < numCIDRs; i++ { 302 a.Occupy(cidrs[i]) 303 } 304 305 // allocate the first 128 CIDRs again 306 var rcidrs []*net.IPNet 307 for i := 0; i < numCIDRs/2; i++ { 308 if c, err := a.AllocateNext(); err == nil { 309 rcidrs = append(rcidrs, c) 310 } else { 311 t.Fatalf("unexpected error: %d, %v for %v", i, err, tc.description) 312 } 313 } 314 _, err = a.AllocateNext() 315 if err == nil { 316 t.Fatalf("expected error because of fully-allocated range for %v", tc.description) 317 } 318 319 // check Occupy() work properly 320 for i := numCIDRs / 2; i < numCIDRs; i++ { 321 rcidrs = append(rcidrs, cidrs[i]) 322 } 323 if !reflect.DeepEqual(cidrs, rcidrs) { 324 t.Fatalf("expected re-allocated cidrs are the same collection for %v", tc.description) 325 } 326 } 327 } 328 329 func TestGetBitforCIDR(t *testing.T) { 330 cases := []struct { 331 clusterCIDRStr string 332 subNetMaskSize int 333 subNetCIDRStr string 334 expectedBit int 335 expectErr bool 336 description string 337 }{ 338 { 339 clusterCIDRStr: "127.0.0.0/8", 340 subNetMaskSize: 16, 341 subNetCIDRStr: "127.0.0.0/16", 342 expectedBit: 0, 343 expectErr: false, 344 description: "Get 0 Bit with IPv4", 345 }, 346 { 347 clusterCIDRStr: "be00::/8", 348 subNetMaskSize: 16, 349 subNetCIDRStr: "be00::/16", 350 expectedBit: 0, 351 expectErr: false, 352 description: "Get 0 Bit with IPv6", 353 }, 354 { 355 clusterCIDRStr: "127.0.0.0/8", 356 subNetMaskSize: 16, 357 subNetCIDRStr: "127.123.0.0/16", 358 expectedBit: 123, 359 expectErr: false, 360 description: "Get 123rd Bit with IPv4", 361 }, 362 { 363 clusterCIDRStr: "be00::/8", 364 subNetMaskSize: 16, 365 subNetCIDRStr: "beef::/16", 366 expectedBit: 0xef, 367 expectErr: false, 368 description: "Get xef Bit with IPv6", 369 }, 370 { 371 clusterCIDRStr: "127.0.0.0/8", 372 subNetMaskSize: 16, 373 subNetCIDRStr: "127.168.0.0/16", 374 expectedBit: 168, 375 expectErr: false, 376 description: "Get 168th Bit with IPv4", 377 }, 378 { 379 clusterCIDRStr: "be00::/8", 380 subNetMaskSize: 16, 381 subNetCIDRStr: "be68::/16", 382 expectedBit: 0x68, 383 expectErr: false, 384 description: "Get x68th Bit with IPv6", 385 }, 386 { 387 clusterCIDRStr: "127.0.0.0/8", 388 subNetMaskSize: 16, 389 subNetCIDRStr: "127.224.0.0/16", 390 expectedBit: 224, 391 expectErr: false, 392 description: "Get 224th Bit with IPv4", 393 }, 394 { 395 clusterCIDRStr: "be00::/8", 396 subNetMaskSize: 16, 397 subNetCIDRStr: "be24::/16", 398 expectedBit: 0x24, 399 expectErr: false, 400 description: "Get x24th Bit with IPv6", 401 }, 402 { 403 clusterCIDRStr: "192.168.0.0/16", 404 subNetMaskSize: 24, 405 subNetCIDRStr: "192.168.12.0/24", 406 expectedBit: 12, 407 expectErr: false, 408 description: "Get 12th Bit with IPv4", 409 }, 410 { 411 clusterCIDRStr: "beef::/16", 412 subNetMaskSize: 24, 413 subNetCIDRStr: "beef:1200::/24", 414 expectedBit: 0x12, 415 expectErr: false, 416 description: "Get x12th Bit with IPv6", 417 }, 418 { 419 clusterCIDRStr: "192.168.0.0/16", 420 subNetMaskSize: 24, 421 subNetCIDRStr: "192.168.151.0/24", 422 expectedBit: 151, 423 expectErr: false, 424 description: "Get 151st Bit with IPv4", 425 }, 426 { 427 clusterCIDRStr: "beef::/16", 428 subNetMaskSize: 24, 429 subNetCIDRStr: "beef:9700::/24", 430 expectedBit: 0x97, 431 expectErr: false, 432 description: "Get x97st Bit with IPv6", 433 }, 434 { 435 clusterCIDRStr: "192.168.0.0/16", 436 subNetMaskSize: 24, 437 subNetCIDRStr: "127.168.224.0/24", 438 expectErr: true, 439 description: "Get error with IPv4", 440 }, 441 { 442 clusterCIDRStr: "beef::/16", 443 subNetMaskSize: 24, 444 subNetCIDRStr: "2001:db00::/24", 445 expectErr: true, 446 description: "Get error with IPv6", 447 }, 448 } 449 450 for _, tc := range cases { 451 _, clusterCIDR, err := net.ParseCIDR(tc.clusterCIDRStr) 452 if err != nil { 453 t.Fatalf("unexpected error: %v for %v", err, tc.description) 454 } 455 456 cs, err := NewCIDRSet(clusterCIDR, tc.subNetMaskSize) 457 if err != nil { 458 t.Fatalf("Error allocating CIDRSet for %v", tc.description) 459 } 460 _, subnetCIDR, err := net.ParseCIDR(tc.subNetCIDRStr) 461 if err != nil { 462 t.Fatalf("unexpected error: %v for %v", err, tc.description) 463 } 464 465 got, err := cs.getIndexForIP(subnetCIDR.IP) 466 if err == nil && tc.expectErr { 467 t.Errorf("expected error but got null for %v", tc.description) 468 continue 469 } 470 471 if err != nil && !tc.expectErr { 472 t.Errorf("unexpected error: %v for %v", err, tc.description) 473 continue 474 } 475 476 if got != tc.expectedBit { 477 t.Errorf("expected %v, but got %v for %v", tc.expectedBit, got, tc.description) 478 } 479 } 480 } 481 482 func TestOccupy(t *testing.T) { 483 cases := []struct { 484 clusterCIDRStr string 485 subNetMaskSize int 486 subNetCIDRStr string 487 expectedUsedBegin int 488 expectedUsedEnd int 489 expectErr bool 490 description string 491 }{ 492 { 493 clusterCIDRStr: "127.0.0.0/8", 494 subNetMaskSize: 16, 495 subNetCIDRStr: "127.0.0.0/8", 496 expectedUsedBegin: 0, 497 expectedUsedEnd: 255, 498 expectErr: false, 499 description: "Occupy all Bits with IPv4", 500 }, 501 { 502 clusterCIDRStr: "2001:beef:1200::/40", 503 subNetMaskSize: 48, 504 subNetCIDRStr: "2001:beef:1200::/40", 505 expectedUsedBegin: 0, 506 expectedUsedEnd: 255, 507 expectErr: false, 508 description: "Occupy all Bits with IPv6", 509 }, 510 { 511 clusterCIDRStr: "127.0.0.0/8", 512 subNetMaskSize: 16, 513 subNetCIDRStr: "127.0.0.0/2", 514 expectedUsedBegin: 0, 515 expectedUsedEnd: 255, 516 expectErr: false, 517 description: "Occupy every Bit with IPv4", 518 }, 519 { 520 clusterCIDRStr: "2001:beef:1200::/40", 521 subNetMaskSize: 48, 522 subNetCIDRStr: "2001:beef:1234::/34", 523 expectedUsedBegin: 0, 524 expectedUsedEnd: 255, 525 expectErr: false, 526 description: "Occupy every Bit with IPv6", 527 }, 528 { 529 clusterCIDRStr: "127.0.0.0/8", 530 subNetMaskSize: 16, 531 subNetCIDRStr: "127.0.0.0/16", 532 expectedUsedBegin: 0, 533 expectedUsedEnd: 0, 534 expectErr: false, 535 description: "Occupy 1st Bit with IPv4", 536 }, 537 { 538 clusterCIDRStr: "2001:beef:1200::/40", 539 subNetMaskSize: 48, 540 subNetCIDRStr: "2001:beef:1200::/48", 541 expectedUsedBegin: 0, 542 expectedUsedEnd: 0, 543 expectErr: false, 544 description: "Occupy 1st Bit with IPv6", 545 }, 546 { 547 clusterCIDRStr: "127.0.0.0/8", 548 subNetMaskSize: 32, 549 subNetCIDRStr: "127.0.0.0/16", 550 expectedUsedBegin: 0, 551 expectedUsedEnd: 65535, 552 expectErr: false, 553 description: "Occupy 65535 Bits with IPv4", 554 }, 555 { 556 clusterCIDRStr: "2001:beef:1200::/48", 557 subNetMaskSize: 64, 558 subNetCIDRStr: "2001:beef:1200::/48", 559 expectedUsedBegin: 0, 560 expectedUsedEnd: 65535, 561 expectErr: false, 562 description: "Occupy 65535 Bits with IPv6", 563 }, 564 { 565 clusterCIDRStr: "127.0.0.0/7", 566 subNetMaskSize: 16, 567 subNetCIDRStr: "127.0.0.0/15", 568 expectedUsedBegin: 256, 569 expectedUsedEnd: 257, 570 expectErr: false, 571 description: "Occupy 257th Bit with IPv4", 572 }, 573 { 574 clusterCIDRStr: "2001:beef:7f00::/39", 575 subNetMaskSize: 48, 576 subNetCIDRStr: "2001:beef:7f00::/47", 577 expectedUsedBegin: 256, 578 expectedUsedEnd: 257, 579 expectErr: false, 580 description: "Occupy 257th Bit with IPv6", 581 }, 582 { 583 clusterCIDRStr: "127.0.0.0/7", 584 subNetMaskSize: 15, 585 subNetCIDRStr: "127.0.0.0/15", 586 expectedUsedBegin: 128, 587 expectedUsedEnd: 128, 588 expectErr: false, 589 description: "Occupy 128th Bit with IPv4", 590 }, 591 { 592 clusterCIDRStr: "2001:beef:7f00::/39", 593 subNetMaskSize: 47, 594 subNetCIDRStr: "2001:beef:7f00::/47", 595 expectedUsedBegin: 128, 596 expectedUsedEnd: 128, 597 expectErr: false, 598 description: "Occupy 128th Bit with IPv6", 599 }, 600 { 601 clusterCIDRStr: "127.0.0.0/7", 602 subNetMaskSize: 18, 603 subNetCIDRStr: "127.0.0.0/15", 604 expectedUsedBegin: 1024, 605 expectedUsedEnd: 1031, 606 expectErr: false, 607 description: "Occupy 1031st Bit with IPv4", 608 }, 609 { 610 clusterCIDRStr: "2001:beef:7f00::/39", 611 subNetMaskSize: 50, 612 subNetCIDRStr: "2001:beef:7f00::/47", 613 expectedUsedBegin: 1024, 614 expectedUsedEnd: 1031, 615 expectErr: false, 616 description: "Occupy 1031st Bit with IPv6", 617 }, 618 } 619 620 for _, tc := range cases { 621 _, clusterCIDR, err := net.ParseCIDR(tc.clusterCIDRStr) 622 if err != nil { 623 t.Fatalf("unexpected error: %v for %v", err, tc.description) 624 } 625 626 cs, err := NewCIDRSet(clusterCIDR, tc.subNetMaskSize) 627 if err != nil { 628 t.Fatalf("Error allocating CIDRSet for %v", tc.description) 629 } 630 631 _, subnetCIDR, err := net.ParseCIDR(tc.subNetCIDRStr) 632 if err != nil { 633 t.Fatalf("unexpected error: %v for %v", err, tc.description) 634 } 635 636 err = cs.Occupy(subnetCIDR) 637 if err == nil && tc.expectErr { 638 t.Errorf("expected error but got none for %v", tc.description) 639 continue 640 } 641 if err != nil && !tc.expectErr { 642 t.Errorf("unexpected error: %v for %v", err, tc.description) 643 continue 644 } 645 646 expectedUsed := big.Int{} 647 for i := tc.expectedUsedBegin; i <= tc.expectedUsedEnd; i++ { 648 expectedUsed.SetBit(&expectedUsed, i, 1) 649 } 650 if expectedUsed.Cmp(&cs.used) != 0 { 651 t.Errorf("error for %v", tc.description) 652 } 653 } 654 } 655 656 func TestCIDRSetv6(t *testing.T) { 657 cases := []struct { 658 clusterCIDRStr string 659 subNetMaskSize int 660 expectedCIDR string 661 expectedCIDR2 string 662 expectErr bool 663 description string 664 }{ 665 { 666 clusterCIDRStr: "127.0.0.0/8", 667 subNetMaskSize: 32, 668 expectErr: false, 669 expectedCIDR: "127.0.0.0/32", 670 expectedCIDR2: "127.0.0.1/32", 671 description: "Max cluster subnet size with IPv4", 672 }, 673 { 674 clusterCIDRStr: "beef:1234::/32", 675 subNetMaskSize: 49, 676 expectErr: true, 677 description: "Max cluster subnet size with IPv6", 678 }, 679 { 680 clusterCIDRStr: "2001:beef:1234:369b::/60", 681 subNetMaskSize: 64, 682 expectedCIDR: "2001:beef:1234:3690::/64", 683 expectedCIDR2: "2001:beef:1234:3691::/64", 684 expectErr: false, 685 description: "Allocate a few IPv6", 686 }, 687 } 688 for _, tc := range cases { 689 t.Run(tc.description, func(t *testing.T) { 690 _, clusterCIDR, _ := net.ParseCIDR(tc.clusterCIDRStr) 691 a, err := NewCIDRSet(clusterCIDR, tc.subNetMaskSize) 692 if gotErr := err != nil; gotErr != tc.expectErr { 693 t.Fatalf("NewCIDRSet(%v, %v) = %v, %v; gotErr = %t, want %t", clusterCIDR, tc.subNetMaskSize, a, err, gotErr, tc.expectErr) 694 } 695 if a == nil { 696 return 697 } 698 p, err := a.AllocateNext() 699 if err == nil && tc.expectErr { 700 t.Errorf("a.AllocateNext() = nil, want error") 701 } 702 if err != nil && !tc.expectErr { 703 t.Errorf("a.AllocateNext() = %+v, want no error", err) 704 } 705 if !tc.expectErr { 706 if p != nil && p.String() != tc.expectedCIDR { 707 t.Fatalf("a.AllocateNext() got %+v, want %+v", p.String(), tc.expectedCIDR) 708 } 709 } 710 p2, err := a.AllocateNext() 711 if err == nil && tc.expectErr { 712 t.Errorf("a.AllocateNext() = nil, want error") 713 } 714 if err != nil && !tc.expectErr { 715 t.Errorf("a.AllocateNext() = %+v, want no error", err) 716 } 717 if !tc.expectErr { 718 if p2 != nil && p2.String() != tc.expectedCIDR2 { 719 t.Fatalf("a.AllocateNext() got %+v, want %+v", p2.String(), tc.expectedCIDR) 720 } 721 } 722 }) 723 } 724 } 725 726 func TestInvalidSubNetMaskSize(t *testing.T) { 727 cases := []struct { 728 clusterCIDRStr string 729 subNetMaskSize int 730 expectErr bool 731 description string 732 }{ 733 { 734 clusterCIDRStr: "10.0.0.0/24", 735 subNetMaskSize: 32, 736 expectErr: false, 737 description: "Check valid subnet mask size with IPv4", 738 }, 739 { 740 clusterCIDRStr: "2001:beef:1234:369b::/60", 741 subNetMaskSize: 64, 742 expectErr: false, 743 description: "Check valid subnet mask size with IPv6", 744 }, 745 { 746 clusterCIDRStr: "10.0.0.0/24", 747 subNetMaskSize: 64, 748 expectErr: true, 749 description: "Check invalid subnet mask size with IPv4", 750 }, 751 { 752 clusterCIDRStr: "2001:beef:1234:369b::/60", 753 subNetMaskSize: 130, 754 expectErr: true, 755 description: "Check invalid subnet mask size with IPv6", 756 }, 757 } 758 for _, tc := range cases { 759 t.Run(tc.description, func(t *testing.T) { 760 _, clusterCIDR, _ := net.ParseCIDR(tc.clusterCIDRStr) 761 a, err := NewCIDRSet(clusterCIDR, tc.subNetMaskSize) 762 if gotErr := err != nil; gotErr != tc.expectErr { 763 t.Fatalf("NewCIDRSet(%v, %v) = %v, %v; gotErr = %t, want %t", clusterCIDR, tc.subNetMaskSize, a, err, gotErr, tc.expectErr) 764 } 765 }) 766 } 767 }