def test_send_produce_request_maintains_request_response_order(self): self.client.ensure_topic_exists('foo') self.client.ensure_topic_exists('bar') requests = [ ProduceRequestPayload('foo', 0, [create_message(b'a'), create_message(b'b')]), ProduceRequestPayload('bar', 1, [create_message(b'a'), create_message(b'b')]), ProduceRequestPayload('foo', 1, [create_message(b'a'), create_message(b'b')]), ProduceRequestPayload('bar', 0, [create_message(b'a'), create_message(b'b')]), ] responses = self.client.send_produce_request(requests) while len(responses): request = requests.pop() response = responses.pop() self.assertEqual(request.topic, response.topic) self.assertEqual(request.partition, response.partition)
def test_encode_produce_request(self): requests = [ ProduceRequestPayload("topic1", 0, [ kafka.protocol.message.Message(b"a"), kafka.protocol.message.Message(b"b") ]), ProduceRequestPayload("topic2", 1, [ kafka.protocol.message.Message(b"c") ]) ] msg_a_binary = KafkaProtocol._encode_message(create_message(b"a")) msg_b_binary = KafkaProtocol._encode_message(create_message(b"b")) msg_c_binary = KafkaProtocol._encode_message(create_message(b"c")) header = b"".join([ struct.pack('>i', 0x94), # The length of the message overall struct.pack('>h', 0), # Msg Header, Message type = Produce struct.pack('>h', 0), # Msg Header, API version struct.pack('>i', 2), # Msg Header, Correlation ID struct.pack('>h7s', 7, b"client1"), # Msg Header, The client ID struct.pack('>h', 2), # Num acks required struct.pack('>i', 100), # Request Timeout struct.pack('>i', 2), # The number of requests ]) total_len = len(msg_a_binary) + len(msg_b_binary) topic1 = b"".join([ struct.pack('>h6s', 6, b'topic1'), # The topic1 struct.pack('>i', 1), # One message set struct.pack('>i', 0), # Partition 0 struct.pack('>i', total_len + 24), # Size of the incoming message set struct.pack('>q', 0), # No offset specified struct.pack('>i', len(msg_a_binary)), # Length of message msg_a_binary, # Actual message struct.pack('>q', 0), # No offset specified struct.pack('>i', len(msg_b_binary)), # Length of message msg_b_binary, # Actual message ]) topic2 = b"".join([ struct.pack('>h6s', 6, b'topic2'), # The topic1 struct.pack('>i', 1), # One message set struct.pack('>i', 1), # Partition 1 struct.pack('>i', len(msg_c_binary) + 12), # Size of the incoming message set struct.pack('>q', 0), # No offset specified struct.pack('>i', len(msg_c_binary)), # Length of message msg_c_binary, # Actual message ]) expected1 = b"".join([ header, topic1, topic2 ]) expected2 = b"".join([ header, topic2, topic1 ]) encoded = KafkaProtocol.encode_produce_request(b"client1", 2, requests, 2, 100) self.assertIn(encoded, [ expected1, expected2 ])
def send_messages(self, partition, messages): messages = [ create_message(self.msg(str(msg))) for msg in messages ] produce = ProduceRequestPayload(self.topic, partition, messages = messages) resp, = self.client.send_produce_request([produce]) self.assertEqual(resp.error, 0) return [ x.value for x in messages ]
def test_send_produce_request_raises_when_topic_unknown( self, protocol, conn): mock_conn(conn) brokers = [ BrokerMetadata(0, 'broker_1', 4567), BrokerMetadata(1, 'broker_2', 5678) ] topics = [ (UNKNOWN_TOPIC_OR_PARTITION, 'topic_doesnt_exist', []), ] protocol.decode_metadata_response.return_value = MetadataResponse( brokers, topics) client = SimpleClient(hosts=['broker_1:4567']) requests = [ ProduceRequestPayload( "topic_doesnt_exist", 0, [create_message("a"), create_message("b")]) ] with self.assertRaises(UnknownTopicOrPartitionError): client.send_produce_request(requests)
def test_send_produce_request_raises_when_noleader(self, protocol, conn): mock_conn(conn) brokers = [ BrokerMetadata(0, 'broker_1', 4567), BrokerMetadata(1, 'broker_2', 5678) ] topics = [ (NO_ERROR, 'topic_noleader', [ (NO_LEADER, 0, -1, [], []), (NO_LEADER, 1, -1, [], []), ]), ] protocol.decode_metadata_response.return_value = MetadataResponse( brokers, topics) client = SimpleClient(hosts=['broker_1:4567']) requests = [ ProduceRequestPayload( "topic_noleader", 0, [create_message("a"), create_message("b")]) ] with self.assertRaises(LeaderNotAvailableError): client.send_produce_request(requests)
def assert_produce_request(self, messages, initial_offset, message_ct, partition=0): produce = ProduceRequestPayload(self.topic, partition, messages=messages) # There should only be one response message from the server. # This will throw an exception if there's more than one. resp = self.client.send_produce_request([ produce ]) self.assert_produce_response(resp, initial_offset) self.assertEqual(self.current_offset(self.topic, partition), initial_offset + message_ct)