k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/test/integration/scheduler/eventhandler/eventhandler_test.go (about) 1 /* 2 Copyright 2023 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 eventhandler 18 19 import ( 20 "context" 21 "testing" 22 23 v1 "k8s.io/api/core/v1" 24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 "k8s.io/apimachinery/pkg/runtime" 26 "k8s.io/component-helpers/scheduling/corev1" 27 configv1 "k8s.io/kube-scheduler/config/v1" 28 "k8s.io/kubernetes/pkg/scheduler" 29 configtesting "k8s.io/kubernetes/pkg/scheduler/apis/config/testing" 30 "k8s.io/kubernetes/pkg/scheduler/framework" 31 frameworkruntime "k8s.io/kubernetes/pkg/scheduler/framework/runtime" 32 st "k8s.io/kubernetes/pkg/scheduler/testing" 33 schedulerutils "k8s.io/kubernetes/test/integration/scheduler" 34 testutils "k8s.io/kubernetes/test/integration/util" 35 "k8s.io/utils/ptr" 36 ) 37 38 var _ framework.FilterPlugin = &fooPlugin{} 39 40 type fooPlugin struct { 41 } 42 43 func (pl *fooPlugin) Name() string { 44 return "foo" 45 } 46 47 func (pl *fooPlugin) Filter(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status { 48 taints := nodeInfo.Node().Spec.Taints 49 if len(taints) == 0 { 50 return nil 51 } 52 53 if corev1.TolerationsTolerateTaint(pod.Spec.Tolerations, &nodeInfo.Node().Spec.Taints[0]) { 54 return nil 55 } 56 return framework.NewStatus(framework.Unschedulable) 57 } 58 59 func (pl *fooPlugin) EventsToRegister() []framework.ClusterEventWithHint { 60 return []framework.ClusterEventWithHint{ 61 {Event: framework.ClusterEvent{Resource: framework.Node, ActionType: framework.UpdateNodeTaint}}, 62 } 63 } 64 65 // newPlugin returns a plugin factory with specified Plugin. 66 func newPlugin(plugin framework.Plugin) frameworkruntime.PluginFactory { 67 return func(_ context.Context, _ runtime.Object, fh framework.Handle) (framework.Plugin, error) { 68 return plugin, nil 69 } 70 } 71 72 func TestUpdateNodeEvent(t *testing.T) { 73 testContext := testutils.InitTestAPIServer(t, "test-event", nil) 74 75 taints := []v1.Taint{{Key: v1.TaintNodeUnschedulable, Value: "", Effect: v1.TaintEffectNoSchedule}} 76 nodeWrapper := st.MakeNode().Name("node-0").Label("kubernetes.io/hostname", "node-0").Taints(taints).Obj() 77 podWrapper := testutils.InitPausePod(&testutils.PausePodConfig{Name: "test-pod", Namespace: testContext.NS.Name}) 78 fooPlugin := &fooPlugin{} 79 80 registry := frameworkruntime.Registry{ 81 fooPlugin.Name(): newPlugin(fooPlugin), 82 } 83 84 // Setup plugins for testing. 85 cfg := configtesting.V1ToInternalWithDefaults(t, configv1.KubeSchedulerConfiguration{ 86 Profiles: []configv1.KubeSchedulerProfile{{ 87 SchedulerName: ptr.To[string](v1.DefaultSchedulerName), 88 Plugins: &configv1.Plugins{ 89 Filter: configv1.PluginSet{ 90 Enabled: []configv1.Plugin{ 91 {Name: fooPlugin.Name()}, 92 }, 93 Disabled: []configv1.Plugin{ 94 {Name: "*"}, 95 }, 96 }, 97 }, 98 }}, 99 }) 100 101 testCtx, teardown := schedulerutils.InitTestSchedulerForFrameworkTest(t, testContext, 0, 102 scheduler.WithProfiles(cfg.Profiles...), 103 scheduler.WithFrameworkOutOfTreeRegistry(registry), 104 ) 105 defer teardown() 106 107 node, err := testutils.CreateNode(testCtx.ClientSet, nodeWrapper) 108 if err != nil { 109 t.Fatalf("Creating node error: %v", err) 110 } 111 112 pod, err := testutils.CreatePausePod(testCtx.ClientSet, podWrapper) 113 if err != nil { 114 t.Fatalf("Creating pod error: %v", err) 115 } 116 117 if err := testutils.WaitForPodUnschedulable(testCtx.ClientSet, pod); err != nil { 118 t.Fatalf("Pod %v got scheduled: %v", pod.Name, err) 119 } 120 node, err = testCtx.ClientSet.CoreV1().Nodes().Get(testCtx.Ctx, node.Name, metav1.GetOptions{}) 121 if err != nil { 122 t.Fatalf("Error while getting a node: %v", err) 123 } 124 125 // Update node label and node taints 126 node.Labels["foo"] = "bar" 127 node.Spec.Taints = nil 128 129 _, err = testCtx.ClientSet.CoreV1().Nodes().Update(testCtx.Ctx, node, metav1.UpdateOptions{}) 130 if err != nil { 131 t.Fatalf("Error updating the node: %v", err) 132 } 133 134 if err := testutils.WaitForPodToSchedule(testCtx.ClientSet, pod); err != nil { 135 t.Errorf("Pod %v was not scheduled: %v", pod.Name, err) 136 } 137 }