volcano.sh/volcano@v1.9.0/pkg/scheduler/actions/reclaim/reclaim_test.go (about)

     1  /*
     2  Copyright 2018 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 reclaim
    18  
    19  import (
    20  	"testing"
    21  
    22  	v1 "k8s.io/api/core/v1"
    23  	schedulingv1 "k8s.io/api/scheduling/v1"
    24  
    25  	schedulingv1beta1 "volcano.sh/apis/pkg/apis/scheduling/v1beta1"
    26  	"volcano.sh/volcano/pkg/scheduler/api"
    27  	"volcano.sh/volcano/pkg/scheduler/conf"
    28  	"volcano.sh/volcano/pkg/scheduler/framework"
    29  	"volcano.sh/volcano/pkg/scheduler/plugins/conformance"
    30  	"volcano.sh/volcano/pkg/scheduler/plugins/gang"
    31  	"volcano.sh/volcano/pkg/scheduler/plugins/priority"
    32  	"volcano.sh/volcano/pkg/scheduler/plugins/proportion"
    33  	"volcano.sh/volcano/pkg/scheduler/uthelper"
    34  	"volcano.sh/volcano/pkg/scheduler/util"
    35  )
    36  
    37  func TestReclaim(t *testing.T) {
    38  	tests := []uthelper.TestCommonStruct{
    39  		{
    40  			Name: "Two Queue with one Queue overusing resource, should reclaim",
    41  			Plugins: map[string]framework.PluginBuilder{
    42  				conformance.PluginName: conformance.New,
    43  				gang.PluginName:        gang.New,
    44  				proportion.PluginName:  proportion.New,
    45  			},
    46  			PodGroups: []*schedulingv1beta1.PodGroup{
    47  				util.BuildPodGroupWithPrio("pg1", "c1", "q1", 0, nil, schedulingv1beta1.PodGroupInqueue, "low-priority"),
    48  				util.BuildPodGroupWithPrio("pg2", "c1", "q2", 0, nil, schedulingv1beta1.PodGroupInqueue, "high-priority"),
    49  			},
    50  			Pods: []*v1.Pod{
    51  				util.BuildPod("c1", "preemptee1", "n1", v1.PodRunning, api.BuildResourceList("1", "1G"), "pg1", map[string]string{schedulingv1beta1.PodPreemptable: "false"}, make(map[string]string)),
    52  				util.BuildPod("c1", "preemptee2", "n1", v1.PodRunning, api.BuildResourceList("1", "1G"), "pg1", map[string]string{schedulingv1beta1.PodPreemptable: "true"}, make(map[string]string)),
    53  				util.BuildPod("c1", "preemptee3", "n1", v1.PodRunning, api.BuildResourceList("1", "1G"), "pg1", map[string]string{schedulingv1beta1.PodPreemptable: "false"}, make(map[string]string)),
    54  				util.BuildPod("c1", "preemptor1", "", v1.PodPending, api.BuildResourceList("1", "1G"), "pg2", make(map[string]string), make(map[string]string)),
    55  			},
    56  			Nodes: []*v1.Node{
    57  				util.BuildNode("n1", api.BuildResourceList("3", "3Gi", []api.ScalarResource{{Name: "pods", Value: "10"}}...), make(map[string]string)),
    58  			},
    59  			Queues: []*schedulingv1beta1.Queue{
    60  				util.BuildQueue("q1", 1, nil),
    61  				util.BuildQueue("q2", 1, nil),
    62  			},
    63  			EvictNum: 1,
    64  			Evicted:  []string{"c1/preemptee2"}, // let pod2 in the middle when sort tasks be preemptable and will not disturb
    65  		},
    66  		{
    67  			Name: "sort reclaimees when reclaiming from overusing queue",
    68  			Plugins: map[string]framework.PluginBuilder{
    69  				conformance.PluginName: conformance.New,
    70  				gang.PluginName:        gang.New,
    71  				priority.PluginName:    priority.New,
    72  				proportion.PluginName:  proportion.New,
    73  			},
    74  			PriClass: []*schedulingv1.PriorityClass{
    75  				util.BuildPriorityClass("low-priority", 100),
    76  				util.BuildPriorityClass("mid-priority", 500),
    77  				util.BuildPriorityClass("high-priority", 1000),
    78  			},
    79  			PodGroups: []*schedulingv1beta1.PodGroup{
    80  				util.BuildPodGroupWithPrio("pg1", "c1", "q1", 0, nil, schedulingv1beta1.PodGroupInqueue, "mid-priority"),
    81  				util.BuildPodGroupWithPrio("pg2", "c1", "q2", 0, nil, schedulingv1beta1.PodGroupInqueue, "low-priority"), // reclaimed first
    82  				util.BuildPodGroupWithPrio("pg3", "c1", "q3", 0, nil, schedulingv1beta1.PodGroupInqueue, "high-priority"),
    83  			},
    84  			Pods: []*v1.Pod{
    85  				util.BuildPod("c1", "preemptee1-1", "n1", v1.PodRunning, api.BuildResourceList("1", "1G"), "pg1", map[string]string{schedulingv1beta1.PodPreemptable: "true"}, make(map[string]string)),
    86  				util.BuildPod("c1", "preemptee1-2", "n1", v1.PodRunning, api.BuildResourceList("1", "1G"), "pg1", map[string]string{schedulingv1beta1.PodPreemptable: "true"}, make(map[string]string)),
    87  				util.BuildPod("c1", "preemptee2-1", "n1", v1.PodRunning, api.BuildResourceList("1", "1G"), "pg2", map[string]string{schedulingv1beta1.PodPreemptable: "true"}, make(map[string]string)),
    88  				util.BuildPod("c1", "preemptee2-2", "n1", v1.PodRunning, api.BuildResourceList("1", "1G"), "pg2", map[string]string{schedulingv1beta1.PodPreemptable: "false"}, make(map[string]string)),
    89  				util.BuildPod("c1", "preemptor1", "", v1.PodPending, api.BuildResourceList("1", "1G"), "pg3", make(map[string]string), make(map[string]string)),
    90  			},
    91  			Nodes: []*v1.Node{
    92  				util.BuildNode("n1", api.BuildResourceList("4", "4Gi", []api.ScalarResource{{Name: "pods", Value: "10"}}...), make(map[string]string)),
    93  			},
    94  			Queues: []*schedulingv1beta1.Queue{
    95  				util.BuildQueue("q1", 1, nil),
    96  				util.BuildQueue("q2", 1, nil),
    97  				util.BuildQueue("q3", 1, nil),
    98  			},
    99  			EvictNum: 1,
   100  			Evicted:  []string{"c1/preemptee2-1"}, // low priority job's preemptable pod is evicted
   101  		},
   102  	}
   103  
   104  	reclaim := New()
   105  	trueValue := true
   106  	tiers := []conf.Tier{
   107  		{
   108  			Plugins: []conf.PluginOption{
   109  				{
   110  					Name:               "conformance",
   111  					EnabledReclaimable: &trueValue,
   112  				},
   113  				{
   114  					Name:               "gang",
   115  					EnabledReclaimable: &trueValue,
   116  				},
   117  				{ // proportion plugin will cause deserved resource large than preemptable pods's usage, and return less victims
   118  					Name:               "proportion",
   119  					EnabledReclaimable: &trueValue,
   120  				},
   121  				{
   122  					Name:             priority.PluginName,
   123  					EnabledJobOrder:  &trueValue,
   124  					EnabledTaskOrder: &trueValue,
   125  				},
   126  			},
   127  		},
   128  	}
   129  	for i, test := range tests {
   130  		t.Run(test.Name, func(t *testing.T) {
   131  			test.RegistSession(tiers, nil)
   132  			defer test.Close()
   133  			test.Run([]framework.Action{reclaim})
   134  			if err := test.CheckAll(i); err != nil {
   135  				t.Fatal(err)
   136  			}
   137  		})
   138  	}
   139  }