Exemplo n.º 1
0
    def setUp(self) -> None:
        self.dummy_logger = logging.getLogger('dummy')
        self.dummy_logger.disabled = True
        self.db = env.REDIS_DB
        self.host = 'dummyhost'
        self.port = 6379
        self.live_check_time_interval = timedelta(seconds=3)
        self.live_check_time_interval_with_error_margin = timedelta(seconds=4)
        self.redis = RedisApi(
            self.dummy_logger,
            self.db,
            self.host,
            self.port,
            live_check_time_interval=self.live_check_time_interval)

        self.key = 'key'
        self.val = 'val'
        self.time = timedelta.max
Exemplo n.º 2
0
    def setUp(self) -> None:
        self.dummy_logger = logging.getLogger('dummy')
        self.dummy_logger.disabled = True
        self.db = env.REDIS_DB
        self.host = 'dummyhost'
        self.port = env.REDIS_PORT
        self.namespace = 'testnamespace'
        self.redis = RedisApi(self.dummy_logger,
                              self.db,
                              self.host,
                              self.port,
                              namespace=self.namespace)

        self.key = 'key'
        self.val = 'val'
        self.hash_name = "dummy hash"
        self.some_key = 'some key'
        self.time = timedelta.max
Exemplo n.º 3
0
    def setUp(self) -> None:
        self.dummy_logger = logging.getLogger('dummy')
        self.dummy_logger.disabled = True
        self.hash_name = "dummy_hash"
        self.db = env.REDIS_DB
        self.host = env.REDIS_IP
        self.port = env.REDIS_PORT
        self.namespace = 'testnamespace'
        self.password = ''
        self.redis = RedisApi(logger=self.dummy_logger,
                              db=self.db,
                              host=self.host,
                              port=self.port,
                              password=self.password,
                              namespace=self.namespace)

        # Ping Redis
        try:
            self.redis.ping_unsafe()
        except RedisConnectionError:
            self.fail('Redis is not online.')

        # Clear test database
        self.redis.delete_all_unsafe()

        self.key1 = 'key1'
        self.key2 = 'key2'
        self.key3 = 'key3'
        self.key4 = 'key4'

        self.val1 = 'val1'
        self.val1_bytes = bytes('val1', encoding='utf8')
        self.val2 = 'val2'
        self.val2_bytes = bytes('val2', encoding='utf8')
        self.val3_int = 123
        self.val4 = str(True)
        self.val4_bool = True

        self.time = timedelta(seconds=3)
        self.time_with_error_margin = timedelta(seconds=4)

        self.default_str = 'DEFAULT'
        self.default_int = 789
        self.default_bool = False
Exemplo n.º 4
0
    def test_set_unsafe_throws_exception_if_incorrect_password(self):
        redis_bad_pass = RedisApi(self.dummy_logger,
                                  self.db,
                                  self.host,
                                  self.port,
                                  password='******',
                                  namespace=self.namespace)

        self.assertRaises((AuthenticationError, ResponseError),
                          redis_bad_pass.set_unsafe, self.key1, self.val1)
Exemplo n.º 5
0
    def setUpClass(cls) -> None:
        # Same as in setUp(), to avoid running all tests if Redis is offline

        dummy_logger = logging.getLogger('dummy')
        dummy_logger.disabled = True
        db = env.REDIS_DB
        host = env.REDIS_IP
        port = env.REDIS_PORT
        password = ''
        redis = RedisApi(logger=dummy_logger,
                         db=db,
                         host=host,
                         port=port,
                         password=password)

        # Ping Redis
        try:
            redis.ping_unsafe()
        except RedisConnectionError:
            raise Exception('Redis is not online.')
Exemplo n.º 6
0
    def __init__(self, name: str, logger: logging.Logger,
                 rabbitmq: RabbitMQApi) -> None:
        super().__init__(logger, rabbitmq)
        self._name = name
        self._mongo_ip = env.DB_IP
        self._mongo_db = env.DB_NAME
        self._mongo_port = env.DB_PORT

        redis_ip = env.REDIS_IP
        redis_db = env.REDIS_DB
        redis_port = env.REDIS_PORT
        unique_alerter_identifier = env.UNIQUE_ALERTER_IDENTIFIER

        self._mongo = None
        self._redis = RedisApi(logger=self._logger.getChild(RedisApi.__name__),
                               db=redis_db,
                               host=redis_ip,
                               port=redis_port,
                               namespace=unique_alerter_identifier)
Exemplo n.º 7
0
    def setUp(self) -> None:
        self.dummy_logger = logging.getLogger('dummy')
        self.dummy_logger.disabled = True
        self.db = env.REDIS_DB
        self.host = env.REDIS_IP
        self.port = env.REDIS_PORT
        self.namespace1 = 'testnamespace1'
        self.namespace2 = 'testnamespace2'
        self.password = ''
        self.redis = RedisApi(logger=self.dummy_logger,
                              db=self.db,
                              host=self.host,
                              port=self.port,
                              password=self.password,
                              namespace=self.namespace1)

        self.same_namespace = RedisApi(logger=self.dummy_logger,
                                       db=self.db,
                                       host=self.host,
                                       port=self.port,
                                       password=self.password,
                                       namespace=self.namespace1)

        self.redis_different_namespace = RedisApi(logger=self.dummy_logger,
                                                  db=self.db,
                                                  host=self.host,
                                                  port=self.port,
                                                  password=self.password,
                                                  namespace=self.namespace2)

        # Ping Redis (all of above instances use same host, port, pass)
        try:
            self.redis.ping_unsafe()
        except RedisConnectionError:
            self.fail('Redis is not online.')

        # Clear test database (all of above instances use same database)
        self.redis.delete_all_unsafe()
        self.redis_different_namespace.delete_all_unsafe()

        self.key1 = 'key1'
        self.key2 = 'key2'

        self.val1 = 'val1'
        self.val1_bytes = bytes('val1', encoding='utf8')
        self.val2 = 'val2'
        self.val2_bytes = bytes('val2', encoding='utf8')
        self.hash_name = 'dummy_hash'
