@@ -1512,8 +1512,8 @@ func TestNewListOptionIndexerTypeGuidance(t *testing.T) {
15121512 for _ , test := range tests {
15131513 t .Run (test .description , func (t * testing.T ) {
15141514 loi , dbPath , err := makeListOptionIndexer (t .Context (), gvk , test .opts , false , namespaceList )
1515- defer cleanTempFiles (dbPath )
15161515 require .NoError (t , err )
1516+ defer cleanTempFiles (dbPath )
15171517
15181518 for _ , item := range itemList .Items {
15191519 err = loi .Add (& item )
@@ -1553,6 +1553,261 @@ func TestNewListOptionIndexerTypeGuidance(t *testing.T) {
15531553 }
15541554}
15551555
1556+ // Tests to verify we can sort on say pods on `spec.containers.image[i]`
1557+ func TestSortPodsOnArrayAccess (t * testing.T ) {
1558+ ctx := context .Background ()
1559+ podGVK := schema.GroupVersionKind {
1560+ Group : "" ,
1561+ Version : "v1" ,
1562+ Kind : "Pod" ,
1563+ }
1564+ make_pod_obj := func (name , image1 , image2 string ) map [string ]any {
1565+ containers := make (map [string ]any )
1566+ if image2 != "" {
1567+ containers ["image" ] = image1 + "|" + image2
1568+ } else {
1569+ containers ["image" ] = image1
1570+ }
1571+ return map [string ]any {
1572+ "metadata" : map [string ]any {
1573+ "name" : name ,
1574+ "namespace" : "ns-a" ,
1575+ },
1576+ "spec" : map [string ]any {
1577+ "containers" : containers ,
1578+ },
1579+ }
1580+ }
1581+ canoe_twix_ritter := make_pod_obj ("canoe" , "twix" , "ritter" )
1582+ catamaran_flake_none := make_pod_obj ("catamaran" , "flake" , "" )
1583+ clipper_butterfinger_payday := make_pod_obj ("clipper" , "butterfinger" , "payday" )
1584+ ferry_twix_yorkie := make_pod_obj ("ferry" , "twix" , "yorkie" )
1585+ hydrofoil_coffeecrisp_ritter := make_pod_obj ("hydrofoil" , "coffeecrisp" , "ritter" )
1586+ kayak_butterfinger_rocher := make_pod_obj ("kayak" , "butterfinger" , "rocher" )
1587+ raft_almondjoy_ragusa := make_pod_obj ("raft" , "almondjoy" , "ragusa" )
1588+ schooner_twix_mounds := make_pod_obj ("schooner" , "twix" , "mounds" )
1589+ sloop_snickers_toblerone := make_pod_obj ("sloop" , "snickers" , "toblerone" )
1590+ trawler_butterfinger_aero := make_pod_obj ("trawler" , "butterfinger" , "aero" )
1591+
1592+ allObjects := []map [string ]any {
1593+ canoe_twix_ritter ,
1594+ catamaran_flake_none ,
1595+ clipper_butterfinger_payday ,
1596+ ferry_twix_yorkie ,
1597+ hydrofoil_coffeecrisp_ritter ,
1598+ kayak_butterfinger_rocher ,
1599+ raft_almondjoy_ragusa ,
1600+ schooner_twix_mounds ,
1601+ sloop_snickers_toblerone ,
1602+ trawler_butterfinger_aero ,
1603+ }
1604+ ns_a := map [string ]any {
1605+ "metadata" : map [string ]any {
1606+ "name" : "ns-a" ,
1607+ },
1608+ }
1609+ ns_b := map [string ]any {
1610+ "metadata" : map [string ]any {
1611+ "name" : "ns-b" ,
1612+ },
1613+ }
1614+
1615+ itemList := makeList (t , allObjects ... )
1616+ namespaceList := makeList (t , ns_a , ns_b )
1617+ fields := [][]string {
1618+ {"spec" , "containers" , "image" },
1619+ }
1620+
1621+ type testCase struct {
1622+ description string
1623+ listOptions sqltypes.ListOptions
1624+ expectedList * unstructured.UnstructuredList
1625+ expectedTotal int
1626+ }
1627+
1628+ tests := make ([]testCase , 0 )
1629+ tests = append (tests , testCase {
1630+ description : "can select for a specific first image" ,
1631+ listOptions : sqltypes.ListOptions {
1632+ Filters : []sqltypes.OrFilter {
1633+ {
1634+ []sqltypes.Filter {
1635+ {
1636+ Field : []string {"spec" , "containers" , "image" , "0" },
1637+ Matches : []string {"butterfinger" },
1638+ Op : sqltypes .Eq ,
1639+ },
1640+ },
1641+ },
1642+ },
1643+ SortList : sqltypes.SortList {
1644+ SortDirectives : []sqltypes.Sort {
1645+ {
1646+ Fields : []string {"metadata" , "name" },
1647+ Order : sqltypes .ASC ,
1648+ },
1649+ },
1650+ },
1651+ },
1652+ expectedList : makeList (t , clipper_butterfinger_payday , kayak_butterfinger_rocher , trawler_butterfinger_aero ),
1653+ expectedTotal : 3 ,
1654+ })
1655+ tests = append (tests , testCase {
1656+ description : "can select for a specific second image" ,
1657+ listOptions : sqltypes.ListOptions {
1658+ Filters : []sqltypes.OrFilter {
1659+ {
1660+ []sqltypes.Filter {
1661+ {
1662+ Field : []string {"spec" , "containers" , "image" , "1" },
1663+ Matches : []string {"toblerone" },
1664+ Op : sqltypes .Eq ,
1665+ },
1666+ },
1667+ },
1668+ },
1669+ SortList : sqltypes.SortList {
1670+ SortDirectives : []sqltypes.Sort {
1671+ {
1672+ Fields : []string {"metadata" , "name" },
1673+ Order : sqltypes .ASC ,
1674+ },
1675+ },
1676+ },
1677+ },
1678+ expectedList : makeList (t , sloop_snickers_toblerone ),
1679+ expectedTotal : 1 ,
1680+ })
1681+ tests = append (tests , testCase {
1682+ description : "can sort on the first image" ,
1683+ listOptions : sqltypes.ListOptions {
1684+ SortList : sqltypes.SortList {
1685+ SortDirectives : []sqltypes.Sort {
1686+ {
1687+ Fields : []string {"spec" , "containers" , "image" , "0" },
1688+ Order : sqltypes .ASC ,
1689+ },
1690+ {
1691+ Fields : []string {"metadata" , "name" },
1692+ Order : sqltypes .ASC ,
1693+ },
1694+ },
1695+ },
1696+ },
1697+ expectedList : makeList (t ,
1698+ raft_almondjoy_ragusa ,
1699+ clipper_butterfinger_payday ,
1700+ kayak_butterfinger_rocher ,
1701+ trawler_butterfinger_aero ,
1702+ hydrofoil_coffeecrisp_ritter ,
1703+ catamaran_flake_none ,
1704+ sloop_snickers_toblerone ,
1705+ canoe_twix_ritter ,
1706+ ferry_twix_yorkie ,
1707+ schooner_twix_mounds ,
1708+ ),
1709+ expectedTotal : len (allObjects ),
1710+ })
1711+ tests = append (tests , testCase {
1712+ description : "can select for any second image" ,
1713+ listOptions : sqltypes.ListOptions {
1714+ Filters : []sqltypes.OrFilter {
1715+ {
1716+ []sqltypes.Filter {
1717+ {
1718+ Field : []string {"spec" , "containers" , "image" , "1" },
1719+ Matches : []string {"" },
1720+ Op : sqltypes .NotEq ,
1721+ },
1722+ },
1723+ },
1724+ },
1725+ SortList : sqltypes.SortList {
1726+ SortDirectives : []sqltypes.Sort {
1727+ {
1728+ Fields : []string {"metadata" , "name" },
1729+ Order : sqltypes .ASC ,
1730+ },
1731+ },
1732+ },
1733+ },
1734+ expectedList : makeList (t , canoe_twix_ritter ,
1735+ clipper_butterfinger_payday ,
1736+ ferry_twix_yorkie ,
1737+ hydrofoil_coffeecrisp_ritter ,
1738+ kayak_butterfinger_rocher ,
1739+ raft_almondjoy_ragusa ,
1740+ schooner_twix_mounds ,
1741+ sloop_snickers_toblerone ,
1742+ trawler_butterfinger_aero ,
1743+ ),
1744+ expectedTotal : 9 ,
1745+ })
1746+ tests = append (tests , testCase {
1747+ description : "can sort on the second image (when present)" ,
1748+ listOptions : sqltypes.ListOptions {
1749+ Filters : []sqltypes.OrFilter {
1750+ {
1751+ []sqltypes.Filter {
1752+ {
1753+ Field : []string {"spec" , "containers" , "image" , "1" },
1754+ Matches : []string {"" },
1755+ Op : sqltypes .NotEq ,
1756+ },
1757+ },
1758+ },
1759+ },
1760+ SortList : sqltypes.SortList {
1761+ SortDirectives : []sqltypes.Sort {
1762+ {
1763+ Fields : []string {"spec" , "containers" , "image" , "1" },
1764+ Order : sqltypes .ASC ,
1765+ },
1766+ {
1767+ Fields : []string {"metadata" , "name" },
1768+ Order : sqltypes .ASC ,
1769+ },
1770+ },
1771+ },
1772+ },
1773+ expectedList : makeList (t ,
1774+ trawler_butterfinger_aero ,
1775+ schooner_twix_mounds ,
1776+ clipper_butterfinger_payday ,
1777+ raft_almondjoy_ragusa ,
1778+ canoe_twix_ritter ,
1779+ hydrofoil_coffeecrisp_ritter ,
1780+ kayak_butterfinger_rocher ,
1781+ sloop_snickers_toblerone ,
1782+ ferry_twix_yorkie ,
1783+ ),
1784+ expectedTotal : 9 ,
1785+ })
1786+
1787+ t .Parallel ()
1788+ for _ , test := range tests {
1789+ t .Run (test .description , func (t * testing.T ) {
1790+ opts := ListOptionIndexerOptions {
1791+ Fields : fields ,
1792+ IsNamespaced : true ,
1793+ }
1794+ loi , dbPath , err := makeListOptionIndexer (ctx , podGVK , opts , false , namespaceList )
1795+ require .NoError (t , err )
1796+ defer cleanTempFiles (dbPath )
1797+
1798+ for _ , item := range itemList .Items {
1799+ err = loi .Add (& item )
1800+ require .NoError (t , err )
1801+ }
1802+ list , total , _ , err := loi .ListByOptions (ctx , & test .listOptions , []partition.Partition {{All : true }}, "" )
1803+ require .NoError (t , err )
1804+
1805+ assert .Equal (t , test .expectedTotal , total )
1806+ assert .Equal (t , test .expectedList , list )
1807+ })
1808+ }
1809+ }
1810+
15561811func TestDropAll (t * testing.T ) {
15571812 ctx := t .Context ()
15581813
0 commit comments