async def test_handle_inbound_message_tries_putting_onto_queue_twice_if_retry_set_to_one( self, mock_sleep): self.workflow = async_express.AsynchronousExpressWorkflow( party_key=FROM_PARTY_KEY, persistence_store=self.mock_persistence_store, transmission=self.mock_transmission_adaptor, queue_adaptor=self.mock_queue_adaptor, # Set number of retries to 1 inbound_queue_max_retries=1, inbound_queue_retry_delay=INBOUND_QUEUE_RETRY_DELAY, persistence_store_max_retries=3, routing=self.mock_routing_reliability) self.setup_mock_work_description() future = asyncio.Future() future.set_exception(proton_queue_adaptor.MessageSendingError()) self.mock_queue_adaptor.send_async.return_value = future mock_sleep.return_value = test_utilities.awaitable(None) with self.assertRaises(exceptions.MaxRetriesExceeded) as cm: await self.workflow.handle_inbound_message( MESSAGE_ID, CORRELATION_ID, self.mock_work_description, PAYLOAD) self.assertIsInstance(cm.exception.__cause__, proton_queue_adaptor.MessageSendingError) self.assertEqual( 2, self.mock_queue_adaptor.send_async.call_count, msg='Incorrect number of attempts at putting message onto queue') mock_sleep.assert_called_once_with( INBOUND_QUEUE_RETRY_DELAY_IN_SECONDS)
async def test_handle_inbound_message_error_putting_message_onto_queue_then_success( self, mock_sleep): self.setup_mock_work_description() error_future = asyncio.Future() error_future.set_exception(proton_queue_adaptor.MessageSendingError()) self.mock_queue_adaptor.send_async.side_effect = [ error_future, test_utilities.awaitable(None) ] mock_sleep.return_value = test_utilities.awaitable(None) await self.workflow.handle_inbound_message(MESSAGE_ID, CORRELATION_ID, self.mock_work_description, PAYLOAD) self.mock_queue_adaptor.send_async.assert_called_with( { 'payload': PAYLOAD, 'attachments': [] }, properties={ 'message-id': MESSAGE_ID, 'correlation-id': CORRELATION_ID }) self.assertEqual([ mock.call(MessageStatus.INBOUND_RESPONSE_RECEIVED), mock.call(MessageStatus.INBOUND_RESPONSE_SUCCESSFULLY_PROCESSED) ], self.mock_work_description.set_inbound_status.call_args_list) mock_sleep.assert_called_once_with( INBOUND_QUEUE_RETRY_DELAY_IN_SECONDS)
async def test_handle_inbound_message_error_putting_message_onto_queue_despite_retries( self, mock_sleep, audit_log_mock): self.setup_mock_work_description() future = asyncio.Future() future.set_exception(proton_queue_adaptor.MessageSendingError()) self.mock_queue_adaptor.send_async.return_value = future mock_sleep.return_value = test_utilities.awaitable(None) with self.assertRaises(exceptions.MaxRetriesExceeded) as cm: await self.workflow.handle_inbound_message( MESSAGE_ID, CORRELATION_ID, self.mock_work_description, PAYLOAD) self.assertIsInstance(cm.exception.__cause__, proton_queue_adaptor.MessageSendingError) self.assertEqual([ mock.call(INBOUND_QUEUE_RETRY_DELAY_IN_SECONDS) for _ in range(INBOUND_QUEUE_MAX_RETRIES) ], mock_sleep.call_args_list) self.assertEqual([ mock.call(MessageStatus.INBOUND_RESPONSE_RECEIVED), mock.call(MessageStatus.INBOUND_RESPONSE_FAILED) ], self.mock_work_description.set_inbound_status.call_args_list) # Should be called when invoked audit_log_mock.assert_called_once_with( '0103', '{WorkflowName} inbound workflow invoked. Message ' 'received from spine', {'WorkflowName': 'async-reliable'})
async def test_handle_unsolicited_inbound_message_error_putting_message_onto_queue_despite_retries( self, mock_sleep, audit_log_mock): self.setup_mock_work_description() future = asyncio.Future() future.set_exception(proton_queue_adaptor.MessageSendingError()) self.mock_queue_adaptor.send_async.return_value = future mock_sleep.return_value = test_utilities.awaitable(None) with self.assertRaises(exceptions.MaxRetriesExceeded) as cm: await self.workflow.handle_unsolicited_inbound_message( MESSAGE_ID, CORRELATION_ID, PAYLOAD, []) self.assertIsInstance(cm.exception.__cause__, proton_queue_adaptor.MessageSendingError) self.assertEqual([ mock.call(INBOUND_QUEUE_RETRY_DELAY_IN_SECONDS) for _ in range(INBOUND_QUEUE_MAX_RETRIES) ], mock_sleep.call_args_list) audit_log_mock.assert_called_with( '0101', 'Unsolicited inbound {WorkflowName} workflow invoked.', {'WorkflowName': 'forward-reliable'}) self.assertEqual( [mock.call(MessageStatus.UNSOLICITED_INBOUND_RESPONSE_FAILED)], self.mock_work_description.set_inbound_status.call_args_list)
async def test_handle_inbound_message_error_putting_message_onto_queue_despite_retries( self): self.setup_mock_work_description() future = asyncio.Future() future.set_exception(proton_queue_adaptor.MessageSendingError()) self.mock_queue_adaptor.send_async.return_value = future with self.assertRaises(proton_queue_adaptor.MessageSendingError): await self.workflow.handle_inbound_message( MESSAGE_ID, CORRELATION_ID, self.mock_work_description, INBOUND_MESSAGE_DATA) self.assertEqual( [mock.call(MessageStatus.INBOUND_RESPONSE_FAILED)], self.mock_work_description.set_inbound_status.call_args_list)
async def test_handle_unsolicited_inbound_message_error_putting_message_onto_queue_despite_retries( self, mock_sleep, audit_log_mock): self.setup_mock_work_description() future = asyncio.Future() future.set_exception(proton_queue_adaptor.MessageSendingError()) self.mock_queue_adaptor.send_async.return_value = future mock_sleep.return_value = test_utilities.awaitable(None) with self.assertRaises(proton_queue_adaptor.MessageSendingError): await self.workflow.handle_unsolicited_inbound_message( MESSAGE_ID, CORRELATION_ID, INBOUND_MESSAGE_DATA) audit_log_mock.assert_called_with( 'Unsolicited inbound {WorkflowName} workflow invoked.', fparams={'WorkflowName': 'forward-reliable'}) self.assertEqual( [mock.call(MessageStatus.UNSOLICITED_INBOUND_RESPONSE_FAILED)], self.mock_work_description.set_inbound_status.call_args_list)
async def test_handle_inbound_message_error_putting_message_onto_queue_despite_retries( self, mock_sleep, audit_log_mock): self.setup_mock_work_description() future = asyncio.Future() future.set_exception(proton_queue_adaptor.MessageSendingError()) self.mock_queue_adaptor.send_async.return_value = future mock_sleep.return_value = test_utilities.awaitable(None) with self.assertRaises(proton_queue_adaptor.MessageSendingError): await self.workflow.handle_inbound_message( MESSAGE_ID, CORRELATION_ID, self.mock_work_description, INBOUND_MESSAGE_DATA) self.assertEqual( [mock.call(MessageStatus.INBOUND_RESPONSE_FAILED)], self.mock_work_description.set_inbound_status.call_args_list) # Should be called when invoked audit_log_mock.assert_called_once_with( '{WorkflowName} inbound workflow invoked. Message ' 'received from spine', fparams={'WorkflowName': 'async-reliable'})