def test_match_resp(self): message1 = self.mkmsg_out( message_id='444', content="hello world", to_addr="1111111111") sequence_num1 = self.esme.get_seq() response1 = SubmitSMResp(sequence_num1, "3rd_party_id_1") yield self.transport._process_message(message1) message2 = self.mkmsg_out( message_id='445', content="hello world", to_addr="1111111111") sequence_num2 = self.esme.get_seq() response2 = SubmitSMResp(sequence_num2, "3rd_party_id_2") yield self.transport._process_message(message2) # respond out of order - just to keep things interesting self.esme.handle_data(response2.get_bin()) self.esme.handle_data(response1.get_bin()) self.assertEqual([ self.mkmsg_ack('445', '3rd_party_id_2'), self.mkmsg_ack('444', '3rd_party_id_1'), ], self.get_dispatched_events()) message3 = self.mkmsg_out( message_id='446', content="hello world", to_addr="1111111111") sequence_num3 = self.esme.get_seq() response3 = SubmitSMResp(sequence_num3, "3rd_party_id_3", command_status="ESME_RSUBMITFAIL") self.transport._process_message(message3) self.esme.handle_data(response3.get_bin()) # There should be no ack self.assertEqual([], self.get_dispatched_events()[2:]) comparison = self.mkmsg_fail(message3.payload, 'ESME_RSUBMITFAIL') actual = self.get_dispatched_failures()[0] self.assertEqual(actual, comparison) message4 = self.mkmsg_out( message_id=447, content="hello world", to_addr="1111111111") sequence_num4 = self.esme.get_seq() response4 = SubmitSMResp(sequence_num4, "3rd_party_id_4", command_status="ESME_RTHROTTLED") self.transport._process_message(message4) self.esme.handle_data(response4.get_bin()) # There should be no ack self.assertEqual([], self.get_dispatched_events()[3:]) comparison = self.mkmsg_fail(message4.payload, 'ESME_RTHROTTLED') actual = self.get_dispatched_failures()[1] self.assertEqual(actual, comparison)
def test_on_submit_sm_resp(self): calls = [] self.patch(EsmeTransceiver, 'on_submit_sm_resp', lambda p, *a: calls.append(a)) transport, protocol = yield self.setup_bind() pdu = SubmitSMResp(sequence_number=0, message_id='foo') protocol.dataReceived(pdu.get_bin()) self.assertEqual(calls, [(0, 'foo', 'ESME_ROK')])
def test_out_of_order_responses(self): # Sequence numbers are hardcoded, assuming we start fresh from 0. yield self.tx_helper.make_dispatch_outbound("msg 1", message_id='444') response1 = SubmitSMResp(1, "3rd_party_id_1") yield self.tx_helper.make_dispatch_outbound("msg 2", message_id='445') response2 = SubmitSMResp(2, "3rd_party_id_2") self.assert_sent_contents(["msg 1", "msg 2"]) # respond out of order - just to keep things interesting yield self.esme.handle_data(response2.get_bin()) yield self.esme.handle_data(response1.get_bin()) [ack1, ack2] = self.tx_helper.get_dispatched_events() 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_failed_submit(self): message = yield self.tx_helper.make_dispatch_outbound( "message", message_id='446') response = SubmitSMResp( 1, "3rd_party_id_3", command_status="ESME_RSUBMITFAIL") yield self.esme.handle_data(response.get_bin()) self.assert_sent_contents(["message"]) # 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'], 'ESME_RSUBMITFAIL') [failure] = yield self.tx_helper.get_dispatched_failures() self.assertEqual(failure['reason'], 'ESME_RSUBMITFAIL')
def test_failed_submit(self): message = yield self.tx_helper.make_dispatch_outbound("message", message_id='446') response = SubmitSMResp(1, "3rd_party_id_3", command_status="ESME_RSUBMITFAIL") yield self.esme.handle_data(response.get_bin()) self.assert_sent_contents(["message"]) # 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'], 'ESME_RSUBMITFAIL') [failure] = yield self.tx_helper.get_dispatched_failures() self.assertEqual(failure['reason'], 'ESME_RSUBMITFAIL')
def test_throttled_submit_ESME_RMSGQFUL(self): clock = Clock() self.transport.callLater = clock.callLater def assert_throttled_status(throttled, messages, acks): self.assertEqual(self.transport.throttled, throttled) self.assert_sent_contents(messages) self.assertEqual(acks, [(m['user_message_id'], m['sent_message_id']) for m in self.tx_helper.get_dispatched_events()]) self.assertEqual([], self.tx_helper.get_dispatched_failures()) assert_throttled_status(False, [], []) yield self.tx_helper.make_dispatch_outbound("Heimlich", message_id="447") response = SubmitSMResp(1, "3rd_party_id_4", command_status="ESME_RMSGQFUL") yield self.esme.handle_data(response.get_bin()) assert_throttled_status(True, ["Heimlich"], []) # Still waiting to resend clock.advance(0.05) yield self.transport.redis.exists('wait for redis') assert_throttled_status(True, ["Heimlich"], []) # Don't wait for this, because it won't be processed until later. self.tx_helper.make_dispatch_outbound("Other", message_id="448") assert_throttled_status(True, ["Heimlich"], []) # Resent clock.advance(0.05) yield self.transport.redis.exists('wait for redis') assert_throttled_status(True, ["Heimlich", "Heimlich"], []) # And acknowledged by the other side yield self.esme.handle_data(SubmitSMResp(2, "3rd_party_5").get_bin()) yield self.tx_helper.kick_delivery() yield self.esme.handle_data(SubmitSMResp(3, "3rd_party_6").get_bin()) assert_throttled_status(False, ["Heimlich", "Heimlich", "Other"], [('447', '3rd_party_5'), ('448', '3rd_party_6')])
def test_throttled_submit_ESME_RMSGQFUL(self): clock = Clock() self.transport.callLater = clock.callLater def assert_throttled_status(throttled, messages, acks): self.assertEqual(self.transport.throttled, throttled) self.assert_sent_contents(messages) self.assertEqual(acks, [ (m['user_message_id'], m['sent_message_id']) for m in self.tx_helper.get_dispatched_events()]) self.assertEqual([], self.tx_helper.get_dispatched_failures()) assert_throttled_status(False, [], []) yield self.tx_helper.make_dispatch_outbound( "Heimlich", message_id="447") response = SubmitSMResp(1, "3rd_party_id_4", command_status="ESME_RMSGQFUL") yield self.esme.handle_data(response.get_bin()) assert_throttled_status(True, ["Heimlich"], []) # Still waiting to resend clock.advance(0.05) yield self.transport.redis.exists('wait for redis') assert_throttled_status(True, ["Heimlich"], []) # Don't wait for this, because it won't be processed until later. self.tx_helper.make_dispatch_outbound("Other", message_id="448") assert_throttled_status(True, ["Heimlich"], []) # Resent clock.advance(0.05) yield self.transport.redis.exists('wait for redis') assert_throttled_status(True, ["Heimlich", "Heimlich"], []) # And acknowledged by the other side yield self.esme.handle_data(SubmitSMResp(2, "3rd_party_5").get_bin()) yield self.tx_helper.kick_delivery() yield self.esme.handle_data(SubmitSMResp(3, "3rd_party_6").get_bin()) assert_throttled_status( False, ["Heimlich", "Heimlich", "Other"], [('447', '3rd_party_5'), ('448', '3rd_party_6')])
def test_match_resp(self): message1 = self.mkmsg_out( message_id='444', content="hello world", to_addr="1111111111") sequence_num1 = self.esme.getSeq() response1 = SubmitSMResp(sequence_num1, "3rd_party_id_1") yield self.transport._process_message(message1) message2 = self.mkmsg_out( message_id='445', content="hello world", to_addr="1111111111") sequence_num2 = self.esme.getSeq() response2 = SubmitSMResp(sequence_num2, "3rd_party_id_2") yield self.transport._process_message(message2) # respond out of order - just to keep things interesting self.esme.handleData(response2.get_bin()) self.esme.handleData(response1.get_bin()) self.assertEqual([ self.mkmsg_ack('445', '3rd_party_id_2'), self.mkmsg_ack('444', '3rd_party_id_1'), ], self.get_dispatched_events()) message3 = self.mkmsg_out( message_id=446, content="hello world", to_addr="1111111111") sequence_num3 = self.esme.getSeq() response3 = SubmitSMResp(sequence_num3, "3rd_party_id_3", command_status="ESME_RSUBMITFAIL") self.transport._process_message(message3) self.esme.handleData(response3.get_bin()) self.assertEqual([self.mkmsg_ack('446', '3rd_party_id_3')], self.get_dispatched_events()[2:]) self.assertEqual([self.mkmsg_fail({'id': '446'}, 'ESME_RSUBMITFAIL')], self.get_dispatched_failures()) message4 = self.mkmsg_out( message_id=447, content="hello world", to_addr="1111111111") sequence_num4 = self.esme.getSeq() response4 = SubmitSMResp(sequence_num4, "3rd_party_id_4", command_status="ESME_RTHROTTLED") self.transport._process_message(message4) self.esme.handleData(response4.get_bin()) self.assertEqual([self.mkmsg_ack('447', '3rd_party_id_4')], self.get_dispatched_events()[3:]) self.assertTrue(self.transport.throttle_invoked_via_pdu) fail_msg = self.mkmsg_out( message_id=555, content="hello world", to_addr="1111111111") self.transport.send_failure(fail_msg, Exception("Foo"), "testing") self.assertEqual([self.mkmsg_fail(fail_msg.payload, "testing")], self.get_dispatched_failures()[1:]) # Some error codes would occur on bind attempts bind_dispatch_methods = { "ESME_ROK": self.transport.ok, "ESME_RINVBNDSTS": self.transport.conn_tempfault, "ESME_RALYBND": self.transport.conn_tempfault, "ESME_RSYSERR": self.transport.conn_permfault, "ESME_RBINDFAIL": self.transport.conn_permfault, "ESME_RINVPASWD": self.transport.conn_permfault, "ESME_RINVSYSID": self.transport.conn_permfault, "ESME_RINVSERTYP": self.transport.conn_permfault, } # Some error codes would occur post bind i.e. on submission attempts submit_dispatch_methods = { "ESME_RINVMSGLEN": self.transport.mess_permfault, "ESME_RINVCMDLEN": self.transport.mess_permfault, "ESME_RINVCMDID": self.transport.mess_permfault, "ESME_RINVPRTFLG": self.transport.mess_permfault, "ESME_RINVREGDLVFLG": self.transport.mess_permfault, "ESME_RINVSRCADR": self.transport.mess_permfault, "ESME_RINVDSTADR": self.transport.mess_permfault, "ESME_RINVMSGID": self.transport.mess_permfault, "ESME_RCANCELFAIL": self.transport.mess_permfault, "ESME_RREPLACEFAIL": self.transport.mess_permfault, "ESME_RMSGQFUL": self.transport.conn_throttle, "ESME_RINVNUMDESTS": self.transport.mess_permfault, "ESME_RINVDLNAME": self.transport.mess_permfault, "ESME_RINVDESTFLAG": self.transport.mess_permfault, "ESME_RINVSUBREP": self.transport.mess_permfault, "ESME_RINVESMCLASS": self.transport.mess_permfault, "ESME_RCNTSUBDL": self.transport.mess_permfault, "ESME_RSUBMITFAIL": self.transport.mess_tempfault, "ESME_RINVSRCTON": self.transport.mess_permfault, "ESME_RINVSRCNPI": self.transport.mess_permfault, "ESME_RINVDSTTON": self.transport.mess_permfault, "ESME_RINVDSTNPI": self.transport.mess_permfault, "ESME_RINVSYSTYP": self.transport.conn_permfault, "ESME_RINVREPFLAG": self.transport.mess_permfault, "ESME_RINVNUMMSGS": self.transport.mess_tempfault, "ESME_RTHROTTLED": self.transport.conn_throttle, "ESME_RINVSCHED": self.transport.mess_permfault, "ESME_RINVEXPIRY": self.transport.mess_permfault, "ESME_RINVDFTMSGID": self.transport.mess_permfault, "ESME_RX_T_APPN": self.transport.mess_tempfault, "ESME_RX_P_APPN": self.transport.mess_permfault, "ESME_RX_R_APPN": self.transport.mess_permfault, "ESME_RQUERYFAIL": self.transport.mess_permfault, "ESME_RINVOPTPARSTREAM": self.transport.mess_permfault, "ESME_ROPTPARNOTALLWD": self.transport.mess_permfault, "ESME_RINVPARLEN": self.transport.mess_permfault, "ESME_RMISSINGOPTPARAM": self.transport.mess_permfault, "ESME_RINVOPTPARAMVAL": self.transport.mess_permfault, "ESME_RDELIVERYFAILURE": self.transport.mess_tempfault, "ESME_RUNKNOWNERR": self.transport.mess_tempfault, } # Also have unknown error codes newfangled_fake_error = { "ESME_NEWFNGLEDFAKERR": self.esme.dummy_unknown, } for code, method in bind_dispatch_methods.items(): response = BindTransceiverResp(1, code) # check the dispatcher returns the correct transport method self.assertEquals(method, self.esme.command_status_dispatch(response.get_obj())) for code, method in submit_dispatch_methods.items(): response = SubmitSMResp(1, "2", code) # check the dispatcher returns the correct transport method self.assertEquals(method, self.esme.command_status_dispatch(response.get_obj())) for code, method in newfangled_fake_error.items(): response = SubmitSMResp(1, "2", code) # check the dispatcher returns the correct transport method self.assertEquals(method, self.esme.command_status_dispatch(response.get_obj()))