github.com/kubewharf/katalyst-core@v0.5.3/pkg/agent/orm/manager_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 orm 18 19 import ( 20 "context" 21 "fmt" 22 "io/ioutil" 23 "os" 24 "testing" 25 "time" 26 27 cadvisorapi "github.com/google/cadvisor/info/v1" 28 "github.com/stretchr/testify/assert" 29 "google.golang.org/grpc" 30 v1 "k8s.io/api/core/v1" 31 "k8s.io/apimachinery/pkg/api/resource" 32 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 33 "k8s.io/apimachinery/pkg/runtime" 34 "k8s.io/apimachinery/pkg/util/uuid" 35 pluginapi "k8s.io/kubelet/pkg/apis/resourceplugin/v1alpha1" 36 "k8s.io/kubernetes/pkg/kubelet/checkpointmanager" 37 38 katalyst_base "github.com/kubewharf/katalyst-core/cmd/base" 39 "github.com/kubewharf/katalyst-core/cmd/katalyst-agent/app/options" 40 "github.com/kubewharf/katalyst-core/pkg/agent/orm/endpoint" 41 "github.com/kubewharf/katalyst-core/pkg/agent/orm/executor" 42 "github.com/kubewharf/katalyst-core/pkg/agent/orm/metamanager" 43 "github.com/kubewharf/katalyst-core/pkg/agent/orm/topology" 44 "github.com/kubewharf/katalyst-core/pkg/config" 45 "github.com/kubewharf/katalyst-core/pkg/config/generic" 46 "github.com/kubewharf/katalyst-core/pkg/metaserver" 47 "github.com/kubewharf/katalyst-core/pkg/metaserver/agent/pod" 48 "github.com/kubewharf/katalyst-core/pkg/metrics" 49 cgroupmgr "github.com/kubewharf/katalyst-core/pkg/util/cgroup/manager" 50 ) 51 52 func TestProcess(t *testing.T) { 53 t.Parallel() 54 55 res1 := TestResource{ 56 resourceName: "domain1.com/resource1", 57 resourceQuantity: *resource.NewQuantity(int64(2), resource.DecimalSI), 58 } 59 res2 := TestResource{ 60 resourceName: "domain2.com/resource2", 61 resourceQuantity: *resource.NewQuantity(int64(2), resource.DecimalSI), 62 } 63 64 testResources := []TestResource{ 65 res1, 66 res2, 67 } 68 69 pods := []*v1.Pod{ 70 makePod("testPod", v1.ResourceList{ 71 "domain1.com/resource1": *resource.NewQuantity(2, resource.DecimalSI), 72 "domain2.com/resource2": *resource.NewQuantity(2, resource.DecimalSI), 73 }), 74 makePod("skipPod", v1.ResourceList{ 75 "domain1.com/resource1": *resource.NewQuantity(2, resource.DecimalSI), 76 "domain2.com/resource2": *resource.NewQuantity(2, resource.DecimalSI), 77 }), 78 } 79 pods[1].OwnerReferences = []metav1.OwnerReference{ 80 { 81 Kind: "DaemonSet", 82 }, 83 } 84 85 ckDir, err := ioutil.TempDir("", "checkpoint-Test") 86 assert.NoError(t, err) 87 defer func() { _ = os.RemoveAll(ckDir) }() 88 89 conf := generateTestConfiguration(ckDir) 90 metaServer, err := generateTestMetaServer(conf, pods) 91 assert.NoError(t, err) 92 metamanager := metamanager.NewManager(metrics.DummyMetrics{}, nil, metaServer) 93 94 checkpointManager, err := checkpointmanager.NewCheckpointManager("/tmp/process") 95 assert.NoError(t, err) 96 97 ctx, cancel := context.WithCancel(context.Background()) 98 defer cancel() 99 100 m := &ManagerImpl{ 101 ctx: ctx, 102 endpoints: map[string]endpoint.EndpointInfo{}, 103 socketdir: "/tmp/process", 104 metaManager: metamanager, 105 resourceNamesMap: map[string]string{}, 106 podResources: newPodResourcesChk(), 107 resourceExecutor: executor.NewExecutor(&cgroupmgr.FakeCgroupManager{}), 108 checkpointManager: checkpointManager, 109 podAddChan: make(chan string, 1), 110 podDeleteChan: make(chan string, 1), 111 qosConfig: generic.NewQoSConfiguration(), 112 } 113 defer func() { _ = os.Remove("/tmp/process/kubelet_qrm_checkpoint") }() 114 topologyManager, _ := topology.NewManager([]cadvisorapi.Node{ 115 { 116 Id: 0, 117 }, 118 }, "restricted", nil) 119 topologyManager.AddHintProvider(m) 120 m.topologyManager = topologyManager 121 err = registerEndpointByRes(m, testResources) 122 assert.NoError(t, err) 123 124 go m.process() 125 126 for _, pod := range pods { 127 m.onPodAdd(string(pod.UID)) 128 } 129 130 time.Sleep(1 * time.Second) 131 containerResources := m.podResources.podResources(string(pods[0].UID)) 132 assert.NotNil(t, containerResources) 133 assert.Equal(t, len(containerResources), 1) 134 135 for _, containerResource := range containerResources { 136 assert.Equal(t, len(containerResource), 2) 137 allocationInfo, ok := containerResource["domain1.com/resource1"] 138 assert.True(t, ok) 139 assert.Equal(t, allocationInfo.OciPropertyName, "CpusetCpus") 140 141 allocationInfo, ok = containerResource["domain2.com/resource2"] 142 assert.True(t, ok) 143 assert.Equal(t, allocationInfo.OciPropertyName, "CpusetMems") 144 } 145 146 containerResources = m.podResources.podResources(string(pods[1].UID)) 147 assert.Nil(t, containerResources) 148 149 // remove pod 150 for _, pod := range pods { 151 m.onPodDelete(string(pod.UID)) 152 } 153 time.Sleep(500 * time.Millisecond) 154 assert.Equal(t, len(m.podResources.allAllocatedResourceNames()), 0) 155 assert.Equal(t, len(m.podResources.pods()), 0) 156 } 157 158 func TestReconcile(t *testing.T) { 159 t.Parallel() 160 161 pods := []*v1.Pod{ 162 makePod("testPod1", v1.ResourceList{ 163 "cpu": *resource.NewQuantity(2, resource.DecimalSI), 164 "memory": *resource.NewQuantity(2, resource.DecimalSI), 165 }), 166 makePod("testPod2", v1.ResourceList{ 167 "cpu": *resource.NewQuantity(2, resource.DecimalSI), 168 "memory": *resource.NewQuantity(2, resource.DecimalSI), 169 }), 170 } 171 172 ckDir, err := ioutil.TempDir("", "checkpoint-Test") 173 assert.NoError(t, err) 174 defer func() { _ = os.RemoveAll(ckDir) }() 175 176 conf := generateTestConfiguration(ckDir) 177 metaServer, err := generateTestMetaServer(conf, pods) 178 assert.NoError(t, err) 179 metamanager := metamanager.NewManager(metrics.DummyMetrics{}, nil, metaServer) 180 181 checkpointManager, err := checkpointmanager.NewCheckpointManager("/tmp/reconcile") 182 assert.NoError(t, err) 183 184 m := &ManagerImpl{ 185 endpoints: map[string]endpoint.EndpointInfo{}, 186 socketdir: "/tmp/reconcile", 187 metaManager: metamanager, 188 resourceNamesMap: map[string]string{ 189 "domain1.com/resource1": "domain1.com/resource1", 190 }, 191 podResources: newPodResourcesChk(), 192 resourceExecutor: executor.NewExecutor(&cgroupmgr.FakeCgroupManager{}), 193 checkpointManager: checkpointManager, 194 podAddChan: make(chan string, 1), 195 podDeleteChan: make(chan string, 1), 196 qosConfig: generic.NewQoSConfiguration(), 197 } 198 defer func() { _ = os.Remove("/tmp/reconcile/kubelet_qrm_checkpoint") }() 199 topologyManager, _ := topology.NewManager([]cadvisorapi.Node{ 200 { 201 Id: 0, 202 }, 203 }, "none", nil) 204 topologyManager.AddHintProvider(m) 205 m.topologyManager = topologyManager 206 err = registerEndpointByPods(m, pods) 207 assert.NoError(t, err) 208 209 m.reconcile() 210 211 assert.Equal(t, len(m.podResources.pods()), 2) 212 for _, pod := range pods { 213 containerResources := m.podResources.podResources(string(pod.UID)) 214 assert.NotNil(t, containerResources) 215 216 for _, resourceAllocation := range containerResources { 217 assert.Equal(t, len(resourceAllocation), 2) 218 } 219 } 220 } 221 222 func TestIsSkippedContainer(t *testing.T) { 223 t.Parallel() 224 225 testCases := []struct { 226 Name string 227 Pod *v1.Pod 228 Container *v1.Container 229 Expected bool 230 }{ 231 { 232 Name: "mainContainer", 233 Pod: &v1.Pod{ 234 Spec: v1.PodSpec{ 235 Containers: []v1.Container{ 236 { 237 Name: "testContainer", 238 }, 239 }, 240 }, 241 }, 242 Container: &v1.Container{ 243 Name: "testContainer", 244 }, 245 Expected: false, 246 }, 247 { 248 Name: "initContainer", 249 Pod: &v1.Pod{ 250 Spec: v1.PodSpec{ 251 InitContainers: []v1.Container{ 252 { 253 Name: "testContainer", 254 }, 255 }, 256 }, 257 }, 258 Container: &v1.Container{ 259 Name: "testContainer", 260 }, 261 Expected: true, 262 }, 263 { 264 Name: "fail", 265 Pod: nil, 266 Container: nil, 267 Expected: false, 268 }, 269 } 270 271 for _, tc := range testCases { 272 tc := tc 273 t.Run(tc.Name, func(t *testing.T) { 274 t.Parallel() 275 res := isSkippedContainer(tc.Pod, tc.Container) 276 assert.Equal(t, res, tc.Expected) 277 }) 278 } 279 } 280 281 func TestGetMappedResourceName(t *testing.T) { 282 t.Parallel() 283 284 m := &ManagerImpl{ 285 resourceNamesMap: map[string]string{ 286 "test/cpu": "cpu", 287 "test/memory": "memory", 288 }, 289 } 290 291 testCases := []struct { 292 Name string 293 resourceName string 294 requests v1.ResourceList 295 expectErr bool 296 expectResource string 297 }{ 298 { 299 Name: "cpu", 300 resourceName: "test/cpu", 301 requests: map[v1.ResourceName]resource.Quantity{ 302 "cpu": *resource.NewQuantity(1, resource.DecimalSI), 303 }, 304 expectErr: false, 305 expectResource: "cpu", 306 }, 307 { 308 Name: "not found", 309 resourceName: "cpu", 310 requests: map[v1.ResourceName]resource.Quantity{ 311 "cpu": *resource.NewQuantity(1, resource.DecimalSI), 312 }, 313 expectErr: false, 314 expectResource: "cpu", 315 }, 316 { 317 Name: "repetition", 318 resourceName: "test/cpu", 319 requests: map[v1.ResourceName]resource.Quantity{ 320 "cpu": *resource.NewQuantity(1, resource.DecimalSI), 321 "test/cpu": *resource.NewQuantity(1, resource.DecimalSI), 322 }, 323 expectErr: true, 324 expectResource: "cpu", 325 }, 326 } 327 328 for _, tc := range testCases { 329 tc := tc 330 t.Run(tc.Name, func(t *testing.T) { 331 t.Parallel() 332 r, err := m.getMappedResourceName(tc.resourceName, tc.requests) 333 if tc.expectErr { 334 assert.NotNil(t, err) 335 } else { 336 assert.Nil(t, err) 337 assert.Equal(t, r, tc.expectResource) 338 } 339 }) 340 } 341 } 342 343 func TestRun(t *testing.T) { 344 t.Parallel() 345 346 pods := []*v1.Pod{ 347 makePod("testPod1", v1.ResourceList{ 348 "cpu": *resource.NewQuantity(2, resource.DecimalSI), 349 "memory": *resource.NewQuantity(2, resource.DecimalSI), 350 }), 351 makePod("testPod2", v1.ResourceList{ 352 "cpu": *resource.NewQuantity(2, resource.DecimalSI), 353 "memory": *resource.NewQuantity(2, resource.DecimalSI), 354 }), 355 } 356 357 ckDir, err := ioutil.TempDir("", "checkpoint-Test") 358 assert.NoError(t, err) 359 defer func() { _ = os.RemoveAll(ckDir) }() 360 361 conf := generateTestConfiguration(ckDir) 362 metaServer, err := generateTestMetaServer(conf, pods) 363 assert.NoError(t, err) 364 365 checkpointManager, err := checkpointmanager.NewCheckpointManager("/tmp/run") 366 assert.NoError(t, err) 367 368 m := &ManagerImpl{ 369 reconcilePeriod: 2 * time.Second, 370 endpoints: map[string]endpoint.EndpointInfo{}, 371 socketdir: "/tmp/run", 372 socketname: "tmp.sock", 373 resourceNamesMap: map[string]string{ 374 "domain1.com/resource1": "domain1.com/resource1", 375 }, 376 podResources: newPodResourcesChk(), 377 resourceExecutor: executor.NewExecutor(&cgroupmgr.FakeCgroupManager{}), 378 checkpointManager: checkpointManager, 379 podAddChan: make(chan string, 1), 380 podDeleteChan: make(chan string, 1), 381 qosConfig: generic.NewQoSConfiguration(), 382 podResourceSocket: "unix:/tmp/run/podresource.sock", 383 } 384 defer func() { _ = os.RemoveAll("/tmp/run") }() 385 metaManager := metamanager.NewManager(metrics.DummyMetrics{}, m.podResources.pods, metaServer) 386 m.metaManager = metaManager 387 388 topologyManager, _ := topology.NewManager([]cadvisorapi.Node{ 389 { 390 Id: 0, 391 }, 392 }, "none", nil) 393 topologyManager.AddHintProvider(m) 394 m.topologyManager = topologyManager 395 396 err = registerEndpointByPods(m, pods) 397 assert.NoError(t, err) 398 399 ctx, cancel := context.WithCancel(context.Background()) 400 defer cancel() 401 402 m.Run(ctx) 403 time.Sleep(5 * time.Second) 404 405 assert.Equal(t, len(m.podResources.pods()), 2) 406 assert.Equal(t, len(m.podResources.allAllocatedResourceNames()), 2) 407 } 408 409 type TestResource struct { 410 resourceName string 411 resourceQuantity resource.Quantity 412 } 413 414 func generateTestMetaServer(conf *config.Configuration, podList []*v1.Pod) (*metaserver.MetaServer, error) { 415 genericCtx, err := katalyst_base.GenerateFakeGenericContext([]runtime.Object{}) 416 if err != nil { 417 return nil, err 418 } 419 420 ms, err := metaserver.NewMetaServer(genericCtx.Client, metrics.DummyMetrics{}, conf) 421 if err != nil { 422 return ms, err 423 } 424 ms.PodFetcher = &pod.PodFetcherStub{ 425 PodList: podList, 426 } 427 return ms, nil 428 } 429 430 func generateTestConfiguration(checkpointDir string) *config.Configuration { 431 conf, _ := options.NewOptions().Config() 432 433 conf.MetaServerConfiguration.CheckpointManagerDir = checkpointDir 434 435 return conf 436 } 437 438 func makePod(name string, rl v1.ResourceList) *v1.Pod { 439 return &v1.Pod{ 440 ObjectMeta: metav1.ObjectMeta{ 441 UID: uuid.NewUUID(), 442 Name: name, 443 }, 444 Spec: v1.PodSpec{ 445 Containers: []v1.Container{ 446 { 447 Name: name, 448 Resources: v1.ResourceRequirements{ 449 Requests: rl.DeepCopy(), 450 Limits: rl.DeepCopy(), 451 }, 452 }, 453 }, 454 }, 455 } 456 } 457 458 func registerEndpointByRes(manager *ManagerImpl, testRes []TestResource) error { 459 if manager == nil { 460 return fmt.Errorf("registerEndpointByRes got nil manager") 461 } 462 463 for i, res := range testRes { 464 var OciPropertyName string 465 if res.resourceName == "domain1.com/resource1" { 466 OciPropertyName = "CpusetCpus" 467 } else if res.resourceName == "domain2.com/resource2" { 468 OciPropertyName = "CpusetMems" 469 } 470 471 curResourceName := res.resourceName 472 473 if res.resourceName == "domain1.com/resource1" || res.resourceName == "domain2.com/resource2" { 474 manager.registerEndpoint(curResourceName, &pluginapi.ResourcePluginOptions{ 475 PreStartRequired: true, 476 WithTopologyAlignment: true, 477 NeedReconcile: true, 478 }, &MockEndpoint{ 479 allocateFunc: func(req *pluginapi.ResourceRequest) (*pluginapi.ResourceAllocationResponse, error) { 480 if req == nil { 481 return nil, fmt.Errorf("allocateFunc got nil request") 482 } 483 484 resp := new(pluginapi.ResourceAllocationResponse) 485 resp.AllocationResult = new(pluginapi.ResourceAllocation) 486 resp.AllocationResult.ResourceAllocation = make(map[string]*pluginapi.ResourceAllocationInfo) 487 resp.AllocationResult.ResourceAllocation[curResourceName] = new(pluginapi.ResourceAllocationInfo) 488 resp.AllocationResult.ResourceAllocation[curResourceName].Envs = make(map[string]string) 489 resp.AllocationResult.ResourceAllocation[curResourceName].Envs[fmt.Sprintf("key%d", i)] = fmt.Sprintf("val%d", i) 490 resp.AllocationResult.ResourceAllocation[curResourceName].Annotations = make(map[string]string) 491 resp.AllocationResult.ResourceAllocation[curResourceName].Annotations[fmt.Sprintf("key%d", i)] = fmt.Sprintf("val%d", i) 492 resp.AllocationResult.ResourceAllocation[curResourceName].IsScalarResource = true 493 resp.AllocationResult.ResourceAllocation[curResourceName].IsNodeResource = true 494 resp.AllocationResult.ResourceAllocation[curResourceName].AllocatedQuantity = req.ResourceRequests[curResourceName] 495 resp.AllocationResult.ResourceAllocation[curResourceName].AllocationResult = "0-1" 496 resp.AllocationResult.ResourceAllocation[curResourceName].OciPropertyName = OciPropertyName 497 return resp, nil 498 }, 499 topologyHints: []*pluginapi.TopologyHint{ 500 { 501 Nodes: []uint64{0}, 502 Preferred: true, 503 }, 504 }, 505 }) 506 } else if res.resourceName == "domain3.com/resource3" { 507 manager.registerEndpoint(curResourceName, &pluginapi.ResourcePluginOptions{ 508 PreStartRequired: true, 509 WithTopologyAlignment: true, 510 NeedReconcile: true, 511 }, &MockEndpoint{ 512 allocateFunc: func(req *pluginapi.ResourceRequest) (*pluginapi.ResourceAllocationResponse, error) { 513 return nil, fmt.Errorf("mock error") 514 }, 515 topologyHints: []*pluginapi.TopologyHint{ 516 { 517 Nodes: []uint64{0}, 518 Preferred: true, 519 }, 520 }, 521 }) 522 } 523 } 524 525 return nil 526 } 527 528 func registerEndpointByPods(manager *ManagerImpl, pods []*v1.Pod) error { 529 for _, resource := range []string{"cpu", "memory"} { 530 resp := &pluginapi.GetResourcesAllocationResponse{ 531 PodResources: map[string]*pluginapi.ContainerResources{}, 532 } 533 for _, pod := range pods { 534 uid := string(pod.UID) 535 if _, ok := resp.PodResources[uid]; !ok { 536 resp.PodResources[uid] = &pluginapi.ContainerResources{ 537 ContainerResources: map[string]*pluginapi.ResourceAllocation{}, 538 } 539 } 540 for _, container := range pod.Spec.Containers { 541 if _, ok := resp.PodResources[uid].ContainerResources[container.Name]; !ok { 542 resp.PodResources[uid].ContainerResources[container.Name] = &pluginapi.ResourceAllocation{ 543 ResourceAllocation: map[string]*pluginapi.ResourceAllocationInfo{}, 544 } 545 } 546 547 for resourceName, quantity := range container.Resources.Requests { 548 if resourceName.String() == resource { 549 resp.PodResources[uid].ContainerResources[container.Name].ResourceAllocation[string(resourceName)] = &pluginapi.ResourceAllocationInfo{ 550 IsNodeResource: true, 551 IsScalarResource: false, 552 AllocatedQuantity: float64(quantity.Value()), 553 AllocationResult: "0-1", 554 } 555 } 556 } 557 } 558 } 559 560 manager.registerEndpoint(resource, &pluginapi.ResourcePluginOptions{ 561 NeedReconcile: true, 562 }, &MockEndpoint{ 563 resourceAlloc: func(ctx context.Context, request *pluginapi.GetResourcesAllocationRequest) (*pluginapi.GetResourcesAllocationResponse, error) { 564 return resp, nil 565 }, 566 allocateFunc: func(resourceRequest *pluginapi.ResourceRequest) (*pluginapi.ResourceAllocationResponse, error) { 567 return &pluginapi.ResourceAllocationResponse{}, nil 568 }, 569 topologyHints: []*pluginapi.TopologyHint{ 570 { 571 Nodes: []uint64{0}, 572 Preferred: true, 573 }, 574 }, 575 }) 576 } 577 578 return nil 579 } 580 581 /* ------------------ mock endpoint for test ----------------------- */ 582 type MockEndpoint struct { 583 allocateFunc func(resourceRequest *pluginapi.ResourceRequest) (*pluginapi.ResourceAllocationResponse, error) 584 resourceAlloc func(ctx context.Context, request *pluginapi.GetResourcesAllocationRequest) (*pluginapi.GetResourcesAllocationResponse, error) 585 getTopologyAwareResourcesFunc func(c context.Context, request *pluginapi.GetTopologyAwareResourcesRequest) (*pluginapi.GetTopologyAwareResourcesResponse, error) 586 getTopologyAwareAllocatableResourcesFunc func(c context.Context, request *pluginapi.GetTopologyAwareAllocatableResourcesRequest) (*pluginapi.GetTopologyAwareAllocatableResourcesResponse, error) 587 stopTime time.Time 588 topologyHints []*pluginapi.TopologyHint 589 } 590 591 func (m *MockEndpoint) Stop() { 592 m.stopTime = time.Now() 593 } 594 func (m *MockEndpoint) run(success chan<- bool) {} 595 596 func (m *MockEndpoint) Allocate(ctx context.Context, resourceRequest *pluginapi.ResourceRequest) (*pluginapi.ResourceAllocationResponse, error) { 597 if m.IsStopped() { 598 return nil, fmt.Errorf("endpoint %v has been stopped", m) 599 } 600 if m.allocateFunc != nil { 601 return m.allocateFunc(resourceRequest) 602 } 603 return nil, nil 604 } 605 606 func (m *MockEndpoint) GetTopologyHints(c context.Context, resourceRequest *pluginapi.ResourceRequest) (*pluginapi.ResourceHintsResponse, error) { 607 return &pluginapi.ResourceHintsResponse{ 608 PodUid: resourceRequest.PodUid, 609 PodNamespace: resourceRequest.PodNamespace, 610 PodName: resourceRequest.PodName, 611 ContainerName: resourceRequest.ContainerName, 612 ContainerIndex: resourceRequest.ContainerIndex, 613 ContainerType: resourceRequest.ContainerType, 614 PodRole: resourceRequest.PodRole, 615 PodType: resourceRequest.PodType, 616 ResourceName: resourceRequest.ResourceName, 617 Labels: resourceRequest.Labels, 618 Annotations: resourceRequest.Annotations, 619 ResourceHints: map[string]*pluginapi.ListOfTopologyHints{ 620 resourceRequest.ResourceName: { 621 Hints: m.topologyHints, 622 }, 623 }, 624 }, nil 625 } 626 627 func (m *MockEndpoint) IsStopped() bool { 628 return !m.stopTime.IsZero() 629 } 630 631 var SGP int = 0 632 633 func (m *MockEndpoint) StopGracePeriodExpired() bool { 634 if SGP == 0 { 635 return false 636 } else { 637 return true 638 } 639 } 640 641 func (m *MockEndpoint) RemovePod(ctx context.Context, removePodRequest *pluginapi.RemovePodRequest) (*pluginapi.RemovePodResponse, error) { 642 return nil, nil 643 } 644 645 func (m *MockEndpoint) GetResourceAllocation(ctx context.Context, request *pluginapi.GetResourcesAllocationRequest) (*pluginapi.GetResourcesAllocationResponse, error) { 646 if m.resourceAlloc != nil { 647 return m.resourceAlloc(ctx, request) 648 } 649 return nil, nil 650 } 651 652 func (m *MockEndpoint) GetResourcePluginOptions(ctx context.Context, in *pluginapi.Empty, opts ...grpc.CallOption) (*pluginapi.ResourcePluginOptions, error) { 653 return &pluginapi.ResourcePluginOptions{ 654 NeedReconcile: true, 655 }, nil 656 } 657 658 func (m *MockEndpoint) GetTopologyAwareResources(c context.Context, request *pluginapi.GetTopologyAwareResourcesRequest) (*pluginapi.GetTopologyAwareResourcesResponse, error) { 659 if m.getTopologyAwareResourcesFunc != nil { 660 return m.getTopologyAwareResourcesFunc(c, request) 661 } 662 return nil, nil 663 } 664 665 func (m *MockEndpoint) GetTopologyAwareAllocatableResources(c context.Context, request *pluginapi.GetTopologyAwareAllocatableResourcesRequest) (*pluginapi.GetTopologyAwareAllocatableResourcesResponse, error) { 666 if m.getTopologyAwareAllocatableResourcesFunc != nil { 667 return m.getTopologyAwareAllocatableResourcesFunc(c, request) 668 } 669 return nil, nil 670 }