feature(scheduler): simplify QueueingHint by introducing new statuses

This commit is contained in:
Kensei Nakada
2023-10-19 11:02:11 +00:00
parent de054fbf94
commit cb5dc46edf
17 changed files with 360 additions and 284 deletions

View File

@@ -87,13 +87,10 @@ var (
cmpopts.IgnoreFields(nominator{}, "podLister", "lock"),
}
queueHintReturnQueueAfterBackoff = func(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) {
return framework.QueueAfterBackoff, nil
queueHintReturnQueue = func(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) {
return framework.Queue, nil
}
queueHintReturnQueueImmediately = func(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) {
return framework.QueueImmediately, nil
}
queueHintReturnQueueSkip = func(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) {
queueHintReturnSkip = func(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) {
return framework.QueueSkip, nil
}
)
@@ -244,7 +241,7 @@ func Test_InFlightPods(t *testing.T) {
AssignedPodAdd: {
{
PluginName: "fooPlugin1",
QueueingHintFn: queueHintReturnQueueSkip,
QueueingHintFn: queueHintReturnSkip,
},
},
},
@@ -340,7 +337,7 @@ func Test_InFlightPods(t *testing.T) {
AssignedPodAdd: {
{
PluginName: "fooPlugin1",
QueueingHintFn: queueHintReturnQueueSkip,
QueueingHintFn: queueHintReturnSkip,
},
},
},
@@ -364,7 +361,7 @@ func Test_InFlightPods(t *testing.T) {
AssignedPodAdd: {
{
PluginName: "fooPlugin1",
QueueingHintFn: queueHintReturnQueueImmediately,
QueueingHintFn: queueHintReturnQueue,
},
},
},
@@ -389,14 +386,14 @@ func Test_InFlightPods(t *testing.T) {
{
// It will be ignored because the event is not NodeAdd.
PluginName: "fooPlugin1",
QueueingHintFn: queueHintReturnQueueImmediately,
QueueingHintFn: queueHintReturnQueue,
},
},
},
},
},
{
name: "pod is enqueued to unschedulable pod pool because the failed plugin has a hint fn but it returns QueueSkip",
name: "pod is enqueued to unschedulable pod pool because the failed plugin has a hint fn but it returns Skip",
isSchedulingQueueHintEnabled: true,
initialPods: []*v1.Pod{pod},
actions: []action{
@@ -414,20 +411,24 @@ func Test_InFlightPods(t *testing.T) {
AssignedPodAdd: {
{
PluginName: "fooPlugin1",
QueueingHintFn: queueHintReturnQueueSkip,
QueueingHintFn: queueHintReturnSkip,
},
},
},
},
},
{
name: "pod is enqueued to activeQ because the failed plugin has a hint fn and it returns QueueImmediately",
name: "pod is enqueued to activeQ because the Pending plugins has a hint fn and it returns Queue",
isSchedulingQueueHintEnabled: true,
initialPods: []*v1.Pod{pod},
actions: []action{
{podPopped: pod},
{eventHappens: &AssignedPodAdd},
{podEnqueued: newQueuedPodInfoForLookup(pod, "fooPlugin1", "fooPlugin2", "fooPlugin3")},
{podEnqueued: &framework.QueuedPodInfo{
PodInfo: mustNewPodInfo(pod),
UnschedulablePlugins: sets.New("fooPlugin2", "fooPlugin3"),
PendingPlugins: sets.New("fooPlugin1"),
}},
},
wantActiveQPodNames: []string{"targetpod"},
wantInFlightPods: nil,
@@ -436,26 +437,24 @@ func Test_InFlightPods(t *testing.T) {
"": {
AssignedPodAdd: {
{
// it will be ignored because the hint fn returns QueueSkip that is weaker than queueHintReturnQueueImmediately from fooPlugin1.
PluginName: "fooPlugin3",
QueueingHintFn: queueHintReturnQueueSkip,
QueueingHintFn: queueHintReturnSkip,
},
{
// it will be ignored because the hint fn returns QueueAfterBackoff that is weaker than queueHintReturnQueueImmediately from fooPlugin1.
PluginName: "fooPlugin2",
QueueingHintFn: queueHintReturnQueueAfterBackoff,
QueueingHintFn: queueHintReturnQueue,
},
{
// The hint fn tells that this event makes a Pod scheudlable immediately.
PluginName: "fooPlugin1",
QueueingHintFn: queueHintReturnQueueImmediately,
QueueingHintFn: queueHintReturnQueue,
},
},
},
},
},
{
name: "pod is enqueued to backoffQ because the failed plugin has a hint fn and it returns QueueAfterBackoff",
name: "pod is enqueued to backoffQ because the failed plugin has a hint fn and it returns Queue",
isSchedulingQueueHintEnabled: true,
initialPods: []*v1.Pod{pod},
actions: []action{
@@ -470,21 +469,21 @@ func Test_InFlightPods(t *testing.T) {
"": {
AssignedPodAdd: {
{
// it will be ignored because the hint fn returns QueueSkip that is weaker than queueHintReturnQueueAfterBackoff from fooPlugin1.
// it will be ignored because the hint fn returns Skip that is weaker than queueHintReturnQueue from fooPlugin1.
PluginName: "fooPlugin2",
QueueingHintFn: queueHintReturnQueueSkip,
QueueingHintFn: queueHintReturnSkip,
},
{
// The hint fn tells that this event makes a Pod scheudlable.
// The hint fn tells that this event makes a Pod schedulable.
PluginName: "fooPlugin1",
QueueingHintFn: queueHintReturnQueueAfterBackoff,
QueueingHintFn: queueHintReturnQueue,
},
},
},
},
},
{
name: "pod is enqueued to activeQ because the failed plugin has a hint fn and it returns QueueImmediately for a concurrent event that was received while some other pod was in flight",
name: "pod is enqueued to activeQ because the failed plugin has a hint fn and it returns Queue for a concurrent event that was received while some other pod was in flight",
isSchedulingQueueHintEnabled: true,
initialPods: []*v1.Pod{pod, pod2},
actions: []action{
@@ -501,7 +500,8 @@ func Test_InFlightPods(t *testing.T) {
}},
{callback: func(t *testing.T, q *PriorityQueue) {
logger, _ := ktesting.NewTestContext(t)
poppedPod2.UnschedulablePlugins = sets.New("fooPlugin1", "fooPlugin2", "fooPlugin3")
poppedPod2.UnschedulablePlugins = sets.New("fooPlugin2", "fooPlugin3")
poppedPod2.PendingPlugins = sets.New("fooPlugin1")
err := q.AddUnschedulableIfNotPresent(logger, poppedPod2, q.SchedulingCycle())
if err != nil {
t.Fatalf("unexpected error from AddUnschedulableIfNotPresent: %v", err)
@@ -517,32 +517,34 @@ func Test_InFlightPods(t *testing.T) {
{
// it will be ignored because the hint fn returns QueueSkip that is weaker than queueHintReturnQueueImmediately from fooPlugin1.
PluginName: "fooPlugin3",
QueueingHintFn: queueHintReturnQueueSkip,
QueueingHintFn: queueHintReturnSkip,
},
{
// it will be ignored because the hint fn returns QueueAfterBackoff that is weaker than queueHintReturnQueueImmediately from fooPlugin1.
// it will be ignored because the fooPlugin2 is registered in UnschedulablePlugins and it's interpret as Queue that is weaker than QueueImmediately from fooPlugin1.
PluginName: "fooPlugin2",
QueueingHintFn: queueHintReturnQueueAfterBackoff,
QueueingHintFn: queueHintReturnQueue,
},
{
// The hint fn tells that this event makes a Pod scheudlable immediately.
// The hint fn tells that this event makes a Pod scheudlable.
// Given fooPlugin1 is registered as Pendings, we interpret Queue as queueImmediately.
PluginName: "fooPlugin1",
QueueingHintFn: queueHintReturnQueueImmediately,
QueueingHintFn: queueHintReturnQueue,
},
},
},
},
},
{
name: "popped pod must have empty UnschedulablePlugins",
name: "popped pod must have empty UnschedulablePlugins and PendingPlugins",
isSchedulingQueueHintEnabled: true,
initialPods: []*v1.Pod{pod},
actions: []action{
{callback: func(t *testing.T, q *PriorityQueue) { poppedPod = popPod(t, q, pod) }},
{callback: func(t *testing.T, q *PriorityQueue) {
logger, _ := ktesting.NewTestContext(t)
// Unschedulable.
poppedPod.UnschedulablePlugins = sets.New("fooPlugin1")
// Unschedulable due to PendingPlugins.
poppedPod.PendingPlugins = sets.New("fooPlugin1")
poppedPod.UnschedulablePlugins = sets.New("fooPlugin2")
if err := q.AddUnschedulableIfNotPresent(logger, poppedPod, q.SchedulingCycle()); err != nil {
t.Errorf("Unexpected error from AddUnschedulableIfNotPresent: %v", err)
}
@@ -568,7 +570,7 @@ func Test_InFlightPods(t *testing.T) {
{
// The hint fn tells that this event makes a Pod scheudlable immediately.
PluginName: "fooPlugin1",
QueueingHintFn: queueHintReturnQueueImmediately,
QueueingHintFn: queueHintReturnQueue,
},
},
},
@@ -694,9 +696,9 @@ func TestPop(t *testing.T) {
"": {
PvAdd: {
{
// The hint fn tells that this event makes a Pod scheudlable immediately.
// The hint fn tells that this event makes a Pod scheudlable.
PluginName: "fooPlugin1",
QueueingHintFn: queueHintReturnQueueImmediately,
QueueingHintFn: queueHintReturnQueue,
},
},
},
@@ -713,7 +715,8 @@ func TestPop(t *testing.T) {
// Simulate failed attempt that makes the pod unschedulable.
poppedPod := popPod(t, q, pod)
poppedPod.UnschedulablePlugins = sets.New("fooPlugin1")
// We put register the plugin to PendingPlugins so that it's interpreted as queueImmediately and skip backoff.
poppedPod.PendingPlugins = sets.New("fooPlugin1")
if err := q.AddUnschedulableIfNotPresent(logger, poppedPod, q.SchedulingCycle()); err != nil {
t.Errorf("Unexpected error from AddUnschedulableIfNotPresent: %v", err)
}
@@ -723,8 +726,8 @@ func TestPop(t *testing.T) {
// Now check result of Pop.
poppedPod = popPod(t, q, pod)
if len(poppedPod.UnschedulablePlugins) > 0 {
t.Errorf("QueuedPodInfo from Pop should have empty UnschedulablePlugins, got instead: %+v", poppedPod)
if len(poppedPod.PendingPlugins) > 0 {
t.Errorf("QueuedPodInfo from Pop should have empty PendingPlugins, got instead: %+v", poppedPod)
}
})
}
@@ -1221,7 +1224,7 @@ func BenchmarkMoveAllToActiveOrBackoffQueue(b *testing.B) {
if (k+1)%(j+1) == 0 {
m[""][events[j]] = append(m[""][events[j]], &QueueingHintFunction{
PluginName: plugins[k],
QueueingHintFn: queueHintReturnQueueAfterBackoff,
QueueingHintFn: queueHintReturnQueue,
})
}
}
@@ -1286,28 +1289,28 @@ func TestPriorityQueue_MoveAllToActiveOrBackoffQueueWithQueueingHint(t *testing.
expectedQ string
}{
{
name: "QueueImmediately queues pod to activeQ",
podInfo: &framework.QueuedPodInfo{PodInfo: mustNewPodInfo(p)},
hint: queueHintReturnQueueImmediately,
name: "Queue queues pod to activeQ",
podInfo: &framework.QueuedPodInfo{PodInfo: mustNewPodInfo(p), PendingPlugins: sets.New("foo")},
hint: queueHintReturnQueue,
expectedQ: activeQ,
},
{
name: "QueueAfterBackoff queues pod to backoffQ if Pod is backing off",
podInfo: &framework.QueuedPodInfo{PodInfo: mustNewPodInfo(p)},
hint: queueHintReturnQueueAfterBackoff,
name: "Queue queues pod to backoffQ if Pod is backing off",
podInfo: &framework.QueuedPodInfo{PodInfo: mustNewPodInfo(p), UnschedulablePlugins: sets.New("foo")},
hint: queueHintReturnQueue,
expectedQ: backoffQ,
},
{
name: "QueueAfterBackoff queues pod to activeQ if Pod is not backing off",
podInfo: &framework.QueuedPodInfo{PodInfo: mustNewPodInfo(p)},
hint: queueHintReturnQueueAfterBackoff,
name: "Queue queues pod to activeQ if Pod is not backing off",
podInfo: &framework.QueuedPodInfo{PodInfo: mustNewPodInfo(p), UnschedulablePlugins: sets.New("foo")},
hint: queueHintReturnQueue,
duration: DefaultPodInitialBackoffDuration, // backoff is finished
expectedQ: activeQ,
},
{
name: "QueueSkip queues pod to unschedulablePods",
podInfo: &framework.QueuedPodInfo{PodInfo: mustNewPodInfo(p)},
hint: queueHintReturnQueueSkip,
name: "Skip queues pod to unschedulablePods",
podInfo: &framework.QueuedPodInfo{PodInfo: mustNewPodInfo(p), UnschedulablePlugins: sets.New("foo")},
hint: queueHintReturnSkip,
expectedQ: unschedulablePods,
},
}
@@ -1362,7 +1365,7 @@ func TestPriorityQueue_MoveAllToActiveOrBackoffQueue(t *testing.T) {
m[""][NodeAdd] = []*QueueingHintFunction{
{
PluginName: "fooPlugin",
QueueingHintFn: queueHintReturnQueueAfterBackoff,
QueueingHintFn: queueHintReturnQueue,
},
}
q := NewTestQueue(ctx, newDefaultQueueSort(), WithClock(c), WithQueueingHintMapPerProfile(m))
@@ -1544,7 +1547,7 @@ func TestPriorityQueue_AssignedPodAdded(t *testing.T) {
m[""][AssignedPodAdd] = []*QueueingHintFunction{
{
PluginName: "fakePlugin",
QueueingHintFn: queueHintReturnQueueAfterBackoff,
QueueingHintFn: queueHintReturnQueue,
},
}
q := NewTestQueue(ctx, newDefaultQueueSort(), WithClock(c), WithQueueingHintMapPerProfile(m))
@@ -2139,7 +2142,7 @@ func TestHighPriorityFlushUnschedulablePodsLeftover(t *testing.T) {
m[""][NodeAdd] = []*QueueingHintFunction{
{
PluginName: "fakePlugin",
QueueingHintFn: queueHintReturnQueueAfterBackoff,
QueueingHintFn: queueHintReturnQueue,
},
}
logger, ctx := ktesting.NewTestContext(t)
@@ -3180,18 +3183,14 @@ func mustNewPodInfo(pod *v1.Pod) *framework.PodInfo {
// Test_isPodWorthRequeuing tests isPodWorthRequeuing function.
func Test_isPodWorthRequeuing(t *testing.T) {
count := 0
queueHintReturnQueueImmediately := func(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) {
queueHintReturnQueue := func(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) {
count++
return framework.QueueImmediately, nil
return framework.Queue, nil
}
queueHintReturnQueueSkip := func(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) {
queueHintReturnSkip := func(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) {
count++
return framework.QueueSkip, nil
}
queueHintReturnQueueAfterBackoff := func(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) {
count++
return framework.QueueAfterBackoff, nil
}
queueHintReturnErr := func(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) {
count++
return framework.QueueSkip, fmt.Errorf("unexpected error")
@@ -3203,12 +3202,12 @@ func Test_isPodWorthRequeuing(t *testing.T) {
event framework.ClusterEvent
oldObj interface{}
newObj interface{}
expected framework.QueueingHint
expected queueingStrategy
expectedExecutionCount int // expected total execution count of queueing hint function
queueingHintMap QueueingHintMapPerProfile
}{
{
name: "return QueueAfterBackoff when no queueing hint function is registered for the event",
name: "return Queue when no queueing hint function is registered for the event",
podInfo: &framework.QueuedPodInfo{
UnschedulablePlugins: sets.New("fooPlugin1"),
PodInfo: mustNewPodInfo(st.MakePod().Name("pod1").Namespace("ns1").UID("1").Obj()),
@@ -3216,7 +3215,7 @@ func Test_isPodWorthRequeuing(t *testing.T) {
event: NodeAdd,
oldObj: nil,
newObj: st.MakeNode().Obj(),
expected: framework.QueueSkip,
expected: queueSkip,
expectedExecutionCount: 0,
queueingHintMap: QueueingHintMapPerProfile{
"": {
@@ -3225,14 +3224,14 @@ func Test_isPodWorthRequeuing(t *testing.T) {
{
// It will be ignored because the event is not NodeAdd.
PluginName: "fooPlugin1",
QueueingHintFn: queueHintReturnQueueImmediately,
QueueingHintFn: queueHintReturnQueue,
},
},
},
},
},
{
name: "Treat the event as QueueAfterBackoff when QueueHintFn returns error",
name: "Treat the event as Queue when QueueHintFn returns error",
podInfo: &framework.QueuedPodInfo{
UnschedulablePlugins: sets.New("fooPlugin1"),
PodInfo: mustNewPodInfo(st.MakePod().Name("pod1").Namespace("ns1").UID("1").Obj()),
@@ -3240,7 +3239,7 @@ func Test_isPodWorthRequeuing(t *testing.T) {
event: NodeAdd,
oldObj: nil,
newObj: st.MakeNode().Obj(),
expected: framework.QueueAfterBackoff,
expected: queueAfterBackoff,
expectedExecutionCount: 1,
queueingHintMap: QueueingHintMapPerProfile{
"": {
@@ -3254,7 +3253,7 @@ func Test_isPodWorthRequeuing(t *testing.T) {
},
},
{
name: "return QueueAfterBackoff when the event is wildcard",
name: "return Queue when the event is wildcard",
podInfo: &framework.QueuedPodInfo{
UnschedulablePlugins: sets.New("fooPlugin1"),
PodInfo: mustNewPodInfo(st.MakePod().Name("pod1").Namespace("ns1").UID("1").Obj()),
@@ -3262,78 +3261,40 @@ func Test_isPodWorthRequeuing(t *testing.T) {
event: WildCardEvent,
oldObj: nil,
newObj: st.MakeNode().Obj(),
expected: framework.QueueAfterBackoff,
expected: queueAfterBackoff,
expectedExecutionCount: 0,
queueingHintMap: QueueingHintMapPerProfile{},
},
{
name: "QueueImmediately is the highest priority",
name: "interprets Queue from the Pending plugin as queueImmediately",
podInfo: &framework.QueuedPodInfo{
UnschedulablePlugins: sets.New("fooPlugin1", "fooPlugin2", "fooPlugin3", "fooPlugin4", "fooPlugin5"),
UnschedulablePlugins: sets.New("fooPlugin1", "fooPlugin3"),
PendingPlugins: sets.New("fooPlugin2"),
PodInfo: mustNewPodInfo(st.MakePod().Name("pod1").Namespace("ns1").UID("1").Obj()),
},
event: NodeAdd,
oldObj: nil,
newObj: st.MakeNode().Obj(),
expected: framework.QueueImmediately,
expectedExecutionCount: 3,
newObj: st.MakeNode().Node,
expected: queueImmediately,
expectedExecutionCount: 2,
queueingHintMap: QueueingHintMapPerProfile{
"": {
NodeAdd: {
{
// executed
PluginName: "fooPlugin1",
QueueingHintFn: queueHintReturnQueueAfterBackoff,
PluginName: "fooPlugin1",
// It returns Queue and it's interpreted as queueAfterBackoff.
// But, the function continues to run other hints because the Pod has PendingPlugins, which can result in queueImmediately.
QueueingHintFn: queueHintReturnQueue,
},
{
// executed
PluginName: "fooPlugin2",
QueueingHintFn: queueHintReturnErr,
},
{
// executed
// But, no more queueing hint function is executed
// because the highest priority is QueueImmediately.
PluginName: "fooPlugin3",
QueueingHintFn: queueHintReturnQueueImmediately,
},
{
PluginName: "fooPlugin4",
QueueingHintFn: queueHintReturnQueueAfterBackoff,
},
{
PluginName: "fooPlugin5",
QueueingHintFn: queueHintReturnQueueSkip,
},
},
},
},
},
{
name: "QueueSkip is the lowest priority",
podInfo: &framework.QueuedPodInfo{
UnschedulablePlugins: sets.New("fooPlugin1", "fooPlugin2", "fooPlugin3", "fooPlugin4"),
PodInfo: mustNewPodInfo(st.MakePod().Name("pod1").Namespace("ns1").UID("1").Obj()),
},
event: NodeAdd,
oldObj: nil,
newObj: st.MakeNode().Obj(),
expected: framework.QueueAfterBackoff,
expectedExecutionCount: 4,
queueingHintMap: QueueingHintMapPerProfile{
"": {
NodeAdd: {
{
PluginName: "fooPlugin1",
QueueingHintFn: queueHintReturnQueueAfterBackoff,
},
{
PluginName: "fooPlugin2",
QueueingHintFn: queueHintReturnQueueSkip,
PluginName: "fooPlugin2",
// It's interpreted as queueImmediately.
// The function doesn't run other hints because queueImmediately is the highest priority.
QueueingHintFn: queueHintReturnQueue,
},
{
PluginName: "fooPlugin3",
QueueingHintFn: queueHintReturnQueueAfterBackoff,
QueueingHintFn: queueHintReturnQueue,
},
{
PluginName: "fooPlugin4",
@@ -3344,7 +3305,7 @@ func Test_isPodWorthRequeuing(t *testing.T) {
},
},
{
name: "Queueing hint function that isn't from the plugin, that is in the UnschedulablePlugins, is ignored",
name: "interprets Queue from the Unschedulable plugin as queueAfterBackoff",
podInfo: &framework.QueuedPodInfo{
UnschedulablePlugins: sets.New("fooPlugin1", "fooPlugin2"),
PodInfo: mustNewPodInfo(st.MakePod().Name("pod1").Namespace("ns1").UID("1").Obj()),
@@ -3352,29 +3313,57 @@ func Test_isPodWorthRequeuing(t *testing.T) {
event: NodeAdd,
oldObj: nil,
newObj: st.MakeNode().Obj(),
expected: framework.QueueAfterBackoff,
expected: queueAfterBackoff,
expectedExecutionCount: 2,
queueingHintMap: QueueingHintMapPerProfile{
"": {
NodeAdd: {
{
// Skip will be ignored
PluginName: "fooPlugin1",
QueueingHintFn: queueHintReturnQueueAfterBackoff,
QueueingHintFn: queueHintReturnSkip,
},
{
// Skip will be ignored
PluginName: "fooPlugin2",
QueueingHintFn: queueHintReturnQueueSkip,
},
{
PluginName: "fooPlugin3",
QueueingHintFn: queueHintReturnQueueImmediately, // It'll be ignored.
QueueingHintFn: queueHintReturnQueue,
},
},
},
},
},
{
name: "If event is specific Node update event, queueing hint function for NodeUpdate/UpdateNodeLabel is executed",
name: "Queueing hint function that isn't from the plugin in UnschedulablePlugins/PendingPlugins is ignored",
podInfo: &framework.QueuedPodInfo{
UnschedulablePlugins: sets.New("fooPlugin1", "fooPlugin2"),
PodInfo: mustNewPodInfo(st.MakePod().Name("pod1").Namespace("ns1").UID("1").Obj()),
},
event: NodeAdd,
oldObj: nil,
newObj: st.MakeNode().Node,
expected: queueSkip,
expectedExecutionCount: 2,
queueingHintMap: QueueingHintMapPerProfile{
"": {
NodeAdd: {
{
PluginName: "fooPlugin1",
QueueingHintFn: queueHintReturnSkip,
},
{
PluginName: "fooPlugin2",
QueueingHintFn: queueHintReturnSkip,
},
{
PluginName: "fooPlugin3",
QueueingHintFn: queueHintReturnQueue, // It'll be ignored.
},
},
},
},
},
{
name: "If event is specific Node update event, queueing hint function for NodeUpdate/UpdateNodeLabel is also executed",
podInfo: &framework.QueuedPodInfo{
UnschedulablePlugins: sets.New("fooPlugin1", "fooPlugin2"),
PodInfo: mustNewPodInfo(st.MakePod().Name("pod1").Namespace("ns1").UID("1").Obj()),
@@ -3382,30 +3371,32 @@ func Test_isPodWorthRequeuing(t *testing.T) {
event: framework.ClusterEvent{Resource: framework.Node, ActionType: framework.UpdateNodeLabel},
oldObj: nil,
newObj: st.MakeNode().Obj(),
expected: framework.QueueAfterBackoff,
expectedExecutionCount: 3,
expected: queueAfterBackoff,
expectedExecutionCount: 1,
queueingHintMap: QueueingHintMapPerProfile{
"": {
framework.ClusterEvent{Resource: framework.Node, ActionType: framework.UpdateNodeLabel}: {
{
PluginName: "fooPlugin1",
QueueingHintFn: queueHintReturnQueueAfterBackoff,
PluginName: "fooPlugin1",
// It's only executed and interpreted as queueAfterBackoff.
// The function doesn't run other hints because this Pod doesn't have PendingPlugins.
QueueingHintFn: queueHintReturnQueue,
},
{
PluginName: "fooPlugin2",
QueueingHintFn: queueHintReturnQueueAfterBackoff,
QueueingHintFn: queueHintReturnQueue,
},
},
framework.ClusterEvent{Resource: framework.Node, ActionType: framework.Update}: {
{
PluginName: "fooPlugin1",
QueueingHintFn: queueHintReturnQueueAfterBackoff,
QueueingHintFn: queueHintReturnQueue,
},
},
NodeAdd: { // not executed because NodeAdd is unrelated.
{
PluginName: "fooPlugin1",
QueueingHintFn: queueHintReturnQueueAfterBackoff,
QueueingHintFn: queueHintReturnQueue,
},
},
},