Beispiel #1
0
class RedisStoreTestCase(TestCase):
    def setUp(self):
        server = FakeServer()
        server.connected = True
        self.store = RedisStore(prefix='prefix:',
                                redis_class=FakeStrictRedis,
                                server=server)
        self.redis = FakeStrictRedis(server=server)

        super(RedisStoreTestCase, self).setUp()

    def tearDown(self):
        flexmock_teardown()
        self.redis.flushdb()

    def test_get_returns_null_when_not_found(self):
        self.assertIsNone(self.store.get('foo'))

    def test_redis_value_is_returned(self):
        self.redis.set('prefix:foo', self.store.serialize('bar'))

        self.assertEqual('bar', self.store.get('foo'))

    def test_redis_value_is_returned_for_numerics(self):
        self.redis.set('prefix:foo', self.store.serialize(1))

        self.assertEqual(1, self.store.get('foo'))

    def test_put_value_into_redis(self):
        self.store.put('foo', 'bar', 60)

        self.assertEqual(self.store.serialize('bar'),
                         self.redis.get('prefix:foo'))
        self.assertEqual(
            60., round(math.ceil(float(self.redis.ttl('prefix:foo')) / 60)))

    def test_put_numeric_value_into_redis(self):
        self.store.put('foo', 1, 60)

        self.assertEqual(self.store.serialize(1), self.redis.get('prefix:foo'))
        self.assertEqual(
            60., round(math.ceil(float(self.redis.ttl('prefix:foo')) / 60)))

    def test_increment(self):
        self.redis.set('prefix:foo', 1)

        self.store.increment('foo', 2)
        self.assertEqual(3, int(self.redis.get('prefix:foo')))

    def test_decrement(self):
        self.redis.set('prefix:foo', 3)

        self.store.decrement('foo', 2)
        self.assertEqual(1, int(self.redis.get('prefix:foo')))

    def test_forever(self):
        self.store.forever('foo', 'bar')

        self.assertEqual(self.store.serialize('bar'),
                         self.redis.get('prefix:foo'))
        assert self.redis.ttl('prefix:foo') == -1

    def test_forget(self):
        self.redis.set('prefix:foo', 'bar')

        self.store.forget('foo')

        self.assertFalse(self.redis.exists('prefix:foo'))
