k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/plugin/pkg/admission/defaulttolerationseconds/admission_test.go (about) 1 /* 2 Copyright 2017 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 defaulttolerationseconds 18 19 import ( 20 "context" 21 "testing" 22 23 v1 "k8s.io/api/core/v1" 24 "k8s.io/apiserver/pkg/admission" 25 admissiontesting "k8s.io/apiserver/pkg/admission/testing" 26 api "k8s.io/kubernetes/pkg/apis/core" 27 "k8s.io/kubernetes/pkg/apis/core/helper" 28 ) 29 30 func TestForgivenessAdmission(t *testing.T) { 31 var defaultTolerationSeconds int64 = 300 32 33 genTolerationSeconds := func(s int64) *int64 { 34 return &s 35 } 36 37 handler := admissiontesting.WithReinvocationTesting(t, NewDefaultTolerationSeconds()) 38 // NOTE: for anyone who want to modify this test, the order of tolerations matters! 39 tests := []struct { 40 description string 41 requestedPod api.Pod 42 expectedPod api.Pod 43 }{ 44 { 45 description: "pod has no tolerations, expect add tolerations for `not-ready:NoExecute` and `unreachable:NoExecute`", 46 requestedPod: api.Pod{ 47 Spec: api.PodSpec{}, 48 }, 49 expectedPod: api.Pod{ 50 Spec: api.PodSpec{ 51 Tolerations: []api.Toleration{ 52 { 53 Key: v1.TaintNodeNotReady, 54 Operator: api.TolerationOpExists, 55 Effect: api.TaintEffectNoExecute, 56 TolerationSeconds: &defaultTolerationSeconds, 57 }, 58 { 59 Key: v1.TaintNodeUnreachable, 60 Operator: api.TolerationOpExists, 61 Effect: api.TaintEffectNoExecute, 62 TolerationSeconds: &defaultTolerationSeconds, 63 }, 64 }, 65 }, 66 }, 67 }, 68 { 69 description: "pod has tolerations, but none is for taint `not-ready:NoExecute` or `unreachable:NoExecute`, expect add tolerations for `not-ready:NoExecute` and `unreachable:NoExecute`", 70 requestedPod: api.Pod{ 71 Spec: api.PodSpec{ 72 Tolerations: []api.Toleration{ 73 { 74 Key: "foo", 75 Operator: api.TolerationOpEqual, 76 Value: "bar", 77 Effect: api.TaintEffectNoSchedule, 78 TolerationSeconds: genTolerationSeconds(700), 79 }, 80 }, 81 }, 82 }, 83 expectedPod: api.Pod{ 84 Spec: api.PodSpec{ 85 Tolerations: []api.Toleration{ 86 { 87 Key: "foo", 88 Operator: api.TolerationOpEqual, 89 Value: "bar", 90 Effect: api.TaintEffectNoSchedule, 91 TolerationSeconds: genTolerationSeconds(700), 92 }, 93 { 94 Key: v1.TaintNodeNotReady, 95 Operator: api.TolerationOpExists, 96 Effect: api.TaintEffectNoExecute, 97 TolerationSeconds: &defaultTolerationSeconds, 98 }, 99 { 100 Key: v1.TaintNodeUnreachable, 101 Operator: api.TolerationOpExists, 102 Effect: api.TaintEffectNoExecute, 103 TolerationSeconds: &defaultTolerationSeconds, 104 }, 105 }, 106 }, 107 }, 108 }, 109 { 110 description: "pod specified a toleration for taint `not-ready:NoExecute`, expect add toleration for `unreachable:NoExecute`", 111 requestedPod: api.Pod{ 112 Spec: api.PodSpec{ 113 Tolerations: []api.Toleration{ 114 { 115 Key: v1.TaintNodeNotReady, 116 Operator: api.TolerationOpExists, 117 Effect: api.TaintEffectNoExecute, 118 TolerationSeconds: genTolerationSeconds(700), 119 }, 120 }, 121 }, 122 }, 123 expectedPod: api.Pod{ 124 Spec: api.PodSpec{ 125 Tolerations: []api.Toleration{ 126 { 127 Key: v1.TaintNodeNotReady, 128 Operator: api.TolerationOpExists, 129 Effect: api.TaintEffectNoExecute, 130 TolerationSeconds: genTolerationSeconds(700), 131 }, 132 { 133 Key: v1.TaintNodeUnreachable, 134 Operator: api.TolerationOpExists, 135 Effect: api.TaintEffectNoExecute, 136 TolerationSeconds: &defaultTolerationSeconds, 137 }, 138 }, 139 }, 140 }, 141 }, 142 { 143 description: "pod specified a toleration for taint `unreachable:NoExecute`, expect add toleration for `not-ready:NoExecute`", 144 requestedPod: api.Pod{ 145 Spec: api.PodSpec{ 146 Tolerations: []api.Toleration{ 147 { 148 Key: v1.TaintNodeUnreachable, 149 Operator: api.TolerationOpExists, 150 Effect: api.TaintEffectNoExecute, 151 TolerationSeconds: genTolerationSeconds(700), 152 }, 153 }, 154 }, 155 }, 156 expectedPod: api.Pod{ 157 Spec: api.PodSpec{ 158 Tolerations: []api.Toleration{ 159 { 160 Key: v1.TaintNodeUnreachable, 161 Operator: api.TolerationOpExists, 162 Effect: api.TaintEffectNoExecute, 163 TolerationSeconds: genTolerationSeconds(700), 164 }, 165 { 166 Key: v1.TaintNodeNotReady, 167 Operator: api.TolerationOpExists, 168 Effect: api.TaintEffectNoExecute, 169 TolerationSeconds: &defaultTolerationSeconds, 170 }, 171 }, 172 }, 173 }, 174 }, 175 { 176 description: "pod specified tolerations for both `not-ready:NoExecute` and `unreachable:NoExecute`, expect no change", 177 requestedPod: api.Pod{ 178 Spec: api.PodSpec{ 179 Tolerations: []api.Toleration{ 180 { 181 Key: v1.TaintNodeNotReady, 182 Operator: api.TolerationOpExists, 183 Effect: api.TaintEffectNoExecute, 184 TolerationSeconds: genTolerationSeconds(700), 185 }, 186 { 187 Key: v1.TaintNodeUnreachable, 188 Operator: api.TolerationOpExists, 189 Effect: api.TaintEffectNoExecute, 190 TolerationSeconds: genTolerationSeconds(700), 191 }, 192 }, 193 }, 194 }, 195 expectedPod: api.Pod{ 196 Spec: api.PodSpec{ 197 Tolerations: []api.Toleration{ 198 { 199 Key: v1.TaintNodeNotReady, 200 Operator: api.TolerationOpExists, 201 Effect: api.TaintEffectNoExecute, 202 TolerationSeconds: genTolerationSeconds(700), 203 }, 204 { 205 Key: v1.TaintNodeUnreachable, 206 Operator: api.TolerationOpExists, 207 Effect: api.TaintEffectNoExecute, 208 TolerationSeconds: genTolerationSeconds(700), 209 }, 210 }, 211 }, 212 }, 213 }, 214 { 215 description: "pod specified toleration for taint `unreachable`, expect add toleration for `not-ready:NoExecute`", 216 requestedPod: api.Pod{ 217 Spec: api.PodSpec{ 218 Tolerations: []api.Toleration{ 219 { 220 Key: v1.TaintNodeUnreachable, 221 Operator: api.TolerationOpExists, 222 TolerationSeconds: genTolerationSeconds(700), 223 }, 224 }, 225 }, 226 }, 227 expectedPod: api.Pod{ 228 Spec: api.PodSpec{ 229 Tolerations: []api.Toleration{ 230 { 231 Key: v1.TaintNodeUnreachable, 232 Operator: api.TolerationOpExists, 233 TolerationSeconds: genTolerationSeconds(700), 234 }, 235 { 236 Key: v1.TaintNodeNotReady, 237 Operator: api.TolerationOpExists, 238 Effect: api.TaintEffectNoExecute, 239 TolerationSeconds: genTolerationSeconds(300), 240 }, 241 }, 242 }, 243 }, 244 }, 245 { 246 description: "pod has wildcard toleration for all kind of taints, expect no change", 247 requestedPod: api.Pod{ 248 Spec: api.PodSpec{ 249 Tolerations: []api.Toleration{ 250 {Operator: api.TolerationOpExists, TolerationSeconds: genTolerationSeconds(700)}, 251 }, 252 }, 253 }, 254 expectedPod: api.Pod{ 255 Spec: api.PodSpec{ 256 Tolerations: []api.Toleration{ 257 { 258 Operator: api.TolerationOpExists, 259 TolerationSeconds: genTolerationSeconds(700), 260 }, 261 }, 262 }, 263 }, 264 }, 265 } 266 267 for _, test := range tests { 268 err := handler.Admit(context.TODO(), admission.NewAttributesRecord(&test.requestedPod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil, false, nil), nil) 269 if err != nil { 270 t.Errorf("[%s]: unexpected error %v for pod %+v", test.description, err, test.requestedPod) 271 } 272 273 if !helper.Semantic.DeepEqual(test.expectedPod.Spec.Tolerations, test.requestedPod.Spec.Tolerations) { 274 t.Errorf("[%s]: expected %#v got %#v", test.description, test.expectedPod.Spec.Tolerations, test.requestedPod.Spec.Tolerations) 275 } 276 } 277 } 278 279 func TestHandles(t *testing.T) { 280 handler := NewDefaultTolerationSeconds() 281 tests := map[admission.Operation]bool{ 282 admission.Update: true, 283 admission.Create: true, 284 admission.Delete: false, 285 admission.Connect: false, 286 } 287 for op, expected := range tests { 288 result := handler.Handles(op) 289 if result != expected { 290 t.Errorf("Unexpected result for operation %s: %v\n", op, result) 291 } 292 } 293 }