Skip to content

Commit bccbf23

Browse files
Add tests to verify we can filter and sort on implicitly-indexed arrays. (#883)
1 parent 6008da4 commit bccbf23

File tree

1 file changed

+256
-1
lines changed

1 file changed

+256
-1
lines changed

pkg/sqlcache/informer/listoption_indexer_test.go

Lines changed: 256 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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+
15561811
func TestDropAll(t *testing.T) {
15571812
ctx := t.Context()
15581813

0 commit comments

Comments
 (0)