@@ -1443,24 +1443,28 @@ func (pl *preEnqueuePlugin) PreEnqueue(ctx context.Context, p *v1.Pod) *framewor
1443
1443
return framework .NewStatus (framework .UnschedulableAndUnresolvable , "pod name not in allowlists" )
1444
1444
}
1445
1445
1446
- func TestPriorityQueue_addToActiveQ (t * testing.T ) {
1446
+ func TestPriorityQueue_moveToActiveQ (t * testing.T ) {
1447
1447
tests := []struct {
1448
- name string
1449
- plugins []framework.PreEnqueuePlugin
1450
- pod * v1.Pod
1451
- wantUnschedulablePods int
1452
- wantSuccess bool
1448
+ name string
1449
+ plugins []framework.PreEnqueuePlugin
1450
+ pod * v1.Pod
1451
+ event string
1452
+ popFromBackoffQEnabled []bool
1453
+ wantUnschedulablePods int
1454
+ wantSuccess bool
1453
1455
}{
1454
1456
{
1455
1457
name : "no plugins registered" ,
1456
1458
pod : st .MakePod ().Name ("p" ).Label ("p" , "" ).Obj (),
1459
+ event : framework .EventUnscheduledPodAdd .Label (),
1457
1460
wantUnschedulablePods : 0 ,
1458
1461
wantSuccess : true ,
1459
1462
},
1460
1463
{
1461
1464
name : "preEnqueue plugin registered, pod name not in allowlists" ,
1462
1465
plugins : []framework.PreEnqueuePlugin {& preEnqueuePlugin {}, & preEnqueuePlugin {}},
1463
1466
pod : st .MakePod ().Name ("p" ).Label ("p" , "" ).Obj (),
1467
+ event : framework .EventUnscheduledPodAdd .Label (),
1464
1468
wantUnschedulablePods : 1 ,
1465
1469
wantSuccess : false ,
1466
1470
},
@@ -1471,47 +1475,178 @@ func TestPriorityQueue_addToActiveQ(t *testing.T) {
1471
1475
& preEnqueuePlugin {allowlists : []string {"foo" }},
1472
1476
},
1473
1477
pod : st .MakePod ().Name ("bar" ).Label ("bar" , "" ).Obj (),
1478
+ event : framework .EventUnscheduledPodAdd .Label (),
1474
1479
wantUnschedulablePods : 1 ,
1475
1480
wantSuccess : false ,
1476
1481
},
1482
+ {
1483
+ // With SchedulerPopFromBackoffQ enabled, the queue assumes the pod has already passed PreEnqueue,
1484
+ // and it doesn't run PreEnqueue again, always puts the pod to activeQ.
1485
+ name : "preEnqueue plugin registered, preEnqueue plugin would reject the pod, but isn't run" ,
1486
+ plugins : []framework.PreEnqueuePlugin {
1487
+ & preEnqueuePlugin {allowlists : []string {"foo" , "bar" }},
1488
+ & preEnqueuePlugin {allowlists : []string {"foo" }},
1489
+ },
1490
+ pod : st .MakePod ().Name ("bar" ).Label ("bar" , "" ).Obj (),
1491
+ event : framework .BackoffComplete ,
1492
+ popFromBackoffQEnabled : []bool {false },
1493
+ wantUnschedulablePods : 1 ,
1494
+ wantSuccess : false ,
1495
+ },
1496
+ {
1497
+ name : "preEnqueue plugin registered, pod would fail one preEnqueue plugin, but is after backoff" ,
1498
+ plugins : []framework.PreEnqueuePlugin {
1499
+ & preEnqueuePlugin {allowlists : []string {"foo" , "bar" }},
1500
+ & preEnqueuePlugin {allowlists : []string {"foo" }},
1501
+ },
1502
+ pod : st .MakePod ().Name ("bar" ).Label ("bar" , "" ).Obj (),
1503
+ event : framework .BackoffComplete ,
1504
+ popFromBackoffQEnabled : []bool {true },
1505
+ wantUnschedulablePods : 0 ,
1506
+ wantSuccess : true ,
1507
+ },
1477
1508
{
1478
1509
name : "preEnqueue plugin registered, pod passed all preEnqueue plugins" ,
1479
1510
plugins : []framework.PreEnqueuePlugin {
1480
1511
& preEnqueuePlugin {allowlists : []string {"foo" , "bar" }},
1481
1512
& preEnqueuePlugin {allowlists : []string {"bar" }},
1482
1513
},
1483
1514
pod : st .MakePod ().Name ("bar" ).Label ("bar" , "" ).Obj (),
1515
+ event : framework .EventUnscheduledPodAdd .Label (),
1484
1516
wantUnschedulablePods : 0 ,
1485
1517
wantSuccess : true ,
1486
1518
},
1487
1519
}
1488
1520
1489
1521
for _ , tt := range tests {
1490
- t .Run (tt .name , func (t * testing.T ) {
1491
- logger , ctx := ktesting .NewTestContext (t )
1492
- ctx , cancel := context .WithCancel (ctx )
1493
- defer cancel ()
1522
+ if tt .popFromBackoffQEnabled == nil {
1523
+ tt .popFromBackoffQEnabled = []bool {true , false }
1524
+ }
1525
+ for _ , popFromBackoffQEnabled := range tt .popFromBackoffQEnabled {
1526
+ t .Run (fmt .Sprintf ("%s popFromBackoffQEnabled(%v)" , tt .name , popFromBackoffQEnabled ), func (t * testing.T ) {
1527
+ featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , features .SchedulerPopFromBackoffQ , popFromBackoffQEnabled )
1528
+ logger , ctx := ktesting .NewTestContext (t )
1529
+ ctx , cancel := context .WithCancel (ctx )
1530
+ defer cancel ()
1494
1531
1495
- m := map [string ][]framework.PreEnqueuePlugin {"" : tt .plugins }
1496
- q := NewTestQueueWithObjects (ctx , newDefaultQueueSort (), []runtime.Object {tt .pod }, WithPreEnqueuePluginMap (m ),
1497
- WithPodInitialBackoffDuration (time .Second * 30 ), WithPodMaxBackoffDuration (time .Second * 60 ))
1498
- got := q .moveToActiveQ (logger , q .newQueuedPodInfo (tt .pod ), framework . EventUnscheduledPodAdd . Label () )
1499
- if got != tt .wantSuccess {
1500
- t .Errorf ("Unexpected result: want %v, but got %v" , tt .wantSuccess , got )
1501
- }
1502
- if tt .wantUnschedulablePods != len (q .unschedulablePods .podInfoMap ) {
1503
- t .Errorf ("Unexpected unschedulablePods: want %v, but got %v" , tt .wantUnschedulablePods , len (q .unschedulablePods .podInfoMap ))
1504
- }
1532
+ m := map [string ][]framework.PreEnqueuePlugin {"" : tt .plugins }
1533
+ q := NewTestQueueWithObjects (ctx , newDefaultQueueSort (), []runtime.Object {tt .pod }, WithPreEnqueuePluginMap (m ),
1534
+ WithPodInitialBackoffDuration (time .Second * 30 ), WithPodMaxBackoffDuration (time .Second * 60 ))
1535
+ got := q .moveToActiveQ (logger , q .newQueuedPodInfo (tt .pod ), tt . event )
1536
+ if got != tt .wantSuccess {
1537
+ t .Errorf ("Unexpected result: want %v, but got %v" , tt .wantSuccess , got )
1538
+ }
1539
+ if tt .wantUnschedulablePods != len (q .unschedulablePods .podInfoMap ) {
1540
+ t .Errorf ("Unexpected unschedulablePods: want %v, but got %v" , tt .wantUnschedulablePods , len (q .unschedulablePods .podInfoMap ))
1541
+ }
1505
1542
1506
- // Simulate an update event.
1507
- clone := tt .pod .DeepCopy ()
1508
- metav1 .SetMetaDataAnnotation (& clone .ObjectMeta , "foo" , "" )
1509
- q .Update (logger , tt .pod , clone )
1510
- // Ensure the pod is still located in unschedulablePods.
1511
- if tt .wantUnschedulablePods != len (q .unschedulablePods .podInfoMap ) {
1512
- t .Errorf ("Unexpected unschedulablePods: want %v, but got %v" , tt .wantUnschedulablePods , len (q .unschedulablePods .podInfoMap ))
1513
- }
1514
- })
1543
+ // Simulate an update event.
1544
+ clone := tt .pod .DeepCopy ()
1545
+ metav1 .SetMetaDataAnnotation (& clone .ObjectMeta , "foo" , "" )
1546
+ q .Update (logger , tt .pod , clone )
1547
+ // Ensure the pod is still located in unschedulablePods.
1548
+ if tt .wantUnschedulablePods != len (q .unschedulablePods .podInfoMap ) {
1549
+ t .Errorf ("Unexpected unschedulablePods: want %v, but got %v" , tt .wantUnschedulablePods , len (q .unschedulablePods .podInfoMap ))
1550
+ }
1551
+ })
1552
+ }
1553
+ }
1554
+ }
1555
+
1556
+ func TestPriorityQueue_moveToBackoffQ (t * testing.T ) {
1557
+ tests := []struct {
1558
+ name string
1559
+ plugins []framework.PreEnqueuePlugin
1560
+ pod * v1.Pod
1561
+ popFromBackoffQEnabled []bool
1562
+ wantSuccess bool
1563
+ }{
1564
+ {
1565
+ name : "no plugins registered" ,
1566
+ pod : st .MakePod ().Name ("p" ).Label ("p" , "" ).Obj (),
1567
+ wantSuccess : true ,
1568
+ },
1569
+ {
1570
+ name : "preEnqueue plugin registered, pod name would not be in allowlists" ,
1571
+ plugins : []framework.PreEnqueuePlugin {& preEnqueuePlugin {}, & preEnqueuePlugin {}},
1572
+ pod : st .MakePod ().Name ("p" ).Label ("p" , "" ).Obj (),
1573
+ popFromBackoffQEnabled : []bool {false },
1574
+ wantSuccess : true ,
1575
+ },
1576
+ {
1577
+ name : "preEnqueue plugin registered, pod name not in allowlists" ,
1578
+ plugins : []framework.PreEnqueuePlugin {& preEnqueuePlugin {}, & preEnqueuePlugin {}},
1579
+ pod : st .MakePod ().Name ("p" ).Label ("p" , "" ).Obj (),
1580
+ popFromBackoffQEnabled : []bool {true },
1581
+ wantSuccess : false ,
1582
+ },
1583
+ {
1584
+ name : "preEnqueue plugin registered, preEnqueue plugin would reject the pod, but isn't run" ,
1585
+ plugins : []framework.PreEnqueuePlugin {
1586
+ & preEnqueuePlugin {allowlists : []string {"foo" , "bar" }},
1587
+ & preEnqueuePlugin {allowlists : []string {"foo" }},
1588
+ },
1589
+ pod : st .MakePod ().Name ("bar" ).Label ("bar" , "" ).Obj (),
1590
+ popFromBackoffQEnabled : []bool {false },
1591
+ wantSuccess : true ,
1592
+ },
1593
+ {
1594
+ name : "preEnqueue plugin registered, pod failed one preEnqueue plugin" ,
1595
+ plugins : []framework.PreEnqueuePlugin {
1596
+ & preEnqueuePlugin {allowlists : []string {"foo" , "bar" }},
1597
+ & preEnqueuePlugin {allowlists : []string {"foo" }},
1598
+ },
1599
+ pod : st .MakePod ().Name ("bar" ).Label ("bar" , "" ).Obj (),
1600
+ popFromBackoffQEnabled : []bool {true },
1601
+ wantSuccess : false ,
1602
+ },
1603
+ {
1604
+ name : "preEnqueue plugin registered, pod passed all preEnqueue plugins" ,
1605
+ plugins : []framework.PreEnqueuePlugin {
1606
+ & preEnqueuePlugin {allowlists : []string {"foo" , "bar" }},
1607
+ & preEnqueuePlugin {allowlists : []string {"bar" }},
1608
+ },
1609
+ pod : st .MakePod ().Name ("bar" ).Label ("bar" , "" ).Obj (),
1610
+ wantSuccess : true ,
1611
+ },
1612
+ }
1613
+
1614
+ for _ , tt := range tests {
1615
+ if tt .popFromBackoffQEnabled == nil {
1616
+ tt .popFromBackoffQEnabled = []bool {true , false }
1617
+ }
1618
+ for _ , popFromBackoffQEnabled := range tt .popFromBackoffQEnabled {
1619
+ t .Run (fmt .Sprintf ("%s popFromBackoffQEnabled(%v)" , tt .name , popFromBackoffQEnabled ), func (t * testing.T ) {
1620
+ featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , features .SchedulerPopFromBackoffQ , popFromBackoffQEnabled )
1621
+ logger , ctx := ktesting .NewTestContext (t )
1622
+ ctx , cancel := context .WithCancel (ctx )
1623
+ defer cancel ()
1624
+
1625
+ m := map [string ][]framework.PreEnqueuePlugin {"" : tt .plugins }
1626
+ q := NewTestQueueWithObjects (ctx , newDefaultQueueSort (), []runtime.Object {tt .pod }, WithPreEnqueuePluginMap (m ),
1627
+ WithPodInitialBackoffDuration (time .Second * 30 ), WithPodMaxBackoffDuration (time .Second * 60 ))
1628
+ pInfo := q .newQueuedPodInfo (tt .pod )
1629
+ got := q .moveToBackoffQ (logger , pInfo , framework .EventUnscheduledPodAdd .Label ())
1630
+ if got != tt .wantSuccess {
1631
+ t .Errorf ("Unexpected result: want %v, but got %v" , tt .wantSuccess , got )
1632
+ }
1633
+ if tt .wantSuccess {
1634
+ if ! q .backoffQ .has (pInfo ) {
1635
+ t .Errorf ("Expected pod to be in backoffQ, but it isn't" )
1636
+ }
1637
+ if q .unschedulablePods .get (pInfo .Pod ) != nil {
1638
+ t .Errorf ("Expected pod not to be in unschedulablePods, but it is" )
1639
+ }
1640
+ } else {
1641
+ if q .backoffQ .has (pInfo ) {
1642
+ t .Errorf ("Expected pod not to be in backoffQ, but it is" )
1643
+ }
1644
+ if q .unschedulablePods .get (pInfo .Pod ) == nil {
1645
+ t .Errorf ("Expected pod to be in unschedulablePods, but it isn't" )
1646
+ }
1647
+ }
1648
+ })
1649
+ }
1515
1650
}
1516
1651
}
1517
1652
0 commit comments