sigs.k8s.io/kueue@v0.6.2/pkg/controller/admissionchecks/multikueue/indexer_test.go (about) 1 /* 2 Copyright 2024 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 multikueue 18 19 import ( 20 "context" 21 "testing" 22 23 "github.com/google/go-cmp/cmp" 24 "github.com/google/go-cmp/cmp/cmpopts" 25 corev1 "k8s.io/api/core/v1" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 "k8s.io/apimachinery/pkg/runtime" 28 clientgoscheme "k8s.io/client-go/kubernetes/scheme" 29 "sigs.k8s.io/controller-runtime/pkg/client" 30 "sigs.k8s.io/controller-runtime/pkg/client/fake" 31 jobset "sigs.k8s.io/jobset/api/jobset/v1alpha2" 32 33 kueuealpha "sigs.k8s.io/kueue/apis/kueue/v1alpha1" 34 kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1" 35 "sigs.k8s.io/kueue/pkg/util/slices" 36 utiltesting "sigs.k8s.io/kueue/pkg/util/testing" 37 ) 38 39 const ( 40 TestNamespace = "ns" 41 ) 42 43 func getClientBuilder() (*fake.ClientBuilder, context.Context) { 44 scheme := runtime.NewScheme() 45 if err := clientgoscheme.AddToScheme(scheme); err != nil { 46 panic(err) 47 } 48 if err := kueue.AddToScheme(scheme); err != nil { 49 panic(err) 50 } 51 if err := kueuealpha.AddToScheme(scheme); err != nil { 52 panic(err) 53 } 54 if err := jobset.AddToScheme(scheme); err != nil { 55 panic(err) 56 } 57 58 ctx := context.Background() 59 builder := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&corev1.Namespace{ 60 ObjectMeta: metav1.ObjectMeta{ 61 Name: TestNamespace, 62 }, 63 }) 64 _ = SetupIndexer(ctx, utiltesting.AsIndexer(builder), TestNamespace) 65 return builder, ctx 66 } 67 68 func TestListMultiKueueClustersUsingKubeConfig(t *testing.T) { 69 cases := map[string]struct { 70 clusters []*kueuealpha.MultiKueueCluster 71 filter client.ListOption 72 wantListError error 73 wantList []string 74 }{ 75 "no clusters": { 76 filter: client.MatchingFields{UsingKubeConfigs: TestNamespace + "/secret1"}, 77 }, 78 "single cluster, single match": { 79 clusters: []*kueuealpha.MultiKueueCluster{ 80 utiltesting.MakeMultiKueueCluster("cluster1").KubeConfig(kueuealpha.SecretLocationType, "secret1").Obj(), 81 }, 82 filter: client.MatchingFields{UsingKubeConfigs: TestNamespace + "/secret1"}, 83 wantList: []string{"cluster1"}, 84 }, 85 "single cluster, no match": { 86 clusters: []*kueuealpha.MultiKueueCluster{ 87 utiltesting.MakeMultiKueueCluster("cluster2").KubeConfig(kueuealpha.SecretLocationType, "secret2").Obj(), 88 }, 89 filter: client.MatchingFields{UsingKubeConfigs: TestNamespace + "/secret1"}, 90 }, 91 "multiple clusters, single match": { 92 clusters: []*kueuealpha.MultiKueueCluster{ 93 utiltesting.MakeMultiKueueCluster("cluster1").KubeConfig(kueuealpha.SecretLocationType, "secret1").Obj(), 94 utiltesting.MakeMultiKueueCluster("cluster2").KubeConfig(kueuealpha.SecretLocationType, "secret2").Obj(), 95 }, 96 filter: client.MatchingFields{UsingKubeConfigs: TestNamespace + "/secret1"}, 97 wantList: []string{"cluster1"}, 98 }, 99 } 100 for name, tc := range cases { 101 t.Run(name, func(t *testing.T) { 102 builder, ctx := getClientBuilder() 103 k8sclient := builder.Build() 104 for _, req := range tc.clusters { 105 if err := k8sclient.Create(ctx, req); err != nil { 106 t.Fatalf("Unable to create %q cluster: %v", client.ObjectKeyFromObject(req), err) 107 } 108 } 109 110 lst := &kueuealpha.MultiKueueClusterList{} 111 112 gotListErr := k8sclient.List(ctx, lst, tc.filter) 113 if diff := cmp.Diff(tc.wantListError, gotListErr); diff != "" { 114 t.Errorf("unexpected list error (-want/+got):\n%s", diff) 115 } 116 117 gotList := slices.Map(lst.Items, func(mkc *kueuealpha.MultiKueueCluster) string { return mkc.Name }) 118 if diff := cmp.Diff(tc.wantList, gotList, cmpopts.EquateEmpty(), cmpopts.SortSlices(func(a, b string) bool { return a < b })); diff != "" { 119 t.Errorf("unexpected list (-want/+got):\n%s", diff) 120 } 121 }) 122 } 123 } 124 125 func TestListMultiKueueConfigsUsingMultiKueueClusters(t *testing.T) { 126 cases := map[string]struct { 127 configs []*kueuealpha.MultiKueueConfig 128 filter client.ListOption 129 wantListError error 130 wantList []string 131 }{ 132 "no configs": { 133 filter: client.MatchingFields{UsingMultiKueueClusters: "cluster1"}, 134 }, 135 "single config, single match": { 136 configs: []*kueuealpha.MultiKueueConfig{ 137 utiltesting.MakeMultiKueueConfig("config1").Clusters("cluster1", "cluster2").Obj(), 138 }, 139 filter: client.MatchingFields{UsingMultiKueueClusters: "cluster2"}, 140 wantList: []string{"config1"}, 141 }, 142 "single config, no match": { 143 configs: []*kueuealpha.MultiKueueConfig{ 144 utiltesting.MakeMultiKueueConfig("config2").Clusters("cluster2").Obj(), 145 }, 146 filter: client.MatchingFields{UsingMultiKueueClusters: "cluster1"}, 147 }, 148 "multiple configs, single match": { 149 configs: []*kueuealpha.MultiKueueConfig{ 150 utiltesting.MakeMultiKueueConfig("config1").Clusters("cluster1", "cluster2").Obj(), 151 utiltesting.MakeMultiKueueConfig("config2").Clusters("cluster2").Obj(), 152 }, 153 filter: client.MatchingFields{UsingMultiKueueClusters: "cluster1"}, 154 wantList: []string{"config1"}, 155 }, 156 } 157 for name, tc := range cases { 158 t.Run(name, func(t *testing.T) { 159 builder, ctx := getClientBuilder() 160 k8sclient := builder.Build() 161 for _, config := range tc.configs { 162 if err := k8sclient.Create(ctx, config); err != nil { 163 t.Fatalf("Unable to create %q config: %v", client.ObjectKeyFromObject(config), err) 164 } 165 } 166 167 lst := &kueuealpha.MultiKueueConfigList{} 168 169 gotListErr := k8sclient.List(ctx, lst, tc.filter) 170 if diff := cmp.Diff(tc.wantListError, gotListErr); diff != "" { 171 t.Errorf("unexpected list error (-want/+got):\n%s", diff) 172 } 173 174 gotList := slices.Map(lst.Items, func(mkc *kueuealpha.MultiKueueConfig) string { return mkc.Name }) 175 if diff := cmp.Diff(tc.wantList, gotList, cmpopts.EquateEmpty(), cmpopts.SortSlices(func(a, b string) bool { return a < b })); diff != "" { 176 t.Errorf("unexpected list (-want/+got):\n%s", diff) 177 } 178 }) 179 } 180 }