def setUp(self) -> None: self.logger = logging.getLogger('dummy') self.monitor_name = 'testmonitor' self.counter_channel = CounterChannel(self.logger) self.channel_set = ChannelSet([self.counter_channel], TestInternalConf) self.repo_name = 'dummy/repository/' self.releases_page = 'dummy.releases.page' self.db = TestInternalConf.redis_test_database self.host = TestUserConf.redis_host self.port = TestUserConf.redis_port self.password = TestUserConf.redis_password self.redis = RedisApi(self.logger, self.db, self.host, self.port, self.password) self.redis.delete_all_unsafe() try: self.redis.ping_unsafe() except RedisConnectionError: self.fail('Redis is not online.') self.monitor = GitHubMonitor(self.monitor_name, self.channel_set, self.logger, self.redis, self.repo_name, self.releases_page) self.monitor._internal_conf = TestInternalConf
def setUp(self) -> None: self.blockchain_name = 'testblockchain' self.redis_prefix = self.blockchain_name self.logger = logging.getLogger('dummy') self.counter_channel = CounterChannel(self.logger) self.channel_set = ChannelSet([self.counter_channel], TestInternalConf) self.db = TestInternalConf.redis_test_database self.host = TestUserConf.redis_host self.port = TestUserConf.redis_port self.password = TestUserConf.redis_password self.redis = RedisApi(self.logger, self.db, self.host, self.port, self.password) self.redis.delete_all_unsafe() try: self.redis.ping_unsafe() except RedisConnectionError: self.fail('Redis is not online.') self.blockchain = Blockchain(self.blockchain_name, self.redis) self.dummy_referendum_count = 10 self.dummy_council_prop_count = 10 self.dummy_public_prop_count = 10 self.dummy_validator_set_size = 120
def setUp(self) -> None: self.logger = logging.getLogger('dummy') self.monitor_name = 'testblockchainmonitor' self.blockchain_name = 'testblockchain' self.counter_channel = CounterChannel(self.logger) self.channel_set = ChannelSet([self.counter_channel], TestInternalConf) self.db = TestInternalConf.redis_test_database self.host = TestUserConf.redis_host self.port = TestUserConf.redis_port self.password = TestUserConf.redis_password self.redis = RedisApi(self.logger, self.db, self.host, self.port, self.password) self.redis.delete_all_unsafe() try: self.redis.ping_unsafe() except RedisConnectionError: self.fail('Redis is not online.') self.data_sources = [] self.blockchain = Blockchain(self.blockchain_name, self.redis) self.polkadot_api_endpoint = 'api_endpoint' self.monitor = BlockchainMonitor(self.monitor_name, self.blockchain, self.channel_set, self.logger, self.redis, self.data_sources, self.polkadot_api_endpoint, TestInternalConf) self.redis_alive_key_timeout = \ TestInternalConf.redis_blockchain_monitor_alive_key_timeout self.alive_key_timeout = \ TestInternalConf.redis_blockchain_monitor_alive_key_timeout
def setUp(self) -> None: self.logger = logging.getLogger('dummy') self.monitor_name = 'testnodemonitor' self.counter_channel = CounterChannel(self.logger) self.channel_set = ChannelSet([self.counter_channel], TestInternalConf) self.db = TestInternalConf.redis_test_database self.host = TestUserConf.redis_host self.port = TestUserConf.redis_port self.password = TestUserConf.redis_password self.redis = RedisApi(self.logger, self.db, self.host, self.port, self.password) self.redis.delete_all_unsafe() try: self.redis.ping_unsafe() except RedisConnectionError: self.fail('Redis is not online.') self.node_monitor_max_catch_up_blocks = \ TestInternalConf.node_monitor_max_catch_up_blocks self.node = None self.archive_alerts_disabled = False self.data_sources = [] self.monitor = NodeMonitor(self.monitor_name, self.channel_set, self.logger, self.node_monitor_max_catch_up_blocks, self.redis, self.node, self.archive_alerts_disabled, self.data_sources, TestInternalConf) self.dummy_last_height_checked = 1000 self.redis_alive_key_timeout = \ TestInternalConf.redis_node_monitor_alive_key_timeout
def setUp(self) -> None: self.logger = logging.getLogger('dummy') self.db = TestInternalConf.redis_test_database self.host = 'dummyhost' self.port = TestUserConf.redis_port self.namespace = 'testnamespace' self.redis = RedisApi(self.logger, self.db, self.host, self.port, namespace=self.namespace) self.key = 'key' self.val = 'val' self.time = timedelta.max
def test_set_unsafe_throws_exception_if_incorrect_password(self): redis_bad_pass = RedisApi(self.logger, self.db, self.host, self.port, password='******', namespace=self.namespace) self.redis.set_unsafe(self.key1, self.val1) # works try: redis_bad_pass.set_unsafe(self.key1, self.val1) self.fail('Expected AuthenticationError to be thrown') except AuthenticationError: pass except ResponseError: pass
def test_redis(host: str, port: str, password: str) -> TestOutcome: redis = RedisApi(DUMMY_LOGGER, 0, host, int(port), password=password, namespace='') try: redis.ping_unsafe() print('Test completed successfully.') return TestOutcome.OK except Exception as e: print('Something went wrong: {}'.format(e)) if yn_prompt('Retry Redis setup? (Y/n)\n'): return TestOutcome.RestartSetup else: return TestOutcome.SkipSetup
def setUp(self) -> None: self.logger = logging.getLogger('dummy') self.db = TestInternalConf.redis_test_database self.host = 'dummyhost' self.port = 6379 self.live_check_time_interval = timedelta(seconds=3) self.live_check_time_interval_with_error_margin = timedelta( seconds=3.5) self.redis = RedisApi( self.logger, self.db, self.host, self.port, live_check_time_interval=self.live_check_time_interval)
def setUpClass(cls) -> None: # Same as in setUp(), to avoid running all tests if Redis is offline logger = logging.getLogger('dummy') db = TestInternalConf.redis_test_database host = TestUserConf.redis_host port = TestUserConf.redis_port password = TestUserConf.redis_password redis = RedisApi(logger, db, host, port, password) try: redis.ping_unsafe() except RedisConnectionError: raise Exception('Redis is not online.')
def setUp(self) -> None: self.logger = logging.getLogger('dummy') self.db = TestInternalConf.redis_test_database self.host = TestUserConf.redis_host self.port = TestUserConf.redis_port self.namespace = 'testnamespace' self.password = TestUserConf.redis_password self.redis = RedisApi(self.logger, self.db, self.host, 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 setUp(self) -> None: self.alerter_name = 'testalerter' self.logger = logging.getLogger('dummy') self.counter_channel = CounterChannel(self.logger) self.channel_set = ChannelSet([self.counter_channel], TestInternalConf) self.db = TestInternalConf.redis_test_database self.host = TestUserConf.redis_host self.port = TestUserConf.redis_port self.password = TestUserConf.redis_password self.redis = RedisApi(self.logger, self.db, self.host, self.port, self.password) self.redis.delete_all_unsafe() try: self.redis.ping_unsafe() except RedisConnectionError: self.fail('Redis is not online.') self.par = PeriodicAliveReminder(timedelta(), self.channel_set, self.redis)
class TestBlockchainMonitorWithRedis(unittest.TestCase): @classmethod def setUpClass(cls) -> None: # Same as in setUp(), to avoid running all tests if Redis is offline logger = logging.getLogger('dummy') db = TestInternalConf.redis_test_database host = TestUserConf.redis_host port = TestUserConf.redis_port password = TestUserConf.redis_password redis = RedisApi(logger, db, host, port, password) try: redis.ping_unsafe() except RedisConnectionError: raise Exception('Redis is not online.') def setUp(self) -> None: self.logger = logging.getLogger('dummy') self.monitor_name = 'testblockchainmonitor' self.blockchain_name = 'testblockchain' self.counter_channel = CounterChannel(self.logger) self.channel_set = ChannelSet([self.counter_channel], TestInternalConf) self.db = TestInternalConf.redis_test_database self.host = TestUserConf.redis_host self.port = TestUserConf.redis_port self.password = TestUserConf.redis_password self.redis = RedisApi(self.logger, self.db, self.host, self.port, self.password) self.redis.delete_all_unsafe() try: self.redis.ping_unsafe() except RedisConnectionError: self.fail('Redis is not online.') self.data_sources = [] self.blockchain = Blockchain(self.blockchain_name, self.redis) self.polkadot_api_endpoint = 'api_endpoint' self.monitor = BlockchainMonitor(self.monitor_name, self.blockchain, self.channel_set, self.logger, self.redis, self.data_sources, self.polkadot_api_endpoint, TestInternalConf) self.redis_alive_key_timeout = \ TestInternalConf.redis_blockchain_monitor_alive_key_timeout self.alive_key_timeout = \ TestInternalConf.redis_blockchain_monitor_alive_key_timeout def test_save_state_saves_alive_key_temporarily(self): self.monitor.save_state() key = Keys.get_blockchain_monitor_alive(self.monitor_name) last_update = self.redis.get(key) timeout = self.redis.time_to_live(key) self.assertIsNotNone(last_update) self.assertEqual(timeout, self.alive_key_timeout)
def run() -> None: # Check if Redis enabled if not UserConf.redis_enabled: raise InitialisationException('Redis is not set up. Run the setup ' 'script to configure Redis.') logger = create_logger(InternalConf.redis_log_file, 'redis', InternalConf.logging_level) print('Deleting all Redis keys.') # Redis database try: RedisApi( logger, InternalConf.redis_database, UserConf.redis_host, UserConf.redis_port, password=UserConf.redis_password, namespace=UserConf.unique_alerter_identifier).delete_all_unsafe() except Exception as e: sys.exit(e) # Redis test database try: RedisApi( logger, InternalConf.redis_test_database, UserConf.redis_host, UserConf.redis_port, password=UserConf.redis_password, namespace=UserConf.unique_alerter_identifier).delete_all_unsafe() except Exception as e: sys.exit(e) print('Done deleting all Redis keys.')
class TestPeriodicWithRedis(unittest.TestCase): def setUp(self) -> None: self.alerter_name = 'testalerter' self.logger = logging.getLogger('dummy') self.counter_channel = CounterChannel(self.logger) self.channel_set = ChannelSet([self.counter_channel], TestInternalConf) self.db = TestInternalConf.redis_test_database self.host = TestUserConf.redis_host self.port = TestUserConf.redis_port self.password = TestUserConf.redis_password self.redis = RedisApi(self.logger, self.db, self.host, self.port, self.password) self.redis.delete_all_unsafe() try: self.redis.ping_unsafe() except RedisConnectionError: self.fail('Redis is not online.') self.par = PeriodicAliveReminder(timedelta(), self.channel_set, self.redis) def test_periodic_alive_reminder_sends_info_alert_if_no_mute_key(self): self.counter_channel.reset() # ignore previous alerts self.par.send_alive_alert() self.assertEqual(self.counter_channel.warning_count, 0) self.assertEqual(self.counter_channel.critical_count, 0) self.assertEqual(self.counter_channel.info_count, 1) self.assertEqual(self.counter_channel.error_count, 0) def test_periodic_alive_reminder_sends_no_alert_if_mute_key_present(self): hours = timedelta(hours=float(1)) until = str(datetime.now() + hours) key = Keys.get_alive_reminder_mute() self.redis.set_for(key, until, hours) self.counter_channel.reset() # ignore previous alerts self.par.send_alive_alert() self.redis.remove(key) self.assertEqual(self.counter_channel.warning_count, 0) self.assertEqual(self.counter_channel.critical_count, 0) self.assertEqual(self.counter_channel.info_count, 0) self.assertEqual(self.counter_channel.error_count, 0)
def setUp(self) -> None: self.logger = logging.getLogger('dummy') self.db = TestInternalConf.redis_test_database self.host = TestUserConf.redis_host self.port = TestUserConf.redis_port self.password = TestUserConf.redis_password self.namespace1 = 'testnamespace1' self.namespace2 = 'testnamespace2' self.redis = RedisApi(self.logger, self.db, self.host, self.port, self.password, namespace=self.namespace1) self.same_namespace = RedisApi(self.logger, self.db, self.host, self.port, self.password, namespace=self.namespace1) self.different_namespace = RedisApi(self.logger, self.db, self.host, self.port, 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.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')
class TestNodeMonitorWithRedis(unittest.TestCase): @classmethod def setUpClass(cls) -> None: # Same as in setUp(), to avoid running all tests if Redis is offline logger = logging.getLogger('dummy') db = TestInternalConf.redis_test_database host = TestUserConf.redis_host port = TestUserConf.redis_port password = TestUserConf.redis_password redis = RedisApi(logger, db, host, port, password) try: redis.ping_unsafe() except RedisConnectionError: raise Exception('Redis is not online.') def setUp(self) -> None: self.logger = logging.getLogger('dummy') self.monitor_name = 'testnodemonitor' self.counter_channel = CounterChannel(self.logger) self.channel_set = ChannelSet([self.counter_channel], TestInternalConf) self.db = TestInternalConf.redis_test_database self.host = TestUserConf.redis_host self.port = TestUserConf.redis_port self.password = TestUserConf.redis_password self.redis = RedisApi(self.logger, self.db, self.host, self.port, self.password) self.redis.delete_all_unsafe() try: self.redis.ping_unsafe() except RedisConnectionError: self.fail('Redis is not online.') self.node_monitor_max_catch_up_blocks = \ TestInternalConf.node_monitor_max_catch_up_blocks self.node = None self.archive_alerts_disabled = False self.data_sources = [] self.monitor = NodeMonitor(self.monitor_name, self.channel_set, self.logger, self.node_monitor_max_catch_up_blocks, self.redis, self.node, self.archive_alerts_disabled, self.data_sources, TestInternalConf) self.dummy_last_height_checked = 1000 self.redis_alive_key_timeout = \ TestInternalConf.redis_node_monitor_alive_key_timeout def test_load_state_changes_nothing_if_nothing_saved(self) -> None: self.monitor.load_state() self.assertEqual(NONE, self.monitor._last_height_checked) def test_load_state_sets_values_to_saved_values(self) -> None: # Set Redis values manually key_lh = Keys.get_node_monitor_last_height_checked(self.monitor_name) self.redis.set_unsafe(key_lh, self.dummy_last_height_checked) # Load the values from Redis self.monitor.load_state() # Assert self.assertEqual(self.dummy_last_height_checked, self.monitor.last_height_checked) def test_save_state_sets_values_to_current_values_and_stores_alive_key_temp( self) -> None: # Set monitor values manually self.monitor._last_height_checked = self.dummy_last_height_checked # Save the values to Redis self.monitor.save_state() key_lh = Keys.get_node_monitor_last_height_checked(self.monitor_name) # Get last update, and its timeout in Redis last_update = self.redis.get(key_lh) timeout = self.redis.time_to_live(key_lh) # Assert self.assertEqual(self.dummy_last_height_checked, self.redis.get_int(key_lh)) self.assertIsNotNone(last_update) self.assertEqual(timeout, self.redis_alive_key_timeout)
class TestRedisApiWithRedisOffline(unittest.TestCase): def setUp(self) -> None: self.logger = logging.getLogger('dummy') self.db = TestInternalConf.redis_test_database self.host = 'dummyhost' self.port = TestUserConf.redis_port self.namespace = 'testnamespace' self.redis = RedisApi(self.logger, self.db, self.host, self.port, namespace=self.namespace) self.key = 'key' self.val = 'val' self.time = timedelta.max def test_add_namespace_adds_namespace(self): key = 'some key' key_with_namespace = self.namespace + ':' + key self.assertEqual(key_with_namespace, self.redis._add_namespace(key)) def test_remove_namespace_remove_namespace(self): key = 'some key' key_with_namespace = self.namespace + ':' + key self.assertEqual(key, self.redis._remove_namespace(key_with_namespace)) def test_add_namespace_adds_nothing_if_already_added_namespace(self): key = 'some key' key_with_namespace = self.namespace + ':' + key self.assertEqual(key_with_namespace, self.redis._add_namespace(key_with_namespace)) def test_remove_namespace_removes_nothing_if_no_namespace(self): key = 'some key' self.assertEqual(key, self.redis._remove_namespace(key)) def test_set_unsafe_throws_connection_exception(self): try: self.redis.set_unsafe(self.key, self.val) self.fail('Expected RedisConnectionError exception to be thrown.') except RedisConnectionError: pass def test_hset_unsafe_throws_connection_exception(self): try: hash_name = "dummy_hash" self.redis.hset_unsafe(hash_name, self.key, self.val) self.fail('Expected RedisConnectionError exception to be thrown.') except RedisConnectionError: pass def test_set_multiple_unsafe_throws_connection_exception(self): try: self.redis.set_multiple_unsafe({self.key: self.val}) self.fail('Expected RedisConnectionError exception to be thrown.') except RedisConnectionError: pass def test_hset_multiple_unsafe_throws_connection_exception(self): try: hash_name = "dummy_hash" self.redis.hset_multiple_unsafe(hash_name, {self.key: self.val}) self.fail('Expected RedisConnectionError exception to be thrown.') except RedisConnectionError: pass def test_set_for_unsafe_throws_connection_exception(self): try: self.redis.set_for_unsafe(self.key, self.val, self.time) self.fail('Expected RedisConnectionError exception to be thrown.') except RedisConnectionError: pass def test_time_to_live_unsafe_throws_connection_exception(self): try: self.redis.time_to_live_unsafe(self.key) self.fail('Expected RedisConnectionError exception to be thrown.') except RedisConnectionError: pass def test_get_unsafe_throws_connection_exception(self): try: self.redis.get_unsafe(self.key) self.fail('Expected RedisConnectionError exception to be thrown.') except RedisConnectionError: pass def test_hget_unsafe_throws_connection_exception(self): try: hash_name = "dummy_hash" self.redis.hget_unsafe(hash_name, self.key) self.fail('Expected RedisConnectionError exception to be thrown.') except RedisConnectionError: pass def test_get_int_unsafe_throws_connection_exception(self): try: self.redis.get_int_unsafe(self.key) self.fail('Expected RedisConnectionError exception to be thrown.') except RedisConnectionError: pass def test_hget_int_unsafe_throws_connection_exception(self): try: hash_name = "dummy_hash" self.redis.hget_int_unsafe(hash_name, self.key) self.fail('Expected RedisConnectionError exception to be thrown.') except RedisConnectionError: pass def test_get_bool_unsafe_throws_connection_exception(self): try: self.redis.get_bool_unsafe(self.key) self.fail('Expected RedisConnectionError exception to be thrown.') except RedisConnectionError: pass def test_hget_bool_unsafe_throws_connection_exception(self): try: hash_name = "dummy_hash" self.redis.hget_bool_unsafe(hash_name, self.key) self.fail('Expected RedisConnectionError exception to be thrown.') except RedisConnectionError: pass def test_exists_unsafe_throws_connection_exception(self): try: self.redis.exists_unsafe(self.key) self.fail('Expected RedisConnectionError exception to be thrown.') except RedisConnectionError: pass def test_hexists_unsafe_throws_connection_exception(self): try: hash_name = "dummy_hash" self.redis.hexists_unsafe(hash_name, self.key) self.fail('Expected RedisConnectionError exception to be thrown.') except RedisConnectionError: pass def test_get_keys_unsafe_throws_connection_exception(self): try: self.redis.get_keys_unsafe() self.fail('Expected RedisConnectionError exception to be thrown.') except RedisConnectionError: pass def test_remove_unsafe_throws_connection_exception(self): try: self.redis.remove_unsafe(self.key) self.fail('Expected RedisConnectionError exception to be thrown.') except RedisConnectionError: pass def test_delete_all_unsafe_throws_connection_exception(self): try: self.redis.delete_all_unsafe() self.fail('Expected RedisConnectionError exception to be thrown.') except RedisConnectionError: pass def test_set_returns_none(self): self.assertIsNone(self.redis.set(self.key, self.val)) def test_hset_returns_none(self): hash_name = "dummy_hash" self.assertIsNone(self.redis.hset(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): hash_name = "dummy_hash" self.assertIsNone( self.redis.hset_multiple(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): hash_name = "dummy_hash" self.assertIsNone(self.redis.hget(hash_name, self.key)) def test_hget_returns_default_if_default_specified(self): hash_name = "dummy_hash" default = 'default' self.assertEqual(self.redis.hget(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): hash_name = "dummy_hash" self.assertIsNone(self.redis.hget_int(hash_name, self.key)) def test_hget_int_returns_default_if_default_specified(self): hash_name = "dummy_hash" default = 123456 self.assertEqual( self.redis.hget_int(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): hash_name = "dummy_hash" self.assertIsNone(self.redis.hget_bool(hash_name, self.key)) def test_hget_bool_returns_default_if_default_specified(self): hash_name = "dummy_hash" default = True self.assertEqual( self.redis.hget_bool(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): hash_name = "dummy_hash" self.assertFalse(self.redis.hexists(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_delete_all_returns_none(self): self.assertIsNone(self.redis.delete_all()) def test_ping_unsafe_throws_connection_exception(self): try: self.redis.ping_unsafe() self.fail('Expected RedisConnectionError exception to be thrown.') except RedisConnectionError: pass def test_second_safe_command_faster_to_throw_than_first_when_offline(self): start_1 = time.perf_counter() self.redis.set(self.key, self.val) elapsed_1 = time.perf_counter() - start_1 start_2 = time.perf_counter() self.redis.set(self.key, self.val) elapsed_2 = time.perf_counter() - start_2 # first executon is more than 10 times slower than second execution self.assertGreater(elapsed_1, elapsed_2 * 10)
class TestBlockchainWithRedis(unittest.TestCase): @classmethod def setUpClass(cls) -> None: # Same as in setUp(), to avoid running all tests if Redis is offline logger = logging.getLogger('dummy') db = TestInternalConf.redis_test_database host = TestUserConf.redis_host port = TestUserConf.redis_port password = TestUserConf.redis_password redis = RedisApi(logger, db, host, port, password) try: redis.ping_unsafe() except RedisConnectionError: raise Exception('Redis is not online.') def setUp(self) -> None: self.blockchain_name = 'testblockchain' self.redis_prefix = self.blockchain_name self.logger = logging.getLogger('dummy') self.counter_channel = CounterChannel(self.logger) self.channel_set = ChannelSet([self.counter_channel], TestInternalConf) self.db = TestInternalConf.redis_test_database self.host = TestUserConf.redis_host self.port = TestUserConf.redis_port self.password = TestUserConf.redis_password self.redis = RedisApi(self.logger, self.db, self.host, self.port, self.password) self.redis.delete_all_unsafe() try: self.redis.ping_unsafe() except RedisConnectionError: self.fail('Redis is not online.') self.blockchain = Blockchain(self.blockchain_name, self.redis) self.dummy_referendum_count = 10 self.dummy_council_prop_count = 10 self.dummy_public_prop_count = 10 self.dummy_validator_set_size = 120 def test_load_state_changes_nothing_if_nothing_saved(self): self.blockchain.load_state(self.logger) self.assertIsNone(self.blockchain.validator_set_size) self.assertIsNone(self.blockchain.public_prop_count) self.assertIsNone(self.blockchain.council_prop_count) self.assertIsNone(self.blockchain.validator_set_size) def test_load_state_sets_values_to_saved_values(self): # Set Redis values manually hash_name = Keys.get_hash_blockchain(self.blockchain.name) self.redis.hset_multiple_unsafe( hash_name, { Keys.get_blockchain_referendum_count(self.blockchain.name): self.dummy_referendum_count, Keys.get_blockchain_public_prop_count(self.blockchain.name): self.dummy_public_prop_count, Keys.get_blockchain_council_prop_count(self.blockchain.name): self.dummy_council_prop_count, Keys.get_blockchain_validator_set_size(self.blockchain.name): self.dummy_validator_set_size, }) # Load the Redis values self.blockchain.load_state(self.logger) # Assert self.assertEqual(self.blockchain.referendum_count, self.dummy_referendum_count) self.assertEqual(self.blockchain.public_prop_count, self.dummy_public_prop_count) self.assertEqual(self.blockchain.council_prop_count, self.dummy_council_prop_count) self.assertEqual(self.blockchain.validator_set_size, self.dummy_validator_set_size) def test_save_state_sets_values_to_current_values(self): # Set blockchain values manually self.blockchain.set_referendum_count(self.dummy_referendum_count, self.channel_set, self.logger) self.blockchain.set_council_prop_count(self.dummy_council_prop_count, self.channel_set, self.logger) self.blockchain.set_public_prop_count(self.dummy_public_prop_count, self.channel_set, self.logger) self.blockchain.set_validator_set_size(self.dummy_validator_set_size, self.channel_set, self.logger) # Save the values to Redis self.blockchain.save_state(self.logger) # Assert hash_name = Keys.get_hash_blockchain(self.blockchain.name) self.assertEqual( self.redis.hget_int_unsafe( hash_name, Keys.get_blockchain_referendum_count(self.blockchain.name)), self.dummy_referendum_count) self.assertEqual( self.redis.hget_int_unsafe( hash_name, Keys.get_blockchain_public_prop_count(self.blockchain.name)), self.dummy_public_prop_count) self.assertEqual( self.redis.hget_int_unsafe( hash_name, Keys.get_blockchain_council_prop_count(self.blockchain.name)), self.dummy_council_prop_count) self.assertEqual( self.redis.hget_int_unsafe( hash_name, Keys.get_blockchain_validator_set_size(self.blockchain.name)), self.dummy_validator_set_size)
class TestRedisApiWithRedisOnline(unittest.TestCase): @classmethod def setUpClass(cls) -> None: # Same as in setUp(), to avoid running all tests if Redis is offline logger = logging.getLogger('dummy') db = TestInternalConf.redis_test_database host = TestUserConf.redis_host port = TestUserConf.redis_port password = TestUserConf.redis_password redis = RedisApi(logger, db, host, port, password=password) # Ping Redis try: redis.ping_unsafe() except RedisConnectionError: raise Exception('Redis is not online.') def setUp(self) -> None: self.logger = logging.getLogger('dummy') self.db = TestInternalConf.redis_test_database self.host = TestUserConf.redis_host self.port = TestUserConf.redis_port self.namespace = 'testnamespace' self.password = TestUserConf.redis_password self.redis = RedisApi(self.logger, self.db, self.host, 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.redis.delete_all_unsafe() def test_set_unsafe_throws_exception_if_incorrect_password(self): redis_bad_pass = RedisApi(self.logger, self.db, self.host, self.port, password='******', namespace=self.namespace) self.redis.set_unsafe(self.key1, self.val1) # works try: redis_bad_pass.set_unsafe(self.key1, self.val1) self.fail('Expected AuthenticationError to be thrown') except AuthenticationError: pass 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): try: self.redis.set_unsafe(self.key1, True) self.fail('Expected DataError exception to be thrown.') except DataError: pass def test_hset_unsafe_throws_exception_if_incorrect_password(self): redis_bad_pass = RedisApi(self.logger, self.db, self.host, self.port, password='******', namespace=self.namespace) hash_name = "dummy_hash" self.redis.hset_unsafe(hash_name, self.key1, self.val1) # works try: redis_bad_pass.hset_unsafe(hash_name, self.key1, self.val1) self.fail('Expected AuthenticationError to be thrown') except AuthenticationError: pass def test_hset_unsafe_sets_the_specified_key_to_the_specified_value(self): hash_name = "dummy_hash" self.redis.hset_unsafe(hash_name, self.key1, self.val1) self.assertEqual(self.redis.hget_unsafe(hash_name, self.key1), self.val1_bytes) def test_hset_unsafe_throws_exception_if_invalid_type(self): try: hash_name = "dummy_hash" self.redis.hset_unsafe(hash_name, self.key1, True) self.fail('Expected DataError exception to be thrown.') except DataError: pass 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): hash_name = "dummy_hash" self.redis.hset_multiple_unsafe(hash_name, { self.key1: self.val1, self.key2: self.val2 }) self.assertEqual(self.redis.hget_unsafe(hash_name, self.key1), self.val1_bytes) self.assertEqual(self.redis.hget_unsafe(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): hash_name = "dummy_hash" self.assertEqual( self.redis.hget_unsafe(hash_name, self.key1, default=self.default_str), self.default_str) def test_hget_unsafe_returns_set_value(self): hash_name = "dummy_hash" self.redis.hset_unsafe(hash_name, self.key1, self.val1) self.assertEqual( self.redis.hget_unsafe(hash_name, self.key1, default=self.default_str), self.val1_bytes) def test_hget_unsafe_returns_none_for_none_string(self): hash_name = "dummy_hash" self.redis.hset_unsafe(hash_name, self.key1, 'None') self.assertIsNone( self.redis.hget_unsafe(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): hash_name = "dummy_hash" self.redis.hset_unsafe(hash_name, self.key3, self.val3_int) self.assertEqual( self.redis.hget_int_unsafe(hash_name, self.key3, default=self.default_int), self.val3_int) def test_hget_int_unsafe_returns_default_for_unset_key(self): hash_name = "dummy_hash" self.assertEqual( self.redis.hget_int_unsafe(hash_name, self.key3, default=self.default_int), self.default_int) def test_hget_int_unsafe_returns_default_for_non_integer_value(self): hash_name = "dummy_hash" self.redis.hset_unsafe(hash_name, self.key2, self.val2) self.assertEqual( self.redis.hget_int_unsafe(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): hash_name = "dummy_hash" self.redis.hset_unsafe(hash_name, self.key4, self.val4) self.assertEqual( self.redis.hget_bool_unsafe(hash_name, self.key4, default=self.default_bool), self.val4_bool) def test_hget_bool_unsafe_returns_default_for_unset_key(self): hash_name = "dummy_hash" self.assertEqual( self.redis.hget_bool_unsafe(hash_name, self.key4, default=self.default_bool), self.default_bool) def test_hget_bool_unsafe_returns_false_for_non_boolean_value(self): hash_name = "dummy_hash" self.redis.hset_unsafe(hash_name, self.key1, self.val1) self.assertFalse( self.redis.hget_bool_unsafe(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): hash_name = "dummy_hash" self.redis.hset_unsafe(hash_name, self.key1, self.val1) self.assertTrue(self.redis.hexists_unsafe(hash_name, self.key1)) def test_hexists_unsafe_returns_false_if_not_exists(self): hash_name = "dummy_hash" self.assertFalse(self.redis.hexists_unsafe(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) 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_delete_all_unsafe_does_nothing_if_no_keys_exist(self): self.redis.delete_all_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): hash_name = "dummy_hash" self.redis.hset(hash_name, self.key1, self.val1) self.assertEqual(self.redis.hget(hash_name, self.key1), self.val1_bytes) def test_hset_returns_none_if_invalid_type(self): hash_name = "dummy_hash" self.assertIsNone(self.redis.hset(hash_name, self.key1, True)) @patch(REDIS_RECENTLY_DOWN_FUNCTION, return_value=True) def test_hset_returns_none_if_redis_down(self, _): hash_name = "dummy_hash" self.assertIsNone(self.redis.hset(hash_name, self.key1, self.val1)) self.assertFalse(self.redis.hexists_unsafe(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): hash_name = "dummy_hahh" self.redis.hset_multiple(hash_name, { self.key1: self.val1, self.key2: self.val2 }) self.assertEqual(self.redis.hget(hash_name, self.key1), self.val1_bytes) self.assertEqual(self.redis.hget(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, _): hash_name = "dummy_dash" self.assertIsNone( self.redis.hset_multiple(hash_name, { self.key1: self.val1, self.key2: self.val2 })) self.assertFalse(self.redis.hexists_unsafe(hash_name, self.key1)) self.assertFalse(self.redis.hexists_unsafe(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.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): hash_name = "dummy_hash" self.assertEqual( self.redis.hget(hash_name, self.key1, default=self.default_str), self.default_str) def test_hget_returns_set_value(self): hash_name = "dummy_hash" self.redis.hset(hash_name, self.key1, self.val1) self.assertEqual( self.redis.hget(hash_name, self.key1, default=self.default_str), self.val1_bytes) def test_hget_returns_none_for_none_string(self): hash_name = "dummy_hash" self.redis.hset(hash_name, self.key1, 'None') self.assertIsNone( self.redis.hget(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, _): hash_name = "dummy_hash" self.redis.hset_unsafe(hash_name, self.key1, self.val1) self.assertEqual( self.redis.hget(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): hash_name = "dummy_hash" self.redis.hset(hash_name, self.key3, self.val3_int) self.assertEqual( self.redis.hget_int(hash_name, self.key3, default=self.default_int), self.val3_int) def test_hget_int_returns_default_for_unset_key(self): hash_name = "dummy_hash" self.assertEqual( self.redis.hget_int(hash_name, self.key3, default=self.default_int), self.default_int) def test_hget_int_returns_default_for_non_integer_value(self): hash_name = "dummy_hash" self.redis.hset(hash_name, self.key2, self.val2) self.assertEqual( self.redis.hget_int(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, _): hash_name = "dummy_hash" self.redis.hset_unsafe(hash_name, self.key3, self.val3_int) self.assertEqual( self.redis.hget_int(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): hash_name = "dummy_hash" self.redis.hset(hash_name, self.key4, self.val4) self.assertEqual( self.redis.hget_bool(hash_name, self.key4, default=self.default_bool), self.val4_bool) def test_hget_bool_returns_default_for_unset_key(self): hash_name = "dummy_hash" self.assertEqual( self.redis.hget_bool(hash_name, self.key4, default=self.default_bool), self.default_bool) def test_hget_bool_returns_false_for_non_boolean_value(self): hash_name = "dummy_hash" self.redis.hset(hash_name, self.key1, self.val1) self.assertFalse( self.redis.hget_bool(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, _): hash_name = "dummy_hash" self.redis.hset_unsafe(hash_name, self.key4, self.val4) self.assertEqual( self.redis.hget_bool(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): hash_name = "dummy_hash" self.redis.hset(hash_name, self.key1, self.val1) self.assertTrue(self.redis.hexists(hash_name, self.key1)) def test_hexists_returns_false_if_not_exists(self): hash_name = "dummy_hash" self.assertFalse(self.redis.hexists(hash_name, self.key1)) @patch(REDIS_RECENTLY_DOWN_FUNCTION, return_value=True) def test_hexists_returns_false_if_redis_down(self, _): hash_name = "dummy_hash" self.redis.hset_unsafe(hash_name, self.key1, self.val1) self.assertFalse(self.redis.hexists(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) 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_delete_all_does_nothing_if_no_keys_exist(self): self.redis.delete_all() 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())
class TestRedisApiLiveAndDownFeaturesWithRedisOffline(unittest.TestCase): def setUp(self) -> None: self.logger = logging.getLogger('dummy') self.db = TestInternalConf.redis_test_database self.host = 'dummyhost' self.port = 6379 self.live_check_time_interval = timedelta(seconds=3) self.live_check_time_interval_with_error_margin = timedelta( seconds=3.5) self.redis = RedisApi( self.logger, self.db, self.host, self.port, live_check_time_interval=self.live_check_time_interval) def test_is_live_returns_true_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_live_leaves_is_live_as_true_if_already_true(self): self.redis._is_live = True self.assertTrue(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_set_as_down_leaves_is_live_as_false_if_already_false(self): self.redis._is_live = False self.assertFalse(self.redis.is_live) self.redis._set_as_down() self.assertFalse(self.redis.is_live) def test_allowed_to_use_by_default(self): # noinspection PyBroadException try: self.redis._do_not_use_if_recently_went_down() except Exception: self.fail('Expected to be allowed to use Redis.') def test_not_allowed_to_use_if_set_as_down_and_within_time_interval(self): self.redis._set_as_down() # noinspection PyBroadException try: self.redis._do_not_use_if_recently_went_down() self.fail('Expected to not be allowed to use Redis.') except Exception: pass def test_allowed_to_use_if_set_as_down_and_within_time_interval(self): self.redis._set_as_down() sleep(self.live_check_time_interval_with_error_margin.seconds) # noinspection PyBroadException try: self.redis._do_not_use_if_recently_went_down() except Exception: self.fail('Expected to be allowed to use Redis.')
class TestRedisNamespaceWithRedisOnline(unittest.TestCase): @classmethod def setUpClass(cls) -> None: # Same as in setUp(), to avoid running all tests if Redis is offline logger = logging.getLogger('dummy') db = TestInternalConf.redis_test_database host = TestUserConf.redis_host port = TestUserConf.redis_port password = TestUserConf.redis_password redis = RedisApi(logger, db, host, port, password) # Ping Redis try: redis.ping_unsafe() except RedisConnectionError: raise Exception('Redis is not online.') def setUp(self) -> None: self.logger = logging.getLogger('dummy') self.db = TestInternalConf.redis_test_database self.host = TestUserConf.redis_host self.port = TestUserConf.redis_port self.password = TestUserConf.redis_password self.namespace1 = 'testnamespace1' self.namespace2 = 'testnamespace2' self.redis = RedisApi(self.logger, self.db, self.host, self.port, self.password, namespace=self.namespace1) self.same_namespace = RedisApi(self.logger, self.db, self.host, self.port, self.password, namespace=self.namespace1) self.different_namespace = RedisApi(self.logger, self.db, self.host, self.port, 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.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') def tearDown(self) -> None: self.redis.delete_all_unsafe() self.different_namespace.delete_all_unsafe() 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): hash_name = "dummy_hash" self.redis.hset_unsafe(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 + ':' + 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): hash_name = "dummy_hash" # Use raw Redis command to set, to bypass automatically-added namespace self.redis._redis.hset(self.namespace1 + ':' + hash_name, self.key1, self.val1) get_value = self.redis.hget_unsafe(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_different_namespace_has_separate_store(self): self.redis.set_unsafe(self.key1, self.val1) self.assertNotEqual(self.different_namespace.get_unsafe(self.key1), self.val1_bytes)
'commands_telegram', InternalConf.logging_level, rotating=True) # Set file location where all alerts will be stored log_file_alerts = InternalConf.alerts_log_file # Sets wrapper to query oasis api connected to nodes oasis_api_data_wrapper = OasisApiWrapper(logger_general) # Set Redis Object if it's enabled, pass the created Logger together # with details of the Redis server to the Redis API Object if UserConf.redis_enabled: REDIS = RedisApi(logger_redis, InternalConf.redis_database, UserConf.redis_host, UserConf.redis_port, password=UserConf.redis_password, namespace=UserConf.unique_alerter_identifier) else: REDIS = None # Set MONGO Object if it's enabled, pass the created Logger together # with details of the MONGO databse to the MONGO API Object if UserConf.mongo_enabled: MONGO = MongoApi(logger_mongo, UserConf.mongo_db_name, UserConf.mongo_host, UserConf.mongo_port, username=UserConf.mongo_user, password=UserConf.mongo_pass) else:
class TestGitHubMonitorWithRedis(unittest.TestCase): @classmethod def setUpClass(cls) -> None: # Same as in setUp(), to avoid running all tests if Redis is offline logger = logging.getLogger('dummy') db = TestInternalConf.redis_test_database host = TestUserConf.redis_host port = TestUserConf.redis_port password = TestUserConf.redis_password redis = RedisApi(logger, db, host, port, password) try: redis.ping_unsafe() except RedisConnectionError: raise Exception('Redis is not online.') def setUp(self) -> None: self.logger = logging.getLogger('dummy') self.monitor_name = 'testmonitor' self.counter_channel = CounterChannel(self.logger) self.channel_set = ChannelSet([self.counter_channel], TestInternalConf) self.repo_name = 'dummy/repository/' self.releases_page = 'dummy.releases.page' self.db = TestInternalConf.redis_test_database self.host = TestUserConf.redis_host self.port = TestUserConf.redis_port self.password = TestUserConf.redis_password self.redis = RedisApi(self.logger, self.db, self.host, self.port, self.password) self.redis.delete_all_unsafe() try: self.redis.ping_unsafe() except RedisConnectionError: self.fail('Redis is not online.') self.monitor = GitHubMonitor(self.monitor_name, self.channel_set, self.logger, self.redis, self.repo_name, self.releases_page) self.monitor._internal_conf = TestInternalConf def test_load_state_changes_nothing_if_nothing_saved(self): self.monitor.load_state() self.assertIsNone(self.monitor._prev_no_of_releases) def test_load_state_sets_values_to_saved_values(self): # Set Redis values manually key = Keys.get_github_releases(self.repo_name) self.redis.set_unsafe(key, 10) # Load the values from Redis self.monitor.load_state() # Assert self.assertEqual(10, self.monitor._prev_no_of_releases) def test_save_state_sets_values_to_current_values(self): # Set monitor values manually self.monitor._prev_no_of_releases = 10 # Save the values to Redis self.monitor.save_state() # Assert key = Keys.get_github_releases(self.repo_name) self.assertEqual(10, self.redis.get_int(key)) def test_save_state_sets_nothing_if_no_previous_state(self): # Save the values to Redis self.monitor.save_state() # Assert key = Keys.get_github_releases(self.repo_name) self.assertIsNone(self.redis.get_int(key))