Merge pull request #82156 from mrkm4ntr/fix-evaluated-nodes

Fix EvaluatedNodes in ScheduleResult
This commit is contained in:
Kubernetes Prow Robot 2019-09-11 22:52:39 -07:00 committed by GitHub
commit 96201b5e57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 49 deletions

View File

@ -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
} }

View File

@ -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),