mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-07-17 11:28:58 +00:00
Merge pull request #137662 from tosi3k/revert-136254-extend-postfilter
Revert "Extend PostFilterResult with a list of victim Pods"
This commit is contained in:
@@ -289,20 +289,11 @@ type Framework interface {
|
||||
Close() error
|
||||
}
|
||||
|
||||
// NewPostFilterResult creates PostFilterResult with a provided nominated node
|
||||
// and a list of victims (if any) that need to be preempted to make the pod schedulable.
|
||||
func NewPostFilterResult(nodeName string, victims []*v1.Pod) *fwk.PostFilterResult {
|
||||
func NewPostFilterResultWithNominatedNode(name string) *fwk.PostFilterResult {
|
||||
return &fwk.PostFilterResult{
|
||||
NominatingInfo: &fwk.NominatingInfo{
|
||||
NominatedNodeName: nodeName,
|
||||
NominatedNodeName: name,
|
||||
NominatingMode: fwk.ModeOverride,
|
||||
},
|
||||
Victims: victims,
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated: use NewPostFilterResult instead, even if no victims were identified.
|
||||
// Deprecated in Kubernetes 1.36 and will be removed in 1.38.
|
||||
func NewPostFilterResultWithNominatedNode(nodeName string) *fwk.PostFilterResult {
|
||||
return NewPostFilterResult(nodeName, nil)
|
||||
}
|
||||
|
||||
@@ -52,12 +52,12 @@ import (
|
||||
apipod "k8s.io/kubernetes/pkg/api/v1/pod"
|
||||
"k8s.io/kubernetes/pkg/scheduler/apis/config"
|
||||
configv1 "k8s.io/kubernetes/pkg/scheduler/apis/config/v1"
|
||||
apicache "k8s.io/kubernetes/pkg/scheduler/backend/api_cache"
|
||||
apidispatcher "k8s.io/kubernetes/pkg/scheduler/backend/api_dispatcher"
|
||||
"k8s.io/kubernetes/pkg/scheduler/backend/api_cache"
|
||||
"k8s.io/kubernetes/pkg/scheduler/backend/api_dispatcher"
|
||||
internalcache "k8s.io/kubernetes/pkg/scheduler/backend/cache"
|
||||
internalqueue "k8s.io/kubernetes/pkg/scheduler/backend/queue"
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework"
|
||||
apicalls "k8s.io/kubernetes/pkg/scheduler/framework/api_calls"
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework/api_calls"
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework/parallelize"
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultbinder"
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature"
|
||||
@@ -163,35 +163,19 @@ const (
|
||||
LabelValueNonViolatingPDB = "non-violating"
|
||||
)
|
||||
|
||||
func checkPostFilterResult(t *testing.T, result *fwk.PostFilterResult, expectedNode string, expectedVictims sets.Set[string]) {
|
||||
if expectedNode != result.NominatedNodeName {
|
||||
t.Errorf("expected NodeName %q, got %q", expectedNode, result.NominatedNodeName)
|
||||
}
|
||||
if len(result.Victims) != len(expectedVictims) {
|
||||
t.Errorf("expected %d victims, got %d", len(expectedVictims), len(result.Victims))
|
||||
}
|
||||
for _, victim := range result.Victims {
|
||||
if !expectedVictims.Has(victim.Name) {
|
||||
t.Errorf("pod %v is not expected to be a victim.", victim.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostFilter(t *testing.T) {
|
||||
onePodRes := map[v1.ResourceName]string{v1.ResourcePods: "1"}
|
||||
nodeRes := map[v1.ResourceName]string{v1.ResourceCPU: "200m", v1.ResourceMemory: "400"}
|
||||
tests := []struct {
|
||||
name string
|
||||
pod *v1.Pod
|
||||
pods []*v1.Pod
|
||||
pdbs []*policy.PodDisruptionBudget
|
||||
nodes []*v1.Node
|
||||
filteredNodesStatuses *framework.NodeToStatus
|
||||
extender fwk.Extender
|
||||
wantNilPostFilterResult bool
|
||||
expectedVictims sets.Set[string]
|
||||
expectedNominatedNode string
|
||||
wantStatus *fwk.Status
|
||||
name string
|
||||
pod *v1.Pod
|
||||
pods []*v1.Pod
|
||||
pdbs []*policy.PodDisruptionBudget
|
||||
nodes []*v1.Node
|
||||
filteredNodesStatuses *framework.NodeToStatus
|
||||
extender fwk.Extender
|
||||
wantResult *fwk.PostFilterResult
|
||||
wantStatus *fwk.Status
|
||||
}{
|
||||
{
|
||||
name: "pod with higher priority can be made schedulable",
|
||||
@@ -205,9 +189,8 @@ func TestPostFilter(t *testing.T) {
|
||||
filteredNodesStatuses: framework.NewNodeToStatus(map[string]*fwk.Status{
|
||||
"node1": fwk.NewStatus(fwk.Unschedulable),
|
||||
}, fwk.NewStatus(fwk.UnschedulableAndUnresolvable)),
|
||||
expectedNominatedNode: "node1",
|
||||
expectedVictims: sets.New("p1"),
|
||||
wantStatus: fwk.NewStatus(fwk.Success),
|
||||
wantResult: framework.NewPostFilterResultWithNominatedNode("node1"),
|
||||
wantStatus: fwk.NewStatus(fwk.Success),
|
||||
},
|
||||
{
|
||||
name: "pod with tied priority is still unschedulable",
|
||||
@@ -221,9 +204,8 @@ func TestPostFilter(t *testing.T) {
|
||||
filteredNodesStatuses: framework.NewNodeToStatus(map[string]*fwk.Status{
|
||||
"node1": fwk.NewStatus(fwk.Unschedulable),
|
||||
}, fwk.NewStatus(fwk.UnschedulableAndUnresolvable)),
|
||||
expectedNominatedNode: "",
|
||||
expectedVictims: nil,
|
||||
wantStatus: fwk.NewStatus(fwk.Unschedulable, "preemption: 0/1 nodes are available: 1 No preemption victims found for incoming pod."),
|
||||
wantResult: framework.NewPostFilterResultWithNominatedNode(""),
|
||||
wantStatus: fwk.NewStatus(fwk.Unschedulable, "preemption: 0/1 nodes are available: 1 No preemption victims found for incoming pod."),
|
||||
},
|
||||
{
|
||||
name: "preemption should respect filteredNodesStatuses",
|
||||
@@ -237,9 +219,8 @@ func TestPostFilter(t *testing.T) {
|
||||
filteredNodesStatuses: framework.NewNodeToStatus(map[string]*fwk.Status{
|
||||
"node1": fwk.NewStatus(fwk.UnschedulableAndUnresolvable),
|
||||
}, fwk.NewStatus(fwk.UnschedulableAndUnresolvable)),
|
||||
expectedNominatedNode: "",
|
||||
expectedVictims: nil,
|
||||
wantStatus: fwk.NewStatus(fwk.Unschedulable, "preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling."),
|
||||
wantResult: framework.NewPostFilterResultWithNominatedNode(""),
|
||||
wantStatus: fwk.NewStatus(fwk.Unschedulable, "preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling."),
|
||||
},
|
||||
{
|
||||
name: "preemption should respect absent NodeToStatusReader entry meaning UnschedulableAndUnresolvable",
|
||||
@@ -251,8 +232,7 @@ func TestPostFilter(t *testing.T) {
|
||||
st.MakeNode().Name("node1").Capacity(onePodRes).Obj(),
|
||||
},
|
||||
filteredNodesStatuses: framework.NewDefaultNodeToStatus(),
|
||||
expectedNominatedNode: "",
|
||||
expectedVictims: nil,
|
||||
wantResult: framework.NewPostFilterResultWithNominatedNode(""),
|
||||
wantStatus: fwk.NewStatus(fwk.Unschedulable, "preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling."),
|
||||
},
|
||||
{
|
||||
@@ -270,9 +250,8 @@ func TestPostFilter(t *testing.T) {
|
||||
"node1": fwk.NewStatus(fwk.Unschedulable),
|
||||
"node2": fwk.NewStatus(fwk.Unschedulable),
|
||||
}, fwk.NewStatus(fwk.UnschedulableAndUnresolvable)),
|
||||
expectedNominatedNode: "node2",
|
||||
expectedVictims: sets.New("p2"),
|
||||
wantStatus: fwk.NewStatus(fwk.Success),
|
||||
wantResult: framework.NewPostFilterResultWithNominatedNode("node2"),
|
||||
wantStatus: fwk.NewStatus(fwk.Success),
|
||||
},
|
||||
{
|
||||
name: "pod can be made schedulable on minHighestPriority node",
|
||||
@@ -294,9 +273,8 @@ func TestPostFilter(t *testing.T) {
|
||||
"node1": fwk.NewStatus(fwk.Unschedulable),
|
||||
"node2": fwk.NewStatus(fwk.Unschedulable),
|
||||
}, fwk.NewStatus(fwk.UnschedulableAndUnresolvable)),
|
||||
expectedNominatedNode: "node2",
|
||||
expectedVictims: sets.New("p3"),
|
||||
wantStatus: fwk.NewStatus(fwk.Success),
|
||||
wantResult: framework.NewPostFilterResultWithNominatedNode("node2"),
|
||||
wantStatus: fwk.NewStatus(fwk.Success),
|
||||
},
|
||||
{
|
||||
name: "preemption result filtered out by extenders",
|
||||
@@ -317,9 +295,8 @@ func TestPostFilter(t *testing.T) {
|
||||
ExtenderName: "FakeExtender1",
|
||||
Predicates: []tf.FitPredicate{tf.Node1PredicateExtender},
|
||||
},
|
||||
expectedNominatedNode: "node1",
|
||||
expectedVictims: sets.New("p1"),
|
||||
wantStatus: fwk.NewStatus(fwk.Success),
|
||||
wantResult: framework.NewPostFilterResultWithNominatedNode("node1"),
|
||||
wantStatus: fwk.NewStatus(fwk.Success),
|
||||
},
|
||||
{
|
||||
name: "no candidate nodes found, no enough resource after removing low priority pods",
|
||||
@@ -336,9 +313,8 @@ func TestPostFilter(t *testing.T) {
|
||||
"node1": fwk.NewStatus(fwk.Unschedulable),
|
||||
"node2": fwk.NewStatus(fwk.Unschedulable),
|
||||
}, fwk.NewStatus(fwk.UnschedulableAndUnresolvable)),
|
||||
expectedNominatedNode: "",
|
||||
expectedVictims: nil,
|
||||
wantStatus: fwk.NewStatus(fwk.Unschedulable, "preemption: 0/2 nodes are available: 2 Insufficient cpu."),
|
||||
wantResult: framework.NewPostFilterResultWithNominatedNode(""),
|
||||
wantStatus: fwk.NewStatus(fwk.Unschedulable, "preemption: 0/2 nodes are available: 2 Insufficient cpu."),
|
||||
},
|
||||
{
|
||||
name: "no candidate nodes found with mixed reasons, no lower priority pod and no enough CPU resource",
|
||||
@@ -358,9 +334,8 @@ func TestPostFilter(t *testing.T) {
|
||||
"node2": fwk.NewStatus(fwk.Unschedulable),
|
||||
"node3": fwk.NewStatus(fwk.Unschedulable),
|
||||
}, fwk.NewStatus(fwk.UnschedulableAndUnresolvable)),
|
||||
expectedNominatedNode: "",
|
||||
expectedVictims: nil,
|
||||
wantStatus: fwk.NewStatus(fwk.Unschedulable, "preemption: 0/3 nodes are available: 1 Insufficient cpu, 2 No preemption victims found for incoming pod."),
|
||||
wantResult: framework.NewPostFilterResultWithNominatedNode(""),
|
||||
wantStatus: fwk.NewStatus(fwk.Unschedulable, "preemption: 0/3 nodes are available: 1 Insufficient cpu, 2 No preemption victims found for incoming pod."),
|
||||
},
|
||||
{
|
||||
name: "no candidate nodes found with mixed reason, 2 UnschedulableAndUnresolvable nodes and 2 nodes don't have enough CPU resource",
|
||||
@@ -380,9 +355,8 @@ func TestPostFilter(t *testing.T) {
|
||||
"node2": fwk.NewStatus(fwk.Unschedulable),
|
||||
"node4": fwk.NewStatus(fwk.UnschedulableAndUnresolvable),
|
||||
}, fwk.NewStatus(fwk.UnschedulableAndUnresolvable)),
|
||||
expectedNominatedNode: "",
|
||||
expectedVictims: nil,
|
||||
wantStatus: fwk.NewStatus(fwk.Unschedulable, "preemption: 0/4 nodes are available: 2 Insufficient cpu, 2 Preemption is not helpful for scheduling."),
|
||||
wantResult: framework.NewPostFilterResultWithNominatedNode(""),
|
||||
wantStatus: fwk.NewStatus(fwk.Unschedulable, "preemption: 0/4 nodes are available: 2 Insufficient cpu, 2 Preemption is not helpful for scheduling."),
|
||||
},
|
||||
{
|
||||
name: "only one node but failed with TestPlugin",
|
||||
@@ -395,8 +369,8 @@ func TestPostFilter(t *testing.T) {
|
||||
filteredNodesStatuses: framework.NewNodeToStatus(map[string]*fwk.Status{
|
||||
"node1": fwk.NewStatus(fwk.Unschedulable),
|
||||
}, fwk.NewStatus(fwk.UnschedulableAndUnresolvable)),
|
||||
wantNilPostFilterResult: true,
|
||||
wantStatus: fwk.AsStatus(errors.New("preemption: running RemovePod on PreFilter plugin \"test-plugin\": failed to remove pod: p")),
|
||||
wantResult: nil,
|
||||
wantStatus: fwk.AsStatus(errors.New("preemption: running RemovePod on PreFilter plugin \"test-plugin\": failed to remove pod: p")),
|
||||
},
|
||||
{
|
||||
name: "one failed with TestPlugin and the other pass",
|
||||
@@ -414,9 +388,8 @@ func TestPostFilter(t *testing.T) {
|
||||
"node1": fwk.NewStatus(fwk.Unschedulable),
|
||||
"node2": fwk.NewStatus(fwk.Unschedulable),
|
||||
}, fwk.NewStatus(fwk.UnschedulableAndUnresolvable)),
|
||||
expectedNominatedNode: "node2",
|
||||
expectedVictims: sets.New("p2"),
|
||||
wantStatus: fwk.NewStatus(fwk.Success),
|
||||
wantResult: framework.NewPostFilterResultWithNominatedNode("node2"),
|
||||
wantStatus: fwk.NewStatus(fwk.Success),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -509,12 +482,8 @@ func TestPostFilter(t *testing.T) {
|
||||
t.Errorf("Unexpected status (-want, +got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
if tt.wantNilPostFilterResult {
|
||||
if gotResult != nil {
|
||||
t.Errorf("expected nil PostFilterResult, got %v", gotResult)
|
||||
}
|
||||
} else {
|
||||
checkPostFilterResult(t, gotResult, tt.expectedNominatedNode, tt.expectedVictims)
|
||||
if diff := cmp.Diff(tt.wantResult, gotResult); diff != "" {
|
||||
t.Errorf("Unexpected postFilterResult (-want, +got):\n%s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -1977,15 +1946,14 @@ func TestPodEligibleToPreemptOthers(t *testing.T) {
|
||||
func TestPreempt(t *testing.T) {
|
||||
metrics.Register()
|
||||
tests := []struct {
|
||||
name string
|
||||
pod *v1.Pod
|
||||
pods []*v1.Pod
|
||||
extenders []*tf.FakeExtender
|
||||
nodeNames []string
|
||||
registerPlugin tf.RegisterPluginFunc
|
||||
wantNilPostFilterResult bool
|
||||
expectedVictims sets.Set[string]
|
||||
expectedNominatedNode string
|
||||
name string
|
||||
pod *v1.Pod
|
||||
pods []*v1.Pod
|
||||
extenders []*tf.FakeExtender
|
||||
nodeNames []string
|
||||
registerPlugin tf.RegisterPluginFunc
|
||||
want *fwk.PostFilterResult
|
||||
expectedPods []string // list of preempted pods
|
||||
}{
|
||||
{
|
||||
name: "basic preemption logic",
|
||||
@@ -1996,10 +1964,10 @@ func TestPreempt(t *testing.T) {
|
||||
st.MakePod().Name("p2.1").UID("p2.1").Node("node2").Priority(highPriority).Req(largeRes).Obj(),
|
||||
st.MakePod().Name("p3.1").UID("p3.1").Node("node3").Priority(midPriority).Req(mediumRes).Obj(),
|
||||
},
|
||||
nodeNames: []string{"node1", "node2", "node3"},
|
||||
registerPlugin: tf.RegisterPluginAsExtensions(noderesources.Name, nodeResourcesFitFunc, "Filter", "PreFilter"),
|
||||
expectedVictims: sets.New("p1.1", "p1.2"),
|
||||
expectedNominatedNode: "node1",
|
||||
nodeNames: []string{"node1", "node2", "node3"},
|
||||
registerPlugin: tf.RegisterPluginAsExtensions(noderesources.Name, nodeResourcesFitFunc, "Filter", "PreFilter"),
|
||||
want: framework.NewPostFilterResultWithNominatedNode("node1"),
|
||||
expectedPods: []string{"p1.1", "p1.2"},
|
||||
},
|
||||
{
|
||||
name: "preemption for topology spread constraints",
|
||||
@@ -2014,10 +1982,10 @@ func TestPreempt(t *testing.T) {
|
||||
st.MakePod().Name("p-x1").UID("p-x1").Namespace(v1.NamespaceDefault).Node("node-x").Label("foo", "").Priority(highPriority).Obj(),
|
||||
st.MakePod().Name("p-x2").UID("p-x2").Namespace(v1.NamespaceDefault).Node("node-x").Label("foo", "").Priority(highPriority).Obj(),
|
||||
},
|
||||
nodeNames: []string{"node-a/zone1", "node-b/zone1", "node-x/zone2"},
|
||||
registerPlugin: tf.RegisterPluginAsExtensions(podtopologyspread.Name, podTopologySpreadFunc, "PreFilter", "Filter"),
|
||||
expectedVictims: sets.New("p-b1"),
|
||||
expectedNominatedNode: "node-b",
|
||||
nodeNames: []string{"node-a/zone1", "node-b/zone1", "node-x/zone2"},
|
||||
registerPlugin: tf.RegisterPluginAsExtensions(podtopologyspread.Name, podTopologySpreadFunc, "PreFilter", "Filter"),
|
||||
want: framework.NewPostFilterResultWithNominatedNode("node-b"),
|
||||
expectedPods: []string{"p-b1"},
|
||||
},
|
||||
{
|
||||
name: "Scheduler extenders allow only node1, otherwise node3 would have been chosen",
|
||||
@@ -2038,9 +2006,9 @@ func TestPreempt(t *testing.T) {
|
||||
Predicates: []tf.FitPredicate{tf.Node1PredicateExtender},
|
||||
},
|
||||
},
|
||||
registerPlugin: tf.RegisterPluginAsExtensions(noderesources.Name, nodeResourcesFitFunc, "Filter", "PreFilter"),
|
||||
expectedVictims: sets.New("p1.1", "p1.2"),
|
||||
expectedNominatedNode: "node1",
|
||||
registerPlugin: tf.RegisterPluginAsExtensions(noderesources.Name, nodeResourcesFitFunc, "Filter", "PreFilter"),
|
||||
want: framework.NewPostFilterResultWithNominatedNode("node1"),
|
||||
expectedPods: []string{"p1.1", "p1.2"},
|
||||
},
|
||||
{
|
||||
name: "Scheduler extenders do not allow any preemption",
|
||||
@@ -2057,8 +2025,9 @@ func TestPreempt(t *testing.T) {
|
||||
Predicates: []tf.FitPredicate{tf.FalsePredicateExtender},
|
||||
},
|
||||
},
|
||||
registerPlugin: tf.RegisterPluginAsExtensions(noderesources.Name, nodeResourcesFitFunc, "Filter", "PreFilter"),
|
||||
wantNilPostFilterResult: true,
|
||||
registerPlugin: tf.RegisterPluginAsExtensions(noderesources.Name, nodeResourcesFitFunc, "Filter", "PreFilter"),
|
||||
want: nil,
|
||||
expectedPods: []string{},
|
||||
},
|
||||
{
|
||||
name: "One scheduler extender allows only node1, the other returns error but ignorable. Only node1 would be chosen",
|
||||
@@ -2080,9 +2049,9 @@ func TestPreempt(t *testing.T) {
|
||||
ExtenderName: "FakeExtender2",
|
||||
},
|
||||
},
|
||||
registerPlugin: tf.RegisterPluginAsExtensions(noderesources.Name, nodeResourcesFitFunc, "Filter", "PreFilter"),
|
||||
expectedVictims: sets.New("p1.1", "p1.2"),
|
||||
expectedNominatedNode: "node1",
|
||||
registerPlugin: tf.RegisterPluginAsExtensions(noderesources.Name, nodeResourcesFitFunc, "Filter", "PreFilter"),
|
||||
want: framework.NewPostFilterResultWithNominatedNode("node1"),
|
||||
expectedPods: []string{"p1.1", "p1.2"},
|
||||
},
|
||||
{
|
||||
name: "One scheduler extender allows only node1, but it is not interested in given pod, otherwise node1 would have been chosen",
|
||||
@@ -2104,10 +2073,10 @@ func TestPreempt(t *testing.T) {
|
||||
Predicates: []tf.FitPredicate{tf.TruePredicateExtender},
|
||||
},
|
||||
},
|
||||
registerPlugin: tf.RegisterPluginAsExtensions(noderesources.Name, nodeResourcesFitFunc, "Filter", "PreFilter"),
|
||||
expectedVictims: sets.New("p2.1"),
|
||||
registerPlugin: tf.RegisterPluginAsExtensions(noderesources.Name, nodeResourcesFitFunc, "Filter", "PreFilter"),
|
||||
// sum of priorities of all victims on node1 is larger than node2, node2 is chosen.
|
||||
expectedNominatedNode: "node2",
|
||||
want: framework.NewPostFilterResultWithNominatedNode("node2"),
|
||||
expectedPods: []string{"p2.1"},
|
||||
},
|
||||
{
|
||||
name: "no preempting in pod",
|
||||
@@ -2118,9 +2087,10 @@ func TestPreempt(t *testing.T) {
|
||||
st.MakePod().Name("p2.1").UID("p2.1").Namespace(v1.NamespaceDefault).Node("node2").Priority(highPriority).Req(largeRes).Obj(),
|
||||
st.MakePod().Name("p3.1").UID("p3.1").Namespace(v1.NamespaceDefault).Node("node3").Priority(midPriority).Req(mediumRes).Obj(),
|
||||
},
|
||||
nodeNames: []string{"node1", "node2", "node3"},
|
||||
registerPlugin: tf.RegisterPluginAsExtensions(noderesources.Name, nodeResourcesFitFunc, "Filter", "PreFilter"),
|
||||
wantNilPostFilterResult: true,
|
||||
nodeNames: []string{"node1", "node2", "node3"},
|
||||
registerPlugin: tf.RegisterPluginAsExtensions(noderesources.Name, nodeResourcesFitFunc, "Filter", "PreFilter"),
|
||||
want: nil,
|
||||
expectedPods: nil,
|
||||
},
|
||||
{
|
||||
name: "PreemptionPolicy is nil",
|
||||
@@ -2131,10 +2101,10 @@ func TestPreempt(t *testing.T) {
|
||||
st.MakePod().Name("p2.1").UID("p2.1").Namespace(v1.NamespaceDefault).Node("node2").Priority(highPriority).Req(largeRes).Obj(),
|
||||
st.MakePod().Name("p3.1").UID("p3.1").Namespace(v1.NamespaceDefault).Node("node3").Priority(midPriority).Req(mediumRes).Obj(),
|
||||
},
|
||||
nodeNames: []string{"node1", "node2", "node3"},
|
||||
registerPlugin: tf.RegisterPluginAsExtensions(noderesources.Name, nodeResourcesFitFunc, "Filter", "PreFilter"),
|
||||
expectedVictims: sets.New("p1.1", "p1.2"),
|
||||
expectedNominatedNode: "node1",
|
||||
nodeNames: []string{"node1", "node2", "node3"},
|
||||
registerPlugin: tf.RegisterPluginAsExtensions(noderesources.Name, nodeResourcesFitFunc, "Filter", "PreFilter"),
|
||||
want: framework.NewPostFilterResultWithNominatedNode("node1"),
|
||||
expectedPods: []string{"p1.1", "p1.2"},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -2298,12 +2268,8 @@ func TestPreempt(t *testing.T) {
|
||||
if !status.IsSuccess() && !status.IsRejected() {
|
||||
t.Errorf("unexpected error in preemption: %v", status.AsError())
|
||||
}
|
||||
if test.wantNilPostFilterResult {
|
||||
if res != nil {
|
||||
t.Errorf("expected nil postFilterResult, got %v", res)
|
||||
}
|
||||
} else {
|
||||
checkPostFilterResult(t, res, test.expectedNominatedNode, test.expectedVictims)
|
||||
if diff := cmp.Diff(test.want, res); diff != "" {
|
||||
t.Errorf("Unexpected status (-want, +got):\n%s", diff)
|
||||
}
|
||||
|
||||
if asyncPreemptionEnabled {
|
||||
@@ -2311,15 +2277,15 @@ func TestPreempt(t *testing.T) {
|
||||
if err := wait.PollUntilContextTimeout(ctx, time.Millisecond*200, wait.ForeverTestTimeout, false, func(ctx context.Context) (bool, error) {
|
||||
mu.RLock()
|
||||
defer mu.RUnlock()
|
||||
return len(deletedPodNames) == len(test.expectedVictims), nil
|
||||
return len(deletedPodNames) == len(test.expectedPods), nil
|
||||
}); err != nil {
|
||||
t.Errorf("expected %v pods to be deleted, got %v.", len(test.expectedVictims), len(deletedPodNames))
|
||||
t.Errorf("expected %v pods to be deleted, got %v.", len(test.expectedPods), len(deletedPodNames))
|
||||
}
|
||||
} else {
|
||||
mu.RLock()
|
||||
// If async preemption is disabled, the pod should be deleted immediately.
|
||||
if len(deletedPodNames) != len(test.expectedVictims) {
|
||||
t.Errorf("expected %v pods to be deleted, got %v.", len(test.expectedVictims), len(deletedPodNames))
|
||||
if len(deletedPodNames) != len(test.expectedPods) {
|
||||
t.Errorf("expected %v pods to be deleted, got %v.", len(test.expectedPods), len(deletedPodNames))
|
||||
}
|
||||
mu.RUnlock()
|
||||
}
|
||||
@@ -2344,9 +2310,16 @@ func TestPreempt(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
for deletedPod := range deletedPodNames {
|
||||
if !test.expectedVictims.Has(deletedPod) {
|
||||
t.Errorf("pod %v is not expected to be deleted.", deletedPod)
|
||||
for victimName := range deletedPodNames {
|
||||
found := false
|
||||
for _, expPod := range test.expectedPods {
|
||||
if expPod == victimName {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("pod %v is not expected to be a victim.", victimName)
|
||||
}
|
||||
}
|
||||
if res != nil && res.NominatingInfo != nil {
|
||||
|
||||
@@ -144,7 +144,7 @@ func (ev *Evaluator) Preempt(ctx context.Context, state fwk.CycleState, pod *v1.
|
||||
}
|
||||
fitError.Diagnosis.NodeToStatus.SetAbsentNodesStatus(fwk.NewStatus(fwk.UnschedulableAndUnresolvable, "Preemption is not helpful for scheduling"))
|
||||
// Specify nominatedNodeName to clear the pod's nominatedNodeName status, if applicable.
|
||||
return framework.NewPostFilterResult("", nil), fwk.NewStatus(fwk.Unschedulable, fitError.Error())
|
||||
return framework.NewPostFilterResultWithNominatedNode(""), fwk.NewStatus(fwk.Unschedulable, fitError.Error())
|
||||
}
|
||||
|
||||
// 3) Interact with registered Extenders to filter out some candidates if needed.
|
||||
@@ -170,7 +170,7 @@ func (ev *Evaluator) Preempt(ctx context.Context, state fwk.CycleState, pod *v1.
|
||||
}
|
||||
}
|
||||
|
||||
return framework.NewPostFilterResult(bestCandidate.Name(), bestCandidate.Victims().Pods), fwk.NewStatus(fwk.Success)
|
||||
return framework.NewPostFilterResultWithNominatedNode(bestCandidate.Name()), fwk.NewStatus(fwk.Success)
|
||||
}
|
||||
|
||||
// FindCandidates calculates a slice of preemption candidates.
|
||||
|
||||
@@ -414,10 +414,6 @@ func (p *PreFilterResult) Merge(in *PreFilterResult) *PreFilterResult {
|
||||
// PostFilterResult wraps needed info for scheduler framework to act upon PostFilter phase.
|
||||
type PostFilterResult struct {
|
||||
*NominatingInfo
|
||||
// Victims are the pods that need to be preempted to make room for the preemptor pod.
|
||||
// For a preemptor that is a member of a pod group, this field skips the pods that were
|
||||
// identified as victims for other members of the pod group.
|
||||
Victims []*v1.Pod
|
||||
}
|
||||
|
||||
// PreBindPreFlightResult wraps needed info for scheduler framework to act upon PreBindPreFlight phase.
|
||||
|
||||
Reference in New Issue
Block a user