1
16
17 package taints
18
19 import (
20 "reflect"
21 "strings"
22 "testing"
23
24 v1 "k8s.io/api/core/v1"
25
26 "github.com/google/go-cmp/cmp"
27 )
28
29 func TestAddOrUpdateTaint(t *testing.T) {
30 taint := v1.Taint{
31 Key: "foo",
32 Value: "bar",
33 Effect: v1.TaintEffectNoSchedule,
34 }
35
36 taintNew := v1.Taint{
37 Key: "foo_1",
38 Value: "bar_1",
39 Effect: v1.TaintEffectNoSchedule,
40 }
41
42 taintUpdateValue := taint
43 taintUpdateValue.Value = "bar_1"
44
45 testcases := []struct {
46 name string
47 node *v1.Node
48 taint *v1.Taint
49 expectedUpdate bool
50 expectedTaints []v1.Taint
51 }{
52 {
53 name: "add a new taint",
54 node: &v1.Node{},
55 taint: &taint,
56 expectedUpdate: true,
57 expectedTaints: []v1.Taint{taint},
58 },
59 {
60 name: "add a unique taint",
61 node: &v1.Node{
62 Spec: v1.NodeSpec{Taints: []v1.Taint{taint}},
63 },
64 taint: &taintNew,
65 expectedUpdate: true,
66 expectedTaints: []v1.Taint{taint, taintNew},
67 },
68 {
69 name: "add duplicate taint",
70 node: &v1.Node{
71 Spec: v1.NodeSpec{Taints: []v1.Taint{taint}},
72 },
73 taint: &taint,
74 expectedUpdate: false,
75 expectedTaints: []v1.Taint{taint},
76 },
77 {
78 name: "update taint value",
79 node: &v1.Node{
80 Spec: v1.NodeSpec{Taints: []v1.Taint{taint}},
81 },
82 taint: &taintUpdateValue,
83 expectedUpdate: true,
84 expectedTaints: []v1.Taint{taintUpdateValue},
85 },
86 }
87
88 for _, tc := range testcases {
89 t.Run(tc.name, func(t *testing.T) {
90 newNode, updated, err := AddOrUpdateTaint(tc.node, tc.taint)
91 if err != nil {
92 t.Errorf("[%s] should not raise error but got %v", tc.name, err)
93 }
94 if updated != tc.expectedUpdate {
95 t.Errorf("[%s] expected taints to not be updated", tc.name)
96 }
97 if diff := cmp.Diff(newNode.Spec.Taints, tc.expectedTaints); diff != "" {
98 t.Errorf("Unexpected result (-want, +got):\n%s", diff)
99 }
100 })
101 }
102 }
103
104 func TestTaintExists(t *testing.T) {
105 testingTaints := []v1.Taint{
106 {
107 Key: "foo_1",
108 Value: "bar_1",
109 Effect: v1.TaintEffectNoExecute,
110 },
111 {
112 Key: "foo_2",
113 Value: "bar_2",
114 Effect: v1.TaintEffectNoSchedule,
115 },
116 }
117
118 cases := []struct {
119 name string
120 taintToFind *v1.Taint
121 expectedResult bool
122 }{
123 {
124 name: "taint exists",
125 taintToFind: &v1.Taint{Key: "foo_1", Value: "bar_1", Effect: v1.TaintEffectNoExecute},
126 expectedResult: true,
127 },
128 {
129 name: "different key",
130 taintToFind: &v1.Taint{Key: "no_such_key", Value: "bar_1", Effect: v1.TaintEffectNoExecute},
131 expectedResult: false,
132 },
133 {
134 name: "different effect",
135 taintToFind: &v1.Taint{Key: "foo_1", Value: "bar_1", Effect: v1.TaintEffectNoSchedule},
136 expectedResult: false,
137 },
138 }
139
140 for _, c := range cases {
141 result := TaintExists(testingTaints, c.taintToFind)
142
143 if result != c.expectedResult {
144 t.Errorf("[%s] unexpected results: %v", c.name, result)
145 continue
146 }
147 }
148 }
149
150 func TestTaintKeyExists(t *testing.T) {
151 testingTaints := []v1.Taint{
152 {
153 Key: "foo_1",
154 Value: "bar_1",
155 Effect: v1.TaintEffectNoExecute,
156 },
157 {
158 Key: "foo_2",
159 Value: "bar_2",
160 Effect: v1.TaintEffectNoSchedule,
161 },
162 }
163
164 cases := []struct {
165 name string
166 taintKeyToMatch string
167 expectedResult bool
168 }{
169 {
170 name: "taint key exists",
171 taintKeyToMatch: "foo_1",
172 expectedResult: true,
173 },
174 {
175 name: "taint key does not exist",
176 taintKeyToMatch: "foo_3",
177 expectedResult: false,
178 },
179 }
180
181 for _, c := range cases {
182 t.Run(c.name, func(t *testing.T) {
183 result := TaintKeyExists(testingTaints, c.taintKeyToMatch)
184
185 if result != c.expectedResult {
186 t.Errorf("[%s] unexpected results: %v", c.name, result)
187 }
188 })
189 }
190 }
191
192 func TestTaintSetFilter(t *testing.T) {
193 testTaint1 := v1.Taint{
194 Key: "foo_1",
195 Value: "bar_1",
196 Effect: v1.TaintEffectNoExecute,
197 }
198 testTaint2 := v1.Taint{
199 Key: "foo_2",
200 Value: "bar_2",
201 Effect: v1.TaintEffectNoSchedule,
202 }
203
204 testTaint3 := v1.Taint{
205 Key: "foo_3",
206 Value: "bar_3",
207 Effect: v1.TaintEffectNoSchedule,
208 }
209 testTaints := []v1.Taint{testTaint1, testTaint2, testTaint3}
210
211 testcases := []struct {
212 name string
213 fn func(t *v1.Taint) bool
214 expectedTaints []v1.Taint
215 }{
216 {
217 name: "Filter out nothing",
218 fn: func(t *v1.Taint) bool {
219 if t.Key == v1.TaintNodeUnschedulable {
220 return true
221 }
222 return false
223 },
224 expectedTaints: []v1.Taint{},
225 },
226 {
227 name: "Filter out a subset",
228 fn: func(t *v1.Taint) bool {
229 if t.Effect == v1.TaintEffectNoExecute {
230 return true
231 }
232 return false
233 },
234 expectedTaints: []v1.Taint{testTaint1},
235 },
236 {
237 name: "Filter out everything",
238 fn: func(t *v1.Taint) bool { return true },
239 expectedTaints: []v1.Taint{testTaint1, testTaint2, testTaint3},
240 },
241 }
242 for _, tc := range testcases {
243 t.Run(tc.name, func(t *testing.T) {
244 taintsAfterFilter := TaintSetFilter(testTaints, tc.fn)
245 if diff := cmp.Diff(tc.expectedTaints, taintsAfterFilter); diff != "" {
246 t.Errorf("Unexpected postFilterResult (-want, +got):\n%s", diff)
247 }
248 })
249 }
250 }
251
252 func TestRemoveTaint(t *testing.T) {
253 cases := []struct {
254 name string
255 node *v1.Node
256 taintToRemove *v1.Taint
257 expectedTaints []v1.Taint
258 expectedResult bool
259 }{
260 {
261 name: "remove taint unsuccessfully",
262 node: &v1.Node{
263 Spec: v1.NodeSpec{
264 Taints: []v1.Taint{
265 {
266 Key: "foo",
267 Effect: v1.TaintEffectNoSchedule,
268 },
269 },
270 },
271 },
272 taintToRemove: &v1.Taint{
273 Key: "foo_1",
274 Effect: v1.TaintEffectNoSchedule,
275 },
276 expectedTaints: []v1.Taint{
277 {
278 Key: "foo",
279 Effect: v1.TaintEffectNoSchedule,
280 },
281 },
282 expectedResult: false,
283 },
284 {
285 name: "remove taint successfully",
286 node: &v1.Node{
287 Spec: v1.NodeSpec{
288 Taints: []v1.Taint{
289 {
290 Key: "foo",
291 Effect: v1.TaintEffectNoSchedule,
292 },
293 },
294 },
295 },
296 taintToRemove: &v1.Taint{
297 Key: "foo",
298 Effect: v1.TaintEffectNoSchedule,
299 },
300 expectedTaints: []v1.Taint{},
301 expectedResult: true,
302 },
303 {
304 name: "remove taint from node with no taint",
305 node: &v1.Node{
306 Spec: v1.NodeSpec{
307 Taints: []v1.Taint{},
308 },
309 },
310 taintToRemove: &v1.Taint{
311 Key: "foo",
312 Effect: v1.TaintEffectNoSchedule,
313 },
314 expectedTaints: []v1.Taint{},
315 expectedResult: false,
316 },
317 }
318
319 for _, c := range cases {
320 newNode, result, err := RemoveTaint(c.node, c.taintToRemove)
321 if err != nil {
322 t.Errorf("[%s] should not raise error but got: %v", c.name, err)
323 }
324 if result != c.expectedResult {
325 t.Errorf("[%s] should return %t, but got: %t", c.name, c.expectedResult, result)
326 }
327 if !reflect.DeepEqual(newNode.Spec.Taints, c.expectedTaints) {
328 t.Errorf("[%s] the new node object should have taints %v, but got: %v", c.name, c.expectedTaints, newNode.Spec.Taints)
329 }
330 }
331 }
332
333 func TestDeleteTaint(t *testing.T) {
334 cases := []struct {
335 name string
336 taints []v1.Taint
337 taintToDelete *v1.Taint
338 expectedTaints []v1.Taint
339 expectedResult bool
340 }{
341 {
342 name: "delete taint with different name",
343 taints: []v1.Taint{
344 {
345 Key: "foo",
346 Effect: v1.TaintEffectNoSchedule,
347 },
348 },
349 taintToDelete: &v1.Taint{Key: "foo_1", Effect: v1.TaintEffectNoSchedule},
350 expectedTaints: []v1.Taint{
351 {
352 Key: "foo",
353 Effect: v1.TaintEffectNoSchedule,
354 },
355 },
356 expectedResult: false,
357 },
358 {
359 name: "delete taint with different effect",
360 taints: []v1.Taint{
361 {
362 Key: "foo",
363 Effect: v1.TaintEffectNoSchedule,
364 },
365 },
366 taintToDelete: &v1.Taint{Key: "foo", Effect: v1.TaintEffectNoExecute},
367 expectedTaints: []v1.Taint{
368 {
369 Key: "foo",
370 Effect: v1.TaintEffectNoSchedule,
371 },
372 },
373 expectedResult: false,
374 },
375 {
376 name: "delete taint successfully",
377 taints: []v1.Taint{
378 {
379 Key: "foo",
380 Effect: v1.TaintEffectNoSchedule,
381 },
382 },
383 taintToDelete: &v1.Taint{Key: "foo", Effect: v1.TaintEffectNoSchedule},
384 expectedTaints: []v1.Taint{},
385 expectedResult: true,
386 },
387 {
388 name: "delete taint from empty taint array",
389 taints: []v1.Taint{},
390 taintToDelete: &v1.Taint{Key: "foo", Effect: v1.TaintEffectNoSchedule},
391 expectedTaints: []v1.Taint{},
392 expectedResult: false,
393 },
394 }
395
396 for _, c := range cases {
397 taints, result := DeleteTaint(c.taints, c.taintToDelete)
398 if result != c.expectedResult {
399 t.Errorf("[%s] should return %t, but got: %t", c.name, c.expectedResult, result)
400 }
401 if !reflect.DeepEqual(taints, c.expectedTaints) {
402 t.Errorf("[%s] the result taints should be %v, but got: %v", c.name, c.expectedTaints, taints)
403 }
404 }
405 }
406
407 func TestDeleteTaintByKey(t *testing.T) {
408 cases := []struct {
409 name string
410 taints []v1.Taint
411 taintKey string
412 expectedTaints []v1.Taint
413 expectedResult bool
414 }{
415 {
416 name: "delete taint unsuccessfully",
417 taints: []v1.Taint{
418 {
419 Key: "foo",
420 Value: "bar",
421 Effect: v1.TaintEffectNoSchedule,
422 },
423 },
424 taintKey: "foo_1",
425 expectedTaints: []v1.Taint{
426 {
427 Key: "foo",
428 Value: "bar",
429 Effect: v1.TaintEffectNoSchedule,
430 },
431 },
432 expectedResult: false,
433 },
434 {
435 name: "delete taint successfully",
436 taints: []v1.Taint{
437 {
438 Key: "foo",
439 Value: "bar",
440 Effect: v1.TaintEffectNoSchedule,
441 },
442 },
443 taintKey: "foo",
444 expectedTaints: []v1.Taint{},
445 expectedResult: true,
446 },
447 {
448 name: "delete taint from empty taint array",
449 taints: []v1.Taint{},
450 taintKey: "foo",
451 expectedTaints: []v1.Taint{},
452 expectedResult: false,
453 },
454 }
455
456 for _, c := range cases {
457 taints, result := DeleteTaintsByKey(c.taints, c.taintKey)
458 if result != c.expectedResult {
459 t.Errorf("[%s] should return %t, but got: %t", c.name, c.expectedResult, result)
460 }
461 if !reflect.DeepEqual(c.expectedTaints, taints) {
462 t.Errorf("[%s] the result taints should be %v, but got: %v", c.name, c.expectedTaints, taints)
463 }
464 }
465 }
466
467 func TestCheckIfTaintsAlreadyExists(t *testing.T) {
468 oldTaints := []v1.Taint{
469 {
470 Key: "foo_1",
471 Value: "bar",
472 Effect: v1.TaintEffectNoSchedule,
473 },
474 {
475 Key: "foo_2",
476 Value: "bar",
477 Effect: v1.TaintEffectNoSchedule,
478 },
479 {
480 Key: "foo_3",
481 Value: "bar",
482 Effect: v1.TaintEffectNoSchedule,
483 },
484 }
485
486 cases := []struct {
487 name string
488 taintsToCheck []v1.Taint
489 expectedResult string
490 }{
491 {
492 name: "empty array",
493 taintsToCheck: []v1.Taint{},
494 expectedResult: "",
495 },
496 {
497 name: "no match",
498 taintsToCheck: []v1.Taint{
499 {
500 Key: "foo_1",
501 Effect: v1.TaintEffectNoExecute,
502 },
503 },
504 expectedResult: "",
505 },
506 {
507 name: "match one taint",
508 taintsToCheck: []v1.Taint{
509 {
510 Key: "foo_2",
511 Effect: v1.TaintEffectNoSchedule,
512 },
513 },
514 expectedResult: "foo_2",
515 },
516 {
517 name: "match two taints",
518 taintsToCheck: []v1.Taint{
519 {
520 Key: "foo_2",
521 Effect: v1.TaintEffectNoSchedule,
522 },
523 {
524 Key: "foo_3",
525 Effect: v1.TaintEffectNoSchedule,
526 },
527 },
528 expectedResult: "foo_2,foo_3",
529 },
530 }
531
532 for _, c := range cases {
533 result := CheckIfTaintsAlreadyExists(oldTaints, c.taintsToCheck)
534 if result != c.expectedResult {
535 t.Errorf("[%s] should return '%s', but got: '%s'", c.name, c.expectedResult, result)
536 }
537 }
538 }
539
540 func TestParseTaints(t *testing.T) {
541 cases := []struct {
542 name string
543 spec []string
544 expectedTaints []v1.Taint
545 expectedTaintsToRemove []v1.Taint
546 expectedErr bool
547 }{
548 {
549 name: "invalid empty spec format",
550 spec: []string{""},
551 expectedErr: true,
552 },
553
554 {
555 name: "invalid spec format without effect",
556 spec: []string{"foo=abc"},
557 expectedErr: true,
558 },
559 {
560 name: "invalid spec format with multiple '=' separators",
561 spec: []string{"foo=abc=xyz:NoSchedule"},
562 expectedErr: true,
563 },
564 {
565 name: "invalid spec format with multiple ':' separators",
566 spec: []string{"foo=abc:xyz:NoSchedule"},
567 expectedErr: true,
568 },
569 {
570 name: "invalid spec taint value without separator",
571 spec: []string{"foo"},
572 expectedErr: true,
573 },
574
575 {
576 name: "invalid spec taint value with special chars '%^@'",
577 spec: []string{"foo=nospecialchars%^@:NoSchedule"},
578 expectedErr: true,
579 },
580 {
581 name: "invalid spec taint value with non-alphanumeric characters",
582 spec: []string{"foo=Tama-nui-te-rā.is.Māori.sun:NoSchedule"},
583 expectedErr: true,
584 },
585 {
586 name: "invalid spec taint value with special chars '\\'",
587 spec: []string{"foo=\\backslashes\\are\\bad:NoSchedule"},
588 expectedErr: true,
589 },
590 {
591 name: "invalid spec taint value with start with an non-alphanumeric character '-'",
592 spec: []string{"foo=-starts-with-dash:NoSchedule"},
593 expectedErr: true,
594 },
595 {
596 name: "invalid spec taint value with end with an non-alphanumeric character '-'",
597 spec: []string{"foo=ends-with-dash-:NoSchedule"},
598 expectedErr: true,
599 },
600 {
601 name: "invalid spec taint value with start with an non-alphanumeric character '.'",
602 spec: []string{"foo=.starts.with.dot:NoSchedule"},
603 expectedErr: true,
604 },
605 {
606 name: "invalid spec taint value with end with an non-alphanumeric character '.'",
607 spec: []string{"foo=ends.with.dot.:NoSchedule"},
608 expectedErr: true,
609 },
610
611 {
612 name: "invalid spec effect for adding taint",
613 spec: []string{"foo=abc:invalid_effect"},
614 expectedErr: true,
615 },
616 {
617 name: "invalid spec effect for deleting taint",
618 spec: []string{"foo:invalid_effect-"},
619 expectedErr: true,
620 },
621 {
622 name: "duplicated taints with the same key and effect",
623 spec: []string{"foo=abc:NoSchedule", "foo=abc:NoSchedule"},
624 expectedErr: true,
625 },
626 {
627 name: "invalid spec taint value exceeding the limit",
628 spec: []string{strings.Repeat("a", 64)},
629 expectedErr: true,
630 },
631 {
632 name: "add new taints with no special chars",
633 spec: []string{"foo=abc:NoSchedule", "bar=abc:NoSchedule", "baz:NoSchedule", "qux:NoSchedule", "foobar=:NoSchedule"},
634 expectedTaints: []v1.Taint{
635 {
636 Key: "foo",
637 Value: "abc",
638 Effect: v1.TaintEffectNoSchedule,
639 },
640 {
641 Key: "bar",
642 Value: "abc",
643 Effect: v1.TaintEffectNoSchedule,
644 },
645 {
646 Key: "baz",
647 Value: "",
648 Effect: v1.TaintEffectNoSchedule,
649 },
650 {
651 Key: "qux",
652 Value: "",
653 Effect: v1.TaintEffectNoSchedule,
654 },
655 {
656 Key: "foobar",
657 Value: "",
658 Effect: v1.TaintEffectNoSchedule,
659 },
660 },
661 expectedErr: false,
662 },
663 {
664 name: "delete taints with no special chars",
665 spec: []string{"foo:NoSchedule-", "bar:NoSchedule-", "qux=:NoSchedule-", "dedicated-"},
666 expectedTaintsToRemove: []v1.Taint{
667 {
668 Key: "foo",
669 Effect: v1.TaintEffectNoSchedule,
670 },
671 {
672 Key: "bar",
673 Effect: v1.TaintEffectNoSchedule,
674 },
675 {
676 Key: "qux",
677 Effect: v1.TaintEffectNoSchedule,
678 },
679 {
680 Key: "dedicated",
681 },
682 },
683 expectedErr: false,
684 },
685 {
686 name: "add taints and delete taints with no special chars",
687 spec: []string{"foo=abc:NoSchedule", "bar=abc:NoSchedule", "baz:NoSchedule", "qux:NoSchedule", "foobar=:NoSchedule", "foo:NoSchedule-", "bar:NoSchedule-", "baz=:NoSchedule-"},
688 expectedTaints: []v1.Taint{
689 {
690 Key: "foo",
691 Value: "abc",
692 Effect: v1.TaintEffectNoSchedule,
693 },
694 {
695 Key: "bar",
696 Value: "abc",
697 Effect: v1.TaintEffectNoSchedule,
698 },
699 {
700 Key: "baz",
701 Value: "",
702 Effect: v1.TaintEffectNoSchedule,
703 },
704 {
705 Key: "qux",
706 Value: "",
707 Effect: v1.TaintEffectNoSchedule,
708 },
709 {
710 Key: "foobar",
711 Value: "",
712 Effect: v1.TaintEffectNoSchedule,
713 },
714 },
715 expectedTaintsToRemove: []v1.Taint{
716 {
717 Key: "foo",
718 Effect: v1.TaintEffectNoSchedule,
719 },
720 {
721 Key: "bar",
722 Effect: v1.TaintEffectNoSchedule,
723 },
724 {
725 Key: "baz",
726 Value: "",
727 Effect: v1.TaintEffectNoSchedule,
728 },
729 },
730 expectedErr: false,
731 },
732 }
733
734 for _, c := range cases {
735 taints, taintsToRemove, err := ParseTaints(c.spec)
736 if c.expectedErr && err == nil {
737 t.Errorf("[%s] expected error for spec %s, but got nothing", c.name, c.spec)
738 }
739 if !c.expectedErr && err != nil {
740 t.Errorf("[%s] expected no error for spec %s, but got: %v", c.name, c.spec, err)
741 }
742 if !reflect.DeepEqual(c.expectedTaints, taints) {
743 t.Errorf("[%s] expected returen taints as %v, but got: %v", c.name, c.expectedTaints, taints)
744 }
745 if !reflect.DeepEqual(c.expectedTaintsToRemove, taintsToRemove) {
746 t.Errorf("[%s] expected return taints to be removed as %v, but got: %v", c.name, c.expectedTaintsToRemove, taintsToRemove)
747 }
748 }
749 }
750
751 func TestValidateTaint(t *testing.T) {
752 cases := []struct {
753 name string
754 taintsToCheck v1.Taint
755 expectedErr bool
756 }{
757 {
758 name: "taint invalid key",
759 taintsToCheck: v1.Taint{Key: "", Value: "bar_1", Effect: v1.TaintEffectNoExecute},
760 expectedErr: true,
761 },
762 {
763 name: "taint invalid value",
764 taintsToCheck: v1.Taint{Key: "foo_1", Value: strings.Repeat("a", 64), Effect: v1.TaintEffectNoExecute},
765 expectedErr: true,
766 },
767 {
768 name: "taint invalid effect",
769 taintsToCheck: v1.Taint{Key: "foo_2", Value: "bar_2", Effect: "no_such_effect"},
770 expectedErr: true,
771 },
772 {
773 name: "valid taint",
774 taintsToCheck: v1.Taint{Key: "foo_3", Value: "bar_3", Effect: v1.TaintEffectNoExecute},
775 expectedErr: false,
776 },
777 {
778 name: "valid taint",
779 taintsToCheck: v1.Taint{Key: "foo_4", Effect: v1.TaintEffectNoExecute},
780 expectedErr: false,
781 },
782 {
783 name: "valid taint",
784 taintsToCheck: v1.Taint{Key: "foo_5", Value: "bar_5"},
785 expectedErr: false,
786 },
787 }
788
789 for _, c := range cases {
790 err := CheckTaintValidation(c.taintsToCheck)
791
792 if c.expectedErr && err == nil {
793 t.Errorf("[%s] expected error for spec %+v, but got nothing", c.name, c.taintsToCheck)
794 }
795 }
796 }
797
798 func TestTaintSetDiff(t *testing.T) {
799 cases := []struct {
800 name string
801 t1 []v1.Taint
802 t2 []v1.Taint
803 expectedTaintsToAdd []*v1.Taint
804 expectedTaintsToRemove []*v1.Taint
805 }{
806 {
807 name: "two_taints_are_nil",
808 expectedTaintsToAdd: nil,
809 expectedTaintsToRemove: nil,
810 },
811 {
812 name: "one_taint_is_nil_and_the_other_is_not_nil",
813 t1: []v1.Taint{
814 {
815 Key: "foo_1",
816 Value: "bar_1",
817 Effect: v1.TaintEffectNoExecute,
818 },
819 {
820 Key: "foo_2",
821 Value: "bar_2",
822 Effect: v1.TaintEffectNoSchedule,
823 },
824 },
825 expectedTaintsToAdd: []*v1.Taint{
826 {
827 Key: "foo_1",
828 Value: "bar_1",
829 Effect: v1.TaintEffectNoExecute,
830 },
831 {
832 Key: "foo_2",
833 Value: "bar_2",
834 Effect: v1.TaintEffectNoSchedule,
835 },
836 },
837 expectedTaintsToRemove: nil,
838 },
839 {
840 name: "shared_taints_with_the_same_key_value_effect",
841 t1: []v1.Taint{
842 {
843 Key: "foo_1",
844 Value: "bar_1",
845 Effect: v1.TaintEffectNoExecute,
846 },
847 {
848 Key: "foo_2",
849 Value: "bar_2",
850 Effect: v1.TaintEffectNoSchedule,
851 },
852 },
853 t2: []v1.Taint{
854 {
855 Key: "foo_3",
856 Value: "bar_3",
857 Effect: v1.TaintEffectNoExecute,
858 },
859 {
860 Key: "foo_2",
861 Value: "bar_2",
862 Effect: v1.TaintEffectNoSchedule,
863 },
864 },
865 expectedTaintsToAdd: []*v1.Taint{
866 {
867 Key: "foo_1",
868 Value: "bar_1",
869 Effect: v1.TaintEffectNoExecute,
870 },
871 },
872 expectedTaintsToRemove: []*v1.Taint{
873 {
874 Key: "foo_3",
875 Value: "bar_3",
876 Effect: v1.TaintEffectNoExecute,
877 },
878 },
879 },
880 {
881 name: "shared_taints_with_the_same_key_effect_different_value",
882 t1: []v1.Taint{
883 {
884 Key: "foo_1",
885 Value: "bar_1",
886 Effect: v1.TaintEffectNoExecute,
887 },
888 {
889 Key: "foo_2",
890 Value: "different-value",
891 Effect: v1.TaintEffectNoSchedule,
892 },
893 },
894 t2: []v1.Taint{
895 {
896 Key: "foo_3",
897 Value: "bar_3",
898 Effect: v1.TaintEffectNoExecute,
899 },
900 {
901 Key: "foo_2",
902 Value: "bar_2",
903 Effect: v1.TaintEffectNoSchedule,
904 },
905 },
906 expectedTaintsToAdd: []*v1.Taint{
907 {
908 Key: "foo_1",
909 Value: "bar_1",
910 Effect: v1.TaintEffectNoExecute,
911 },
912 },
913 expectedTaintsToRemove: []*v1.Taint{
914 {
915 Key: "foo_3",
916 Value: "bar_3",
917 Effect: v1.TaintEffectNoExecute,
918 },
919 },
920 },
921 {
922 name: "shared_taints_with_the_same_key_different_value_effect",
923 t1: []v1.Taint{
924 {
925 Key: "foo_1",
926 Value: "bar_1",
927 Effect: v1.TaintEffectNoExecute,
928 },
929 {
930 Key: "foo_2",
931 Value: "different-value",
932 Effect: v1.TaintEffectNoExecute,
933 },
934 },
935 t2: []v1.Taint{
936 {
937 Key: "foo_3",
938 Value: "bar_3",
939 Effect: v1.TaintEffectNoExecute,
940 },
941 {
942 Key: "foo_2",
943 Value: "bar_2",
944 Effect: v1.TaintEffectNoSchedule,
945 },
946 },
947 expectedTaintsToAdd: []*v1.Taint{
948 {
949 Key: "foo_1",
950 Value: "bar_1",
951 Effect: v1.TaintEffectNoExecute,
952 },
953 {
954 Key: "foo_2",
955 Value: "different-value",
956 Effect: v1.TaintEffectNoExecute,
957 },
958 },
959 expectedTaintsToRemove: []*v1.Taint{
960 {
961 Key: "foo_3",
962 Value: "bar_3",
963 Effect: v1.TaintEffectNoExecute,
964 },
965 {
966 Key: "foo_2",
967 Value: "bar_2",
968 Effect: v1.TaintEffectNoSchedule,
969 },
970 },
971 },
972 }
973
974 for _, tt := range cases {
975 t.Run(tt.name, func(t *testing.T) {
976 add, remove := TaintSetDiff(tt.t1, tt.t2)
977 if !reflect.DeepEqual(add, tt.expectedTaintsToAdd) {
978 t.Errorf("taintsToAdd: %v should equal %v, but get unexpected results", add, tt.expectedTaintsToAdd)
979 }
980 if !reflect.DeepEqual(remove, tt.expectedTaintsToRemove) {
981 t.Errorf("taintsToRemove: %v should equal %v, but get unexpected results", remove, tt.expectedTaintsToRemove)
982 }
983 })
984 }
985 }
986
View as plain text