github.com/operator-framework/operator-lifecycle-manager@v0.30.0/pkg/controller/operators/olm/groups_test.go (about) 1 package olm 2 3 import ( 4 "strings" 5 "testing" 6 7 operatorsv1 "github.com/operator-framework/api/pkg/operators/v1" 8 opregistry "github.com/operator-framework/operator-registry/pkg/registry" 9 "github.com/stretchr/testify/require" 10 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 12 "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/cache" 13 ) 14 15 func buildAPIOperatorGroup(namespace, name string, targets []string, gvks []string) *operatorsv1.OperatorGroup { 16 return &operatorsv1.OperatorGroup{ 17 ObjectMeta: metav1.ObjectMeta{ 18 Namespace: namespace, 19 Name: name, 20 Annotations: map[string]string{ 21 operatorsv1.OperatorGroupProvidedAPIsAnnotationKey: strings.Join(gvks, ","), 22 }, 23 }, 24 Status: operatorsv1.OperatorGroupStatus{ 25 Namespaces: targets, 26 }, 27 } 28 } 29 func TestNewOperatorGroup(t *testing.T) { 30 tests := []struct { 31 name string 32 in *operatorsv1.OperatorGroup 33 want *OperatorGroup 34 }{ 35 { 36 name: "NoTargetNamespaces/NoProvidedAPIs", 37 in: buildAPIOperatorGroup("ns", "empty-group", nil, nil), 38 want: &OperatorGroup{ 39 namespace: "ns", 40 name: "empty-group", 41 targets: make(NamespaceSet), 42 providedAPIs: make(cache.APISet), 43 }, 44 }, 45 { 46 name: "OneTargetNamespace/NoProvidedAPIs", 47 in: buildAPIOperatorGroup("ns", "empty-group", []string{"ns-1"}, nil), 48 want: &OperatorGroup{ 49 namespace: "ns", 50 name: "empty-group", 51 targets: NamespaceSet{ 52 "ns": {}, 53 "ns-1": {}, 54 }, 55 providedAPIs: make(cache.APISet), 56 }, 57 }, 58 { 59 name: "OwnTargetNamespace/NoProvidedAPIs", 60 in: buildAPIOperatorGroup("ns", "empty-group", []string{"ns"}, nil), 61 want: &OperatorGroup{ 62 namespace: "ns", 63 name: "empty-group", 64 targets: NamespaceSet{ 65 "ns": {}, 66 }, 67 providedAPIs: make(cache.APISet), 68 }, 69 }, 70 { 71 name: "MultipleTargetNamespaces/NoProvidedAPIs", 72 in: buildAPIOperatorGroup("ns", "empty-group", []string{"ns-1", "ns-2"}, nil), 73 want: &OperatorGroup{ 74 namespace: "ns", 75 name: "empty-group", 76 targets: NamespaceSet{ 77 "ns": {}, 78 "ns-1": {}, 79 "ns-2": {}, 80 }, 81 providedAPIs: make(cache.APISet), 82 }, 83 }, 84 { 85 name: "AllTargetNamespaces/NoProvidedAPIs", 86 in: buildAPIOperatorGroup("ns", "empty-group", []string{metav1.NamespaceAll}, nil), 87 want: &OperatorGroup{ 88 namespace: "ns", 89 name: "empty-group", 90 targets: NamespaceSet{ 91 metav1.NamespaceAll: {}, 92 }, 93 providedAPIs: make(cache.APISet), 94 }, 95 }, 96 { 97 name: "OneTargetNamespace/OneProvidedAPI", 98 in: buildAPIOperatorGroup("ns", "group", []string{"ns-1"}, []string{"Goose.v1alpha1.birds.com"}), 99 want: &OperatorGroup{ 100 namespace: "ns", 101 name: "group", 102 targets: NamespaceSet{ 103 "ns": {}, 104 "ns-1": {}, 105 }, 106 providedAPIs: cache.APISet{ 107 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 108 }, 109 }, 110 }, 111 { 112 name: "OneTargetNamespace/BadProvidedAPI", 113 in: buildAPIOperatorGroup("ns", "group", []string{"ns-1"}, []string{"Goose.v1alpha1"}), 114 want: &OperatorGroup{ 115 namespace: "ns", 116 name: "group", 117 targets: NamespaceSet{ 118 "ns": {}, 119 "ns-1": {}, 120 }, 121 providedAPIs: make(cache.APISet), 122 }, 123 }, 124 { 125 name: "OneTargetNamespace/MultipleProvidedAPIs/OneBad", 126 in: buildAPIOperatorGroup("ns", "group", []string{"ns-1"}, []string{"Goose.v1alpha1,Moose.v1alpha1.mammals.com"}), 127 want: &OperatorGroup{ 128 namespace: "ns", 129 name: "group", 130 targets: NamespaceSet{ 131 "ns": {}, 132 "ns-1": {}, 133 }, 134 providedAPIs: cache.APISet{ 135 opregistry.APIKey{Group: "mammals.com", Version: "v1alpha1", Kind: "Moose"}: {}, 136 }, 137 }, 138 }, 139 { 140 name: "OneTargetNamespace/MultipleProvidedAPIs", 141 in: buildAPIOperatorGroup("ns", "group", []string{"ns-1"}, []string{"Goose.v1alpha1.birds.com,Moose.v1alpha1.mammals.com"}), 142 want: &OperatorGroup{ 143 namespace: "ns", 144 name: "group", 145 targets: NamespaceSet{ 146 "ns": {}, 147 "ns-1": {}, 148 }, 149 providedAPIs: cache.APISet{ 150 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 151 opregistry.APIKey{Group: "mammals.com", Version: "v1alpha1", Kind: "Moose"}: {}, 152 }, 153 }, 154 }, 155 } 156 157 for _, tt := range tests { 158 t.Run(tt.name, func(t *testing.T) { 159 group := NewOperatorGroup(tt.in) 160 require.NotNil(t, group) 161 require.EqualValues(t, tt.want, group) 162 }) 163 } 164 } 165 166 func TestNamespaceSetIntersection(t *testing.T) { 167 type input struct { 168 left NamespaceSet 169 right NamespaceSet 170 } 171 tests := []struct { 172 name string 173 in input 174 want NamespaceSet 175 }{ 176 { 177 name: "EmptySets", 178 in: input{ 179 left: make(NamespaceSet), 180 right: make(NamespaceSet), 181 }, 182 want: make(NamespaceSet), 183 }, 184 { 185 name: "EmptyLeft/MultipleRight/NoIntersection", 186 in: input{ 187 left: make(NamespaceSet), 188 right: NamespaceSet{ 189 "ns": {}, 190 "ns-1": {}, 191 "ns-2": {}, 192 }, 193 }, 194 want: make(NamespaceSet), 195 }, 196 { 197 name: "MultipleLeft/EmptyRight/NoIntersection", 198 in: input{ 199 left: NamespaceSet{ 200 "ns": {}, 201 "ns-1": {}, 202 "ns-2": {}, 203 }, 204 right: make(NamespaceSet), 205 }, 206 want: make(NamespaceSet), 207 }, 208 { 209 name: "OneLeft/OneRight/Intersection", 210 in: input{ 211 left: NamespaceSet{ 212 "ns": {}, 213 }, 214 right: NamespaceSet{ 215 "ns": {}, 216 }, 217 }, 218 want: NamespaceSet{ 219 "ns": {}, 220 }, 221 }, 222 { 223 name: "MultipleLeft/MultipleRight/SomeIntersect", 224 in: input{ 225 left: NamespaceSet{ 226 "ns": {}, 227 "ns-1": {}, 228 "ns-2": {}, 229 }, 230 right: NamespaceSet{ 231 "ns": {}, 232 "ns-1": {}, 233 "ns-3": {}, 234 }, 235 }, 236 want: NamespaceSet{ 237 "ns": {}, 238 "ns-1": {}, 239 }, 240 }, 241 { 242 name: "MultipleLeft/MultipleRight/AllIntersect", 243 in: input{ 244 left: NamespaceSet{ 245 "ns": {}, 246 "ns-1": {}, 247 "ns-2": {}, 248 }, 249 right: NamespaceSet{ 250 "ns": {}, 251 "ns-1": {}, 252 "ns-2": {}, 253 }, 254 }, 255 want: NamespaceSet{ 256 "ns": {}, 257 "ns-1": {}, 258 "ns-2": {}, 259 }, 260 }, 261 { 262 name: "AllLeft/MultipleRight/RightIsIntersection", 263 in: input{ 264 left: NamespaceSet{ 265 "": {}, 266 }, 267 right: NamespaceSet{ 268 "ns": {}, 269 "ns-1": {}, 270 "ns-2": {}, 271 }, 272 }, 273 want: NamespaceSet{ 274 "ns": {}, 275 "ns-1": {}, 276 "ns-2": {}, 277 }, 278 }, 279 { 280 name: "MultipleLeft/AllRight/LeftIsIntersection", 281 in: input{ 282 left: NamespaceSet{ 283 "ns": {}, 284 "ns-1": {}, 285 "ns-2": {}, 286 }, 287 right: NamespaceSet{ 288 "": {}, 289 }, 290 }, 291 want: NamespaceSet{ 292 "ns": {}, 293 "ns-1": {}, 294 "ns-2": {}, 295 }, 296 }, 297 { 298 name: "AllLeft/EmptyRight/NoIntersection", 299 in: input{ 300 left: NamespaceSet{ 301 "": {}, 302 }, 303 right: make(NamespaceSet), 304 }, 305 want: make(NamespaceSet), 306 }, 307 { 308 name: "EmptyLeft/AllRight/NoIntersection", 309 in: input{ 310 left: make(NamespaceSet), 311 right: NamespaceSet{ 312 "": {}, 313 }, 314 }, 315 want: make(NamespaceSet), 316 }, 317 { 318 name: "AllLeft/AllRight/Intersection", 319 in: input{ 320 left: NamespaceSet{ 321 "": {}, 322 }, 323 right: NamespaceSet{ 324 "": {}, 325 }, 326 }, 327 want: NamespaceSet{ 328 "": {}, 329 }, 330 }, 331 } 332 333 for _, tt := range tests { 334 t.Run(tt.name, func(t *testing.T) { 335 require.EqualValues(t, tt.want, tt.in.left.Intersection(tt.in.right)) 336 }) 337 } 338 } 339 340 func TestNamespaceSetUnion(t *testing.T) { 341 type input struct { 342 left NamespaceSet 343 right NamespaceSet 344 } 345 tests := []struct { 346 name string 347 in input 348 want NamespaceSet 349 }{ 350 { 351 name: "EmptySets", 352 in: input{ 353 left: make(NamespaceSet), 354 right: make(NamespaceSet), 355 }, 356 want: make(NamespaceSet), 357 }, 358 { 359 name: "EmptyLeft/MultipleRight", 360 in: input{ 361 left: make(NamespaceSet), 362 right: NamespaceSet{ 363 "ns": {}, 364 "ns-1": {}, 365 "ns-2": {}, 366 }, 367 }, 368 want: NamespaceSet{ 369 "ns": {}, 370 "ns-1": {}, 371 "ns-2": {}, 372 }, 373 }, 374 { 375 name: "MultipleLeft/EmptyRight", 376 in: input{ 377 left: NamespaceSet{ 378 "ns": {}, 379 "ns-1": {}, 380 "ns-2": {}, 381 }, 382 right: make(NamespaceSet), 383 }, 384 want: NamespaceSet{ 385 "ns": {}, 386 "ns-1": {}, 387 "ns-2": {}, 388 }, 389 }, 390 { 391 name: "OneLeft/SameRight", 392 in: input{ 393 left: NamespaceSet{ 394 "ns": {}, 395 }, 396 right: NamespaceSet{ 397 "ns": {}, 398 }, 399 }, 400 want: NamespaceSet{ 401 "ns": {}, 402 }, 403 }, 404 { 405 name: "MultipleLeft/MultipleRight/Differ", 406 in: input{ 407 left: NamespaceSet{ 408 "ns": {}, 409 "ns-1": {}, 410 "ns-2": {}, 411 }, 412 right: NamespaceSet{ 413 "ns": {}, 414 "ns-1": {}, 415 "ns-3": {}, 416 }, 417 }, 418 want: NamespaceSet{ 419 "ns": {}, 420 "ns-1": {}, 421 "ns-2": {}, 422 "ns-3": {}, 423 }, 424 }, 425 { 426 name: "MultipleLeft/MultipleRight/AllSame", 427 in: input{ 428 left: NamespaceSet{ 429 "ns": {}, 430 "ns-1": {}, 431 "ns-2": {}, 432 }, 433 right: NamespaceSet{ 434 "ns": {}, 435 "ns-1": {}, 436 "ns-2": {}, 437 }, 438 }, 439 want: NamespaceSet{ 440 "ns": {}, 441 "ns-1": {}, 442 "ns-2": {}, 443 }, 444 }, 445 { 446 name: "AllLeft/MultipleRight", 447 in: input{ 448 left: NamespaceSet{ 449 "": {}, 450 }, 451 right: NamespaceSet{ 452 "ns": {}, 453 "ns-1": {}, 454 "ns-2": {}, 455 }, 456 }, 457 want: NamespaceSet{ 458 "": {}, 459 }, 460 }, 461 { 462 name: "MultipleLeft/AllRight", 463 in: input{ 464 left: NamespaceSet{ 465 "ns": {}, 466 "ns-1": {}, 467 "ns-2": {}, 468 }, 469 right: NamespaceSet{ 470 "": {}, 471 }, 472 }, 473 want: NamespaceSet{ 474 "": {}, 475 }, 476 }, 477 { 478 name: "AllLeft/EmptyRight", 479 in: input{ 480 left: NamespaceSet{ 481 "": {}, 482 }, 483 right: make(NamespaceSet), 484 }, 485 want: NamespaceSet{ 486 "": {}, 487 }, 488 }, 489 { 490 name: "EmptyLeft/AllRight", 491 in: input{ 492 left: make(NamespaceSet), 493 right: NamespaceSet{ 494 "": {}, 495 }, 496 }, 497 want: NamespaceSet{ 498 "": {}, 499 }, 500 }, 501 { 502 name: "AllLeft/AllRight", 503 in: input{ 504 left: NamespaceSet{ 505 "": {}, 506 }, 507 right: NamespaceSet{ 508 "": {}, 509 }, 510 }, 511 want: NamespaceSet{ 512 "": {}, 513 }, 514 }, 515 } 516 517 for _, tt := range tests { 518 t.Run(tt.name, func(t *testing.T) { 519 require.EqualValues(t, tt.want, tt.in.left.Union(tt.in.right)) 520 }) 521 } 522 } 523 524 func TestNamespaceSetIsAllNamespaces(t *testing.T) { 525 type input struct { 526 set NamespaceSet 527 } 528 tests := []struct { 529 name string 530 in input 531 want bool 532 }{ 533 { 534 name: "All/Yes", 535 in: input{ 536 set: NewNamespaceSet([]string{metav1.NamespaceAll}), 537 }, 538 want: true, 539 }, 540 { 541 name: "One/NotAll", 542 in: input{ 543 set: NewNamespaceSet([]string{"a"}), 544 }, 545 want: false, 546 }, 547 { 548 name: "Many/NotAll", 549 in: input{ 550 set: NewNamespaceSet([]string{"a", "b", "c"}), 551 }, 552 want: false, 553 }, 554 } 555 556 for _, tt := range tests { 557 t.Run(tt.name, func(t *testing.T) { 558 require.Equal(t, tt.want, tt.in.set.IsAllNamespaces()) 559 }) 560 } 561 } 562 563 func TestNamespaceSetContains(t *testing.T) { 564 type input struct { 565 set NamespaceSet 566 contains string 567 } 568 tests := []struct { 569 name string 570 in input 571 want bool 572 }{ 573 { 574 name: "AllContainsAnything", 575 in: input{ 576 set: NewNamespaceSet([]string{metav1.NamespaceAll}), 577 contains: "any", 578 }, 579 want: true, 580 }, 581 { 582 name: "SetContainsChild/a", 583 in: input{ 584 set: NewNamespaceSet([]string{"a", "b"}), 585 contains: "a", 586 }, 587 want: true, 588 }, 589 { 590 name: "SetContainsChild/a", 591 in: input{ 592 set: NewNamespaceSet([]string{"a", "b"}), 593 contains: "b", 594 }, 595 want: true, 596 }, 597 { 598 name: "SetOmitsChild", 599 in: input{ 600 set: NewNamespaceSet([]string{"a", "b"}), 601 contains: "c", 602 }, 603 want: false, 604 }, 605 } 606 607 for _, tt := range tests { 608 t.Run(tt.name, func(t *testing.T) { 609 require.Equal(t, tt.want, tt.in.set.Contains(tt.in.contains)) 610 }) 611 } 612 } 613 614 func TestNewNamespaceSetFromString(t *testing.T) { 615 type input struct { 616 list string 617 } 618 tests := []struct { 619 name string 620 in input 621 wantNamespaces []string 622 }{ 623 { 624 name: "SingleEntry", 625 in: input{ 626 list: "a", 627 }, 628 wantNamespaces: []string{"a"}, 629 }, 630 { 631 name: "TwoEntry", 632 in: input{ 633 list: "a,b", 634 }, 635 wantNamespaces: []string{"a", "b"}, 636 }, 637 { 638 name: "All", 639 in: input{ 640 list: "", 641 }, 642 wantNamespaces: []string{"a"}, 643 }, 644 } 645 for _, tt := range tests { 646 t.Run(tt.name, func(t *testing.T) { 647 for _, ns := range tt.wantNamespaces { 648 require.True(t, NewNamespaceSetFromString(tt.in.list).Contains(ns)) 649 } 650 }) 651 } 652 } 653 654 func buildOperatorGroup(namespace, name string, targets []string, gvks []string) *OperatorGroup { 655 return NewOperatorGroup(buildAPIOperatorGroup(namespace, name, targets, gvks)) 656 } 657 658 func TestGroupIntersection(t *testing.T) { 659 type input struct { 660 left OperatorGroupSurface 661 right []OperatorGroupSurface 662 } 663 tests := []struct { 664 name string 665 in input 666 want []OperatorGroupSurface 667 }{ 668 { 669 name: "NoTargets/NilGroups/NoIntersection", 670 in: input{ 671 left: buildOperatorGroup("ns", "empty-group", nil, nil), 672 right: nil, 673 }, 674 want: []OperatorGroupSurface{}, 675 }, 676 { 677 name: "MatchingTarget/SingleOtherGroup/Intersection", 678 in: input{ 679 left: buildOperatorGroup("ns", "group-a", []string{"ns-1"}, nil), 680 right: []OperatorGroupSurface{ 681 buildOperatorGroup("ns-2", "group-b", []string{"ns-1"}, nil), 682 }, 683 }, 684 want: []OperatorGroupSurface{ 685 buildOperatorGroup("ns-2", "group-b", []string{"ns-1"}, nil), 686 }, 687 }, 688 { 689 name: "TargetIsOperatorNamespace/SingleOtherGroup/Intersection", 690 in: input{ 691 left: buildOperatorGroup("ns", "group-a", []string{"ns-1"}, nil), 692 right: []OperatorGroupSurface{ 693 buildOperatorGroup("ns-2", "group-b", []string{"ns"}, nil), 694 }, 695 }, 696 want: []OperatorGroupSurface{ 697 buildOperatorGroup("ns-2", "group-b", []string{"ns"}, nil), 698 }, 699 }, 700 { 701 name: "MatchingOperatorNamespaces/SingleOtherGroup/Intersection", 702 in: input{ 703 left: buildOperatorGroup("ns", "group-a", []string{"ns-1"}, nil), 704 right: []OperatorGroupSurface{ 705 buildOperatorGroup("ns", "group-b", []string{"ns-2"}, nil), 706 }, 707 }, 708 want: []OperatorGroupSurface{ 709 buildOperatorGroup("ns", "group-b", []string{"ns-2"}, nil), 710 }, 711 }, 712 { 713 name: "MatchingTarget/MultipleOtherGroups/Intersection", 714 in: input{ 715 left: buildOperatorGroup("ns", "group-a", []string{"ns-1"}, nil), 716 right: []OperatorGroupSurface{ 717 buildOperatorGroup("ns-2", "group-b", []string{"ns-1"}, nil), 718 buildOperatorGroup("ns-3", "group-c", []string{"ns-1"}, nil), 719 }, 720 }, 721 want: []OperatorGroupSurface{ 722 buildOperatorGroup("ns-2", "group-b", []string{"ns-1"}, nil), 723 buildOperatorGroup("ns-3", "group-c", []string{"ns-1"}, nil), 724 }, 725 }, 726 { 727 name: "NonMatchingTargets/MultipleOtherGroups/NoIntersection", 728 in: input{ 729 left: buildOperatorGroup("ns", "group-a", []string{"ns-1", "ns-2", "ns-3"}, nil), 730 right: []OperatorGroupSurface{ 731 buildOperatorGroup("ns-4", "group-b", []string{"ns-6", "ns-7", "ns-8"}, nil), 732 buildOperatorGroup("ns-5", "group-c", []string{"ns-6", "ns-7", "ns-8"}, nil), 733 }, 734 }, 735 want: []OperatorGroupSurface{}, 736 }, 737 { 738 name: "AllNamespaces/MultipleTargets/Intersection", 739 in: input{ 740 left: buildOperatorGroup("ns", "group-a", []string{""}, nil), 741 right: []OperatorGroupSurface{ 742 buildOperatorGroup("ns-4", "group-b", []string{"ns-6", "ns-7", "ns-8"}, nil), 743 buildOperatorGroup("ns-5", "group-c", []string{"ns-9", "ns-10", "ns-11"}, nil), 744 buildOperatorGroup("ns-6", "group-d", []string{"ns-11", "ns-12"}, nil), 745 }, 746 }, 747 want: []OperatorGroupSurface{ 748 buildOperatorGroup("ns-4", "group-b", []string{"ns-6", "ns-7", "ns-8"}, nil), 749 buildOperatorGroup("ns-5", "group-c", []string{"ns-9", "ns-10", "ns-11"}, nil), 750 buildOperatorGroup("ns-6", "group-d", []string{"ns-11", "ns-12"}, nil), 751 }, 752 }, 753 { 754 name: "MatchingTargetAllNamespace/MultipleTargets/Intersection", 755 in: input{ 756 left: buildOperatorGroup("ns", "group-a", []string{"ns-1", "ns-2", "ns-3"}, nil), 757 right: []OperatorGroupSurface{ 758 buildOperatorGroup("ns-4", "group-b", []string{""}, nil), 759 buildOperatorGroup("ns-5", "group-c", []string{"ns-9", "ns-10", "ns-11"}, nil), 760 buildOperatorGroup("ns-6", "group-d", []string{"ns-11", "ns-12"}, nil), 761 }, 762 }, 763 want: []OperatorGroupSurface{ 764 buildOperatorGroup("ns-4", "group-b", []string{""}, nil), 765 }, 766 }, 767 { 768 name: "AllNamespace/MultipleTargets/OneAllNamespace/Intersection", 769 in: input{ 770 left: buildOperatorGroup("ns", "group-a", []string{""}, nil), 771 right: []OperatorGroupSurface{ 772 buildOperatorGroup("ns-4", "group-b", []string{""}, nil), 773 buildOperatorGroup("ns-5", "group-c", []string{"ns-9", "ns-10", "ns-11"}, nil), 774 buildOperatorGroup("ns-6", "group-d", []string{"ns-11", "ns-12"}, nil), 775 }, 776 }, 777 want: []OperatorGroupSurface{ 778 buildOperatorGroup("ns-4", "group-b", []string{""}, nil), 779 buildOperatorGroup("ns-5", "group-c", []string{"ns-9", "ns-10", "ns-11"}, nil), 780 buildOperatorGroup("ns-6", "group-d", []string{"ns-11", "ns-12"}, nil), 781 }, 782 }, 783 { 784 name: "AllNamespace/AllNamespace/Intersection", 785 in: input{ 786 left: buildOperatorGroup("ns", "group-a", []string{""}, nil), 787 right: []OperatorGroupSurface{ 788 buildOperatorGroup("ns-4", "group-b", []string{""}, nil), 789 }, 790 }, 791 want: []OperatorGroupSurface{ 792 buildOperatorGroup("ns-4", "group-b", []string{""}, nil), 793 }, 794 }, 795 } 796 797 for _, tt := range tests { 798 t.Run(tt.name, func(t *testing.T) { 799 require.EqualValues(t, tt.want, tt.in.left.GroupIntersection(tt.in.right...)) 800 }) 801 } 802 } 803 804 func apiIntersectionReconcilerSuite(t *testing.T, reconciler APIIntersectionReconciler) { 805 tests := []struct { 806 name string 807 add cache.APISet 808 group OperatorGroupSurface 809 otherGroups []OperatorGroupSurface 810 want APIReconciliationResult 811 }{ 812 { 813 name: "Empty/NoAPIConflict", 814 add: make(cache.APISet), 815 group: buildOperatorGroup("ns", "g1", []string{"ns"}, nil), 816 otherGroups: nil, 817 want: NoAPIConflict, 818 }, 819 { 820 name: "NoNamespaceIntersection/APIIntersection/NoAPIConflict", 821 add: cache.APISet{ 822 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 823 }, 824 group: buildOperatorGroup("ns", "g1", []string{"ns-1"}, []string{"Goose.v1alpha1.birds.com"}), 825 otherGroups: []OperatorGroupSurface{ 826 buildOperatorGroup("ns-2", "g1", []string{"ns-3"}, []string{"Goose.v1alpha1.birds.com"}), 827 }, 828 want: NoAPIConflict, 829 }, 830 { 831 name: "NamespaceIntersection/NoAPIIntersection/NoAPIConflict", 832 add: cache.APISet{ 833 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 834 }, 835 group: buildOperatorGroup("ns", "g1", []string{"ns-1"}, []string{"Goose.v1alpha1.birds.com"}), 836 otherGroups: []OperatorGroupSurface{ 837 buildOperatorGroup("ns-2", "g1", []string{"ns-1"}, []string{"Moose.v1alpha1.mammals.com"}), 838 }, 839 want: NoAPIConflict, 840 }, 841 { 842 name: "MultipleNamespaceIntersections/NoAPIIntersection/NoAPIConflict", 843 add: cache.APISet{ 844 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 845 }, 846 group: buildOperatorGroup("ns", "g1", []string{"ns-1"}, []string{"Goose.v1alpha1.birds.com"}), 847 otherGroups: []OperatorGroupSurface{ 848 buildOperatorGroup("ns-2", "g1", []string{"ns-1"}, []string{"Moose.v1alpha1.mammals.com"}), 849 buildOperatorGroup("ns-2", "g1", []string{"ns"}, []string{"Egret.v1alpha1.birds.com"}), 850 }, 851 want: NoAPIConflict, 852 }, 853 { 854 name: "SomeNamespaceIntersection/NoAPIIntersection/NoAPIConflict", 855 add: cache.APISet{ 856 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 857 opregistry.APIKey{Group: "mammals.com", Version: "v1alpha1", Kind: "Moose"}: {}, 858 }, 859 group: buildOperatorGroup("ns", "g1", []string{"ns-1", "ns-2", "ns-3"}, []string{"Goose.v1alpha1.birds.com,Moose.v1alpha1.mammals.com"}), 860 otherGroups: []OperatorGroupSurface{ 861 buildOperatorGroup("ns-7", "g1", []string{"ns-4"}, []string{"Moose.v1alpha1.mammals.com"}), 862 buildOperatorGroup("ns-8", "g1", []string{"ns-5"}, []string{"Goose.v1alpha1.birds.com"}), 863 buildOperatorGroup("ns-9", "g1", []string{""}, []string{"Goat.v1alpha1.mammals.com"}), 864 }, 865 want: NoAPIConflict, 866 }, 867 { 868 name: "AllNamespaceIntersection/NoAPIIntersection/NoAPIConflict", 869 add: cache.APISet{ 870 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 871 }, 872 group: buildOperatorGroup("ns", "g1", []string{""}, []string{"Goose.v1alpha1.birds.com"}), 873 otherGroups: []OperatorGroupSurface{ 874 buildOperatorGroup("ns-2", "g1", []string{"ns-1"}, []string{"Moose.v1alpha1.mammals.com"}), 875 }, 876 want: NoAPIConflict, 877 }, 878 { 879 name: "AllNamespaceIntersectionOnOther/NoAPIIntersection/NoAPIConflict", 880 add: cache.APISet{ 881 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 882 }, 883 group: buildOperatorGroup("ns", "g1", []string{"ns-1"}, []string{"Goose.v1alpha1.birds.com"}), 884 otherGroups: []OperatorGroupSurface{ 885 buildOperatorGroup("ns-2", "g1", []string{""}, []string{"Moose.v1alpha1.mammals.com"}), 886 }, 887 want: NoAPIConflict, 888 }, 889 { 890 name: "AllNamespaceInstersectionOnOther/NoAPIIntersection/NoAPIConflict", 891 add: cache.APISet{ 892 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 893 }, 894 group: buildOperatorGroup("ns", "g1", []string{""}, []string{"Goose.v1alpha1.birds.com"}), 895 otherGroups: []OperatorGroupSurface{ 896 buildOperatorGroup("ns-2", "g1", []string{""}, []string{"Moose.v1alpha1.mammals.com"}), 897 }, 898 want: NoAPIConflict, 899 }, 900 { 901 name: "NamespaceIntersection/NoAPIIntersection/NoAPIConflict", 902 add: cache.APISet{ 903 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 904 }, 905 group: buildOperatorGroup("ns", "g1", []string{"ns-1"}, []string{"Goose.v1alpha1.birds.com"}), 906 otherGroups: []OperatorGroupSurface{ 907 buildOperatorGroup("ns-2", "g1", []string{"ns-1"}, nil), 908 }, 909 want: NoAPIConflict, 910 }, 911 { 912 name: "NamespaceIntersection/APIIntersection/APIConflict", 913 add: cache.APISet{ 914 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 915 }, 916 group: buildOperatorGroup("ns", "g1", []string{"ns-1"}, nil), 917 otherGroups: []OperatorGroupSurface{ 918 buildOperatorGroup("ns-2", "g1", []string{"ns-1"}, []string{"Goose.v1alpha1.birds.com"}), 919 }, 920 want: APIConflict, 921 }, 922 { 923 name: "AllNamespaceIntersection/APIIntersection/APIConflict", 924 add: cache.APISet{ 925 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 926 }, 927 group: buildOperatorGroup("ns", "g1", []string{""}, nil), 928 otherGroups: []OperatorGroupSurface{ 929 buildOperatorGroup("ns-2", "g1", []string{"ns-1"}, []string{"Goose.v1alpha1.birds.com"}), 930 }, 931 want: APIConflict, 932 }, 933 { 934 name: "AllNamespaceIntersectionOnOther/APIIntersection/APIConflict", 935 add: cache.APISet{ 936 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 937 }, 938 group: buildOperatorGroup("ns", "g1", []string{"ns-1"}, nil), 939 otherGroups: []OperatorGroupSurface{ 940 buildOperatorGroup("ns-2", "g1", []string{""}, []string{"Goose.v1alpha1.birds.com"}), 941 }, 942 want: APIConflict, 943 }, 944 { 945 name: "AllNamespaceIntersectionOnBoth/APIIntersection/APIConflict", 946 add: cache.APISet{ 947 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 948 }, 949 group: buildOperatorGroup("ns", "g1", []string{""}, nil), 950 otherGroups: []OperatorGroupSurface{ 951 buildOperatorGroup("ns-2", "g1", []string{""}, []string{"Goose.v1alpha1.birds.com"}), 952 }, 953 want: APIConflict, 954 }, 955 { 956 name: "NamespaceIntersection/SomeAPIIntersection/APIConflict", 957 add: cache.APISet{ 958 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 959 }, 960 group: buildOperatorGroup("ns", "g1", []string{"ns-1"}, nil), 961 otherGroups: []OperatorGroupSurface{ 962 buildOperatorGroup("ns-2", "g1", []string{"ns-1"}, []string{"Moose.v1alpha1.birds.com"}), 963 buildOperatorGroup("ns-3", "g1", []string{"ns-1"}, []string{"Goose.v1alpha1.birds.com,Egret.v1alpha1.birds.com"}), 964 }, 965 want: APIConflict, 966 }, 967 { 968 name: "NamespaceIntersectionOnOperatorNamespace/SomeAPIIntersection/APIConflict", 969 add: cache.APISet{ 970 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 971 }, 972 group: buildOperatorGroup("ns", "g1", []string{"ns-1"}, nil), 973 otherGroups: []OperatorGroupSurface{ 974 buildOperatorGroup("ns-3", "g1", []string{"ns"}, []string{"Goose.v1alpha1.birds.com,Egret.v1alpha1.birds.com"}), 975 }, 976 want: APIConflict, 977 }, 978 979 { 980 name: "NoNamespaceIntersection/NoAPIIntersection/AddAPIs", 981 add: cache.APISet{ 982 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 983 }, 984 group: buildOperatorGroup("ns", "g1", []string{"ns-1"}, nil), 985 otherGroups: []OperatorGroupSurface{ 986 buildOperatorGroup("ns-2", "g1", []string{"ns-2"}, []string{"Goose.v1alpha1.birds.com"}), 987 }, 988 want: AddAPIs, 989 }, 990 { 991 name: "NamespaceIntersection/NoAPIIntersection/AddAPIs", 992 add: cache.APISet{ 993 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 994 }, 995 group: buildOperatorGroup("ns", "g1", []string{"ns-1"}, nil), 996 otherGroups: []OperatorGroupSurface{ 997 buildOperatorGroup("ns-2", "g1", []string{"ns-1"}, []string{"Moose.v1alpha1.mammals.com"}), 998 }, 999 want: AddAPIs, 1000 }, 1001 { 1002 name: "OperatorNamespaceIntersection/NoAPIIntersection/AddAPIs", 1003 add: cache.APISet{ 1004 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 1005 }, 1006 group: buildOperatorGroup("ns", "g1", []string{"ns-1"}, nil), 1007 otherGroups: []OperatorGroupSurface{ 1008 buildOperatorGroup("ns-2", "g1", []string{"ns"}, []string{"Moose.v1alpha1.mammals.com"}), 1009 }, 1010 want: AddAPIs, 1011 }, 1012 { 1013 name: "AllNamespaceIntersection/NoAPIIntersection/AddAPIs", 1014 add: cache.APISet{ 1015 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 1016 }, 1017 group: buildOperatorGroup("ns", "g1", []string{""}, nil), 1018 otherGroups: []OperatorGroupSurface{ 1019 buildOperatorGroup("ns-2", "g1", []string{"ns-1"}, []string{"Moose.v1alpha1.mammals.com"}), 1020 buildOperatorGroup("ns-3", "g1", []string{"ns-1"}, []string{"Goat.v1alpha1.mammals.com,Egret.v1alpha1.birds.com"}), 1021 }, 1022 want: AddAPIs, 1023 }, 1024 { 1025 name: "AllNamespaceIntersectionOnOthers/NoAPIIntersection/AddAPIs", 1026 add: cache.APISet{ 1027 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 1028 }, 1029 group: buildOperatorGroup("ns", "g1", []string{"ns-1"}, nil), 1030 otherGroups: []OperatorGroupSurface{ 1031 buildOperatorGroup("ns-2", "g1", []string{""}, []string{"Moose.v1alpha1.mammals.com"}), 1032 buildOperatorGroup("ns-3", "g1", []string{""}, []string{"Goat.v1alpha1.mammals.com,Egret.v1alpha1.birds.com"}), 1033 }, 1034 want: AddAPIs, 1035 }, 1036 { 1037 name: "AllNamespaceIntersectionOnOthers/NoAPIIntersection/AddAPIs/PrexistingAddition", 1038 add: cache.APISet{ 1039 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 1040 opregistry.APIKey{Group: "mammals.com", Version: "v1alpha1", Kind: "Cow"}: {}, 1041 }, 1042 group: buildOperatorGroup("ns", "g1", []string{"ns-1"}, []string{"Cow.v1alpha1.mammals.com"}), 1043 otherGroups: []OperatorGroupSurface{ 1044 buildOperatorGroup("ns-2", "g1", []string{""}, []string{"Moose.v1alpha1.mammals.com"}), 1045 buildOperatorGroup("ns-3", "g1", []string{""}, []string{"Goat.v1alpha1.mammals.com,Egret.v1alpha1.birds.com"}), 1046 }, 1047 want: AddAPIs, 1048 }, 1049 { 1050 name: "NamespaceInstersection/APIIntersection/RemoveAPIs", 1051 add: cache.APISet{ 1052 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 1053 }, 1054 group: buildOperatorGroup("ns", "g1", []string{"ns-1"}, []string{"Goose.v1alpha1.birds.com"}), 1055 otherGroups: []OperatorGroupSurface{ 1056 buildOperatorGroup("ns-2", "g1", []string{"ns-1"}, []string{"Goose.v1alpha1.birds.com"}), 1057 }, 1058 want: RemoveAPIs, 1059 }, 1060 { 1061 name: "AllNamespaceInstersection/APIIntersection/RemoveAPIs", 1062 add: cache.APISet{ 1063 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 1064 }, 1065 group: buildOperatorGroup("ns", "g1", []string{""}, []string{"Goose.v1alpha1.birds.com"}), 1066 otherGroups: []OperatorGroupSurface{ 1067 buildOperatorGroup("ns-2", "g1", []string{"ns-1"}, []string{"Goose.v1alpha1.birds.com"}), 1068 }, 1069 want: RemoveAPIs, 1070 }, 1071 { 1072 name: "AllNamespaceInstersectionOnOther/APIIntersection/RemoveAPIs", 1073 add: cache.APISet{ 1074 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 1075 }, 1076 group: buildOperatorGroup("ns", "g1", []string{""}, []string{"Goose.v1alpha1.birds.com"}), 1077 otherGroups: []OperatorGroupSurface{ 1078 buildOperatorGroup("ns-2", "g1", []string{""}, []string{"Goose.v1alpha1.birds.com"}), 1079 }, 1080 want: RemoveAPIs, 1081 }, 1082 { 1083 name: "MultipleNamespaceIntersections/APIIntersection/RemoveAPIs", 1084 add: cache.APISet{ 1085 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 1086 }, 1087 group: buildOperatorGroup("ns", "g1", []string{"ns-1"}, []string{"Goose.v1alpha1.birds.com"}), 1088 otherGroups: []OperatorGroupSurface{ 1089 buildOperatorGroup("ns-2", "g1", []string{"ns-1"}, []string{"Goose.v1alpha1.birds.com"}), 1090 buildOperatorGroup("ns-2", "g1", []string{"ns"}, []string{"Goose.v1alpha1.birds.com"}), 1091 }, 1092 want: RemoveAPIs, 1093 }, 1094 { 1095 name: "SomeNamespaceIntersection/APIIntersection/RemoveAPIs", 1096 add: cache.APISet{ 1097 opregistry.APIKey{Group: "birds.com", Version: "v1alpha1", Kind: "Goose"}: {}, 1098 opregistry.APIKey{Group: "mammals.com", Version: "v1alpha1", Kind: "Moose"}: {}, 1099 }, 1100 group: buildOperatorGroup("ns", "g1", []string{"ns-1", "ns-2", "ns-3"}, []string{"Goose.v1alpha1.birds.com,Moose.v1alpha1.mammals.com"}), 1101 otherGroups: []OperatorGroupSurface{ 1102 buildOperatorGroup("ns-7", "g1", []string{"ns-4"}, []string{"Moose.v1alpha1.mammals.com"}), 1103 buildOperatorGroup("ns-8", "g1", []string{"ns-5", "ns-3"}, []string{"Goose.v1alpha1.birds.com"}), 1104 buildOperatorGroup("ns-9", "g1", []string{""}, []string{"Goat.v1alpha1.mammals.com"}), 1105 }, 1106 want: RemoveAPIs, 1107 }, 1108 } 1109 1110 for _, tt := range tests { 1111 t.Run(tt.name, func(t *testing.T) { 1112 require.Equal(t, tt.want, reconciler.Reconcile(tt.add, tt.group, tt.otherGroups...)) 1113 }) 1114 } 1115 } 1116 func TestReconcileAPIIntersection(t *testing.T) { 1117 apiIntersectionReconcilerSuite(t, APIIntersectionReconcileFunc(ReconcileAPIIntersection)) 1118 }