volcano.sh/volcano@v1.9.0/pkg/scheduler/actions/shuffle/shuffle_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 shuffle 18 19 import ( 20 "reflect" 21 "testing" 22 "time" 23 24 "github.com/agiledragon/gomonkey/v2" 25 "github.com/golang/mock/gomock" 26 v1 "k8s.io/api/core/v1" 27 schedulingv1 "k8s.io/api/scheduling/v1" 28 "k8s.io/client-go/tools/record" 29 30 schedulingv1beta1 "volcano.sh/apis/pkg/apis/scheduling/v1beta1" 31 "volcano.sh/volcano/pkg/scheduler/api" 32 "volcano.sh/volcano/pkg/scheduler/cache" 33 "volcano.sh/volcano/pkg/scheduler/conf" 34 "volcano.sh/volcano/pkg/scheduler/framework" 35 mock_framework "volcano.sh/volcano/pkg/scheduler/framework/mock_gen" 36 "volcano.sh/volcano/pkg/scheduler/util" 37 ) 38 39 func TestShuffle(t *testing.T) { 40 var tmp *cache.SchedulerCache 41 patchUpdateQueueStatus := gomonkey.ApplyMethod(reflect.TypeOf(tmp), "UpdateQueueStatus", func(scCache *cache.SchedulerCache, queue *api.QueueInfo) error { 42 return nil 43 }) 44 defer patchUpdateQueueStatus.Reset() 45 46 var highPriority int32 47 var lowPriority int32 48 highPriority = 100 49 lowPriority = 10 50 51 ctl := gomock.NewController(t) 52 fakePlugin := mock_framework.NewMockPlugin(ctl) 53 fakePlugin.EXPECT().Name().AnyTimes().Return("fake") 54 fakePlugin.EXPECT().OnSessionOpen(gomock.Any()).Return() 55 fakePlugin.EXPECT().OnSessionClose(gomock.Any()).Return() 56 fakePluginBuilder := func(arguments framework.Arguments) framework.Plugin { 57 return fakePlugin 58 } 59 framework.RegisterPluginBuilder("fake", fakePluginBuilder) 60 61 tests := []struct { 62 name string 63 podGroups []*schedulingv1beta1.PodGroup 64 pods []*v1.Pod 65 nodes []*v1.Node 66 queues []*schedulingv1beta1.Queue 67 expected int 68 }{ 69 { 70 name: "select pods with low priority and evict them", 71 nodes: []*v1.Node{ 72 util.BuildNode("node1", api.BuildResourceList("4", "8Gi", []api.ScalarResource{{Name: "pods", Value: "10"}}...), make(map[string]string)), 73 util.BuildNode("node2", api.BuildResourceList("4", "8Gi", []api.ScalarResource{{Name: "pods", Value: "10"}}...), make(map[string]string)), 74 }, 75 queues: []*schedulingv1beta1.Queue{ 76 util.BuildQueue("default", 1, nil), 77 }, 78 podGroups: []*schedulingv1beta1.PodGroup{ 79 util.BuildPodGroup("pg1", "test", "default", 0, nil, schedulingv1beta1.PodGroupRunning), 80 util.BuildPodGroup("pg2", "test", "default", 0, nil, schedulingv1beta1.PodGroupRunning), 81 util.BuildPodGroup("pg3", "test", "default", 0, nil, schedulingv1beta1.PodGroupRunning), 82 }, 83 pods: []*v1.Pod{ 84 util.BuildPodWithPriority("test", "pod1-1", "node1", v1.PodRunning, api.BuildResourceList("1", "2G"), "pg1", make(map[string]string), make(map[string]string), &lowPriority), 85 util.BuildPodWithPriority("test", "pod1-2", "node1", v1.PodRunning, api.BuildResourceList("1", "2G"), "pg1", make(map[string]string), make(map[string]string), &highPriority), 86 util.BuildPodWithPriority("test", "pod1-3", "node1", v1.PodRunning, api.BuildResourceList("1", "2G"), "pg1", make(map[string]string), make(map[string]string), &highPriority), 87 util.BuildPodWithPriority("test", "pod2-1", "node1", v1.PodRunning, api.BuildResourceList("1", "2G"), "pg2", make(map[string]string), make(map[string]string), &lowPriority), 88 util.BuildPodWithPriority("test", "pod2-2", "node2", v1.PodRunning, api.BuildResourceList("1", "2G"), "pg2", make(map[string]string), make(map[string]string), &highPriority), 89 util.BuildPodWithPriority("test", "pod3-1", "node2", v1.PodRunning, api.BuildResourceList("1", "2G"), "pg3", make(map[string]string), make(map[string]string), &lowPriority), 90 util.BuildPodWithPriority("test", "pod3-2", "node2", v1.PodRunning, api.BuildResourceList("1", "2G"), "pg3", make(map[string]string), make(map[string]string), &highPriority), 91 }, 92 expected: 3, 93 }, 94 } 95 shuffle := New() 96 97 for i, test := range tests { 98 binder := &util.FakeBinder{ 99 Binds: map[string]string{}, 100 Channel: make(chan string, 1), 101 } 102 evictor := &util.FakeEvictor{ 103 Channel: make(chan string), 104 } 105 schedulerCache := &cache.SchedulerCache{ 106 Nodes: make(map[string]*api.NodeInfo), 107 Jobs: make(map[api.JobID]*api.JobInfo), 108 Queues: make(map[api.QueueID]*api.QueueInfo), 109 Binder: binder, 110 Evictor: evictor, 111 StatusUpdater: &util.FakeStatusUpdater{}, 112 VolumeBinder: &util.FakeVolumeBinder{}, 113 PriorityClasses: make(map[string]*schedulingv1.PriorityClass), 114 115 Recorder: record.NewFakeRecorder(100), 116 } 117 schedulerCache.PriorityClasses["high-priority"] = &schedulingv1.PriorityClass{ 118 Value: highPriority, 119 } 120 schedulerCache.PriorityClasses["low-priority"] = &schedulingv1.PriorityClass{ 121 Value: lowPriority, 122 } 123 124 for _, node := range test.nodes { 125 schedulerCache.AddOrUpdateNode(node) 126 } 127 for _, q := range test.queues { 128 schedulerCache.AddQueueV1beta1(q) 129 } 130 for _, ss := range test.podGroups { 131 schedulerCache.AddPodGroupV1beta1(ss) 132 } 133 for _, pod := range test.pods { 134 schedulerCache.AddPod(pod) 135 } 136 137 trueValue := true 138 ssn := framework.OpenSession(schedulerCache, []conf.Tier{ 139 { 140 Plugins: []conf.PluginOption{ 141 { 142 Name: "fake", 143 EnabledVictim: &trueValue, 144 }, 145 }, 146 }, 147 }, nil) 148 defer framework.CloseSession(ssn) 149 150 fakePluginVictimFns := func() []api.VictimTasksFn { 151 victimTasksFn := func(candidates []*api.TaskInfo) []*api.TaskInfo { 152 evicts := make([]*api.TaskInfo, 0) 153 for _, task := range candidates { 154 if task.Priority == lowPriority { 155 evicts = append(evicts, task) 156 } 157 } 158 return evicts 159 } 160 161 victimTasksFns := make([]api.VictimTasksFn, 0) 162 victimTasksFns = append(victimTasksFns, victimTasksFn) 163 return victimTasksFns 164 } 165 ssn.AddVictimTasksFns("fake", fakePluginVictimFns()) 166 167 shuffle.Execute(ssn) 168 for { 169 select { 170 case <-evictor.Channel: 171 case <-time.After(2 * time.Second): 172 goto LOOP 173 } 174 } 175 176 LOOP: 177 if test.expected != len(evictor.Evicts()) { 178 t.Errorf("case %d (%s): expected: %v, got %v ", i, test.name, test.expected, len(evictor.Evicts())) 179 } 180 } 181 }