示例#1
0
 def setUp(self):
     self.service_calls = []
     self.encoder = pdu_encoding.PDUEncoder()
     self.smpp_config = SMPPServerConfig(msgHandler=self._serviceHandler,
                                         systems={'userA': {"max_bindings": 2}}
                                         )
     portal = Portal(self.SmppRealm())
     credential_checker = InMemoryUsernamePasswordDatabaseDontUse()
     credential_checker.addUser('userA', 'valid')
     portal.registerChecker(credential_checker)
     self.factory = SMPPServerFactory(self.smpp_config, auth_portal=portal)
     self.proto = self.factory.buildProtocol(('127.0.0.1', 0))
     self.tr = proto_helpers.StringTransport()
     self.proto.makeConnection(self.tr)
示例#2
0
class SMPPServerTimeoutTestCase(SMPPServerBaseTest):
    def setUp(self):
        self.service_calls = []
        self.clock = task.Clock()
        self.encoder = pdu_encoding.PDUEncoder()
        self.smpp_config = SMPPServerConfig(msgHandler=self._serviceHandler,
                                            systems={'userA': {"max_bindings": 2}},
                                            enquireLinkTimerSecs=0.1,
                                            responseTimerSecs=0.1
                                            )
        portal = Portal(self.SmppRealm())
        credential_checker = InMemoryUsernamePasswordDatabaseDontUse()
        credential_checker.addUser('userA', 'valid')
        portal.registerChecker(credential_checker)
        self.factory = SMPPServerFactory(self.smpp_config, auth_portal=portal)
        self.proto = self.factory.buildProtocol(('127.0.0.1', 0))
        self.proto.callLater = self.clock.callLater
        self.tr = proto_helpers.StringTransport()
        self.proto.makeConnection(self.tr)

    def testEnquireTimeout(self):
        self._bind()
        pdu = operations.SubmitSM(source_addr='t1', destination_addr='1208230', short_message='HELLO', seqNum=6)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.SubmitSMResp(seqNum=6)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        self.service_calls.pop()
        self.tr.clear()
        self.clock.advance(0.1)
        self.clock.advance(0.1)
        self.assertEqual(self.proto.sessionState, SMPPSessionStates.UNBIND_PENDING)
示例#3
0
class SMPPServerTimeoutTestCase(SMPPServerBaseTest):

    def setUp(self):
        self.service_calls = []
        self.clock = task.Clock()
        self.encoder = pdu_encoding.PDUEncoder()
        self.smpp_config = SMPPServerConfig(msgHandler=self._serviceHandler,
                                            systems={'userA': {"max_bindings": 2}},
                                            enquireLinkTimerSecs=0.1,
                                            responseTimerSecs=0.1
                                            )
        portal = Portal(self.SmppRealm())
        credential_checker = InMemoryUsernamePasswordDatabaseDontUse()
        credential_checker.addUser('userA', 'valid')
        portal.registerChecker(credential_checker)
        self.factory = SMPPServerFactory(self.smpp_config, auth_portal=portal)
        self.proto = self.factory.buildProtocol(('127.0.0.1', 0))
        self.proto.callLater = self.clock.callLater
        self.tr = proto_helpers.StringTransport()
        self.proto.makeConnection(self.tr)

    def testEnquireTimeout(self):
        self._bind()
        pdu = operations.SubmitSM(source_addr='t1', destination_addr='1208230', short_message='HELLO', seqNum=6)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.SubmitSMResp(seqNum=6)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        self.service_calls.pop()
        self.tr.clear()
        self.clock.advance(0.1)
        self.clock.advance(0.1)
        self.assertEqual(self.proto.sessionState, SMPPSessionStates.UNBIND_PENDING)
示例#4
0
    def buildProtocol(self, addr):
        """Provision protocol with the dedicated logger
        """
        proto = _SMPPServerFactory.buildProtocol(self, addr)

        # Setup logger
        proto.log = self.log

        return proto
