sigs.k8s.io/kueue@v0.6.2/pkg/webhooks/resourceflavor_webhook_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 webhooks 18 19 import ( 20 "testing" 21 22 "github.com/google/go-cmp/cmp" 23 "github.com/google/go-cmp/cmp/cmpopts" 24 corev1 "k8s.io/api/core/v1" 25 "k8s.io/apimachinery/pkg/util/validation/field" 26 27 kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1" 28 utiltesting "sigs.k8s.io/kueue/pkg/util/testing" 29 ) 30 31 func TestValidateResourceFlavor(t *testing.T) { 32 testcases := []struct { 33 name string 34 rf *kueue.ResourceFlavor 35 labels map[string]string 36 wantErr field.ErrorList 37 }{ 38 { 39 name: "empty", 40 rf: utiltesting.MakeResourceFlavor("resource-flavor").Obj(), 41 }, 42 { 43 name: "valid", 44 rf: utiltesting.MakeResourceFlavor("resource-flavor"). 45 Label("foo", "bar"). 46 Taint(corev1.Taint{ 47 Key: "spot", 48 Value: "true", 49 Effect: corev1.TaintEffectNoSchedule, 50 }).Obj(), 51 }, 52 { 53 // Taint validation is not exhaustively tested, because the code was copied from upstream k8s. 54 name: "invalid taint", 55 rf: utiltesting.MakeResourceFlavor("resource-flavor").Taint(corev1.Taint{ 56 Key: "skdajf", 57 }).Obj(), 58 wantErr: field.ErrorList{ 59 field.Required(field.NewPath("spec", "nodeTaints").Index(0).Child("effect"), ""), 60 }, 61 }, 62 { 63 name: "invalid label name", 64 rf: utiltesting.MakeResourceFlavor("resource-flavor").Label("@abc", "foo").Obj(), 65 wantErr: field.ErrorList{ 66 field.Invalid(field.NewPath("spec", "nodeLabels"), "@abc", ""), 67 }, 68 }, 69 { 70 name: "invalid label value", 71 rf: utiltesting.MakeResourceFlavor("resource-flavor").Label("foo", "@abc").Obj(), 72 wantErr: field.ErrorList{ 73 field.Invalid(field.NewPath("spec", "nodeLabels"), "@abc", ""), 74 }, 75 }, 76 { 77 name: "bad tolerations", 78 rf: utiltesting.MakeResourceFlavor("resource-flavor"). 79 Toleration(corev1.Toleration{ 80 Key: "@abc", 81 Operator: corev1.TolerationOpEqual, 82 Value: "v", 83 Effect: corev1.TaintEffectNoSchedule, 84 }). 85 Toleration(corev1.Toleration{ 86 Key: "abc", 87 Operator: corev1.TolerationOpExists, 88 Value: "v", 89 Effect: corev1.TaintEffectNoSchedule, 90 }). 91 Toleration(corev1.Toleration{ 92 Key: "abc", 93 Operator: corev1.TolerationOpEqual, 94 Value: "v", 95 Effect: corev1.TaintEffect("not-valid"), 96 }). 97 Toleration(corev1.Toleration{ 98 Key: "abc", 99 Operator: corev1.TolerationOpEqual, 100 Value: "v", 101 Effect: corev1.TaintEffectNoSchedule, 102 }). 103 Obj(), 104 wantErr: field.ErrorList{ 105 field.Invalid(field.NewPath("spec", "tolerations").Index(0).Child("key"), "@abc", ""), 106 field.Invalid(field.NewPath("spec", "tolerations").Index(1).Child("operator"), corev1.Toleration{ 107 Key: "abc", 108 Operator: corev1.TolerationOpExists, 109 Value: "v", 110 Effect: corev1.TaintEffectNoSchedule, 111 }, ""), 112 field.NotSupported(field.NewPath("spec", "tolerations").Index(2).Child("effect"), corev1.TaintEffect("not-valid"), []corev1.TaintEffect{}), 113 }, 114 }, 115 } 116 117 for _, tc := range testcases { 118 t.Run(tc.name, func(t *testing.T) { 119 gotErr := ValidateResourceFlavor(tc.rf) 120 if diff := cmp.Diff(tc.wantErr, gotErr, cmpopts.IgnoreFields(field.Error{}, "Detail")); diff != "" { 121 t.Errorf("validateResourceFlavorLabels() mismatch (-want +got):\n%s", diff) 122 } 123 }) 124 } 125 }