mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Merge pull request #82156 from mrkm4ntr/fix-evaluated-nodes
Fix EvaluatedNodes in ScheduleResult
This commit is contained in:
commit
96201b5e57
@ -243,7 +243,7 @@ func (g *genericScheduler) Schedule(pod *v1.Pod, pluginContext *framework.Plugin
|
|||||||
metrics.DeprecatedSchedulingAlgorithmPriorityEvaluationDuration.Observe(metrics.SinceInMicroseconds(startPriorityEvalTime))
|
metrics.DeprecatedSchedulingAlgorithmPriorityEvaluationDuration.Observe(metrics.SinceInMicroseconds(startPriorityEvalTime))
|
||||||
return ScheduleResult{
|
return ScheduleResult{
|
||||||
SuggestedHost: filteredNodes[0].Name,
|
SuggestedHost: filteredNodes[0].Name,
|
||||||
EvaluatedNodes: 1 + len(failedPredicateMap),
|
EvaluatedNodes: 1 + len(failedPredicateMap) + len(filteredNodesStatuses),
|
||||||
FeasibleNodes: 1,
|
FeasibleNodes: 1,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@ -263,7 +263,7 @@ func (g *genericScheduler) Schedule(pod *v1.Pod, pluginContext *framework.Plugin
|
|||||||
trace.Step("Selecting host done")
|
trace.Step("Selecting host done")
|
||||||
return ScheduleResult{
|
return ScheduleResult{
|
||||||
SuggestedHost: host,
|
SuggestedHost: host,
|
||||||
EvaluatedNodes: len(filteredNodes) + len(failedPredicateMap),
|
EvaluatedNodes: len(filteredNodes) + len(failedPredicateMap) + len(filteredNodesStatuses),
|
||||||
FeasibleNodes: len(filteredNodes),
|
FeasibleNodes: len(filteredNodes),
|
||||||
}, err
|
}, err
|
||||||
}
|
}
|
||||||
|
@ -143,8 +143,8 @@ var emptyFramework, _ = framework.NewFramework(EmptyPluginRegistry, nil, []sched
|
|||||||
|
|
||||||
// FakeFilterPlugin is a test filter plugin used by default scheduler.
|
// FakeFilterPlugin is a test filter plugin used by default scheduler.
|
||||||
type FakeFilterPlugin struct {
|
type FakeFilterPlugin struct {
|
||||||
numFilterCalled int32
|
numFilterCalled int32
|
||||||
returnCode framework.Code
|
failedNodeReturnCodeMap map[string]framework.Code
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name returns name of the plugin.
|
// Name returns name of the plugin.
|
||||||
@ -155,19 +155,19 @@ func (fp *FakeFilterPlugin) Name() string {
|
|||||||
// reset is used to reset filter plugin.
|
// reset is used to reset filter plugin.
|
||||||
func (fp *FakeFilterPlugin) reset() {
|
func (fp *FakeFilterPlugin) reset() {
|
||||||
fp.numFilterCalled = 0
|
fp.numFilterCalled = 0
|
||||||
fp.returnCode = framework.Success
|
fp.failedNodeReturnCodeMap = map[string]framework.Code{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter is a test function that returns an error or nil, depending on the
|
// Filter is a test function that returns an error or nil, depending on the
|
||||||
// value of "failFilter".
|
// value of "failedNodeReturnCodeMap".
|
||||||
func (fp *FakeFilterPlugin) Filter(pc *framework.PluginContext, pod *v1.Pod, nodeName string) *framework.Status {
|
func (fp *FakeFilterPlugin) Filter(pc *framework.PluginContext, pod *v1.Pod, nodeName string) *framework.Status {
|
||||||
atomic.AddInt32(&fp.numFilterCalled, 1)
|
atomic.AddInt32(&fp.numFilterCalled, 1)
|
||||||
|
|
||||||
if fp.returnCode == framework.Success {
|
if returnCode, ok := fp.failedNodeReturnCodeMap[nodeName]; ok {
|
||||||
return nil
|
return framework.NewStatus(returnCode, fmt.Sprintf("injecting failure for pod %v", pod.Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
return framework.NewStatus(fp.returnCode, fmt.Sprintf("injecting failure for pod %v", pod.Name))
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// newPlugin returns a plugin factory with specified Plugin.
|
// newPlugin returns a plugin factory with specified Plugin.
|
||||||
@ -274,25 +274,23 @@ func TestGenericScheduler(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
predicates map[string]algorithmpredicates.FitPredicate
|
predicates map[string]algorithmpredicates.FitPredicate
|
||||||
prioritizers []priorities.PriorityConfig
|
prioritizers []priorities.PriorityConfig
|
||||||
alwaysCheckAllPredicates bool
|
alwaysCheckAllPredicates bool
|
||||||
nodes []string
|
nodes []string
|
||||||
pvcs []*v1.PersistentVolumeClaim
|
pvcs []*v1.PersistentVolumeClaim
|
||||||
pod *v1.Pod
|
pod *v1.Pod
|
||||||
pods []*v1.Pod
|
pods []*v1.Pod
|
||||||
buildPredMeta bool // build predicates metadata or not
|
buildPredMeta bool // build predicates metadata or not
|
||||||
filterReturnCode framework.Code
|
filterFailedNodeReturnCodeMap map[string]framework.Code
|
||||||
expectedHosts sets.String
|
expectedHosts sets.String
|
||||||
expectsErr bool
|
wErr error
|
||||||
wErr error
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
predicates: map[string]algorithmpredicates.FitPredicate{"false": falsePredicate},
|
predicates: map[string]algorithmpredicates.FitPredicate{"false": falsePredicate},
|
||||||
prioritizers: []priorities.PriorityConfig{{Map: EqualPriorityMap, Weight: 1}},
|
prioritizers: []priorities.PriorityConfig{{Map: EqualPriorityMap, Weight: 1}},
|
||||||
nodes: []string{"machine1", "machine2"},
|
nodes: []string{"machine1", "machine2"},
|
||||||
expectsErr: true,
|
|
||||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "2", UID: types.UID("2")}},
|
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "2", UID: types.UID("2")}},
|
||||||
name: "test 1",
|
name: "test 1",
|
||||||
wErr: &FitError{
|
wErr: &FitError{
|
||||||
@ -356,7 +354,6 @@ func TestGenericScheduler(t *testing.T) {
|
|||||||
prioritizers: []priorities.PriorityConfig{{Function: numericPriority, Weight: 1}},
|
prioritizers: []priorities.PriorityConfig{{Function: numericPriority, Weight: 1}},
|
||||||
nodes: []string{"3", "2", "1"},
|
nodes: []string{"3", "2", "1"},
|
||||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "2", UID: types.UID("2")}},
|
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "2", UID: types.UID("2")}},
|
||||||
expectsErr: true,
|
|
||||||
name: "test 7",
|
name: "test 7",
|
||||||
wErr: &FitError{
|
wErr: &FitError{
|
||||||
Pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "2", UID: types.UID("2")}},
|
Pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "2", UID: types.UID("2")}},
|
||||||
@ -388,7 +385,6 @@ func TestGenericScheduler(t *testing.T) {
|
|||||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "2", UID: types.UID("2")}},
|
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "2", UID: types.UID("2")}},
|
||||||
prioritizers: []priorities.PriorityConfig{{Function: numericPriority, Weight: 1}},
|
prioritizers: []priorities.PriorityConfig{{Function: numericPriority, Weight: 1}},
|
||||||
nodes: []string{"1", "2"},
|
nodes: []string{"1", "2"},
|
||||||
expectsErr: true,
|
|
||||||
name: "test 8",
|
name: "test 8",
|
||||||
wErr: &FitError{
|
wErr: &FitError{
|
||||||
Pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "2", UID: types.UID("2")}},
|
Pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "2", UID: types.UID("2")}},
|
||||||
@ -443,9 +439,8 @@ func TestGenericScheduler(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
name: "unknown PVC",
|
name: "unknown PVC",
|
||||||
expectsErr: true,
|
wErr: fmt.Errorf("persistentvolumeclaim \"unknownPVC\" not found"),
|
||||||
wErr: fmt.Errorf("persistentvolumeclaim \"unknownPVC\" not found"),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Pod with deleting PVC
|
// Pod with deleting PVC
|
||||||
@ -467,9 +462,8 @@ func TestGenericScheduler(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
name: "deleted PVC",
|
name: "deleted PVC",
|
||||||
expectsErr: true,
|
wErr: fmt.Errorf("persistentvolumeclaim \"existingPVC\" is being deleted"),
|
||||||
wErr: fmt.Errorf("persistentvolumeclaim \"existingPVC\" is being deleted"),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// alwaysCheckAllPredicates is true
|
// alwaysCheckAllPredicates is true
|
||||||
@ -599,14 +593,13 @@ func TestGenericScheduler(t *testing.T) {
|
|||||||
wErr: nil,
|
wErr: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "test with filter plugin returning Unschedulable status",
|
name: "test with filter plugin returning Unschedulable status",
|
||||||
predicates: map[string]algorithmpredicates.FitPredicate{"true": truePredicate},
|
predicates: map[string]algorithmpredicates.FitPredicate{"true": truePredicate},
|
||||||
prioritizers: []priorities.PriorityConfig{{Function: numericPriority, Weight: 1}},
|
prioritizers: []priorities.PriorityConfig{{Function: numericPriority, Weight: 1}},
|
||||||
nodes: []string{"3"},
|
nodes: []string{"3"},
|
||||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
|
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
|
||||||
expectedHosts: nil,
|
expectedHosts: nil,
|
||||||
filterReturnCode: framework.Unschedulable,
|
filterFailedNodeReturnCodeMap: map[string]framework.Code{"3": framework.Unschedulable},
|
||||||
expectsErr: true,
|
|
||||||
wErr: &FitError{
|
wErr: &FitError{
|
||||||
Pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
|
Pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
|
||||||
NumAllNodes: 1,
|
NumAllNodes: 1,
|
||||||
@ -617,14 +610,13 @@ func TestGenericScheduler(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "test with filter plugin returning UnschedulableAndUnresolvable status",
|
name: "test with filter plugin returning UnschedulableAndUnresolvable status",
|
||||||
predicates: map[string]algorithmpredicates.FitPredicate{"true": truePredicate},
|
predicates: map[string]algorithmpredicates.FitPredicate{"true": truePredicate},
|
||||||
prioritizers: []priorities.PriorityConfig{{Function: numericPriority, Weight: 1}},
|
prioritizers: []priorities.PriorityConfig{{Function: numericPriority, Weight: 1}},
|
||||||
nodes: []string{"3"},
|
nodes: []string{"3"},
|
||||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
|
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
|
||||||
expectedHosts: nil,
|
expectedHosts: nil,
|
||||||
filterReturnCode: framework.UnschedulableAndUnresolvable,
|
filterFailedNodeReturnCodeMap: map[string]framework.Code{"3": framework.UnschedulableAndUnresolvable},
|
||||||
expectsErr: true,
|
|
||||||
wErr: &FitError{
|
wErr: &FitError{
|
||||||
Pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
|
Pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
|
||||||
NumAllNodes: 1,
|
NumAllNodes: 1,
|
||||||
@ -634,10 +626,20 @@ func TestGenericScheduler(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "test with partial failed filter plugin",
|
||||||
|
predicates: map[string]algorithmpredicates.FitPredicate{"true": truePredicate},
|
||||||
|
prioritizers: []priorities.PriorityConfig{{Function: numericPriority, Weight: 1}},
|
||||||
|
nodes: []string{"1", "2"},
|
||||||
|
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
|
||||||
|
expectedHosts: nil,
|
||||||
|
filterFailedNodeReturnCodeMap: map[string]framework.Code{"1": framework.Unschedulable},
|
||||||
|
wErr: nil,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
filterPlugin.returnCode = test.filterReturnCode
|
filterPlugin.failedNodeReturnCodeMap = test.filterFailedNodeReturnCodeMap
|
||||||
|
|
||||||
cache := internalcache.New(time.Duration(0), wait.NeverStop)
|
cache := internalcache.New(time.Duration(0), wait.NeverStop)
|
||||||
for _, pod := range test.pods {
|
for _, pod := range test.pods {
|
||||||
@ -678,6 +680,9 @@ func TestGenericScheduler(t *testing.T) {
|
|||||||
if test.expectedHosts != nil && !test.expectedHosts.Has(result.SuggestedHost) {
|
if test.expectedHosts != nil && !test.expectedHosts.Has(result.SuggestedHost) {
|
||||||
t.Errorf("Expected: %s, got: %s", test.expectedHosts, result.SuggestedHost)
|
t.Errorf("Expected: %s, got: %s", test.expectedHosts, result.SuggestedHost)
|
||||||
}
|
}
|
||||||
|
if test.wErr == nil && len(test.nodes) != result.EvaluatedNodes {
|
||||||
|
t.Errorf("Expected EvaluatedNodes: %d, got: %d", len(test.nodes), result.EvaluatedNodes)
|
||||||
|
}
|
||||||
|
|
||||||
filterPlugin.reset()
|
filterPlugin.reset()
|
||||||
})
|
})
|
||||||
@ -1366,17 +1371,19 @@ func TestSelectNodesForPreemption(t *testing.T) {
|
|||||||
labelKeys := []string{"hostname", "zone", "region"}
|
labelKeys := []string{"hostname", "zone", "region"}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
filterFailedNodeReturnCodeMap := map[string]framework.Code{}
|
||||||
cache := internalcache.New(time.Duration(0), wait.NeverStop)
|
cache := internalcache.New(time.Duration(0), wait.NeverStop)
|
||||||
for _, pod := range test.pods {
|
for _, pod := range test.pods {
|
||||||
cache.AddPod(pod)
|
cache.AddPod(pod)
|
||||||
}
|
}
|
||||||
for _, name := range test.nodes {
|
for _, name := range test.nodes {
|
||||||
|
filterFailedNodeReturnCodeMap[name] = test.filterReturnCode
|
||||||
cache.AddNode(&v1.Node{ObjectMeta: metav1.ObjectMeta{Name: name, Labels: map[string]string{"hostname": name}}})
|
cache.AddNode(&v1.Node{ObjectMeta: metav1.ObjectMeta{Name: name, Labels: map[string]string{"hostname": name}}})
|
||||||
}
|
}
|
||||||
|
|
||||||
predMetaProducer := algorithmpredicates.EmptyPredicateMetadataProducer
|
predMetaProducer := algorithmpredicates.EmptyPredicateMetadataProducer
|
||||||
|
|
||||||
filterPlugin.returnCode = test.filterReturnCode
|
filterPlugin.failedNodeReturnCodeMap = filterFailedNodeReturnCodeMap
|
||||||
scheduler := NewGenericScheduler(
|
scheduler := NewGenericScheduler(
|
||||||
nil,
|
nil,
|
||||||
internalqueue.NewSchedulingQueue(nil, nil),
|
internalqueue.NewSchedulingQueue(nil, nil),
|
||||||
|
Loading…
Reference in New Issue
Block a user