Repository: kubernetes/kubernetes (language: go)

Issue:
Change EvaluatedNodes to count Nodes that reach Filter phase only
Currently, `EvaluatedNodes` contains the number of nodes that filtered out by PreFilterResult and Filter plugins.
But, before #119779, actually it only contains Nodes reach Filter plugins, which is actually more useful than the current state.

This issue aims to bring back the previous `EvaluatedNodes`.

ref: https://github.com/kubernetes/kubernetes/pull/119779#discussion_r1589213337
/cc @alculquicondor 
/sig scheduling
/kind feature


Discussion / hints:
This issue is currently awaiting triage.

If a SIG or subproject determines this is a relevant issue, they will accept it by applying the `triage/accepted` label and provide further guidance.

The `triage/accepted` label can be added by org members by writing `/triage accepted` in a comment.


<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
</details>
/assign
I'll take a look recently
FYI #124709

Fix patch:
diff --git a/pkg/scheduler/framework/types.go b/pkg/scheduler/framework/types.go
index 97b8010e0e533..164e6aa409589 100644
--- a/pkg/scheduler/framework/types.go
+++ b/pkg/scheduler/framework/types.go
@@ -337,6 +337,9 @@ type Diagnosis struct {
 	PreFilterMsg string
 	// PostFilterMsg records the messages returned from PostFilter plugins.
 	PostFilterMsg string
+	// EvaluatedNodes records the number of nodes evaluated by Filter stage.
+	// It is used for debugging purposes only.
+	EvaluatedNodes int
 }
 
 // FitError describes a fit error of a pod.
diff --git a/pkg/scheduler/schedule_one.go b/pkg/scheduler/schedule_one.go
index 282ce5ab8e2f2..1a38f30578b09 100644
--- a/pkg/scheduler/schedule_one.go
+++ b/pkg/scheduler/schedule_one.go
@@ -417,7 +417,7 @@ func (sched *Scheduler) schedulePod(ctx context.Context, fwk framework.Framework
 	if len(feasibleNodes) == 1 {
 		return ScheduleResult{
 			SuggestedHost:  feasibleNodes[0].Node().Name,
-			EvaluatedNodes: 1 + len(diagnosis.NodeToStatusMap),
+			EvaluatedNodes: diagnosis.EvaluatedNodes,
 			FeasibleNodes:  1,
 		}, nil
 	}
@@ -432,7 +432,7 @@ func (sched *Scheduler) schedulePod(ctx context.Context, fwk framework.Framework
 
 	return ScheduleResult{
 		SuggestedHost:  host,
-		EvaluatedNodes: len(feasibleNodes) + len(diagnosis.NodeToStatusMap),
+		EvaluatedNodes: diagnosis.EvaluatedNodes,
 		FeasibleNodes:  len(feasibleNodes),
 	}, err
 }
@@ -594,6 +594,7 @@ func (sched *Scheduler) findNodesThatPassFilters(
 		for i := range feasibleNodes {
 			feasibleNodes[i] = nodes[(sched.nextStartNodeIndex+i)%numAllNodes]
 		}
+		diagnosis.EvaluatedNodes = int(numNodesToFind)
 		return feasibleNodes, nil
 	}
 
@@ -642,11 +643,13 @@ func (sched *Scheduler) findNodesThatPassFilters(
 	// are found.
 	fwk.Parallelizer().Until(ctx, numAllNodes, checkNode, metrics.Filter)
 	feasibleNodes = feasibleNodes[:feasibleNodesLen]
+	diagnosis.EvaluatedNodes = int(feasibleNodesLen)
 	for _, item := range result {
 		if item == nil {
 			continue
 		}
 		diagnosis.NodeToStatusMap[item.node] = item.status
+		diagnosis.EvaluatedNodes++
 		diagnosis.AddPluginStatus(item.status)
 	}
 	if err := errCh.ReceiveError(); err != nil {


Test patch:
diff --git a/pkg/scheduler/schedule_one_test.go b/pkg/scheduler/schedule_one_test.go
index ecedf52654e32..9b487b1da10ec 100644
--- a/pkg/scheduler/schedule_one_test.go
+++ b/pkg/scheduler/schedule_one_test.go
@@ -935,6 +935,7 @@ func TestSchedulerNoPhantomPodAfterDelete(t *testing.T) {
 					node.Name: framework.NewStatus(framework.Unschedulable, nodeports.ErrReason).WithPlugin(nodeports.Name),
 				},
 				UnschedulablePlugins: sets.New(nodeports.Name),
+				EvaluatedNodes:       1,
 			},
 		}
 		if !reflect.DeepEqual(expectErr, err) {
@@ -1042,6 +1043,7 @@ func TestSchedulerFailedSchedulingReasons(t *testing.T) {
 			Diagnosis: framework.Diagnosis{
 				NodeToStatusMap:      failedNodeStatues,
 				UnschedulablePlugins: sets.New(noderesources.Name),
+				EvaluatedNodes:       100,
 			},
 		}
 		if len(fmt.Sprint(expectErr)) > 150 {
@@ -1829,6 +1831,7 @@ func TestSchedulerSchedulePod(t *testing.T) {
 						"node2": framework.NewStatus(framework.Unschedulable, tf.ErrReasonFake).WithPlugin("FalseFilter"),
 					},
 					UnschedulablePlugins: sets.New("FalseFilter"),
+					EvaluatedNodes:       2,
 				},
 			},
 		},
