Python 扭曲反应器在使用trail运行时未收到回复 给你

Python 扭曲反应器在使用trail运行时未收到回复 给你,python,twisted,Python,Twisted,有一个类主体将消息发送到远程透视图 经纪人(PB)朋友 测试正在检查Me实例是否可以与进行通信 通过呼叫“对朋友说话”或“告诉方法”来结交朋友 speak_uuto_uuFriend是Soul.speak虚拟函数的包装器,它被Body.tell方法覆盖。 灵魂阶层被封装在身体里 通过等待收到的回调函数中的gotAnswer事件,告诉方法模拟阻塞调用 根据打印输出,Friend与我的沟通方式与unittest和独立案例相同 问题 。。。就是说,当使用try运行unittest(unittest

有一个类主体将消息发送到远程透视图 经纪人(PB)朋友

  • 测试正在检查Me实例是否可以与进行通信 通过呼叫“对朋友说话”或“告诉方法”来结交朋友

  • speak_uuto_uuFriend是Soul.speak虚拟函数的包装器,它被Body.tell方法覆盖。 灵魂阶层被封装在身体里

  • 通过等待收到的回调函数中的gotAnswer事件,告诉方法模拟阻塞调用

  • 根据打印输出,Friend与我的沟通方式与unittest和独立案例相同

  • 问题 。。。就是说,当使用try运行unittest(unittest me.py)时,从未调用收到的回调。而不是在客户端打印愚蠢的错误消息:

    连接完全关闭

    在我看来,在延迟队列被完全处理之前,反应器已经关闭

    如果我正在运行standalone test-test-body.py,那么一切都按预期进行:朋友和我交谈

    问题
  • 在这种情况下,为什么unittest的行为不同
  • 如何修复它

  • 单元测试输出 test-body.py body.py friend.py
    Python2.7\Scripts\trial.py ..\Soapbox\Node\unittest-me.py
    unittest-me
      Trial_TestCase
        test_conversation ... wake upConnecting to localhost:18800
    
    DBG: speak
    DBG: say
                                                   [FAIL]
    Friend not willing to talk with me because:  [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone
    '>: Connection was closed cleanly.
    ]
    
    ===============================================================================
    [FAIL]
    Traceback (most recent call last):
      File "..\Soapbox\Node\unittest-me.py", line 50, in test_conversation
        self.assertTrue(answer is not None, "Friend gave no answer")
    twisted.trial.unittest.FailTest: Friend gave no answer
    
    unittest-me.Trial_TestCase.test_conversation
    -------------------------------------------------------------------------------
    Ran 1 tests in 3.096s
    
    FAILED (failures=1)
    
    python test-body.py
    connector:  <twisted.internet.tcp.Connector instance at 0x01C87940>
    Press any key to continue...Starting reactor
    
    
    wake upDBG: speak
    DBG: say
    
    DBG: received
    Friend's reply: <username>
    Press any key to continue...
    
    That's all
    
    Dr. Livesey: I got your words: whoami
    DBG: answer:  <username>
    
    Dr. Livesey: I got your words: whoami
    DBG: answer:  <username>
    
    from twisted.trial import unittest
    from twisted.spread import pb
    from twisted.internet import reactor
    from body import Body
    
    class Trial_TestCase(unittest.TestCase):
    
        def setUp(self):
            self.ref = None
            self.Me = Body('localhost', 18800)
            self.assertTrue(self.Me is not None, "Creating Me assertion failed")
            self.Me.start()
    
            self.Me.pbFactory = pb.PBClientFactory(self.Me)
    
            print "Connecting to " + self.Me.hostName + ":" + str(self.Me.portNo)
            connector = reactor.connectTCP(self.Me.hostName,
                                           self.Me.portNo,
                                           self.Me.pbFactory)
            self.addCleanup(connector.disconnect)
    
            # =====================================================================
            # unittest related parts
            # =====================================================================
            def gotRoot(ref):
                self.ref = ref
    
            df = self.Me.pbFactory.getRootObject()
            '''
                Without this dummy call, I can say no word - say not called
            '''
            obj = df.addCallback(gotRoot)
            return obj
    
    
        def tearDown(self):
            self.Me.remoteObj.broker.transport.loseConnection()
            self.Me.pbFactory.disconnect()
            pass
    
    
        def test_conversation(self):
            # answer = self.Me.speak_to_friend()
            answer = self.Me.tell(None)
            self.assertTrue(answer is not None, "Friend gave no answer")
    
            return self.Me.dm
    
    if __name__ == "__main__":
        #import sys;sys.argv = ['', 'Test.testName']
        unittest.main()
    
    if __name__ == '__main__':
        pass
    
    from twisted.spread import pb
    from twisted.internet import reactor, threads
    import threading
    import time
    from body import Body
    
    def controlThread(name, body):
        print "Press any key to continue..."
        raw_input()
    
        body.start()
    
        result = body.tell(None)
    
        print "Friend's reply: " + str(result)
    
        print "Press any key to continue..."
        raw_input()
        reactor.stop()
        pass
    
    
    body = Body('127.0.0.1', 18800)
    f = pb.PBClientFactory(body)
    body.pbFactory = f
    
    connector = reactor.connectTCP("127.0.0.1", 18800, f)
    print "connector: ", connector
    
    threading.Thread(target=controlThread, args=("Control", body)).start()
    print "Starting reactor"
    reactor.run()
    print "That's all"
    
    import threading
    import types
    
    class Soul():
        def speak(self):
            '''
                virtual method must be overwritten by derived class
            '''
            raise NotImplementedError("I cannot speak without a body. "\
                                      "Please give me body first")
            pass
    
    class Body(threading.Thread):
        def __init__(self, hostname, portno):
            self.hostName = hostname
            self.portNo   = portno
    
            self.df = None
            self.dg = None
            self.dm = None
            self.remoteObj = None
            self.pbFactory = None
    
            self.answer = None
            self.gotAnswer = threading.Event()
    
            self.Soul = Soul()
            self.Soul.speak = types.MethodType(self.tell, self.Soul)
    
            threading.Thread.__init__(self)
            pass
    
        def run(self):
            print "wake up"
            pass
    
        def speak_to_friend(self):
            print 'DBG: speak_to_friend'
            return self.Soul.speak()
    
        def tell(self, soul):
            print 'DBG: speak'
            self.df = self.pbFactory.getRootObject()
    
            self.answer = None
            self.gotAnswer.clear()
            self.dg = self.df.addCallback(self.say)
            self.gotAnswer.wait(timeout=3)
            return self.answer
    
        def say(self, remoteObj):
            print 'DBG: say'
            self.remoteObj = remoteObj
            self.dm = remoteObj.callRemote('talk', 'whoami')
            self.dm.addCallback(self.received)
            self.dm.addErrback(self.broken)
            pass
    
        def received(self, (answer, result)):
            print 'DBG: received'
            self.answer = '\n\t'.join(str.splitlines(answer))
            self.gotAnswer.set()
            pass
    
        def broken(self,reason):
            print "Friend not willing to talk with me because: ", reason.getErrorMessage()
            pass
    
    from twisted.spread import pb
    from twisted.internet import reactor
    from twisted.internet import defer
    
    from subprocess import Popen
    import subprocess
    
    from twisted.web import _newclient
    
    
    class BrokenError(pb.Error):    pass
    
    class Friend(pb.Root):
        def __init__(self,name):
            self.counter = 0
            self.name = str(name)
    
        def remote_broken(self):
            msg = "I don't hear you"
            print "Talk louder" % msg
            raise BrokenError(msg)
    
        def broken(self,reason):
            print "Communication is broken: ", reason.getErrorMessage()
            # print "printError > %r" % failure
            if reason.check(_newclient.RequestGenerationFailed):
                print "printError: RequestGenerationFailed"
                for f in reason.value.reasons:
                    print "printError > %r" % f
                    print f.getTraceback()
            pass
    
    
        def remote_talk(self,words):
            print self.name + ": I got your words: " + words
    
            process = Popen(words,stdout=subprocess.PIPE)
            answer = process.stdout.read()
            process.wait()
    
            print "DBG: answer: ", answer
    
            return (answer, process.returncode)
    
    def main():
        reactor.listenTCP(18800, pb.PBServerFactory(Friend("Dr. Livesey")))
        reactor.run()
    
    if __name__ == '__main__':
        main()