Exemplo n.º 8
0
class TestRedisNamespaceWithRedisOnline(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        # Same as in setUp(), to avoid running all tests if Redis is offline

        dummy_logger = logging.getLogger('dummy')
        dummy_logger.disabled = True
        db = env.REDIS_DB
        host = env.REDIS_IP
        port = env.REDIS_PORT
        password = ''
        redis = RedisApi(logger=dummy_logger,
                         db=db,
                         host=host,
                         port=port,
                         password=password)

        # Ping Redis
        try:
            redis.ping_unsafe()
        except RedisConnectionError:
            raise Exception('Redis is not online.')

    def setUp(self) -> None:
        self.dummy_logger = logging.getLogger('dummy')
        self.dummy_logger.disabled = True
        self.db = env.REDIS_DB
        self.host = env.REDIS_IP
        self.port = env.REDIS_PORT
        self.namespace1 = 'testnamespace1'
        self.namespace2 = 'testnamespace2'
        self.password = ''
        self.redis = RedisApi(logger=self.dummy_logger,
                              db=self.db,
                              host=self.host,
                              port=self.port,
                              password=self.password,
                              namespace=self.namespace1)

        self.same_namespace = RedisApi(logger=self.dummy_logger,
                                       db=self.db,
                                       host=self.host,
                                       port=self.port,
                                       password=self.password,
                                       namespace=self.namespace1)

        self.redis_different_namespace = RedisApi(logger=self.dummy_logger,
                                                  db=self.db,
                                                  host=self.host,
                                                  port=self.port,
                                                  password=self.password,
                                                  namespace=self.namespace2)

        # Ping Redis (all of above instances use same host, port, pass)
        try:
            self.redis.ping_unsafe()
        except RedisConnectionError:
            self.fail('Redis is not online.')

        # Clear test database (all of above instances use same database)
        self.redis.delete_all_unsafe()
        self.redis_different_namespace.delete_all_unsafe()

        self.key1 = 'key1'
        self.key2 = 'key2'

        self.val1 = 'val1'
        self.val1_bytes = bytes('val1', encoding='utf8')
        self.val2 = 'val2'
        self.val2_bytes = bytes('val2', encoding='utf8')
        self.hash_name = 'dummy_hash'

    def tearDown(self) -> None:
        self.dummy_logger = None
        self.redis.delete_all_unsafe()
        self.redis_different_namespace.delete_all_unsafe()
        self.redis = None

    def test_set_uses_namespace_internally(self):
        self.redis.set_unsafe(self.key1, self.val1)

        # Use raw Redis command to get, to bypass automatically-added namespace
        get_value = self.redis._redis.get(self.namespace1 + ':' + self.key1)

        self.assertEqual(get_value, self.val1_bytes)

    def test_hset_uses_namespace_internally(self):
        self.redis.hset_unsafe(self.hash_name, self.key1, self.val1)

        # Use raw Redis command to get, to bypass automatically-added namespace
        get_value = self.redis._redis.hget(
            self.namespace1 + ':' + self.hash_name, self.key1)

        self.assertEqual(get_value, self.val1_bytes)

    def test_get_uses_namespace_internally(self):
        # Use raw Redis command to set, to bypass automatically-added namespace
        self.redis._redis.set(self.namespace1 + ':' + self.key1, self.val1)

        get_value = self.redis.get_unsafe(self.key1)
        self.assertEqual(get_value, self.val1_bytes)

    def test_hget_uses_namespace_internally(self):

        # Use raw Redis command to set, to bypass automatically-added namespace
        self.redis._redis.hset(self.namespace1 + ':' + self.hash_name,
                               self.key1, self.val1)

        get_value = self.redis.hget_unsafe(self.hash_name, self.key1)
        self.assertEqual(get_value, self.val1_bytes)

    def test_redis_api_with_same_namespace_has_access_to_same_store(self):
        self.redis.set_unsafe(self.key1, self.val1)

        self.assertEqual(self.same_namespace.get_unsafe(self.key1),
                         self.val1_bytes)

    def test_redis_api_with_redis_different_namespace_has_separate_store(self):
        self.redis.set_unsafe(self.key1, self.val1)

        self.assertNotEqual(
            self.redis_different_namespace.get_unsafe(self.key1),
            self.val1_bytes)
Exemplo n.º 9
0
class TestRedisApiWithRedisOffline(unittest.TestCase):
    def setUp(self) -> None:
        self.dummy_logger = logging.getLogger('dummy')
        self.dummy_logger.disabled = True
        self.db = env.REDIS_DB
        self.host = 'dummyhost'
        self.port = env.REDIS_PORT
        self.namespace = 'testnamespace'
        self.redis = RedisApi(self.dummy_logger,
                              self.db,
                              self.host,
                              self.port,
                              namespace=self.namespace)

        self.key = 'key'
        self.val = 'val'
        self.hash_name = "dummy hash"
        self.some_key = 'some key'
        self.time = timedelta.max

    def tearDown(self) -> None:
        self.dummy_logger = None
        self.redis = None

    def test_add_namespace_adds_namespace(self):
        key_with_namespace = self.namespace + ':' + self.some_key

        self.assertEqual(key_with_namespace,
                         self.redis._add_namespace(self.some_key))

    def test_remove_namespace_remove_namespace(self):
        key_with_namespace = self.namespace + ':' + self.some_key

        self.assertEqual(self.some_key,
                         self.redis._remove_namespace(key_with_namespace))

    def test_add_namespace_adds_nothing_if_already_added_namespace(self):
        key_with_namespace = self.namespace + ':' + self.some_key

        self.assertEqual(key_with_namespace,
                         self.redis._add_namespace(key_with_namespace))

    def test_remove_namespace_removes_nothing_if_no_namespace(self):
        self.assertEqual(self.some_key,
                         self.redis._remove_namespace(self.some_key))

    def test_set_unsafe_throws_connection_exception(self):
        self.assertRaises(RedisConnectionError, self.redis.set_unsafe,
                          self.key, self.val)

    def test_hset_unsafe_throws_connection_exception(self):
        self.assertRaises(RedisConnectionError, self.redis.hset_unsafe,
                          self.hash_name, self.key, self.val)

    def test_set_multiple_unsafe_throws_connection_exception(self):
        self.assertRaises(RedisConnectionError, self.redis.set_multiple_unsafe,
                          {self.key: self.val})

    def test_hset_multiple_unsafe_throws_connection_exception(self):
        self.assertRaises(RedisConnectionError,
                          self.redis.hset_multiple_unsafe, self.hash_name,
                          {self.key: self.val})

    def test_set_for_unsafe_throws_connection_exception(self):
        self.assertRaises(RedisConnectionError, self.redis.set_for_unsafe,
                          self.key, self.val, self.time)

    def test_time_to_live_unsafe_throws_connection_exception(self):
        self.assertRaises(RedisConnectionError, self.redis.time_to_live_unsafe,
                          self.key)

    def test_get_unsafe_throws_connection_exception(self):
        self.assertRaises(RedisConnectionError, self.redis.get_unsafe,
                          self.key)

    def test_hget_unsafe_throws_connection_exception(self):
        self.assertRaises(RedisConnectionError, self.redis.hget_unsafe,
                          self.hash_name, self.key)

    def test_get_int_unsafe_throws_connection_exception(self):
        self.assertRaises(RedisConnectionError, self.redis.get_int_unsafe,
                          self.key)

    def test_hget_int_unsafe_throws_connection_exception(self):
        self.assertRaises(RedisConnectionError, self.redis.hget_int_unsafe,
                          self.hash_name, self.key)

    def test_get_bool_unsafe_throws_connection_exception(self):
        self.assertRaises(RedisConnectionError, self.redis.get_bool_unsafe,
                          self.key)

    def test_hget_bool_unsafe_throws_connection_exception(self):
        self.assertRaises(RedisConnectionError, self.redis.hget_bool_unsafe,
                          self.hash_name, self.key)

    def test_exists_unsafe_throws_connection_exception(self):
        self.assertRaises(RedisConnectionError, self.redis.exists_unsafe,
                          self.key)

    def test_hexists_unsafe_throws_connection_exception(self):
        self.assertRaises(RedisConnectionError, self.redis.hexists_unsafe,
                          self.hash_name, self.key)

    def test_get_keys_unsafe_throws_connection_exception(self):
        self.assertRaises(RedisConnectionError, self.redis.get_keys_unsafe)

    def test_remove_unsafe_throws_connection_exception(self):
        self.assertRaises(RedisConnectionError, self.redis.remove_unsafe,
                          self.key)

    def test_hremove_unsafe_throws_connection_exception(self):
        self.assertRaises(RedisConnectionError, self.redis.hremove_unsafe,
                          self.hash_name, self.key)

    def test_delete_all_unsafe_throws_connection_exception(self):
        self.assertRaises(RedisConnectionError, self.redis.delete_all_unsafe)

    def test_set_returns_none(self):
        self.assertIsNone(self.redis.set(self.key, self.val))

    def test_hset_returns_none(self):
        self.assertIsNone(self.redis.hset(self.hash_name, self.key, self.val))

    def test_set_multiple_returns_none(self):
        self.assertIsNone(self.redis.set_multiple({self.key: self.val}))

    def test_hset_multiple_returns_none(self):
        self.assertIsNone(
            self.redis.hset_multiple(self.hash_name, {self.key: self.val}))

    def test_set_for_returns_none(self):
        self.assertIsNone(self.redis.set_for(self.key, self.val, self.time))

    def test_time_to_live_returns_none(self):
        self.assertIsNone(self.redis.time_to_live(self.key))

    def test_get_returns_none_if_no_default_specified(self):
        self.assertIsNone(self.redis.get(self.key))

    def test_get_returns_default_if_default_specified(self):
        default = 'default'
        self.assertEqual(self.redis.get(self.key, default=default), default)

    def test_hget_returns_none_if_no_default_specified(self):
        self.assertIsNone(self.redis.hget(self.hash_name, self.key))

    def test_hget_returns_default_if_default_specified(self):
        default = 'default'
        self.assertEqual(
            self.redis.hget(self.hash_name, self.key, default=default),
            default)

    def test_get_int_returns_none_if_no_default_specified(self):
        self.assertIsNone(self.redis.get_int(self.key))

    def test_get_int_returns_default_if_default_specified(self):
        default = 123456
        self.assertEqual(self.redis.get_int(self.key, default=default),
                         default)

    def test_hget_int_returns_none_if_no_default_specified(self):
        self.assertIsNone(self.redis.hget_int(self.hash_name, self.key))

    def test_hget_int_returns_default_if_default_specified(self):
        default = 123456
        self.assertEqual(
            self.redis.hget_int(self.hash_name, self.key, default=default),
            default)

    def test_get_bool_returns_none_if_no_default_specified(self):
        self.assertIsNone(self.redis.get_bool(self.key))

    def test_get_bool_returns_default_if_default_specified(self):
        default = True
        self.assertEqual(self.redis.get_bool(self.key, default=default),
                         default)

    def test_hget_bool_returns_none_if_no_default_specified(self):
        self.assertIsNone(self.redis.hget_bool(self.hash_name, self.key))

    def test_hget_bool_returns_default_if_default_specified(self):
        default = True
        self.assertEqual(
            self.redis.hget_bool(self.hash_name, self.key, default=default),
            default)

    def test_exists_returns_false(self):
        self.assertFalse(self.redis.exists(self.key))

    def test_hexists_returns_false(self):
        self.assertFalse(self.redis.hexists(self.hash_name, self.key))

    def test_get_keys_returns_empty_list(self):
        self.assertListEqual(self.redis.get_keys(), [])

    def test_remove_returns_none(self):
        self.assertIsNone(self.redis.remove(self.key))

    def test_hremove_returns_none(self):
        self.assertIsNone(self.redis.hremove(self.hash_name, self.key))

    def test_delete_all_returns_none(self):
        self.assertIsNone(self.redis.delete_all())

    def test_ping_unsafe_throws_connection_exception(self):
        self.assertRaises(RedisConnectionError, self.redis.ping_unsafe)
Exemplo n.º 10
0
class TestRedisApiWithRedisOnline(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        # Same as in setUp(), to avoid running all tests if Redis is offline

        dummy_logger = logging.getLogger('dummy')
        dummy_logger.disabled = True
        db = env.REDIS_DB
        host = env.REDIS_IP
        port = env.REDIS_PORT
        password = ''
        redis = RedisApi(logger=dummy_logger,
                         db=db,
                         host=host,
                         port=port,
                         password=password)

        # Ping Redis
        try:
            redis.ping_unsafe()
        except RedisConnectionError:
            raise Exception('Redis is not online.')

    def setUp(self) -> None:
        self.dummy_logger = logging.getLogger('dummy')
        self.dummy_logger.disabled = True
        self.hash_name = "dummy_hash"
        self.db = env.REDIS_DB
        self.host = env.REDIS_IP
        self.port = env.REDIS_PORT
        self.namespace = 'testnamespace'
        self.password = ''
        self.redis = RedisApi(logger=self.dummy_logger,
                              db=self.db,
                              host=self.host,
                              port=self.port,
                              password=self.password,
                              namespace=self.namespace)

        # Ping Redis
        try:
            self.redis.ping_unsafe()
        except RedisConnectionError:
            self.fail('Redis is not online.')

        # Clear test database
        self.redis.delete_all_unsafe()

        self.key1 = 'key1'
        self.key2 = 'key2'
        self.key3 = 'key3'
        self.key4 = 'key4'

        self.val1 = 'val1'
        self.val1_bytes = bytes('val1', encoding='utf8')
        self.val2 = 'val2'
        self.val2_bytes = bytes('val2', encoding='utf8')
        self.val3_int = 123
        self.val4 = str(True)
        self.val4_bool = True

        self.time = timedelta(seconds=3)
        self.time_with_error_margin = timedelta(seconds=4)

        self.default_str = 'DEFAULT'
        self.default_int = 789
        self.default_bool = False

    def tearDown(self) -> None:
        self.dummy_logger = None
        self.redis.delete_all_unsafe()
        self.redis = None

    def test_set_unsafe_throws_exception_if_incorrect_password(self):
        redis_bad_pass = RedisApi(self.dummy_logger,
                                  self.db,
                                  self.host,
                                  self.port,
                                  password='******',
                                  namespace=self.namespace)

        self.assertRaises((AuthenticationError, ResponseError),
                          redis_bad_pass.set_unsafe, self.key1, self.val1)

    def test_set_unsafe_sets_the_specified_key_to_the_specified_value(self):
        self.redis.set_unsafe(self.key1, self.val1)
        self.assertEqual(self.redis.get_unsafe(self.key1), self.val1_bytes)

    def test_set_unsafe_throws_exception_if_invalid_type(self):
        self.assertRaises(DataError, self.redis.set_unsafe, self.key1, True)

    def test_hset_unsafe_throws_exception_if_incorrect_password(self):
        redis_bad_pass = RedisApi(self.dummy_logger,
                                  self.db,
                                  self.host,
                                  self.port,
                                  password='******',
                                  namespace=self.namespace)
        self.assertRaises((AuthenticationError, ResponseError),
                          redis_bad_pass.hset_unsafe, self.hash_name,
                          self.key1, self.val1)

    def test_hset_unsafe_sets_the_specified_key_to_the_specified_value(self):
        self.redis.hset_unsafe(self.hash_name, self.key1, self.val1)
        self.assertEqual(self.redis.hget_unsafe(self.hash_name, self.key1),
                         self.val1_bytes)

    def test_hset_unsafe_throws_exception_if_invalid_type(self):
        self.assertRaises(DataError, self.redis.hset_unsafe, self.hash_name,
                          self.key1, True)

    def test_set_multiple_unsafe_sets_multiple_key_value_pairs(self):
        self.redis.set_multiple_unsafe({
            self.key1: self.val1,
            self.key2: self.val2
        })
        self.assertEqual(self.redis.get_unsafe(self.key1), self.val1_bytes)
        self.assertEqual(self.redis.get_unsafe(self.key2), self.val2_bytes)

    def test_hset_multiple_unsafe_sets_multiple_key_value_pairs(self):
        self.redis.hset_multiple_unsafe(self.hash_name, {
            self.key1: self.val1,
            self.key2: self.val2
        })
        self.assertEqual(self.redis.hget_unsafe(self.hash_name, self.key1),
                         self.val1_bytes)
        self.assertEqual(self.redis.hget_unsafe(self.hash_name, self.key2),
                         self.val2_bytes)

    def test_set_for_unsafe_temporarily_sets_specified_key_value_pair(self):
        self.redis.set_for_unsafe(self.key1, self.val1, self.time)
        self.assertEqual(self.redis.get_unsafe(self.key1), self.val1_bytes)

        sleep(self.time_with_error_margin.seconds)
        self.assertNotEqual(self.redis.get_unsafe(self.key1), self.val1_bytes)

    def test_time_to_live_unsafe_returns_None_if_key_does_not_exist(self):
        self.redis.set(self.key1, self.val1)

        self.assertIsNone(self.redis.time_to_live_unsafe(self.key1))

    def test_time_to_live_unsafe_returns_None_if_key_does_not_have_timeout(
            self):
        self.assertIsNone(self.redis.time_to_live_unsafe(self.key1))

    def test_time_to_live_unsafe_returns_correct_timeout_if_set(self):
        self.redis.set_for_unsafe(self.key1, self.val1, self.time)

        self.assertEqual(self.time.seconds,
                         self.redis.time_to_live_unsafe(self.key1))

    def test_get_unsafe_returns_default_for_unset_key(self):
        self.assertEqual(
            self.redis.get_unsafe(self.key1, default=self.default_str),
            self.default_str)

    def test_get_unsafe_returns_set_value(self):
        self.redis.set_unsafe(self.key1, self.val1)
        self.assertEqual(
            self.redis.get_unsafe(self.key1, default=self.default_str),
            self.val1_bytes)

    def test_get_unsafe_returns_none_for_none_string(self):
        self.redis.set_unsafe(self.key1, 'None')
        self.assertIsNone(
            self.redis.get_unsafe(self.key1, default=self.default_str))

    def test_hget_unsafe_returns_default_for_unset_key(self):
        self.assertEqual(
            self.redis.hget_unsafe(self.hash_name,
                                   self.key1,
                                   default=self.default_str), self.default_str)

    def test_hget_unsafe_returns_set_value(self):
        self.redis.hset_unsafe(self.hash_name, self.key1, self.val1)
        self.assertEqual(
            self.redis.hget_unsafe(self.hash_name,
                                   self.key1,
                                   default=self.default_str), self.val1_bytes)

    def test_hget_unsafe_returns_none_for_none_string(self):
        self.redis.hset_unsafe(self.hash_name, self.key1, 'None')
        self.assertIsNone(
            self.redis.hget_unsafe(self.hash_name,
                                   self.key1,
                                   default=self.default_str))

    def test_get_int_unsafe_returns_set_integer(self):
        self.redis.set_unsafe(self.key3, self.val3_int)
        self.assertEqual(
            self.redis.get_int_unsafe(self.key3, default=self.default_int),
            self.val3_int)

    def test_get_int_unsafe_returns_default_for_unset_key(self):
        self.assertEqual(
            self.redis.get_int_unsafe(self.key3, default=self.default_int),
            self.default_int)

    def test_get_int_unsafe_returns_default_for_non_integer_value(self):
        self.redis.set_unsafe(self.key2, self.val2)
        self.assertEqual(
            self.redis.get_int_unsafe(self.key2, default=self.default_int),
            self.default_int)

    def test_hget_int_unsafe_returns_set_integer(self):
        self.redis.hset_unsafe(self.hash_name, self.key3, self.val3_int)
        self.assertEqual(
            self.redis.hget_int_unsafe(self.hash_name,
                                       self.key3,
                                       default=self.default_int),
            self.val3_int)

    def test_hget_int_unsafe_returns_default_for_unset_key(self):
        self.assertEqual(
            self.redis.hget_int_unsafe(self.hash_name,
                                       self.key3,
                                       default=self.default_int),
            self.default_int)

    def test_hget_int_unsafe_returns_default_for_non_integer_value(self):
        self.redis.hset_unsafe(self.hash_name, self.key2, self.val2)
        self.assertEqual(
            self.redis.hget_int_unsafe(self.hash_name,
                                       self.key2,
                                       default=self.default_int),
            self.default_int)

    def test_get_bool_unsafe_returns_set_boolean(self):
        self.redis.set_unsafe(self.key4, self.val4)
        self.assertEqual(
            self.redis.get_bool_unsafe(self.key4, default=self.default_bool),
            self.val4_bool)

    def test_get_bool_unsafe_returns_default_for_unset_key(self):
        self.assertEqual(
            self.redis.get_bool_unsafe(self.key4, default=self.default_bool),
            self.default_bool)

    def test_get_bool_unsafe_returns_false_for_non_boolean_value(self):
        self.redis.set_unsafe(self.key1, self.val1)
        self.assertFalse(
            self.redis.get_bool_unsafe(self.key1, default=self.default_bool))

    def test_hget_bool_unsafe_returns_set_boolean(self):
        self.redis.hset_unsafe(self.hash_name, self.key4, self.val4)
        self.assertEqual(
            self.redis.hget_bool_unsafe(self.hash_name,
                                        self.key4,
                                        default=self.default_bool),
            self.val4_bool)

    def test_hget_bool_unsafe_returns_default_for_unset_key(self):
        self.assertEqual(
            self.redis.hget_bool_unsafe(self.hash_name,
                                        self.key4,
                                        default=self.default_bool),
            self.default_bool)

    def test_hget_bool_unsafe_returns_false_for_non_boolean_value(self):
        self.redis.hset_unsafe(self.hash_name, self.key1, self.val1)
        self.assertFalse(
            self.redis.hget_bool_unsafe(self.hash_name,
                                        self.key1,
                                        default=self.default_bool))

    def test_exists_unsafe_returns_true_if_exists(self):
        self.redis.set_unsafe(self.key1, self.val1)
        self.assertTrue(self.redis.exists_unsafe(self.key1))

    def test_exists_unsafe_returns_false_if_not_exists(self):
        self.assertFalse(self.redis.exists_unsafe(self.key1))

    def test_hexists_unsafe_returns_true_if_exists(self):
        self.redis.hset_unsafe(self.hash_name, self.key1, self.val1)
        self.assertTrue(self.redis.hexists_unsafe(self.hash_name, self.key1))

    def test_hexists_unsafe_returns_false_if_not_exists(self):
        self.assertFalse(self.redis.hexists_unsafe(self.hash_name, self.key1))

    def test_get_keys_unsafe_returns_empty_list_if_no_keys(self):
        keys_list = self.redis.get_keys_unsafe()
        self.assertListEqual(keys_list, [])

    def test_get_keys_unsafe_returns_list_with_all_keys(self):
        self.redis.set_unsafe(self.key1, self.val1)
        self.redis.set_unsafe(self.key2, self.val2)
        self.redis.set_unsafe(self.key3, self.val3_int)

        keys_list = self.redis.get_keys_unsafe()
        self.assertSetEqual(set(keys_list), {self.key1, self.key2, self.key3})
        # Set is used just in case the keys list is unordered

    def test_get_keys_unsafe_gets_key_that_matches_specific_pattern(self):
        self.redis.set_unsafe(self.key1, self.val1)
        self.redis.set_unsafe(self.key2, self.val2)
        self.redis.set_unsafe(self.key3, self.val3_int)

        keys_list = self.redis.get_keys_unsafe(self.key1)
        self.assertListEqual(keys_list, [self.key1])

        keys_list = self.redis.get_keys_unsafe(self.key2)
        self.assertListEqual(keys_list, [self.key2])

        keys_list = self.redis.get_keys_unsafe(self.key3)
        self.assertListEqual(keys_list, [self.key3])

    def test_get_keys_unsafe_gets_only_keys_that_match_prefix_pattern(self):
        prefixed_key1 = 'aaa' + self.key1
        prefixed_key2 = 'bbb' + self.key2
        prefixed_key3 = 'aa' + self.key3
        self.redis.set_unsafe(prefixed_key1, self.val1)
        self.redis.set_unsafe(prefixed_key2, self.val2)
        self.redis.set_unsafe(prefixed_key3, self.val3_int)

        keys_list = self.redis.get_keys_unsafe('aa*')
        self.assertSetEqual(set(keys_list), {prefixed_key1, prefixed_key3})

    def test_remove_unsafe_does_nothing_if_key_does_not_exists(self):
        self.redis.remove_unsafe(self.key1)
        self.assertFalse(self.redis.exists_unsafe(self.key1))

    def test_hremove_unsafe_does_nothing_if_key_does_not_exists(self):
        self.redis.hremove_unsafe(self.hash_name, self.key1)
        self.assertFalse(self.redis.hexists_unsafe(self.hash_name, self.key1))

    def test_remove_unsafe_removes_key_if_key_exists(self):
        self.redis.set_unsafe(self.key1, self.val1)
        self.assertTrue(self.redis.exists_unsafe(self.key1))

        self.redis.remove_unsafe(self.key1)
        self.assertFalse(self.redis.exists_unsafe(self.key1))

    def test_hremove_unsafe_removes_key_if_key_exists(self):
        self.redis.hset_multiple(self.hash_name, {self.key1: self.val1})
        self.assertEqual(self.redis.hget(self.hash_name, self.key1),
                         self.val1_bytes)
        self.assertTrue(self.redis.hexists_unsafe(self.hash_name, self.key1))

        self.redis.hremove_unsafe(self.hash_name, self.key1)
        self.assertFalse(self.redis.hexists_unsafe(self.hash_name, self.key1))

    def test_delete_all_unsafe_does_nothing_if_no_keys_exist(self):
        self.redis.delete_all_unsafe()
        self.assertEqual(0, len(self.redis.get_keys_unsafe()))

    def test_delete_all_unsafe_removes_keys_if_they_exist(self):
        self.redis.set_unsafe(self.key1, self.val1)
        self.redis.set_unsafe(self.key2, self.val2)
        self.assertTrue(self.redis.exists_unsafe(self.key1))
        self.assertTrue(self.redis.exists_unsafe(self.key2))

        self.redis.delete_all_unsafe()
        self.assertFalse(self.redis.exists_unsafe(self.key1))
        self.assertFalse(self.redis.exists_unsafe(self.key2))

    def test_set_sets_the_specified_key_to_the_specified_value(self):
        self.redis.set(self.key1, self.val1)
        self.assertEqual(self.redis.get(self.key1), self.val1_bytes)

    def test_set_returns_none_if_invalid_type(self):
        self.assertIsNone(self.redis.set(self.key1, True))

    @patch(REDIS_RECENTLY_DOWN_FUNCTION, return_value=True)
    def test_set_returns_none_if_redis_down(self, _):
        self.assertIsNone(self.redis.set(self.key1, self.val1))
        self.assertFalse(self.redis.exists_unsafe(self.key1))

    def test_hset_sets_the_specified_key_to_the_specified_value(self):
        self.redis.hset(self.hash_name, self.key1, self.val1)
        self.assertEqual(self.redis.hget(self.hash_name, self.key1),
                         self.val1_bytes)

    def test_hset_returns_none_if_invalid_type(self):
        self.assertIsNone(self.redis.hset(self.hash_name, self.key1, True))

    @patch(REDIS_RECENTLY_DOWN_FUNCTION, return_value=True)
    def test_hset_returns_none_if_redis_down(self, _):
        self.assertIsNone(self.redis.hset(self.hash_name, self.key1,
                                          self.val1))
        self.assertFalse(self.redis.hexists_unsafe(self.hash_name, self.key1))

    def test_set_multiple_sets_multiple_key_value_pairs(self):
        self.redis.set_multiple({self.key1: self.val1, self.key2: self.val2})
        self.assertEqual(self.redis.get(self.key1), self.val1_bytes)
        self.assertEqual(self.redis.get(self.key2), self.val2_bytes)

    @patch(REDIS_RECENTLY_DOWN_FUNCTION, return_value=True)
    def test_set_multiple_returns_none_and_nothing_set_if_redis_down(self, _):
        self.assertIsNone(
            self.redis.set_multiple({
                self.key1: self.val1,
                self.key2: self.val2
            }))
        self.assertFalse(self.redis.exists_unsafe(self.key1))
        self.assertFalse(self.redis.exists_unsafe(self.key2))

    def test_hset_multiple_sets_multiple_key_value_pairs(self):
        self.redis.hset_multiple(self.hash_name, {
            self.key1: self.val1,
            self.key2: self.val2
        })
        self.assertEqual(self.redis.hget(self.hash_name, self.key1),
                         self.val1_bytes)
        self.assertEqual(self.redis.hget(self.hash_name, self.key2),
                         self.val2_bytes)

    @patch(REDIS_RECENTLY_DOWN_FUNCTION, return_value=True)
    def test_hset_multiple_returns_none_and_nothing_set_if_redis_down(self, _):
        self.assertIsNone(
            self.redis.hset_multiple(self.hash_name, {
                self.key1: self.val1,
                self.key2: self.val2
            }))
        self.assertFalse(self.redis.hexists_unsafe(self.hash_name, self.key1))
        self.assertFalse(self.redis.hexists_unsafe(self.hash_name, self.key2))

    def test_set_for_temporarily_sets_specified_key_value_pair(self):
        self.redis.set_for(self.key1, self.val1, self.time)
        self.assertEqual(self.redis.get(self.key1), self.val1_bytes)

        sleep(self.time_with_error_margin.seconds)
        self.assertNotEqual(self.redis.get(self.key1), self.val1_bytes)

    @patch(REDIS_RECENTLY_DOWN_FUNCTION, return_value=True)
    def test_set_for_returns_none_and_nothing_set_if_redis_down(self, _):
        self.assertIsNone(self.redis.set_for(self.key1, self.val1, self.time))
        self.assertFalse(self.redis.exists_unsafe(self.key1))

    def test_time_to_live_returns_correct_timeout_when_set(self):
        self.redis.set_for(self.key1, self.val1, self.time)

        self.assertEqual(self.redis.time_to_live(self.key1), self.time.seconds)

    @patch(REDIS_RECENTLY_DOWN_FUNCTION, return_value=True)
    def test_time_to_live_returns_none_if_redis_down(self, _):
        self.redis.set_for_unsafe(self.key1, self.val1, self.time)
        self.assertIsNone(self.redis.time_to_live(self.key1))

    def test_get_returns_default_for_unset_key(self):
        self.assertEqual(self.redis.get(self.key1, default=self.default_str),
                         self.default_str)

    def test_get_returns_set_value(self):
        self.redis.set(self.key1, self.val1)
        self.assertEqual(self.redis.get(self.key1, default=self.default_str),
                         self.val1_bytes)

    def test_get_returns_none_for_none_string(self):
        self.redis.set(self.key1, 'None')
        self.assertIsNone(self.redis.get(self.key1, default=self.default_str))

    @patch(REDIS_RECENTLY_DOWN_FUNCTION, return_value=True)
    def test_get_returns_default_if_redis_down(self, _):
        self.redis.set_unsafe(self.key1, self.val1)
        self.assertEqual(self.redis.get(self.key1, default=self.default_str),
                         self.default_str)

    def test_hget_returns_default_for_unset_key(self):
        self.assertEqual(
            self.redis.hget(self.hash_name,
                            self.key1,
                            default=self.default_str), self.default_str)

    def test_hget_returns_set_value(self):
        self.redis.hset(self.hash_name, self.key1, self.val1)
        self.assertEqual(
            self.redis.hget(self.hash_name,
                            self.key1,
                            default=self.default_str), self.val1_bytes)

    def test_hget_returns_none_for_none_string(self):
        self.redis.hset(self.hash_name, self.key1, 'None')
        self.assertIsNone(
            self.redis.hget(self.hash_name,
                            self.key1,
                            default=self.default_str))

    @patch(REDIS_RECENTLY_DOWN_FUNCTION, return_value=True)
    def test_hget_returns_default_if_redis_down(self, _):
        self.redis.hset_unsafe(self.hash_name, self.key1, self.val1)
        self.assertEqual(
            self.redis.hget(self.hash_name,
                            self.key1,
                            default=self.default_str), self.default_str)

    def test_get_int_returns_set_integer(self):
        self.redis.set(self.key3, self.val3_int)
        self.assertEqual(
            self.redis.get_int(self.key3, default=self.default_int),
            self.val3_int)

    def test_get_int_returns_default_for_unset_key(self):
        self.assertEqual(
            self.redis.get_int(self.key3, default=self.default_int),
            self.default_int)

    def test_get_int_returns_default_for_non_integer_value(self):
        self.redis.set(self.key2, self.val2)
        self.assertEqual(
            self.redis.get_int(self.key2, default=self.default_int),
            self.default_int)

    @patch(REDIS_RECENTLY_DOWN_FUNCTION, return_value=True)
    def test_get_int_returns_default_if_redis_down(self, _):
        self.redis.set_unsafe(self.key3, self.val3_int)
        self.assertEqual(
            self.redis.get_int(self.key3, default=self.default_int),
            self.default_int)

    def test_hget_int_returns_set_integer(self):
        self.redis.hset(self.hash_name, self.key3, self.val3_int)
        self.assertEqual(
            self.redis.hget_int(self.hash_name,
                                self.key3,
                                default=self.default_int), self.val3_int)

    def test_hget_int_returns_default_for_unset_key(self):
        self.assertEqual(
            self.redis.hget_int(self.hash_name,
                                self.key3,
                                default=self.default_int), self.default_int)

    def test_hget_int_returns_default_for_non_integer_value(self):
        self.redis.hset(self.hash_name, self.key2, self.val2)
        self.assertEqual(
            self.redis.hget_int(self.hash_name,
                                self.key2,
                                default=self.default_int), self.default_int)

    @patch(REDIS_RECENTLY_DOWN_FUNCTION, return_value=True)
    def test_hget_int_returns_default_if_redis_down(self, _):
        self.redis.hset_unsafe(self.hash_name, self.key3, self.val3_int)
        self.assertEqual(
            self.redis.hget_int(self.hash_name,
                                self.key3,
                                default=self.default_int), self.default_int)

    def test_get_bool_returns_set_boolean(self):
        self.redis.set(self.key4, self.val4)
        self.assertEqual(
            self.redis.get_bool(self.key4, default=self.default_bool),
            self.val4_bool)

    def test_get_bool_returns_default_for_unset_key(self):
        self.assertEqual(
            self.redis.get_bool(self.key4, default=self.default_bool),
            self.default_bool)

    def test_get_bool_returns_false_for_non_boolean_value(self):
        self.redis.set(self.key1, self.val1)
        self.assertFalse(
            self.redis.get_bool(self.key1, default=self.default_bool))

    @patch(REDIS_RECENTLY_DOWN_FUNCTION, return_value=True)
    def test_get_bool_returns_default_if_redis_down(self, _):
        self.redis.set_unsafe(self.key4, self.val4)
        self.assertEqual(
            self.redis.get_bool(self.key4, default=self.default_bool),
            self.default_bool)

    def test_hget_bool_returns_set_boolean(self):
        self.redis.hset(self.hash_name, self.key4, self.val4)
        self.assertEqual(
            self.redis.hget_bool(self.hash_name,
                                 self.key4,
                                 default=self.default_bool), self.val4_bool)

    def test_hget_bool_returns_default_for_unset_key(self):
        self.assertEqual(
            self.redis.hget_bool(self.hash_name,
                                 self.key4,
                                 default=self.default_bool), self.default_bool)

    def test_hget_bool_returns_false_for_non_boolean_value(self):
        self.redis.hset(self.hash_name, self.key1, self.val1)
        self.assertFalse(
            self.redis.hget_bool(self.hash_name,
                                 self.key1,
                                 default=self.default_bool))

    @patch(REDIS_RECENTLY_DOWN_FUNCTION, return_value=True)
    def test_hget_bool_returns_default_if_redis_down(self, _):
        self.redis.hset_unsafe(self.hash_name, self.key4, self.val4)
        self.assertEqual(
            self.redis.hget_bool(self.hash_name,
                                 self.key4,
                                 default=self.default_bool), self.default_bool)

    def test_exists_returns_true_if_exists(self):
        self.redis.set(self.key1, self.val1)
        self.assertTrue(self.redis.exists(self.key1))

    def test_exists_returns_false_if_not_exists(self):
        self.assertFalse(self.redis.exists(self.key1))

    @patch(REDIS_RECENTLY_DOWN_FUNCTION, return_value=True)
    def test_exists_returns_false_if_redis_down(self, _):
        self.redis.set_unsafe(self.key1, self.val1)
        self.assertFalse(self.redis.exists(self.key1))

    def test_hexists_returns_true_if_exists(self):
        self.redis.hset(self.hash_name, self.key1, self.val1)
        self.assertTrue(self.redis.hexists(self.hash_name, self.key1))

    def test_hexists_returns_false_if_not_exists(self):
        self.assertFalse(self.redis.hexists(self.hash_name, self.key1))

    @patch(REDIS_RECENTLY_DOWN_FUNCTION, return_value=True)
    def test_hexists_returns_false_if_redis_down(self, _):
        self.redis.hset_unsafe(self.hash_name, self.key1, self.val1)
        self.assertFalse(self.redis.hexists(self.hash_name, self.key1))

    def test_get_keys_returns_empty_list_if_no_keys(self):
        keys_list = self.redis.get_keys()
        self.assertListEqual(keys_list, [])

    def test_get_keys_returns_list_with_all_keys(self):
        self.redis.set_unsafe(self.key1, self.val1)
        self.redis.set_unsafe(self.key2, self.val2)
        self.redis.set_unsafe(self.key3, self.val3_int)

        keys_list = self.redis.get_keys()
        self.assertSetEqual(set(keys_list), {self.key1, self.key2, self.key3})
        # Set is used just in case the keys list is unordered

    def test_get_keys_gets_key_that_matches_specific_pattern(self):
        self.redis.set_unsafe(self.key1, self.val1)
        self.redis.set_unsafe(self.key2, self.val2)
        self.redis.set_unsafe(self.key3, self.val3_int)

        keys_list = self.redis.get_keys(self.key1)
        self.assertListEqual(keys_list, [self.key1])

        keys_list = self.redis.get_keys(self.key2)
        self.assertListEqual(keys_list, [self.key2])

        keys_list = self.redis.get_keys(self.key3)
        self.assertListEqual(keys_list, [self.key3])

    def test_get_keys_gets_only_keys_that_match_prefix_pattern(self):
        prefixed_key1 = 'aaa' + self.key1
        prefixed_key2 = 'bbb' + self.key2
        prefixed_key3 = 'aa' + self.key3
        self.redis.set_unsafe(prefixed_key1, self.val1)
        self.redis.set_unsafe(prefixed_key2, self.val2)
        self.redis.set_unsafe(prefixed_key3, self.val3_int)

        keys_list = self.redis.get_keys('aa*')
        self.assertSetEqual(set(keys_list), {prefixed_key1, prefixed_key3})

    @patch(REDIS_RECENTLY_DOWN_FUNCTION, return_value=True)
    def test_get_keys_returns_empty_set_if_redis_down(self, _):
        self.redis.set_unsafe(self.key1, self.val1)
        self.redis.set_unsafe(self.key2, self.val2)
        self.redis.set_unsafe(self.key3, self.val3_int)

        keys_list = self.redis.get_keys()
        self.assertSetEqual(set(keys_list), set())

    def test_remove_does_nothing_if_key_does_not_exists(self):
        self.redis.remove(self.key1)
        self.assertFalse(self.redis.exists(self.key1))

    def test_remove_removes_key_if_key_exists(self):
        self.redis.set(self.key1, self.val1)
        self.assertTrue(self.redis.exists(self.key1))

        self.redis.remove(self.key1)
        self.assertFalse(self.redis.exists(self.key1))

    @patch(REDIS_RECENTLY_DOWN_FUNCTION, return_value=True)
    def test_remove_returns_none_if_redis_down(self, _):
        self.redis.set_unsafe(self.key1, self.val1)
        self.assertTrue(self.redis.exists_unsafe(self.key1))

        self.assertIsNone(self.redis.remove(self.key1))
        self.assertTrue(self.redis.exists_unsafe(self.key1))

    def test_hremove_does_nothing_if_key_does_not_exists(self):
        self.redis.hremove(self.key1)
        self.assertFalse(self.redis.hexists(self.hash_name, self.key1))

    def test_hremove_removes_key_if_key_exists(self):
        self.redis.hset(self.hash_name, self.key1, self.val1)
        self.assertTrue(self.redis.hexists(self.hash_name, self.key1))
        self.redis.hremove(self.hash_name, self.key1)
        self.assertFalse(self.redis.hexists(self.hash_name, self.key1))

    @patch(REDIS_RECENTLY_DOWN_FUNCTION, return_value=True)
    def test_hremove_returns_none_if_redis_down(self, _):
        self.redis.hset_unsafe(self.hash_name, self.key1, self.val1)
        self.assertTrue(self.redis.hexists_unsafe(self.hash_name, self.key1))

        self.assertIsNone(self.redis.hremove(self.hash_name, self.key1))
        self.assertTrue(self.redis.hexists_unsafe(self.hash_name, self.key1))

    def test_delete_all_does_nothing_if_no_keys_exist(self):
        self.redis.delete_all()
        self.assertEqual(0, len(self.redis.get_keys()))

    def test_delete_all_removes_keys_if_they_exist(self):
        self.redis.set(self.key1, self.val1)
        self.redis.set(self.key2, self.val2)
        self.assertTrue(self.redis.exists(self.key1))
        self.assertTrue(self.redis.exists(self.key2))

        self.redis.delete_all()
        self.assertFalse(self.redis.exists(self.key1))
        self.assertFalse(self.redis.exists(self.key2))

    @patch(REDIS_RECENTLY_DOWN_FUNCTION, return_value=True)
    def test_delete_all_returns_none_and_deletes_nothing_if_redis_down(
            self, _):
        self.redis.set_unsafe(self.key1, self.val1)
        self.redis.set_unsafe(self.key2, self.val2)
        self.assertTrue(self.redis.exists_unsafe(self.key1))
        self.assertTrue(self.redis.exists_unsafe(self.key2))

        self.assertIsNone(self.redis.delete_all())
        self.assertTrue(self.redis.exists_unsafe(self.key1))
        self.assertTrue(self.redis.exists_unsafe(self.key2))

    def test_ping_unsafe_returns_true(self):
        self.assertTrue(self.redis.ping_unsafe())
Exemplo n.º 11
0
class TestRedisApiLiveAndDownFeaturesWithRedisOffline(unittest.TestCase):
    def setUp(self) -> None:
        self.dummy_logger = logging.getLogger('dummy')
        self.dummy_logger.disabled = True
        self.db = env.REDIS_DB
        self.host = 'dummyhost'
        self.port = 6379
        self.live_check_time_interval = timedelta(seconds=3)
        self.live_check_time_interval_with_error_margin = timedelta(seconds=4)
        self.redis = RedisApi(
            self.dummy_logger,
            self.db,
            self.host,
            self.port,
            live_check_time_interval=self.live_check_time_interval)

        self.key = 'key'
        self.val = 'val'
        self.time = timedelta.max

    def tearDown(self) -> None:
        self.dummy_logger = None
        self.redis = None

    def test_is_live_by_default(self):
        self.assertTrue(self.redis.is_live)

    def test_set_as_live_changes_is_live_to_true(self):
        self.redis._is_live = False
        self.assertFalse(self.redis.is_live)

        self.redis._set_as_live()
        self.assertTrue(self.redis._is_live)

    def test_set_as_down_changes_is_live_to_false(self):
        self.redis._set_as_down()
        self.assertFalse(self.redis.is_live)

    def test_allowed_to_use_by_default(self):
        self.assertFalse(self.redis._do_not_use_if_recently_went_down())

    def test_not_allowed_to_use_if_set_as_down_and_within_time_interval(self):
        self.redis._set_as_down()
        self.assertTrue(self.redis._do_not_use_if_recently_went_down())

    def test_allowed_to_use_if_set_as_down_and_time_interval_exceeded(self):
        self.redis._set_as_down()
        sleep(self.live_check_time_interval_with_error_margin.seconds)
        self.assertFalse(self.redis._do_not_use_if_recently_went_down())
Exemplo n.º 12
0
    def setUp(self) -> None:
        self.dummy_logger = logging.getLogger('Dummy')
        self.dummy_logger.disabled = True
        self.connection_check_time_interval = timedelta(seconds=0)
        self.rabbit_ip = env.RABBIT_IP
        self.rabbitmq = RabbitMQApi(
            self.dummy_logger,
            self.rabbit_ip,
            connection_check_time_interval=self.connection_check_time_interval)

        self.test_rabbit_manager = RabbitMQApi(
            self.dummy_logger,
            self.rabbit_ip,
            connection_check_time_interval=self.connection_check_time_interval)

        self.mongo_ip = env.DB_IP
        self.mongo_db = env.DB_NAME
        self.mongo_port = env.DB_PORT

        self.mongo = MongoApi(logger=self.dummy_logger.getChild(
            MongoApi.__name__),
                              db_name=self.mongo_db,
                              host=self.mongo_ip,
                              port=self.mongo_port)

        self.redis_db = env.REDIS_DB
        self.redis_host = env.REDIS_IP
        self.redis_port = env.REDIS_PORT
        self.redis_namespace = env.UNIQUE_ALERTER_IDENTIFIER
        self.redis = RedisApi(self.dummy_logger, self.redis_db,
                              self.redis_host, self.redis_port, '',
                              self.redis_namespace,
                              self.connection_check_time_interval)

        self.test_store_name = 'store name'
        self.test_store = AlertStore(self.test_store_name, self.dummy_logger,
                                     self.rabbitmq)

        self.routing_key = 'heartbeat.worker'
        self.test_queue_name = 'test queue'

        connect_to_rabbit(self.rabbitmq)
        self.rabbitmq.exchange_declare(HEALTH_CHECK_EXCHANGE, 'topic', False,
                                       True, False, False)
        self.rabbitmq.exchange_declare(STORE_EXCHANGE, 'direct', False, True,
                                       False, False)
        self.rabbitmq.queue_declare(ALERT_STORE_INPUT_QUEUE, False, True,
                                    False, False)
        self.rabbitmq.queue_bind(ALERT_STORE_INPUT_QUEUE, STORE_EXCHANGE,
                                 ALERT_STORE_INPUT_ROUTING_KEY)

        connect_to_rabbit(self.test_rabbit_manager)
        self.test_rabbit_manager.queue_declare(self.test_queue_name, False,
                                               True, False, False)
        self.test_rabbit_manager.queue_bind(self.test_queue_name,
                                            HEALTH_CHECK_EXCHANGE,
                                            self.routing_key)

        self.test_data_str = 'test data'
        self.test_exception = PANICException('test_exception', 1)

        self.parent_id = 'test_parent_id'

        self.alert_id = 'test_alert_id'
        self.origin_id = 'test_origin_id'
        self.alert_name = 'test_alert'
        self.metric = 'system_is_down'
        self.severity = 'warning'
        self.message = 'alert message'
        self.value = 'alert_code_1'

        self.alert_id_2 = 'test_alert_id_2'
        self.origin_id_2 = 'test_origin_id_2'
        self.alert_name_2 = 'test_alert_2'
        self.severity_2 = 'critical'
        self.message_2 = 'alert message 2'
        self.value_2 = 'alert_code_2'

        self.alert_id_3 = 'test_alert_id_3'
        self.origin_id_3 = 'test_origin_id_3'
        self.alert_name_3 = 'test_alert_3'
        self.severity_3 = 'info'
        self.message_3 = 'alert message 3'
        self.value_3 = 'alert_code_3'

        self.last_monitored = datetime(2012, 1, 1).timestamp()
        self.none = None

        self.alert_data_1 = {
            'parent_id': self.parent_id,
            'origin_id': self.origin_id,
            'alert_code': {
                'name': self.alert_name,
                'value': self.value,
            },
            'severity': self.severity,
            'metric': self.metric,
            'message': self.message,
            'timestamp': self.last_monitored,
        }
        self.alert_data_2 = {
            'parent_id': self.parent_id,
            'origin_id': self.origin_id_2,
            'alert_code': {
                'name': self.alert_name_2,
                'value': self.value_2,
            },
            'severity': self.severity_2,
            'metric': self.metric,
            'message': self.message_2,
            'timestamp': self.last_monitored,
        }
        self.alert_data_3 = {
            'parent_id': self.parent_id,
            'origin_id': self.origin_id_3,
            'alert_code': {
                'name': self.alert_name_3,
                'value': self.value_3,
            },
            'severity': self.severity_3,
            'metric': self.metric,
            'message': self.message_3,
            'timestamp': self.last_monitored,
        }
        self.alert_data_key_error = {"result": {"data": {}, "data2": {}}}
        self.alert_data_unexpected = {"unexpected": {}}
Exemplo n.º 13
0
class TestAlertStore(unittest.TestCase):
    def setUp(self) -> None:
        self.dummy_logger = logging.getLogger('Dummy')
        self.dummy_logger.disabled = True
        self.connection_check_time_interval = timedelta(seconds=0)
        self.rabbit_ip = env.RABBIT_IP
        self.rabbitmq = RabbitMQApi(
            self.dummy_logger,
            self.rabbit_ip,
            connection_check_time_interval=self.connection_check_time_interval)

        self.test_rabbit_manager = RabbitMQApi(
            self.dummy_logger,
            self.rabbit_ip,
            connection_check_time_interval=self.connection_check_time_interval)

        self.mongo_ip = env.DB_IP
        self.mongo_db = env.DB_NAME
        self.mongo_port = env.DB_PORT

        self.mongo = MongoApi(logger=self.dummy_logger.getChild(
            MongoApi.__name__),
                              db_name=self.mongo_db,
                              host=self.mongo_ip,
                              port=self.mongo_port)

        self.redis_db = env.REDIS_DB
        self.redis_host = env.REDIS_IP
        self.redis_port = env.REDIS_PORT
        self.redis_namespace = env.UNIQUE_ALERTER_IDENTIFIER
        self.redis = RedisApi(self.dummy_logger, self.redis_db,
                              self.redis_host, self.redis_port, '',
                              self.redis_namespace,
                              self.connection_check_time_interval)

        self.test_store_name = 'store name'
        self.test_store = AlertStore(self.test_store_name, self.dummy_logger,
                                     self.rabbitmq)

        self.routing_key = 'heartbeat.worker'
        self.test_queue_name = 'test queue'

        connect_to_rabbit(self.rabbitmq)
        self.rabbitmq.exchange_declare(HEALTH_CHECK_EXCHANGE, 'topic', False,
                                       True, False, False)
        self.rabbitmq.exchange_declare(STORE_EXCHANGE, 'direct', False, True,
                                       False, False)
        self.rabbitmq.queue_declare(ALERT_STORE_INPUT_QUEUE, False, True,
                                    False, False)
        self.rabbitmq.queue_bind(ALERT_STORE_INPUT_QUEUE, STORE_EXCHANGE,
                                 ALERT_STORE_INPUT_ROUTING_KEY)

        connect_to_rabbit(self.test_rabbit_manager)
        self.test_rabbit_manager.queue_declare(self.test_queue_name, False,
                                               True, False, False)
        self.test_rabbit_manager.queue_bind(self.test_queue_name,
                                            HEALTH_CHECK_EXCHANGE,
                                            self.routing_key)

        self.test_data_str = 'test data'
        self.test_exception = PANICException('test_exception', 1)

        self.parent_id = 'test_parent_id'

        self.alert_id = 'test_alert_id'
        self.origin_id = 'test_origin_id'
        self.alert_name = 'test_alert'
        self.metric = 'system_is_down'
        self.severity = 'warning'
        self.message = 'alert message'
        self.value = 'alert_code_1'

        self.alert_id_2 = 'test_alert_id_2'
        self.origin_id_2 = 'test_origin_id_2'
        self.alert_name_2 = 'test_alert_2'
        self.severity_2 = 'critical'
        self.message_2 = 'alert message 2'
        self.value_2 = 'alert_code_2'

        self.alert_id_3 = 'test_alert_id_3'
        self.origin_id_3 = 'test_origin_id_3'
        self.alert_name_3 = 'test_alert_3'
        self.severity_3 = 'info'
        self.message_3 = 'alert message 3'
        self.value_3 = 'alert_code_3'

        self.last_monitored = datetime(2012, 1, 1).timestamp()
        self.none = None

        self.alert_data_1 = {
            'parent_id': self.parent_id,
            'origin_id': self.origin_id,
            'alert_code': {
                'name': self.alert_name,
                'value': self.value,
            },
            'severity': self.severity,
            'metric': self.metric,
            'message': self.message,
            'timestamp': self.last_monitored,
        }
        self.alert_data_2 = {
            'parent_id': self.parent_id,
            'origin_id': self.origin_id_2,
            'alert_code': {
                'name': self.alert_name_2,
                'value': self.value_2,
            },
            'severity': self.severity_2,
            'metric': self.metric,
            'message': self.message_2,
            'timestamp': self.last_monitored,
        }
        self.alert_data_3 = {
            'parent_id': self.parent_id,
            'origin_id': self.origin_id_3,
            'alert_code': {
                'name': self.alert_name_3,
                'value': self.value_3,
            },
            'severity': self.severity_3,
            'metric': self.metric,
            'message': self.message_3,
            'timestamp': self.last_monitored,
        }
        self.alert_data_key_error = {"result": {"data": {}, "data2": {}}}
        self.alert_data_unexpected = {"unexpected": {}}

    def tearDown(self) -> None:
        connect_to_rabbit(self.rabbitmq)
        delete_queue_if_exists(self.rabbitmq, ALERT_STORE_INPUT_QUEUE)
        delete_exchange_if_exists(self.rabbitmq, STORE_EXCHANGE)
        delete_exchange_if_exists(self.rabbitmq, HEALTH_CHECK_EXCHANGE)
        disconnect_from_rabbit(self.rabbitmq)

        connect_to_rabbit(self.test_rabbit_manager)
        delete_queue_if_exists(self.test_rabbit_manager, self.test_queue_name)
        disconnect_from_rabbit(self.test_rabbit_manager)

        self.dummy_logger = None
        self.connection_check_time_interval = None
        self.rabbitmq = None
        self.test_rabbit_manager = None
        self.redis.delete_all_unsafe()
        self.redis = None
        self.mongo.drop_collection(self.parent_id)
        self.mongo = None
        self.test_store = None

    def test__str__returns_name_correctly(self) -> None:
        self.assertEqual(self.test_store_name, str(self.test_store))

    def test_name_property_returns_name_correctly(self) -> None:
        self.assertEqual(self.test_store_name, self.test_store.name)

    def test_mongo_ip_property_returns_mongo_ip_correctly(self) -> None:
        self.assertEqual(self.mongo_ip, self.test_store.mongo_ip)

    def test_mongo_db_property_returns_mongo_db_correctly(self) -> None:
        self.assertEqual(self.mongo_db, self.test_store.mongo_db)

    def test_mongo_port_property_returns_mongo_port_correctly(self) -> None:
        self.assertEqual(self.mongo_port, self.test_store.mongo_port)

    def test_mongo_property_returns_mongo(self) -> None:
        self.assertEqual(type(self.mongo), type(self.test_store.mongo))

    def test_redis_property_returns_redis_correctly(self) -> None:
        self.assertEqual(type(self.redis), type(self.test_store.redis))

    def test_initialise_rabbitmq_initialises_everything_as_expected(
            self) -> None:
        try:
            # To make sure that the exchanges have not already been declared
            self.rabbitmq.connect()
            self.rabbitmq.queue_delete(ALERT_STORE_INPUT_QUEUE)
            self.test_rabbit_manager.queue_delete(self.test_queue_name)
            self.rabbitmq.exchange_delete(HEALTH_CHECK_EXCHANGE)
            self.rabbitmq.exchange_delete(STORE_EXCHANGE)
            self.rabbitmq.disconnect()

            self.test_store._initialise_rabbitmq()

            # Perform checks that the connection has been opened, marked as open
            # and that the delivery confirmation variable is set.
            self.assertTrue(self.test_store.rabbitmq.is_connected)
            self.assertTrue(self.test_store.rabbitmq.connection.is_open)
            self.assertTrue(
                self.test_store.rabbitmq.channel._delivery_confirmation)

            # Check whether the producing exchanges have been created by
            # using passive=True. If this check fails an exception is raised
            # automatically.
            self.test_store.rabbitmq.exchange_declare(STORE_EXCHANGE,
                                                      passive=True)
            self.test_store.rabbitmq.exchange_declare(HEALTH_CHECK_EXCHANGE,
                                                      passive=True)

            # Check whether the exchange has been creating by sending messages
            # to it. If this fails an exception is raised, hence the test fails.
            self.test_store.rabbitmq.basic_publish_confirm(
                exchange=HEALTH_CHECK_EXCHANGE,
                routing_key=self.routing_key,
                body=self.test_data_str,
                is_body_dict=False,
                properties=pika.BasicProperties(delivery_mode=2),
                mandatory=False)

            # Check whether the exchange has been creating by sending messages
            # to it. If this fails an exception is raised, hence the test fails.
            self.test_store.rabbitmq.basic_publish_confirm(
                exchange=STORE_EXCHANGE,
                routing_key=ALERT_STORE_INPUT_ROUTING_KEY,
                body=self.test_data_str,
                is_body_dict=False,
                properties=pika.BasicProperties(delivery_mode=2),
                mandatory=False)

            # Re-declare queue to get the number of messages
            res = self.test_store.rabbitmq.queue_declare(
                ALERT_STORE_INPUT_QUEUE, False, True, False, False)

            self.assertEqual(1, res.method.message_count)
        except Exception as e:
            self.fail("Test failed: {}".format(e))

    @parameterized.expand([
        ("KeyError", "self.alert_data_key_error "),
    ])
    @mock.patch("src.data_store.stores.store.RabbitMQApi.basic_ack",
                autospec=True)
    @mock.patch("src.data_store.stores.store.Store._send_heartbeat",
                autospec=True)
    def test_process_data_with_bad_data_does_raises_exceptions(
            self, mock_error, mock_bad_data, mock_send_hb, mock_ack) -> None:
        mock_ack.return_value = None
        try:
            self.test_store._initialise_rabbitmq()

            blocking_channel = self.test_store.rabbitmq.channel
            method_chains = pika.spec.Basic.Deliver(
                routing_key=ALERT_STORE_INPUT_ROUTING_KEY)

            properties = pika.spec.BasicProperties()
            self.test_store._process_data(
                blocking_channel, method_chains, properties,
                json.dumps(self.alert_data_unexpected).encode())
            self.assertRaises(eval(mock_error),
                              self.test_store._process_mongo_store,
                              eval(mock_bad_data))
            mock_ack.assert_called_once()
            mock_send_hb.assert_not_called()
        except Exception as e:
            self.fail("Test failed: {}".format(e))

    @freeze_time("2012-01-01")
    @mock.patch("src.data_store.stores.store.RabbitMQApi.basic_ack",
                autospec=True)
    @mock.patch("src.data_store.stores.alert.AlertStore._process_redis_store",
                autospec=True)
    @mock.patch("src.data_store.stores.alert.AlertStore._process_mongo_store",
                autospec=True)
    def test_process_data_sends_heartbeat_correctly(self,
                                                    mock_process_mongo_store,
                                                    mock_process_redis_store,
                                                    mock_basic_ack) -> None:

        mock_basic_ack.return_value = None
        try:
            self.test_rabbit_manager.connect()
            self.test_store._initialise_rabbitmq()

            self.test_rabbit_manager.queue_delete(self.test_queue_name)
            res = self.test_rabbit_manager.queue_declare(
                queue=self.test_queue_name,
                durable=True,
                exclusive=False,
                auto_delete=False,
                passive=False)
            self.assertEqual(0, res.method.message_count)

            self.test_rabbit_manager.queue_bind(queue=self.test_queue_name,
                                                exchange=HEALTH_CHECK_EXCHANGE,
                                                routing_key=self.routing_key)

            blocking_channel = self.test_store.rabbitmq.channel
            method_chains = pika.spec.Basic.Deliver(
                routing_key=ALERT_STORE_INPUT_ROUTING_KEY)

            properties = pika.spec.BasicProperties()
            self.test_store._process_data(
                blocking_channel, method_chains, properties,
                json.dumps(self.alert_data_1).encode())

            res = self.test_rabbit_manager.queue_declare(
                queue=self.test_queue_name,
                durable=True,
                exclusive=False,
                auto_delete=False,
                passive=True)
            self.assertEqual(1, res.method.message_count)

            heartbeat_test = {
                'component_name': self.test_store_name,
                'is_alive': True,
                'timestamp': datetime(2012, 1, 1).timestamp()
            }

            _, _, body = self.test_rabbit_manager.basic_get(
                self.test_queue_name)
            self.assertEqual(heartbeat_test, json.loads(body))
            mock_process_mongo_store.assert_called_once()
            mock_process_redis_store.assert_called_once()
        except Exception as e:
            self.fail("Test failed: {}".format(e))

    @mock.patch("src.data_store.stores.store.RabbitMQApi.basic_ack",
                autospec=True)
    def test_process_data_doesnt_send_heartbeat_on_processing_error(
            self, mock_basic_ack) -> None:

        mock_basic_ack.return_value = None
        try:
            self.test_rabbit_manager.connect()
            self.test_store._initialise_rabbitmq()

            self.test_rabbit_manager.queue_delete(self.test_queue_name)
            res = self.test_rabbit_manager.queue_declare(
                queue=self.test_queue_name,
                durable=True,
                exclusive=False,
                auto_delete=False,
                passive=False)
            self.assertEqual(0, res.method.message_count)

            self.test_rabbit_manager.queue_bind(queue=self.test_queue_name,
                                                exchange=HEALTH_CHECK_EXCHANGE,
                                                routing_key=self.routing_key)

            blocking_channel = self.test_store.rabbitmq.channel
            method_chains = pika.spec.Basic.Deliver(
                routing_key=ALERT_STORE_INPUT_ROUTING_KEY)

            properties = pika.spec.BasicProperties()
            self.test_store._process_data(
                blocking_channel, method_chains, properties,
                json.dumps(self.alert_data_unexpected).encode())

            res = self.test_rabbit_manager.queue_declare(
                queue=self.test_queue_name,
                durable=True,
                exclusive=False,
                auto_delete=False,
                passive=True)
            self.assertEqual(0, res.method.message_count)
        except Exception as e:
            self.fail("Test failed: {}".format(e))

    @mock.patch.object(MongoApi, "update_one")
    def test_process_mongo_store_calls_update_one(self,
                                                  mock_update_one) -> None:
        self.test_store._process_mongo_store(self.alert_data_1)
        mock_update_one.assert_called_once()

    @mock.patch.object(RedisApi, "hset")
    def test_process_redis_store_calls_hset(self, mock_hset) -> None:
        self.test_store._process_redis_store(self.alert_data_1)
        mock_hset.assert_called_once()

    @parameterized.expand([
        ("self.alert_data_1", ),
        ("self.alert_data_2", ),
        ("self.alert_data_3", ),
    ])
    @freeze_time("2012-01-01")
    @mock.patch.object(MongoApi, "update_one")
    def test_process_mongo_store_calls_mongo_correctly(
            self, mock_system_data, mock_update_one) -> None:
        data = eval(mock_system_data)
        self.test_store._process_mongo_store(data)

        call_1 = call(data['parent_id'], {
            'doc_type': 'alert',
            'n_alerts': {
                '$lt': 1000
            }
        }, {
            '$push': {
                'alerts': {
                    'origin': data['origin_id'],
                    'alert_name': data['alert_code']['name'],
                    'severity': data['severity'],
                    'metric': data['metric'],
                    'message': data['message'],
                    'timestamp': str(data['timestamp']),
                }
            },
            '$min': {
                'first': data['timestamp']
            },
            '$max': {
                'last': data['timestamp']
            },
            '$inc': {
                'n_alerts': 1
            },
        })
        mock_update_one.assert_has_calls([call_1])

    @parameterized.expand([
        ("self.alert_data_1", ),
        ("self.alert_data_2", ),
        ("self.alert_data_3", ),
    ])
    @freeze_time("2012-01-01")
    @mock.patch.object(RedisApi, "hset")
    def test_process_redis_store_calls_redis_correctly(self, mock_system_data,
                                                       mock_hset) -> None:
        data = eval(mock_system_data)
        self.test_store._process_redis_store(data)

        metric_data = {
            'severity': data['severity'],
            'message': data['message']
        }
        key = data['origin_id']

        call_1 = call(Keys.get_hash_parent(data['parent_id']),
                      eval('Keys.get_alert_{}(key)'.format(data['metric'])),
                      json.dumps(metric_data))
        mock_hset.assert_has_calls([call_1])

    @parameterized.expand([
        ("self.alert_data_1", ),
        ("self.alert_data_2", ),
        ("self.alert_data_3", ),
    ])
    @freeze_time("2012-01-01")
    @mock.patch("src.data_store.stores.store.RabbitMQApi.basic_ack",
                autospec=True)
    @mock.patch("src.data_store.stores.alert.AlertStore._process_redis_store",
                autospec=True)
    @mock.patch("src.data_store.stores.store.Store._send_heartbeat",
                autospec=True)
    @mock.patch.object(MongoApi, "update_one")
    def test_process_data_calls_mongo_correctly(self, mock_system_data,
                                                mock_update_one, mock_send_hb,
                                                mock_process_redis_store,
                                                mock_ack) -> None:

        mock_ack.return_value = None
        try:
            self.test_store._initialise_rabbitmq()

            data = eval(mock_system_data)
            blocking_channel = self.test_store.rabbitmq.channel
            method_chains = pika.spec.Basic.Deliver(
                routing_key=ALERT_STORE_INPUT_ROUTING_KEY)

            properties = pika.spec.BasicProperties()
            self.test_store._process_data(blocking_channel, method_chains,
                                          properties,
                                          json.dumps(data).encode())

            mock_ack.assert_called_once()
            mock_send_hb.assert_called_once()

            call_1 = call(data['parent_id'], {
                'doc_type': 'alert',
                'n_alerts': {
                    '$lt': 1000
                }
            }, {
                '$push': {
                    'alerts': {
                        'origin': data['origin_id'],
                        'alert_name': data['alert_code']['name'],
                        'severity': data['severity'],
                        'metric': data['metric'],
                        'message': data['message'],
                        'timestamp': str(data['timestamp']),
                    }
                },
                '$min': {
                    'first': data['timestamp']
                },
                '$max': {
                    'last': data['timestamp']
                },
                '$inc': {
                    'n_alerts': 1
                },
            })
            mock_update_one.assert_has_calls([call_1])
            mock_process_redis_store.assert_called_once()
        except Exception as e:
            self.fail("Test failed: {}".format(e))

    @parameterized.expand([
        ("self.alert_data_1", ),
        ("self.alert_data_2", ),
        ("self.alert_data_3", ),
    ])
    @freeze_time("2012-01-01")
    @mock.patch("src.data_store.stores.store.RabbitMQApi.basic_ack",
                autospec=True)
    @mock.patch("src.data_store.stores.alert.AlertStore._process_mongo_store",
                autospec=True)
    @mock.patch("src.data_store.stores.store.Store._send_heartbeat",
                autospec=True)
    @mock.patch.object(RedisApi, "hset")
    def test_process_data_calls_redis_correctly(self, mock_system_data,
                                                mock_hset, mock_send_hb,
                                                mock_process_mongo_store,
                                                mock_ack) -> None:

        mock_ack.return_value = None
        try:
            self.test_store._initialise_rabbitmq()

            data = eval(mock_system_data)
            blocking_channel = self.test_store.rabbitmq.channel
            method_chains = pika.spec.Basic.Deliver(
                routing_key=ALERT_STORE_INPUT_ROUTING_KEY)

            properties = pika.spec.BasicProperties()
            self.test_store._process_data(blocking_channel, method_chains,
                                          properties,
                                          json.dumps(data).encode())

            mock_ack.assert_called_once()
            mock_send_hb.assert_called_once()

            metric_data = {
                'severity': data['severity'],
                'message': data['message']
            }
            key = data['origin_id']

            call_1 = call(
                Keys.get_hash_parent(data['parent_id']),
                eval('Keys.get_alert_{}(key)'.format(data['metric'])),
                json.dumps(metric_data))
            mock_hset.assert_has_calls([call_1])
            mock_process_mongo_store.assert_called_once()
        except Exception as e:
            self.fail("Test failed: {}".format(e))

    @parameterized.expand([
        ("self.alert_data_1", ),
        ("self.alert_data_2", ),
        ("self.alert_data_3", ),
    ])
    def test_process_mongo_store_mongo_stores_correctly(
            self, mock_system_data) -> None:

        data = eval(mock_system_data)
        self.test_store._process_mongo_store(data)

        documents = self.mongo.get_all(data['parent_id'])
        document = documents[0]
        expected = [
            'alert', 1,
            str(data['origin_id']),
            str(data['alert_code']['name']),
            str(data['severity']),
            str(data['metric']),
            str(data['message']),
            str(data['timestamp'])
        ]
        actual = [
            document['doc_type'], document['n_alerts'],
            document['alerts'][0]['origin'],
            document['alerts'][0]['alert_name'],
            document['alerts'][0]['severity'], document['alerts'][0]['metric'],
            document['alerts'][0]['message'],
            document['alerts'][0]['timestamp']
        ]

        self.assertListEqual(expected, actual)

    @parameterized.expand([
        ("self.alert_data_1", ),
        ("self.alert_data_2", ),
        ("self.alert_data_3", ),
    ])
    def test_process_redis_store_redis_stores_correctly(
            self, mock_system_data) -> None:

        data = eval(mock_system_data)
        self.test_store._process_redis_store(data)

        key = data['origin_id']

        stored_data = self.redis.hget(
            Keys.get_hash_parent(data['parent_id']),
            eval('Keys.get_alert_{}(key)'.format(data['metric'])))

        expected_data = {
            'severity': data['severity'],
            'message': data['message']
        }

        self.assertEqual(expected_data, json.loads(stored_data))

    @parameterized.expand([
        ("self.alert_data_1", ),
        ("self.alert_data_2", ),
        ("self.alert_data_3", ),
    ])
    @mock.patch("src.data_store.stores.store.RabbitMQApi.basic_ack",
                autospec=True)
    @mock.patch("src.data_store.stores.alert.AlertStore._process_redis_store",
                autospec=True)
    @mock.patch("src.data_store.stores.store.Store._send_heartbeat",
                autospec=True)
    def test_process_data_results_stores_in_mongo_correctly(
            self, mock_system_data, mock_send_hb, mock_process_redis_store,
            mock_ack) -> None:

        mock_ack.return_value = None
        try:
            self.test_store._initialise_rabbitmq()

            data = eval(mock_system_data)
            blocking_channel = self.test_store.rabbitmq.channel
            method_chains = pika.spec.Basic.Deliver(
                routing_key=ALERT_STORE_INPUT_ROUTING_KEY)

            properties = pika.spec.BasicProperties()
            self.test_store._process_data(blocking_channel, method_chains,
                                          properties,
                                          json.dumps(data).encode())

            mock_process_redis_store.assert_called_once()
            mock_ack.assert_called_once()
            mock_send_hb.assert_called_once()

            documents = self.mongo.get_all(data['parent_id'])
            document = documents[0]
            expected = [
                'alert', 1,
                str(data['origin_id']),
                str(data['alert_code']['name']),
                str(data['severity']),
                str(data['message']),
                str(data['timestamp'])
            ]
            actual = [
                document['doc_type'], document['n_alerts'],
                document['alerts'][0]['origin'],
                document['alerts'][0]['alert_name'],
                document['alerts'][0]['severity'],
                document['alerts'][0]['message'],
                document['alerts'][0]['timestamp']
            ]

            self.assertListEqual(expected, actual)
        except Exception as e:
            self.fail("Test failed: {}".format(e))

    @parameterized.expand([
        ("self.alert_data_1", ),
        ("self.alert_data_2", ),
        ("self.alert_data_3", ),
    ])
    @mock.patch("src.data_store.stores.store.RabbitMQApi.basic_ack",
                autospec=True)
    @mock.patch("src.data_store.stores.alert.AlertStore._process_mongo_store",
                autospec=True)
    @mock.patch("src.data_store.stores.store.Store._send_heartbeat",
                autospec=True)
    def test_process_data_results_stores_in_redis_correctly(
            self, mock_system_data, mock_send_hb, mock_process_mongo_store,
            mock_ack) -> None:

        mock_ack.return_value = None
        try:
            self.test_store._initialise_rabbitmq()

            data = eval(mock_system_data)
            blocking_channel = self.test_store.rabbitmq.channel
            method_chains = pika.spec.Basic.Deliver(
                routing_key=ALERT_STORE_INPUT_ROUTING_KEY)

            properties = pika.spec.BasicProperties()
            self.test_store._process_data(blocking_channel, method_chains,
                                          properties,
                                          json.dumps(data).encode())

            mock_process_mongo_store.assert_called_once()
            mock_ack.assert_called_once()
            mock_send_hb.assert_called_once()

            key = data['origin_id']

            stored_data = self.redis.hget(
                Keys.get_hash_parent(data['parent_id']),
                eval('Keys.get_alert_{}(key)'.format(data['metric'])))

            expected_data = {
                'severity': data['severity'],
                'message': data['message']
            }

            self.assertEqual(expected_data, json.loads(stored_data))
        except Exception as e:
            self.fail("Test failed: {}".format(e))