示例#5
0
 def setUp(self):
     self.service_calls = []
     self.encoder = pdu_encoding.PDUEncoder()
     self.smpp_config = SMPPServerConfig(msgHandler=self._serviceHandler,
                                         systems={'userA': {"max_bindings": 2}}
                                         )
     portal = Portal(self.SmppRealm())
     credential_checker = InMemoryUsernamePasswordDatabaseDontUse()
     credential_checker.addUser('userA', 'valid')
     portal.registerChecker(credential_checker)
     self.factory = SMPPServerFactory(self.smpp_config, auth_portal=portal)
     self.proto = self.factory.buildProtocol(('127.0.0.1', 0))
     self.tr = proto_helpers.StringTransport()
     self.proto.makeConnection(self.tr)
示例#6
0
    def test_canOpenNewConnection_receiver(self):
        server = SMPPServerFactory(self.config, None)
        can_bind = server.canOpenNewConnection('lala', pdu_types.CommandId.bind_transceiver)
        self.assertTrue(can_bind, 'Should be able to bind trx as none bound yet')
        can_bind = server.canOpenNewConnection('lala', pdu_types.CommandId.bind_transmitter)
        self.assertTrue(can_bind, 'Should be able to bind tx as none bound yet')
        can_bind = server.canOpenNewConnection('lala', pdu_types.CommandId.bind_receiver)
        self.assertTrue(can_bind, 'Should be able to bind rx as none bound yet')

        mk_server_cnxn = _makeMockServerConnection('lala', pdu_types.CommandId.bind_receiver)
        server.addBoundConnection(mk_server_cnxn)
        can_bind = server.canOpenNewConnection('lala', pdu_types.CommandId.bind_transceiver)
        self.assertTrue(can_bind, 'Should still be able to bind as only one rx bound')
        can_bind = server.canOpenNewConnection('lala', pdu_types.CommandId.bind_transmitter)
        self.assertTrue(can_bind, 'Should still be able to bind only bindings are rx')
        can_bind = server.canOpenNewConnection('lala', pdu_types.CommandId.bind_receiver)
        self.assertTrue(can_bind, 'Should still be able to bind as only one rx bound')

        mk_server_cnxn = _makeMockServerConnection('lala', pdu_types.CommandId.bind_receiver)
        server.addBoundConnection(mk_server_cnxn)
        can_bind = server.canOpenNewConnection('lala', pdu_types.CommandId.bind_transceiver)
        self.assertFalse(can_bind, 'Should not be able to bind as two rx already bound')
        # NOTE this one different
        can_bind = server.canOpenNewConnection('lala', pdu_types.CommandId.bind_transmitter)
        self.assertTrue(can_bind, 'Should still be able to bind only bindings are rx')
        can_bind = server.canOpenNewConnection('lala', pdu_types.CommandId.bind_receiver)
        self.assertFalse(can_bind, 'Should not be able to bind as two rx already bound')
