def test_subclassing_api(self): worker = get_stubbed_worker(ApplicationWorker, {'transport_name': 'test'}) ack = TransportEvent(event_type='ack', sent_message_id='remote-id', user_message_id='ack-uuid') dr = TransportEvent(event_type='delivery_report', delivery_status='pending', user_message_id='dr-uuid') worker.consume_ack(ack) worker.consume_delivery_report(dr) worker.consume_unknown_event(FakeUserMessage()) worker.consume_user_message(FakeUserMessage()) worker.new_session(FakeUserMessage()) worker.close_session(FakeUserMessage())
def test_event_dispatch(self): events = [ ('ack', TransportEvent(event_type='ack', sent_message_id='remote-id', user_message_id='ack-uuid')), ('delivery_report', TransportEvent(event_type='delivery_report', delivery_status='pending', user_message_id='dr-uuid')), ] for name, event in events: yield self.send_event(event) self.assertEqual(self.worker.record, [(name, event)]) del self.worker.record[:]
def handle_raw_inbound_event(self, request): try: data = json.loads(request.content.read()) msg = TransportEvent(_process_fields=True, **to_kwargs(data)) yield self.handle_inbound_event(msg) request.finish() if msg.payload["event_type"] == "ack": self.update_status(status='ok', component='sent-by-vumi-go', type='vumi_go_sent', message='Sent by Vumi Go') elif msg.payload["event_type"] == "nack": self.update_status(status='down', component='sent-by-vumi-go', type='vumi_go_failed', message='Vumi Go failed to send') self.update_status(status='ok', component='vumi-go-event', type='good_request', message='Good event received from Vumi Go') except Exception as e: log.err(e) request.setResponseCode(400) request.finish() self.update_status(status='down', component='vumi-go-event', type='bad_request', message='Bad event received from Vumi Go')
def test_unknown_event_dispatch(self): # temporarily pretend the worker doesn't know about acks del self.worker._event_handlers['ack'] bad_event = TransportEvent(event_type='ack', sent_message_id='remote-id', user_message_id='bad-uuid') yield self.send_event(bad_event) self.assertEqual(self.worker.record, [('unknown_event', bad_event)])
def _ignore_message(self, failure, msg): failure.trap(IgnoreMessage) log.debug("Ignoring msg (with NACK) due to %r: %r" % (failure.value, msg)) return self.publish_event( TransportEvent(user_message_id=msg['message_id'], nack_reason=str(failure.value), event_type='nack'))
def make_message(self, **extra_fields): fields = dict( event_id='def', event_type='ack', user_message_id='abc', sent_message_id='ghi', ) fields.update(extra_fields) return TransportEvent(**fields)
def handle_raw_inbound_event(self, request): try: data = json.loads(request.content.read()) msg = TransportEvent(_process_fields=True, **to_kwargs(data)) yield self.handle_inbound_event(msg) request.finish() except Exception as e: log.err(e) request.setResponseCode(400) request.finish()
def mkmsg_ack(self, transport_name, **kw): event_kw = dict( event_type='ack', user_message_id='1', sent_message_id='abc', transport_name=transport_name, transport_metadata={}, ) event_kw.update(kw) return TransportEvent(**event_kw)
def publish_event(self, **kw): """ Publish a :class:`TransportEvent` message. Some default parameters are handled, so subclasses don't have to provide a lot of boilerplate. """ kw.setdefault('transport_name', self.transport_name) kw.setdefault('transport_metadata', {}) event = TransportEvent(**kw) return self.connectors[self.transport_name].publish_event(event)
def test_store_event(self): '''Stores the event under the message ID''' store = yield self.create_store() event = TransportEvent(user_message_id='message_id', sent_message_id='message_id', event_type='ack') yield store.store_event('channel_id', 'message_id', event) event_json = yield self.redis.hget( 'channel_id:outbound_messages:message_id', event['event_id']) self.assertEqual(event_json, event.to_json())
def test_load_event(self): store = yield self.create_store() event = TransportEvent(user_message_id='message_id', sent_message_id='message_id', event_type='nack', nack_reason='error error') yield self.redis.hset('channel_id:outbound_messages:message_id', event['event_id'], event.to_json()) stored_event = yield store.load_event('channel_id', 'message_id', event['event_id']) self.assertEqual(stored_event, event)
def test_load_all_events_one(self): '''Returns a list with one event inside''' store = yield self.create_store() event = TransportEvent(user_message_id='message_id', sent_message_id='message_id', event_type='delivery_report', delivery_status='pending') yield self.redis.hset('channel_id:outbound_messages:message_id', event['event_id'], event.to_json()) events = yield store.load_all_events('channel_id', 'message_id') self.assertEqual(events, [event])
def test_forward_nack_no_message(self): self.patch_logger() event = TransportEvent(event_type='nack', user_message_id='msg-21', nack_reason='too many foos', timestamp='2015-09-22 15:39:44.827794') yield self.worker.consume_nack(event) self.assertEqual(self.logging_api.requests, []) yield self.assert_event_stored(event)
def test_forward_dr_no_message(self): self.patch_logger() event = TransportEvent(event_type='delivery_report', user_message_id='msg-21', delivery_status='pending', timestamp='2015-09-22 15:39:44.827794') yield self.worker.consume_delivery_report(event) self.assertEqual(self.logging_api.requests, []) yield self.assert_event_stored(event)
def test_add_ack_event(self): batch_id = self.store.batch_start([("pool", "tag")]) msg = self.mkmsg_out(content="outfoo") msg_id = msg['message_id'] ack = TransportEvent(user_message_id=msg_id, event_type='ack', sent_message_id='xyz') ack_id = ack['event_id'] self.store.add_outbound_message(msg, batch_id=batch_id) self.store.add_event(ack) self.assertEqual(self.store.get_event(ack_id), ack) self.assertEqual(self.store.message_events(msg_id), [ack_id])
def mkmsg_ack(self, user_message_id='1', sent_message_id='abc', transport_metadata=None): if transport_metadata is None: transport_metadata = {} return TransportEvent( event_type='ack', user_message_id=user_message_id, sent_message_id=sent_message_id, transport_name=self.transport_name, transport_metadata=transport_metadata, )
def publish_event(self, **kw): """ Publish a :class:`TransportEvent` message. Some default parameters are handled, so subclasses don't have to provide a lot of boilerplate. """ kw.setdefault('transport_name', self.transport_name) kw.setdefault('transport_metadata', {}) event = TransportEvent(**kw) d = self._middlewares.apply_publish("event", event, self.transport_name) d.addCallback(self.event_publisher.publish_message) return d
def test_transport_event_nack(self): msg = TransportEvent( event_id='def', event_type='nack', user_message_id='abc', nack_reason='unknown', ) self.assertEqual('event', msg['message_type']) self.assertEqual('nack', msg['event_type']) self.assertEqual('unknown', msg['nack_reason']) self.assertEqual('def', msg['event_id']) self.assertEqual('abc', msg['user_message_id']) self.assertEqual('20110921', msg['message_version']) self.assertEqual({}, msg['helper_metadata'])
def mkmsg_delivery(self, status='delivered', user_message_id='abc', transport_metadata=None): if transport_metadata is None: transport_metadata = {} return TransportEvent( event_type='delivery_report', transport_name=self.transport_name, user_message_id=user_message_id, delivery_status=status, to_addr='+41791234567', transport_metadata=transport_metadata, )
def test_transport_event_ack(self): msg = TransportEvent( event_id='def', event_type='ack', user_message_id='abc', sent_message_id='ghi', ) self.assertEqual('event', msg['message_type']) self.assertEqual('ack', msg['event_type']) self.assertEqual('def', msg['event_id']) self.assertEqual('abc', msg['user_message_id']) self.assertEqual('20110921', msg['message_version']) self.assertEqual('ghi', msg['sent_message_id']) self.assertEqual({}, msg['helper_metadata'])
def test_load_all_events_with_other_stored_fields(self): '''Should return just the stored events''' store = yield self.create_store() event = TransportEvent(user_message_id='message_id', sent_message_id='message_id', event_type='delivery_report', delivery_status='pending') yield self.redis.hset('channel_id:outbound_messages:message_id', event['event_id'], event.to_json()) yield self.redis.hset('channel_id:outbound_messages:message_id', 'event_url', 'test_url') stored_events = yield store.load_all_events('channel_id', 'message_id') self.assertEqual(stored_events, [event])
def mkmsg_ack(self, user_message_id='1', sent_message_id='abc', transport_metadata=None): if transport_metadata is None: transport_metadata = {} return TransportEvent( event_id=RegexMatcher(r'^[0-9a-fA-F]{32}$'), event_type='ack', user_message_id=user_message_id, sent_message_id=sent_message_id, timestamp=datetime.now(), transport_name=self.transport_name, transport_metadata=transport_metadata, )
def test_transport_event_ack(self): msg = TransportEvent( event_id='def', event_type='ack', user_message_id='abc', # transport_name='sphex', sent_message_id='ghi', ) self.assertEqual('event', msg['message_type']) self.assertEqual('ack', msg['event_type']) self.assertEqual('def', msg['event_id']) self.assertEqual('abc', msg['user_message_id']) self.assertEqual('20110921', msg['message_version']) # self.assertEqual('sphex', msg['transport_name']) self.assertEqual('ghi', msg['sent_message_id'])
def test_api_from_event_dr_failed(self): self.assertEqual( api_from_event( 'channel-23', TransportEvent( event_type='delivery_report', user_message_id='msg-21', timestamp=date(2321, 2, 3), delivery_status='failed', )), { 'event_type': 'delivery_failed', 'channel_id': 'channel-23', 'message_id': 'msg-21', 'timestamp': date(2321, 2, 3), 'event_details': {}, })
def test_api_from_event_dr_unknown(self): event = TransportEvent(event_type='delivery_report', user_message_id='msg-21', timestamp=date(2321, 2, 3), delivery_status='pending') event['delivery_status'] = 'unknown' self.assertEqual( api_from_event('channel-23', event), { 'event_type': None, 'channel_id': 'channel-23', 'message_id': 'msg-21', 'timestamp': date(2321, 2, 3), 'event_details': {}, })
def test_forward_dr_amqp(self): '''A sent delivery report event should be forwarded to the correct AMQP queue if the config option is set.''' worker = yield self.get_worker(config={'message_queue': 'testqueue'}) event = TransportEvent(event_type='delivery_report', user_message_id='msg-21', delivery_status='pending', timestamp='2015-09-22 15:39:44.827794') yield worker.consume_nack(event) [dispatched_msg ] = self.app_helper.get_dispatched('testqueue', 'event', TransportEvent) self.assertEqual(dispatched_msg['event_id'], event['event_id'])
def test_api_from_event_unknown_type(self): event = TransportEvent(event_type='ack', user_message_id='msg-21', sent_message_id='msg-21', timestamp=date(2321, 2, 3)) event['event_type'] = 'unknown' self.assertEqual( api_from_event('channel-23', event), { 'event_type': None, 'channel_id': 'channel-23', 'message_id': 'msg-21', 'timestamp': date(2321, 2, 3), 'event_details': {}, })
def test_cache_add_event(self): msg_id, msg, batch_id = yield self._create_outbound() ack = TransportEvent(user_message_id=msg_id, event_type='ack', sent_message_id='xyz') yield self.store.add_event(ack) self.assertEqual( (yield self.store.cache.get_event_status(batch_id)), { 'delivery_report': 0, 'delivery_report.delivered': 0, 'delivery_report.failed': 0, 'delivery_report.pending': 0, 'ack': 1, 'nack': 0, 'sent': 1, })
def test_load_all_events_multiple(self): '''Returns a list of all the stored events''' store = yield self.create_store() events = [] for i in range(5): event = TransportEvent(user_message_id='message_id', sent_message_id='message_id', event_type='delivery_report', delivery_status='pending') events.append(event) yield self.redis.hset('channel_id:outbound_messages:message_id', event['event_id'], event.to_json()) stored_events = yield store.load_all_events('channel_id', 'message_id') self.assertEqual(sorted(events, key=lambda e: e['event_id']), sorted(stored_events, key=lambda e: e['event_id']))
def test_forward_event_no_message_id(self): ''' If we receive an event, and we don't have a message ID to associate the event to, then we should log the event and carry on. ''' self.patch_logger() event = TransportEvent(event_type='ack', user_message_id=None, sent_message_id='msg-21', timestamp='2015-09-22 15:39:44.827794') yield self.worker.consume_ack(event) self.assert_was_logged('Cannot store event') self.assert_was_logged('Cannot find event URL') self.assert_was_logged('%r' % event)