@@ -3,6 +3,7 @@ package removepodsviolatingtopologyspreadconstraint
3
3
import (
4
4
"context"
5
5
"fmt"
6
+ "reflect"
6
7
"sort"
7
8
"testing"
8
9
@@ -1476,6 +1477,231 @@ func TestTopologySpreadConstraint(t *testing.T) {
1476
1477
}
1477
1478
}
1478
1479
1480
+ func TestSortDomains (t * testing.T ) {
1481
+ tests := []struct {
1482
+ name string
1483
+ constraintTopology map [topologyPair ][]* v1.Pod
1484
+ want []topology
1485
+ }{
1486
+ {
1487
+ name : "empty input" ,
1488
+ constraintTopology : map [topologyPair ][]* v1.Pod {},
1489
+ want : []topology {},
1490
+ },
1491
+ {
1492
+ name : "single domain with mixed pods" ,
1493
+ constraintTopology : map [topologyPair ][]* v1.Pod {
1494
+ {"zone" , "a" }: {
1495
+ {
1496
+ ObjectMeta : metav1.ObjectMeta {
1497
+ Name : "non-evictable-pod" ,
1498
+ Annotations : map [string ]string {"evictable" : "false" },
1499
+ },
1500
+ },
1501
+ {
1502
+ ObjectMeta : metav1.ObjectMeta {
1503
+ Name : "evictable-with-affinity" ,
1504
+ Annotations : map [string ]string {"evictable" : "true" , "hasSelectorOrAffinity" : "true" },
1505
+ },
1506
+ Spec : v1.PodSpec {
1507
+ Priority : utilptr.To [int32 ](10 ),
1508
+ },
1509
+ },
1510
+ {
1511
+ ObjectMeta : metav1.ObjectMeta {
1512
+ Name : "evictable-high-priority" ,
1513
+ Annotations : map [string ]string {"evictable" : "true" },
1514
+ },
1515
+ Spec : v1.PodSpec {
1516
+ Priority : utilptr.To [int32 ](15 ),
1517
+ },
1518
+ },
1519
+ },
1520
+ },
1521
+ want : []topology {
1522
+ {pair : topologyPair {"zone" , "a" }, pods : []* v1.Pod {
1523
+ {
1524
+ ObjectMeta : metav1.ObjectMeta {
1525
+ Name : "non-evictable-pod" ,
1526
+ Annotations : map [string ]string {"evictable" : "false" },
1527
+ },
1528
+ },
1529
+ {
1530
+ ObjectMeta : metav1.ObjectMeta {
1531
+ Name : "evictable-with-affinity" ,
1532
+ Annotations : map [string ]string {"evictable" : "true" , "hasSelectorOrAffinity" : "true" },
1533
+ },
1534
+ Spec : v1.PodSpec {
1535
+ Priority : utilptr.To [int32 ](10 ),
1536
+ },
1537
+ },
1538
+ {
1539
+ ObjectMeta : metav1.ObjectMeta {
1540
+ Name : "evictable-high-priority" ,
1541
+ Annotations : map [string ]string {"evictable" : "true" },
1542
+ },
1543
+ Spec : v1.PodSpec {
1544
+ Priority : utilptr.To [int32 ](15 ),
1545
+ },
1546
+ },
1547
+ }},
1548
+ },
1549
+ },
1550
+ {
1551
+ name : "multiple domains with different priorities and selectors" ,
1552
+ constraintTopology : map [topologyPair ][]* v1.Pod {
1553
+ {"zone" , "a" }: {
1554
+ {
1555
+ ObjectMeta : metav1.ObjectMeta {
1556
+ Name : "high-priority-affinity" ,
1557
+ Annotations : map [string ]string {"evictable" : "true" },
1558
+ },
1559
+ Spec : v1.PodSpec {
1560
+ Priority : utilptr.To [int32 ](20 ),
1561
+ },
1562
+ },
1563
+ {
1564
+ ObjectMeta : metav1.ObjectMeta {
1565
+ Name : "low-priority-no-affinity" ,
1566
+ Annotations : map [string ]string {"evictable" : "true" },
1567
+ },
1568
+ Spec : v1.PodSpec {
1569
+ Priority : utilptr.To [int32 ](5 ),
1570
+ },
1571
+ },
1572
+ },
1573
+ {"zone" , "b" }: {
1574
+ {
1575
+ ObjectMeta : metav1.ObjectMeta {
1576
+ Name : "medium-priority-affinity" ,
1577
+ Annotations : map [string ]string {"evictable" : "true" },
1578
+ },
1579
+ Spec : v1.PodSpec {
1580
+ Priority : utilptr.To [int32 ](15 ),
1581
+ },
1582
+ },
1583
+ {
1584
+ ObjectMeta : metav1.ObjectMeta {
1585
+ Name : "non-evictable-pod" ,
1586
+ Annotations : map [string ]string {"evictable" : "false" },
1587
+ },
1588
+ },
1589
+ },
1590
+ },
1591
+ want : []topology {
1592
+ {pair : topologyPair {"zone" , "a" }, pods : []* v1.Pod {
1593
+ {
1594
+ ObjectMeta : metav1.ObjectMeta {
1595
+ Name : "low-priority-no-affinity" ,
1596
+ Annotations : map [string ]string {"evictable" : "true" },
1597
+ },
1598
+ Spec : v1.PodSpec {
1599
+ Priority : utilptr.To [int32 ](5 ),
1600
+ },
1601
+ },
1602
+ {
1603
+ ObjectMeta : metav1.ObjectMeta {
1604
+ Name : "high-priority-affinity" ,
1605
+ Annotations : map [string ]string {"evictable" : "true" },
1606
+ },
1607
+ Spec : v1.PodSpec {
1608
+ Priority : utilptr.To [int32 ](20 ),
1609
+ },
1610
+ },
1611
+ }},
1612
+ {pair : topologyPair {"zone" , "b" }, pods : []* v1.Pod {
1613
+ {
1614
+ ObjectMeta : metav1.ObjectMeta {
1615
+ Name : "non-evictable-pod" ,
1616
+ Annotations : map [string ]string {"evictable" : "false" },
1617
+ },
1618
+ },
1619
+ {
1620
+ ObjectMeta : metav1.ObjectMeta {
1621
+ Name : "medium-priority-affinity" ,
1622
+ Annotations : map [string ]string {"evictable" : "true" },
1623
+ },
1624
+ Spec : v1.PodSpec {
1625
+ Priority : utilptr.To [int32 ](15 ),
1626
+ },
1627
+ },
1628
+ }},
1629
+ },
1630
+ },
1631
+ {
1632
+ name : "domain with pods having different selector/affinity" ,
1633
+ constraintTopology : map [topologyPair ][]* v1.Pod {
1634
+ {"zone" , "a" }: {
1635
+ {
1636
+ ObjectMeta : metav1.ObjectMeta {
1637
+ Name : "pod-with-affinity" ,
1638
+ Annotations : map [string ]string {"evictable" : "true" },
1639
+ },
1640
+ Spec : v1.PodSpec {
1641
+ Affinity : & v1.Affinity {
1642
+ NodeAffinity : & v1.NodeAffinity {},
1643
+ },
1644
+ Priority : utilptr.To [int32 ](10 ),
1645
+ },
1646
+ },
1647
+ {
1648
+ ObjectMeta : metav1.ObjectMeta {
1649
+ Name : "pod-no-affinity" ,
1650
+ Annotations : map [string ]string {"evictable" : "true" },
1651
+ },
1652
+ Spec : v1.PodSpec {
1653
+ Priority : utilptr.To [int32 ](15 ),
1654
+ },
1655
+ },
1656
+ },
1657
+ },
1658
+ want : []topology {
1659
+ {pair : topologyPair {"zone" , "a" }, pods : []* v1.Pod {
1660
+ {
1661
+ ObjectMeta : metav1.ObjectMeta {
1662
+ Name : "pod-with-affinity" ,
1663
+ Annotations : map [string ]string {"evictable" : "true" },
1664
+ },
1665
+ Spec : v1.PodSpec {
1666
+ Affinity : & v1.Affinity {
1667
+ NodeAffinity : & v1.NodeAffinity {},
1668
+ },
1669
+ Priority : utilptr.To [int32 ](10 ),
1670
+ },
1671
+ },
1672
+ {
1673
+ ObjectMeta : metav1.ObjectMeta {
1674
+ Name : "pod-no-affinity" ,
1675
+ Annotations : map [string ]string {"evictable" : "true" },
1676
+ },
1677
+ Spec : v1.PodSpec {
1678
+ Priority : utilptr.To [int32 ](15 ),
1679
+ },
1680
+ },
1681
+ }},
1682
+ },
1683
+ },
1684
+ }
1685
+
1686
+ for _ , tt := range tests {
1687
+ t .Run (tt .name , func (t * testing.T ) {
1688
+ mockIsEvictable := func (pod * v1.Pod ) bool {
1689
+ if val , exists := pod .Annotations ["evictable" ]; exists {
1690
+ return val == "true"
1691
+ }
1692
+ return false
1693
+ }
1694
+ got := sortDomains (tt .constraintTopology , mockIsEvictable )
1695
+ sort .Slice (got , func (i , j int ) bool {
1696
+ return got [i ].pair .value < got [j ].pair .value
1697
+ })
1698
+ if ! reflect .DeepEqual (got , tt .want ) {
1699
+ t .Errorf ("sortDomains() = %v, want %v" , got , tt .want )
1700
+ }
1701
+ })
1702
+ }
1703
+ }
1704
+
1479
1705
type testPodList struct {
1480
1706
count int
1481
1707
node string
0 commit comments