def test_default_connection_with_init_class(self): sentinel = SentinelExtension() sentinel.init_app(self.app, client_class=FakeRedis) conn = sentinel.default_connection with self.app.app_context(): inst = conn._get_current_object() self.assertEqual(inst.kwargs['url'], 'redis://localhost/0')
def test_mixed_apps(self): sentinel1 = SentinelExtension(app=self.app, client_class=FakeRedis) conn1 = sentinel1.default_connection self.app2 = Flask('test2') sentinel2 = SentinelExtension(app=self.app2, config_prefix='CUSTOM_REDIS', client_class=FakeRedis) conn2 = sentinel2.default_connection self.app3 = Flask('test3') with self.app2.app_context(): with self.assertRaisesRegexp( ValueError, 'RedisSentinel extension with config prefix REDIS was not initialized for application test2' ): conn1._get_current_object() with self.app3.app_context(): with self.assertRaisesRegexp( ValueError, 'RedisSentinel extension with config prefix REDIS was not initialized for application test3' ): conn1._get_current_object()
def connect_redis(self): self.logger.debug("Connecting to redis...") if self.app.testing: self.logger.info("Configuring Fake Redis...") import fakeredis self.app.redis = FlaskRedis.from_custom_provider( fakeredis.FakeStrictRedis) self.app.redis.connect = self._mock_redis(True) self.app.redis.disconnect = self._mock_redis(False) self.app.redis.init_app(self.app) elif self.app.config["REDIS_URL"].startswith("redis+sentinel"): self.logger.info("Configuring Redis Sentinel...", redis_url=self.app.config["REDIS_URL"]) redis_sentinel = SentinelExtension() redis_connection = redis_sentinel.default_connection redis_sentinel.init_app(self.app) self.app.redis = redis_connection else: self.logger.info("Configuring Redis...", redis_url=self.app.config["REDIS_URL"]) self.app.redis = FlaskRedis() self.app.redis.init_app(self.app) self.logger.info("Connection to redis successful")
def test_unsupported_url_scheme(self): sentinel = SentinelExtension(client_class=FakeRedis, sentinel_class=FakeSentinel) self.app.config[ 'REDIS_URL'] = 'redis+something://hostname:7001/myslave/3?slave=true' with self.assertRaisesRegexp( ValueError, r'Unsupported redis URL scheme: redis\+something'): sentinel.init_app(self.app)
def test_sentinel_kwargs_from_config(self): sentinel = SentinelExtension(client_class=FakeRedis, sentinel_class=FakeSentinel) self.app.config['REDIS_URL'] = 'redis+sentinel://hostname:7001/mymaster/3' self.app.config['REDIS_SENTINEL_SOCKET_CONNECT_TIMEOUT'] = 0.3 sentinel.init_app(self.app) with self.app.app_context(): self.assertIsNotNone(sentinel.sentinel) self.assertEquals(sentinel.sentinel.sentinel_kwargs, {'socket_connect_timeout': 0.3})
def test_default_connection_with_config_class_string(self): sentinel = SentinelExtension() self.app.config['REDIS_CLASS'] = 'test_flask_redis_sentinel.FakeRedis' sentinel.init_app(self.app) conn = sentinel.default_connection with self.app.app_context(): inst = conn._get_current_object() self.assertEqual(inst.kwargs['url'], 'redis://localhost/0')
def test_named_slave_no_sentinel(self): sentinel = SentinelExtension(client_class=FakeRedis, sentinel_class=FakeSentinel) self.app.config['REDIS_URL'] = 'redis://hostname:7001/3' sentinel.init_app(self.app) conn = sentinel.slave_for('otherslave', db=6) with self.app.app_context(): self.assertIsNone(sentinel.sentinel._get_current_object()) with self.assertRaisesRegexp(ValueError, 'Cannot get slave otherslave using non-sentinel configuration'): inst = conn._get_current_object()
def test_default_connection(self): sentinel = SentinelExtension(client_class=FakeRedis) sentinel.init_app(self.app) conn = sentinel.default_connection with self.app.app_context(): inst = conn._get_current_object() self.assertEqual(inst.kwargs['host'], 'localhost') self.assertEqual(inst.kwargs['port'], 6379) self.assertEqual(inst.kwargs['db'], 0)
def test_default_connection_with_init_class(self): sentinel = SentinelExtension() sentinel.init_app(self.app, client_class=FakeRedis) conn = sentinel.default_connection with self.app.app_context(): inst = conn._get_current_object() self.assertEqual(inst.kwargs['host'], 'localhost') self.assertEqual(inst.kwargs['port'], 6379) self.assertEqual(inst.kwargs['db'], 0)
def test_default_connection_with_init_sentinel_class(self): sentinel = SentinelExtension(client_class=FakeRedis) self.app.config['REDIS_URL'] = 'redis+sentinel://hostname:7001/mymaster/3' sentinel.init_app(self.app, sentinel_class=FakeSentinel) conn = sentinel.default_connection with self.app.app_context(): self.assertIsNotNone(sentinel.sentinel) inst = conn._get_current_object() self.assertEqual(inst.kwargs['is_master'], True)
def test_default_connection_redis_vars(self): sentinel = SentinelExtension(client_class=FakeRedis) self.app.config['REDIS_URL'] = 'redis://hostname:7001/3' self.app.config['REDIS_DECODE_RESPONSES'] = True sentinel.init_app(self.app) conn = sentinel.default_connection with self.app.app_context(): inst = conn._get_current_object() self.assertEqual(inst.kwargs['url'], 'redis://hostname:7001/3') self.assertEqual(inst.kwargs['decode_responses'], True)
def test_default_connection_with_init_sentinel_class(self): sentinel = SentinelExtension(client_class=FakeRedis) self.app.config[ 'REDIS_URL'] = 'redis+sentinel://hostname:7001/mymaster/3' sentinel.init_app(self.app, sentinel_class=FakeSentinel) conn = sentinel.default_connection with self.app.app_context(): self.assertIsNotNone(sentinel.sentinel) inst = conn._get_current_object() self.assertEqual(inst.kwargs['is_master'], True)
def test_default_connection_with_config_class_string(self): sentinel = SentinelExtension() self.app.config['REDIS_CLASS'] = 'test_flask_redis_sentinel.FakeRedis' sentinel.init_app(self.app) conn = sentinel.default_connection with self.app.app_context(): inst = conn._get_current_object() self.assertEqual(inst.kwargs['host'], 'localhost') self.assertEqual(inst.kwargs['port'], 6379) self.assertEqual(inst.kwargs['db'], 0)
def test_sentinel_kwargs_from_config(self): sentinel = SentinelExtension(client_class=FakeRedis, sentinel_class=FakeSentinel) self.app.config[ 'REDIS_URL'] = 'redis+sentinel://hostname:7001/mymaster/3' self.app.config['REDIS_SENTINEL_SOCKET_CONNECT_TIMEOUT'] = 0.3 sentinel.init_app(self.app) with self.app.app_context(): self.assertIsNotNone(sentinel.sentinel) self.assertEquals(sentinel.sentinel.sentinel_kwargs, {'socket_connect_timeout': 0.3})
def test_named_slave_no_sentinel(self): sentinel = SentinelExtension(client_class=FakeRedis, sentinel_class=FakeSentinel) self.app.config['REDIS_URL'] = 'redis://hostname:7001/3' sentinel.init_app(self.app) conn = sentinel.slave_for('otherslave', db=6) with self.app.app_context(): self.assertIsNone(sentinel.sentinel._get_current_object()) with self.assertRaisesRegexp( RuntimeError, 'Cannot get slave otherslave using non-sentinel configuration' ): inst = conn._get_current_object()
def test_named_slave(self): sentinel = SentinelExtension(client_class=FakeRedis, sentinel_class=FakeSentinel) self.app.config['REDIS_URL'] = 'redis+sentinel://hostname:7001/mymaster/3' self.app.config['REDIS_DECODE_RESPONSES'] = True sentinel.init_app(self.app) conn = sentinel.slave_for('otherslave', db=6) with self.app.app_context(): self.assertIsNotNone(sentinel.sentinel) inst = conn._get_current_object() self.assertEqual(inst.kwargs['is_master'], False) self.assertEqual(inst.kwargs['service_name'], 'otherslave') self.assertEqual(inst.kwargs['connection_kwargs']['db'], 6) self.assertEqual(inst.kwargs['connection_kwargs']['decode_responses'], True)
def test_redis_threads(self): sentinel = SentinelExtension(client_class=FakeRedis, sentinel_class=FakeSentinel) self.app.config['REDIS_URL'] = 'redis://hostname:7001/0' sentinel.init_app(self.app) connections = self._check_threads(sentinel) self.assertIs(connections['from_another_thread'], connections['from_main_thread']) self.assertIs(connections['from_another_thread'], connections['from_main_thread_later']) self.assertIs(connections['from_main_thread'], connections['from_main_thread_later'])
def test_default_connection_redis_vars(self): sentinel = SentinelExtension(client_class=FakeRedis) self.app.config['REDIS_HOST'] = 'hostname' self.app.config['REDIS_PORT'] = 7001 self.app.config['REDIS_DB'] = 3 self.app.config['REDIS_DECODE_RESPONSES'] = True sentinel.init_app(self.app) conn = sentinel.default_connection with self.app.app_context(): inst = conn._get_current_object() self.assertEqual(inst.kwargs['host'], 'hostname') self.assertEqual(inst.kwargs['port'], 7001) self.assertEqual(inst.kwargs['db'], 3) self.assertEqual(inst.kwargs['decode_responses'], True)
def test_default_connection_redis_url(self): sentinel = SentinelExtension(client_class=FakeRedis) self.app.config['REDIS_URL'] = 'redis://hostname:7001/3' self.app.config['REDIS_HOST'] = 'ignored' # should be ignored self.app.config['REDIS_PORT'] = 5000 # should be ignored self.app.config['REDIS_DB'] = 7 # should be ignored sentinel.init_app(self.app) conn = sentinel.default_connection with self.app.app_context(): inst = conn._get_current_object() self.assertEqual(inst.kwargs['url'], 'redis://hostname:7001/3') self.assertNotIn('host', inst.kwargs) self.assertNotIn('port', inst.kwargs) self.assertNotIn('db', inst.kwargs)
def test_duplicate_prefix_registration(self): sentinel = SentinelExtension() sentinel2 = SentinelExtension() sentinel.init_app(self.app) with self.assertRaisesRegexp(ValueError, 'Config prefix REDIS already registered'): sentinel2.init_app(self.app)
def test_default_connection_sentinel_url_slave(self): sentinel = SentinelExtension(client_class=FakeRedis, sentinel_class=FakeSentinel) self.app.config['REDIS_URL'] = 'redis+sentinel://hostname:7001/myslave/3?client_type=slave' self.app.config['REDIS_DECODE_RESPONSES'] = True self.app.config['REDIS_SENTINEL_SOCKET_CONNECT_TIMEOUT'] = 0.3 sentinel.init_app(self.app) conn = sentinel.default_connection with self.app.app_context(): self.assertIsNotNone(sentinel.sentinel) inst = conn._get_current_object() self.assertEqual(inst.kwargs['is_master'], False) self.assertEqual(inst.kwargs['service_name'], 'myslave') self.assertEqual(inst.kwargs['connection_kwargs']['db'], 3) self.assertEqual(inst.kwargs['connection_kwargs']['decode_responses'], True)
def test_init_app_in_constructor(self): self.app.config['REDIS_URL'] = 'redis://hostname:7001/3' sentinel = SentinelExtension(app=self.app, client_class=FakeRedis) conn = sentinel.default_connection with self.app.app_context(): inst = conn._get_current_object() self.assertEqual(inst.kwargs['url'], 'redis://hostname:7001/3')
def test_named_slave(self): sentinel = SentinelExtension(client_class=FakeRedis, sentinel_class=FakeSentinel) self.app.config[ 'REDIS_URL'] = 'redis+sentinel://hostname:7001/mymaster/3' self.app.config['REDIS_DECODE_RESPONSES'] = True sentinel.init_app(self.app) conn = sentinel.slave_for('otherslave', db=6) with self.app.app_context(): self.assertIsNotNone(sentinel.sentinel) inst = conn._get_current_object() self.assertEqual(inst.kwargs['is_master'], False) self.assertEqual(inst.kwargs['service_name'], 'otherslave') self.assertEqual(inst.kwargs['connection_kwargs']['db'], 6) self.assertEqual( inst.kwargs['connection_kwargs']['decode_responses'], True)
def test_duplicate_prefix_registration(self): sentinel = SentinelExtension() sentinel2 = SentinelExtension() sentinel.init_app(self.app) msg = 'Redis sentinel extension with config prefix REDIS is already registered' with self.assertRaisesRegexp(RuntimeError, msg): sentinel2.init_app(self.app)
def test_default_connection_sentinel_url_slave(self): sentinel = SentinelExtension(client_class=FakeRedis, sentinel_class=FakeSentinel) self.app.config[ 'REDIS_URL'] = 'redis+sentinel://hostname:7001/myslave/3?client_type=slave' self.app.config['REDIS_DECODE_RESPONSES'] = True self.app.config['REDIS_SENTINEL_SOCKET_CONNECT_TIMEOUT'] = 0.3 sentinel.init_app(self.app) conn = sentinel.default_connection with self.app.app_context(): self.assertIsNotNone(sentinel.sentinel) inst = conn._get_current_object() self.assertEqual(inst.kwargs['is_master'], False) self.assertEqual(inst.kwargs['service_name'], 'myslave') self.assertEqual(inst.kwargs['connection_kwargs']['db'], 3) self.assertEqual( inst.kwargs['connection_kwargs']['decode_responses'], True)
def test_port(self): self.assertEqual( SentinelExtension._config_from_variables( {'PORT': 7379}, redis.StrictRedis)['port'], 7379)
# Python 2.x from urlparse import urlparse from urllib import quote except ImportError: # Python 3.x from urllib.parse import urlparse, quote from collections import OrderedDict from flask import Flask, render_template, request, jsonify, abort from flask import current_app as capp from flask_redis import FlaskRedis from flask_redis_sentinel import SentinelExtension from flask_bootstrap import Bootstrap import redis_sentinel_url import redis redis_sentinel = SentinelExtension() sentinel = redis_sentinel.sentinel app = Flask(__name__) # Let Redis decode responses from bytes to strings app.config['REDIS_DECODE_RESPONSES'] = True def _get_service(services): for service_name, instances in services.items(): for instance in instances: if 'redis' in instance.get('tags', []): return instance
def test_host_file_url(self): self.assertEqual( SentinelExtension._config_from_variables( {'HOST': 'file:///path/to/socket'}, redis.StrictRedis), {'unix_socket_path': 'file:///path/to/socket'})
def test_host(self): self.assertEqual( SentinelExtension._config_from_variables({'HOST': 'otherhost'}, redis.StrictRedis), {'host': 'otherhost'})
def test_multiple_prefix_registration(self): sentinel = SentinelExtension() sentinel2 = SentinelExtension() sentinel.init_app(self.app) sentinel2.init_app(self.app, config_prefix='ANOTHER_REDIS')
def test_db(self): self.assertEqual( SentinelExtension._config_from_variables({'DB': 2}, redis.StrictRedis), {'db': 2})
def test_empty_settings(self): self.assertEqual(SentinelExtension._config_from_variables({}, redis.StrictRedis), {})
def init_app(self, app, **kwargs): self._sentinel = SentinelExtension(app)
def test_host(self): self.assertEqual(SentinelExtension._config_from_variables({'HOST': 'otherhost'}, redis.StrictRedis), {'host': 'otherhost'})
def test_port(self): self.assertEqual(SentinelExtension._config_from_variables({'PORT': 7379}, redis.StrictRedis)['port'], 7379)
def test_unsupported_url_scheme(self): sentinel = SentinelExtension(client_class=FakeRedis, sentinel_class=FakeSentinel) self.app.config['REDIS_URL'] = 'redis+something://hostname:7001/myslave/3?slave=true' with self.assertRaisesRegexp(ValueError, r'Unsupported redis URL scheme: redis\+something'): sentinel.init_app(self.app)
def test_empty_settings(self): self.assertEqual( SentinelExtension._config_from_variables({}, redis.StrictRedis), {})
def test_host_file_url(self): self.assertEqual(SentinelExtension._config_from_variables({'HOST': 'file:///path/to/socket'}, redis.StrictRedis), {'unix_socket_path': 'file:///path/to/socket'})
def test_db(self): self.assertEqual(SentinelExtension._config_from_variables({'DB': 2}, redis.StrictRedis), {'db': 2})