diff --git a/pkg/scheduler/framework/interface.go b/pkg/scheduler/framework/interface.go index 00a14ad1a39..10c2776ddb6 100644 --- a/pkg/scheduler/framework/interface.go +++ b/pkg/scheduler/framework/interface.go @@ -250,6 +250,9 @@ func NewStatus(code Code, reasons ...string) *Status { // AsStatus wraps an error in a Status. func AsStatus(err error) *Status { + if err == nil { + return nil + } return &Status{ code: Error, reasons: []string{err.Error()}, diff --git a/pkg/scheduler/framework/plugins/interpodaffinity/scoring.go b/pkg/scheduler/framework/plugins/interpodaffinity/scoring.go index 238691bd46f..fce624b3bb1 100644 --- a/pkg/scheduler/framework/plugins/interpodaffinity/scoring.go +++ b/pkg/scheduler/framework/plugins/interpodaffinity/scoring.go @@ -22,7 +22,7 @@ import ( "math" "sync/atomic" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/kubernetes/pkg/scheduler/framework" ) diff --git a/pkg/scheduler/framework/runtime/framework.go b/pkg/scheduler/framework/runtime/framework.go index 286fd45c006..7c11ba6522b 100644 --- a/pkg/scheduler/framework/runtime/framework.go +++ b/pkg/scheduler/framework/runtime/framework.go @@ -1003,8 +1003,13 @@ func (f *frameworkImpl) RunPreBindPlugins(ctx context.Context, state *framework. for _, pl := range f.preBindPlugins { status = f.runPreBindPlugin(ctx, pl, state, pod, nodeName) if !status.IsSuccess() { + if status.IsUnschedulable() { + klog.V(4).InfoS("Pod rejected by PreBind plugin", "pod", klog.KObj(pod), "node", nodeName, "plugin", pl.Name(), "status", status.Message()) + status.SetFailedPlugin(pl.Name()) + return status + } err := status.AsError() - klog.ErrorS(err, "Failed running PreBind plugin", "plugin", pl.Name(), "pod", klog.KObj(pod)) + klog.ErrorS(err, "Failed running PreBind plugin", "plugin", pl.Name(), "pod", klog.KObj(pod), "node", nodeName) return framework.AsStatus(fmt.Errorf("running PreBind plugin %q: %w", pl.Name(), err)) } } @@ -1030,15 +1035,20 @@ func (f *frameworkImpl) RunBindPlugins(ctx context.Context, state *framework.Cyc if len(f.bindPlugins) == 0 { return framework.NewStatus(framework.Skip, "") } - for _, bp := range f.bindPlugins { - status = f.runBindPlugin(ctx, bp, state, pod, nodeName) + for _, pl := range f.bindPlugins { + status = f.runBindPlugin(ctx, pl, state, pod, nodeName) if status.IsSkip() { continue } if !status.IsSuccess() { + if status.IsUnschedulable() { + klog.V(4).InfoS("Pod rejected by Bind plugin", "pod", klog.KObj(pod), "node", nodeName, "plugin", pl.Name(), "status", status.Message()) + status.SetFailedPlugin(pl.Name()) + return status + } err := status.AsError() - klog.ErrorS(err, "Failed running Bind plugin", "plugin", bp.Name(), "pod", klog.KObj(pod)) - return framework.AsStatus(fmt.Errorf("running Bind plugin %q: %w", bp.Name(), err)) + klog.ErrorS(err, "Failed running Bind plugin", "plugin", pl.Name(), "pod", klog.KObj(pod), "node", nodeName) + return framework.AsStatus(fmt.Errorf("running Bind plugin %q: %w", pl.Name(), err)) } return status } diff --git a/pkg/scheduler/framework/runtime/framework_test.go b/pkg/scheduler/framework/runtime/framework_test.go index 868889f3820..31cdcc1e941 100644 --- a/pkg/scheduler/framework/runtime/framework_test.go +++ b/pkg/scheduler/framework/runtime/framework_test.go @@ -54,6 +54,9 @@ const ( testProfileName = "test-profile" nodeName = "testNode" + + injectReason = "injected status" + injectFilterReason = "injected filter status" ) // TestScoreWithNormalizePlugin implements ScoreWithNormalizePlugin interface. @@ -121,7 +124,7 @@ func (pl *TestScorePlugin) Name() string { } func (pl *TestScorePlugin) PreScore(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodes []*v1.Node) *framework.Status { - return framework.NewStatus(framework.Code(pl.inj.PreScoreStatus), "injected status") + return framework.NewStatus(framework.Code(pl.inj.PreScoreStatus), injectReason) } func (pl *TestScorePlugin) Score(ctx context.Context, state *framework.CycleState, p *v1.Pod, nodeName string) (int64, *framework.Status) { @@ -150,10 +153,10 @@ type TestPlugin struct { } func (pl *TestPlugin) AddPod(ctx context.Context, state *framework.CycleState, podToSchedule *v1.Pod, podInfoToAdd *framework.PodInfo, nodeInfo *framework.NodeInfo) *framework.Status { - return framework.NewStatus(framework.Code(pl.inj.PreFilterAddPodStatus), "injected status") + return framework.NewStatus(framework.Code(pl.inj.PreFilterAddPodStatus), injectReason) } func (pl *TestPlugin) RemovePod(ctx context.Context, state *framework.CycleState, podToSchedule *v1.Pod, podInfoToRemove *framework.PodInfo, nodeInfo *framework.NodeInfo) *framework.Status { - return framework.NewStatus(framework.Code(pl.inj.PreFilterRemovePodStatus), "injected status") + return framework.NewStatus(framework.Code(pl.inj.PreFilterRemovePodStatus), injectReason) } func (pl *TestPlugin) Name() string { @@ -165,7 +168,7 @@ func (pl *TestPlugin) Less(*framework.QueuedPodInfo, *framework.QueuedPodInfo) b } func (pl *TestPlugin) Score(ctx context.Context, state *framework.CycleState, p *v1.Pod, nodeName string) (int64, *framework.Status) { - return 0, framework.NewStatus(framework.Code(pl.inj.ScoreStatus), "injected status") + return 0, framework.NewStatus(framework.Code(pl.inj.ScoreStatus), injectReason) } func (pl *TestPlugin) ScoreExtensions() framework.ScoreExtensions { @@ -173,7 +176,7 @@ func (pl *TestPlugin) ScoreExtensions() framework.ScoreExtensions { } func (pl *TestPlugin) PreFilter(ctx context.Context, state *framework.CycleState, p *v1.Pod) (*framework.PreFilterResult, *framework.Status) { - return nil, framework.NewStatus(framework.Code(pl.inj.PreFilterStatus), "injected status") + return nil, framework.NewStatus(framework.Code(pl.inj.PreFilterStatus), injectReason) } func (pl *TestPlugin) PreFilterExtensions() framework.PreFilterExtensions { @@ -181,37 +184,37 @@ func (pl *TestPlugin) PreFilterExtensions() framework.PreFilterExtensions { } func (pl *TestPlugin) Filter(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status { - return framework.NewStatus(framework.Code(pl.inj.FilterStatus), "injected filter status") + return framework.NewStatus(framework.Code(pl.inj.FilterStatus), injectFilterReason) } func (pl *TestPlugin) PostFilter(_ context.Context, _ *framework.CycleState, _ *v1.Pod, _ framework.NodeToStatusMap) (*framework.PostFilterResult, *framework.Status) { - return nil, framework.NewStatus(framework.Code(pl.inj.PostFilterStatus), "injected status") + return nil, framework.NewStatus(framework.Code(pl.inj.PostFilterStatus), injectReason) } func (pl *TestPlugin) PreScore(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodes []*v1.Node) *framework.Status { - return framework.NewStatus(framework.Code(pl.inj.PreScoreStatus), "injected status") + return framework.NewStatus(framework.Code(pl.inj.PreScoreStatus), injectReason) } func (pl *TestPlugin) Reserve(ctx context.Context, state *framework.CycleState, p *v1.Pod, nodeName string) *framework.Status { - return framework.NewStatus(framework.Code(pl.inj.ReserveStatus), "injected status") + return framework.NewStatus(framework.Code(pl.inj.ReserveStatus), injectReason) } func (pl *TestPlugin) Unreserve(ctx context.Context, state *framework.CycleState, p *v1.Pod, nodeName string) { } func (pl *TestPlugin) PreBind(ctx context.Context, state *framework.CycleState, p *v1.Pod, nodeName string) *framework.Status { - return framework.NewStatus(framework.Code(pl.inj.PreBindStatus), "injected status") + return framework.NewStatus(framework.Code(pl.inj.PreBindStatus), injectReason) } func (pl *TestPlugin) PostBind(ctx context.Context, state *framework.CycleState, p *v1.Pod, nodeName string) { } func (pl *TestPlugin) Permit(ctx context.Context, state *framework.CycleState, p *v1.Pod, nodeName string) (*framework.Status, time.Duration) { - return framework.NewStatus(framework.Code(pl.inj.PermitStatus), "injected status"), time.Duration(0) + return framework.NewStatus(framework.Code(pl.inj.PermitStatus), injectReason), time.Duration(0) } func (pl *TestPlugin) Bind(ctx context.Context, state *framework.CycleState, p *v1.Pod, nodeName string) *framework.Status { - return framework.NewStatus(framework.Code(pl.inj.BindStatus), "injected status") + return framework.NewStatus(framework.Code(pl.inj.BindStatus), injectReason) } // TestPreFilterPlugin only implements PreFilterPlugin interface. @@ -374,8 +377,8 @@ var nodes = []*v1.Node{ } var ( - errInjectedStatus = errors.New("injected status") - errInjectedFilterStatus = errors.New("injected filter status") + errInjectedStatus = errors.New(injectReason) + errInjectedFilterStatus = errors.New(injectFilterReason) ) func newFrameworkWithQueueSortAndBind(r Registry, profile config.KubeSchedulerProfile, stopCh <-chan struct{}, opts ...Option) (framework.Framework, error) { @@ -1307,9 +1310,9 @@ func TestFilterPlugins(t *testing.T) { inj: injectedResult{FilterStatus: int(framework.Unschedulable)}, }, }, - wantStatus: framework.NewStatus(framework.Unschedulable, "injected filter status").WithFailedPlugin("TestPlugin"), + wantStatus: framework.NewStatus(framework.Unschedulable, injectFilterReason).WithFailedPlugin("TestPlugin"), wantStatusMap: framework.PluginToStatus{ - "TestPlugin": framework.NewStatus(framework.Unschedulable, "injected filter status").WithFailedPlugin("TestPlugin"), + "TestPlugin": framework.NewStatus(framework.Unschedulable, injectFilterReason).WithFailedPlugin("TestPlugin"), }, }, { @@ -1321,9 +1324,9 @@ func TestFilterPlugins(t *testing.T) { FilterStatus: int(framework.UnschedulableAndUnresolvable)}, }, }, - wantStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, "injected filter status").WithFailedPlugin("TestPlugin"), + wantStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, injectFilterReason).WithFailedPlugin("TestPlugin"), wantStatusMap: framework.PluginToStatus{ - "TestPlugin": framework.NewStatus(framework.UnschedulableAndUnresolvable, "injected filter status").WithFailedPlugin("TestPlugin"), + "TestPlugin": framework.NewStatus(framework.UnschedulableAndUnresolvable, injectFilterReason).WithFailedPlugin("TestPlugin"), }, }, // following tests cover multiple-plugins scenarios @@ -1409,9 +1412,9 @@ func TestFilterPlugins(t *testing.T) { inj: injectedResult{FilterStatus: int(framework.Unschedulable)}, }, }, - wantStatus: framework.NewStatus(framework.Unschedulable, "injected filter status").WithFailedPlugin("TestPlugin2"), + wantStatus: framework.NewStatus(framework.Unschedulable, injectFilterReason).WithFailedPlugin("TestPlugin2"), wantStatusMap: framework.PluginToStatus{ - "TestPlugin2": framework.NewStatus(framework.Unschedulable, "injected filter status").WithFailedPlugin("TestPlugin2"), + "TestPlugin2": framework.NewStatus(framework.Unschedulable, injectFilterReason).WithFailedPlugin("TestPlugin2"), }, }, } @@ -1467,7 +1470,7 @@ func TestPostFilterPlugins(t *testing.T) { inj: injectedResult{PostFilterStatus: int(framework.Success)}, }, }, - wantStatus: framework.NewStatus(framework.Success, "injected status"), + wantStatus: framework.NewStatus(framework.Success, injectReason), }, { name: "plugin1 failed to make a Pod schedulable, followed by plugin2 which makes the Pod schedulable", @@ -1481,7 +1484,7 @@ func TestPostFilterPlugins(t *testing.T) { inj: injectedResult{PostFilterStatus: int(framework.Success)}, }, }, - wantStatus: framework.NewStatus(framework.Success, "injected status"), + wantStatus: framework.NewStatus(framework.Success, injectReason), }, { name: "plugin1 makes a Pod schedulable, followed by plugin2 which cannot make the Pod schedulable", @@ -1495,7 +1498,7 @@ func TestPostFilterPlugins(t *testing.T) { inj: injectedResult{PostFilterStatus: int(framework.Unschedulable)}, }, }, - wantStatus: framework.NewStatus(framework.Success, "injected status"), + wantStatus: framework.NewStatus(framework.Success, injectReason), }, } @@ -1712,7 +1715,7 @@ func TestPreBindPlugins(t *testing.T) { inj: injectedResult{PreBindStatus: int(framework.Unschedulable)}, }, }, - wantStatus: framework.AsStatus(fmt.Errorf(`running PreBind plugin "TestPlugin": %w`, errInjectedStatus)), + wantStatus: framework.NewStatus(framework.Unschedulable, injectReason).WithFailedPlugin("TestPlugin"), }, { name: "ErrorPreBindPlugin", @@ -1732,7 +1735,7 @@ func TestPreBindPlugins(t *testing.T) { inj: injectedResult{PreBindStatus: int(framework.UnschedulableAndUnresolvable)}, }, }, - wantStatus: framework.AsStatus(fmt.Errorf(`running PreBind plugin "TestPlugin": %w`, errInjectedStatus)), + wantStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, injectReason).WithFailedPlugin("TestPlugin"), }, { name: "SuccessErrorPreBindPlugins", @@ -1802,7 +1805,7 @@ func TestPreBindPlugins(t *testing.T) { inj: injectedResult{PreBindStatus: int(framework.Success)}, }, }, - wantStatus: framework.AsStatus(fmt.Errorf(`running PreBind plugin "TestPlugin": %w`, errInjectedStatus)), + wantStatus: framework.NewStatus(framework.Unschedulable, injectReason).WithFailedPlugin("TestPlugin"), }, } @@ -2028,7 +2031,7 @@ func TestPermitPlugins(t *testing.T) { inj: injectedResult{PermitStatus: int(framework.Unschedulable)}, }, }, - want: framework.NewStatus(framework.Unschedulable, "injected status").WithFailedPlugin("TestPlugin"), + want: framework.NewStatus(framework.Unschedulable, injectReason).WithFailedPlugin("TestPlugin"), }, { name: "ErrorPermitPlugin", @@ -2048,7 +2051,7 @@ func TestPermitPlugins(t *testing.T) { inj: injectedResult{PermitStatus: int(framework.UnschedulableAndUnresolvable)}, }, }, - want: framework.NewStatus(framework.UnschedulableAndUnresolvable, "injected status").WithFailedPlugin("TestPlugin"), + want: framework.NewStatus(framework.UnschedulableAndUnresolvable, injectReason).WithFailedPlugin("TestPlugin"), }, { name: "WaitPermitPlugin", @@ -2341,7 +2344,7 @@ func TestRunBindPlugins(t *testing.T) { { name: "invalid status", injects: []framework.Code{framework.Unschedulable}, - wantStatus: framework.Error, + wantStatus: framework.Unschedulable, }, { name: "simple error", @@ -2356,7 +2359,7 @@ func TestRunBindPlugins(t *testing.T) { { name: "invalid status, returns error", injects: []framework.Code{framework.Skip, framework.UnschedulableAndUnresolvable}, - wantStatus: framework.Error, + wantStatus: framework.UnschedulableAndUnresolvable, }, { name: "error after success status, returns success", diff --git a/pkg/scheduler/schedule_one.go b/pkg/scheduler/schedule_one.go index 338bb94f37c..e270204b3c4 100644 --- a/pkg/scheduler/schedule_one.go +++ b/pkg/scheduler/schedule_one.go @@ -239,9 +239,13 @@ func (sched *Scheduler) bindingCycle(ctx context.Context, state *framework.Cycle // Avoid moving the assumed Pod itself as it's always Unschedulable. // It's intentional to "defer" this operation; otherwise MoveAllToActiveOrBackoffQueue() would // update `q.moveRequest` and thus move the assumed pod to backoffQ anyways. - defer sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(internalqueue.AssignedPodDelete, func(pod *v1.Pod) bool { - return assumedPod.UID != pod.UID - }) + if waitOnPermitStatus.IsUnschedulable() { + defer sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(internalqueue.AssignedPodDelete, func(pod *v1.Pod) bool { + return assumedPod.UID != pod.UID + }) + } else { + sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(internalqueue.AssignedPodDelete, nil) + } } sched.FailureHandler(ctx, fwk, assumedPodInfo, waitOnPermitStatus.AsError(), reason, clearNominatedNode) return @@ -250,7 +254,15 @@ func (sched *Scheduler) bindingCycle(ctx context.Context, state *framework.Cycle // Run "prebind" plugins. preBindStatus := fwk.RunPreBindPlugins(ctx, state, assumedPod, scheduleResult.SuggestedHost) if !preBindStatus.IsSuccess() { - metrics.PodScheduleError(fwk.ProfileName(), metrics.SinceInSeconds(start)) + var reason string + if preBindStatus.IsUnschedulable() { + metrics.PodUnschedulable(fwk.ProfileName(), metrics.SinceInSeconds(start)) + reason = v1.PodReasonUnschedulable + } else { + metrics.PodScheduleError(fwk.ProfileName(), metrics.SinceInSeconds(start)) + reason = v1.PodReasonSchedulerError + } + // trigger un-reserve plugins to clean up state associated with the reserved Pod fwk.RunReservePluginsUnreserve(ctx, state, assumedPod, scheduleResult.SuggestedHost) if forgetErr := sched.Cache.ForgetPod(assumedPod); forgetErr != nil { @@ -259,15 +271,29 @@ func (sched *Scheduler) bindingCycle(ctx context.Context, state *framework.Cycle // "Forget"ing an assumed Pod in binding cycle should be treated as a PodDelete event, // as the assumed Pod had occupied a certain amount of resources in scheduler cache. // TODO(#103853): de-duplicate the logic. - sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(internalqueue.AssignedPodDelete, nil) + if preBindStatus.IsUnschedulable() { + defer sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(internalqueue.AssignedPodDelete, func(pod *v1.Pod) bool { + return assumedPod.UID != pod.UID + }) + } else { + sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(internalqueue.AssignedPodDelete, nil) + } } - sched.FailureHandler(ctx, fwk, assumedPodInfo, preBindStatus.AsError(), v1.PodReasonSchedulerError, clearNominatedNode) + sched.FailureHandler(ctx, fwk, assumedPodInfo, preBindStatus.AsError(), reason, clearNominatedNode) return } - err := sched.bind(ctx, fwk, assumedPod, scheduleResult.SuggestedHost, state) - if err != nil { - metrics.PodScheduleError(fwk.ProfileName(), metrics.SinceInSeconds(start)) + bindStatus := sched.bind(ctx, fwk, assumedPod, scheduleResult.SuggestedHost, state) + if !bindStatus.IsSuccess() { + var reason string + if bindStatus.IsUnschedulable() { + metrics.PodUnschedulable(fwk.ProfileName(), metrics.SinceInSeconds(start)) + reason = v1.PodReasonUnschedulable + } else { + metrics.PodScheduleError(fwk.ProfileName(), metrics.SinceInSeconds(start)) + reason = v1.PodReasonSchedulerError + } + // trigger un-reserve plugins to clean up state associated with the reserved Pod fwk.RunReservePluginsUnreserve(ctx, state, assumedPod, scheduleResult.SuggestedHost) if err := sched.Cache.ForgetPod(assumedPod); err != nil { @@ -276,9 +302,15 @@ func (sched *Scheduler) bindingCycle(ctx context.Context, state *framework.Cycle // "Forget"ing an assumed Pod in binding cycle should be treated as a PodDelete event, // as the assumed Pod had occupied a certain amount of resources in scheduler cache. // TODO(#103853): de-duplicate the logic. - sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(internalqueue.AssignedPodDelete, nil) + if bindStatus.IsUnschedulable() { + defer sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(internalqueue.AssignedPodDelete, func(pod *v1.Pod) bool { + return assumedPod.UID != pod.UID + }) + } else { + sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(internalqueue.AssignedPodDelete, nil) + } } - sched.FailureHandler(ctx, fwk, assumedPodInfo, fmt.Errorf("binding rejected: %w", err), v1.PodReasonSchedulerError, clearNominatedNode) + sched.FailureHandler(ctx, fwk, assumedPodInfo, fmt.Errorf("binding rejected: %w", bindStatus.AsError()), reason, clearNominatedNode) return } // Calculating nodeResourceString can be heavy. Avoid it if klog verbosity is below 2. @@ -773,23 +805,16 @@ func (sched *Scheduler) assume(assumed *v1.Pod, host string) error { // bind binds a pod to a given node defined in a binding object. // The precedence for binding is: (1) extenders and (2) framework plugins. // We expect this to run asynchronously, so we handle binding metrics internally. -func (sched *Scheduler) bind(ctx context.Context, fwk framework.Framework, assumed *v1.Pod, targetNode string, state *framework.CycleState) (err error) { +func (sched *Scheduler) bind(ctx context.Context, fwk framework.Framework, assumed *v1.Pod, targetNode string, state *framework.CycleState) (status *framework.Status) { defer func() { - sched.finishBinding(fwk, assumed, targetNode, err) + sched.finishBinding(fwk, assumed, targetNode, status) }() bound, err := sched.extendersBinding(assumed, targetNode) if bound { - return err + return framework.AsStatus(err) } - bindStatus := fwk.RunBindPlugins(ctx, state, assumed, targetNode) - if bindStatus.IsSuccess() { - return nil - } - if bindStatus.Code() == framework.Error { - return bindStatus.AsError() - } - return fmt.Errorf("bind status: %s, %v", bindStatus.Code().String(), bindStatus.Message()) + return fwk.RunBindPlugins(ctx, state, assumed, targetNode) } // TODO(#87159): Move this to a Plugin. @@ -806,11 +831,11 @@ func (sched *Scheduler) extendersBinding(pod *v1.Pod, node string) (bool, error) return false, nil } -func (sched *Scheduler) finishBinding(fwk framework.Framework, assumed *v1.Pod, targetNode string, err error) { +func (sched *Scheduler) finishBinding(fwk framework.Framework, assumed *v1.Pod, targetNode string, status *framework.Status) { if finErr := sched.Cache.FinishBinding(assumed); finErr != nil { klog.ErrorS(finErr, "Scheduler cache FinishBinding failed") } - if err != nil { + if !status.IsSuccess() { klog.V(1).InfoS("Failed to bind pod", "pod", klog.KObj(assumed)) return } diff --git a/pkg/scheduler/schedule_one_test.go b/pkg/scheduler/schedule_one_test.go index 4af56210492..dc11fd75c35 100644 --- a/pkg/scheduler/schedule_one_test.go +++ b/pkg/scheduler/schedule_one_test.go @@ -1061,9 +1061,9 @@ func TestSchedulerBinding(t *testing.T) { nodeInfoSnapshot: nil, percentageOfNodesToScore: 0, } - err = sched.bind(ctx, fwk, pod, "node", nil) - if err != nil { - t.Error(err) + status := sched.bind(ctx, fwk, pod, "node", nil) + if !status.IsSuccess() { + t.Error(status.AsError()) } // Checking default binding. diff --git a/test/integration/scheduler/plugins/plugins_test.go b/test/integration/scheduler/plugins/plugins_test.go index e0fbd31b8d1..80e6865c8af 100644 --- a/test/integration/scheduler/plugins/plugins_test.go +++ b/test/integration/scheduler/plugins/plugins_test.go @@ -988,12 +988,6 @@ func TestPrebindPlugin(t *testing.T) { reject: false, succeedOnRetry: true, }, - { - name: "reject on 1st try but succeed on retry", - fail: false, - reject: true, - succeedOnRetry: true, - }, { name: "failure on preBind moves unschedulable pods", fail: true, @@ -1022,7 +1016,7 @@ func TestPrebindPlugin(t *testing.T) { t.Errorf("Error while creating a test pod: %v", err) } - if test.fail || test.reject { + if test.fail { if test.succeedOnRetry { if err = testutils.WaitForPodToScheduleWithTimeout(testCtx.ClientSet, pod, 10*time.Second); err != nil { t.Errorf("Expected the pod to be schedulable on retry, but got an error: %v", err) @@ -1030,6 +1024,10 @@ func TestPrebindPlugin(t *testing.T) { } else if err = wait.Poll(10*time.Millisecond, 30*time.Second, podSchedulingError(testCtx.ClientSet, pod.Namespace, pod.Name)); err != nil { t.Errorf("Expected a scheduling error, but didn't get it. error: %v", err) } + } else if test.reject { + if err = testutils.WaitForPodUnschedulable(testCtx.ClientSet, pod); err != nil { + t.Errorf("Expected the pod to be unschedulable") + } } else if err = testutils.WaitForPodToSchedule(testCtx.ClientSet, pod); err != nil { t.Errorf("Expected the pod to be scheduled. error: %v", err) } @@ -1212,27 +1210,27 @@ func TestUnReservePermitPlugins(t *testing.T) { tests := []struct { name string plugin *PermitPlugin - fail bool + reject bool }{ { - name: "All Reserve plugins passed, but a Permit plugin was rejected", - fail: true, + name: "All Reserve plugins passed, but a Permit plugin was rejected", + reject: true, plugin: &PermitPlugin{ name: "rejectedPermitPlugin", rejectPermit: true, }, }, { - name: "All Reserve plugins passed, but a Permit plugin timeout in waiting", - fail: true, + name: "All Reserve plugins passed, but a Permit plugin timeout in waiting", + reject: true, plugin: &PermitPlugin{ name: "timeoutPermitPlugin", timeoutPermit: true, }, }, { - name: "The Permit plugin succeed", - fail: false, + name: "The Permit plugin succeed", + reject: false, plugin: &PermitPlugin{ name: "succeedPermitPlugin", }, @@ -1264,7 +1262,7 @@ func TestUnReservePermitPlugins(t *testing.T) { t.Errorf("Error while creating a test pod: %v", err) } - if test.fail { + if test.reject { if err = waitForPodUnschedulable(testCtx.ClientSet, pod); err != nil { t.Errorf("Didn't expect the pod to be scheduled. error: %v", err) } @@ -1296,22 +1294,22 @@ func TestUnReservePermitPlugins(t *testing.T) { // TestUnReservePreBindPlugins tests unreserve of Prebind plugins. func TestUnReservePreBindPlugins(t *testing.T) { tests := []struct { - name string - plugin *PreBindPlugin - fail bool + name string + plugin *PreBindPlugin + wantReject bool }{ { - name: "All Reserve plugins passed, but a PreBind plugin failed", - fail: true, + name: "All Reserve plugins passed, but a PreBind plugin failed", + wantReject: true, plugin: &PreBindPlugin{ podUIDs: make(map[types.UID]struct{}), rejectPreBind: true, }, }, { - name: "All Reserve plugins passed, and PreBind plugin succeed", - fail: false, - plugin: &PreBindPlugin{podUIDs: make(map[types.UID]struct{})}, + name: "All Reserve plugins passed, and PreBind plugin succeed", + wantReject: false, + plugin: &PreBindPlugin{podUIDs: make(map[types.UID]struct{})}, }, } @@ -1340,8 +1338,8 @@ func TestUnReservePreBindPlugins(t *testing.T) { t.Errorf("Error while creating a test pod: %v", err) } - if test.fail { - if err = wait.Poll(10*time.Millisecond, 30*time.Second, podSchedulingError(testCtx.ClientSet, pod.Namespace, pod.Name)); err != nil { + if test.wantReject { + if err = waitForPodUnschedulable(testCtx.ClientSet, pod); err != nil { t.Errorf("Expected a reasons other than Unschedulable, but got: %v", err) }