k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/plugin/pkg/admission/nodetaint/admission_test.go (about) 1 /* 2 Copyright 2019 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 nodetaint 18 19 import ( 20 "context" 21 "reflect" 22 23 "testing" 24 25 v1 "k8s.io/api/core/v1" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 "k8s.io/apimachinery/pkg/runtime" 28 "k8s.io/apiserver/pkg/admission" 29 "k8s.io/apiserver/pkg/authentication/user" 30 api "k8s.io/kubernetes/pkg/apis/core" 31 ) 32 33 func Test_nodeTaints(t *testing.T) { 34 var ( 35 mynode = &user.DefaultInfo{Name: "system:node:mynode", Groups: []string{"system:nodes"}} 36 resource = api.Resource("nodes").WithVersion("v1") 37 notReadyTaint = api.Taint{Key: v1.TaintNodeNotReady, Effect: api.TaintEffectNoSchedule} 38 notReadyCondition = api.NodeCondition{Type: api.NodeReady, Status: api.ConditionFalse} 39 myNodeObjMeta = metav1.ObjectMeta{Name: "mynode"} 40 myNodeObj = api.Node{ObjectMeta: myNodeObjMeta} 41 myTaintedNodeObj = api.Node{ObjectMeta: myNodeObjMeta, 42 Spec: api.NodeSpec{Taints: []api.Taint{notReadyTaint}}} 43 myUnreadyNodeObj = api.Node{ObjectMeta: myNodeObjMeta, 44 Status: api.NodeStatus{Conditions: []api.NodeCondition{notReadyCondition}}} 45 nodeKind = api.Kind("Node").WithVersion("v1") 46 ) 47 tests := []struct { 48 name string 49 node api.Node 50 oldNode api.Node 51 operation admission.Operation 52 options runtime.Object 53 expectedTaints []api.Taint 54 }{ 55 { 56 name: "notReady taint is added on creation", 57 node: myNodeObj, 58 operation: admission.Create, 59 options: &metav1.CreateOptions{}, 60 expectedTaints: []api.Taint{notReadyTaint}, 61 }, 62 { 63 name: "already tainted node is not tainted again", 64 node: myTaintedNodeObj, 65 operation: admission.Create, 66 options: &metav1.CreateOptions{}, 67 expectedTaints: []api.Taint{notReadyTaint}, 68 }, 69 { 70 name: "NotReady taint is added to an unready node as well", 71 node: myUnreadyNodeObj, 72 operation: admission.Create, 73 options: &metav1.CreateOptions{}, 74 expectedTaints: []api.Taint{notReadyTaint}, 75 }, 76 } 77 for _, tt := range tests { 78 t.Run(tt.name, func(t *testing.T) { 79 attributes := admission.NewAttributesRecord(&tt.node, &tt.oldNode, nodeKind, myNodeObj.Namespace, myNodeObj.Name, resource, "", tt.operation, tt.options, false, mynode) 80 c := NewPlugin() 81 err := c.Admit(context.TODO(), attributes, nil) 82 if err != nil { 83 t.Errorf("nodePlugin.Admit() error = %v", err) 84 } 85 node, _ := attributes.GetObject().(*api.Node) 86 if !reflect.DeepEqual(node.Spec.Taints, tt.expectedTaints) { 87 t.Errorf("Unexpected Node taints. Got %v\nExpected: %v", node.Spec.Taints, tt.expectedTaints) 88 } 89 }) 90 } 91 }