@@ -1294,13 +1294,17 @@ func TestPriorityQueue_Delete(t *testing.T) {
1294
1294
}
1295
1295
1296
1296
func TestPriorityQueue_Activate (t * testing.T ) {
1297
+ metrics .Register ()
1297
1298
tests := []struct {
1298
1299
name string
1299
1300
qPodInfoInUnschedulablePods []* framework.QueuedPodInfo
1300
1301
qPodInfoInPodBackoffQ []* framework.QueuedPodInfo
1301
1302
qPodInActiveQ []* v1.Pod
1302
1303
qPodInfoToActivate * framework.QueuedPodInfo
1304
+ qPodInInFlightPod * v1.Pod
1305
+ expectedInFlightEvent * clusterEvent
1303
1306
want []* framework.QueuedPodInfo
1307
+ qHintEnabled bool
1304
1308
}{
1305
1309
{
1306
1310
name : "pod already in activeQ" ,
@@ -1313,6 +1317,21 @@ func TestPriorityQueue_Activate(t *testing.T) {
1313
1317
qPodInfoToActivate : & framework.QueuedPodInfo {PodInfo : highPriNominatedPodInfo },
1314
1318
want : []* framework.QueuedPodInfo {},
1315
1319
},
1320
+ {
1321
+ name : "[QHint] pod not in unschedulablePods/podBackoffQ but in-flight" ,
1322
+ qPodInfoToActivate : & framework.QueuedPodInfo {PodInfo : highPriNominatedPodInfo },
1323
+ qPodInInFlightPod : highPriNominatedPodInfo .Pod ,
1324
+ expectedInFlightEvent : & clusterEvent {oldObj : (* v1 .Pod )(nil ), newObj : highPriNominatedPodInfo .Pod , event : framework .EventForceActivate },
1325
+ want : []* framework.QueuedPodInfo {},
1326
+ qHintEnabled : true ,
1327
+ },
1328
+ {
1329
+ name : "[QHint] pod not in unschedulablePods/podBackoffQ and not in-flight" ,
1330
+ qPodInfoToActivate : & framework.QueuedPodInfo {PodInfo : highPriNominatedPodInfo },
1331
+ qPodInInFlightPod : medPriorityPodInfo .Pod , // different pod is in-flight
1332
+ want : []* framework.QueuedPodInfo {},
1333
+ qHintEnabled : true ,
1334
+ },
1316
1335
{
1317
1336
name : "pod in unschedulablePods" ,
1318
1337
qPodInfoInUnschedulablePods : []* framework.QueuedPodInfo {{PodInfo : highPriNominatedPodInfo }},
@@ -1329,12 +1348,30 @@ func TestPriorityQueue_Activate(t *testing.T) {
1329
1348
1330
1349
for _ , tt := range tests {
1331
1350
t .Run (tt .name , func (t * testing.T ) {
1351
+ featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , features .SchedulerQueueingHints , tt .qHintEnabled )
1332
1352
var objs []runtime.Object
1333
1353
logger , ctx := ktesting .NewTestContext (t )
1334
1354
ctx , cancel := context .WithCancel (ctx )
1335
1355
defer cancel ()
1336
1356
q := NewTestQueueWithObjects (ctx , newDefaultQueueSort (), objs )
1337
1357
1358
+ if tt .qPodInInFlightPod != nil {
1359
+ // Put -> Pop the Pod to make it registered in inFlightPods.
1360
+ q .activeQ .underLock (func (unlockedActiveQ unlockedActiveQueuer ) {
1361
+ unlockedActiveQ .AddOrUpdate (newQueuedPodInfoForLookup (tt .qPodInInFlightPod ))
1362
+ })
1363
+ p , err := q .activeQ .pop (logger )
1364
+ if err != nil {
1365
+ t .Fatalf ("Pop failed: %v" , err )
1366
+ }
1367
+ if p .Pod .Name != tt .qPodInInFlightPod .Name {
1368
+ t .Errorf ("Unexpected popped pod: %v" , p .Pod .Name )
1369
+ }
1370
+ if len (q .activeQ .listInFlightEvents ()) != 1 {
1371
+ t .Fatal ("Expected the pod to be recorded in in-flight events, but it doesn't" )
1372
+ }
1373
+ }
1374
+
1338
1375
// Prepare activeQ/unschedulablePods/podBackoffQ according to the table
1339
1376
for _ , qPod := range tt .qPodInActiveQ {
1340
1377
q .Add (logger , qPod )
@@ -1353,7 +1390,29 @@ func TestPriorityQueue_Activate(t *testing.T) {
1353
1390
1354
1391
// Check the result after activation by the length of activeQ
1355
1392
if wantLen := len (tt .want ); q .activeQ .len () != wantLen {
1356
- t .Errorf ("length compare: want %v, got %v" , wantLen , q .activeQ .len ())
1393
+ t .Fatalf ("length compare: want %v, got %v" , wantLen , q .activeQ .len ())
1394
+ }
1395
+
1396
+ if tt .expectedInFlightEvent != nil {
1397
+ if len (q .activeQ .listInFlightEvents ()) != 2 {
1398
+ t .Fatalf ("Expected two in-flight event to be recorded, but got %v events" , len (q .activeQ .listInFlightEvents ()))
1399
+ }
1400
+ found := false
1401
+ for _ , e := range q .activeQ .listInFlightEvents () {
1402
+ event , ok := e .(* clusterEvent )
1403
+ if ! ok {
1404
+ continue
1405
+ }
1406
+
1407
+ if d := cmp .Diff (tt .expectedInFlightEvent , event , cmpopts .EquateComparable (clusterEvent {})); d != "" {
1408
+ t .Fatalf ("Unexpected in-flight event (-want, +got):\n %s" , d )
1409
+ }
1410
+ found = true
1411
+ }
1412
+
1413
+ if ! found {
1414
+ t .Fatalf ("Expected in-flight event to be recorded, but it wasn't." )
1415
+ }
1357
1416
}
1358
1417
1359
1418
// Check if the specific pod exists in activeQ
@@ -3779,6 +3838,7 @@ func mustNewPodInfo(pod *v1.Pod) *framework.PodInfo {
3779
3838
3780
3839
// Test_isPodWorthRequeuing tests isPodWorthRequeuing function.
3781
3840
func Test_isPodWorthRequeuing (t * testing.T ) {
3841
+ metrics .Register ()
3782
3842
count := 0
3783
3843
queueHintReturnQueue := func (logger klog.Logger , pod * v1.Pod , oldObj , newObj interface {}) (framework.QueueingHint , error ) {
3784
3844
count ++
@@ -3857,11 +3917,37 @@ func Test_isPodWorthRequeuing(t *testing.T) {
3857
3917
},
3858
3918
event : framework .EventUnschedulableTimeout ,
3859
3919
oldObj : nil ,
3860
- newObj : st . MakeNode (). Obj () ,
3920
+ newObj : nil ,
3861
3921
expected : queueAfterBackoff ,
3862
3922
expectedExecutionCount : 0 ,
3863
3923
queueingHintMap : QueueingHintMapPerProfile {},
3864
3924
},
3925
+ {
3926
+ name : "return Queue when the event is wildcard and the wildcard targets the pod to be requeued right now" ,
3927
+ podInfo : & framework.QueuedPodInfo {
3928
+ UnschedulablePlugins : sets .New ("fooPlugin1" ),
3929
+ PodInfo : mustNewPodInfo (st .MakePod ().Name ("pod1" ).Namespace ("ns1" ).UID ("1" ).Obj ()),
3930
+ },
3931
+ event : framework .EventForceActivate ,
3932
+ oldObj : nil ,
3933
+ newObj : st .MakePod ().Name ("pod1" ).Namespace ("ns1" ).UID ("1" ).Obj (),
3934
+ expected : queueAfterBackoff ,
3935
+ expectedExecutionCount : 0 ,
3936
+ queueingHintMap : QueueingHintMapPerProfile {},
3937
+ },
3938
+ {
3939
+ name : "return Skip when the event is wildcard, but the wildcard targets a different pod" ,
3940
+ podInfo : & framework.QueuedPodInfo {
3941
+ UnschedulablePlugins : sets .New ("fooPlugin1" ),
3942
+ PodInfo : mustNewPodInfo (st .MakePod ().Name ("pod1" ).Namespace ("ns1" ).UID ("1" ).Obj ()),
3943
+ },
3944
+ event : framework .EventForceActivate ,
3945
+ oldObj : nil ,
3946
+ newObj : st .MakePod ().Name ("pod-different" ).Namespace ("ns2" ).UID ("2" ).Obj (),
3947
+ expected : queueSkip ,
3948
+ expectedExecutionCount : 0 ,
3949
+ queueingHintMap : QueueingHintMapPerProfile {},
3950
+ },
3865
3951
{
3866
3952
name : "interprets Queue from the Pending plugin as queueImmediately" ,
3867
3953
podInfo : & framework.QueuedPodInfo {
0 commit comments