volcano.sh/volcano@v1.9.0/pkg/webhooks/admission/pods/mutate/mutate_pod_test.go (about) 1 /* 2 Copyright 2021 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 mutate 18 19 import ( 20 "encoding/json" 21 "reflect" 22 "testing" 23 24 v1 "k8s.io/api/core/v1" 25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 27 webconfig "volcano.sh/volcano/pkg/webhooks/config" 28 ) 29 30 func TestMutatePods(t *testing.T) { 31 affinityJSONStr := `{"nodeAffinity":{"requiredDuringSchedulingIgnoredDuringExecution":{"nodeSelectorTerms":[{"matchExpressions":[{"key":"kubernetes.io/os","operator":"In","values":["linux"]}]}]}}}` 32 var affinity v1.Affinity 33 json.Unmarshal([]byte(affinityJSONStr), &affinity) 34 35 admissionConfigData := &webconfig.AdmissionConfiguration{ 36 ResGroupsConfig: []webconfig.ResGroupConfig{ 37 { 38 ResourceGroup: "management", 39 Object: webconfig.Object{ 40 Key: "namespace", 41 Value: []string{ 42 "mng-ns-1", 43 "mng-ns-2", 44 }, 45 }, 46 SchedulerName: "default-scheduler", 47 Tolerations: []v1.Toleration{ 48 { 49 Key: "mng-taint-1", 50 Operator: v1.TolerationOpExists, 51 Effect: v1.TaintEffectNoSchedule, 52 }, 53 }, 54 Affinity: affinityJSONStr, 55 Labels: map[string]string{ 56 "volcano.sh/nodetype": "management", 57 }, 58 }, 59 { 60 ResourceGroup: "cpu", 61 Object: webconfig.Object{ 62 Key: "annotation", 63 Value: []string{ 64 "volcano.sh/resource-group: cpu", 65 }, 66 }, 67 SchedulerName: "volcano", 68 Labels: map[string]string{ 69 "volcano.sh/nodetype": "cpu", 70 }, 71 }, 72 { 73 ResourceGroup: "gpu", 74 SchedulerName: "volcano", 75 Labels: map[string]string{ 76 "volcano.sh/nodetype": "gpu", 77 }, 78 }, 79 }, 80 } 81 82 config.ConfigData = admissionConfigData 83 84 testCases := []struct { 85 Name string 86 Pod *v1.Pod 87 expect []patchOperation 88 }{ 89 { 90 Name: "test-1", 91 Pod: &v1.Pod{ 92 TypeMeta: metav1.TypeMeta{ 93 APIVersion: "v1", 94 Kind: "Pod", 95 }, 96 ObjectMeta: metav1.ObjectMeta{ 97 Namespace: "mng-ns-1", 98 Name: "mng-pod", 99 }, 100 Spec: v1.PodSpec{ 101 SchedulerName: "default-scheduler", 102 }, 103 }, 104 expect: []patchOperation{ 105 { 106 Op: "add", 107 Path: "/spec/nodeSelector", 108 Value: map[string]string{ 109 "volcano.sh/nodetype": "management", 110 }, 111 }, 112 { 113 Op: "add", 114 Path: "/spec/affinity", 115 Value: affinity, 116 }, 117 { 118 Op: "add", 119 Path: "/spec/tolerations", 120 Value: []v1.Toleration{ 121 { 122 Key: "mng-taint-1", 123 Operator: v1.TolerationOpExists, 124 Effect: v1.TaintEffectNoSchedule, 125 }, 126 }, 127 }, 128 { 129 Op: "add", 130 Path: "/spec/schedulerName", 131 Value: "default-scheduler", 132 }, 133 }, 134 }, 135 { 136 Name: "test-2", 137 Pod: &v1.Pod{ 138 TypeMeta: metav1.TypeMeta{ 139 APIVersion: "v1", 140 Kind: "Pod", 141 }, 142 ObjectMeta: metav1.ObjectMeta{ 143 Name: "cpu-pod", 144 Annotations: map[string]string{ 145 "volcano.sh/resource-group": "cpu", 146 }, 147 }, 148 }, 149 expect: []patchOperation{ 150 { 151 Op: "add", 152 Path: "/spec/nodeSelector", 153 Value: map[string]string{ 154 "volcano.sh/nodetype": "cpu", 155 }, 156 }, 157 { 158 Op: "add", 159 Path: "/spec/schedulerName", 160 Value: "volcano", 161 }, 162 }, 163 }, 164 { 165 Name: "test-3", 166 Pod: &v1.Pod{ 167 TypeMeta: metav1.TypeMeta{ 168 APIVersion: "v1", 169 Kind: "Pod", 170 }, 171 ObjectMeta: metav1.ObjectMeta{ 172 Name: "gpu-pod", 173 Annotations: map[string]string{ 174 "volcano.sh/resource-group": "gpu", 175 }, 176 }, 177 }, 178 expect: []patchOperation{ 179 { 180 Op: "add", 181 Path: "/spec/nodeSelector", 182 Value: map[string]string{ 183 "volcano.sh/nodetype": "gpu", 184 }, 185 }, 186 { 187 Op: "add", 188 Path: "/spec/schedulerName", 189 Value: "volcano", 190 }, 191 }, 192 }, 193 { 194 Name: "test-4", 195 Pod: &v1.Pod{ 196 TypeMeta: metav1.TypeMeta{ 197 APIVersion: "v1", 198 Kind: "Pod", 199 }, 200 ObjectMeta: metav1.ObjectMeta{ 201 Name: "normal-pod", 202 }, 203 }, 204 expect: nil, 205 }, 206 } 207 208 for _, testCase := range testCases { 209 t.Run(testCase.Name, func(t *testing.T) { 210 patchBytes, _ := createPatch(testCase.Pod) 211 expectBytes, _ := json.Marshal(testCase.expect) 212 if !reflect.DeepEqual(patchBytes, expectBytes) { 213 t.Errorf("Test case '%s' failed, expect: %v, got: %v", testCase.Name, 214 expectBytes, patchBytes) 215 } 216 }) 217 } 218 }