@@ -1919,6 +1922,7 @@ func TestSchedulerSchedulePod(t *testing.T) {
 						"1": framework.NewStatus(framework.Unschedulable, tf.ErrReasonFake).WithPlugin("FalseFilter"),
 					},
 					UnschedulablePlugins: sets.New("FalseFilter"),
+					EvaluatedNodes:       3,
 				},
 			},
 		},
@@ -1945,6 +1949,7 @@ func TestSchedulerSchedulePod(t *testing.T) {
 						"2": framework.NewStatus(framework.Unschedulable, tf.ErrReasonFake).WithPlugin("NoPodsFilter"),
 					},
 					UnschedulablePlugins: sets.New("MatchFilter", "NoPodsFilter"),
+					EvaluatedNodes:       2,
 				},
 			},
 		},
@@ -2110,6 +2115,7 @@ func TestSchedulerSchedulePod(t *testing.T) {
 						"3": framework.NewStatus(framework.Unschedulable, "injecting failure for pod test-filter").WithPlugin("FakeFilter"),
 					},
 					UnschedulablePlugins: sets.New("FakeFilter"),
+					EvaluatedNodes:       1,
 				},
 			},
 		},
@@ -2143,6 +2149,7 @@ func TestSchedulerSchedulePod(t *testing.T) {
 						"3": framework.NewStatus(framework.Unschedulable, "injecting failure for pod test-filter").WithPlugin("FakeFilter"),
 					},
 					UnschedulablePlugins: sets.New("FakeFilter", framework.ExtenderName),
+					EvaluatedNodes:       3,
 				},
 			},
 		},
@@ -2168,6 +2175,7 @@ func TestSchedulerSchedulePod(t *testing.T) {
 						"3": framework.NewStatus(framework.UnschedulableAndUnresolvable, "injecting failure for pod test-filter").WithPlugin("FakeFilter"),
 					},
 					UnschedulablePlugins: sets.New("FakeFilter"),
+					EvaluatedNodes:       1,
 				},
 			},
 		},
@@ -2249,7 +2257,7 @@ func TestSchedulerSchedulePod(t *testing.T) {
 			nodes:              []string{"node1", "node2", "node3"},
 			pod:                st.MakePod().Name("test-prefilter").UID("test-prefilter").Obj(),
 			wantNodes:          sets.New("node2"),
-			wantEvaluatedNodes: ptr.To[int32](3),
+			wantEvaluatedNodes: ptr.To[int32](1),
 		},
 		{
 			name: "test prefilter plugin returning non-intersecting nodes",
@@ -2338,6 +2346,7 @@ func TestSchedulerSchedulePod(t *testing.T) {
 						"node2": framework.NewStatus(framework.Unschedulable, "injecting failure for pod test-prefilter").WithPlugin("FakeFilter"),
 					},
 					UnschedulablePlugins: sets.New("FakeFilter"),
+					EvaluatedNodes:       1,
 					PreFilterMsg:         "",
 				},
 			},
@@ -2416,10 +2425,11 @@ func TestSchedulerSchedulePod(t *testing.T) {
 				),
 				tf.RegisterBindPlugin(defaultbinder.Name, defaultbinder.New),
 			},
-			nodes:              []string{"node1", "node2", "node3"},
-			pod:                st.MakePod().Name("test-prefilter").UID("test-prefilter").Obj(),
-			wantNodes:          sets.New("node1", "node2"),
-			wantEvaluatedNodes: ptr.To[int32](2),
+			nodes:     []string{"node1", "node2", "node3"},
+			pod:       st.MakePod().Name("test-prefilter").UID("test-prefilter").Obj(),
+			wantNodes: sets.New("node1", "node2"),
+			// since this case has no score plugin, we'll only try to find one node in Filter stage
+			wantEvaluatedNodes: ptr.To[int32](1),
 		},
 	}
 	for _, test := range tests {
@@ -2483,7 +2493,7 @@ func TestSchedulerSchedulePod(t *testing.T) {
 				if gotOK != wantOK {
 					t.Errorf("Expected err to be FitError: %v, but got %v (error: %v)", wantOK, gotOK, err)
 				} else if gotOK {
-					if diff := cmp.Diff(gotFitErr, wantFitErr); diff != "" {
+					if diff := cmp.Diff(wantFitErr, gotFitErr); diff != "" {
 						t.Errorf("Unexpected fitErr: (-want, +got): %s", diff)
 					}
 				}
@@ -2536,6 +2546,7 @@ func TestFindFitAllError(t *testing.T) {
 			"3": framework.NewStatus(framework.Unschedulable, tf.ErrReasonFake).WithPlugin("MatchFilter"),
 		},
 		UnschedulablePlugins: sets.New("MatchFilter"),
+		EvaluatedNodes:       3,
 	}
 	if diff := cmp.Diff(diagnosis, expected); diff != "" {
 		t.Errorf("Unexpected diagnosis: (-want, +got): %s", diff)