1
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
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 }
294
View as plain text