volcano.sh/volcano@v1.9.0/pkg/scheduler/plugins/cdp/cdp_test.go (about) 1 /* 2 Copyright 2022 The Volcano 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 cdp 18 19 import ( 20 "reflect" 21 "testing" 22 "time" 23 24 v1 "k8s.io/api/core/v1" 25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 27 "volcano.sh/apis/pkg/apis/scheduling/v1beta1" 28 "volcano.sh/volcano/pkg/scheduler/api" 29 "volcano.sh/volcano/pkg/scheduler/cache" 30 "volcano.sh/volcano/pkg/scheduler/conf" 31 "volcano.sh/volcano/pkg/scheduler/framework" 32 ) 33 34 func makePod(labels map[string]string, annotations map[string]string, podScheduledTime time.Time) *v1.Pod { 35 annotations[v1beta1.KubeGroupNameAnnotationKey] = "test-group" 36 phase := v1.PodPending 37 conditions := []v1.PodCondition{} 38 if !podScheduledTime.IsZero() { 39 phase = v1.PodRunning 40 conditions = append(conditions, v1.PodCondition{ 41 Type: v1.PodScheduled, 42 LastTransitionTime: metav1.NewTime(podScheduledTime), 43 Status: v1.ConditionTrue, 44 }) 45 } 46 return &v1.Pod{ 47 ObjectMeta: metav1.ObjectMeta{ 48 Name: "test-pod", 49 Namespace: "default", 50 Labels: labels, 51 Annotations: annotations, 52 }, 53 Status: v1.PodStatus{ 54 Phase: phase, 55 Conditions: conditions, 56 }, 57 Spec: v1.PodSpec{ 58 Containers: []v1.Container{ 59 {}, 60 }, 61 }, 62 } 63 64 } 65 66 func Test_CooldownTimePlugin_podPreemptStableTime(t *testing.T) { 67 type args struct { 68 pod *v1.Pod 69 } 70 plugin := &CooldownProtectionPlugin{} 71 tests := []struct { 72 name string 73 sp *CooldownProtectionPlugin 74 args args 75 wantEnabled bool 76 wantValue time.Duration 77 }{ 78 { 79 name: "normal", 80 sp: plugin, 81 args: args{ 82 pod: makePod(map[string]string{}, 83 map[string]string{v1beta1.CooldownTime: "600s"}, 84 time.Now().Add(time.Second*-100)), 85 }, 86 wantEnabled: true, 87 wantValue: time.Second * 600, 88 }, 89 { 90 name: "not-enabled", 91 sp: plugin, 92 args: args{ 93 pod: makePod(map[string]string{}, 94 map[string]string{v1beta1.CooldownTime: "600abcde"}, 95 time.Now().Add(time.Second*-100)), 96 }, 97 wantEnabled: false, 98 wantValue: 0, 99 }, 100 } 101 for _, tt := range tests { 102 t.Run(tt.name, func(t *testing.T) { 103 sp := &CooldownProtectionPlugin{} 104 gotValue, gotEnabled := sp.podCooldownTime(tt.args.pod) 105 if gotEnabled != tt.wantEnabled { 106 t.Errorf("CooldownTimePlugin.podPreemptStableTime() gotEnabled = %v, want %v", gotEnabled, tt.wantEnabled) 107 } 108 if gotValue != tt.wantValue { 109 t.Errorf("CooldownTimePlugin.podPreemptStableTime() gotValue = %v, want %v", gotValue, tt.wantValue) 110 } 111 }) 112 } 113 } 114 115 func TestPreemptableFn(t *testing.T) { 116 plugin := &CooldownProtectionPlugin{} 117 enabledPreemptable := true 118 pluginOption := conf.PluginOption{ 119 Name: PluginName, 120 EnabledPreemptable: &enabledPreemptable, 121 } 122 schedulerCache := &cache.SchedulerCache{} 123 ssn := framework.OpenSession(schedulerCache, []conf.Tier{ 124 { 125 Plugins: []conf.PluginOption{pluginOption}, 126 }, 127 }, 128 []conf.Configuration{ 129 { 130 Name: "preempt", 131 }, 132 }, 133 ) 134 135 plugin.OnSessionOpen(ssn) // register preempt fn 136 137 // prepare preemptor and preemptees 138 // task1: should be filtered 139 task1 := api.NewTaskInfo( 140 makePod(map[string]string{v1beta1.PodPreemptable: "true"}, 141 map[string]string{v1beta1.CooldownTime: "600s"}, 142 time.Now().Add(time.Second*-100)), 143 ) 144 // task2: invalid label, not enabled 145 task2 := api.NewTaskInfo( 146 makePod(map[string]string{v1beta1.PodPreemptable: "true"}, 147 map[string]string{v1beta1.CooldownTime: "600abcde"}, 148 time.Now().Add(time.Second*-100)), 149 ) 150 // task3: after stable time, can be preempted 151 task3 := api.NewTaskInfo( 152 makePod(map[string]string{v1beta1.PodPreemptable: "true"}, 153 map[string]string{v1beta1.CooldownTime: "600s"}, 154 time.Now().Add(time.Second*-800)), 155 ) 156 preemptees := []*api.TaskInfo{task1, task2, task3} 157 victims := ssn.Preemptable(&api.TaskInfo{}, preemptees) 158 159 expectVictims := []*api.TaskInfo{task2, task3} 160 if !reflect.DeepEqual(victims, expectVictims) { 161 t.Errorf("stable preempt test not equal! expect victims %v, actual %v", expectVictims, victims) 162 } 163 }