def test_parsing_without_enough_data(self): # Test that we return with nothing to do... received a partial packet not_enough_data_command_buffer = struct.pack('!4s', protocol.MAGIC_RES_STRING) cmd_type, cmd_args, cmd_len = protocol.parse_binary_command(not_enough_data_command_buffer) self.assertEquals(cmd_type, None) self.assertEquals(cmd_args, None) self.assertEquals(cmd_len, 0) # Test that we return with nothing to do... received a partial packet (expected binary payload of size 4, got 0) not_enough_data_command_buffer = struct.pack('!4sII', protocol.MAGIC_RES_STRING, protocol.GEARMAN_COMMAND_ECHO_RES, 4) cmd_type, cmd_args, cmd_len = protocol.parse_binary_command(not_enough_data_command_buffer) self.assertEquals(cmd_type, None) self.assertEquals(cmd_args, None) self.assertEquals(cmd_len, 0)
def test_parsing_no_args(self): noop_command_buffer = struct.pack('!4sII', protocol.MAGIC_RES_STRING, protocol.GEARMAN_COMMAND_NOOP, 0) noop_command_buffer = array.array("c", noop_command_buffer) cmd_type, cmd_args, cmd_len = protocol.parse_binary_command(noop_command_buffer) self.assertEquals(cmd_type, protocol.GEARMAN_COMMAND_NOOP) self.assertEquals(cmd_args, dict()) self.assertEquals(cmd_len, len(noop_command_buffer))
def test_parsing_no_args(self): noop_command_buffer = struct.pack('!4sII', protocol.MAGIC_RES_STRING.encode(), protocol.GEARMAN_COMMAND_NOOP, 0) noop_command_buffer = array.array("b", noop_command_buffer) cmd_type, cmd_args, cmd_len = protocol.parse_binary_command(noop_command_buffer) self.assertEquals(cmd_type, protocol.GEARMAN_COMMAND_NOOP) self.assertEquals(cmd_args, dict()) self.assertEquals(cmd_len, len(noop_command_buffer))
def test_parsing_no_args(self): noop_command_buffer = struct.pack('!4sII', protocol.MAGIC_RES_STRING, protocol.GEARMAN_COMMAND_NOOP, 0) noop_command_buffer = array.array("b", noop_command_buffer) cmd_type, cmd_args, cmd_len = protocol.parse_binary_command(noop_command_buffer) assert cmd_type == protocol.GEARMAN_COMMAND_NOOP assert cmd_args == dict() assert cmd_len == len(noop_command_buffer)
def test_parsing_single_arg(self): echoed_string = 'abcd' echo_command_buffer = struct.pack('!4sII4s', protocol.MAGIC_RES_STRING, protocol.GEARMAN_COMMAND_ECHO_RES, 4, echoed_string) cmd_type, cmd_args, cmd_len = protocol.parse_binary_command(echo_command_buffer) self.assertEquals(cmd_type, protocol.GEARMAN_COMMAND_ECHO_RES) self.assertEquals(cmd_args, dict(data=echoed_string)) self.assertEquals(cmd_len, len(echo_command_buffer))
def test_parsing_request(self): # Test parsing a request for a job (server side parsing) grab_job_command_buffer = struct.pack('!4sII', protocol.MAGIC_REQ_STRING, protocol.GEARMAN_COMMAND_GRAB_JOB_UNIQ, 0) cmd_type, cmd_args, cmd_len = protocol.parse_binary_command(grab_job_command_buffer, is_response=False) self.assertEquals(cmd_type, protocol.GEARMAN_COMMAND_GRAB_JOB_UNIQ) self.assertEquals(cmd_args, dict()) self.assertEquals(cmd_len, len(grab_job_command_buffer))
def test_parsing_single_arg(self): echoed_string = b'abcd' echo_command_buffer = struct.pack('!4sII4s', protocol.MAGIC_RES_STRING, protocol.GEARMAN_COMMAND_ECHO_RES, 4, echoed_string) echo_command_buffer = array.array("b", echo_command_buffer) cmd_type, cmd_args, cmd_len = protocol.parse_binary_command(echo_command_buffer) assert cmd_type == protocol.GEARMAN_COMMAND_ECHO_RES assert cmd_args == {u"data": echoed_string} assert cmd_len == len(echo_command_buffer)
def test_parsing_request(self): # Test parsing a request for a job (server side parsing) grab_job_command_buffer = struct.pack('!4sII', protocol.MAGIC_REQ_STRING, protocol.GEARMAN_COMMAND_GRAB_JOB_UNIQ, 0) grab_job_command_buffer = array.array("b", grab_job_command_buffer) cmd_type, cmd_args, cmd_len = protocol.parse_binary_command(grab_job_command_buffer, is_response=False) assert cmd_type == protocol.GEARMAN_COMMAND_GRAB_JOB_UNIQ assert cmd_args == {} assert cmd_len == len(grab_job_command_buffer)
def test_parsing_single_arg_with_extra_data(self): echoed_string = 'abcd' excess_bytes = 5 excess_data = echoed_string + (protocol.NULL_CHAR * excess_bytes) excess_echo_command_buffer = struct.pack('!4sII9s', protocol.MAGIC_RES_STRING, protocol.GEARMAN_COMMAND_ECHO_RES, 4, excess_data) cmd_type, cmd_args, cmd_len = protocol.parse_binary_command(excess_echo_command_buffer) self.assertEquals(cmd_type, protocol.GEARMAN_COMMAND_ECHO_RES) self.assertEquals(cmd_args, dict(data=echoed_string)) self.assertEquals(cmd_len, len(excess_echo_command_buffer) - excess_bytes)
def test_parsing_multiple_args(self): # Tests ordered argument processing and proper NULL_CHAR splitting expected_data = protocol.NULL_CHAR * 4 binary_payload = protocol.NULL_CHAR.join(['test', 'function', 'identifier', expected_data]) payload_size = len(binary_payload) uniq_command_buffer = struct.pack('!4sII%ds' % payload_size, protocol.MAGIC_RES_STRING, protocol.GEARMAN_COMMAND_JOB_ASSIGN_UNIQ, payload_size, binary_payload) cmd_type, cmd_args, cmd_len = protocol.parse_binary_command(uniq_command_buffer) self.assertEquals(cmd_type, protocol.GEARMAN_COMMAND_JOB_ASSIGN_UNIQ) self.assertEquals(cmd_args, dict(job_handle='test', task='function', unique='identifier', data=expected_data)) self.assertEquals(cmd_len, len(uniq_command_buffer))
def test_parsing_single_arg_with_extra_data(self): echoed_string = b'abcd' excess_bytes = 5 excess_data = echoed_string + (protocol.NULL_CHAR * excess_bytes) excess_echo_command_buffer = struct.pack('!4sII9s', protocol.MAGIC_RES_STRING, protocol.GEARMAN_COMMAND_ECHO_RES, 4, excess_data) excess_echo_command_buffer = array.array("b", excess_echo_command_buffer) cmd_type, cmd_args, cmd_len = protocol.parse_binary_command(excess_echo_command_buffer) assert cmd_type == protocol.GEARMAN_COMMAND_ECHO_RES assert cmd_args == dict(data=echoed_string) assert cmd_len == len(excess_echo_command_buffer) - excess_bytes
def test_parsing_multiple_args(self): # Tests ordered argument processing and proper NULL_CHAR splitting expected_data = protocol.NULL_CHAR * 4 binary_payload = protocol.NULL_CHAR.join([b'test', b'function', b'identifier', expected_data]) payload_size = len(binary_payload) uniq_command_buffer = struct.pack('!4sII%ds' % payload_size, protocol.MAGIC_RES_STRING, protocol.GEARMAN_COMMAND_JOB_ASSIGN_UNIQ, payload_size, binary_payload) uniq_command_buffer = array.array("b", uniq_command_buffer) cmd_type, cmd_args, cmd_len = protocol.parse_binary_command(uniq_command_buffer) assert cmd_type == protocol.GEARMAN_COMMAND_JOB_ASSIGN_UNIQ assert cmd_args == { u"job_handle": b"test", u"task": b"function", u"unique": b"identifier", u"data": expected_data } assert cmd_len == len(uniq_command_buffer)
def _unpack_command(self, given_buffer): """Conditionally unpack a binary command or a text based server command""" if not given_buffer: cmd_type, cmd_args, cmd_len = None, None, 0 elif given_buffer[0] == protocol.NULL_CHAR: # We'll be expecting a response if we know we're a client side command cmd_type, cmd_args, cmd_len = protocol.parse_binary_command( given_buffer) else: cmd_type, cmd_args, cmd_len = protocol.parse_text_command( given_buffer) log.msg("%s - recv - %s - %r" % ( id(self), protocol.get_command_name(cmd_type), cmd_args), loglevel=logging.DEBUG) return cmd_type, cmd_args, cmd_len
def _unpack_command(self, given_buffer): """Conditionally unpack a binary command or a text based server command""" assert self._is_client_side is not None, "Ambiguous connection state" if not given_buffer: cmd_type = None cmd_args = None cmd_len = 0 elif given_buffer[0] == NULL_CHAR: # We'll be expecting a response if we know we're a client side command is_response = bool(self._is_client_side) cmd_type, cmd_args, cmd_len = parse_binary_command(given_buffer, is_response=is_response) else: cmd_type, cmd_args, cmd_len = parse_text_command(given_buffer) if _DEBUG_MODE_ and cmd_type is not None: gearman_logger.debug('%s - Recv - %s - %r', hex(id(self)), get_command_name(cmd_type), cmd_args) return cmd_type, cmd_args, cmd_len
def execute_command(self, buf): self._incoming_buffer += buf cmd_type, cmd_args, cmd_len = protocol.parse_binary_command(self._incoming_buffer, False) print protocol.get_command_name(cmd_type), cmd_args, cmd_len gearman_command_name = protocol.get_command_name(cmd_type) recv_command_function_name = gearman_command_name.lower().replace('gearman_command_', 'recv_') cmd_callback = getattr(self, recv_command_function_name, None) if not cmd_callback: missing_callback_msg = 'Could not handle command: %r - %r' % (protocol.get_command_name(cmd_type), cmd_args) #gearman_logger.error(missing_callback_msg) #raise UnknownCommandError(missing_callback_msg) raise Exception(missing_callback_msg) # Expand the arguments as passed by the protocol # This must match the parameter names as defined in the command handler completed_work = cmd_callback(**cmd_args) self.read_command()
def test_parsing_errors_raw(self, data, is_response): in_buffer = array.array("b", data) with pytest.raises(ProtocolError): protocol.parse_binary_command(in_buffer, is_response=is_response)
def test_parsing_errors_struct(self, struct_components): data = struct.pack(*struct_components) in_buffer = array.array("b", data) with pytest.raises(ProtocolError): protocol.parse_binary_command(in_buffer)
def test_parsing_either_succeeds_or_is_protocolerror(self, in_buffer): try: protocol.parse_binary_command(array.array("b", in_buffer)) except ProtocolError: pass