mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Merge pull request #114125 from sanposhiho/skip-reimplementation
feature(scheduler): won't run Filter if PreFilter returned a Skip status
This commit is contained in:
		@@ -19,6 +19,8 @@ package framework
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"k8s.io/apimachinery/pkg/util/sets"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
@@ -48,6 +50,8 @@ type CycleState struct {
 | 
				
			|||||||
	storage sync.Map
 | 
						storage sync.Map
 | 
				
			||||||
	// if recordPluginMetrics is true, PluginExecutionDuration will be recorded for this cycle.
 | 
						// if recordPluginMetrics is true, PluginExecutionDuration will be recorded for this cycle.
 | 
				
			||||||
	recordPluginMetrics bool
 | 
						recordPluginMetrics bool
 | 
				
			||||||
 | 
						// SkipFilterPlugins are plugins that will be skipped in the Filter extension point.
 | 
				
			||||||
 | 
						SkipFilterPlugins sets.Set[string]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewCycleState initializes a new CycleState and returns its pointer.
 | 
					// NewCycleState initializes a new CycleState and returns its pointer.
 | 
				
			||||||
@@ -83,6 +87,7 @@ func (c *CycleState) Clone() *CycleState {
 | 
				
			|||||||
		return true
 | 
							return true
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	copy.recordPluginMetrics = c.recordPluginMetrics
 | 
						copy.recordPluginMetrics = c.recordPluginMetrics
 | 
				
			||||||
 | 
						copy.SkipFilterPlugins = c.SkipFilterPlugins
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return copy
 | 
						return copy
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -91,7 +91,9 @@ const (
 | 
				
			|||||||
	UnschedulableAndUnresolvable
 | 
						UnschedulableAndUnresolvable
 | 
				
			||||||
	// Wait is used when a Permit plugin finds a pod scheduling should wait.
 | 
						// Wait is used when a Permit plugin finds a pod scheduling should wait.
 | 
				
			||||||
	Wait
 | 
						Wait
 | 
				
			||||||
	// Skip is used when a Bind plugin chooses to skip binding.
 | 
						// Skip is used in the following scenarios:
 | 
				
			||||||
 | 
						// - when a Bind plugin chooses to skip binding.
 | 
				
			||||||
 | 
						// - when a PreFilter plugin returns Skip so that coupled Filter plugin/PreFilterExtensions() will be skipped.
 | 
				
			||||||
	Skip
 | 
						Skip
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -348,6 +350,8 @@ type PreFilterPlugin interface {
 | 
				
			|||||||
	// plugins must return success or the pod will be rejected. PreFilter could optionally
 | 
						// plugins must return success or the pod will be rejected. PreFilter could optionally
 | 
				
			||||||
	// return a PreFilterResult to influence which nodes to evaluate downstream. This is useful
 | 
						// return a PreFilterResult to influence which nodes to evaluate downstream. This is useful
 | 
				
			||||||
	// for cases where it is possible to determine the subset of nodes to process in O(1) time.
 | 
						// for cases where it is possible to determine the subset of nodes to process in O(1) time.
 | 
				
			||||||
 | 
						// When it returns Skip status, returned PreFilterResult and other fields in status are just ignored,
 | 
				
			||||||
 | 
						// and coupled Filter plugin/PreFilterExtensions() will be skipped in this scheduling cycle.
 | 
				
			||||||
	PreFilter(ctx context.Context, state *CycleState, p *v1.Pod) (*PreFilterResult, *Status)
 | 
						PreFilter(ctx context.Context, state *CycleState, p *v1.Pod) (*PreFilterResult, *Status)
 | 
				
			||||||
	// PreFilterExtensions returns a PreFilterExtensions interface if the plugin implements one,
 | 
						// PreFilterExtensions returns a PreFilterExtensions interface if the plugin implements one,
 | 
				
			||||||
	// or nil if it does not. A Pre-filter plugin can provide extensions to incrementally
 | 
						// or nil if it does not. A Pre-filter plugin can provide extensions to incrementally
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,7 +20,7 @@ import (
 | 
				
			|||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"k8s.io/api/core/v1"
 | 
						v1 "k8s.io/api/core/v1"
 | 
				
			||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
						"k8s.io/apimachinery/pkg/runtime"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/sets"
 | 
						"k8s.io/apimachinery/pkg/util/sets"
 | 
				
			||||||
@@ -89,13 +89,19 @@ func (pl *NodeAffinity) EventsToRegister() []framework.ClusterEvent {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// PreFilter builds and writes cycle state used by Filter.
 | 
					// PreFilter builds and writes cycle state used by Filter.
 | 
				
			||||||
func (pl *NodeAffinity) PreFilter(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod) (*framework.PreFilterResult, *framework.Status) {
 | 
					func (pl *NodeAffinity) PreFilter(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod) (*framework.PreFilterResult, *framework.Status) {
 | 
				
			||||||
 | 
						affinity := pod.Spec.Affinity
 | 
				
			||||||
 | 
						noNodeAffinity := (affinity == nil ||
 | 
				
			||||||
 | 
							affinity.NodeAffinity == nil ||
 | 
				
			||||||
 | 
							affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution == nil)
 | 
				
			||||||
 | 
						if noNodeAffinity && pl.addedNodeSelector == nil && pod.Spec.NodeSelector == nil {
 | 
				
			||||||
 | 
							// NodeAffinity Filter has nothing to do with the Pod.
 | 
				
			||||||
 | 
							return nil, framework.NewStatus(framework.Skip)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	state := &preFilterState{requiredNodeSelectorAndAffinity: nodeaffinity.GetRequiredNodeAffinity(pod)}
 | 
						state := &preFilterState{requiredNodeSelectorAndAffinity: nodeaffinity.GetRequiredNodeAffinity(pod)}
 | 
				
			||||||
	cycleState.Write(preFilterStateKey, state)
 | 
						cycleState.Write(preFilterStateKey, state)
 | 
				
			||||||
	affinity := pod.Spec.Affinity
 | 
					
 | 
				
			||||||
	if affinity == nil ||
 | 
						if noNodeAffinity || len(affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms) == 0 {
 | 
				
			||||||
		affinity.NodeAffinity == nil ||
 | 
					 | 
				
			||||||
		affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution == nil ||
 | 
					 | 
				
			||||||
		len(affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms) == 0 {
 | 
					 | 
				
			||||||
		return nil, nil
 | 
							return nil, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,10 +44,6 @@ func TestNodeAffinity(t *testing.T) {
 | 
				
			|||||||
		args                config.NodeAffinityArgs
 | 
							args                config.NodeAffinityArgs
 | 
				
			||||||
		disablePreFilter    bool
 | 
							disablePreFilter    bool
 | 
				
			||||||
	}{
 | 
						}{
 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			name: "no selector",
 | 
					 | 
				
			||||||
			pod:  &v1.Pod{},
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name: "missing labels",
 | 
								name: "missing labels",
 | 
				
			||||||
			pod: st.MakePod().NodeSelector(map[string]string{
 | 
								pod: st.MakePod().NodeSelector(map[string]string{
 | 
				
			||||||
@@ -285,6 +281,7 @@ func TestNodeAffinity(t *testing.T) {
 | 
				
			|||||||
			labels: map[string]string{
 | 
								labels: map[string]string{
 | 
				
			||||||
				"foo": "bar",
 | 
									"foo": "bar",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
 | 
								wantPreFilterStatus: framework.NewStatus(framework.Skip),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name: "Pod with Affinity but nil NodeSelector will schedule onto a node",
 | 
								name: "Pod with Affinity but nil NodeSelector will schedule onto a node",
 | 
				
			||||||
@@ -300,6 +297,7 @@ func TestNodeAffinity(t *testing.T) {
 | 
				
			|||||||
			labels: map[string]string{
 | 
								labels: map[string]string{
 | 
				
			||||||
				"foo": "bar",
 | 
									"foo": "bar",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
 | 
								wantPreFilterStatus: framework.NewStatus(framework.Skip),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name: "Pod with multiple matchExpressions ANDed that matches the existing node",
 | 
								name: "Pod with multiple matchExpressions ANDed that matches the existing node",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -599,8 +599,10 @@ func (f *frameworkImpl) QueueSortFunc() framework.LessFunc {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// RunPreFilterPlugins runs the set of configured PreFilter plugins. It returns
 | 
					// RunPreFilterPlugins runs the set of configured PreFilter plugins. It returns
 | 
				
			||||||
// *Status and its code is set to non-success if any of the plugins returns
 | 
					// *Status and its code is set to non-success if any of the plugins returns
 | 
				
			||||||
// anything but Success. If a non-success status is returned, then the scheduling
 | 
					// anything but Success/Skip.
 | 
				
			||||||
// cycle is aborted.
 | 
					// When it returns Skip status, returned PreFilterResult and other fields in status are just ignored,
 | 
				
			||||||
 | 
					// and coupled Filter plugin/PreFilterExtensions() will be skipped in this scheduling cycle.
 | 
				
			||||||
 | 
					// If a non-success status is returned, then the scheduling cycle is aborted.
 | 
				
			||||||
func (f *frameworkImpl) RunPreFilterPlugins(ctx context.Context, state *framework.CycleState, pod *v1.Pod) (_ *framework.PreFilterResult, status *framework.Status) {
 | 
					func (f *frameworkImpl) RunPreFilterPlugins(ctx context.Context, state *framework.CycleState, pod *v1.Pod) (_ *framework.PreFilterResult, status *framework.Status) {
 | 
				
			||||||
	startTime := time.Now()
 | 
						startTime := time.Now()
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
@@ -608,8 +610,13 @@ func (f *frameworkImpl) RunPreFilterPlugins(ctx context.Context, state *framewor
 | 
				
			|||||||
	}()
 | 
						}()
 | 
				
			||||||
	var result *framework.PreFilterResult
 | 
						var result *framework.PreFilterResult
 | 
				
			||||||
	var pluginsWithNodes []string
 | 
						var pluginsWithNodes []string
 | 
				
			||||||
 | 
						skipPlugins := sets.New[string]()
 | 
				
			||||||
	for _, pl := range f.preFilterPlugins {
 | 
						for _, pl := range f.preFilterPlugins {
 | 
				
			||||||
		r, s := f.runPreFilterPlugin(ctx, pl, state, pod)
 | 
							r, s := f.runPreFilterPlugin(ctx, pl, state, pod)
 | 
				
			||||||
 | 
							if s.IsSkip() {
 | 
				
			||||||
 | 
								skipPlugins.Insert(pl.Name())
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		if !s.IsSuccess() {
 | 
							if !s.IsSuccess() {
 | 
				
			||||||
			s.SetFailedPlugin(pl.Name())
 | 
								s.SetFailedPlugin(pl.Name())
 | 
				
			||||||
			if s.IsUnschedulable() {
 | 
								if s.IsUnschedulable() {
 | 
				
			||||||
@@ -628,8 +635,8 @@ func (f *frameworkImpl) RunPreFilterPlugins(ctx context.Context, state *framewor
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			return nil, framework.NewStatus(framework.Unschedulable, msg)
 | 
								return nil, framework.NewStatus(framework.Unschedulable, msg)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						state.SkipFilterPlugins = skipPlugins
 | 
				
			||||||
	return result, nil
 | 
						return result, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -654,7 +661,7 @@ func (f *frameworkImpl) RunPreFilterExtensionAddPod(
 | 
				
			|||||||
	nodeInfo *framework.NodeInfo,
 | 
						nodeInfo *framework.NodeInfo,
 | 
				
			||||||
) (status *framework.Status) {
 | 
					) (status *framework.Status) {
 | 
				
			||||||
	for _, pl := range f.preFilterPlugins {
 | 
						for _, pl := range f.preFilterPlugins {
 | 
				
			||||||
		if pl.PreFilterExtensions() == nil {
 | 
							if pl.PreFilterExtensions() == nil || state.SkipFilterPlugins.Has(pl.Name()) {
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		status = f.runPreFilterExtensionAddPod(ctx, pl, state, podToSchedule, podInfoToAdd, nodeInfo)
 | 
							status = f.runPreFilterExtensionAddPod(ctx, pl, state, podToSchedule, podInfoToAdd, nodeInfo)
 | 
				
			||||||
@@ -689,7 +696,7 @@ func (f *frameworkImpl) RunPreFilterExtensionRemovePod(
 | 
				
			|||||||
	nodeInfo *framework.NodeInfo,
 | 
						nodeInfo *framework.NodeInfo,
 | 
				
			||||||
) (status *framework.Status) {
 | 
					) (status *framework.Status) {
 | 
				
			||||||
	for _, pl := range f.preFilterPlugins {
 | 
						for _, pl := range f.preFilterPlugins {
 | 
				
			||||||
		if pl.PreFilterExtensions() == nil {
 | 
							if pl.PreFilterExtensions() == nil || state.SkipFilterPlugins.Has(pl.Name()) {
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		status = f.runPreFilterExtensionRemovePod(ctx, pl, state, podToSchedule, podInfoToRemove, nodeInfo)
 | 
							status = f.runPreFilterExtensionRemovePod(ctx, pl, state, podToSchedule, podInfoToRemove, nodeInfo)
 | 
				
			||||||
@@ -726,6 +733,9 @@ func (f *frameworkImpl) RunFilterPlugins(
 | 
				
			|||||||
	var status *framework.Status
 | 
						var status *framework.Status
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, pl := range f.filterPlugins {
 | 
						for _, pl := range f.filterPlugins {
 | 
				
			||||||
 | 
							if state.SkipFilterPlugins.Has(pl.Name()) {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		status = f.runFilterPlugin(ctx, pl, state, pod, nodeInfo)
 | 
							status = f.runFilterPlugin(ctx, pl, state, pod, nodeInfo)
 | 
				
			||||||
		if !status.IsSuccess() {
 | 
							if !status.IsSuccess() {
 | 
				
			||||||
			if !status.IsUnschedulable() {
 | 
								if !status.IsUnschedulable() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1402,9 +1402,11 @@ func TestPreFilterPlugins(t *testing.T) {
 | 
				
			|||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			t.Fatalf("Failed to create framework for testing: %v", err)
 | 
								t.Fatalf("Failed to create framework for testing: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		f.RunPreFilterPlugins(ctx, nil, nil)
 | 
							state := framework.NewCycleState()
 | 
				
			||||||
		f.RunPreFilterExtensionAddPod(ctx, nil, nil, nil, nil)
 | 
					
 | 
				
			||||||
		f.RunPreFilterExtensionRemovePod(ctx, nil, nil, nil, nil)
 | 
							f.RunPreFilterPlugins(ctx, state, nil)
 | 
				
			||||||
 | 
							f.RunPreFilterExtensionAddPod(ctx, state, nil, nil, nil)
 | 
				
			||||||
 | 
							f.RunPreFilterExtensionRemovePod(ctx, state, nil, nil, nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if preFilter1.PreFilterCalled != 1 {
 | 
							if preFilter1.PreFilterCalled != 1 {
 | 
				
			||||||
			t.Errorf("preFilter1 called %v, expected: 1", preFilter1.PreFilterCalled)
 | 
								t.Errorf("preFilter1 called %v, expected: 1", preFilter1.PreFilterCalled)
 | 
				
			||||||
@@ -1421,31 +1423,300 @@ func TestPreFilterPlugins(t *testing.T) {
 | 
				
			|||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestRunPreFilterPluginsStatus(t *testing.T) {
 | 
					func TestRunPreFilterPlugins(t *testing.T) {
 | 
				
			||||||
	preFilter := &TestPlugin{
 | 
						tests := []struct {
 | 
				
			||||||
		name: preFilterPluginName,
 | 
							name                string
 | 
				
			||||||
 | 
							plugins             []*TestPlugin
 | 
				
			||||||
 | 
							wantPreFilterResult *framework.PreFilterResult
 | 
				
			||||||
 | 
							wantSkippedPlugins  sets.Set[string]
 | 
				
			||||||
 | 
							wantStatusCode      framework.Code
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "all PreFilter returned success",
 | 
				
			||||||
 | 
								plugins: []*TestPlugin{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "success1",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "success2",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantPreFilterResult: nil,
 | 
				
			||||||
 | 
								wantStatusCode:      framework.Success,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "one PreFilter plugin returned success, but another PreFilter plugin returned non-success",
 | 
				
			||||||
 | 
								plugins: []*TestPlugin{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "success",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "error",
 | 
				
			||||||
					inj:  injectedResult{PreFilterStatus: int(framework.Error)},
 | 
										inj:  injectedResult{PreFilterStatus: int(framework.Error)},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantPreFilterResult: nil,
 | 
				
			||||||
 | 
								wantStatusCode:      framework.Error,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "one PreFilter plugin returned skip, but another PreFilter plugin returned non-success",
 | 
				
			||||||
 | 
								plugins: []*TestPlugin{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "skip",
 | 
				
			||||||
 | 
										inj:  injectedResult{PreFilterStatus: int(framework.Skip)},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "error",
 | 
				
			||||||
 | 
										inj:  injectedResult{PreFilterStatus: int(framework.Error)},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantPreFilterResult: nil,
 | 
				
			||||||
 | 
								wantStatusCode:      framework.Error,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "all PreFilter plugins returned skip",
 | 
				
			||||||
 | 
								plugins: []*TestPlugin{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "skip1",
 | 
				
			||||||
 | 
										inj:  injectedResult{PreFilterStatus: int(framework.Skip)},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "skip2",
 | 
				
			||||||
 | 
										inj:  injectedResult{PreFilterStatus: int(framework.Skip)},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "skip3",
 | 
				
			||||||
 | 
										inj:  injectedResult{PreFilterStatus: int(framework.Skip)},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantPreFilterResult: nil,
 | 
				
			||||||
 | 
								wantSkippedPlugins:  sets.New("skip1", "skip2", "skip3"),
 | 
				
			||||||
 | 
								wantStatusCode:      framework.Success,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "some PreFilter plugins returned skip",
 | 
				
			||||||
 | 
								plugins: []*TestPlugin{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "skip1",
 | 
				
			||||||
 | 
										inj:  injectedResult{PreFilterStatus: int(framework.Skip)},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "success1",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "skip2",
 | 
				
			||||||
 | 
										inj:  injectedResult{PreFilterStatus: int(framework.Skip)},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "success2",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantPreFilterResult: nil,
 | 
				
			||||||
 | 
								wantSkippedPlugins:  sets.New("skip1", "skip2"),
 | 
				
			||||||
 | 
								wantStatusCode:      framework.Success,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						for _, tt := range tests {
 | 
				
			||||||
 | 
							t.Run(tt.name, func(t *testing.T) {
 | 
				
			||||||
			r := make(Registry)
 | 
								r := make(Registry)
 | 
				
			||||||
	r.Register(preFilterPluginName,
 | 
								enabled := make([]config.Plugin, len(tt.plugins))
 | 
				
			||||||
		func(_ runtime.Object, fh framework.Handle) (framework.Plugin, error) {
 | 
								for i, p := range tt.plugins {
 | 
				
			||||||
			return preFilter, nil
 | 
									p := p
 | 
				
			||||||
 | 
									enabled[i].Name = p.name
 | 
				
			||||||
 | 
									r.Register(p.name, func(_ runtime.Object, fh framework.Handle) (framework.Plugin, error) {
 | 
				
			||||||
 | 
										return p, nil
 | 
				
			||||||
				})
 | 
									})
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	plugins := &config.Plugins{PreFilter: config.PluginSet{Enabled: []config.Plugin{{Name: preFilterPluginName}}}}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	profile := config.KubeSchedulerProfile{Plugins: plugins}
 | 
					 | 
				
			||||||
			ctx, cancel := context.WithCancel(context.Background())
 | 
								ctx, cancel := context.WithCancel(context.Background())
 | 
				
			||||||
			defer cancel()
 | 
								defer cancel()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	f, err := newFrameworkWithQueueSortAndBind(r, profile, ctx.Done())
 | 
								f, err := newFrameworkWithQueueSortAndBind(
 | 
				
			||||||
 | 
									r,
 | 
				
			||||||
 | 
									config.KubeSchedulerProfile{Plugins: &config.Plugins{PreFilter: config.PluginSet{Enabled: enabled}}},
 | 
				
			||||||
 | 
									ctx.Done(),
 | 
				
			||||||
 | 
								)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				t.Fatalf("Failed to create framework for testing: %v", err)
 | 
									t.Fatalf("Failed to create framework for testing: %v", err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
	_, status := f.RunPreFilterPlugins(ctx, nil, nil)
 | 
					
 | 
				
			||||||
	wantStatus := framework.AsStatus(fmt.Errorf("running PreFilter plugin %q: %w", preFilter.Name(), errInjectedStatus)).WithFailedPlugin(preFilter.Name())
 | 
								state := framework.NewCycleState()
 | 
				
			||||||
	if !reflect.DeepEqual(status, wantStatus) {
 | 
								result, status := f.RunPreFilterPlugins(ctx, state, nil)
 | 
				
			||||||
		t.Errorf("wrong status. got: %v, want:%v", status, wantStatus)
 | 
								if d := cmp.Diff(result, tt.wantPreFilterResult); d != "" {
 | 
				
			||||||
 | 
									t.Errorf("wrong status. got: %v, want: %v, diff: %s", result, tt.wantPreFilterResult, d)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if status.Code() != tt.wantStatusCode {
 | 
				
			||||||
 | 
									t.Errorf("wrong status code. got: %v, want: %v", status, tt.wantStatusCode)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								skipped := state.SkipFilterPlugins
 | 
				
			||||||
 | 
								if d := cmp.Diff(skipped, tt.wantSkippedPlugins); d != "" {
 | 
				
			||||||
 | 
									t.Errorf("wrong skip filter plugins. got: %v, want: %v, diff: %s", skipped, tt.wantSkippedPlugins, d)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestRunPreFilterExtensionRemovePod(t *testing.T) {
 | 
				
			||||||
 | 
						tests := []struct {
 | 
				
			||||||
 | 
							name               string
 | 
				
			||||||
 | 
							plugins            []*TestPlugin
 | 
				
			||||||
 | 
							skippedPluginNames sets.Set[string]
 | 
				
			||||||
 | 
							wantStatusCode     framework.Code
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "no plugins are skipped and all RemovePod() returned success",
 | 
				
			||||||
 | 
								plugins: []*TestPlugin{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "success1",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "success2",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantStatusCode: framework.Success,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "one RemovePod() returned error",
 | 
				
			||||||
 | 
								plugins: []*TestPlugin{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "success1",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "error1",
 | 
				
			||||||
 | 
										inj:  injectedResult{PreFilterRemovePodStatus: int(framework.Error)},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantStatusCode: framework.Error,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "one RemovePod() is skipped",
 | 
				
			||||||
 | 
								plugins: []*TestPlugin{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "success1",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "skipped",
 | 
				
			||||||
 | 
										// To confirm it's skipped, return error so that this test case will fail when it isn't skipped.
 | 
				
			||||||
 | 
										inj: injectedResult{PreFilterRemovePodStatus: int(framework.Error)},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								skippedPluginNames: sets.New("skipped"),
 | 
				
			||||||
 | 
								wantStatusCode:     framework.Success,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, tt := range tests {
 | 
				
			||||||
 | 
							t.Run(tt.name, func(t *testing.T) {
 | 
				
			||||||
 | 
								r := make(Registry)
 | 
				
			||||||
 | 
								enabled := make([]config.Plugin, len(tt.plugins))
 | 
				
			||||||
 | 
								for i, p := range tt.plugins {
 | 
				
			||||||
 | 
									p := p
 | 
				
			||||||
 | 
									enabled[i].Name = p.name
 | 
				
			||||||
 | 
									r.Register(p.name, func(_ runtime.Object, fh framework.Handle) (framework.Plugin, error) {
 | 
				
			||||||
 | 
										return p, nil
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ctx, cancel := context.WithCancel(context.Background())
 | 
				
			||||||
 | 
								defer cancel()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								f, err := newFrameworkWithQueueSortAndBind(
 | 
				
			||||||
 | 
									r,
 | 
				
			||||||
 | 
									config.KubeSchedulerProfile{Plugins: &config.Plugins{PreFilter: config.PluginSet{Enabled: enabled}}},
 | 
				
			||||||
 | 
									ctx.Done(),
 | 
				
			||||||
 | 
								)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									t.Fatalf("Failed to create framework for testing: %v", err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								state := framework.NewCycleState()
 | 
				
			||||||
 | 
								state.SkipFilterPlugins = tt.skippedPluginNames
 | 
				
			||||||
 | 
								status := f.RunPreFilterExtensionRemovePod(ctx, state, nil, nil, nil)
 | 
				
			||||||
 | 
								if status.Code() != tt.wantStatusCode {
 | 
				
			||||||
 | 
									t.Errorf("wrong status code. got: %v, want: %v", status, tt.wantStatusCode)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestRunPreFilterExtensionAddPod(t *testing.T) {
 | 
				
			||||||
 | 
						tests := []struct {
 | 
				
			||||||
 | 
							name               string
 | 
				
			||||||
 | 
							plugins            []*TestPlugin
 | 
				
			||||||
 | 
							skippedPluginNames sets.Set[string]
 | 
				
			||||||
 | 
							wantStatusCode     framework.Code
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "no plugins are skipped and all AddPod() returned success",
 | 
				
			||||||
 | 
								plugins: []*TestPlugin{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "success1",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "success2",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantStatusCode: framework.Success,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "one AddPod() returned error",
 | 
				
			||||||
 | 
								plugins: []*TestPlugin{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "success1",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "error1",
 | 
				
			||||||
 | 
										inj:  injectedResult{PreFilterAddPodStatus: int(framework.Error)},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantStatusCode: framework.Error,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "one AddPod() is skipped",
 | 
				
			||||||
 | 
								plugins: []*TestPlugin{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "success1",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "skipped",
 | 
				
			||||||
 | 
										// To confirm it's skipped, return error so that this test case will fail when it isn't skipped.
 | 
				
			||||||
 | 
										inj: injectedResult{PreFilterAddPodStatus: int(framework.Error)},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								skippedPluginNames: sets.New("skipped"),
 | 
				
			||||||
 | 
								wantStatusCode:     framework.Success,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, tt := range tests {
 | 
				
			||||||
 | 
							t.Run(tt.name, func(t *testing.T) {
 | 
				
			||||||
 | 
								r := make(Registry)
 | 
				
			||||||
 | 
								enabled := make([]config.Plugin, len(tt.plugins))
 | 
				
			||||||
 | 
								for i, p := range tt.plugins {
 | 
				
			||||||
 | 
									p := p
 | 
				
			||||||
 | 
									enabled[i].Name = p.name
 | 
				
			||||||
 | 
									r.Register(p.name, func(_ runtime.Object, fh framework.Handle) (framework.Plugin, error) {
 | 
				
			||||||
 | 
										return p, nil
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ctx, cancel := context.WithCancel(context.Background())
 | 
				
			||||||
 | 
								defer cancel()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								f, err := newFrameworkWithQueueSortAndBind(
 | 
				
			||||||
 | 
									r,
 | 
				
			||||||
 | 
									config.KubeSchedulerProfile{Plugins: &config.Plugins{PreFilter: config.PluginSet{Enabled: enabled}}},
 | 
				
			||||||
 | 
									ctx.Done(),
 | 
				
			||||||
 | 
								)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									t.Fatalf("Failed to create framework for testing: %v", err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								state := framework.NewCycleState()
 | 
				
			||||||
 | 
								state.SkipFilterPlugins = tt.skippedPluginNames
 | 
				
			||||||
 | 
								status := f.RunPreFilterExtensionAddPod(ctx, state, nil, nil, nil)
 | 
				
			||||||
 | 
								if status.Code() != tt.wantStatusCode {
 | 
				
			||||||
 | 
									t.Errorf("wrong status code. got: %v, want: %v", status, tt.wantStatusCode)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1453,6 +1724,7 @@ func TestFilterPlugins(t *testing.T) {
 | 
				
			|||||||
	tests := []struct {
 | 
						tests := []struct {
 | 
				
			||||||
		name           string
 | 
							name           string
 | 
				
			||||||
		plugins        []*TestPlugin
 | 
							plugins        []*TestPlugin
 | 
				
			||||||
 | 
							skippedPlugins sets.Set[string]
 | 
				
			||||||
		wantStatus     *framework.Status
 | 
							wantStatus     *framework.Status
 | 
				
			||||||
	}{
 | 
						}{
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -1553,6 +1825,22 @@ func TestFilterPlugins(t *testing.T) {
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
			wantStatus: nil,
 | 
								wantStatus: nil,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "SuccessAndSkipFilters",
 | 
				
			||||||
 | 
								plugins: []*TestPlugin{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "TestPlugin1",
 | 
				
			||||||
 | 
										inj:  injectedResult{FilterStatus: int(framework.Success)},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "TestPlugin2",
 | 
				
			||||||
 | 
										inj:  injectedResult{FilterStatus: int(framework.Error)}, // To make sure this plugins isn't called, set error as an injected result.
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantStatus:     nil,
 | 
				
			||||||
 | 
								skippedPlugins: sets.New("TestPlugin2"),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name: "ErrorAndSuccessFilters",
 | 
								name: "ErrorAndSuccessFilters",
 | 
				
			||||||
			plugins: []*TestPlugin{
 | 
								plugins: []*TestPlugin{
 | 
				
			||||||
@@ -1624,7 +1912,9 @@ func TestFilterPlugins(t *testing.T) {
 | 
				
			|||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				t.Fatalf("fail to create framework: %s", err)
 | 
									t.Fatalf("fail to create framework: %s", err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			gotStatus := f.RunFilterPlugins(ctx, nil, pod, nil)
 | 
								state := framework.NewCycleState()
 | 
				
			||||||
 | 
								state.SkipFilterPlugins = tt.skippedPlugins
 | 
				
			||||||
 | 
								gotStatus := f.RunFilterPlugins(ctx, state, pod, nil)
 | 
				
			||||||
			if diff := cmp.Diff(gotStatus, tt.wantStatus, cmpOpts...); diff != "" {
 | 
								if diff := cmp.Diff(gotStatus, tt.wantStatus, cmpOpts...); diff != "" {
 | 
				
			||||||
				t.Errorf("Unexpected status: (-got, +want):\n%s", diff)
 | 
									t.Errorf("Unexpected status: (-got, +want):\n%s", diff)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -1896,7 +2186,7 @@ func TestFilterPluginsWithNominatedPods(t *testing.T) {
 | 
				
			|||||||
				t.Fatalf("fail to create framework: %s", err)
 | 
									t.Fatalf("fail to create framework: %s", err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			tt.nodeInfo.SetNode(tt.node)
 | 
								tt.nodeInfo.SetNode(tt.node)
 | 
				
			||||||
			gotStatus := f.RunFilterPluginsWithNominatedPods(ctx, nil, tt.pod, tt.nodeInfo)
 | 
								gotStatus := f.RunFilterPluginsWithNominatedPods(ctx, framework.NewCycleState(), tt.pod, tt.nodeInfo)
 | 
				
			||||||
			if diff := cmp.Diff(gotStatus, tt.wantStatus, cmpOpts...); diff != "" {
 | 
								if diff := cmp.Diff(gotStatus, tt.wantStatus, cmpOpts...); diff != "" {
 | 
				
			||||||
				t.Errorf("Unexpected status: (-got, +want):\n%s", diff)
 | 
									t.Errorf("Unexpected status: (-got, +want):\n%s", diff)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1980,6 +1980,42 @@ func TestSchedulerSchedulePod(t *testing.T) {
 | 
				
			|||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "test prefilter plugin returning skip",
 | 
				
			||||||
 | 
								registerPlugins: []st.RegisterPluginFunc{
 | 
				
			||||||
 | 
									st.RegisterQueueSortPlugin(queuesort.Name, queuesort.New),
 | 
				
			||||||
 | 
									st.RegisterPreFilterPlugin(
 | 
				
			||||||
 | 
										"FakePreFilter1",
 | 
				
			||||||
 | 
										st.NewFakePreFilterPlugin("FakeFilter1", nil, nil),
 | 
				
			||||||
 | 
									),
 | 
				
			||||||
 | 
									st.RegisterFilterPlugin(
 | 
				
			||||||
 | 
										"FakeFilter1",
 | 
				
			||||||
 | 
										st.NewFakeFilterPlugin(map[string]framework.Code{
 | 
				
			||||||
 | 
											"node1": framework.Unschedulable,
 | 
				
			||||||
 | 
										}),
 | 
				
			||||||
 | 
									),
 | 
				
			||||||
 | 
									st.RegisterPluginAsExtensions("FakeFilter2", func(configuration runtime.Object, f framework.Handle) (framework.Plugin, error) {
 | 
				
			||||||
 | 
										return st.FakePreFilterAndFilterPlugin{
 | 
				
			||||||
 | 
											FakePreFilterPlugin: &st.FakePreFilterPlugin{
 | 
				
			||||||
 | 
												Result: nil,
 | 
				
			||||||
 | 
												Status: framework.NewStatus(framework.Skip),
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
 | 
											FakeFilterPlugin: &st.FakeFilterPlugin{
 | 
				
			||||||
 | 
												// This Filter plugin shouldn't be executed in the Filter extension point due to skip.
 | 
				
			||||||
 | 
												// To confirm that, return the status code Error to all Nodes.
 | 
				
			||||||
 | 
												FailedNodeReturnCodeMap: map[string]framework.Code{
 | 
				
			||||||
 | 
													"node1": framework.Error, "node2": framework.Error, "node3": framework.Error,
 | 
				
			||||||
 | 
												},
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
 | 
										}, nil
 | 
				
			||||||
 | 
									}, "PreFilter", "Filter"),
 | 
				
			||||||
 | 
									st.RegisterBindPlugin(defaultbinder.Name, defaultbinder.New),
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								nodes:              []string{"node1", "node2", "node3"},
 | 
				
			||||||
 | 
								pod:                st.MakePod().Name("test-prefilter").UID("test-prefilter").Obj(),
 | 
				
			||||||
 | 
								wantNodes:          sets.NewString("node2", "node3"),
 | 
				
			||||||
 | 
								wantEvaluatedNodes: pointer.Int32(3),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, test := range tests {
 | 
						for _, test := range tests {
 | 
				
			||||||
		t.Run(test.name, func(t *testing.T) {
 | 
							t.Run(test.name, func(t *testing.T) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,7 @@ import (
 | 
				
			|||||||
	"sync/atomic"
 | 
						"sync/atomic"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"k8s.io/api/core/v1"
 | 
						v1 "k8s.io/api/core/v1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
						"k8s.io/apimachinery/pkg/runtime"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/scheduler/framework"
 | 
						"k8s.io/kubernetes/pkg/scheduler/framework"
 | 
				
			||||||
	frameworkruntime "k8s.io/kubernetes/pkg/scheduler/framework/runtime"
 | 
						frameworkruntime "k8s.io/kubernetes/pkg/scheduler/framework/runtime"
 | 
				
			||||||
@@ -67,6 +67,16 @@ func NewTrueFilterPlugin(_ runtime.Object, _ framework.Handle) (framework.Plugin
 | 
				
			|||||||
	return &TrueFilterPlugin{}, nil
 | 
						return &TrueFilterPlugin{}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type FakePreFilterAndFilterPlugin struct {
 | 
				
			||||||
 | 
						*FakePreFilterPlugin
 | 
				
			||||||
 | 
						*FakeFilterPlugin
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Name returns name of the plugin.
 | 
				
			||||||
 | 
					func (pl FakePreFilterAndFilterPlugin) Name() string {
 | 
				
			||||||
 | 
						return "FakePreFilterAndFilterPlugin"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// FakeFilterPlugin is a test filter plugin to record how many times its Filter() function have
 | 
					// FakeFilterPlugin is a test filter plugin to record how many times its Filter() function have
 | 
				
			||||||
// been called, and it returns different 'Code' depending on its internal 'failedNodeReturnCodeMap'.
 | 
					// been called, and it returns different 'Code' depending on its internal 'failedNodeReturnCodeMap'.
 | 
				
			||||||
type FakeFilterPlugin struct {
 | 
					type FakeFilterPlugin struct {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user