From acd82613efe26e766964546849a2fa698ff383fa Mon Sep 17 00:00:00 2001 From: Shintaro Murakami Date: Tue, 13 Aug 2019 18:09:22 +0900 Subject: [PATCH] Add fast path to podFitsOnNode Add test --- pkg/scheduler/core/generic_scheduler.go | 6 +- pkg/scheduler/core/generic_scheduler_test.go | 66 ++++++++++++++++++++ 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/pkg/scheduler/core/generic_scheduler.go b/pkg/scheduler/core/generic_scheduler.go index aa5f598f1fb..b2ea8df439b 100644 --- a/pkg/scheduler/core/generic_scheduler.go +++ b/pkg/scheduler/core/generic_scheduler.go @@ -573,7 +573,7 @@ func (g *genericScheduler) findNodesThatFit(pluginContext *framework.PluginConte // addNominatedPods adds pods with equal or greater priority which are nominated // to run on the node given in nodeInfo to meta and nodeInfo. It returns 1) whether -// any pod was found, 2) augmented meta data, 3) augmented nodeInfo. +// any pod was added, 2) augmented meta data, 3) augmented nodeInfo. func addNominatedPods(pod *v1.Pod, meta predicates.PredicateMetadata, nodeInfo *schedulernodeinfo.NodeInfo, queue internalqueue.SchedulingQueue) (bool, predicates.PredicateMetadata, *schedulernodeinfo.NodeInfo) { @@ -590,15 +590,17 @@ func addNominatedPods(pod *v1.Pod, meta predicates.PredicateMetadata, metaOut = meta.ShallowCopy() } nodeInfoOut := nodeInfo.Clone() + podsAdded := false for _, p := range nominatedPods { if util.GetPodPriority(p) >= util.GetPodPriority(pod) && p.UID != pod.UID { nodeInfoOut.AddPod(p) if metaOut != nil { metaOut.AddPod(p, nodeInfoOut) } + podsAdded = true } } - return true, metaOut, nodeInfoOut + return podsAdded, metaOut, nodeInfoOut } // podFitsOnNode checks whether a node given by NodeInfo satisfies the given predicate functions. diff --git a/pkg/scheduler/core/generic_scheduler_test.go b/pkg/scheduler/core/generic_scheduler_test.go index 2b8ee9674cd..8a7bf6004da 100644 --- a/pkg/scheduler/core/generic_scheduler_test.go +++ b/pkg/scheduler/core/generic_scheduler_test.go @@ -750,6 +750,72 @@ func TestFindFitSomeError(t *testing.T) { } } +type predicateCallCounter struct { + count int +} + +func (c *predicateCallCounter) truePredicate() algorithmpredicates.FitPredicate { + return func(pod *v1.Pod, meta algorithmpredicates.PredicateMetadata, nodeInfo *schedulernodeinfo.NodeInfo) (bool, []algorithmpredicates.PredicateFailureReason, error) { + c.count++ + return truePredicate(pod, meta, nodeInfo) + } +} + +func TestFindFitPredicateCallCounts(t *testing.T) { + defer algorithmpredicates.SetPredicatesOrderingDuringTest(order)() + + tests := []struct { + name string + pod *v1.Pod + expectedCount int + }{ + { + name: "nominated pods have lower priority, predicate is called once", + pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "1", UID: types.UID("1")}, Spec: v1.PodSpec{Priority: &highPriority}}, + expectedCount: 1, + }, + { + name: "nominated pods have higher priority, predicate is called twice", + pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "1", UID: types.UID("1")}, Spec: v1.PodSpec{Priority: &lowPriority}}, + expectedCount: 2, + }, + } + + for _, test := range tests { + pc := predicateCallCounter{} + predicates := map[string]algorithmpredicates.FitPredicate{"true": pc.truePredicate()} + nodes := makeNodeList([]string{"1"}) + + cache := internalcache.New(time.Duration(0), wait.NeverStop) + for _, n := range nodes { + cache.AddNode(n) + } + prioritizers := []priorities.PriorityConfig{{Map: EqualPriorityMap, Weight: 1}} + queue := internalqueue.NewSchedulingQueue(nil, nil) + scheduler := NewGenericScheduler( + cache, + queue, + predicates, + algorithmpredicates.EmptyPredicateMetadataProducer, + prioritizers, + priorities.EmptyPriorityMetadataProducer, + emptyFramework, + nil, nil, nil, nil, false, false, + schedulerapi.DefaultPercentageOfNodesToScore, false).(*genericScheduler) + cache.UpdateNodeInfoSnapshot(scheduler.nodeInfoSnapshot) + queue.UpdateNominatedPodForNode(&v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("nominated")}, Spec: v1.PodSpec{Priority: &midPriority}}, "1") + + _, _, _, err := scheduler.findNodesThatFit(nil, test.pod) + + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if test.expectedCount != pc.count { + t.Errorf("predicate was called %d times, expected is %d", pc.count, test.expectedCount) + } + } +} + func makeNode(node string, milliCPU, memory int64) *v1.Node { return &v1.Node{ ObjectMeta: metav1.ObjectMeta{Name: node},