sigs.k8s.io/kueue@v0.6.2/pkg/util/priority/priority_test.go (about)

     1  /*
     2  Copyright 2022 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 priority
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  
    23  	"github.com/google/go-cmp/cmp"
    24  	schedulingv1 "k8s.io/api/scheduling/v1"
    25  	apierrors "k8s.io/apimachinery/pkg/api/errors"
    26  	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    27  	"k8s.io/apimachinery/pkg/runtime"
    28  	"sigs.k8s.io/controller-runtime/pkg/client/fake"
    29  
    30  	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
    31  	"sigs.k8s.io/kueue/pkg/constants"
    32  	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
    33  )
    34  
    35  func TestPriority(t *testing.T) {
    36  	tests := map[string]struct {
    37  		workload *kueue.Workload
    38  		want     int32
    39  	}{
    40  		"priority is specified": {
    41  			workload: utiltesting.MakeWorkload("name", "ns").Priority(100).Obj(),
    42  			want:     100,
    43  		},
    44  		"priority is empty": {
    45  			workload: &kueue.Workload{
    46  				Spec: kueue.WorkloadSpec{},
    47  			},
    48  			want: constants.DefaultPriority,
    49  		},
    50  	}
    51  
    52  	for desc, tt := range tests {
    53  		t.Run(desc, func(t *testing.T) {
    54  			got := Priority(tt.workload)
    55  			if got != tt.want {
    56  				t.Errorf("Priority does not match: got: %d, expected: %d", got, tt.want)
    57  			}
    58  		})
    59  	}
    60  }
    61  
    62  func TestGetPriorityFromPriorityClass(t *testing.T) {
    63  	scheme := runtime.NewScheme()
    64  	if err := schedulingv1.AddToScheme(scheme); err != nil {
    65  		t.Fatalf("Failed adding scheduling scheme: %v", err)
    66  	}
    67  
    68  	tests := map[string]struct {
    69  		priorityClassList       *schedulingv1.PriorityClassList
    70  		priorityClassName       string
    71  		wantPriorityClassName   string
    72  		wantPriorityClassSource string
    73  		wantPriorityClassValue  int32
    74  		wantErr                 error
    75  	}{
    76  		"priorityClass is specified and it exists": {
    77  			priorityClassList: &schedulingv1.PriorityClassList{
    78  				Items: []schedulingv1.PriorityClass{
    79  					{
    80  						ObjectMeta: v1.ObjectMeta{Name: "test"},
    81  						Value:      50,
    82  					},
    83  				},
    84  			},
    85  			priorityClassName:       "test",
    86  			wantPriorityClassSource: constants.PodPriorityClassSource,
    87  			wantPriorityClassName:   "test",
    88  			wantPriorityClassValue:  50,
    89  		},
    90  		"priorityClass is specified and it does not exist": {
    91  			priorityClassList: &schedulingv1.PriorityClassList{
    92  				Items: []schedulingv1.PriorityClass{},
    93  			},
    94  			priorityClassName: "test",
    95  			wantErr:           apierrors.NewNotFound(schedulingv1.Resource("priorityclasses"), "test"),
    96  		},
    97  		"priorityClass is unspecified and one global default exists": {
    98  			priorityClassList: &schedulingv1.PriorityClassList{
    99  				Items: []schedulingv1.PriorityClass{
   100  					{
   101  						ObjectMeta:    v1.ObjectMeta{Name: "globalDefault"},
   102  						GlobalDefault: true,
   103  						Value:         40,
   104  					},
   105  				},
   106  			},
   107  			wantPriorityClassName:   "globalDefault",
   108  			wantPriorityClassSource: constants.PodPriorityClassSource,
   109  			wantPriorityClassValue:  40,
   110  		},
   111  		"priorityClass is unspecified and multiple global defaults exist": {
   112  			priorityClassList: &schedulingv1.PriorityClassList{
   113  				Items: []schedulingv1.PriorityClass{
   114  					{
   115  						ObjectMeta:    v1.ObjectMeta{Name: "globalDefault1"},
   116  						GlobalDefault: true,
   117  						Value:         90,
   118  					},
   119  					{
   120  						ObjectMeta:    v1.ObjectMeta{Name: "globalDefault2"},
   121  						GlobalDefault: true,
   122  						Value:         20,
   123  					},
   124  					{
   125  						ObjectMeta:    v1.ObjectMeta{Name: "globalDefault3"},
   126  						GlobalDefault: true,
   127  						Value:         50,
   128  					},
   129  				},
   130  			},
   131  			wantPriorityClassName:   "globalDefault2",
   132  			wantPriorityClassSource: constants.PodPriorityClassSource,
   133  			wantPriorityClassValue:  20,
   134  		},
   135  	}
   136  
   137  	for desc, tt := range tests {
   138  		tt := tt
   139  		t.Run(desc, func(t *testing.T) {
   140  			t.Parallel()
   141  
   142  			builder := fake.NewClientBuilder().WithScheme(scheme).WithLists(tt.priorityClassList)
   143  			client := builder.Build()
   144  
   145  			name, source, value, err := GetPriorityFromPriorityClass(context.Background(), client, tt.priorityClassName)
   146  			if diff := cmp.Diff(tt.wantErr, err); diff != "" {
   147  				t.Errorf("unexpected error (-want,+got):\n%s", diff)
   148  			}
   149  
   150  			if name != tt.wantPriorityClassName {
   151  				t.Errorf("unexpected name: got: %s, expected: %s", name, tt.wantPriorityClassName)
   152  			}
   153  
   154  			if source != tt.wantPriorityClassSource {
   155  				t.Errorf("unexpected source: got: %s, expected: %s", source, tt.wantPriorityClassSource)
   156  			}
   157  
   158  			if value != tt.wantPriorityClassValue {
   159  				t.Errorf("unexpected value: got: %d, expected: %d", value, tt.wantPriorityClassValue)
   160  			}
   161  		})
   162  	}
   163  }
   164  
   165  func TestGetPriorityFromWorkloadPriorityClass(t *testing.T) {
   166  	scheme := runtime.NewScheme()
   167  	if err := kueue.AddToScheme(scheme); err != nil {
   168  		t.Fatalf("Failed adding kueue scheme: %v", err)
   169  	}
   170  
   171  	tests := map[string]struct {
   172  		workloadPriorityClassList       *kueue.WorkloadPriorityClassList
   173  		workloadPriorityClassName       string
   174  		wantWorkloadPriorityClassName   string
   175  		wantWorkloadPriorityClassSource string
   176  		wantWorkloadPriorityClassValue  int32
   177  		wantErr                         error
   178  	}{
   179  		"workloadPriorityClass is specified and it exists": {
   180  			workloadPriorityClassList: &kueue.WorkloadPriorityClassList{
   181  				Items: []kueue.WorkloadPriorityClass{
   182  					{
   183  						ObjectMeta: v1.ObjectMeta{Name: "test"},
   184  						Value:      50,
   185  					},
   186  				},
   187  			},
   188  			workloadPriorityClassName:       "test",
   189  			wantWorkloadPriorityClassSource: constants.WorkloadPriorityClassSource,
   190  			wantWorkloadPriorityClassName:   "test",
   191  			wantWorkloadPriorityClassValue:  50,
   192  		},
   193  		"workloadPriorityClass is specified and it does not exist": {
   194  			workloadPriorityClassList: &kueue.WorkloadPriorityClassList{
   195  				Items: []kueue.WorkloadPriorityClass{},
   196  			},
   197  			workloadPriorityClassName: "test",
   198  			wantErr:                   apierrors.NewNotFound(kueue.Resource("workloadpriorityclasses"), "test"),
   199  		},
   200  	}
   201  
   202  	for desc, tt := range tests {
   203  		tt := tt
   204  		t.Run(desc, func(t *testing.T) {
   205  			t.Parallel()
   206  
   207  			builder := fake.NewClientBuilder().WithScheme(scheme).WithLists(tt.workloadPriorityClassList)
   208  			client := builder.Build()
   209  
   210  			name, source, value, err := GetPriorityFromWorkloadPriorityClass(context.Background(), client, tt.workloadPriorityClassName)
   211  			if diff := cmp.Diff(tt.wantErr, err); diff != "" {
   212  				t.Errorf("unexpected error (-want,+got):\n%s", diff)
   213  			}
   214  
   215  			if name != tt.wantWorkloadPriorityClassName {
   216  				t.Errorf("unexpected name: got: %s, expected: %s", name, tt.wantWorkloadPriorityClassName)
   217  			}
   218  
   219  			if source != tt.wantWorkloadPriorityClassSource {
   220  				t.Errorf("unexpected source: got: %s, expected: %s", source, tt.wantWorkloadPriorityClassSource)
   221  			}
   222  
   223  			if value != tt.wantWorkloadPriorityClassValue {
   224  				t.Errorf("unexpected value: got: %d, expected: %d", value, tt.wantWorkloadPriorityClassValue)
   225  			}
   226  		})
   227  	}
   228  }