Skip to content

Commit 4857fc0

Browse files
committed
Add unit test to catch scheduler's node order evaluation regressions
1 parent 3531136 commit 4857fc0

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
@@ -165,7 +165,7 @@ type genericScheduler struct {
165165
disablePreemption bool
166166
percentageOfNodesToScore int32
167167
enableNonPreempting bool
168-
lastProcessedNodeIndex int
168+
nextStartNodeIndex int
169169
}
170170

171171
// 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
@@ -2282,3 +2282,32 @@ func assignDefaultStartTime(pods []*v1.Pod) {
22822282
}
22832283
}
22842284
}
2285+
2286+
func TestFairEvaluationForNodes(t *testing.T) {
2287+
defer algorithmpredicates.SetPredicatesOrderingDuringTest(order)()
2288+
predicates := map[string]algorithmpredicates.FitPredicate{"true": truePredicate}
2289+
numAllNodes := 500
2290+
nodeNames := make([]string, 0, numAllNodes)
2291+
for i := 0; i < numAllNodes; i++ {
2292+
nodeNames = append(nodeNames, strconv.Itoa(i))
2293+
}
2294+
nodes := makeNodeList(nodeNames)
2295+
g := makeScheduler(predicates, nodes)
2296+
// To make numAllNodes % nodesToFind != 0
2297+
g.percentageOfNodesToScore = 30
2298+
nodesToFind := int(g.numFeasibleNodesToFind(int32(numAllNodes)))
2299+
2300+
// Iterating over all nodes more than twice
2301+
for i := 0; i < 2*(numAllNodes/nodesToFind+1); i++ {
2302+
nodesThatFit, _, _, err := g.findNodesThatFit(context.Background(), framework.NewCycleState(), &v1.Pod{})
2303+
if err != nil {
2304+
t.Errorf("unexpected error: %v", err)
2305+
}
2306+
if len(nodesThatFit) != nodesToFind {
2307+
t.Errorf("got %d nodes filtered, want %d", len(nodesThatFit), nodesToFind)
2308+
}
2309+
if g.nextStartNodeIndex != (i+1)*nodesToFind%numAllNodes {
2310+
t.Errorf("got %d lastProcessedNodeIndex, want %d", g.nextStartNodeIndex, (i+1)*nodesToFind%numAllNodes)
2311+
}
2312+
}
2313+
}

0 commit comments

Comments
 (0)