Beispiel #2
0
class CacheRedis(object):
    redis = None

    def __init__(self, env, host: str, port: int = 6379, db: int = 0):
        if env.config.get(ConfigKeys.TESTING, False) or host == 'mock':
            from fakeredis import FakeStrictRedis as Redis
        else:
            from redis import Redis

        self.redis = Redis(host=host, port=port, db=db)
        self.cache = MemoryCache()

    def _flushall(self):
        self.redis.flushdb()
        self.cache.flushall()

    def _set(self, key, val, ttl=None):
        if ttl is None:
            self.cache.set(key, val)
        else:
            self.cache.set(key, val, ttl=ttl)

    def _get(self, key):
        return self.cache.get(key)

    def _del(self, key):
        self.cache.delete(key)

    def set_is_room_ephemeral(self, room_id: str, is_ephemeral: bool) -> None:
        redis_key = RedisKeys.non_ephemeral_rooms()
        cache_key = '%s-%s' % (redis_key, room_id)
        self.cache.set(cache_key, is_ephemeral)

    def is_room_ephemeral(self, room_id: str) -> bool:
        redis_key = RedisKeys.non_ephemeral_rooms()
        cache_key = '%s-%s' % (redis_key, room_id)
        return self.cache.get(cache_key)

    def get_black_list(self) -> set:
        cache_key = RedisKeys.black_list()
        value = self.cache.get(cache_key)
        if value is not None:
            return value

        values = self.redis.smembers(cache_key)
        if value is not None:
            decoded = {str(v, 'utf-8') for v in values}
            self.cache.set(cache_key, decoded, ttl=60 * 10)
            return decoded
        return None

    def set_black_list(self, the_list: set) -> None:
        cache_key = RedisKeys.black_list()
        self.cache.set(cache_key, the_list, ttl=60 * 10)
        self.redis.delete(cache_key)
        self.redis.sadd(cache_key, *the_list)

    def remove_from_black_list(self, word: str) -> None:
        cache_key = RedisKeys.black_list()
        the_cached_list = self.cache.get(cache_key)
        the_cached_list.remove(word)
        self.cache.set(cache_key, the_cached_list, ttl=60 * 10)
        self.redis.srem(cache_key, word)

    def add_to_black_list(self, word: str) -> None:
        cache_key = RedisKeys.black_list()
        the_cached_list = self.cache.get(cache_key)
        the_cached_list.add(word)
        self.cache.set(cache_key, the_cached_list, ttl=60 * 10)
        self.redis.sadd(cache_key, word)

    def _set_ban_timestamp(self, key: str, user_id: str,
                           timestamp: str) -> None:
        cache_key = '%s-%s' % (key, user_id)
        self.cache.set(cache_key, timestamp)
        self.redis.hset(key, user_id, timestamp)

    def set_global_ban_timestamp(self, user_id: str, duration: str,
                                 timestamp: str, username: str) -> None:
        key = RedisKeys.banned_users()
        self._set_ban_timestamp(key, user_id,
                                '%s|%s|%s' % (duration, timestamp, username))

    def set_channel_ban_timestamp(self, channel_id: str, user_id: str,
                                  duration: str, timestamp: str,
                                  username: str) -> None:
        key = RedisKeys.banned_users_channel(channel_id)
        self._set_ban_timestamp(key, user_id,
                                '%s|%s|%s' % (duration, timestamp, username))

    def set_room_ban_timestamp(self, room_id: str, user_id: str, duration: str,
                               timestamp: str, username: str) -> None:
        key = RedisKeys.banned_users(room_id)
        self._set_ban_timestamp(key, user_id,
                                '%s|%s|%s' % (duration, timestamp, username))

    def get_user_roles(self, user_id: str) -> None:
        key = RedisKeys.user_roles()
        cache_key = '%s-%s' % (key, user_id)
        value = self.cache.get(cache_key)
        if value is not None:
            return value

        value = self.redis.hget(key, user_id)
        if value is not None:
            value = json.loads(str(value, 'utf-8'))
            self.cache.set(cache_key, value, ttl=10)
        return value

    def set_user_roles(self, user_id: str, roles: dict) -> None:
        key = RedisKeys.user_roles()
        cache_key = '%s-%s' % (key, user_id)
        self.redis.hset(key, user_id, json.dumps(roles))
        self.cache.set(cache_key, roles, ttl=10)

    def reset_user_roles(self, user_id: str) -> None:
        key = RedisKeys.user_roles()
        cache_key = '%s-%s' % (key, user_id)
        self.redis.hdel(key, user_id)
        self.cache.delete(cache_key)

    def get_admin_room(self) -> str:
        key = RedisKeys.admin_room()
        value = self.cache.get(key)
        if value is not None:
            return value

        room_id = self.redis.get(key)
        if room_id is None or len(str(room_id, 'utf-8').strip()) == 0:
            return None

        room_id = str(room_id, 'utf-8')
        self.cache.set(key, room_id, ttl=EIGHT_HOURS_IN_SECONDS)
        return room_id

    def set_admin_room(self, room_id: str) -> None:
        key = RedisKeys.admin_room()
        self.redis.set(key, room_id)
        self.cache.set(key, room_id, ttl=EIGHT_HOURS_IN_SECONDS)

    def _get_ban_timestamp(self, key: str, user_id: str) -> str:
        cache_key = '%s-%s' % (key, user_id)
        value = self.cache.get(cache_key)
        if value is not None:
            return value.split('|', 2)

        ban_info = self.redis.hget(key, user_id)
        if ban_info is None:
            return None, None, None

        ban_info = str(ban_info, 'utf-8')
        return ban_info.split('|', 2)

    def get_global_ban_timestamp(self, user_id: str) -> str:
        key = RedisKeys.banned_users()
        return self._get_ban_timestamp(key, user_id)

    def get_channel_ban_timestamp(self, channel_id: str, user_id: str) -> str:
        key = RedisKeys.banned_users_channel(channel_id)
        return self._get_ban_timestamp(key, user_id)

    def get_room_ban_timestamp(self, room_id: str, user_id: str) -> str:
        key = RedisKeys.banned_users(room_id)
        return self._get_ban_timestamp(key, user_id)

    def get_room_id_for_name(self, channel_id: str, room_name: str) -> str:
        key = RedisKeys.room_id_for_name(channel_id)
        cache_key = '%s-%s' % (key, room_name)
        value = self.cache.get(cache_key)
        if value is not None:
            return value

        value = self.redis.hget(key, room_name)
        if value is None:
            return None

        value = str(value, 'utf-8')
        self.cache.set(cache_key, value)
        return value

    def set_room_id_for_name(self, channel_id, room_name, room_id):
        key = RedisKeys.room_id_for_name(channel_id)
        cache_key = '%s-%s' % (key, room_name)
        self.cache.set(cache_key, room_id)
        self.redis.hset(key, room_name, room_id)

    def get_user_name(self, user_id: str) -> str:
        key = RedisKeys.user_names()
        cache_key = '%s-%s' % (key, user_id)
        value = self.cache.get(cache_key)
        if value is not None:
            return value

        user_name = self.redis.hget(key, user_id)
        if user_name is not None:
            user_name = str(user_name, 'utf-8')
            self.cache.set(cache_key, user_name)
            return user_name
        return user_name

    def set_user_name(self, user_id: str, user_name: str):
        key = RedisKeys.user_names()
        cache_key = '%s-%s' % (key, user_id)
        self.redis.hset(key, user_id, user_name)
        self.cache.set(cache_key, user_name)

    def get_room_exists(self, channel_id, room_id):
        key = RedisKeys.rooms(channel_id)
        cache_key = '%s-%s' % (key, room_id)
        value = self.cache.get(cache_key)
        if value is not None:
            return True

        exists = self.redis.hexists(key, room_id)
        if exists == 1:
            self.cache.set(cache_key, True)
            return True
        return None

    def remove_room_exists(self, channel_id, room_id):
        key = RedisKeys.rooms(channel_id)
        cache_key = '%s-%s' % (key, room_id)
        self.cache.set(cache_key, None)
        self.redis.hdel(key, room_id)

    def set_room_exists(self, channel_id, room_id, room_name):
        key = RedisKeys.rooms(channel_id)
        cache_key = '%s-%s' % (key, room_id)
        self.cache.set(cache_key, room_name)
        self.redis.hset(key, room_id, room_name)

    def set_channel_exists(self, channel_id: str) -> None:
        key = RedisKeys.channel_exists()
        cache_key = '%s-%s' % (key, channel_id)
        self.redis.hset(key, channel_id, True)
        self.cache.set(cache_key, True)

    def set_channel_for_room(self, channel_id: str, room_id: str) -> None:
        key = RedisKeys.channel_for_rooms()
        cache_key = '%s-%s' % (key, room_id)
        self.redis.hset(key, room_id, channel_id)
        self.cache.set(cache_key, channel_id)

    def get_channel_exists(self, channel_id):
        key = RedisKeys.channel_exists()
        cache_key = '%s-%s' % (key, channel_id)
        value = self.cache.get(cache_key)
        if value is not None:
            return True

        value = self.redis.hget(key, channel_id)
        if value is None:
            return None

        self.cache.set(cache_key, True)
        return True

    def set_channel_name(self, channel_id: str, channel_name: str) -> None:
        key = RedisKeys.channels()
        cache_key = '%s-name-%s' % (key, channel_id)
        self.cache.set(cache_key, channel_name)
        self.redis.hset(key, channel_id, channel_name)

    def get_channel_name(self, channel_id: str) -> str:
        key = RedisKeys.channels()
        cache_key = '%s-name-%s' % (key, channel_id)
        value = self.cache.get(cache_key)
        if value is not None:
            return value

        value = self.redis.hget(key, channel_id)
        if value is None:
            return None

        value = str(value, 'utf-8')
        self.cache.set(cache_key, value)
        return value

    def get_room_name(self, room_id: str) -> str:
        key = RedisKeys.room_name_for_id()
        cache_key = '%s-%s-name' % (key, room_id)
        value = self.cache.get(cache_key)
        if value is not None:
            return value

        value = self.redis.hget(key, room_id)
        if value is None:
            return None

        value = str(value, 'utf-8')
        self.cache.set(cache_key, value)
        return value

    def get_channel_for_room(self, room_id):
        key = RedisKeys.channel_for_rooms()
        cache_key = '%s-%s' % (key, room_id)
        value = self.cache.get(key)
        if value is not None:
            return value

        channel_id = self.redis.hget(key, room_id)
        if channel_id is None:
            return None

        channel_id = str(channel_id, 'utf-8')
        self.cache.set(cache_key, channel_id)
        return channel_id

    def get_user_status(self, user_id: str):
        key = RedisKeys.user_status(user_id)
        value = self.cache.get(key)
        if value is not None:
            return value

        status = self.redis.get(key)
        if status is None or status == '':
            return None

        user_status = str(status, 'utf-8')
        self.cache.set(key, user_status)
        return user_status

    def set_user_status(self, user_id: str, status: str) -> None:
        key = RedisKeys.user_status(user_id)
        self.redis.set(key, status)
        self.cache.set(key, status)

    def user_check_status(self, user_id, other_status):
        return self.get_user_status(user_id) == other_status

    def user_is_offline(self, user_id):
        return self.user_check_status(user_id, UserKeys.STATUS_UNAVAILABLE)

    def user_is_online(self, user_id):
        return self.user_check_status(user_id, UserKeys.STATUS_AVAILABLE)

    def user_is_invisible(self, user_id):
        return self.user_check_status(user_id, UserKeys.STATUS_INVISIBLE)

    def set_user_offline(self, user_id: str) -> None:
        self.cache.set(RedisKeys.user_status(user_id),
                       UserKeys.STATUS_UNAVAILABLE)
        self.redis.setbit(RedisKeys.online_bitmap(), int(user_id), 0)
        self.redis.srem(RedisKeys.online_set(), int(user_id))
        self.redis.srem(RedisKeys.users_multi_cast(), user_id)
        self.redis.set(RedisKeys.user_status(user_id),
                       UserKeys.STATUS_UNAVAILABLE)

    def set_user_online(self, user_id: str) -> None:
        self.cache.set(RedisKeys.user_status(user_id),
                       UserKeys.STATUS_AVAILABLE)
        self.redis.setbit(RedisKeys.online_bitmap(), int(user_id), 1)
        self.redis.sadd(RedisKeys.online_set(), int(user_id))
        self.redis.sadd(RedisKeys.users_multi_cast(), user_id)
        self.redis.set(RedisKeys.user_status(user_id),
                       UserKeys.STATUS_AVAILABLE)

    def set_user_invisible(self, user_id: str) -> None:
        self.cache.set(RedisKeys.user_status(user_id),
                       UserKeys.STATUS_INVISIBLE)
        self.redis.setbit(RedisKeys.online_bitmap(), int(user_id), 0)
        self.redis.srem(RedisKeys.online_set(), int(user_id))
        self.redis.sadd(RedisKeys.users_multi_cast(), user_id)
        self.redis.set(RedisKeys.user_status(user_id),
                       UserKeys.STATUS_INVISIBLE)
