async def test_sender__do_txn_offset_commit_ok(self): sender = await self._setup_sender() offsets = { TopicPartition("topic", 0): OffsetAndMetadata(10, ""), TopicPartition("topic", 1): OffsetAndMetadata(11, ""), } add_handler = TxnOffsetCommitHandler(sender, offsets, "some_group") tm = sender._txn_manager tm.offset_committed = mock.Mock() # Handle response cls = TxnOffsetCommitResponse[0] resp = cls( throttle_time_ms=300, errors=[ ("topic", [ (0, NoError.errno), (1, NoError.errno) ]) ] ) backoff = add_handler.handle_response(resp) self.assertIsNone(backoff) self.assertEqual(tm.offset_committed.call_count, 2) tm.offset_committed.assert_has_calls([ mock.call(TopicPartition("topic", 0), 10, "some_group"), mock.call(TopicPartition("topic", 1), 11, "some_group"), ])
async def test_sender__do_txn_offset_commit_create(self): sender = await self._setup_sender() offsets = { TopicPartition("topic", 0): OffsetAndMetadata(10, ""), TopicPartition("topic", 1): OffsetAndMetadata(11, ""), } add_handler = TxnOffsetCommitHandler(sender, offsets, "some_group") req = add_handler.create_request() self.assertEqual(req.API_KEY, TxnOffsetCommitRequest[0].API_KEY) self.assertEqual(req.API_VERSION, 0) self.assertEqual(req.transactional_id, "test_tid") self.assertEqual(req.group_id, "some_group") self.assertEqual(req.producer_id, 120) self.assertEqual(req.producer_epoch, 22) self.assertEqual(req.topics, [("topic", [(0, 10, ""), (1, 11, "")])])
async def test_sender__do_txn_offset_commit_create(self): sender = await self._setup_sender() offsets = { TopicPartition("topic", 0): OffsetAndMetadata(10, ""), TopicPartition("topic", 1): OffsetAndMetadata(11, ""), } add_handler = TxnOffsetCommitHandler(sender, offsets, "some_group") req = add_handler.create_request() self.assertEqual(req.API_KEY, TxnOffsetCommitRequest[0].API_KEY) self.assertEqual(req.API_VERSION, 0) self.assertEqual(req.transactional_id, "test_tid") self.assertEqual(req.group_id, "some_group") self.assertEqual(req.producer_id, 120) self.assertEqual(req.producer_epoch, 22) self.assertEqual(req.topics, [ ("topic", [ (0, 10, ""), (1, 11, "") ]) ])
async def test_sender__do_txn_offset_commit_not_ok(self): sender = await self._setup_sender() offsets = { TopicPartition("topic", 0): OffsetAndMetadata(10, ""), TopicPartition("topic", 1): OffsetAndMetadata(11, ""), } add_handler = TxnOffsetCommitHandler(sender, offsets, "some_group") tm = sender._txn_manager tm.offset_committed = mock.Mock() def create_response(error_type): cls = TxnOffsetCommitResponse[0] resp = cls(throttle_time_ms=300, errors=[("topic", [(0, error_type.errno), (1, error_type.errno)])]) return resp # Handle coordination errors for error_cls in [ CoordinatorNotAvailableError, NotCoordinatorError, RequestTimedOutError ]: with mock.patch.object(sender, "_coordinator_dead") as mocked: resp = create_response(error_cls) backoff = add_handler.handle_response(resp) self.assertEqual(backoff, 0.1) tm.offset_committed.assert_not_called() mocked.assert_called_with(CoordinationType.GROUP) # Not coordination retriable errors for error_cls in [ CoordinatorLoadInProgressError, UnknownTopicOrPartitionError ]: resp = create_response(error_cls) backoff = add_handler.handle_response(resp) self.assertEqual(backoff, 0.1) tm.offset_committed.assert_not_called() # ProducerFenced case resp = create_response(InvalidProducerEpoch) with self.assertRaises(ProducerFenced): add_handler.handle_response(resp) tm.offset_committed.assert_not_called() # Handle unknown error resp = create_response(UnknownError) with self.assertRaises(UnknownError): add_handler.handle_response(resp) tm.offset_committed.assert_not_called()
async def test_sender__do_txn_offset_commit_not_ok(self): sender = await self._setup_sender() offsets = { TopicPartition("topic", 0): OffsetAndMetadata(10, ""), TopicPartition("topic", 1): OffsetAndMetadata(11, ""), } add_handler = TxnOffsetCommitHandler(sender, offsets, "some_group") tm = sender._txn_manager tm.begin_transaction() tm.offset_committed = mock.Mock() def create_response(error_type): cls = TxnOffsetCommitResponse[0] resp = cls( throttle_time_ms=300, errors=[ ("topic", [ (0, error_type.errno), (1, error_type.errno) ]) ] ) return resp # Handle coordination errors for error_cls in [ CoordinatorNotAvailableError, NotCoordinatorError, RequestTimedOutError]: with mock.patch.object(sender, "_coordinator_dead") as mocked: resp = create_response(error_cls) backoff = add_handler.handle_response(resp) self.assertEqual(backoff, 0.1) tm.offset_committed.assert_not_called() mocked.assert_called_with(CoordinationType.GROUP) # Not coordination retriable errors for error_cls in [ CoordinatorLoadInProgressError, UnknownTopicOrPartitionError]: resp = create_response(error_cls) backoff = add_handler.handle_response(resp) self.assertEqual(backoff, 0.1) tm.offset_committed.assert_not_called() # ProducerFenced case resp = create_response(InvalidProducerEpoch) with self.assertRaises(ProducerFenced): add_handler.handle_response(resp) tm.offset_committed.assert_not_called() # TransactionalIdAuthorizationFailed case resp = create_response(TransactionalIdAuthorizationFailed) with self.assertRaises(TransactionalIdAuthorizationFailed) as cm: add_handler.handle_response(resp) tm.offset_committed.assert_not_called() self.assertEqual(cm.exception.args[0], "test_tid") # Handle unknown error resp = create_response(UnknownError) with self.assertRaises(UnknownError): add_handler.handle_response(resp) tm.offset_committed.assert_not_called() # GroupAuthorizationFailedError case self.assertNotEqual(tm.state, TransactionState.ABORTABLE_ERROR) resp = create_response(GroupAuthorizationFailedError) backoff = add_handler.handle_response(resp) self.assertIsNone(backoff) tm.offset_committed.assert_not_called() with self.assertRaises(GroupAuthorizationFailedError) as cm: tm.committing_transaction() self.assertEqual(cm.exception.args[0], "some_group") self.assertEqual(tm.state, TransactionState.ABORTABLE_ERROR)