def test_error_raised_if_delivery_acknowledgement_not_received_in_time(self): """Test that an error is raised if delivery acknowledgement isn't received before the given acknowledgement timeout. """ message_handler = OrderedMessageHandler(subscriber=MockSubscriber(), subscription=self.mock_subscription) with patch("tests.cloud.pub_sub.mocks.MockSubscriber.pull", return_value=MockPullResponse()): with self.assertRaises(exceptions.QuestionNotDelivered): message_handler.handle_messages(delivery_acknowledgement_timeout=0)
def test_in_order_messages_are_handled_in_order(self): """Test that messages received in order are handled in order.""" message_handling_order = [] message_handler = OrderedMessageHandler( subscriber=MockSubscriber(), subscription=self.mock_subscription, message_handlers={ "test": self._make_order_recording_message_handler(message_handling_order), "finish-test": lambda message: "This is the result.", }, ) with patch( "octue.cloud.pub_sub.service.OrderedMessageHandler._pull_message", new=MockMessagePuller( messages=[ {"type": "test", "message_number": 0}, {"type": "test", "message_number": 1}, {"type": "test", "message_number": 2}, {"type": "finish-test", "message_number": 3}, ] ).pull, ): result = message_handler.handle_messages() self.assertEqual(result, "This is the result.") self.assertEqual(message_handling_order, [0, 1, 2])
def test_timeout(self): """Test that a TimeoutError is raised if message handling takes longer than the given timeout.""" message_handler = OrderedMessageHandler( subscriber=MockSubscriber(), subscription=self.mock_subscription, message_handlers={ "test": self._make_order_recording_message_handler([]), "finish-test": lambda message: message, }, ) with patch( "octue.cloud.pub_sub.service.OrderedMessageHandler._pull_message", new=MockMessagePuller(messages=[{"type": "test", "message_number": 0}]).pull, ): with self.assertRaises(TimeoutError): message_handler.handle_messages(timeout=0)
def wait_for_answer( self, subscription, handle_monitor_message=None, service_name="REMOTE", timeout=60, delivery_acknowledgement_timeout=120, ): """Wait for an answer to a question on the given subscription, deleting the subscription and its topic once the answer is received. :param octue.cloud.pub_sub.subscription.Subscription subscription: the subscription for the question's answer :param callable|None handle_monitor_message: a function to handle monitor messages (e.g. send them to an endpoint for plotting or displaying) - this function should take a single JSON-compatible python primitive as an argument (note that this could be an array or object) :param str service_name: a name by which to refer to the child subscribed to (used for labelling its log messages if subscribed to) :param float|None timeout: how long in seconds to wait for an answer before raising a `TimeoutError` :param float delivery_acknowledgement_timeout: how long in seconds to wait for a delivery acknowledgement before aborting :raise TimeoutError: if the timeout is exceeded :raise octue.exceptions.QuestionNotDelivered: if a delivery acknowledgement is not received in time :return dict: dictionary containing the keys "output_values" and "output_manifest" """ if subscription.is_push_subscription: raise octue.exceptions.PushSubscriptionCannotBePulled( f"Cannot pull from {subscription.path!r} subscription as it is a push subscription." ) subscriber = pubsub_v1.SubscriberClient(credentials=self.credentials) message_handler = OrderedMessageHandler( subscriber=subscriber, subscription=subscription, handle_monitor_message=handle_monitor_message, service_name=service_name, ) try: return message_handler.handle_messages( timeout=timeout, delivery_acknowledgement_timeout=delivery_acknowledgement_timeout, ) finally: subscription.delete() subscriber.close()
def test_delivery_acknowledgement(self): """Test that a delivery acknowledgement message is handled correctly.""" message_handler = OrderedMessageHandler(subscriber=MockSubscriber(), subscription=self.mock_subscription) self.assertFalse(message_handler.received_delivery_acknowledgement) with patch( "octue.cloud.pub_sub.service.OrderedMessageHandler._pull_message", new=MockMessagePuller( [ { "type": "delivery_acknowledgement", "delivery_time": "2021-11-17 17:33:59.717428", "message_number": 0, }, {"type": "result", "output_values": None, "output_manifest": None, "message_number": 1}, ] ).pull, ): result = message_handler.handle_messages() self.assertTrue(message_handler.received_delivery_acknowledgement) self.assertEqual(result, {"output_values": None, "output_manifest": None})