sigs.k8s.io/cluster-api@v1.7.1/exp/addons/internal/webhooks/clusterresourceset_webhook_test.go (about) 1 /* 2 Copyright 2021 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 webhooks 18 19 import ( 20 "testing" 21 22 . "github.com/onsi/gomega" 23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 ctrl "sigs.k8s.io/controller-runtime" 25 26 addonsv1 "sigs.k8s.io/cluster-api/exp/addons/api/v1beta1" 27 "sigs.k8s.io/cluster-api/internal/webhooks/util" 28 ) 29 30 var ctx = ctrl.SetupSignalHandler() 31 32 func TestClusterResourcesetDefault(t *testing.T) { 33 g := NewWithT(t) 34 clusterResourceSet := &addonsv1.ClusterResourceSet{} 35 defaultingValidationCRS := clusterResourceSet.DeepCopy() 36 defaultingValidationCRS.Spec.ClusterSelector = metav1.LabelSelector{ 37 MatchLabels: map[string]string{"foo": "bar"}, 38 } 39 webhook := ClusterResourceSet{} 40 t.Run("for ClusterResourceSet", util.CustomDefaultValidateTest(ctx, defaultingValidationCRS, &webhook)) 41 g.Expect(webhook.Default(ctx, clusterResourceSet)).To(Succeed()) 42 43 g.Expect(clusterResourceSet.Spec.Strategy).To(Equal(string(addonsv1.ClusterResourceSetStrategyApplyOnce))) 44 } 45 46 func TestClusterResourceSetLabelSelectorAsSelectorValidation(t *testing.T) { 47 tests := []struct { 48 name string 49 selectors map[string]string 50 expectErr bool 51 }{ 52 { 53 name: "should not return error for valid selector", 54 selectors: map[string]string{"foo": "bar"}, 55 expectErr: false, 56 }, 57 { 58 name: "should return error for invalid selector", 59 selectors: map[string]string{"-123-foo": "bar"}, 60 expectErr: true, 61 }, 62 } 63 64 for _, tt := range tests { 65 t.Run(tt.name, func(t *testing.T) { 66 g := NewWithT(t) 67 clusterResourceSet := &addonsv1.ClusterResourceSet{ 68 Spec: addonsv1.ClusterResourceSetSpec{ 69 ClusterSelector: metav1.LabelSelector{ 70 MatchLabels: tt.selectors, 71 }, 72 }, 73 } 74 webhook := ClusterResourceSet{} 75 if tt.expectErr { 76 warnings, err := webhook.ValidateCreate(ctx, clusterResourceSet) 77 g.Expect(err).To(HaveOccurred()) 78 g.Expect(warnings).To(BeEmpty()) 79 warnings, err = webhook.ValidateUpdate(ctx, clusterResourceSet, clusterResourceSet) 80 g.Expect(err).To(HaveOccurred()) 81 g.Expect(warnings).To(BeEmpty()) 82 } else { 83 warnings, err := webhook.ValidateCreate(ctx, clusterResourceSet) 84 g.Expect(err).ToNot(HaveOccurred()) 85 g.Expect(warnings).To(BeEmpty()) 86 warnings, err = webhook.ValidateUpdate(ctx, clusterResourceSet, clusterResourceSet) 87 g.Expect(err).ToNot(HaveOccurred()) 88 g.Expect(warnings).To(BeEmpty()) 89 } 90 }) 91 } 92 } 93 94 func TestClusterResourceSetStrategyImmutable(t *testing.T) { 95 tests := []struct { 96 name string 97 oldStrategy string 98 newStrategy string 99 expectErr bool 100 }{ 101 { 102 name: "when the Strategy has not changed", 103 oldStrategy: string(addonsv1.ClusterResourceSetStrategyApplyOnce), 104 newStrategy: string(addonsv1.ClusterResourceSetStrategyApplyOnce), 105 expectErr: false, 106 }, 107 { 108 name: "when the Strategy has changed", 109 oldStrategy: string(addonsv1.ClusterResourceSetStrategyApplyOnce), 110 newStrategy: "", 111 expectErr: true, 112 }, 113 } 114 115 for _, tt := range tests { 116 t.Run(tt.name, func(t *testing.T) { 117 g := NewWithT(t) 118 119 newClusterResourceSet := &addonsv1.ClusterResourceSet{ 120 Spec: addonsv1.ClusterResourceSetSpec{ 121 ClusterSelector: metav1.LabelSelector{ 122 MatchLabels: map[string]string{ 123 "test": "test", 124 }, 125 }, 126 Strategy: tt.newStrategy, 127 }, 128 } 129 130 oldClusterResourceSet := &addonsv1.ClusterResourceSet{ 131 Spec: addonsv1.ClusterResourceSetSpec{ 132 ClusterSelector: metav1.LabelSelector{ 133 MatchLabels: map[string]string{ 134 "test": "test", 135 }, 136 }, 137 Strategy: tt.oldStrategy, 138 }, 139 } 140 webhook := ClusterResourceSet{} 141 142 warnings, err := webhook.ValidateUpdate(ctx, oldClusterResourceSet, newClusterResourceSet) 143 if tt.expectErr { 144 g.Expect(err).To(HaveOccurred()) 145 g.Expect(warnings).To(BeEmpty()) 146 return 147 } 148 g.Expect(err).ToNot(HaveOccurred()) 149 g.Expect(warnings).To(BeEmpty()) 150 }) 151 } 152 } 153 154 func TestClusterResourceSetClusterSelectorImmutable(t *testing.T) { 155 tests := []struct { 156 name string 157 oldClusterSelector map[string]string 158 newClusterSelector map[string]string 159 expectErr bool 160 }{ 161 { 162 name: "when the ClusterSelector has not changed", 163 oldClusterSelector: map[string]string{"foo": "bar"}, 164 newClusterSelector: map[string]string{"foo": "bar"}, 165 expectErr: false, 166 }, 167 { 168 name: "when the ClusterSelector has changed", 169 oldClusterSelector: map[string]string{"foo": "bar"}, 170 newClusterSelector: map[string]string{"foo": "different"}, 171 expectErr: true, 172 }, 173 } 174 175 for _, tt := range tests { 176 t.Run(tt.name, func(t *testing.T) { 177 g := NewWithT(t) 178 179 newClusterResourceSet := &addonsv1.ClusterResourceSet{ 180 Spec: addonsv1.ClusterResourceSetSpec{ 181 ClusterSelector: metav1.LabelSelector{ 182 MatchLabels: tt.newClusterSelector, 183 }, 184 }, 185 } 186 187 oldClusterResourceSet := &addonsv1.ClusterResourceSet{ 188 Spec: addonsv1.ClusterResourceSetSpec{ 189 ClusterSelector: metav1.LabelSelector{ 190 MatchLabels: tt.oldClusterSelector, 191 }, 192 }, 193 } 194 webhook := ClusterResourceSet{} 195 196 warnings, err := webhook.ValidateUpdate(ctx, oldClusterResourceSet, newClusterResourceSet) 197 if tt.expectErr { 198 g.Expect(err).To(HaveOccurred()) 199 g.Expect(warnings).To(BeEmpty()) 200 return 201 } 202 g.Expect(err).ToNot(HaveOccurred()) 203 g.Expect(warnings).To(BeEmpty()) 204 }) 205 } 206 } 207 208 func TestClusterResourceSetSelectorNotEmptyValidation(t *testing.T) { 209 g := NewWithT(t) 210 clusterResourceSet := &addonsv1.ClusterResourceSet{} 211 webhook := ClusterResourceSet{} 212 err := webhook.validate(nil, clusterResourceSet) 213 g.Expect(err).To(HaveOccurred()) 214 g.Expect(err.Error()).To(ContainSubstring("selector must not be empty")) 215 }