X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=ricsdl-package%2Ftests%2Fbackend%2Ftest_redis.py;h=72d7c023930555c6d785c5dac5091f1372ccc42a;hb=276ed3c833c81a4142d7c4607474ee95a7f01355;hp=d1b8223255cb665a7ef486dca871bd3ea80ec7fe;hpb=dada8463c0fd4c3b90eedc54b6c913f0fa0e7272;p=ric-plt%2Fsdlpy.git diff --git a/ricsdl-package/tests/backend/test_redis.py b/ricsdl-package/tests/backend/test_redis.py index d1b8223..72d7c02 100644 --- a/ricsdl-package/tests/backend/test_redis.py +++ b/ricsdl-package/tests/backend/test_redis.py @@ -41,19 +41,18 @@ def redis_backend_fixture(request): request.cls.data = b'123' request.cls.old_data = b'1' request.cls.new_data = b'3' - request.cls.keyprefix = 'x?' - request.cls.keyprefix_redis = r'{some-ns},x\?*' - request.cls.matchedkeys = ['x1', 'x2', 'x3', 'x4', 'x5'] - request.cls.matchedkeys_redis = [b'{some-ns},x1', b'{some-ns},x2', b'{some-ns},x3', - b'{some-ns},x4', b'{some-ns},x5'] - request.cls.matcheddata_dl_redis = [b'10', b'11', b'12', b'13', b'14'] - request.cls.matcheddata_dm = {'x1': b'10', 'x2': b'11', 'x3': b'12', - 'x4': b'13', 'x5': b'14'} + request.cls.keypattern = r'[Aa]bc-\[1\].?-*' + request.cls.keypattern_redis = r'{some-ns},[Aa]bc-\[1\].?-*' + request.cls.matchedkeys = ['Abc-[1].0-def', 'abc-[1].1-ghi'] + request.cls.matchedkeys_redis = [b'{some-ns},Abc-[1].0-def', + b'{some-ns},abc-[1].1-ghi'] + request.cls.matcheddata_redis = [b'10', b'11'] + request.cls.matchedkeydata = {'Abc-[1].0-def': b'10', + 'abc-[1].1-ghi': b'11'} request.cls.group = 'some-group' request.cls.group_redis = '{some-ns},some-group' request.cls.groupmembers = set([b'm1', b'm2']) request.cls.groupmember = b'm1' - request.cls.is_atomic = True request.cls.configuration = Mock() mock_conf_params = _Configuration.Params(db_host=None, @@ -141,36 +140,77 @@ class TestRedisBackend: def test_find_keys_function_success(self): self.mock_redis.keys.return_value = self.matchedkeys_redis - ret = self.db.find_keys(self.ns, self.keyprefix) - self.mock_redis.keys.assert_called_once_with(self.keyprefix_redis) + ret = self.db.find_keys(self.ns, self.keypattern) + self.mock_redis.keys.assert_called_once_with(self.keypattern_redis) assert ret == self.matchedkeys def test_find_keys_function_returns_empty_list_when_no_matching_keys_found(self): self.mock_redis.keys.return_value = [] - ret = self.db.find_keys(self.ns, self.keyprefix) - self.mock_redis.keys.assert_called_once_with(self.keyprefix_redis) + ret = self.db.find_keys(self.ns, self.keypattern) + self.mock_redis.keys.assert_called_once_with(self.keypattern_redis) assert ret == [] def test_find_keys_function_can_map_redis_exception_to_sdl_exception(self): self.mock_redis.keys.side_effect = redis_exceptions.ResponseError('redis error!') with pytest.raises(ricsdl.exceptions.RejectedByBackend): - self.db.find_keys(self.ns, self.keyprefix) + self.db.find_keys(self.ns, self.keypattern) + + def test_find_keys_function_can_raise_exception_when_redis_key_convert_to_string_fails(self): + # Redis returns an illegal key, which conversion to string fails + corrupt_redis_key = b'\x81' + self.mock_redis.keys.return_value = [corrupt_redis_key] + with pytest.raises(ricsdl.exceptions.RejectedByBackend) as excinfo: + self.db.find_keys(self.ns, self.keypattern) + assert f"Namespace {self.ns} key:{corrupt_redis_key} " + "has no namespace prefix" in str(excinfo.value) + + def test_find_keys_function_can_raise_exception_when_redis_key_is_without_prefix(self): + # Redis returns an illegal key, which doesn't have comma separated namespace prefix + corrupt_redis_key = 'some-corrupt-key' + self.mock_redis.keys.return_value = [f'{corrupt_redis_key}'.encode()] + with pytest.raises(ricsdl.exceptions.RejectedByBackend) as excinfo: + self.db.find_keys(self.ns, self.keypattern) + assert f"Namespace {self.ns} key:{corrupt_redis_key} " + "has no namespace prefix" in str(excinfo.value) def test_find_and_get_function_success(self): self.mock_redis.keys.return_value = self.matchedkeys_redis - self.mock_redis.mget.return_value = self.matcheddata_dl_redis - ret = self.db.find_and_get(self.ns, self.keyprefix, self.is_atomic) - self.mock_redis.keys.assert_called_once_with(self.keyprefix_redis) + self.mock_redis.mget.return_value = self.matcheddata_redis + ret = self.db.find_and_get(self.ns, self.keypattern) + self.mock_redis.keys.assert_called_once_with(self.keypattern_redis) self.mock_redis.mget.assert_called_once_with([i.decode() for i in self.matchedkeys_redis]) - assert ret == self.matcheddata_dm + assert ret == self.matchedkeydata def test_find_and_get_function_returns_empty_dict_when_no_matching_keys_exist(self): self.mock_redis.keys.return_value = list() - ret = self.db.find_and_get(self.ns, self.keyprefix, self.is_atomic) - self.mock_redis.keys.assert_called_once_with(self.keyprefix_redis) + ret = self.db.find_and_get(self.ns, self.keypattern) + self.mock_redis.keys.assert_called_once_with(self.keypattern_redis) assert not self.mock_redis.mget.called assert ret == dict() + def test_find_and_get_function_can_map_redis_exception_to_sdl_exception(self): + self.mock_redis.keys.side_effect = redis_exceptions.ResponseError('redis error!') + with pytest.raises(ricsdl.exceptions.RejectedByBackend): + self.db.find_and_get(self.ns, self.keypattern) + + def test_find_and_get_function_can_raise_exception_when_redis_key_convert_to_string_fails(self): + # Redis returns an illegal key, which conversion to string fails + corrupt_redis_key = b'\x81' + self.mock_redis.keys.return_value = [corrupt_redis_key] + with pytest.raises(ricsdl.exceptions.RejectedByBackend) as excinfo: + self.db.find_and_get(self.ns, self.keypattern) + assert f"Namespace {self.ns} key:{corrupt_redis_key} " + "has no namespace prefix" in str(excinfo.value) + + def test_find_and_get_function_can_raise_exception_when_redis_key_is_without_prefix(self): + # Redis returns an illegal key, which doesn't have comma separated namespace prefix + corrupt_redis_key = 'some-corrupt-key' + self.mock_redis.keys.return_value = [f'{corrupt_redis_key}'.encode()] + with pytest.raises(ricsdl.exceptions.RejectedByBackend) as excinfo: + self.db.find_and_get(self.ns, self.keypattern) + assert f"Namespace {self.ns} key:{corrupt_redis_key} " + "has no namespace prefix" in str(excinfo.value) + def test_remove_function_success(self): self.db.remove(self.ns, self.keys) self.mock_redis.delete.assert_called_once_with(*self.keys_redis) @@ -353,6 +393,16 @@ class TestRedisBackendLock: keys=[self.lockname_redis], args=[123], client=self.mock_redis) assert ret == 2 + def test_get_validity_time_function_second_fraction_success(self): + self.mock_redis_lock.name = self.lockname_redis + self.mock_redis_lock.local.token = 123 + self.mock_lua_get_validity_time.return_value = 234 + + ret = self.lock.get_validity_time() + self.mock_lua_get_validity_time.assert_called_once_with( + keys=[self.lockname_redis], args=[123], client=self.mock_redis) + assert ret == 0.234 + def test_get_validity_time_function_can_raise_exception_if_lock_is_unlocked(self): self.mock_redis_lock.name = self.lockname_redis self.mock_redis_lock.local.token = None @@ -371,8 +421,17 @@ class TestRedisBackendLock: assert f"Getting validity time of a lock {self.lockname} failed with error code: -10" in str(excinfo.value) def test_redis_backend_lock_object_string_representation(self): - str_out = str(self.lock) - assert str_out is not None + expected_lock_info = {'lock namespace': 'some-ns', + 'lock name': 'some-lock-name', + 'lock status': 'locked'} + assert str(self.lock) == str(expected_lock_info) + + def test_redis_backend_lock_object_string_representation_can_catch_redis_exception(self): + self.mock_redis_lock.owned.side_effect = redis_exceptions.LockError('redis lock error!') + expected_lock_info = {'lock namespace': 'some-ns', + 'lock name': 'some-lock-name', + 'lock status': 'Error: redis lock error!'} + assert str(self.lock) == str(expected_lock_info) def test_redis_response_error_exception_is_mapped_to_rejected_by_backend_sdl_exception():