@@ -1820,7 +1820,6 @@ func TestMonitorNodeHealthUpdateStatus(t *testing.T) {
1820
1820
expectedPodStatusUpdate : false ,
1821
1821
},
1822
1822
}
1823
-
1824
1823
for i , item := range table {
1825
1824
nodeController , _ := newNodeLifecycleControllerFromClient (
1826
1825
nil ,
@@ -2610,6 +2609,157 @@ func TestMonitorNodeHealthMarkPodsNotReady(t *testing.T) {
2610
2609
}
2611
2610
}
2612
2611
2612
+ // TestApplyNoExecuteTaints, ensures we just have a NoExecute taint applied to node.
2613
+ // NodeController is just responsible for enqueuing the node to tainting queue from which taint manager picks up
2614
+ // and evicts the pods on the node.
2615
+ func TestApplyNoExecuteTaints (t * testing.T ) {
2616
+ fakeNow := metav1 .Date (2017 , 1 , 1 , 12 , 0 , 0 , 0 , time .UTC )
2617
+ evictionTimeout := 10 * time .Minute
2618
+
2619
+ fakeNodeHandler := & testutil.FakeNodeHandler {
2620
+ Existing : []* v1.Node {
2621
+ // Unreachable Taint with effect 'NoExecute' should be applied to this node.
2622
+ {
2623
+ ObjectMeta : metav1.ObjectMeta {
2624
+ Name : "node0" ,
2625
+ CreationTimestamp : metav1 .Date (2012 , 1 , 1 , 0 , 0 , 0 , 0 , time .UTC ),
2626
+ Labels : map [string ]string {
2627
+ kubeletapis .LabelZoneRegion : "region1" ,
2628
+ kubeletapis .LabelZoneFailureDomain : "zone1" ,
2629
+ },
2630
+ },
2631
+ Status : v1.NodeStatus {
2632
+ Conditions : []v1.NodeCondition {
2633
+ {
2634
+ Type : v1 .NodeReady ,
2635
+ Status : v1 .ConditionUnknown ,
2636
+ LastHeartbeatTime : metav1 .Date (2015 , 1 , 1 , 12 , 0 , 0 , 0 , time .UTC ),
2637
+ LastTransitionTime : metav1 .Date (2015 , 1 , 1 , 12 , 0 , 0 , 0 , time .UTC ),
2638
+ },
2639
+ },
2640
+ },
2641
+ },
2642
+ // Because of the logic that prevents NC from evicting anything when all Nodes are NotReady
2643
+ // we need second healthy node in tests.
2644
+ {
2645
+ ObjectMeta : metav1.ObjectMeta {
2646
+ Name : "node1" ,
2647
+ CreationTimestamp : metav1 .Date (2012 , 1 , 1 , 0 , 0 , 0 , 0 , time .UTC ),
2648
+ Labels : map [string ]string {
2649
+ kubeletapis .LabelZoneRegion : "region1" ,
2650
+ kubeletapis .LabelZoneFailureDomain : "zone1" ,
2651
+ },
2652
+ },
2653
+ Status : v1.NodeStatus {
2654
+ Conditions : []v1.NodeCondition {
2655
+ {
2656
+ Type : v1 .NodeReady ,
2657
+ Status : v1 .ConditionTrue ,
2658
+ LastHeartbeatTime : metav1 .Date (2017 , 1 , 1 , 12 , 0 , 0 , 0 , time .UTC ),
2659
+ LastTransitionTime : metav1 .Date (2017 , 1 , 1 , 12 , 0 , 0 , 0 , time .UTC ),
2660
+ },
2661
+ },
2662
+ },
2663
+ },
2664
+ // NotReady Taint with NoExecute effect should be applied to this node.
2665
+ {
2666
+ ObjectMeta : metav1.ObjectMeta {
2667
+ Name : "node2" ,
2668
+ CreationTimestamp : metav1 .Date (2012 , 1 , 1 , 0 , 0 , 0 , 0 , time .UTC ),
2669
+ Labels : map [string ]string {
2670
+ kubeletapis .LabelZoneRegion : "region1" ,
2671
+ kubeletapis .LabelZoneFailureDomain : "zone1" ,
2672
+ },
2673
+ },
2674
+ Status : v1.NodeStatus {
2675
+ Conditions : []v1.NodeCondition {
2676
+ {
2677
+ Type : v1 .NodeReady ,
2678
+ Status : v1 .ConditionFalse ,
2679
+ LastHeartbeatTime : metav1 .Date (2015 , 1 , 1 , 12 , 0 , 0 , 0 , time .UTC ),
2680
+ LastTransitionTime : metav1 .Date (2015 , 1 , 1 , 12 , 0 , 0 , 0 , time .UTC ),
2681
+ },
2682
+ },
2683
+ },
2684
+ },
2685
+ },
2686
+ Clientset : fake .NewSimpleClientset (& v1.PodList {Items : []v1.Pod {* testutil .NewPod ("pod0" , "node0" )}}),
2687
+ }
2688
+ healthyNodeNewStatus := v1.NodeStatus {
2689
+ Conditions : []v1.NodeCondition {
2690
+ {
2691
+ Type : v1 .NodeReady ,
2692
+ Status : v1 .ConditionTrue ,
2693
+ LastHeartbeatTime : metav1 .Date (2017 , 1 , 1 , 12 , 10 , 0 , 0 , time .UTC ),
2694
+ LastTransitionTime : metav1 .Date (2017 , 1 , 1 , 12 , 0 , 0 , 0 , time .UTC ),
2695
+ },
2696
+ },
2697
+ }
2698
+ originalTaint := UnreachableTaintTemplate
2699
+ nodeController , _ := newNodeLifecycleControllerFromClient (
2700
+ nil ,
2701
+ fakeNodeHandler ,
2702
+ evictionTimeout ,
2703
+ testRateLimiterQPS ,
2704
+ testRateLimiterQPS ,
2705
+ testLargeClusterThreshold ,
2706
+ testUnhealthyThreshold ,
2707
+ testNodeMonitorGracePeriod ,
2708
+ testNodeStartupGracePeriod ,
2709
+ testNodeMonitorPeriod ,
2710
+ true )
2711
+ nodeController .now = func () metav1.Time { return fakeNow }
2712
+ nodeController .recorder = testutil .NewFakeRecorder ()
2713
+ if err := nodeController .syncNodeStore (fakeNodeHandler ); err != nil {
2714
+ t .Errorf ("unexpected error: %v" , err )
2715
+ }
2716
+ if err := nodeController .monitorNodeHealth (); err != nil {
2717
+ t .Errorf ("unexpected error: %v" , err )
2718
+ }
2719
+ nodeController .doNoExecuteTaintingPass ()
2720
+ node0 , err := fakeNodeHandler .Get ("node0" , metav1.GetOptions {})
2721
+ if err != nil {
2722
+ t .Errorf ("Can't get current node0..." )
2723
+ return
2724
+ }
2725
+ if ! taintutils .TaintExists (node0 .Spec .Taints , UnreachableTaintTemplate ) {
2726
+ t .Errorf ("Can't find taint %v in %v" , originalTaint , node0 .Spec .Taints )
2727
+ }
2728
+ node2 , err := fakeNodeHandler .Get ("node2" , metav1.GetOptions {})
2729
+ if err != nil {
2730
+ t .Errorf ("Can't get current node2..." )
2731
+ return
2732
+ }
2733
+ if ! taintutils .TaintExists (node2 .Spec .Taints , NotReadyTaintTemplate ) {
2734
+ t .Errorf ("Can't find taint %v in %v" , NotReadyTaintTemplate , node2 .Spec .Taints )
2735
+ }
2736
+
2737
+ // Make node3 healthy again.
2738
+ node2 .Status = healthyNodeNewStatus
2739
+ _ , err = fakeNodeHandler .UpdateStatus (node2 )
2740
+ if err != nil {
2741
+ t .Errorf (err .Error ())
2742
+ return
2743
+ }
2744
+ if err := nodeController .syncNodeStore (fakeNodeHandler ); err != nil {
2745
+ t .Errorf ("unexpected error: %v" , err )
2746
+ }
2747
+ if err := nodeController .monitorNodeHealth (); err != nil {
2748
+ t .Errorf ("unexpected error: %v" , err )
2749
+ }
2750
+ nodeController .doNoExecuteTaintingPass ()
2751
+
2752
+ node2 , err = fakeNodeHandler .Get ("node2" , metav1.GetOptions {})
2753
+ if err != nil {
2754
+ t .Errorf ("Can't get current node2..." )
2755
+ return
2756
+ }
2757
+ // We should not see any taint on the node(especially the Not-Ready taint with NoExecute effect).
2758
+ if taintutils .TaintExists (node2 .Spec .Taints , NotReadyTaintTemplate ) || len (node2 .Spec .Taints ) > 0 {
2759
+ t .Errorf ("Found taint %v in %v, which should not be present" , NotReadyTaintTemplate , node2 .Spec .Taints )
2760
+ }
2761
+ }
2762
+
2613
2763
func TestSwapUnreachableNotReadyTaints (t * testing.T ) {
2614
2764
fakeNow := metav1 .Date (2017 , 1 , 1 , 12 , 0 , 0 , 0 , time .UTC )
2615
2765
evictionTimeout := 10 * time .Minute
0 commit comments