From e67b9abd75c6ebeda849e5e718a507de4027f65d Mon Sep 17 00:00:00 2001 From: Timo Tietavainen Date: Mon, 14 Mar 2022 07:27:30 +0200 Subject: [PATCH] Read list type of environment variables DBAAS Helm Charts appconfig has been changed to have individual ports and master names for each SDL cluster due to problems seen with DBAAS upgrade and rollback caused by re-allocation of the same address/port of Redis to some other SDL cluster. Implement support for new list type environment variables reading in SDL: * DBAAS_SERVICE_PORT * DBAAS_SERVICE_SENTINEL_PORT * DBAAS_MASTER_NAME Issue-Id: RIC-698 Signed-off-by: Timo Tietavainen Change-Id: Id75e53c3542f2c2b24a2fd815a5583b1394d8d79 --- docs/release-notes.rst | 6 +- ricsdl-package/examples/notify.py | 17 +++-- ricsdl-package/examples/sync.py | 20 +++--- ricsdl-package/ricsdl/__init__.py | 4 +- ricsdl-package/ricsdl/backend/redis.py | 27 ++++--- ricsdl-package/ricsdl/configuration.py | 60 ++++++++++++---- ricsdl-package/ricsdl/syncstorage.py | 6 +- ricsdl-package/tests/backend/test_fake_dict_db.py | 18 ++--- ricsdl-package/tests/backend/test_redis.py | 46 ++++++------ ricsdl-package/tests/test_configuration.py | 87 +++++++++++++++++------ 10 files changed, 188 insertions(+), 103 deletions(-) diff --git a/docs/release-notes.rst b/docs/release-notes.rst index 4013a07..2e1477b 100644 --- a/docs/release-notes.rst +++ b/docs/release-notes.rst @@ -1,6 +1,6 @@ .. .. Copyright (c) 2019 AT&T Intellectual Property. -.. Copyright (c) 2019 Nokia. +.. Copyright (c) 2019-2022 Nokia. .. .. Licensed under the Creative Commons Attribution 4.0 International .. Public License (the "License"); you may not use this file except @@ -33,6 +33,10 @@ This document provides the release notes of the ricsdl library. Version history --------------- +[3.1.0] - 2022-03-14 + +* Enable redis/sentinel port and sentinel master name configuration + [3.0.2] - 2022-01-20 * Bump Redis client version to 4.1.1 and replace deprecated Redis client '_compat' diff --git a/ricsdl-package/examples/notify.py b/ricsdl-package/examples/notify.py index 006001f..47d9b04 100755 --- a/ricsdl-package/examples/notify.py +++ b/ricsdl-package/examples/notify.py @@ -38,13 +38,16 @@ Execution of these examples requires: * Following environment variables are needed to set to the pod/container where the application utilizing SDL is going to be run. DBAAS_SERVICE_HOST = [DB service address] - DBAAS_SERVICE_PORT= [DB service port] - DBAAS_MASTER_NAME = [DB name]. Needed to set only if Redis sentinel is used to provide high - availability for Redis DB solution. - DBAAS_SERVICE_SENTINEL_PORT = [Redis sentinel port number]. Needed to set only if Redis - sentinel is in use. - DBASS_CLUSTER_ADDR_LIST = [list of DB service addresses]. Is set only if more than one - Redis sentinel groups are in use. + DBAAS_SERVICE_PORT= [Comma separated list of DB service ports]. Only one port supported in + RIC deployments, Nokia SEP deployments can have multiple ports. + DBAAS_MASTER_NAME = [Comma separated list of DB names]. Needed to set only if Redis + sentinel is used to provide high availability for Redis DB solution. Only one DB name + supported in RIC deployments, Nokia SEP deployments can have multiple DB names. + DBAAS_SERVICE_SENTINEL_PORT = [Comma separated list of Redis sentinel port number]. Needed + to set only if Redis sentinel is in use. Only one port supported in RIC deployments, Nokia + SEP deployments can have multiple ports. + DBASS_CLUSTER_ADDR_LIST = [Comma separated list of DB service addresses]. Is set only if + more than one Redis sentinel groups are in use. Only in use in Nokia SEP deployments. In official RIC deployments four first environment variables are defined in Helm configMaps of the DBaaS and these configurations can be loaded automatically as environment variables into application pods via `envFrom dbaas-appconfig` statement in an application Helm Charts. diff --git a/ricsdl-package/examples/sync.py b/ricsdl-package/examples/sync.py index 618586d..ce6ad20 100755 --- a/ricsdl-package/examples/sync.py +++ b/ricsdl-package/examples/sync.py @@ -1,5 +1,5 @@ # Copyright (c) 2019 AT&T Intellectual Property. -# Copyright (c) 2018-2019 Nokia. +# Copyright (c) 2018-2022 Nokia. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -40,18 +40,22 @@ Execution of these examples requires: * Following environment variables are needed to set to the pod/container where the application utilizing SDL is going to be run. DBAAS_SERVICE_HOST = [DB service address] - DBAAS_SERVICE_PORT= [DB service port] - DBAAS_MASTER_NAME = [DB name]. Needed to set only if Redis sentinel is used to provide high - availability for Redis DB solution. - DBAAS_SERVICE_SENTINEL_PORT = [Redis sentinel port number]. Needed to set only if Redis - sentinel is in use. - DBASS_CLUSTER_ADDR_LIST = [list of DB service addresses]. Is set only if more than one - Redis sentinel groups are in use. + DBAAS_SERVICE_PORT= [Comma separated list of DB service ports]. Only one port supported in + RIC deployments, Nokia SEP deployments can have multiple ports. + DBAAS_MASTER_NAME = [Comma separated list of DB names]. Needed to set only if Redis + sentinel is used to provide high availability for Redis DB solution. Only one DB name + supported in RIC deployments, Nokia SEP deployments can have multiple DB names. + DBAAS_SERVICE_SENTINEL_PORT = [Comma separated list of Redis sentinel port number]. Needed + to set only if Redis sentinel is in use. Only one port supported in RIC deployments, Nokia + SEP deployments can have multiple ports. + DBASS_CLUSTER_ADDR_LIST = [Comma separated list of DB service addresses]. Is set only if + more than one Redis sentinel groups are in use. Only in use in Nokia SEP deployments. In official RIC deployments four first environment variables are defined in Helm configMaps of the DBaaS and these configurations can be loaded automatically as environment variables into application pods via `envFrom dbaas-appconfig` statement in an application Helm Charts. The last environment variable is not for time being in use in official RIC deployments, only in Nokia SEP deployments. + """ from ricsdl.syncstorage import SyncStorage from ricsdl.exceptions import RejectedByBackend, NotConnected, BackendError diff --git a/ricsdl-package/ricsdl/__init__.py b/ricsdl-package/ricsdl/__init__.py index d8e421e..fc607ca 100644 --- a/ricsdl-package/ricsdl/__init__.py +++ b/ricsdl-package/ricsdl/__init__.py @@ -1,5 +1,5 @@ # Copyright (c) 2019 AT&T Intellectual Property. -# Copyright (c) 2018-2019 Nokia. +# Copyright (c) 2018-2022 Nokia. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ from .exceptions import ( ) -__version__ = '3.0.2' +__version__ = '3.1.0' __all__ = [ diff --git a/ricsdl-package/ricsdl/backend/redis.py b/ricsdl-package/ricsdl/backend/redis.py index 3ebc8cb..822afcf 100755 --- a/ricsdl-package/ricsdl/backend/redis.py +++ b/ricsdl-package/ricsdl/backend/redis.py @@ -1,5 +1,5 @@ # Copyright (c) 2019 AT&T Intellectual Property. -# Copyright (c) 2018-2019 Nokia. +# Copyright (c) 2018-2022 Nokia. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -370,25 +370,22 @@ class RedisBackend(DbBackendAbc): def __create_redis_clients(self, config): clients = list() cfg_params = config.get_params() - if cfg_params.db_cluster_addr_list is None: - clients.append(self.__create_legacy_redis_client(cfg_params)) - else: - for addr in cfg_params.db_cluster_addr_list.split(","): - client = self.__create_redis_client(cfg_params, addr) - clients.append(client) - return clients + for i, addr in enumerate(cfg_params.db_cluster_addrs): + port = cfg_params.db_ports[i] if i < len(cfg_params.db_ports) else "" + sport = cfg_params.db_sentinel_ports[i] if i < len(cfg_params.db_sentinel_ports) else "" + name = cfg_params.db_sentinel_master_names[i] if i < len(cfg_params.db_sentinel_master_names) else "" - def __create_legacy_redis_client(self, cfg_params): - return self.__create_redis_client(cfg_params, cfg_params.db_host) + client = self.__create_redis_client(addr, port, sport, name) + clients.append(client) + return clients - def __create_redis_client(self, cfg_params, addr): + def __create_redis_client(self, addr, port, sentinel_port, master_name): new_sentinel = None new_redis = None - if cfg_params.db_sentinel_port is None: - new_redis = Redis(host=addr, port=cfg_params.db_port, db=0, max_connections=20) + if len(sentinel_port) == 0: + new_redis = Redis(host=addr, port=port, db=0, max_connections=20) else: - sentinel_node = (addr, cfg_params.db_sentinel_port) - master_name = cfg_params.db_sentinel_master_name + sentinel_node = (addr, sentinel_port) new_sentinel = Sentinel([sentinel_node]) new_redis = new_sentinel.master_for(master_name) diff --git a/ricsdl-package/ricsdl/configuration.py b/ricsdl-package/ricsdl/configuration.py index e99e68e..99cde0f 100644 --- a/ricsdl-package/ricsdl/configuration.py +++ b/ricsdl-package/ricsdl/configuration.py @@ -1,5 +1,5 @@ # Copyright (c) 2019 AT&T Intellectual Property. -# Copyright (c) 2018-2019 Nokia. +# Copyright (c) 2018-2022 Nokia. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -33,9 +33,9 @@ class DbBackendType(Enum): class _Configuration(): """This class implements Shared Data Layer (SDL) configurability.""" - Params = namedtuple('Params', ['db_host', 'db_port', 'db_sentinel_port', - 'db_sentinel_master_name', - 'db_cluster_addr_list', 'db_type']) + Params = namedtuple('Params', ['db_host', 'db_ports', 'db_sentinel_ports', + 'db_sentinel_master_names', + 'db_cluster_addrs', 'db_type']) def __init__(self, fake_db_backend): self.params = self._read_configuration(fake_db_backend) @@ -44,10 +44,10 @@ class _Configuration(): return str( { "DB host": self.params.db_host, - "DB port": self.params.db_port, - "DB master sentinel": self.params.db_sentinel_master_name, - "DB sentinel port": self.params.db_sentinel_port, - "DB cluster address list": self.params.db_cluster_addr_list, + "DB ports": self.params.db_ports, + "DB master sentinels": self.params.db_sentinel_master_names, + "DB sentinel ports": self.params.db_sentinel_ports, + "DB cluster addresses": self.params.db_cluster_addrs, "DB type": self.params.db_type.name, } ) @@ -69,14 +69,48 @@ class _Configuration(): raise ValueError(msg) backend_type = DbBackendType.FAKE_DICT + host = os.getenv('DBAAS_SERVICE_HOST', "") - return _Configuration.Params(db_host=os.getenv('DBAAS_SERVICE_HOST'), - db_port=os.getenv('DBAAS_SERVICE_PORT'), - db_sentinel_port=os.getenv('DBAAS_SERVICE_SENTINEL_PORT'), - db_sentinel_master_name=os.getenv('DBAAS_MASTER_NAME'), - db_cluster_addr_list=os.getenv('DBAAS_CLUSTER_ADDR_LIST'), + port_env = os.getenv('DBAAS_SERVICE_PORT') + ports = port_env.split(",") if port_env is not None else list() + + sentinel_port_env = os.getenv('DBAAS_SERVICE_SENTINEL_PORT') + sentinel_ports = sentinel_port_env.split(",") if sentinel_port_env is not None else list() + + sentinel_name_env = os.getenv('DBAAS_MASTER_NAME') + sentinel_names = sentinel_name_env.split(",") if sentinel_name_env is not None else list() + + addr_env = os.getenv('DBAAS_CLUSTER_ADDR_LIST') + addrs = addr_env.split(",") if addr_env is not None else list() + + if len(addrs) == 0 and len(host) > 0: + addrs.append(host) + + addrs, ports, sentinel_ports, sentinel_names = cls._complete_configuration( + addrs, ports, sentinel_ports, sentinel_names) + + return _Configuration.Params(db_host=host, + db_ports=ports, + db_sentinel_ports=sentinel_ports, + db_sentinel_master_names=sentinel_names, + db_cluster_addrs=addrs, db_type=backend_type) + @classmethod + def _complete_configuration(cls, addrs, ports, sentinel_ports, sentinel_names): + if len(sentinel_ports) == 0: + if len(addrs) > len(ports) and len(ports) > 0: + for i in range(len(ports), len(addrs)): + ports.append(ports[i - 1]) + else: + if len(addrs) > len(sentinel_ports): + for i in range(len(sentinel_ports), len(addrs)): + sentinel_ports.append(sentinel_ports[i - 1]) + if len(addrs) > len(sentinel_names) and len(sentinel_names) > 0: + for i in range(len(sentinel_names), len(addrs)): + sentinel_names.append(sentinel_names[i - 1]) + return addrs, ports, sentinel_ports, sentinel_names + @classmethod def get_event_separator(cls): return "___" diff --git a/ricsdl-package/ricsdl/syncstorage.py b/ricsdl-package/ricsdl/syncstorage.py index b15365a..62e3a7f 100755 --- a/ricsdl-package/ricsdl/syncstorage.py +++ b/ricsdl-package/ricsdl/syncstorage.py @@ -1,5 +1,5 @@ # Copyright (c) 2019 AT&T Intellectual Property. -# Copyright (c) 2018-2019 Nokia. +# Copyright (c) 2018-2022 Nokia. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -119,6 +119,7 @@ class SyncStorage(SyncStorageAbc): """ def __init__(self, fake_db_backend=None) -> None: super().__init__() + self.__dbbackend = None self.__configuration = _Configuration(fake_db_backend) self.event_separator = self.__configuration.get_event_separator() self.__dbbackend = ricsdl.backend.get_backend_instance(self.__configuration) @@ -141,7 +142,8 @@ class SyncStorage(SyncStorageAbc): return False def close(self): - self.__dbbackend.close() + if self.__dbbackend: + self.__dbbackend.close() @func_arg_checker(SdlTypeError, 1, ns=str, data_map=dict) def set(self, ns: str, data_map: Dict[str, bytes]) -> None: diff --git a/ricsdl-package/tests/backend/test_fake_dict_db.py b/ricsdl-package/tests/backend/test_fake_dict_db.py index 6c5fd88..67b6ac1 100755 --- a/ricsdl-package/tests/backend/test_fake_dict_db.py +++ b/ricsdl-package/tests/backend/test_fake_dict_db.py @@ -1,5 +1,5 @@ # Copyright (c) 2019 AT&T Intellectual Property. -# Copyright (c) 2018-2019 Nokia. +# Copyright (c) 2018-2022 Nokia. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -50,10 +50,10 @@ def fake_dict_backend_fixture(request): request.cls.configuration = Mock() mock_conf_params = _Configuration.Params(db_host=None, - db_port=None, - db_sentinel_port=None, - db_sentinel_master_name=None, - db_cluster_addr_list=None, + db_ports=None, + db_sentinel_ports=None, + db_sentinel_master_names=None, + db_cluster_addrs=None, db_type=DbBackendType.FAKE_DICT) request.cls.configuration.get_params.return_value = mock_conf_params request.cls.db = ricsdl.backend.get_backend_instance(request.cls.configuration) @@ -327,10 +327,10 @@ def fake_dict_backend_lock_fixture(request): request.cls.configuration = Mock() mock_conf_params = _Configuration.Params(db_host=None, - db_port=None, - db_sentinel_port=None, - db_sentinel_master_name=None, - db_cluster_addr_list=None, + db_ports=None, + db_sentinel_ports=None, + db_sentinel_master_names=None, + db_cluster_addrs=None, db_type=DbBackendType.FAKE_DICT) request.cls.configuration.get_params.return_value = mock_conf_params request.cls.lock = ricsdl.backend.get_backend_lock_instance(request.cls.configuration, diff --git a/ricsdl-package/tests/backend/test_redis.py b/ricsdl-package/tests/backend/test_redis.py index 100795e..744f927 100755 --- a/ricsdl-package/tests/backend/test_redis.py +++ b/ricsdl-package/tests/backend/test_redis.py @@ -1,5 +1,5 @@ # Copyright (c) 2019 AT&T Intellectual Property. -# Copyright (c) 2018-2019 Nokia. +# Copyright (c) 2018-2022 Nokia. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -32,26 +32,26 @@ EVENT_SEPARATOR = "___" def get_test_sdl_standby_config(): return _Configuration.Params(db_host='service-ricplt-dbaas-tcp-cluster-0.ricplt', - db_port=6379, - db_sentinel_port=None, - db_sentinel_master_name=None, - db_cluster_addr_list=None, + db_ports=['6379'], + db_sentinel_ports=[], + db_sentinel_master_names=[], + db_cluster_addrs=['service-ricplt-dbaas-tcp-cluster-0.ricplt'], db_type=DbBackendType.REDIS) def get_test_sdl_sentinel_config(): return _Configuration.Params(db_host='service-ricplt-dbaas-tcp-cluster-0.ricplt', - db_port=6379, - db_sentinel_port=26379, - db_sentinel_master_name='dbaasmaster', - db_cluster_addr_list=None, + db_ports=['6379'], + db_sentinel_ports=['26379'], + db_sentinel_master_names=['dbaasmaster'], + db_cluster_addrs=['service-ricplt-dbaas-tcp-cluster-0.ricplt'], db_type=DbBackendType.REDIS) def get_test_sdl_sentinel_cluster_config(): return _Configuration.Params(db_host='service-ricplt-dbaas-tcp-cluster-0.ricplt', - db_port=6379, - db_sentinel_port=26379, - db_sentinel_master_name='dbaasmaster', - db_cluster_addr_list='service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt', + db_ports=['6379','6380'], + db_sentinel_ports=['26379','26380'], + db_sentinel_master_names=['dbaasmaster-cluster-0','dbaasmaster-cluster-1'], + db_cluster_addrs=['service-ricplt-dbaas-tcp-cluster-0.ricplt','service-ricplt-dbaas-tcp-cluster-1.ricplt'], db_type=DbBackendType.REDIS) @pytest.fixture() @@ -105,7 +105,7 @@ def redis_backend_fixture(request, redis_backend_common_fixture): request.cls.mock_pubsub_thread.is_alive.return_value = False request.cls.db = db - mock_redis.assert_called_once_with(db=0, host=cfg.db_host, max_connections=20, port=cfg.db_port) + mock_redis.assert_called_once_with(db=0, host=cfg.db_host, max_connections=20, port=cfg.db_ports[0]) mock_pubsub.assert_called_once_with(EVENT_SEPARATOR, request.cls.mock_redis.connection_pool, ignore_subscribe_messages=True) assert request.cls.mock_redis.set_response_callback.call_count == 2 @@ -124,8 +124,8 @@ def redis_backend_fixture(request, redis_backend_common_fixture): request.cls.mock_pubsub_thread.is_alive.return_value = False request.cls.db = db - mock_sentinel.assert_called_once_with([(cfg.db_host, cfg.db_sentinel_port)]) - mock_sentinel.master_for.called_once_with(cfg.db_sentinel_master_name) + mock_sentinel.assert_called_once_with([(cfg.db_host, cfg.db_sentinel_ports[0])]) + mock_sentinel.master_for.called_once_with(cfg.db_sentinel_master_names[0]) mock_pubsub.assert_called_once_with(EVENT_SEPARATOR, request.cls.mock_redis.connection_pool, ignore_subscribe_messages=True) assert request.cls.mock_redis.set_response_callback.call_count == 2 @@ -146,12 +146,12 @@ def redis_backend_fixture(request, redis_backend_common_fixture): assert mock_sentinel.call_count == 2 mock_sentinel.assert_has_calls([ - call([('service-ricplt-dbaas-tcp-cluster-0.ricplt', cfg.db_sentinel_port)]), - call([('service-ricplt-dbaas-tcp-cluster-1.ricplt', cfg.db_sentinel_port)]), + call([('service-ricplt-dbaas-tcp-cluster-0.ricplt', '26379')]), + call([('service-ricplt-dbaas-tcp-cluster-1.ricplt', '26380')]), ], any_order=True) assert mock_sentinel.return_value.master_for.call_count == 2 mock_sentinel.return_value.master_for.assert_has_calls( - [call(cfg.db_sentinel_master_name), call(cfg.db_sentinel_master_name)], any_order=True, + [call('dbaasmaster-cluster-0'), call('dbaasmaster-cluster-1')], any_order=True, ) assert mock_pubsub.call_count == 2 mock_pubsub.assert_has_calls([ @@ -728,10 +728,10 @@ def redis_backend_lock_fixture(request, mock_redis_lock): request.cls.configuration = Mock() mock_conf_params = _Configuration.Params(db_host=None, - db_port=None, - db_sentinel_port=None, - db_sentinel_master_name=None, - db_cluster_addr_list=None, + db_ports=None, + db_sentinel_ports=None, + db_sentinel_master_names=None, + db_cluster_addrs=None, db_type=DbBackendType.REDIS) request.cls.configuration.get_params.return_value = mock_conf_params diff --git a/ricsdl-package/tests/test_configuration.py b/ricsdl-package/tests/test_configuration.py index 1c89663..28fa90e 100644 --- a/ricsdl-package/tests/test_configuration.py +++ b/ricsdl-package/tests/test_configuration.py @@ -1,5 +1,5 @@ # Copyright (c) 2019 AT&T Intellectual Property. -# Copyright (c) 2018-2019 Nokia. +# Copyright (c) 2018-2022 Nokia. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -27,13 +27,12 @@ from ricsdl.configuration import DbBackendType @pytest.fixture() def config_fixture(request, monkeypatch): monkeypatch.setenv('DBAAS_SERVICE_HOST', 'service-ricplt-dbaas-tcp-cluster-0.ricplt') - monkeypatch.setenv('DBAAS_SERVICE_PORT', '10000') - monkeypatch.setenv('DBAAS_SERVICE_SENTINEL_PORT', '11000') - monkeypatch.setenv('DBAAS_MASTER_NAME', 'my-master') + monkeypatch.setenv('DBAAS_SERVICE_PORT', '10000,10001') + monkeypatch.setenv('DBAAS_SERVICE_SENTINEL_PORT', '11000,11001') + monkeypatch.setenv('DBAAS_MASTER_NAME', 'my-master-0,my-master-1') monkeypatch.setenv('DBAAS_CLUSTER_ADDR_LIST', 'service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt') request.cls.config = _Configuration(fake_db_backend=None) - @pytest.fixture def fake_db_config_fixture(request, monkeypatch): monkeypatch.delenv('DBAAS_SERVICE_HOST', raising=False) @@ -43,22 +42,21 @@ def fake_db_config_fixture(request, monkeypatch): monkeypatch.delenv('DBAAS_CLUSTER_ADDR_LIST', raising=False) request.cls.config = _Configuration(fake_db_backend='dict') - class TestConfiguration: def test_get_params_function_returns_read_configuration(self, config_fixture): expected_config = _Configuration.Params(db_host='service-ricplt-dbaas-tcp-cluster-0.ricplt', - db_port='10000', - db_sentinel_port='11000', - db_sentinel_master_name='my-master', - db_cluster_addr_list='service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt', + db_ports=['10000','10001'], + db_sentinel_ports=['11000','11001'], + db_sentinel_master_names=['my-master-0','my-master-1'], + db_cluster_addrs=['service-ricplt-dbaas-tcp-cluster-0.ricplt','service-ricplt-dbaas-tcp-cluster-1.ricplt'], db_type=DbBackendType.REDIS) assert expected_config == self.config.get_params() def test_get_params_function_can_return_fake_db_configuration(self, fake_db_config_fixture): - expected_config = _Configuration.Params(db_host=None, db_port=None, - db_sentinel_port=None, - db_sentinel_master_name=None, - db_cluster_addr_list=None, + expected_config = _Configuration.Params(db_host='', db_ports=[], + db_sentinel_ports=[], + db_sentinel_master_names=[], + db_cluster_addrs=[], db_type=DbBackendType.FAKE_DICT) assert expected_config == self.config.get_params() @@ -72,18 +70,61 @@ class TestConfiguration: def test_configuration_object_string_representation(self, config_fixture): expected_config_info = {'DB host': 'service-ricplt-dbaas-tcp-cluster-0.ricplt', - 'DB port': '10000', - 'DB master sentinel': 'my-master', - 'DB sentinel port': '11000', - 'DB cluster address list': 'service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt', + 'DB ports': ['10000','10001'], + 'DB master sentinels': ['my-master-0','my-master-1'], + 'DB sentinel ports': ['11000','11001'], + 'DB cluster addresses': ['service-ricplt-dbaas-tcp-cluster-0.ricplt','service-ricplt-dbaas-tcp-cluster-1.ricplt'], 'DB type': 'REDIS'} assert str(self.config) == str(expected_config_info) def test_configuration_object_string_representation_if_fake_db(self, fake_db_config_fixture): - expected_config_info = {'DB host': None, - 'DB port': None, - 'DB master sentinel': None, - 'DB sentinel port': None, - 'DB cluster address list': None, + expected_config_info = {'DB host': '', + 'DB ports': [], + 'DB master sentinels': [], + 'DB sentinel ports': [], + 'DB cluster addresses': [], 'DB type': 'FAKE_DICT'} assert str(self.config) == str(expected_config_info) + + def test_complete_configuration_if_less_ports_than_addresses(self, monkeypatch): + monkeypatch.setenv('DBAAS_SERVICE_HOST', 'service-ricplt-dbaas-tcp-cluster-0.ricplt') + monkeypatch.setenv('DBAAS_SERVICE_PORT', '10000') + monkeypatch.setenv('DBAAS_CLUSTER_ADDR_LIST', 'service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt') + + expected_config = _Configuration.Params(db_host='service-ricplt-dbaas-tcp-cluster-0.ricplt', + db_ports=['10000','10000'], + db_sentinel_ports=[], + db_sentinel_master_names=[], + db_cluster_addrs=['service-ricplt-dbaas-tcp-cluster-0.ricplt','service-ricplt-dbaas-tcp-cluster-1.ricplt'], + db_type=DbBackendType.REDIS) + assert expected_config == _Configuration(fake_db_backend=None).get_params() + + def test_complete_configuration_if_less_sentinel_ports_than_addresses(self, monkeypatch): + monkeypatch.setenv('DBAAS_SERVICE_HOST', 'service-ricplt-dbaas-tcp-cluster-0.ricplt') + monkeypatch.setenv('DBAAS_SERVICE_PORT', '10000,10001') + monkeypatch.setenv('DBAAS_SERVICE_SENTINEL_PORT', '11000') + monkeypatch.setenv('DBAAS_MASTER_NAME', 'my-master-0,my-master-1') + monkeypatch.setenv('DBAAS_CLUSTER_ADDR_LIST', 'service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt') + + expected_config = _Configuration.Params(db_host='service-ricplt-dbaas-tcp-cluster-0.ricplt', + db_ports=['10000','10001'], + db_sentinel_ports=['11000','11000'], + db_sentinel_master_names=['my-master-0','my-master-1'], + db_cluster_addrs=['service-ricplt-dbaas-tcp-cluster-0.ricplt','service-ricplt-dbaas-tcp-cluster-1.ricplt'], + db_type=DbBackendType.REDIS) + assert expected_config == _Configuration(fake_db_backend=None).get_params() + + def test_complete_configuration_if_less_sentinel_names_than_addresses(self, monkeypatch): + monkeypatch.setenv('DBAAS_SERVICE_HOST', 'service-ricplt-dbaas-tcp-cluster-0.ricplt') + monkeypatch.setenv('DBAAS_SERVICE_PORT', '10000,10001') + monkeypatch.setenv('DBAAS_SERVICE_SENTINEL_PORT', '11000,11001') + monkeypatch.setenv('DBAAS_MASTER_NAME', 'my-master-0') + monkeypatch.setenv('DBAAS_CLUSTER_ADDR_LIST', 'service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt') + + expected_config = _Configuration.Params(db_host='service-ricplt-dbaas-tcp-cluster-0.ricplt', + db_ports=['10000','10001'], + db_sentinel_ports=['11000','11001'], + db_sentinel_master_names=['my-master-0','my-master-0'], + db_cluster_addrs=['service-ricplt-dbaas-tcp-cluster-0.ricplt','service-ricplt-dbaas-tcp-cluster-1.ricplt'], + db_type=DbBackendType.REDIS) + assert expected_config == _Configuration(fake_db_backend=None).get_params() -- 2.16.6