Beispiel #3
0
class RedisStoreTestCase(TestCase):

    def setUp(self):
        self.redis = FakeStrictRedis()

        super(RedisStoreTestCase, self).setUp()

    def tearDown(self):
        flexmock_teardown()
        self.redis.flushdb()

    def test_get_returns_null_when_not_found(self):
        store = self.get_store()

        self.assertIsNone(store.get('foo'))

    def test_redis_value_is_returned(self):
        store = self.get_store()
        self.redis.set('prefix:foo', store.serialize('bar'))

        self.assertEqual('bar', store.get('foo'))

    def test_redis_value_is_returned_for_numerics(self):
        store = self.get_store()
        self.redis.set('prefix:foo', store.serialize(1))

        self.assertEqual(1, store.get('foo'))

    def test_put_value_into_redis(self):
        store = self.get_store()
        store.put('foo', 'bar', 60)

        self.assertEqual(store.serialize('bar'), self.redis.get('prefix:foo'))
        self.assertEqual(60., round(math.ceil(float(self.redis.ttl('prefix:foo')) / 60)))

    def test_put_numeric_value_into_redis(self):
        store = self.get_store()
        store.put('foo', 1, 60)

        self.assertEqual(store.serialize(1), self.redis.get('prefix:foo'))
        self.assertEqual(60., round(math.ceil(float(self.redis.ttl('prefix:foo')) / 60)))

    def test_increment(self):
        store = self.get_store()
        self.redis.set('prefix:foo', 1)

        store.increment('foo', 2)
        self.assertEqual(3, int(self.redis.get('prefix:foo')))

    def test_decrement(self):
        store = self.get_store()
        self.redis.set('prefix:foo', 3)

        store.decrement('foo', 2)
        self.assertEqual(1, int(self.redis.get('prefix:foo')))

    def test_forever(self):
        store = self.get_store()

        store.forever('foo', 'bar')

        self.assertEqual(store.serialize('bar'), self.redis.get('prefix:foo'))
        self.assertIsNone(self.redis.ttl('prefix:foo'))

    def test_forget(self):
        store = self.get_store()
        self.redis.set('prefix:foo', 'bar')

        store.forget('foo')

        self.assertFalse(self.redis.exists('prefix:foo'))

    def get_store(self):
        return RedisStore(prefix='prefix:', redis_class=FakeStrictRedis)