1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: Apache-2.0
11 from unittest import mock
17 class KeysetTestHelper:
18 def __init__(self, expect):
22 def fn(self, **kwargs):
23 if self.expect[self.n][0] != kwargs:
24 raise Exception("Didn't match %s != %s" % (self.expect[self.n][0], kwargs))
27 def execute(self, num_retries):
29 return self.expect[self.n-1][1]
32 'uuid': 'zzzzz-zyyyz-zzzzzyyyyywwwww',
33 'name': 'KeysetListAllTestCase.test_select mock',
34 'created_at': '2023-08-28T12:34:56.123456Z',
37 class KeysetListAllTestCase(unittest.TestCase):
39 ks = KeysetTestHelper([[
40 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": []},
44 ls = list(arvados.util.keyset_list_all(ks.fn))
45 self.assertEqual(ls, [])
47 def test_oneitem(self):
48 ks = KeysetTestHelper([[
49 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": []},
50 {"items": [{"created_at": "1", "uuid": "1"}]}
52 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", "=", "1"], ["uuid", ">", "1"]]},
55 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", ">", "1"]]},
59 ls = list(arvados.util.keyset_list_all(ks.fn))
60 self.assertEqual(ls, [{"created_at": "1", "uuid": "1"}])
62 def test_onepage2(self):
63 ks = KeysetTestHelper([[
64 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": []},
65 {"items": [{"created_at": "1", "uuid": "1"}, {"created_at": "2", "uuid": "2"}]}
67 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", ">=", "2"], ["uuid", "!=", "2"]]},
71 ls = list(arvados.util.keyset_list_all(ks.fn))
72 self.assertEqual(ls, [{"created_at": "1", "uuid": "1"}, {"created_at": "2", "uuid": "2"}])
74 def test_onepage3(self):
75 ks = KeysetTestHelper([[
76 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": []},
77 {"items": [{"created_at": "1", "uuid": "1"}, {"created_at": "2", "uuid": "2"}, {"created_at": "3", "uuid": "3"}]}
79 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", ">=", "3"], ["uuid", "!=", "3"]]},
83 ls = list(arvados.util.keyset_list_all(ks.fn))
84 self.assertEqual(ls, [{"created_at": "1", "uuid": "1"}, {"created_at": "2", "uuid": "2"}, {"created_at": "3", "uuid": "3"}])
87 def test_twopage(self):
88 ks = KeysetTestHelper([[
89 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": []},
90 {"items": [{"created_at": "1", "uuid": "1"}, {"created_at": "2", "uuid": "2"}]}
92 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", ">=", "2"], ["uuid", "!=", "2"]]},
93 {"items": [{"created_at": "3", "uuid": "3"}, {"created_at": "4", "uuid": "4"}]}
95 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", ">=", "4"], ["uuid", "!=", "4"]]},
99 ls = list(arvados.util.keyset_list_all(ks.fn))
100 self.assertEqual(ls, [{"created_at": "1", "uuid": "1"},
101 {"created_at": "2", "uuid": "2"},
102 {"created_at": "3", "uuid": "3"},
103 {"created_at": "4", "uuid": "4"}
106 def test_repeated_key(self):
107 ks = KeysetTestHelper([[
108 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": []},
109 {"items": [{"created_at": "1", "uuid": "1"}, {"created_at": "2", "uuid": "2"}, {"created_at": "2", "uuid": "3"}]}
111 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", ">=", "2"], ["uuid", "!=", "3"]]},
112 {"items": [{"created_at": "2", "uuid": "2"}, {"created_at": "2", "uuid": "4"}]}
114 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", "=", "2"], ["uuid", ">", "4"]]},
117 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", ">", "2"]]},
118 {"items": [{"created_at": "3", "uuid": "5"}, {"created_at": "4", "uuid": "6"}]}
120 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", ">=", "4"], ["uuid", "!=", "6"]]},
125 ls = list(arvados.util.keyset_list_all(ks.fn))
126 self.assertEqual(ls, [{"created_at": "1", "uuid": "1"},
127 {"created_at": "2", "uuid": "2"},
128 {"created_at": "2", "uuid": "3"},
129 {"created_at": "2", "uuid": "4"},
130 {"created_at": "3", "uuid": "5"},
131 {"created_at": "4", "uuid": "6"}
134 def test_onepage_withfilter(self):
135 ks = KeysetTestHelper([[
136 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["foo", ">", "bar"]]},
137 {"items": [{"created_at": "1", "uuid": "1"}, {"created_at": "2", "uuid": "2"}]}
139 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", ">=", "2"], ["uuid", "!=", "2"], ["foo", ">", "bar"]]},
143 ls = list(arvados.util.keyset_list_all(ks.fn, filters=[["foo", ">", "bar"]]))
144 self.assertEqual(ls, [{"created_at": "1", "uuid": "1"}, {"created_at": "2", "uuid": "2"}])
146 def test_onepage_desc(self):
147 ks = KeysetTestHelper([[
148 {"limit": 1000, "count": "none", "order": ["created_at desc", "uuid desc"], "filters": []},
149 {"items": [{"created_at": "2", "uuid": "2"}, {"created_at": "1", "uuid": "1"}]}
151 {"limit": 1000, "count": "none", "order": ["created_at desc", "uuid desc"], "filters": [["created_at", "<=", "1"], ["uuid", "!=", "1"]]},
155 ls = list(arvados.util.keyset_list_all(ks.fn, ascending=False))
156 self.assertEqual(ls, [{"created_at": "2", "uuid": "2"}, {"created_at": "1", "uuid": "1"}])
158 @parameterized.parameterized.expand(zip(
159 itertools.cycle(_SELECT_FAKE_ITEM),
160 itertools.chain.from_iterable(
161 itertools.combinations(_SELECT_FAKE_ITEM, count)
162 for count in range(len(_SELECT_FAKE_ITEM) + 1)
165 def test_select(self, order_key, select):
166 # keyset_list_all must have both uuid and order_key to function.
167 # Test that it selects those fields along with user-specified ones.
168 expect_select = {'uuid', order_key, *select}
171 for key, value in _SELECT_FAKE_ITEM.items()
172 if key in expect_select
174 list_func = mock.Mock()
175 list_func().execute = mock.Mock(
182 list_func.reset_mock()
183 actual = list(arvados.util.keyset_list_all(list_func, order_key, select=list(select)))
184 self.assertEqual(actual, [item])
185 calls = list_func.call_args_list
186 self.assertTrue(len(calls) >= 2, "list_func() not called enough to exhaust items")
187 for args, kwargs in calls:
188 self.assertEqual(set(kwargs.get('select', ())), expect_select)