def cmd_ping(self, command, args, now, connection): if len(args) == 0: return RedisString('PONG') elif len(args) == 1: return RedisString(args[0]) else: raise WrongNumberOfArgumentsError(command)
def test_ping_one_argument_echoes_back(self, command_processor, connection): result = command_processor.process_command( [b'ping', b'echo this please'], connection=connection, ) assert result == RedisString('echo this please')
def cmd_select(self, command, args, now, connection): if len(args) != 1: raise WrongNumberOfArgumentsError(command) db_index = ensure_int(args[0]) if db_index < 0 or db_index > len(self.storage.dbs): raise RedisError('invalid DB index') connection.db_index = db_index return RedisString(b'OK')
def cmd_mget(self, command, args, now, connection): if len(args) == 0: raise WrongNumberOfArgumentsError(command) db = self._get_db(connection) result = [db.get_active_key(key, now) for key in args] return RedisArray([ RedisString(key) if key is not None else RedisNullBulkString() for key in result ])
def cmd_keys(self, command, args, now, connection): if len(args) != 1: raise WrongNumberOfArgumentsError(command) db = self._get_db(connection) result = [] pattern_re = build_re_from_pattern(args[0]) logger.info('Will filter keys by pattern: re=%s', pattern_re.pattern) for key in db.kv.keys(): if not pattern_re.fullmatch(key.decode()): continue if not db.is_key_active(key, now): continue result.append(key) return RedisArray([RedisString(key) for key in result])
def test_keys_return_matching_keys(self, storage, command_processor, connection, args, expected_result): now = datetime.utcnow() storage.dbs[0].kv = { b'foo': b'1', b'foo1': b'1', b'foo2': b'1', b'with spaces in ': b'1', b'expired': b'1', b'not-yet-expired': b'1', } storage.dbs[3].kv = {b'foo3': b'1'} storage.dbs[0].set_expiry_for_key(b'expired', 0, now) storage.dbs[0].set_expiry_for_key(b'not-yet-expired', 2000, now) result = command_processor.process_command([b'keys'] + args, connection=connection) assert result == RedisArray([RedisString(r) for r in expected_result]), result
def cmd_mset(self, command, args, now, connection): if len(args) < 2: raise WrongNumberOfArgumentsError(command) if len(args) % 2 != 0: raise WrongNumberOfArgumentsError(command) db = self._get_db(connection) i = 0 while i < len(args): key = args[i] value = args[i + 1] logger.info('Setting key: db=%s, key=%s, value=%s', db.index, key, value) db.kv[key] = value db.remove_key_from_expiration(key) i += 2 return RedisString(b'OK')
def test_ping_no_arguments_returns_pong(self, command_processor, connection): result = command_processor.process_command([b'ping'], connection=connection) assert result == RedisString('PONG')
def test_redis_string(data, expected_resp): r = RedisString(data) assert r.to_resp() == expected_resp, r.to_resp()
@pytest.mark.parametrize('data,expected_resp', [ (0, b':0\r\n'), (3, b':3\r\n'), (-3, b':-3\r\n'), (2**32, b':4294967296\r\n'), ]) def test_redis_integer(data, expected_resp): r = RedisInteger(data) assert r.to_resp() == expected_resp, r.to_resp() @pytest.mark.parametrize('items,expected_resp', [ ([], b'*0\r\n'), ([RedisInteger(5)], b'*1\r\n:5\r\n'), ([RedisString(b'foo')], b'*1\r\n+foo\r\n'), ([RedisString(b'foo'), RedisBulkString(b'bar') ], b'*2\r\n+foo\r\n$3\r\nbar\r\n'), ]) def test_redis_array(items, expected_resp): r = RedisArray(items) assert r.to_resp() == expected_resp, r.to_resp() @pytest.mark.parametrize('items,expected_resp', [ ([], b''), ([RedisInteger(5)], b':5\r\n'), ([RedisString(b'foo')], b'+foo\r\n'), ([RedisString(b'foo'), RedisBulkString(b'bar')], b'+foo\r\n$3\r\nbar\r\n'), ]) def test_redis_multiple_responses(items, expected_resp):
def cmd_set(self, command, args, now, connection): if len(args) < 2: raise WrongNumberOfArgumentsError(command) db = self._get_db(connection) key = args[0] value = args[1] nx = False xx = False ex = None px = None if len(args) > 2: i = 2 while i < len(args): if args[i] == b'nx': nx = True elif args[i] == b'xx': xx = True elif args[i] == b'ex': if i >= len(args): raise CommandSyntaxError() ex = ensure_int(args[i + 1]) i += 1 elif args[i] == b'px': if i >= len(args): raise CommandSyntaxError() px = ensure_int(args[i + 1]) i += 1 i += 1 if xx and nx: raise CommandSyntaxError() if ex and px: raise CommandSyntaxError() key_exists = db.get_active_key(key, now) is not None if key_exists and nx: logger.info( 'Not setting key, exists and nx is specified: db=%s, key=%s', db.index, key) return RedisNullBulkString() if not key_exists and xx: logger.info( 'Not setting key, doesnt exist and xx is specified: db=%s, key=%s', db.index, key, ) return RedisNullBulkString() logger.info('Setting key: db=%s, key=%s, value=%s', db.index, key, value) db.kv[key] = value if px: db.set_expiry_for_key(key, px, now) elif ex: db.set_expiry_for_key(key, ex * 1000, now) else: db.remove_key_from_expiration(key) return RedisString(b'OK')