示例#7
0
class SMPPServerTestCase(SMPPServerBaseTest):
    def setUp(self):
        self.service_calls = []
        self.encoder = pdu_encoding.PDUEncoder()
        self.smpp_config = SMPPServerConfig(msgHandler=self._serviceHandler,
                                            systems={'userA': {"max_bindings": 2}}
                                            )
        portal = Portal(self.SmppRealm())
        credential_checker = InMemoryUsernamePasswordDatabaseDontUse()
        credential_checker.addUser('userA', 'valid')
        portal.registerChecker(credential_checker)
        self.factory = SMPPServerFactory(self.smpp_config, auth_portal=portal)
        self.proto = self.factory.buildProtocol(('127.0.0.1', 0))
        self.tr = proto_helpers.StringTransport()
        self.proto.makeConnection(self.tr)

    def tearDown(self):
        self.proto.connectionLost('test end')

    def testTRXBindRequest(self):
        pdu = operations.BindTransceiver(
            system_id='userA',
            password='******',
            seqNum=1
        )
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.BindTransceiverResp(system_id='userA', seqNum=1)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        connection = self.factory.getBoundConnections('userA')
        self.assertEqual(connection.system_id, 'userA')
        self.assertEqual(connection._binds[pdu_types.CommandId.bind_transceiver][0], self.proto)

    def testTRXBindRequestInvalidSysId(self):
        pdu = operations.BindTransceiver(
            system_id='userB',
            password='******',
            seqNum=1
        )
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.BindTransceiverResp(system_id='userB', seqNum=1,
                                                      status=pdu_types.CommandStatus.ESME_RINVPASWD)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        connection = self.factory.getBoundConnections('userA')
        self.assertEqual(connection, None)
        connection = self.factory.getBoundConnections('userB')
        self.assertEqual(connection, None)

    def testTRXBindRequestInvalidPassword(self):
        pdu = operations.BindTransceiver(
            system_id='userA',
            password='******',
            seqNum=1
        )
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.BindTransceiverResp(system_id='userA', seqNum=1,
                                                      status=pdu_types.CommandStatus.ESME_RINVPASWD)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        connection = self.factory.getBoundConnections('userA')
        self.assertEqual(connection, None)

    def testTransmitterBindRequest(self):
        system_id = 'userA'
        pdu = operations.BindTransmitter(
            system_id=system_id,
            password='******',
            seqNum=1
        )
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.BindTransmitterResp(system_id='userA', seqNum=1)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        self.tr.clear()
        connection = self.factory.getBoundConnections(system_id)
        self.assertEqual(connection.system_id, system_id)
        self.assertEqual(connection._binds[pdu_types.CommandId.bind_transmitter][0], self.proto)
        bind_manager = self.factory.getBoundConnections(system_id)
        delivery_binding = bind_manager.getNextBindingForDelivery()
        self.assertTrue(delivery_binding is None)

    def testReceiverBindRequest(self):
        system_id = 'userA'
        pdu = operations.BindReceiver(
            system_id=system_id,
            password='******',
            seqNum=1
        )
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.BindReceiverResp(system_id='userA', seqNum=1)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        self.tr.clear()
        connection = self.factory.getBoundConnections(system_id)
        self.assertEqual(connection.system_id, system_id)
        self.assertEqual(connection._binds[pdu_types.CommandId.bind_receiver][0], self.proto)
        bind_manager = self.factory.getBoundConnections(system_id)
        delivery_binding = bind_manager.getNextBindingForDelivery()
        self.assertTrue(delivery_binding is not None)
        # TODO Identify what should be returned here
        pdu = operations.SubmitSM(source_addr='t1', destination_addr='1208230', short_message='HELLO', seqNum=6)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.SubmitSMResp(seqNum=6)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))

    def testUnboundSubmitRequest(self):
        pdu = operations.SubmitSM(source_addr='t1', destination_addr='1208230', short_message='HELLO', seqNum=1)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.SubmitSMResp(status=pdu_types.CommandStatus.ESME_RINVBNDSTS, seqNum=1)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))

    def testUnboundSubmitRequest(self):
        pdu = operations.EnquireLink(seqNum=576)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.EnquireLinkResp(status=pdu_types.CommandStatus.ESME_RINVBNDSTS, seqNum=576)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))

    def testTRXUnbindRequest(self):
        self._bind()
        pdu = operations.Unbind(seqNum=346)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.UnbindResp(seqNum=346)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        connection = self.factory.getBoundConnections('userA')
        self.assertEqual(connection.system_id, 'userA')
        # Still in list of binds as the connection has not been closed yet. is removed after test tearDown
        self.assertEqual(connection._binds[pdu_types.CommandId.bind_transceiver][0].sessionState,
                         SMPPSessionStates.UNBOUND)

    def testTRXSubmitSM(self):
        self._bind()
        pdu = operations.SubmitSM(source_addr='t1', destination_addr='1208230', short_message='HELLO', seqNum=6)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.SubmitSMResp(seqNum=6)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        system_id, smpp, pdu_notified = self.service_calls.pop()
        self.assertEqual(system_id, self.proto.system_id)
        self.assertEqual(pdu.params['short_message'], pdu_notified.params['short_message'])
        self.assertEqual(pdu.params['source_addr'], pdu_notified.params['source_addr'])
        self.assertEqual(pdu.params['destination_addr'], pdu_notified.params['destination_addr'])

    def testTRXDataSM(self):
        self._bind()
        pdu = operations.DataSM(source_addr='t1', destination_addr='1208230', short_message='tests', seqNum=6)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.DataSMResp(seqNum=6)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        system_id, smpp, pdu_notified = self.service_calls.pop()
        self.assertEqual(system_id, self.proto.system_id)

    def testTRXQuerySM(self):
        def _serviceHandler(system_id, smpp, pdu):
            self.service_calls.append((system_id, smpp, pdu))
            return DataHandlerResponse(status=pdu_types.CommandStatus.ESME_ROK,
                                       message_id='tests',
                                       final_date=None,
                                       message_state=pdu_types.MessageState.ACCEPTED,
                                       error_code=0)

        self.proto.dataRequestHandler = lambda *args, **kwargs: _serviceHandler(self.proto.system_id, *args, **kwargs)
        self._bind()
        pdu = operations.QuerySM(message_id='tests', source_addr='t1', seqNum=23)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.QuerySMResp(message_id='tests', error_code=0, final_date=None,
                                              message_state=pdu_types.MessageState.ACCEPTED, seqNum=23)
        # Does not work as application using library must reply correctly.
        print(self.tr.value())
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        system_id, smpp, pdu_notified = self.service_calls.pop()
        self.assertEqual(system_id, self.proto.system_id)

    def testRecievePduWhileUnbindPending(self):
        self._bind()
        self.proto.unbind()
        expected_pdu = operations.Unbind(seqNum=1)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        self.tr.clear()
        pdu = operations.SubmitSM(source_addr='t1', destination_addr='1208230', short_message='HELLO', seqNum=6)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.SubmitSMResp(seqNum=6)
        self.assertEqual(self.tr.value(), '')
        pdu = operations.UnbindResp(seqNum=1)
        self.proto.dataReceived(self.encoder.encode(pdu))

    def testTRXClientUnbindRequestAfterSubmit(self):
        d = defer.Deferred()

        def _serviceHandler(system_id, smpp, pdu):
            logging.debug("%s, %s, %s", system_id, smpp, pdu)
            return d

        self.proto.dataRequestHandler = lambda *args, **kwargs: _serviceHandler(self.proto.system_id, *args, **kwargs)
        self._bind()

        pdu = operations.SubmitSM(source_addr='t1', destination_addr='1208230', short_message='HELLO', seqNum=1)
        self.proto.dataReceived(self.encoder.encode(pdu))
        pdu = operations.Unbind(seqNum=52)
        self.proto.dataReceived(self.encoder.encode(pdu))

        # All PDU requests should fail now.
        # Once we fire this we should get our Submit Resp and the unbind Resp
        pdu = operations.SubmitSM(source_addr='t1', destination_addr='1208230', short_message='goodbye', seqNum=5)
        self.proto.dataReceived(self.encoder.encode(pdu))

        unbind_resp_pdu = operations.UnbindResp(seqNum=52)
        submit_fail_pdu = operations.SubmitSMResp(status=pdu_types.CommandStatus.ESME_RINVBNDSTS, seqNum=5)
        # We should have a reply here as our service handler should not be called
        self.assertEqual(self.tr.value(), self.encoder.encode(submit_fail_pdu))
        self.tr.clear()

        d.callback(pdu_types.CommandStatus.ESME_ROK)
        # Then we should get our initial message response and the unbind response
        expected_pdu = operations.SubmitSMResp(seqNum=1)
        self.assertEqual(self.tr.value(),
                         '%s%s' % (self.encoder.encode(expected_pdu), self.encoder.encode(unbind_resp_pdu)))

    def testTRXServerUnbindRequestAfterSubmit(self):
        deferreds = []

        def _serviceHandler(system_id, smpp, pdu):
            d = defer.Deferred()
            deferreds.append(d)
            logging.debug("%s, %s, %s", system_id, smpp, pdu)
            return d

        self.proto.dataRequestHandler = lambda *args, **kwargs: _serviceHandler(self.proto.system_id, *args, **kwargs)
        self._bind()

        pdu = operations.SubmitSM(source_addr='t1', destination_addr='1208230', short_message='HELLO', seqNum=1)
        self.proto.dataReceived(self.encoder.encode(pdu))
        unbind_d = self.proto.unbind()
        print(self.tr.value())

        pdu2 = operations.SubmitSM(source_addr='t1', destination_addr='1208230', short_message='HELLO2', seqNum=2)
        self.proto.dataReceived(self.encoder.encode(pdu))

        self.assertEqual(1, len(deferreds))
        self.assertEqual(self.tr.value(), '')
        self.tr.clear()
        deferreds[-1].callback(pdu_types.CommandStatus.ESME_ROK)
        deferreds = deferreds[:-1]
        submit_resp_pdu = operations.SubmitSMResp(seqNum=1)

        unbind_pdu = operations.Unbind(seqNum=1)
        # We should have a reply here as our service handler should not be called
        self.assertEqual(self.tr.value(),
                         '%s%s' % (self.encoder.encode(submit_resp_pdu), self.encoder.encode(unbind_pdu)))
        self.tr.clear()
        pdu = operations.UnbindResp(seqNum=1)
        self.proto.dataReceived(self.encoder.encode(pdu))
    def test_canOpenNewConnection_transmitter(self):
        server = SMPPServerFactory(self.config, None)
        can_bind = server.canOpenNewConnection(
            'lala', pdu_types.CommandId.bind_transceiver)
        self.assertTrue(can_bind,
                        'Should be able to bind trx as none bound yet')
        can_bind = server.canOpenNewConnection(
            'lala', pdu_types.CommandId.bind_transmitter)
        self.assertTrue(can_bind,
                        'Should be able to bind tx as none bound yet')
        can_bind = server.canOpenNewConnection(
            'lala', pdu_types.CommandId.bind_receiver)
        self.assertTrue(can_bind,
                        'Should be able to bind rx as none bound yet')

        mk_server_cnxn = _makeMockServerConnection(
            'lala', pdu_types.CommandId.bind_transmitter)
        server.addBoundConnection(mk_server_cnxn)
        can_bind = server.canOpenNewConnection(
            'lala', pdu_types.CommandId.bind_transceiver)
        self.assertTrue(can_bind,
                        'Should still be able to bind as only one tx bound')
        can_bind = server.canOpenNewConnection(
            'lala', pdu_types.CommandId.bind_transmitter)
        self.assertTrue(can_bind,
                        'Should still be able to bind as only one tx bound')
        can_bind = server.canOpenNewConnection(
            'lala', pdu_types.CommandId.bind_receiver)
        self.assertTrue(can_bind,
                        'Should still be able to bind only bindings are tx')

        mk_server_cnxn = _makeMockServerConnection(
            'lala', pdu_types.CommandId.bind_transmitter)
        server.addBoundConnection(mk_server_cnxn)
        can_bind = server.canOpenNewConnection(
            'lala', pdu_types.CommandId.bind_transceiver)
        self.assertFalse(can_bind,
                         'Should not be able to bind as two tx already bound')
        can_bind = server.canOpenNewConnection(
            'lala', pdu_types.CommandId.bind_transmitter)
        self.assertFalse(can_bind,
                         'Should not be able to bind as two tx already bound')
        # NOTE this one different
        can_bind = server.canOpenNewConnection(
            'lala', pdu_types.CommandId.bind_receiver)
        self.assertTrue(can_bind,
                        'Should still be able to bind only bindings are tx')
