1 # Copyright (c) 2019 AT&T Intellectual Property.
2 # Copyright (c) 2018-2019 Nokia.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
17 # This source code is part of the near-RT RIC (RAN Intelligent Controller)
18 # platform project (RICP).
22 from unittest.mock import patch, Mock
24 from ricsdl.syncstorage import SyncStorage
25 from ricsdl.syncstorage import SyncLock
26 from ricsdl.syncstorage import func_arg_checker
27 from ricsdl.exceptions import (SdlTypeError, NotConnected)
29 EVENT_SEPARATOR = "___"
32 def sync_storage_fixture(request):
33 request.cls.ns = 'some-ns'
35 request.cls.keys = {'a', 'b'}
36 request.cls.dm = {'b': b'2', 'a': b'1'}
37 request.cls.old_data = b'1'
38 request.cls.new_data = b'3'
39 request.cls.keyprefix = 'x'
40 request.cls.matchedkeys = ['x1', 'x2', 'x3', 'x4', 'x5']
41 request.cls.group = 'some-group'
42 request.cls.groupmembers = set([b'm1', b'm2'])
43 request.cls.groupmember = b'm1'
44 request.cls.lock_name = 'some-lock-name'
45 request.cls.lock_int_expiration = 10
46 request.cls.lock_float_expiration = 1.1
47 request.cls.channels = {'abs', 'cbn'}
48 request.cls.channels_and_events = {'ch1': 'ev1', 'ch2': ['ev1', 'ev2', 'ev3']}
49 request.cls.ill_event = "illegal" + EVENT_SEPARATOR + "ev"
51 with patch('ricsdl.backend.get_backend_instance') as mock_db_backend:
52 storage = SyncStorage()
53 request.cls.mock_db_backend = mock_db_backend.return_value
54 request.cls.storage = storage
58 @pytest.mark.usefixtures('sync_storage_fixture')
59 class TestSyncStorage:
60 def test_is_active_function_success(self):
61 self.mock_db_backend.is_connected.return_value = True
62 ret = self.storage.is_active()
63 self.mock_db_backend.is_connected.assert_called_once()
66 def test_is_active_function_can_catch_backend_exception_and_return_false(self):
67 self.mock_db_backend.is_connected.side_effect = NotConnected
68 ret = self.storage.is_active()
69 self.mock_db_backend.is_connected.assert_called_once()
72 def test_set_function_success(self):
73 self.storage.set(self.ns, self.dm)
74 self.mock_db_backend.set.assert_called_once_with(self.ns, self.dm)
76 def test_set_function_can_raise_exception_for_wrong_argument(self):
77 with pytest.raises(SdlTypeError):
78 self.storage.set(123, {'a': b'v1'})
79 with pytest.raises(SdlTypeError):
80 self.storage.set('ns', [1, 2])
81 with pytest.raises(SdlTypeError):
82 self.storage.set('ns', {0xbad: b'v1'})
83 with pytest.raises(SdlTypeError):
84 self.storage.set('ns', {'a': 0xbad})
86 def test_set_if_function_success(self):
87 self.mock_db_backend.set_if.return_value = True
88 ret = self.storage.set_if(self.ns, self.key, self.old_data, self.new_data)
89 self.mock_db_backend.set_if.assert_called_once_with(self.ns, self.key, self.old_data,
93 def test_set_if_function_can_return_false_if_same_data_already_exists(self):
94 self.mock_db_backend.set_if.return_value = False
95 ret = self.storage.set_if(self.ns, self.key, self.old_data, self.new_data)
96 self.mock_db_backend.set_if.assert_called_once_with(self.ns, self.key, self.old_data,
100 def test_set_if_function_can_raise_exception_for_wrong_argument(self):
101 with pytest.raises(SdlTypeError):
102 self.storage.set_if(0xbad, 'key', b'v1', b'v2')
103 with pytest.raises(SdlTypeError):
104 self.storage.set_if('ns', 0xbad, b'v1', b'v2')
105 with pytest.raises(SdlTypeError):
106 self.storage.set_if('ns', 'key', 0xbad, b'v2')
107 with pytest.raises(SdlTypeError):
108 self.storage.set_if('ns', 'key', b'v1', 0xbad)
110 def test_set_if_not_exists_function_success(self):
111 self.mock_db_backend.set_if_not_exists.return_value = True
112 ret = self.storage.set_if_not_exists(self.ns, self.key, self.new_data)
113 self.mock_db_backend.set_if_not_exists.assert_called_once_with(self.ns, self.key,
117 def test_set_if_not_exists_function_can_return_false_if_key_already_exists(self):
118 self.mock_db_backend.set_if_not_exists.return_value = False
119 ret = self.storage.set_if_not_exists(self.ns, self.key, self.new_data)
120 self.mock_db_backend.set_if_not_exists.assert_called_once_with(self.ns, self.key,
124 def test_set_if_not_exists_function_can_raise_exception_for_wrong_argument(self):
125 with pytest.raises(SdlTypeError):
126 self.storage.set_if_not_exists(0xbad, 'key', b'v1')
127 with pytest.raises(SdlTypeError):
128 self.storage.set_if_not_exists('ns', 0xbad, b'v1')
129 with pytest.raises(SdlTypeError):
130 self.storage.set_if_not_exists('ns', 'key', 0xbad)
132 def test_get_function_success(self):
133 self.mock_db_backend.get.return_value = self.dm
134 ret = self.storage.get(self.ns, self.keys)
135 self.mock_db_backend.get.assert_called_once()
136 call_args, _ = self.mock_db_backend.get.call_args
137 assert call_args[0] == self.ns
138 assert len(call_args[1]) == len(self.keys)
139 assert all(k in call_args[1] for k in self.keys)
140 assert ret == self.dm
141 # Validate that SDL returns a dictionary with keys in alphabetical order
142 assert sorted(self.dm)[0] == list(ret.keys())[0]
144 def test_get_function_can_return_empty_dict_when_no_key_values_exist(self):
145 self.mock_db_backend.get.return_value = dict()
146 ret = self.storage.get(self.ns, self.keys)
147 self.mock_db_backend.get.assert_called_once()
148 call_args, _ = self.mock_db_backend.get.call_args
149 assert call_args[0] == self.ns
150 assert len(call_args[1]) == len(self.keys)
151 assert all(k in call_args[1] for k in self.keys)
154 def test_get_function_can_raise_exception_for_wrong_argument(self):
155 with pytest.raises(SdlTypeError):
156 self.storage.get(0xbad, self.key)
157 with pytest.raises(SdlTypeError):
158 self.storage.get(self.ns, 0xbad)
160 def test_find_keys_function_success(self):
161 self.mock_db_backend.find_keys.return_value = self.matchedkeys
162 ret = self.storage.find_keys(self.ns, self.keyprefix)
163 self.mock_db_backend.find_keys.assert_called_once_with(self.ns, self.keyprefix)
164 assert ret == self.matchedkeys
166 def test_find_keys_function_can_return_empty_list_when_no_keys_exist(self):
167 self.mock_db_backend.find_keys.return_value = list()
168 ret = self.storage.find_keys(self.ns, self.keyprefix)
169 self.mock_db_backend.find_keys.assert_called_once_with(self.ns, self.keyprefix)
172 def test_find_keys_function_can_raise_exception_for_wrong_argument(self):
173 with pytest.raises(SdlTypeError):
174 self.storage.find_keys(0xbad, self.keyprefix)
175 with pytest.raises(SdlTypeError):
176 self.storage.find_keys(self.ns, 0xbad)
178 def test_find_and_get_function_success(self):
179 self.mock_db_backend.find_and_get.return_value = self.dm
180 ret = self.storage.find_and_get(self.ns, self.keyprefix)
181 self.mock_db_backend.find_and_get.assert_called_once_with(self.ns, self.keyprefix)
182 assert ret == self.dm
183 # Validate that SDL returns a dictionary with keys in alphabetical order
184 assert sorted(self.dm)[0] == list(ret.keys())[0]
186 def test_find_and_get_function_can_return_empty_dict_when_no_keys_exist(self):
187 self.mock_db_backend.find_and_get.return_value = dict()
188 ret = self.storage.find_and_get(self.ns, self.keyprefix)
189 self.mock_db_backend.find_and_get.assert_called_once_with(self.ns, self.keyprefix)
192 def test_find_and_get_function_can_raise_exception_for_wrong_argument(self):
193 with pytest.raises(SdlTypeError):
194 self.storage.find_and_get(0xbad, self.keyprefix)
195 with pytest.raises(SdlTypeError):
196 self.storage.find_and_get(self.ns, 0xbad)
198 def test_remove_function_success(self):
199 self.storage.remove(self.ns, self.keys)
200 self.mock_db_backend.remove.assert_called_once()
201 call_args, _ = self.mock_db_backend.remove.call_args
202 assert call_args[0] == self.ns
203 assert isinstance(call_args[1], list)
204 assert len(call_args[1]) == len(self.keys)
205 assert all(k in call_args[1] for k in self.keys)
207 def test_remove_function_can_raise_exception_for_wrong_argument(self):
208 with pytest.raises(SdlTypeError):
209 self.storage.remove(0xbad, self.keys)
210 with pytest.raises(SdlTypeError):
211 self.storage.remove(self.ns, 0xbad)
213 def test_remove_if_function_success(self):
214 self.mock_db_backend.remove_if.return_value = True
215 ret = self.storage.remove_if(self.ns, self.key, self.new_data)
216 self.mock_db_backend.remove_if.assert_called_once_with(self.ns, self.key, self.new_data)
219 def test_remove_if_function_can_return_false_if_data_does_not_match(self):
220 self.mock_db_backend.remove_if.return_value = False
221 ret = self.storage.remove_if(self.ns, self.key, self.old_data)
222 self.mock_db_backend.remove_if.assert_called_once_with(self.ns, self.key, self.old_data)
225 def test_remove_if_function_can_raise_exception_for_wrong_argument(self):
226 with pytest.raises(SdlTypeError):
227 self.storage.remove_if(0xbad, self.keys, self.old_data)
228 with pytest.raises(SdlTypeError):
229 self.storage.remove_if(self.ns, 0xbad, self.old_data)
230 with pytest.raises(SdlTypeError):
231 self.storage.remove_if(self.ns, self.keys, 0xbad)
233 def test_remove_all_function_success(self):
234 self.mock_db_backend.find_keys.return_value = ['a1']
235 self.storage.remove_all(self.ns)
236 self.mock_db_backend.find_keys.assert_called_once_with(self.ns, '*')
237 self.mock_db_backend.remove.assert_called_once_with(self.ns,
238 self.mock_db_backend.find_keys.return_value)
240 def test_remove_all_function_can_raise_exception_for_wrong_argument(self):
241 with pytest.raises(SdlTypeError):
242 self.storage.remove_all(0xbad)
244 def test_add_member_function_success(self):
245 self.storage.add_member(self.ns, self.group, self.groupmembers)
246 self.mock_db_backend.add_member.assert_called_once_with(self.ns,
247 self.group, self.groupmembers)
249 def test_add_member_function_can_raise_exception_for_wrong_argument(self):
250 with pytest.raises(SdlTypeError):
251 self.storage.add_member(0xbad, self.group, self.groupmembers)
252 with pytest.raises(SdlTypeError):
253 self.storage.add_member(self.ns, 0xbad, self.groupmembers)
254 with pytest.raises(SdlTypeError):
255 self.storage.add_member(self.ns, self.group, 0xbad)
257 def test_remove_member_function_success(self):
258 self.storage.remove_member(self.ns, self.group, self.groupmembers)
259 self.mock_db_backend.remove_member.assert_called_once_with(self.ns, self.group,
262 def test_remove_member_function_can_raise_exception_for_wrong_argument(self):
263 with pytest.raises(SdlTypeError):
264 self.storage.remove_member(0xbad, self.group, self.groupmembers)
265 with pytest.raises(SdlTypeError):
266 self.storage.remove_member(self.ns, 0xbad, self.groupmembers)
267 with pytest.raises(SdlTypeError):
268 self.storage.remove_member(self.ns, self.group, 0xbad)
270 def test_remove_group_function_success(self):
271 self.storage.remove_group(self.ns, self.group)
272 self.mock_db_backend.remove_group.assert_called_once_with(self.ns, self.group)
274 def test_remove_group_function_can_raise_exception_for_wrong_argument(self):
275 with pytest.raises(SdlTypeError):
276 self.storage.remove_group(0xbad, self.group)
277 with pytest.raises(SdlTypeError):
278 self.storage.remove_group(self.ns, 0xbad)
280 def test_get_members_function_success(self):
281 self.mock_db_backend.get_members.return_value = self.groupmembers
282 ret = self.storage.get_members(self.ns, self.group)
283 self.mock_db_backend.get_members.assert_called_once_with(self.ns, self.group)
284 assert ret == self.groupmembers
286 def test_get_members_function_can_raise_exception_for_wrong_argument(self):
287 with pytest.raises(SdlTypeError):
288 self.storage.get_members(0xbad, self.group)
289 with pytest.raises(SdlTypeError):
290 self.storage.get_members(self.ns, 0xbad)
292 def test_is_member_function_success(self):
293 self.mock_db_backend.is_member.return_value = True
294 ret = self.storage.is_member(self.ns, self.group, self.groupmember)
295 self.mock_db_backend.is_member.assert_called_once_with(self.ns, self.group,
299 def test_is_member_function_can_raise_exception_for_wrong_argument(self):
300 with pytest.raises(SdlTypeError):
301 self.storage.is_member(0xbad, self.group, self.groupmember)
302 with pytest.raises(SdlTypeError):
303 self.storage.is_member(self.ns, 0xbad, self.groupmember)
304 with pytest.raises(SdlTypeError):
305 self.storage.is_member(self.ns, self.group, 0xbad)
307 def test_group_size_function_success(self):
308 self.mock_db_backend.group_size.return_value = 100
309 ret = self.storage.group_size(self.ns, self.group)
310 self.mock_db_backend.group_size.assert_called_once_with(self.ns, self.group)
313 def test_group_size_function_can_raise_exception_for_wrong_argument(self):
314 with pytest.raises(SdlTypeError):
315 self.storage.group_size(0xbad, self.group)
316 with pytest.raises(SdlTypeError):
317 self.storage.group_size(self.ns, 0xbad)
319 def test_set_and_publish_function_success(self):
320 self.storage.set_and_publish(self.ns, self.channels_and_events, self.dm)
321 self.mock_db_backend.set_and_publish.assert_called_once_with(self.ns,
322 self.channels_and_events,
325 def test_set_and_publish_can_raise_exception_for_wrong_argument(self):
326 with pytest.raises(SdlTypeError):
327 self.storage.set_and_publish(123, self.channels_and_events, self.dm)
328 with pytest.raises(SdlTypeError):
329 self.storage.set_and_publish(self.ns, None, self.dm)
330 with pytest.raises(SdlTypeError):
331 self.storage.set_and_publish(self.ns, {0xbad: "ev1"}, self.dm)
332 with pytest.raises(SdlTypeError):
333 self.storage.set_and_publish(self.ns, {"ch1": 0xbad}, self.dm)
334 with pytest.raises(SdlTypeError):
335 self.storage.set_and_publish(self.ns, {"ch1": self.ill_event}, self.dm)
336 with pytest.raises(SdlTypeError):
337 self.storage.set_and_publish(self.ns, {"ch1": ["ev1", 0xbad]}, self.dm)
338 with pytest.raises(SdlTypeError):
339 self.storage.set_and_publish(self.ns, {"ch1": ["ev1", self.ill_event]}, self.dm)
340 with pytest.raises(SdlTypeError):
341 self.storage.set_and_publish(self.ns, self.channels_and_events, [1, 2])
342 with pytest.raises(SdlTypeError):
343 self.storage.set_and_publish(self.ns, self.channels_and_events, {0xbad: b'v1'})
344 with pytest.raises(SdlTypeError):
345 self.storage.set_and_publish(self.ns, self.channels_and_events, {'a': 0xbad})
347 def test_set_if_and_publish_success(self):
348 self.mock_db_backend.set_if_and_publish.return_value = True
349 ret = self.storage.set_if_and_publish(self.ns, self.channels_and_events, self.key,
350 self.old_data, self.new_data)
351 self.mock_db_backend.set_if_and_publish.assert_called_once_with(
352 self.ns, self.channels_and_events, self.key, self.old_data, self.new_data)
355 def test_set_if_and_publish_can_return_false_if_same_data_already_exists(self):
356 self.mock_db_backend.set_if_and_publish.return_value = False
357 ret = self.storage.set_if_and_publish(self.ns, self.channels_and_events, self.key,
358 self.old_data, self.new_data)
359 self.mock_db_backend.set_if_and_publish.assert_called_once_with(
360 self.ns, self.channels_and_events, self.key, self.old_data, self.new_data)
363 def test_set_if_and_publish_can_raise_exception_for_wrong_argument(self):
364 with pytest.raises(SdlTypeError):
365 self.storage.set_if_and_publish(0xbad, self.channels_and_events, self.key,
366 self.old_data, self.new_data)
367 with pytest.raises(SdlTypeError):
368 self.storage.set_if_and_publish(self.ns, None, self.key, self.old_data,
370 with pytest.raises(SdlTypeError):
371 self.storage.set_if_and_publish(self.ns, {0xbad: "ev1"}, self.key,
372 self.old_data, self.new_data)
373 with pytest.raises(SdlTypeError):
374 self.storage.set_if_and_publish(self.ns, {"ch1": 0xbad}, self.key,
375 self.old_data, self.new_data)
376 with pytest.raises(SdlTypeError):
377 self.storage.set_if_and_publish(self.ns, {"ch1": self.ill_event}, self.key,
378 self.old_data, self.new_data)
379 with pytest.raises(SdlTypeError):
380 self.storage.set_if_and_publish(self.ns, {"ch1": ["ev1", 0xbad]}, self.key,
381 self.old_data, self.new_data)
382 with pytest.raises(SdlTypeError):
383 self.storage.set_if_and_publish(self.ns, {"ch1": ["ev1", self.ill_event]}, self.key,
384 self.old_data, self.new_data)
385 with pytest.raises(SdlTypeError):
386 self.storage.set_if_and_publish(self.ns, self.channels_and_events, 0xbad,
387 self.old_data, self.new_data)
388 with pytest.raises(SdlTypeError):
389 self.storage.set_if_and_publish(self.ns, self.channels_and_events, self.key,
390 0xbad, self.new_data)
391 with pytest.raises(SdlTypeError):
392 self.storage.set_if_and_publish(self.ns, self.channels_and_events, self.key,
393 self.old_data, 0xbad)
395 def test_set_if_not_exists_and_publish_success(self):
396 self.mock_db_backend.set_if_not_exists_and_publish.return_value = True
397 ret = self.storage.set_if_not_exists_and_publish(self.ns, self.channels_and_events,
398 self.key, self.new_data)
399 self.mock_db_backend.set_if_not_exists_and_publish.assert_called_once_with(
400 self.ns, self.channels_and_events, self.key, self.new_data)
403 def test_set_if_not_exists_and_publish_function_can_return_false_if_key_already_exists(self):
404 self.mock_db_backend.set_if_not_exists_and_publish.return_value = False
405 ret = self.storage.set_if_not_exists_and_publish(self.ns, self.channels_and_events,
406 self.key, self.new_data)
407 self.mock_db_backend.set_if_not_exists_and_publish.assert_called_once_with(
408 self.ns, self.channels_and_events, self.key, self.new_data)
411 def test_set_if_not_exists_and_publish_can_raise_exception_for_wrong_argument(self):
412 with pytest.raises(SdlTypeError):
413 self.storage.set_if_not_exists_and_publish(0xbad, self.channels_and_events,
414 self.key, self.new_data)
415 with pytest.raises(SdlTypeError):
416 self.storage.set_if_not_exists_and_publish(self.ns, None, self.key,
418 with pytest.raises(SdlTypeError):
419 self.storage.set_if_not_exists_and_publish(self.ns, {0xbad: "ev1"},
420 self.key, self.new_data)
421 with pytest.raises(SdlTypeError):
422 self.storage.set_if_not_exists_and_publish(self.ns, {"ch1": 0xbad},
423 self.key, self.new_data)
424 with pytest.raises(SdlTypeError):
425 self.storage.set_if_not_exists_and_publish(self.ns, {"ch1": self.ill_event},
426 self.key, self.new_data)
427 with pytest.raises(SdlTypeError):
428 self.storage.set_if_not_exists_and_publish(self.ns, {"ch1": ["ev1", 0xbad]},
429 self.key, self.new_data)
430 with pytest.raises(SdlTypeError):
431 self.storage.set_if_not_exists_and_publish(self.ns, {"ch1": ["ev1", self.ill_event]},
432 self.key, self.new_data)
433 with pytest.raises(SdlTypeError):
434 self.storage.set_if_not_exists_and_publish(self.ns, self.channels_and_events,
436 with pytest.raises(SdlTypeError):
437 self.storage.set_if_not_exists_and_publish(self.ns, self.channels_and_events,
440 def test_remove_and_publish_function_success(self):
441 self.storage.remove_and_publish(self.ns, self.channels_and_events, self.keys)
442 self.mock_db_backend.remove_and_publish.assert_called_once_with(
443 self.ns, self.channels_and_events, list(self.keys))
445 def test_remove_and_publish_can_raise_exception_for_wrong_argument(self):
446 with pytest.raises(SdlTypeError):
447 self.storage.remove_and_publish(0xbad, self.channels_and_events, self.keys)
448 with pytest.raises(SdlTypeError):
449 self.storage.remove_and_publish(self.ns, None, self.keys)
450 with pytest.raises(SdlTypeError):
451 self.storage.remove_and_publish(self.ns, {0xbad: "ev1"}, self.keys)
452 with pytest.raises(SdlTypeError):
453 self.storage.remove_and_publish(self.ns, {"ch1": 0xbad}, self.keys)
454 with pytest.raises(SdlTypeError):
455 self.storage.remove_and_publish(self.ns, {"ch1": self.ill_event}, self.keys)
456 with pytest.raises(SdlTypeError):
457 self.storage.remove_and_publish(self.ns, {"ch1": ["ev1", 0xbad]}, self.keys)
458 with pytest.raises(SdlTypeError):
459 self.storage.remove_and_publish(self.ns, {"ch1": ["ev1", self.ill_event]}, self.keys)
460 with pytest.raises(SdlTypeError):
461 self.storage.remove_and_publish(self.ns, self.channels_and_events, 0xbad)
463 def test_remove_if_and_publish_success(self):
464 self.mock_db_backend.remove_if_and_publish.return_value = True
465 ret = self.storage.remove_if_and_publish(self.ns, self.channels_and_events, self.key,
467 self.mock_db_backend.remove_if_and_publish.assert_called_once_with(
468 self.ns, self.channels_and_events, self.key, self.new_data)
471 def test_remove_if_remove_and_publish_can_return_false_if_data_does_not_match(self):
472 self.mock_db_backend.remove_if_and_publish.return_value = False
473 ret = self.storage.remove_if_and_publish(self.ns, self.channels_and_events, self.key,
475 self.mock_db_backend.remove_if_and_publish.assert_called_once_with(
476 self.ns, self.channels_and_events, self.key, self.old_data)
479 def test_remove_if_remove_and_publish_can_raise_exception_for_wrong_argument(self):
480 with pytest.raises(SdlTypeError):
481 self.storage.remove_if_and_publish(0xbad, self.channels_and_events, self.keys,
483 with pytest.raises(SdlTypeError):
484 self.storage.remove_if_and_publish(self.ns, None, self.keys, self.old_data)
485 with pytest.raises(SdlTypeError):
486 self.storage.remove_if_and_publish(self.ns, {0xbad: "ev1"}, self.keys,
488 with pytest.raises(SdlTypeError):
489 self.storage.remove_if_and_publish(self.ns, {"ch1": 0xbad}, self.keys,
491 with pytest.raises(SdlTypeError):
492 self.storage.remove_if_and_publish(self.ns, {"ch1": self.ill_event}, self.keys,
494 with pytest.raises(SdlTypeError):
495 self.storage.remove_if_and_publish(self.ns, {"ch1": ["ev1", 0xbad]}, self.keys,
497 with pytest.raises(SdlTypeError):
498 self.storage.remove_if_and_publish(self.ns, {"ch1": ["ev1", self.ill_event]}, self.keys,
500 with pytest.raises(SdlTypeError):
501 self.storage.remove_if_and_publish(self.ns, self.channels_and_events, 0xbad,
503 with pytest.raises(SdlTypeError):
504 self.storage.remove_if_and_publish(self.ns, self.channels_and_events, self.keys, 0xbad)
506 def test_remove_all_and_publish_success(self):
507 self.storage.remove_all_and_publish(self.ns, self.channels_and_events)
508 self.mock_db_backend.remove_all_and_publish.assert_called_once_with(
509 self.ns, self.channels_and_events)
511 def test_remove_all_and_publish_can_raise_exception_for_wrong_argument(self):
512 with pytest.raises(SdlTypeError):
513 self.storage.remove_all_and_publish(0xbad, self.channels_and_events)
514 with pytest.raises(SdlTypeError):
515 self.storage.remove_all_and_publish(self.ns, None)
516 with pytest.raises(SdlTypeError):
517 self.storage.remove_all_and_publish(self.ns, {0xbad: "ev1"})
518 with pytest.raises(SdlTypeError):
519 self.storage.remove_all_and_publish(self.ns, {"ch1": 0xbad})
520 with pytest.raises(SdlTypeError):
521 self.storage.remove_all_and_publish(self.ns, {"ch1": self.ill_event})
522 with pytest.raises(SdlTypeError):
523 self.storage.remove_all_and_publish(self.ns, {"ch1": ["ev1", 0xbad]})
524 with pytest.raises(SdlTypeError):
525 self.storage.remove_all_and_publish(self.ns, {"ch1": ["ev1", self.ill_event]})
527 def test_subscribe_function_success(self):
528 def cb(channel, message):
530 self.storage.subscribe_channel(self.ns, cb, self.channels)
531 self.mock_db_backend.subscribe_channel.assert_called_once_with(
532 self.ns, cb, list(self.channels))
534 def test_subscribe_can_raise_exception_for_wrong_argument(self):
535 def cb3(channel, message, extra):
539 with pytest.raises(SdlTypeError):
540 self.storage.subscribe_channel(self.ns, cb3, self.channels)
541 with pytest.raises(SdlTypeError):
542 self.storage.subscribe_channel(self.ns, cb1, self.channels)
544 def test_unsubscribe_function_success(self):
545 self.storage.unsubscribe_channel(self.ns, self.channels)
546 self.mock_db_backend.unsubscribe_channel.assert_called_once_with(
547 self.ns, list(self.channels))
549 def test_start_event_listener_success(self):
550 self.storage.start_event_listener()
551 self.mock_db_backend.start_event_listener.assert_called()
553 def test_handle_events_success(self):
554 self.storage.handle_events()
555 self.mock_db_backend.handle_events.assert_called()
557 @patch('ricsdl.syncstorage.SyncLock')
558 def test_get_lock_resource_function_success_when_expiration_time_is_integer(self, mock_db_lock):
559 ret = self.storage.get_lock_resource(self.ns, self.lock_name, self.lock_int_expiration)
560 mock_db_lock.assert_called_once_with(self.ns, self.lock_name, self.lock_int_expiration,
562 assert ret == mock_db_lock.return_value
564 @patch('ricsdl.syncstorage.SyncLock')
565 def test_get_lock_resource_function_success_when_expiration_time_is_float_number(self,
567 ret = self.storage.get_lock_resource(self.ns, self.lock_name, self.lock_float_expiration)
568 mock_db_lock.assert_called_once_with(self.ns, self.lock_name, self.lock_float_expiration,
570 assert ret == mock_db_lock.return_value
572 def test_get_lock_resource_function_can_raise_exception_for_wrong_argument(self):
573 with pytest.raises(SdlTypeError):
574 self.storage.get_lock_resource(0xbad, self.lock_name, self.lock_int_expiration)
575 with pytest.raises(SdlTypeError):
576 self.storage.get_lock_resource(self.ns, 0xbad, self.lock_int_expiration)
577 with pytest.raises(SdlTypeError):
578 self.storage.get_lock_resource(self.ns, self.lock_name, 'bad')
580 def test_get_backend_function_success(self):
581 ret = self.storage.get_backend()
582 assert ret == self.mock_db_backend
584 def test_storage_object_string_representation(self):
585 str_out = str(self.storage)
586 assert str_out is not None
590 def lock_fixture(request):
591 request.cls.ns = 'some-ns'
592 request.cls.lockname = 'some-lock-name'
593 request.cls.expiration = 10
594 request.cls.retry_interval = 0.1
595 request.cls.retry_timeout = 1
597 with patch('ricsdl.backend.get_backend_lock_instance') as mock_db_backend_lock:
598 lock = SyncLock('test-ns', 'test-lock-name', request.cls.expiration, Mock())
599 request.cls.mock_db_backend_lock = mock_db_backend_lock.return_value
600 request.cls.lock = lock
604 @pytest.mark.usefixtures('lock_fixture')
606 def test_acquire_function_success_when_timeout_and_interval_are_integers(self):
607 self.lock.acquire(self.retry_interval, self.retry_timeout)
608 self.mock_db_backend_lock.acquire.assert_called_once_with(self.retry_interval,
611 def test_acquire_function_success_when_timeout_and_interval_are_float_numbers(self):
612 self.lock.acquire(float(self.retry_interval), float(self.retry_timeout))
613 self.mock_db_backend_lock.acquire.assert_called_once_with(float(self.retry_interval),
614 float(self.retry_timeout))
616 def test_acquire_function_can_raise_exception_for_wrong_argument(self):
617 with pytest.raises(SdlTypeError):
618 self.lock.acquire('bad', self.retry_timeout)
619 with pytest.raises(SdlTypeError):
620 self.lock.acquire(self.retry_interval, 'bad')
622 def test_release_function_success(self):
624 self.mock_db_backend_lock.release.assert_called_once()
626 def test_refresh_function_success(self):
628 self.mock_db_backend_lock.refresh.assert_called_once()
630 def test_get_validity_time_function_success(self):
631 self.mock_db_backend_lock.get_validity_time.return_value = self.expiration
632 ret = self.lock.get_validity_time()
633 self.mock_db_backend_lock.get_validity_time.assert_called_once()
634 assert ret == self.expiration
636 def test_get_validity_time_function_success_when_returned_time_is_float(self):
637 self.mock_db_backend_lock.get_validity_time.return_value = float(self.expiration)
638 ret = self.lock.get_validity_time()
639 self.mock_db_backend_lock.get_validity_time.assert_called_once()
640 assert ret == float(self.expiration)
642 def test_lock_object_string_representation(self):
643 str_out = str(self.lock)
644 assert str_out is not None
647 def test_function_arg_validator():
648 @func_arg_checker(SdlTypeError, 0, a=str, b=(int, float), c=set, d=(dict, type(None)))
649 def _my_func(a='abc', b=1, c={'x', 'y'}, d={'x': b'1'}):
651 with pytest.raises(SdlTypeError, match=r"Wrong argument type: 'a'=<class 'NoneType'>. "
652 r"Must be: <class 'str'>"):
655 with pytest.raises(SdlTypeError, match=r"Wrong argument type: 'b'=<class 'str'>. "):
656 _my_func('abc', 'wrong type')
658 with pytest.raises(SdlTypeError, match=r"Wrong argument type: 'c'=<class 'str'>. "
659 r"Must be: <class 'set'>"):
660 _my_func('abc', 1.0, 'wrong type')
662 with pytest.raises(SdlTypeError, match=r"Wrong argument type: 'd'=<class 'str'>. "):
663 _my_func('abc', 1.0, {'x', 'y'}, 'wrong type')
666 def test_function_kwarg_validator():
667 @func_arg_checker(SdlTypeError, 0, a=str, b=(int, float), c=set, d=(dict, type(None)))
668 def _my_func(a='abc', b=1, c={'x', 'y'}, d={'x': b'1'}):
670 with pytest.raises(SdlTypeError, match=r"Wrong argument type: 'a'=<class 'NoneType'>. "
671 r"Must be: <class 'str'>"):
674 with pytest.raises(SdlTypeError, match=r"Wrong argument type: 'b'=<class 'str'>. "):
675 _my_func(b='wrong type')
677 with pytest.raises(SdlTypeError, match=r"Wrong argument type: 'c'=<class 'str'>. "
678 r"Must be: <class 'set'>"):
679 _my_func(c='wrong type')
681 with pytest.raises(SdlTypeError, match=r"Wrong argument type: 'd'=<class 'str'>. "):
682 _my_func(d='wrong type')