1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: Apache-2.0
12 from unittest import mock
17 class KeysetTestHelper:
18 def __init__(self, expect, expect_num_retries=0):
21 self.expect_num_retries = expect_num_retries
23 def fn(self, **kwargs):
24 assert kwargs == self.expect[self.n][0]
27 def execute(self, num_retries):
28 assert num_retries == self.expect_num_retries
30 return self.expect[self.n-1][1]
33 'uuid': 'zzzzz-zyyyz-zzzzzyyyyywwwww',
34 'name': 'KeysetListAllTestCase.test_select mock',
35 'created_at': '2023-08-28T12:34:56.123456Z',
38 _FAKE_COMPUTED_PERMISSIONS_ITEM = {
39 'user_uuid': 'zzzzz-zyyyz-zzzzzyyyyywwwww',
40 'target_uuid': 'zzzzz-ttttt-xxxxxyyyyyzzzzz',
41 'perm_level': 'can_write',
44 class KeysetListAllTestCase(unittest.TestCase):
46 ks = KeysetTestHelper([[
47 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": []},
51 ls = list(arvados.util.keyset_list_all(ks.fn))
52 self.assertEqual(ls, [])
54 def test_oneitem(self):
55 ks = KeysetTestHelper([[
56 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": []},
57 {"items": [{"created_at": "1", "uuid": "1"}]}
59 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", "=", "1"], ["uuid", ">", "1"]]},
62 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", ">", "1"]]},
66 ls = list(arvados.util.keyset_list_all(ks.fn))
67 self.assertEqual(ls, [{"created_at": "1", "uuid": "1"}])
69 def test_onepage2(self):
70 ks = KeysetTestHelper([[
71 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": []},
72 {"items": [{"created_at": "1", "uuid": "1"}, {"created_at": "2", "uuid": "2"}]}
74 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", ">=", "2"], ["uuid", "!=", "2"]]},
78 ls = list(arvados.util.keyset_list_all(ks.fn))
79 self.assertEqual(ls, [{"created_at": "1", "uuid": "1"}, {"created_at": "2", "uuid": "2"}])
81 def test_onepage3(self):
82 ks = KeysetTestHelper([[
83 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": []},
84 {"items": [{"created_at": "1", "uuid": "1"}, {"created_at": "2", "uuid": "2"}, {"created_at": "3", "uuid": "3"}]}
86 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", ">=", "3"], ["uuid", "!=", "3"]]},
90 ls = list(arvados.util.keyset_list_all(ks.fn))
91 self.assertEqual(ls, [{"created_at": "1", "uuid": "1"}, {"created_at": "2", "uuid": "2"}, {"created_at": "3", "uuid": "3"}])
94 def test_twopage(self):
95 ks = KeysetTestHelper([[
96 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": []},
97 {"items": [{"created_at": "1", "uuid": "1"}, {"created_at": "2", "uuid": "2"}]}
99 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", ">=", "2"], ["uuid", "!=", "2"]]},
100 {"items": [{"created_at": "3", "uuid": "3"}, {"created_at": "4", "uuid": "4"}]}
102 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", ">=", "4"], ["uuid", "!=", "4"]]},
106 ls = list(arvados.util.keyset_list_all(ks.fn))
107 self.assertEqual(ls, [{"created_at": "1", "uuid": "1"},
108 {"created_at": "2", "uuid": "2"},
109 {"created_at": "3", "uuid": "3"},
110 {"created_at": "4", "uuid": "4"}
113 def test_repeated_key(self):
114 ks = KeysetTestHelper([[
115 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": []},
116 {"items": [{"created_at": "1", "uuid": "1"}, {"created_at": "2", "uuid": "2"}, {"created_at": "2", "uuid": "3"}]}
118 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", ">=", "2"], ["uuid", "!=", "3"]]},
119 {"items": [{"created_at": "2", "uuid": "2"}, {"created_at": "2", "uuid": "4"}]}
121 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", "=", "2"], ["uuid", ">", "4"]]},
124 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", ">", "2"]]},
125 {"items": [{"created_at": "3", "uuid": "5"}, {"created_at": "4", "uuid": "6"}]}
127 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", ">=", "4"], ["uuid", "!=", "6"]]},
132 ls = list(arvados.util.keyset_list_all(ks.fn))
133 self.assertEqual(ls, [{"created_at": "1", "uuid": "1"},
134 {"created_at": "2", "uuid": "2"},
135 {"created_at": "2", "uuid": "3"},
136 {"created_at": "2", "uuid": "4"},
137 {"created_at": "3", "uuid": "5"},
138 {"created_at": "4", "uuid": "6"}
141 def test_onepage_withfilter(self):
142 ks = KeysetTestHelper([[
143 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["foo", ">", "bar"]]},
144 {"items": [{"created_at": "1", "uuid": "1"}, {"created_at": "2", "uuid": "2"}]}
146 {"limit": 1000, "count": "none", "order": ["created_at asc", "uuid asc"], "filters": [["created_at", ">=", "2"], ["uuid", "!=", "2"], ["foo", ">", "bar"]]},
150 ls = list(arvados.util.keyset_list_all(ks.fn, filters=[["foo", ">", "bar"]]))
151 self.assertEqual(ls, [{"created_at": "1", "uuid": "1"}, {"created_at": "2", "uuid": "2"}])
153 def test_onepage_desc(self):
154 ks = KeysetTestHelper([[
155 {"limit": 1000, "count": "none", "order": ["created_at desc", "uuid desc"], "filters": []},
156 {"items": [{"created_at": "2", "uuid": "2"}, {"created_at": "1", "uuid": "1"}]}
158 {"limit": 1000, "count": "none", "order": ["created_at desc", "uuid desc"], "filters": [["created_at", "<=", "1"], ["uuid", "!=", "1"]]},
162 ls = list(arvados.util.keyset_list_all(ks.fn, ascending=False))
163 self.assertEqual(ls, [{"created_at": "2", "uuid": "2"}, {"created_at": "1", "uuid": "1"}])
165 @parameterized.parameterized.expand(
166 (fake_item, key_fields, order_key, select)
167 for (fake_item, key_fields) in [
168 (_SELECT_FAKE_ITEM, ('uuid',)),
169 (_FAKE_COMPUTED_PERMISSIONS_ITEM, ('user_uuid', 'target_uuid')),
171 for order_key in fake_item
172 if order_key != 'perm_level'
173 for count in range(len(fake_item) + 1)
174 for select in itertools.combinations(fake_item, count)
176 def test_select(self, fake_item, key_fields, order_key, select):
177 # keyset_list_all must have both uuid and order_key to function.
178 # Test that it selects those fields along with user-specified ones.
179 expect_select = {*key_fields, order_key, *select}
182 for key, value in fake_item.items()
183 if key in expect_select
185 list_func = mock.Mock()
186 list_func().execute = mock.Mock(
193 list_func.reset_mock()
194 actual = list(arvados.util.keyset_list_all(list_func, order_key, select=list(select), key_fields=key_fields))
195 self.assertEqual(actual, [item])
196 calls = list_func.call_args_list
197 self.assertTrue(len(calls) >= 2, "list_func() not called enough to exhaust items")
198 for args, kwargs in calls:
199 self.assertEqual(set(kwargs.get('select', ())), expect_select)
202 class TestIterStorageClasses:
204 def mixed_config(self):
205 return {'StorageClasses': {
206 'foo': {'Default': False},
207 'bar': {'Default': True},
208 'baz': {'Default': True},
212 def nodef_config(self):
213 return {'StorageClasses': {
214 'foo': {'Default': False},
215 'bar': {'Default': False},
218 def test_defaults(self, mixed_config):
219 assert list(arvados.util.iter_storage_classes(mixed_config)) == ['bar', 'baz']
221 def test_custom_check(self, mixed_config):
222 assert list(arvados.util.iter_storage_classes(mixed_config, bool)) == ['foo', 'bar', 'baz']
224 def test_default_fallback(self, nodef_config):
225 assert list(arvados.util.iter_storage_classes(nodef_config)) == ['default']
227 def test_custom_fallback(self, nodef_config):
228 assert list(arvados.util.iter_storage_classes(nodef_config, fallback='fb')) == ['fb']
230 def test_no_fallback(self, nodef_config):
231 assert list(arvados.util.iter_storage_classes(nodef_config, fallback='')) == []