class SMPPServerTestCase(SMPPServerBaseTest):
    def setUp(self):
        self.service_calls = []
        self.encoder = pdu_encoding.PDUEncoder()
        self.smpp_config = SMPPServerConfig(
            msgHandler=self._serviceHandler,
            systems={'userA': {
                "max_bindings": 2
            }})
        portal = Portal(self.SmppRealm())
        credential_checker = InMemoryUsernamePasswordDatabaseDontUse()
        credential_checker.addUser('userA', 'valid')
        portal.registerChecker(credential_checker)
        self.factory = SMPPServerFactory(self.smpp_config, auth_portal=portal)
        self.proto = self.factory.buildProtocol(('127.0.0.1', 0))
        self.tr = proto_helpers.StringTransport()
        self.proto.makeConnection(self.tr)

    def tearDown(self):
        self.proto.connectionLost('test end')

    def testTRXBindRequest(self):
        pdu = operations.BindTransceiver(system_id='userA',
                                         password='******',
                                         seqNum=1)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.BindTransceiverResp(system_id='userA',
                                                      seqNum=1)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        connection = self.factory.getBoundConnections('userA')
        self.assertEqual(connection.system_id, 'userA')
        self.assertEqual(
            connection._binds[pdu_types.CommandId.bind_transceiver][0],
            self.proto)

    def testTRXBindRequestInvalidSysId(self):
        pdu = operations.BindTransceiver(system_id='userB',
                                         password='******',
                                         seqNum=1)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.BindTransceiverResp(
            system_id='userB',
            seqNum=1,
            status=pdu_types.CommandStatus.ESME_RINVSYSID)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        connection = self.factory.getBoundConnections('userA')
        self.assertEqual(connection, None)
        connection = self.factory.getBoundConnections('userB')
        self.assertEqual(connection, None)

    def testTRXBindRequestInvalidPassword(self):
        pdu = operations.BindTransceiver(system_id='userA',
                                         password='******',
                                         seqNum=1)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.BindTransceiverResp(
            system_id='userA',
            seqNum=1,
            status=pdu_types.CommandStatus.ESME_RINVPASWD)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        connection = self.factory.getBoundConnections('userA')
        self.assertEqual(connection, None)

    def testTransmitterBindRequest(self):
        system_id = 'userA'
        pdu = operations.BindTransmitter(system_id=system_id,
                                         password='******',
                                         seqNum=1)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.BindTransmitterResp(system_id='userA',
                                                      seqNum=1)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        self.tr.clear()
        connection = self.factory.getBoundConnections(system_id)
        self.assertEqual(connection.system_id, system_id)
        self.assertEqual(
            connection._binds[pdu_types.CommandId.bind_transmitter][0],
            self.proto)
        bind_manager = self.factory.getBoundConnections(system_id)
        delivery_binding = bind_manager.getNextBindingForDelivery()
        self.assertTrue(delivery_binding is None)

    def testReceiverBindRequest(self):
        system_id = 'userA'
        pdu = operations.BindReceiver(system_id=system_id,
                                      password='******',
                                      seqNum=1)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.BindReceiverResp(system_id='userA', seqNum=1)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        self.tr.clear()
        connection = self.factory.getBoundConnections(system_id)
        self.assertEqual(connection.system_id, system_id)
        self.assertEqual(
            connection._binds[pdu_types.CommandId.bind_receiver][0],
            self.proto)
        bind_manager = self.factory.getBoundConnections(system_id)
        delivery_binding = bind_manager.getNextBindingForDelivery()
        self.assertTrue(delivery_binding is not None)
        # TODO Identify what should be returned here
        pdu = operations.SubmitSM(source_addr='t1',
                                  destination_addr='1208230',
                                  short_message='HELLO',
                                  seqNum=6)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.SubmitSMResp(seqNum=6)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))

    def testUnboundSubmitRequest(self):
        pdu = operations.SubmitSM(source_addr='t1',
                                  destination_addr='1208230',
                                  short_message='HELLO',
                                  seqNum=1)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.SubmitSMResp(
            status=pdu_types.CommandStatus.ESME_RINVBNDSTS, seqNum=1)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))

    def testUnboundSubmitRequest(self):
        pdu = operations.EnquireLink(seqNum=576)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.EnquireLinkResp(
            status=pdu_types.CommandStatus.ESME_RINVBNDSTS, seqNum=576)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))

    def testTRXUnbindRequest(self):
        self._bind()
        pdu = operations.Unbind(seqNum=346)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.UnbindResp(seqNum=346)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        connection = self.factory.getBoundConnections('userA')
        self.assertEqual(connection.system_id, 'userA')
        # Still in list of binds as the connection has not been closed yet. is removed after test tearDown
        self.assertEqual(
            connection._binds[pdu_types.CommandId.bind_transceiver]
            [0].sessionState, SMPPSessionStates.UNBOUND)

    def testTRXSubmitSM(self):
        self._bind()
        pdu = operations.SubmitSM(source_addr='t1',
                                  destination_addr='1208230',
                                  short_message='HELLO',
                                  seqNum=6)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.SubmitSMResp(seqNum=6)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        system_id, smpp, pdu_notified = self.service_calls.pop()
        self.assertEqual(system_id, self.proto.system_id)
        self.assertEqual(pdu.params['short_message'],
                         pdu_notified.params['short_message'])
        self.assertEqual(pdu.params['source_addr'],
                         pdu_notified.params['source_addr'])
        self.assertEqual(pdu.params['destination_addr'],
                         pdu_notified.params['destination_addr'])

    def testTRXDataSM(self):
        self._bind()
        pdu = operations.DataSM(source_addr='t1',
                                destination_addr='1208230',
                                short_message='tests',
                                seqNum=6)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.DataSMResp(seqNum=6)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        system_id, smpp, pdu_notified = self.service_calls.pop()
        self.assertEqual(system_id, self.proto.system_id)

    def testTRXQuerySM(self):
        def _serviceHandler(system_id, smpp, pdu):
            self.service_calls.append((system_id, smpp, pdu))
            return DataHandlerResponse(
                status=pdu_types.CommandStatus.ESME_ROK,
                message_id='tests',
                final_date=None,
                message_state=pdu_types.MessageState.ACCEPTED,
                error_code=0)

        self.proto.dataRequestHandler = lambda *args, **kwargs: _serviceHandler(
            self.proto.system_id, *args, **kwargs)
        self._bind()
        pdu = operations.QuerySM(message_id='tests',
                                 source_addr='t1',
                                 seqNum=23)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.QuerySMResp(
            message_id='tests',
            error_code=0,
            final_date=None,
            message_state=pdu_types.MessageState.ACCEPTED,
            seqNum=23)
        # Does not work as application using library must reply correctly.
        print self.tr.value()
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        system_id, smpp, pdu_notified = self.service_calls.pop()
        self.assertEqual(system_id, self.proto.system_id)

    def testRecievePduWhileUnbindPending(self):
        self._bind()
        self.proto.unbind()
        expected_pdu = operations.Unbind(seqNum=1)
        self.assertEqual(self.tr.value(), self.encoder.encode(expected_pdu))
        self.tr.clear()
        pdu = operations.SubmitSM(source_addr='t1',
                                  destination_addr='1208230',
                                  short_message='HELLO',
                                  seqNum=6)
        self.proto.dataReceived(self.encoder.encode(pdu))
        expected_pdu = operations.SubmitSMResp(seqNum=6)
        self.assertEqual(self.tr.value(), '')
        pdu = operations.UnbindResp(seqNum=1)
        self.proto.dataReceived(self.encoder.encode(pdu))

    def testTRXClientUnbindRequestAfterSubmit(self):
        d = defer.Deferred()

        def _serviceHandler(system_id, smpp, pdu):
            logging.debug("%s, %s, %s", system_id, smpp, pdu)
            return d

        self.proto.dataRequestHandler = lambda *args, **kwargs: _serviceHandler(
            self.proto.system_id, *args, **kwargs)
        self._bind()

        pdu = operations.SubmitSM(source_addr='t1',
                                  destination_addr='1208230',
                                  short_message='HELLO',
                                  seqNum=1)
        self.proto.dataReceived(self.encoder.encode(pdu))
        pdu = operations.Unbind(seqNum=52)
        self.proto.dataReceived(self.encoder.encode(pdu))

        #All PDU requests should fail now.
        #Once we fire this we should get our Submit Resp and the unbind Resp
        pdu = operations.SubmitSM(source_addr='t1',
                                  destination_addr='1208230',
                                  short_message='goodbye',
                                  seqNum=5)
        self.proto.dataReceived(self.encoder.encode(pdu))

        unbind_resp_pdu = operations.UnbindResp(seqNum=52)
        submit_fail_pdu = operations.SubmitSMResp(
            status=pdu_types.CommandStatus.ESME_RINVBNDSTS, seqNum=5)
        # We should have a reply here as our service handler should not be called
        self.assertEqual(self.tr.value(), self.encoder.encode(submit_fail_pdu))
        self.tr.clear()

        d.callback(pdu_types.CommandStatus.ESME_ROK)
        #Then we should get our initial message response and the unbind response
        expected_pdu = operations.SubmitSMResp(seqNum=1)
        self.assertEqual(
            self.tr.value(), '%s%s' % (self.encoder.encode(expected_pdu),
                                       self.encoder.encode(unbind_resp_pdu)))

    def testTRXServerUnbindRequestAfterSubmit(self):
        deferreds = []

        def _serviceHandler(system_id, smpp, pdu):
            d = defer.Deferred()
            deferreds.append(d)
            logging.debug("%s, %s, %s", system_id, smpp, pdu)
            return d

        self.proto.dataRequestHandler = lambda *args, **kwargs: _serviceHandler(
            self.proto.system_id, *args, **kwargs)
        self._bind()

        pdu = operations.SubmitSM(source_addr='t1',
                                  destination_addr='1208230',
                                  short_message='HELLO',
                                  seqNum=1)
        self.proto.dataReceived(self.encoder.encode(pdu))
        unbind_d = self.proto.unbind()
        print self.tr.value()

        pdu2 = operations.SubmitSM(source_addr='t1',
                                   destination_addr='1208230',
                                   short_message='HELLO2',
                                   seqNum=2)
        self.proto.dataReceived(self.encoder.encode(pdu))

        self.assertEqual(1, len(deferreds))
        self.assertEqual(self.tr.value(), '')
        self.tr.clear()
        deferreds[-1].callback(pdu_types.CommandStatus.ESME_ROK)
        deferreds = deferreds[:-1]
        submit_resp_pdu = operations.SubmitSMResp(seqNum=1)

        unbind_pdu = operations.Unbind(seqNum=1)
        # We should have a reply here as our service handler should not be called
        self.assertEqual(
            self.tr.value(), '%s%s' % (self.encoder.encode(submit_resp_pdu),
                                       self.encoder.encode(unbind_pdu)))
        self.tr.clear()
        pdu = operations.UnbindResp(seqNum=1)
        self.proto.dataReceived(self.encoder.encode(pdu))