github.com/kubewharf/katalyst-core@v0.5.3/pkg/agent/qrm-plugins/cpu/util/util_test.go (about) 1 /* 2 Copyright 2022 The Katalyst 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 util 18 19 import ( 20 "reflect" 21 "testing" 22 23 "github.com/stretchr/testify/assert" 24 v1 "k8s.io/api/core/v1" 25 pluginapi "k8s.io/kubelet/pkg/apis/resourceplugin/v1alpha1" 26 27 "github.com/kubewharf/katalyst-api/pkg/consts" 28 "github.com/kubewharf/katalyst-core/pkg/agent/qrm-plugins/cpu/dynamicpolicy/state" 29 "github.com/kubewharf/katalyst-core/pkg/agent/qrm-plugins/util" 30 "github.com/kubewharf/katalyst-core/pkg/config" 31 "github.com/kubewharf/katalyst-core/pkg/config/agent" 32 "github.com/kubewharf/katalyst-core/pkg/config/agent/qrm" 33 "github.com/kubewharf/katalyst-core/pkg/metaserver" 34 "github.com/kubewharf/katalyst-core/pkg/util/machine" 35 ) 36 37 func TestGetCoresReservedForSystem(t *testing.T) { 38 t.Parallel() 39 40 topology, err := machine.GenerateDummyCPUTopology(16, 2, 4) 41 assert.Nil(t, err) 42 machineInfo := &machine.KatalystMachineInfo{ 43 CPUTopology: topology, 44 } 45 46 type args struct { 47 conf *config.Configuration 48 metaServer *metaserver.MetaServer 49 machineInfo *machine.KatalystMachineInfo 50 allCPUs machine.CPUSet 51 } 52 tests := []struct { 53 name string 54 args args 55 want machine.CPUSet 56 wantErr bool 57 }{ 58 { 59 name: "GetCoresReservedForSystem with nil conf", 60 want: machine.NewCPUSet(), 61 wantErr: true, 62 }, 63 { 64 name: "GetCoresReservedForSystem with nil metaServer", 65 args: args{ 66 conf: &config.Configuration{ 67 AgentConfiguration: &agent.AgentConfiguration{ 68 GenericAgentConfiguration: &agent.GenericAgentConfiguration{ 69 GenericQRMPluginConfiguration: &qrm.GenericQRMPluginConfiguration{}, 70 }, 71 }, 72 }, 73 machineInfo: &machine.KatalystMachineInfo{}, 74 }, 75 want: machine.NewCPUSet(), 76 wantErr: true, 77 }, 78 { 79 name: "GetCoresReservedForSystem with nil machineInfo", 80 args: args{ 81 conf: &config.Configuration{ 82 AgentConfiguration: &agent.AgentConfiguration{ 83 GenericAgentConfiguration: &agent.GenericAgentConfiguration{ 84 GenericQRMPluginConfiguration: &qrm.GenericQRMPluginConfiguration{}, 85 }, 86 }, 87 }, 88 metaServer: &metaserver.MetaServer{}, 89 }, 90 want: machine.NewCPUSet(), 91 wantErr: true, 92 }, 93 { 94 name: "GetCoresReservedForSystem with conf", 95 args: args{ 96 allCPUs: topology.CPUDetails.CPUs(), 97 conf: &config.Configuration{ 98 AgentConfiguration: &agent.AgentConfiguration{ 99 GenericAgentConfiguration: &agent.GenericAgentConfiguration{ 100 GenericQRMPluginConfiguration: &qrm.GenericQRMPluginConfiguration{}, 101 }, 102 StaticAgentConfiguration: &agent.StaticAgentConfiguration{ 103 QRMPluginsConfiguration: &qrm.QRMPluginsConfiguration{ 104 CPUQRMPluginConfig: &qrm.CPUQRMPluginConfig{ 105 ReservedCPUCores: 4, 106 }, 107 }, 108 }, 109 }, 110 }, 111 metaServer: &metaserver.MetaServer{}, 112 machineInfo: machineInfo, 113 }, 114 want: machine.NewCPUSet(0, 2, 4, 6), 115 wantErr: false, 116 }, 117 } 118 for _, tt := range tests { 119 tt := tt 120 t.Run(tt.name, func(t *testing.T) { 121 t.Parallel() 122 123 got, err := GetCoresReservedForSystem(tt.args.conf, tt.args.metaServer, tt.args.machineInfo, tt.args.allCPUs) 124 if (err != nil) != tt.wantErr { 125 t.Errorf("GetCoresReservedForSystem() error = %v, wantErr %v", err, tt.wantErr) 126 return 127 } 128 if !reflect.DeepEqual(got, tt.want) { 129 t.Errorf("GetCoresReservedForSystem() = %v, want %v", got, tt.want) 130 } 131 }) 132 } 133 } 134 135 func TestRegenerateHints(t *testing.T) { 136 t.Parallel() 137 138 type args struct { 139 allocationInfo *state.AllocationInfo 140 reqInt int 141 } 142 tests := []struct { 143 name string 144 args args 145 want map[string]*pluginapi.ListOfTopologyHints 146 }{ 147 { 148 name: "test RegenerateHints", 149 args: args{ 150 allocationInfo: &state.AllocationInfo{ 151 PodUid: "test", 152 PodNamespace: "test", 153 PodName: "test", 154 ContainerName: "test", 155 ContainerType: pluginapi.ContainerType_MAIN.String(), 156 ContainerIndex: 0, 157 RampUp: false, 158 OwnerPoolName: state.PoolNameDedicated, 159 AllocationResult: machine.NewCPUSet(1, 3, 8, 9, 10, 11), 160 OriginalAllocationResult: machine.NewCPUSet(1, 3, 8, 9, 10, 11), 161 TopologyAwareAssignments: map[int]machine.CPUSet{ 162 0: machine.NewCPUSet(1, 8, 9), 163 1: machine.NewCPUSet(3, 10, 11), 164 }, 165 OriginalTopologyAwareAssignments: map[int]machine.CPUSet{ 166 0: machine.NewCPUSet(1, 8, 9), 167 1: machine.NewCPUSet(3, 10, 11), 168 }, 169 Labels: map[string]string{ 170 consts.PodAnnotationQoSLevelKey: consts.PodAnnotationQoSLevelDedicatedCores, 171 }, 172 Annotations: map[string]string{ 173 consts.PodAnnotationQoSLevelKey: consts.PodAnnotationQoSLevelDedicatedCores, 174 consts.PodAnnotationMemoryEnhancementNumaBinding: consts.PodAnnotationMemoryEnhancementNumaBindingEnable, 175 }, 176 QoSLevel: consts.PodAnnotationQoSLevelDedicatedCores, 177 RequestQuantity: 2, 178 }, 179 reqInt: 2, 180 }, 181 want: map[string]*pluginapi.ListOfTopologyHints{ 182 string(v1.ResourceCPU): { 183 Hints: []*pluginapi.TopologyHint{ 184 { 185 Nodes: []uint64{0, 1}, 186 Preferred: true, 187 }, 188 }, 189 }, 190 }, 191 }, 192 } 193 for _, tt := range tests { 194 tt := tt 195 t.Run(tt.name, func(t *testing.T) { 196 t.Parallel() 197 if got := RegenerateHints(tt.args.allocationInfo, tt.args.reqInt); !reflect.DeepEqual(got, tt.want) { 198 t.Errorf("RegenerateHints() = %v, want %v", got, tt.want) 199 } 200 }) 201 } 202 } 203 204 func TestPackAllocationResponse(t *testing.T) { 205 t.Parallel() 206 207 type args struct { 208 allocationInfo *state.AllocationInfo 209 resourceName string 210 ociPropertyName string 211 isNodeResource bool 212 isScalarResource bool 213 req *pluginapi.ResourceRequest 214 } 215 tests := []struct { 216 name string 217 args args 218 want *pluginapi.ResourceAllocationResponse 219 wantErr bool 220 }{ 221 { 222 name: "test PackAllocationResponse with nil allocationInfo", 223 args: args{}, 224 want: nil, 225 wantErr: true, 226 }, 227 { 228 name: "test PackAllocationResponse with nil req", 229 args: args{ 230 allocationInfo: &state.AllocationInfo{}, 231 }, 232 want: nil, 233 wantErr: true, 234 }, 235 { 236 name: "test PackAllocationResponse", 237 args: args{ 238 allocationInfo: &state.AllocationInfo{ 239 PodUid: "test", 240 PodNamespace: "test", 241 PodName: "test", 242 ContainerName: "test", 243 ContainerType: pluginapi.ContainerType_MAIN.String(), 244 ContainerIndex: 0, 245 RampUp: false, 246 OwnerPoolName: state.PoolNameDedicated, 247 AllocationResult: machine.NewCPUSet(1, 3, 8, 9, 10, 11), 248 OriginalAllocationResult: machine.NewCPUSet(1, 3, 8, 9, 10, 11), 249 TopologyAwareAssignments: map[int]machine.CPUSet{ 250 0: machine.NewCPUSet(1, 8, 9), 251 1: machine.NewCPUSet(3, 10, 11), 252 }, 253 OriginalTopologyAwareAssignments: map[int]machine.CPUSet{ 254 0: machine.NewCPUSet(1, 8, 9), 255 1: machine.NewCPUSet(3, 10, 11), 256 }, 257 Labels: map[string]string{ 258 consts.PodAnnotationQoSLevelKey: consts.PodAnnotationQoSLevelDedicatedCores, 259 }, 260 Annotations: map[string]string{ 261 consts.PodAnnotationQoSLevelKey: consts.PodAnnotationQoSLevelDedicatedCores, 262 consts.PodAnnotationMemoryEnhancementNumaBinding: consts.PodAnnotationMemoryEnhancementNumaBindingEnable, 263 }, 264 QoSLevel: consts.PodAnnotationQoSLevelDedicatedCores, 265 RequestQuantity: 2, 266 }, 267 resourceName: string(v1.ResourceCPU), 268 ociPropertyName: util.OCIPropertyNameCPUSetCPUs, 269 isNodeResource: false, 270 isScalarResource: true, 271 req: &pluginapi.ResourceRequest{ 272 PodUid: "test", 273 PodNamespace: "test", 274 PodName: "test", 275 ContainerName: "test", 276 ContainerType: pluginapi.ContainerType_MAIN, 277 ContainerIndex: 0, 278 }, 279 }, 280 want: &pluginapi.ResourceAllocationResponse{ 281 PodUid: "test", 282 PodNamespace: "test", 283 PodName: "test", 284 ContainerName: "test", 285 ContainerType: pluginapi.ContainerType_MAIN, 286 ContainerIndex: 0, 287 ResourceName: string(v1.ResourceCPU), 288 AllocationResult: &pluginapi.ResourceAllocation{ 289 ResourceAllocation: map[string]*pluginapi.ResourceAllocationInfo{ 290 string(v1.ResourceCPU): { 291 OciPropertyName: util.OCIPropertyNameCPUSetCPUs, 292 IsNodeResource: false, 293 IsScalarResource: true, 294 AllocatedQuantity: float64(6), 295 AllocationResult: machine.NewCPUSet(1, 3, 8, 9, 10, 11).String(), 296 ResourceHints: &pluginapi.ListOfTopologyHints{ 297 Hints: []*pluginapi.TopologyHint{ 298 nil, 299 }, 300 }, 301 }, 302 }, 303 }, 304 }, 305 wantErr: false, 306 }, 307 } 308 for _, tt := range tests { 309 tt := tt 310 t.Run(tt.name, func(t *testing.T) { 311 t.Parallel() 312 313 got, err := PackAllocationResponse(tt.args.allocationInfo, tt.args.resourceName, tt.args.ociPropertyName, tt.args.isNodeResource, tt.args.isScalarResource, tt.args.req) 314 if (err != nil) != tt.wantErr { 315 t.Errorf("PackAllocationResponse() error = %v, wantErr %v", err, tt.wantErr) 316 return 317 } 318 if !reflect.DeepEqual(got, tt.want) { 319 t.Errorf("PackAllocationResponse() = %v, want %v", got, tt.want) 320 } 321 }) 322 } 323 }