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))
return ScheduleResult{
SuggestedHost: filteredNodes[0].Name,
EvaluatedNodes: 1 + len(failedPredicateMap),
EvaluatedNodes: 1 + len(failedPredicateMap) + len(filteredNodesStatuses),
FeasibleNodes: 1,
}, nil
}
@ -263,7 +263,7 @@ func (g *genericScheduler) Schedule(pod *v1.Pod, pluginContext *framework.Plugin
trace.Step("Selecting host done")
return ScheduleResult{
SuggestedHost: host,
EvaluatedNodes: len(filteredNodes) + len(failedPredicateMap),
EvaluatedNodes: len(filteredNodes) + len(failedPredicateMap) + len(filteredNodesStatuses),
FeasibleNodes: len(filteredNodes),
}, err
}

View File

@ -143,8 +143,8 @@ var emptyFramework, _ = framework.NewFramework(EmptyPluginRegistry, nil, []sched
// FakeFilterPlugin is a test filter plugin used by default scheduler.
type FakeFilterPlugin struct {
numFilterCalled int32
returnCode framework.Code
numFilterCalled int32
failedNodeReturnCodeMap map[string]framework.Code
}
// Name returns name of the plugin.
@ -155,19 +155,19 @@ func (fp *FakeFilterPlugin) Name() string {
// reset is used to reset filter plugin.
func (fp *FakeFilterPlugin) reset() {
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
// value of "failFilter".
// value of "failedNodeReturnCodeMap".
func (fp *FakeFilterPlugin) Filter(pc *framework.PluginContext, pod *v1.Pod, nodeName string) *framework.Status {
atomic.AddInt32(&fp.numFilterCalled, 1)
if fp.returnCode == framework.Success {
return nil
if returnCode, ok := fp.failedNodeReturnCodeMap[nodeName]; ok {
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.
@ -274,25 +274,23 @@ func TestGenericScheduler(t *testing.T) {
}
tests := []struct {
name string
predicates map[string]algorithmpredicates.FitPredicate
prioritizers []priorities.PriorityConfig
alwaysCheckAllPredicates bool
nodes []string
pvcs []*v1.PersistentVolumeClaim
pod *v1.Pod
pods []*v1.Pod
buildPredMeta bool // build predicates metadata or not
filterReturnCode framework.Code
expectedHosts sets.String
expectsErr bool
wErr error
name string
predicates map[string]algorithmpredicates.FitPredicate
prioritizers []priorities.PriorityConfig
alwaysCheckAllPredicates bool
nodes []string
pvcs []*v1.PersistentVolumeClaim
pod *v1.Pod
pods []*v1.Pod
buildPredMeta bool // build predicates metadata or not
filterFailedNodeReturnCodeMap map[string]framework.Code
expectedHosts sets.String
wErr error
}{
{
predicates: map[string]algorithmpredicates.FitPredicate{"false": falsePredicate},
prioritizers: []priorities.PriorityConfig{{Map: EqualPriorityMap, Weight: 1}},
nodes: []string{"machine1", "machine2"},
expectsErr: true,
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "2", UID: types.UID("2")}},
name: "test 1",
wErr: &FitError{
@ -356,7 +354,6 @@ func TestGenericScheduler(t *testing.T) {
prioritizers: []priorities.PriorityConfig{{Function: numericPriority, Weight: 1}},
nodes: []string{"3", "2", "1"},
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "2", UID: types.UID("2")}},
expectsErr: true,
name: "test 7",
wErr: &FitError{
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")}},
prioritizers: []priorities.PriorityConfig{{Function: numericPriority, Weight: 1}},
nodes: []string{"1", "2"},
expectsErr: true,
name: "test 8",
wErr: &FitError{
Pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "2", UID: types.UID("2")}},
@ -443,9 +439,8 @@ func TestGenericScheduler(t *testing.T) {
},
},
},
name: "unknown PVC",
expectsErr: true,
wErr: fmt.Errorf("persistentvolumeclaim \"unknownPVC\" not found"),
name: "unknown PVC",
wErr: fmt.Errorf("persistentvolumeclaim \"unknownPVC\" not found"),
},
{
// Pod with deleting PVC
@ -467,9 +462,8 @@ func TestGenericScheduler(t *testing.T) {
},
},
},
name: "deleted PVC",
expectsErr: true,
wErr: fmt.Errorf("persistentvolumeclaim \"existingPVC\" is being deleted"),
name: "deleted PVC",
wErr: fmt.Errorf("persistentvolumeclaim \"existingPVC\" is being deleted"),
},
{
// alwaysCheckAllPredicates is true
@ -599,14 +593,13 @@ func TestGenericScheduler(t *testing.T) {
wErr: nil,
},
{
name: "test with filter plugin returning Unschedulable status",
predicates: map[string]algorithmpredicates.FitPredicate{"true": truePredicate},
prioritizers: []priorities.PriorityConfig{{Function: numericPriority, Weight: 1}},
nodes: []string{"3"},
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
expectedHosts: nil,
filterReturnCode: framework.Unschedulable,
expectsErr: true,
name: "test with filter plugin returning Unschedulable status",
predicates: map[string]algorithmpredicates.FitPredicate{"true": truePredicate},
prioritizers: []priorities.PriorityConfig{{Function: numericPriority, Weight: 1}},
nodes: []string{"3"},
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
expectedHosts: nil,
filterFailedNodeReturnCodeMap: map[string]framework.Code{"3": framework.Unschedulable},
wErr: &FitError{
Pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
NumAllNodes: 1,
@ -617,14 +610,13 @@ func TestGenericScheduler(t *testing.T) {
},
},
{
name: "test with filter plugin returning UnschedulableAndUnresolvable status",
predicates: map[string]algorithmpredicates.FitPredicate{"true": truePredicate},
prioritizers: []priorities.PriorityConfig{{Function: numericPriority, Weight: 1}},
nodes: []string{"3"},
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
expectedHosts: nil,
filterReturnCode: framework.UnschedulableAndUnresolvable,
expectsErr: true,
name: "test with filter plugin returning UnschedulableAndUnresolvable status",
predicates: map[string]algorithmpredicates.FitPredicate{"true": truePredicate},
prioritizers: []priorities.PriorityConfig{{Function: numericPriority, Weight: 1}},
nodes: []string{"3"},
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
expectedHosts: nil,
filterFailedNodeReturnCodeMap: map[string]framework.Code{"3": framework.UnschedulableAndUnresolvable},
wErr: &FitError{
Pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-filter", UID: types.UID("test-filter")}},
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 {
t.Run(test.name, func(t *testing.T) {
filterPlugin.returnCode = test.filterReturnCode
filterPlugin.failedNodeReturnCodeMap = test.filterFailedNodeReturnCodeMap
cache := internalcache.New(time.Duration(0), wait.NeverStop)
for _, pod := range test.pods {
@ -678,6 +680,9 @@ func TestGenericScheduler(t *testing.T) {
if test.expectedHosts != nil && !test.expectedHosts.Has(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()
})
@ -1366,17 +1371,19 @@ func TestSelectNodesForPreemption(t *testing.T) {
labelKeys := []string{"hostname", "zone", "region"}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
filterFailedNodeReturnCodeMap := map[string]framework.Code{}
cache := internalcache.New(time.Duration(0), wait.NeverStop)
for _, pod := range test.pods {
cache.AddPod(pod)
}
for _, name := range test.nodes {
filterFailedNodeReturnCodeMap[name] = test.filterReturnCode
cache.AddNode(&v1.Node{ObjectMeta: metav1.ObjectMeta{Name: name, Labels: map[string]string{"hostname": name}}})
}
predMetaProducer := algorithmpredicates.EmptyPredicateMetadataProducer
filterPlugin.returnCode = test.filterReturnCode
filterPlugin.failedNodeReturnCodeMap = filterFailedNodeReturnCodeMap
scheduler := NewGenericScheduler(
nil,
internalqueue.NewSchedulingQueue(nil, nil),