def test_mt_sms_queue_full(self): smpp_helper = yield self.get_smpp_helper() transport_config = smpp_helper.transport.get_static_config() msg = self.tx_helper.make_outbound('hello world') yield self.tx_helper.dispatch_outbound(msg) [submit_sm_pdu] = yield smpp_helper.wait_for_pdus(1) yield smpp_helper.handle_pdu( SubmitSMResp(sequence_number=seq_no(submit_sm_pdu), message_id='foo', command_status='ESME_RMSGQFUL')) self.clock.advance(transport_config.throttle_delay) [submit_sm_pdu_retry] = yield smpp_helper.wait_for_pdus(1) yield smpp_helper.handle_pdu( SubmitSMResp(sequence_number=seq_no(submit_sm_pdu_retry), message_id='bar', command_status='ESME_ROK')) self.assertTrue(seq_no(submit_sm_pdu_retry) > seq_no(submit_sm_pdu)) self.assertEqual(short_message(submit_sm_pdu), 'hello world') self.assertEqual(short_message(submit_sm_pdu_retry), 'hello world') [event] = yield self.tx_helper.wait_for_dispatched_events(1) self.assertEqual(event['event_type'], 'ack') self.assertEqual(event['user_message_id'], msg['message_id'])
def test_unbind(self): calls = [] self.patch(EsmeTransceiver, 'handle_unbind_resp', lambda p, pdu: calls.append(pdu)) transport, protocol = yield self.setup_bind() yield protocol.unbind() [unbind_pdu] = yield wait_for_pdus(transport, 1) protocol.dataReceived(UnbindResp(seq_no(unbind_pdu)).get_bin()) [unbind_resp_pdu] = calls self.assertEqual(seq_no(unbind_resp_pdu), seq_no(unbind_pdu))
def test_unbind(self): protocol = yield self.get_protocol() calls = [] protocol.handle_unbind_resp = calls.append yield self.fake_smsc.bind() yield protocol.unbind() unbind_pdu = yield self.fake_smsc.await_pdu() protocol.dataReceived(UnbindResp(seq_no(unbind_pdu)).get_bin()) [unbind_resp_pdu] = calls self.assertEqual(seq_no(unbind_resp_pdu), seq_no(unbind_pdu))
def test_mt_sms_throttle_while_throttled(self): smpp_helper = yield self.get_smpp_helper() transport_config = smpp_helper.transport.get_static_config() msg1 = self.tx_helper.make_outbound('hello world 1') msg2 = self.tx_helper.make_outbound('hello world 2') yield self.tx_helper.dispatch_outbound(msg1) yield self.tx_helper.dispatch_outbound(msg2) [ssm_pdu1, ssm_pdu2] = yield smpp_helper.wait_for_pdus(2) yield smpp_helper.handle_pdu( SubmitSMResp(sequence_number=seq_no(ssm_pdu1), message_id='foo1', command_status='ESME_RTHROTTLED')) yield smpp_helper.handle_pdu( SubmitSMResp(sequence_number=seq_no(ssm_pdu2), message_id='foo2', command_status='ESME_RTHROTTLED')) # Advance clock, still throttled. self.clock.advance(transport_config.throttle_delay) [ssm_pdu1_retry1] = yield smpp_helper.wait_for_pdus(1) yield smpp_helper.handle_pdu( SubmitSMResp(sequence_number=seq_no(ssm_pdu1_retry1), message_id='bar1', command_status='ESME_RTHROTTLED')) # Advance clock, message no longer throttled. self.clock.advance(transport_config.throttle_delay) [ssm_pdu2_retry1] = yield smpp_helper.wait_for_pdus(1) yield smpp_helper.handle_pdu( SubmitSMResp(sequence_number=seq_no(ssm_pdu2_retry1), message_id='bar2', command_status='ESME_ROK')) # Prod clock, message no longer throttled. self.clock.advance(0) [ssm_pdu1_retry2] = yield smpp_helper.wait_for_pdus(1) yield smpp_helper.handle_pdu( SubmitSMResp(sequence_number=seq_no(ssm_pdu1_retry2), message_id='baz1', command_status='ESME_ROK')) self.assertEqual(short_message(ssm_pdu1), 'hello world 1') self.assertEqual(short_message(ssm_pdu2), 'hello world 2') self.assertEqual(short_message(ssm_pdu1_retry1), 'hello world 1') self.assertEqual(short_message(ssm_pdu2_retry1), 'hello world 2') self.assertEqual(short_message(ssm_pdu1_retry2), 'hello world 1') [event2, event1] = yield self.tx_helper.wait_for_dispatched_events(2) self.assertEqual(event1['event_type'], 'ack') self.assertEqual(event1['user_message_id'], msg1['message_id']) self.assertEqual(event2['event_type'], 'ack') self.assertEqual(event2['user_message_id'], msg2['message_id'])
def handle_deliver_sm(self, pdu): # These operate before the PDUs ``short_message`` or # ``message_payload`` fields have been string decoded. # NOTE: order is important! pdu_handler_chain = [ self.dr_processor.handle_delivery_report_pdu, self.deliver_sm_processor.handle_multipart_pdu, self.deliver_sm_processor.handle_ussd_pdu, ] for handler in pdu_handler_chain: handled = yield handler(pdu) if handled: self.send_pdu(DeliverSMResp(seq_no(pdu), command_status='ESME_ROK')) return # At this point we either have a DR in the message payload # or have a normal SMS that needs to be decoded and handled. content_parts = self.deliver_sm_processor.decode_pdus([pdu]) if not all([isinstance(part, unicode) for part in content_parts]): command_status = self.config.deliver_sm_decoding_error self.log.msg( 'Not all parts of the PDU were able to be decoded. ' 'Responding with %s.' % (command_status,), parts=content_parts) self.send_pdu(DeliverSMResp(seq_no(pdu), command_status=command_status)) return content = u''.join(content_parts) was_cdr = yield self.dr_processor.handle_delivery_report_content( content) if was_cdr: self.send_pdu(DeliverSMResp(seq_no(pdu), command_status='ESME_ROK')) return handled = yield self.deliver_sm_processor.handle_short_message_pdu(pdu) if handled: self.send_pdu(DeliverSMResp(seq_no(pdu), command_status="ESME_ROK")) return command_status = self.config.deliver_sm_decoding_error self.log.warning( 'Unable to process message. ' 'Responding with %s.' % (command_status,), content=content, pdu=pdu.get_obj()) self.send_pdu(DeliverSMResp(seq_no(pdu), command_status=command_status))
def handle_deliver_sm(self, pdu): # These operate before the PDUs ``short_message`` or # ``message_payload`` fields have been string decoded. # NOTE: order is important! pdu_handler_chain = [ self.dr_processor.handle_delivery_report_pdu, self.deliver_sm_processor.handle_multipart_pdu, self.deliver_sm_processor.handle_ussd_pdu, ] for handler in pdu_handler_chain: handled = yield handler(pdu) if handled: self.send_pdu( DeliverSMResp(seq_no(pdu), command_status='ESME_ROK')) return # At this point we either have a DR in the message payload # or have a normal SMS that needs to be decoded and handled. content_parts = self.deliver_sm_processor.decode_pdus([pdu]) if not all([isinstance(part, unicode) for part in content_parts]): command_status = self.config.deliver_sm_decoding_error log.msg('Not all parts of the PDU were able to be decoded. ' 'Responding with %s.' % (command_status, ), parts=content_parts) self.send_pdu( DeliverSMResp(seq_no(pdu), command_status=command_status)) return content = u''.join(content_parts) was_cdr = yield self.dr_processor.handle_delivery_report_content( content) if was_cdr: self.send_pdu(DeliverSMResp(seq_no(pdu), command_status='ESME_ROK')) return handled = yield self.deliver_sm_processor.handle_short_message_pdu(pdu) if handled: self.send_pdu(DeliverSMResp(seq_no(pdu), command_status="ESME_ROK")) return command_status = self.config.deliver_sm_decoding_error log.warning('Unable to process message. ' 'Responding with %s.' % (command_status, ), content=content, pdu=pdu.get_obj()) self.send_pdu(DeliverSMResp(seq_no(pdu), command_status=command_status))
def bind_protocol(transport, protocol, clear=True): [bind_pdu] = yield wait_for_pdus(transport, 1) resp_pdu_class = { BindTransceiver: BindTransceiverResp, BindReceiver: BindReceiverResp, BindTransmitter: BindTransmitterResp, }.get(protocol.bind_pdu) protocol.dataReceived( resp_pdu_class(seq_no(bind_pdu)).get_bin()) [enquire_link] = yield wait_for_pdus(transport, 1) protocol.dataReceived( EnquireLinkResp(seq_no(enquire_link)).get_bin()) if clear: transport.clear() returnValue(bind_pdu)
def test_submit_and_deliver_ussd_close(self): smpp_helper = yield self.get_smpp_helper() yield self.tx_helper.make_dispatch_outbound( "hello world", transport_type="ussd", session_event=TransportUserMessage.SESSION_CLOSE) [submit_sm_pdu] = yield smpp_helper.wait_for_pdus(1) self.assertEqual(command_id(submit_sm_pdu), 'submit_sm') self.assertEqual(pdu_tlv(submit_sm_pdu, 'ussd_service_op'), '02') self.assertEqual(pdu_tlv(submit_sm_pdu, 'its_session_info'), '0001') # Server delivers a USSD message to the Client pdu = DeliverSM(seq_no(submit_sm_pdu) + 1, short_message="reply!") pdu.add_optional_parameter('ussd_service_op', '02') pdu.add_optional_parameter('its_session_info', '0001') yield smpp_helper.handle_pdu(pdu) [mess] = yield self.tx_helper.wait_for_dispatched_inbound(1) self.assertEqual(mess['content'], "reply!") self.assertEqual(mess['transport_type'], "ussd") self.assertEqual(mess['session_event'], TransportUserMessage.SESSION_CLOSE)
def _submit_sm_resp(self, submit_sm_pdu, message_id, **kw): self.assert_command_id(submit_sm_pdu, 'submit_sm') sequence_number = seq_no(submit_sm_pdu) if message_id is None: message_id = "id%s" % (sequence_number, ) # We use handle_pdu here to avoid complications with all the async. return self.handle_pdu(SubmitSMResp(sequence_number, message_id, **kw))
def _submit_sm_resp(self, submit_sm_pdu, message_id, **kw): self.assert_command_id(submit_sm_pdu, 'submit_sm') sequence_number = seq_no(submit_sm_pdu) if message_id is None: message_id = "id%s" % (sequence_number,) # We use handle_pdu here to avoid complications with all the async. return self.handle_pdu(SubmitSMResp(sequence_number, message_id, **kw))
def handle_bind_receiver_resp(self, pdu): if not pdu_ok(pdu): log.warning('Unable to bind: %r' % (command_status(pdu), )) self.transport.loseConnection() return self.state = self.BOUND_STATE_RX return self.on_smpp_bind(seq_no(pdu))
def handle_bind_receiver_resp(self, pdu): if not pdu_ok(pdu): self.log.warning('Unable to bind: %r' % (command_status(pdu),)) self.transport.loseConnection() return self.state = self.BOUND_STATE_RX return self.on_smpp_bind(seq_no(pdu))
def test_on_enquire_link_resp(self): protocol = yield self.get_protocol() calls = [] protocol.handle_enquire_link_resp = calls.append yield self.fake_smsc.bind() [pdu] = calls # bind_transceiver is sequence_number 1 self.assertEqual(seq_no(pdu), 2) self.assertEqual(command_id(pdu), 'enquire_link_resp')
def test_mt_sms_multipart_fail_second_part(self): smpp_helper = yield self.get_smpp_helper(config={ 'submit_short_message_processor_config': { 'send_multipart_udh': True, } }) content = '1' * 161 msg = self.tx_helper.make_outbound(content) yield self.tx_helper.dispatch_outbound(msg) [submit_sm1, submit_sm2] = yield smpp_helper.wait_for_pdus(2) smpp_helper.send_pdu( SubmitSMResp(sequence_number=seq_no(submit_sm1), message_id='foo')) smpp_helper.send_pdu( SubmitSMResp(sequence_number=seq_no(submit_sm2), message_id='bar', command_status='ESME_RSUBMITFAIL')) [event] = yield self.tx_helper.wait_for_dispatched_events(1) self.assertEqual(event['event_type'], 'nack') self.assertEqual(event['user_message_id'], msg['message_id'])
def test_on_enquire_link_resp(self): calls = [] self.patch(EsmeTransceiver, 'handle_enquire_link_resp', lambda p, pdu: calls.append(pdu)) transport, protocol = yield self.setup_bind() [pdu] = calls # bind_transceiver is sequence_number 1 self.assertEqual(seq_no(pdu), 2) self.assertEqual(command_id(pdu), 'enquire_link_resp')
def test_out_of_order_responses(self): smpp_helper = yield self.get_smpp_helper() yield self.tx_helper.make_dispatch_outbound("msg 1", message_id='444') [submit_sm1] = yield smpp_helper.wait_for_pdus(1) response1 = SubmitSMResp(seq_no(submit_sm1), "3rd_party_id_1") yield self.tx_helper.make_dispatch_outbound("msg 2", message_id='445') [submit_sm2] = yield smpp_helper.wait_for_pdus(1) response2 = SubmitSMResp(seq_no(submit_sm2), "3rd_party_id_2") # respond out of order - just to keep things interesting yield smpp_helper.handle_pdu(response2) yield smpp_helper.handle_pdu(response1) [ack1, ack2] = yield self.tx_helper.wait_for_dispatched_events(2) self.assertEqual(ack1['user_message_id'], '445') self.assertEqual(ack1['sent_message_id'], '3rd_party_id_2') self.assertEqual(ack2['user_message_id'], '444') self.assertEqual(ack2['sent_message_id'], '3rd_party_id_1')
def test_mt_sms_multipart_ack(self): smpp_helper = yield self.get_smpp_helper( config={ 'submit_short_message_processor_config': { 'send_multipart_udh': True, } }) content = '1' * 161 msg = self.tx_helper.make_outbound(content) yield self.tx_helper.dispatch_outbound(msg) [submit_sm1, submit_sm2] = yield smpp_helper.wait_for_pdus(2) smpp_helper.send_pdu( SubmitSMResp(sequence_number=seq_no(submit_sm1), message_id='foo')) smpp_helper.send_pdu( SubmitSMResp(sequence_number=seq_no(submit_sm2), message_id='bar')) [event] = yield self.tx_helper.wait_for_dispatched_events(1) self.assertEqual(event['event_type'], 'ack') self.assertEqual(event['user_message_id'], msg['message_id']) self.assertEqual(event['sent_message_id'], 'bar,foo')
def test_drop_link(self): protocol = yield self.get_protocol() bind_pdu = yield self.fake_smsc.await_pdu() self.assertCommand(bind_pdu, 'bind_transceiver') self.assertFalse(protocol.is_bound()) self.assertEqual(protocol.state, EsmeProtocol.OPEN_STATE) self.clock.advance(protocol.config.smpp_bind_timeout + 1) unbind_pdu = yield self.fake_smsc.await_pdu() self.assertCommand(unbind_pdu, 'unbind') yield self.fake_smsc.send_pdu(UnbindResp(seq_no(unbind_pdu))) yield self.fake_smsc.await_disconnect()
def _bind_resp(self, bind_pdu): resp_pdu_classes = { 'bind_transceiver': BindTransceiverResp, 'bind_receiver': BindReceiverResp, 'bind_transmitter': BindTransmitterResp, } self.assert_command_id(bind_pdu, *resp_pdu_classes) resp_pdu_class = resp_pdu_classes.get(command_id(bind_pdu)) self.send_pdu(resp_pdu_class(seq_no(bind_pdu))) eq_d = self.respond_to_enquire_link() return eq_d.addCallback(self._bound_d.callback)
def test_mt_sms_ack(self): smpp_helper = yield self.get_smpp_helper() msg = self.tx_helper.make_outbound('hello world') yield self.tx_helper.dispatch_outbound(msg) [submit_sm_pdu] = yield smpp_helper.wait_for_pdus(1) smpp_helper.send_pdu( SubmitSMResp(sequence_number=seq_no(submit_sm_pdu), message_id='foo')) [event] = yield self.tx_helper.wait_for_dispatched_events(1) self.assertEqual(event['event_type'], 'ack') self.assertEqual(event['user_message_id'], msg['message_id']) self.assertEqual(event['sent_message_id'], 'foo')
def test_mt_sms_nack(self): smpp_helper = yield self.get_smpp_helper() msg = self.tx_helper.make_outbound('hello world') yield self.tx_helper.dispatch_outbound(msg) [submit_sm_pdu] = yield smpp_helper.wait_for_pdus(1) smpp_helper.send_pdu( SubmitSMResp(sequence_number=seq_no(submit_sm_pdu), message_id='foo', command_status='ESME_RINVDSTADR')) [event] = yield self.tx_helper.wait_for_dispatched_events(1) self.assertEqual(event['event_type'], 'nack') self.assertEqual(event['user_message_id'], msg['message_id']) self.assertEqual(event['nack_reason'], 'ESME_RINVDSTADR')
def test_mo_sms_multipart_long(self): smpp_helper = yield self.get_smpp_helper() content = '1' * 255 pdu = DeliverSM(sequence_number=1) pdu.add_optional_parameter('message_payload', content.encode('hex')) smpp_helper.send_pdu(pdu) [deliver_sm_resp] = yield smpp_helper.wait_for_pdus(1) self.assertEqual(1, seq_no(deliver_sm_resp)) self.assertTrue(pdu_ok(deliver_sm_resp)) [msg] = yield self.tx_helper.wait_for_dispatched_inbound(1) self.assertEqual(msg['content'], content)
def test_drop_link(self): protocol = yield self.get_protocol() transport = yield connect_transport(protocol) [bind_pdu] = yield wait_for_pdus(transport, 1) self.assertCommand(bind_pdu, 'bind_transceiver') self.assertFalse(protocol.is_bound()) self.assertEqual(protocol.state, EsmeTransceiver.OPEN_STATE) self.assertFalse(transport.disconnecting) self.clock.advance(protocol.config.smpp_bind_timeout + 1) [unbind_pdu] = yield wait_for_pdus(transport, 1) self.assertCommand(unbind_pdu, 'unbind') unbind_resp_pdu = UnbindResp(sequence_number=seq_no(unbind_pdu)) yield protocol.on_pdu(unpack_pdu(unbind_resp_pdu.get_bin())) self.assertTrue(transport.disconnecting)
def test_mt_sms_throttled(self): smpp_helper = yield self.get_smpp_helper() transport_config = smpp_helper.transport.get_static_config() msg = self.tx_helper.make_outbound('hello world') yield self.tx_helper.dispatch_outbound(msg) [submit_sm_pdu] = yield smpp_helper.wait_for_pdus(1) with LogCatcher(message="Throttling outbound messages.") as lc: yield smpp_helper.handle_pdu( SubmitSMResp(sequence_number=seq_no(submit_sm_pdu), message_id='foo', command_status='ESME_RTHROTTLED')) [logmsg] = lc.logs self.assertEqual(logmsg['logLevel'], logging.WARNING) self.clock.advance(transport_config.throttle_delay) [submit_sm_pdu_retry] = yield smpp_helper.wait_for_pdus(1) yield smpp_helper.handle_pdu( SubmitSMResp(sequence_number=seq_no(submit_sm_pdu_retry), message_id='bar', command_status='ESME_ROK')) self.assertTrue(seq_no(submit_sm_pdu_retry) > seq_no(submit_sm_pdu)) self.assertEqual(short_message(submit_sm_pdu), 'hello world') self.assertEqual(short_message(submit_sm_pdu_retry), 'hello world') [event] = yield self.tx_helper.wait_for_dispatched_events(1) self.assertEqual(event['event_type'], 'ack') self.assertEqual(event['user_message_id'], msg['message_id']) # We're still throttled until our next attempt to unthrottle finds no # messages to retry. with LogCatcher(message="No longer throttling outbound") as lc: self.clock.advance(transport_config.throttle_delay) [logmsg] = lc.logs self.assertEqual(logmsg['logLevel'], logging.WARNING)
def test_partial_pdu_data_received(self): calls = [] self.patch(EsmeTransceiver, 'handle_deliver_sm', lambda p, pdu: calls.append(pdu)) transport, protocol = yield self.setup_bind() deliver_sm = DeliverSM(sequence_number=1, short_message='foo') pdu = deliver_sm.get_bin() half = len(pdu) / 2 pdu_part1, pdu_part2 = pdu[:half], pdu[half:] protocol.dataReceived(pdu_part1) self.assertEqual([], calls) protocol.dataReceived(pdu_part2) [handled_pdu] = calls self.assertEqual(command_id(handled_pdu), 'deliver_sm') self.assertEqual(seq_no(handled_pdu), 1) self.assertEqual(short_message(handled_pdu), 'foo')
def test_enquire_link_looping(self): transport, protocol = yield self.setup_bind(clear=False) enquire_link_resp = EnquireLinkResp(1) protocol.clock.advance(protocol.idle_timeout - 1) protocol.dataReceived(enquire_link_resp.get_bin()) protocol.clock.advance(protocol.idle_timeout - 1) self.assertFalse(transport.disconnecting) protocol.clock.advance(1) [unbind_pdu] = yield wait_for_pdus(transport, 1) self.assertCommand(unbind_pdu, 'unbind') unbind_resp_pdu = UnbindResp(sequence_number=seq_no(unbind_pdu)) yield protocol.on_pdu(unpack_pdu(unbind_resp_pdu.get_bin())) self.assertTrue(transport.disconnecting)
def test_partial_pdu_data_received(self): protocol = yield self.get_protocol() calls = [] protocol.handle_deliver_sm = calls.append yield self.fake_smsc.bind() deliver_sm = DeliverSM(1, short_message='foo') pdu = deliver_sm.get_bin() half = len(pdu) / 2 pdu_part1, pdu_part2 = pdu[:half], pdu[half:] yield self.fake_smsc.send_bytes(pdu_part1) self.assertEqual([], calls) yield self.fake_smsc.send_bytes(pdu_part2) [handled_pdu] = calls self.assertEqual(command_id(handled_pdu), 'deliver_sm') self.assertEqual(seq_no(handled_pdu), 1) self.assertEqual(short_message(handled_pdu), 'foo')
def test_submit_and_deliver_ussd_continue(self): user_msisdn = 'msisdn' session_identifier = 12345 vumi_session_identifier = make_vumi_session_identifier( user_msisdn, session_identifier) transport = yield self.get_transport() deliver_sm_processor = transport.deliver_sm_processor session_manager = deliver_sm_processor.session_manager yield session_manager.create_session(vumi_session_identifier, ussd_code='*123#') yield self.tx_helper.make_dispatch_outbound( "hello world", transport_type="ussd", transport_metadata={ 'session_info': { 'session_identifier': session_identifier } }, to_addr=user_msisdn) submit_sm_pdu = yield self.fake_smsc.await_pdu() self.assertEqual(command_id(submit_sm_pdu), 'submit_sm') self.assertEqual(pdu_tlv(submit_sm_pdu, 'ussd_service_op'), '02') self.assertEqual(pdu_tlv(submit_sm_pdu, 'user_message_reference'), session_identifier) # Server delivers a USSD message to the Client pdu = DeliverSM(seq_no(submit_sm_pdu) + 1, short_message="reply!", source_addr=user_msisdn) # 0x12 is 'continue' pdu.add_optional_parameter('ussd_service_op', '12') pdu.add_optional_parameter('user_message_reference', session_identifier) yield self.fake_smsc.handle_pdu(pdu) [mess] = yield self.tx_helper.wait_for_dispatched_inbound(1) self.assertEqual(mess['content'], "reply!") self.assertEqual(mess['transport_type'], "ussd") self.assertEqual(mess['to_addr'], '*123#') self.assertEqual(mess['session_event'], TransportUserMessage.SESSION_RESUME)
def test_mt_sms_failure(self): smpp_helper = yield self.get_smpp_helper() message = yield self.tx_helper.make_dispatch_outbound( "message", message_id='446') [submit_sm] = yield smpp_helper.wait_for_pdus(1) response = SubmitSMResp(seq_no(submit_sm), "3rd_party_id_3", command_status="ESME_RSUBMITFAIL") # A failure PDU might not have a body. response.obj.pop('body') smpp_helper.send_pdu(response) # There should be a nack [nack] = yield self.tx_helper.wait_for_dispatched_events(1) [failure] = yield self.tx_helper.get_dispatched_failures() self.assertEqual(failure['reason'], 'ESME_RSUBMITFAIL') self.assertEqual(failure['message'], message.payload)
def test_mt_sms_failure(self): smpp_helper = yield self.get_smpp_helper() message = yield self.tx_helper.make_dispatch_outbound("message", message_id='446') [submit_sm] = yield smpp_helper.wait_for_pdus(1) response = SubmitSMResp(seq_no(submit_sm), "3rd_party_id_3", command_status="ESME_RSUBMITFAIL") # A failure PDU might not have a body. response.obj.pop('body') smpp_helper.send_pdu(response) # There should be a nack [nack] = yield self.tx_helper.wait_for_dispatched_events(1) [failure] = yield self.tx_helper.get_dispatched_failures() self.assertEqual(failure['reason'], 'ESME_RSUBMITFAIL') self.assertEqual(failure['message'], message.payload)
def test_link_remote_message_id(self): smpp_helper = yield self.get_smpp_helper() transport = smpp_helper.transport config = transport.get_static_config() msg = self.tx_helper.make_outbound('hello world') yield self.tx_helper.dispatch_outbound(msg) [pdu] = yield smpp_helper.wait_for_pdus(1) yield smpp_helper.handle_pdu( SubmitSMResp(sequence_number=seq_no(pdu), message_id='foo', command_status='ESME_ROK')) self.assertEqual( msg['message_id'], (yield transport.message_stash.get_internal_message_id('foo'))) ttl = yield transport.redis.ttl(remote_message_key('foo')) self.assertTrue(0 < ttl <= config.third_party_id_expiry)
def assertCommand(self, pdu, cmd_id, sequence_number=None, status=None, params={}): self.assertEqual(command_id(pdu), cmd_id) if sequence_number is not None: self.assertEqual(seq_no(pdu), sequence_number) if status is not None: self.assertEqual(command_status(pdu), status) pdu_params = {} if params: if 'body' not in pdu: raise Exception('Body does not have parameters.') mandatory_parameters = pdu['body']['mandatory_parameters'] for key in params: if key in mandatory_parameters: pdu_params[key] = mandatory_parameters[key] self.assertEqual(params, pdu_params)
def test_submit_and_deliver_ussd_continue(self): user_msisdn = 'msisdn' session_identifier = 12345 vumi_session_identifier = make_vumi_session_identifier( user_msisdn, session_identifier) smpp_helper = yield self.get_smpp_helper() deliver_sm_processor = smpp_helper.transport.deliver_sm_processor session_manager = deliver_sm_processor.session_manager yield session_manager.create_session( vumi_session_identifier, ussd_code='*123#') yield self.tx_helper.make_dispatch_outbound( "hello world", transport_type="ussd", transport_metadata={ 'session_info': { 'session_identifier': session_identifier } }, to_addr=user_msisdn) [submit_sm_pdu] = yield smpp_helper.wait_for_pdus(1) self.assertEqual(command_id(submit_sm_pdu), 'submit_sm') self.assertEqual(pdu_tlv(submit_sm_pdu, 'ussd_service_op'), '02') self.assertEqual( pdu_tlv(submit_sm_pdu, 'user_message_reference'), session_identifier) # Server delivers a USSD message to the Client pdu = DeliverSM(seq_no(submit_sm_pdu) + 1, short_message="reply!", source_addr=user_msisdn) # 0x12 is 'continue' pdu.add_optional_parameter('ussd_service_op', '12') pdu.add_optional_parameter('user_message_reference', session_identifier) yield smpp_helper.handle_pdu(pdu) [mess] = yield self.tx_helper.wait_for_dispatched_inbound(1) self.assertEqual(mess['content'], "reply!") self.assertEqual(mess['transport_type'], "ussd") self.assertEqual(mess['to_addr'], '*123#') self.assertEqual(mess['session_event'], TransportUserMessage.SESSION_RESUME)
def test_mt_sms_failure_with_no_reason(self): smpp_helper = yield self.get_smpp_helper() message = yield self.tx_helper.make_dispatch_outbound("message", message_id='446') [submit_sm] = yield smpp_helper.wait_for_pdus(1) yield smpp_helper.handle_pdu( SubmitSMResp(sequence_number=seq_no(submit_sm), message_id='foo', command_status=None)) # There should be a nack [nack] = yield self.tx_helper.wait_for_dispatched_events(1) self.assertEqual(nack['user_message_id'], message['message_id']) self.assertEqual(nack['nack_reason'], 'Unspecified') [failure] = yield self.tx_helper.get_dispatched_failures() self.assertEqual(failure['reason'], 'Unspecified')
def test_mt_sms_failure_with_no_reason(self): smpp_helper = yield self.get_smpp_helper() message = yield self.tx_helper.make_dispatch_outbound( "message", message_id='446') [submit_sm] = yield smpp_helper.wait_for_pdus(1) yield smpp_helper.handle_pdu( SubmitSMResp(sequence_number=seq_no(submit_sm), message_id='foo', command_status=None)) # There should be a nack [nack] = yield self.tx_helper.wait_for_dispatched_events(1) self.assertEqual(nack['user_message_id'], message['message_id']) self.assertEqual(nack['nack_reason'], 'Unspecified') [failure] = yield self.tx_helper.get_dispatched_failures() self.assertEqual(failure['reason'], 'Unspecified')
def test_submit_and_deliver_ussd_continue(self): session = SessionInfo() smpp_helper = yield self.get_smpp_helper() deliver_sm_processor = smpp_helper.transport.deliver_sm_processor session_manager = deliver_sm_processor.session_manager yield session_manager.create_session(session.vumi_id, ussd_code='*123#') yield self.tx_helper.make_dispatch_outbound( "hello world", transport_type="ussd", transport_metadata={ 'session_info': { 'session_identifier': session.sixdee_id, } }, to_addr=session.addr) [submit_sm_pdu] = yield smpp_helper.wait_for_pdus(1) self.assertEqual(command_id(submit_sm_pdu), 'submit_sm') self.assertEqual(pdu_tlv(submit_sm_pdu, 'ussd_service_op'), '02') self.assertEqual(pdu_tlv(submit_sm_pdu, 'its_session_info'), session.its_info) # Server delivers a USSD message to the Client pdu = DeliverSM(seq_no(submit_sm_pdu) + 1, short_message="reply!", source_addr=session.addr) # 0x12 is 'continue' pdu.add_optional_parameter('ussd_service_op', '12') pdu.add_optional_parameter('its_session_info', session.its_info) yield smpp_helper.handle_pdu(pdu) [mess] = yield self.tx_helper.wait_for_dispatched_inbound(1) self.assertEqual(mess['content'], "reply!") self.assertEqual(mess['transport_type'], "ussd") self.assertEqual(mess['to_addr'], '*123#') self.assertEqual(mess['session_event'], TransportUserMessage.SESSION_RESUME)
def test_submit_and_deliver_ussd_continue(self): session = SessionInfo() transport = yield self.get_transport() deliver_sm_processor = transport.deliver_sm_processor session_manager = deliver_sm_processor.session_manager yield session_manager.create_session( session.vumi_id, ussd_code='*123#') yield self.tx_helper.make_dispatch_outbound( "hello world", transport_type="ussd", transport_metadata={ 'session_info': { 'session_identifier': session.sixdee_id, } }, to_addr=session.addr) submit_sm_pdu = yield self.fake_smsc.await_pdu() self.assertEqual(command_id(submit_sm_pdu), 'submit_sm') self.assertEqual(pdu_tlv(submit_sm_pdu, 'ussd_service_op'), '02') self.assertEqual(pdu_tlv(submit_sm_pdu, 'its_session_info'), session.its_info) # Server delivers a USSD message to the Client pdu = DeliverSM(seq_no(submit_sm_pdu) + 1, short_message="reply!", source_addr=session.addr) # 0x12 is 'continue' pdu.add_optional_parameter('ussd_service_op', '12') pdu.add_optional_parameter('its_session_info', session.its_info) yield self.fake_smsc.handle_pdu(pdu) [mess] = yield self.tx_helper.wait_for_dispatched_inbound(1) self.assertEqual(mess['content'], "reply!") self.assertEqual(mess['transport_type'], "ussd") self.assertEqual(mess['to_addr'], '*123#') self.assertEqual(mess['session_event'], TransportUserMessage.SESSION_RESUME)
def test_enquire_link_looping(self): self.fake_smsc.auto_unbind = False protocol = yield self.get_protocol() yield self.fake_smsc.bind() self.assertEqual(self.fake_smsc.connected, True) # Respond to a few enquire_link cycles. for i in range(5): self.clock.advance(protocol.idle_timeout - 1) pdu = yield self.fake_smsc.await_pdu() self.assertCommand(pdu, 'enquire_link') yield self.fake_smsc.respond_to_enquire_link(pdu) # Fail to respond, so we disconnect. self.clock.advance(protocol.idle_timeout - 1) pdu = yield self.fake_smsc.await_pdu() self.assertCommand(pdu, 'enquire_link') self.clock.advance(1) unbind_pdu = yield self.fake_smsc.await_pdu() self.assertCommand(unbind_pdu, 'unbind') yield self.fake_smsc.send_pdu( UnbindResp(seq_no(unbind_pdu))) yield self.fake_smsc.await_disconnect()
def test_submit_and_deliver_ussd_continue(self): user_msisdn = "msisdn" session_identifier = 12345 vumi_session_identifier = make_vumi_session_identifier(user_msisdn, session_identifier) transport = yield self.get_transport() deliver_sm_processor = transport.deliver_sm_processor session_manager = deliver_sm_processor.session_manager yield session_manager.create_session(vumi_session_identifier, ussd_code="*123#") yield self.tx_helper.make_dispatch_outbound( "hello world", transport_type="ussd", transport_metadata={"session_info": {"session_identifier": session_identifier}}, to_addr=user_msisdn, ) submit_sm_pdu = yield self.fake_smsc.await_pdu() self.assertEqual(command_id(submit_sm_pdu), "submit_sm") self.assertEqual(pdu_tlv(submit_sm_pdu, "ussd_service_op"), "02") self.assertEqual(pdu_tlv(submit_sm_pdu, "user_message_reference"), session_identifier) # Server delivers a USSD message to the Client pdu = DeliverSM(seq_no(submit_sm_pdu) + 1, short_message="reply!", source_addr=user_msisdn) # 0x12 is 'continue' pdu.add_optional_parameter("ussd_service_op", "12") pdu.add_optional_parameter("user_message_reference", session_identifier) yield self.fake_smsc.handle_pdu(pdu) [mess] = yield self.tx_helper.wait_for_dispatched_inbound(1) self.assertEqual(mess["content"], "reply!") self.assertEqual(mess["transport_type"], "ussd") self.assertEqual(mess["to_addr"], "*123#") self.assertEqual(mess["session_event"], TransportUserMessage.SESSION_RESUME)
def handle_enquire_link(self, pdu): return self.send_pdu(EnquireLinkResp(seq_no(pdu)))