def _test_positive(self, data, expected): """ Template function for simple positive tests :param data: :param expected: :return: """ parser = RedisDataParser() d = parser.getDeferred() d.addCallback(self.assertEqual, expected) parser.parse(data) return d
def test_bulk_string_failure(self): """ Test failure when actual string size differs from given size :return: """ parser = RedisDataParser() data = b'$13\r\nHello, world!abc\r\n' self.assertRaises(ParserBulkStringWrongSize, parser.parse, data) parser = RedisDataParser() data = b'$13\r\nHello, wor\r\n' self.assertEqual(b'Hello, wor\r\n', parser.parse(data))
def test_wrong_first_byte(self): """ Test failure when wrong first byte in data is given :return: """ parser = RedisDataParser() data = b'!a\r\n' self.assertRaises(ParserFirstByteNotRecognized, parser.parse, data) #self.assertFailure(d, ParserFirstByteNotRecognized) #parser.parse(data) parser = RedisDataParser() # Wrong first byte in one element of the array data = b'*3\r\n+OK\r\n!a\r\n' self.assertRaises(ParserFirstByteNotRecognized, parser.parse, data)
def test_int_partial(self): """ Test correct parsing of an integer, when data is given partially :return: """ parser = RedisDataParser() d = parser.getDeferred() d.addCallback(self.assertEqual, 123) data = b':123\r\n' data_buffer = b'' for i in range(len(data)): data_buffer += data[i:i + 1] data_buffer = parser.parse(data_buffer) return d
def test_simple_string_partial(self): """ Test correct parsing of a simple string, when data is given partially :return: """ parser = RedisDataParser() d = parser.getDeferred() d.addCallback(self.assertEqual, 'Hello, world!') data = b'+Hello, world!\r\n' data_buffer = b'' for i in range(len(data)): data_buffer += data[i:i + 1] data_buffer = parser.parse(data_buffer) return d
def test_array_partial(self): """ Test correct parsing of an array, when data is given partially :return: """ parser = RedisDataParser() d = parser.getDeferred() d.addCallback(self.assertEqual, ['OK', 'Hi', 42]) data = b'*3\r\n+OK\r\n$2\r\nHi\r\n:42\r\n' data_buffer = b'' for i in range(len(data)): data_buffer += data[i:i + 1] data_buffer = parser.parse(data_buffer) return d
def _parseBuffer(self): """ Parse data buffer with RedisDataParser class. When some value is completely parsed, _valueParsed is called with the value as argument. :return: """ try: self._data_buffer = self._parser.parse(self._data_buffer) except RedisDataParserException as err: print(err) self._data_buffer = b'' self._parser = RedisDataParser() self._parser_defer = self._parser.getDeferred() self._parser_defer.addCallback(self._valueParsed)
def test_error_msg(self): """ Test correct parsing of an error message :return: """ parser = RedisDataParser() d = parser.getDeferred() data = b'-Some error\r\n' def compareError(error): self.assertEqual(RedisProtocolError, type(error)) self.assertEqual('Some error', error.msg) d.addCallback(compareError) parser.parse(data) return d
def test_int_failure(self): """ Test failure when given not int after ':' first byte :return: """ parser = RedisDataParser() data = b':abc\r\n' self.assertRaises(ParserValueError, parser.parse, data)
def test_bulk_string(self): """ Test correct parsing of a bulk string :return: """ defers = [] data = b'$13\r\nHello, world!\r\n' defers.append(self._test_positive(data, 'Hello, world!')) parser = RedisDataParser() d = parser.getDeferred() defers.append(d) data = b'$13\r\nHello, world!\r\nabc' d.addCallback(self.assertEqual, 'Hello, world!') data = parser.parse(data) self.assertEqual(b'abc', data) return defers
class RedisProtocol(Protocol): """ Class that implements Redis protocol """ def __init__(self): self._data_buffer = b'' self._parser = RedisDataParser() self._parser_defer = self._parser.getDeferred() self._parser_defer.addCallback(self._valueParsed) def dataReceived(self, data): self._data_buffer += data self._parseBuffer() def sendData(self, data: bytes): self.transport.write(data) def _parseBuffer(self): """ Parse data buffer with RedisDataParser class. When some value is completely parsed, _valueParsed is called with the value as argument. :return: """ try: self._data_buffer = self._parser.parse(self._data_buffer) except RedisDataParserException as err: print(err) self._data_buffer = b'' self._parser = RedisDataParser() self._parser_defer = self._parser.getDeferred() self._parser_defer.addCallback(self._valueParsed) def _valueParsed(self, value): """ callback for parsing a value. When inheriting, call it from super or get new deferred yourself :return: """ self._parser_defer = self._parser.getDeferred() self._parser_defer.addCallback(self._valueParsed)
def __init__(self): self._data_buffer = b'' self._parser = RedisDataParser() self._parser_defer = self._parser.getDeferred() self._parser_defer.addCallback(self._valueParsed)