Skip to content

Commit 979688b

Browse files
authored
Merge pull request kubernetes#84335 from mrkm4ntr/fix-node-evaluation
Add unit test to catch scheduler's node order evaluation regressions
2 parents 77e110f + 4857fc0 commit 979688b

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

pkg/scheduler/core/generic_scheduler.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ type genericScheduler struct {
164164
disablePreemption bool
165165
percentageOfNodesToScore int32
166166
enableNonPreempting bool
167-
lastProcessedNodeIndex int
167+
nextStartNodeIndex int
168168
}
169169

170170
// snapshot snapshots scheduler cache and node infos for all fit and priority
@@ -499,7 +499,7 @@ func (g *genericScheduler) findNodesThatFit(ctx context.Context, state *framewor
499499
checkNode := func(i int) {
500500
// We check the nodes starting from where we left off in the previous scheduling cycle,
501501
// this is to make sure all nodes have the same chance of being examined across pods.
502-
nodeInfo := g.nodeInfoSnapshot.NodeInfoList[(g.lastProcessedNodeIndex+i)%allNodes]
502+
nodeInfo := g.nodeInfoSnapshot.NodeInfoList[(g.nextStartNodeIndex+i)%allNodes]
503503
fits, failedPredicates, status, err := g.podFitsOnNode(
504504
ctx,
505505
state,
@@ -536,7 +536,7 @@ func (g *genericScheduler) findNodesThatFit(ctx context.Context, state *framewor
536536
// are found.
537537
workqueue.ParallelizeUntil(ctx, 16, allNodes, checkNode)
538538
processedNodes := int(filteredLen) + len(filteredNodesStatuses) + len(failedPredicateMap)
539-
g.lastProcessedNodeIndex = (g.lastProcessedNodeIndex + processedNodes) % allNodes
539+
g.nextStartNodeIndex = (g.nextStartNodeIndex + processedNodes) % allNodes
540540

541541
filtered = filtered[:filteredLen]
542542
if err := errCh.ReceiveError(); err != nil {

pkg/scheduler/core/generic_scheduler_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2286,3 +2286,32 @@ func assignDefaultStartTime(pods []*v1.Pod) {
22862286
}
22872287
}
22882288
}
2289+
2290+
func TestFairEvaluationForNodes(t *testing.T) {
2291+
defer algorithmpredicates.SetPredicatesOrderingDuringTest(order)()
2292+
predicates := map[string]algorithmpredicates.FitPredicate{"true": truePredicate}
2293+
numAllNodes := 500
2294+
nodeNames := make([]string, 0, numAllNodes)
2295+
for i := 0; i < numAllNodes; i++ {
2296+
nodeNames = append(nodeNames, strconv.Itoa(i))
2297+
}
2298+
nodes := makeNodeList(nodeNames)
2299+
g := makeScheduler(predicates, nodes)
2300+
// To make numAllNodes % nodesToFind != 0
2301+
g.percentageOfNodesToScore = 30
2302+
nodesToFind := int(g.numFeasibleNodesToFind(int32(numAllNodes)))
2303+
2304+
// Iterating over all nodes more than twice
2305+
for i := 0; i < 2*(numAllNodes/nodesToFind+1); i++ {
2306+
nodesThatFit, _, _, err := g.findNodesThatFit(context.Background(), framework.NewCycleState(), &v1.Pod{})
2307+
if err != nil {
2308+
t.Errorf("unexpected error: %v", err)
2309+
}
2310+
if len(nodesThatFit) != nodesToFind {
2311+
t.Errorf("got %d nodes filtered, want %d", len(nodesThatFit), nodesToFind)
2312+
}
2313+
if g.nextStartNodeIndex != (i+1)*nodesToFind%numAllNodes {
2314+
t.Errorf("got %d lastProcessedNodeIndex, want %d", g.nextStartNodeIndex, (i+1)*nodesToFind%numAllNodes)
2315+
}
2316+
}
2317+
}

0 commit comments

Comments
 (0)