sigs.k8s.io/cluster-api@v1.7.1/exp/addons/internal/controllers/clusterresourceset_helpers_test.go (about) 1 /* 2 Copyright 2020 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 controllers 18 19 import ( 20 "context" 21 "testing" 22 "time" 23 24 . "github.com/onsi/gomega" 25 corev1 "k8s.io/api/core/v1" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 "k8s.io/apimachinery/pkg/runtime" 28 "k8s.io/apimachinery/pkg/types" 29 "sigs.k8s.io/controller-runtime/pkg/client" 30 "sigs.k8s.io/controller-runtime/pkg/client/fake" 31 32 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" 33 addonsv1 "sigs.k8s.io/cluster-api/exp/addons/api/v1beta1" 34 ) 35 36 const ( 37 notDefaultNamespace = "not-default" 38 ) 39 40 func TestGetorCreateClusterResourceSetBinding(t *testing.T) { 41 testClusterWithBinding := &clusterv1.Cluster{ 42 ObjectMeta: metav1.ObjectMeta{ 43 Name: "test-cluster-with-binding", 44 Namespace: metav1.NamespaceDefault, 45 }, 46 } 47 48 testClusterResourceSetBinding := &addonsv1.ClusterResourceSetBinding{ 49 ObjectMeta: metav1.ObjectMeta{ 50 Namespace: testClusterWithBinding.Namespace, 51 Name: testClusterWithBinding.Name, 52 }, 53 Spec: addonsv1.ClusterResourceSetBindingSpec{ 54 Bindings: []*addonsv1.ResourceSetBinding{ 55 { 56 ClusterResourceSetName: "test-clusterResourceSet", 57 Resources: []addonsv1.ResourceBinding{ 58 { 59 ResourceRef: addonsv1.ResourceRef{ 60 Name: "mySecret", 61 Kind: "Secret", 62 }, 63 Applied: true, 64 Hash: "xyz", 65 LastAppliedTime: &metav1.Time{Time: time.Now().UTC()}, 66 }, 67 }, 68 }, 69 }, 70 }, 71 } 72 73 testClusterNoBinding := &clusterv1.Cluster{ 74 ObjectMeta: metav1.ObjectMeta{ 75 Name: "test-cluster-no-binding", 76 Namespace: metav1.NamespaceDefault, 77 }, 78 } 79 80 c := fake.NewClientBuilder(). 81 WithObjects(testClusterResourceSetBinding). 82 Build() 83 r := &ClusterResourceSetReconciler{ 84 Client: c, 85 } 86 87 tests := []struct { 88 name string 89 cluster *clusterv1.Cluster 90 numOfClusterResourceSets int 91 }{ 92 { 93 name: "should return existing ClusterResourceSetBinding ", 94 cluster: testClusterWithBinding, 95 numOfClusterResourceSets: 1, 96 }, 97 { 98 name: "should return a new ClusterResourceSetBinding", 99 cluster: testClusterNoBinding, 100 numOfClusterResourceSets: 0, 101 }, 102 } 103 104 for _, tt := range tests { 105 t.Run(tt.name, func(t *testing.T) { 106 gs := NewWithT(t) 107 108 clusterResourceSetBinding, err := r.getOrCreateClusterResourceSetBinding(context.TODO(), tt.cluster, &addonsv1.ClusterResourceSet{}) 109 gs.Expect(err).ToNot(HaveOccurred()) 110 111 gs.Expect(clusterResourceSetBinding.Spec.Bindings).To(HaveLen(tt.numOfClusterResourceSets)) 112 }) 113 } 114 } 115 116 func TestGetSecretFromNamespacedName(t *testing.T) { 117 existingSecretName := types.NamespacedName{Name: "my-secret", Namespace: metav1.NamespaceDefault} 118 existingSecret := &corev1.Secret{ 119 TypeMeta: metav1.TypeMeta{Kind: "Secret", APIVersion: "v1"}, 120 ObjectMeta: metav1.ObjectMeta{ 121 Name: existingSecretName.Name, 122 Namespace: existingSecretName.Namespace, 123 }, 124 } 125 126 tests := []struct { 127 name string 128 secretName types.NamespacedName 129 want *corev1.Secret 130 wantErr bool 131 }{ 132 { 133 name: "should return secret when secret exists", 134 secretName: types.NamespacedName{Name: "my-secret", Namespace: metav1.NamespaceDefault}, 135 want: existingSecret, 136 wantErr: false, 137 }, 138 { 139 name: "should return error when secret does not exist", 140 secretName: types.NamespacedName{Name: "my-secret", Namespace: notDefaultNamespace}, 141 want: nil, 142 wantErr: true, 143 }, 144 } 145 146 for _, tt := range tests { 147 t.Run(tt.name, func(t *testing.T) { 148 gs := NewWithT(t) 149 150 c := fake.NewClientBuilder(). 151 WithObjects(existingSecret). 152 Build() 153 154 got, err := getSecret(context.TODO(), c, tt.secretName) 155 156 if tt.wantErr { 157 gs.Expect(err).To(HaveOccurred()) 158 return 159 } 160 gs.Expect(err).ToNot(HaveOccurred()) 161 162 gs.Expect(*got).To(BeComparableTo(*tt.want)) 163 }) 164 } 165 } 166 167 func TestGetConfigMapFromNamespacedName(t *testing.T) { 168 g := NewWithT(t) 169 170 scheme := runtime.NewScheme() 171 g.Expect(corev1.AddToScheme(scheme)).To(Succeed()) 172 173 existingConfigMapName := types.NamespacedName{Name: "my-configmap", Namespace: metav1.NamespaceDefault} 174 existingConfigMap := &corev1.ConfigMap{ 175 TypeMeta: metav1.TypeMeta{Kind: "ConfigMap", APIVersion: "v1"}, 176 ObjectMeta: metav1.ObjectMeta{ 177 Name: existingConfigMapName.Name, 178 Namespace: existingConfigMapName.Namespace, 179 }, 180 } 181 182 tests := []struct { 183 name string 184 configMapName types.NamespacedName 185 want *corev1.ConfigMap 186 wantErr bool 187 }{ 188 { 189 name: "should return configmap when configmap exists", 190 configMapName: types.NamespacedName{Name: "my-configmap", Namespace: metav1.NamespaceDefault}, 191 want: existingConfigMap, 192 wantErr: false, 193 }, 194 { 195 name: "should return error when configmap does not exist", 196 configMapName: types.NamespacedName{Name: "my-configmap", Namespace: notDefaultNamespace}, 197 want: nil, 198 wantErr: true, 199 }, 200 } 201 202 for _, tt := range tests { 203 t.Run(tt.name, func(t *testing.T) { 204 gs := NewWithT(t) 205 206 c := fake.NewClientBuilder(). 207 WithScheme(scheme). 208 WithObjects(existingConfigMap). 209 Build() 210 211 got, err := getConfigMap(context.TODO(), c, tt.configMapName) 212 213 if tt.wantErr { 214 gs.Expect(err).To(HaveOccurred()) 215 return 216 } 217 gs.Expect(err).ToNot(HaveOccurred()) 218 219 gs.Expect(*got).To(BeComparableTo(*tt.want)) 220 }) 221 } 222 } 223 224 func TestEnsureKubernetesServiceCreated(t *testing.T) { 225 g := NewWithT(t) 226 227 scheme := runtime.NewScheme() 228 g.Expect(corev1.AddToScheme(scheme)).To(Succeed()) 229 230 kubernetesAPIServerService := &corev1.Service{ 231 TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "v1"}, 232 ObjectMeta: metav1.ObjectMeta{ 233 Name: "kubernetes", 234 Namespace: metav1.NamespaceDefault, 235 }, 236 } 237 238 tests := []struct { 239 name string 240 existingObjs []client.Object 241 wantErr bool 242 }{ 243 { 244 name: "should return nil when Kubernetes API Server Service exists", 245 existingObjs: []client.Object{kubernetesAPIServerService}, 246 wantErr: false, 247 }, 248 { 249 name: "should return error when Kubernetes API Server Service does not exist", 250 existingObjs: []client.Object{}, 251 wantErr: true, 252 }, 253 } 254 255 for _, tt := range tests { 256 t.Run(tt.name, func(t *testing.T) { 257 gs := NewWithT(t) 258 259 c := fake.NewClientBuilder(). 260 WithScheme(scheme). 261 WithObjects(tt.existingObjs...). 262 Build() 263 264 err := ensureKubernetesServiceCreated(context.TODO(), c) 265 266 if tt.wantErr { 267 gs.Expect(err).To(HaveOccurred()) 268 return 269 } 270 gs.Expect(err).ToNot(HaveOccurred()) 271 }) 272 } 273 }