gpt4 book ai didi

python - 扭曲的审判 : How to test a MultiService with a client in it -- Reactor was unclean

转载 作者:行者123 更新时间:2023-11-28 17:40:11 25 4
gpt4 key购买 nike

我继承了一个 Twisted MultiService,我正在尝试向其添加测试,但无论我做什么,我最终都会遇到 DirtyReactorAggregateError。该服务使用 twisted.application.internet.TCPClient 连接到服务器。我认为错误是因为 TCPClient 没有断开连接,但我不确定我应该如何断开它。测试带有客户端的 Twisted 服务的正确方法是什么?

这是测试用例:

from labrad.node import *
from twisted.trial import unittest
import os
from socket import gethostname

class NodeTestCase(unittest.TestCase):

def setUp(self):
import labrad
name = os.environ.get('LABRADNODE', gethostname()) + '_test'
self.node = Node(name,
labrad.constants.MANAGER_HOST,
labrad.constants.MANAGER_PORT)
self.node.startService()
#self.addCleanup(self.node.stopService)

def test_nothing(self):
self.assertEqual(3, 3)

def tearDown(self):
return self.node.stopService()

这是节点服务本身:

class Node(MultiService):
"""Parent Service that keeps the node running.

If the manager is stopped or we lose the network connection,
this service attempts to restart it so that we will come
back online when the manager is back up.
"""
reconnectDelay = 10

def __init__(self, name, host, port):
MultiService.__init__(self)
self.name = name
self.host = host
self.port = port

def startService(self):
MultiService.startService(self)
self.startConnection()

def startConnection(self):
"""Attempt to start the node and connect to LabRAD."""
print 'Connecting to %s:%d...' % (self.host, self.port)
self.node = NodeServer(self.name, self.host, self.port)
self.node.onStartup().addErrback(self._error)
self.node.onShutdown().addCallbacks(self._disconnected, self._error)
self.cxn = TCPClient(self.host, self.port, self.node)
self.addService(self.cxn)

def stopService(self):
if hasattr(self, 'cxn'):
d = defer.maybeDeferred(self.cxn.stopService)
self.removeService(self.cxn)
del self.cxn
return defer.gatherResults([MultiService.stopService(self), d])
else:
return MultiService.stopService(self)

def _disconnected(self, data):
print 'Node disconnected from manager.'
return self._reconnect()

def _error(self, failure):
r = failure.trap(UserError)
if r == UserError:
print "UserError found!"
return None
print failure.getErrorMessage()
return self._reconnect()

def _reconnect(self):
"""Clean up from the last run and reconnect."""
## hack: manually clearing the dispatcher...
dispatcher.connections.clear()
dispatcher.senders.clear()
dispatcher._boundMethods.clear()
## end hack
if hasattr(self, 'cxn'):
self.removeService(self.cxn)
del self.cxn
reactor.callLater(self.reconnectDelay, self.startConnection)
print 'Will try to reconnect in %d seconds...' % self.reconnectDelay

最佳答案

您应该重构您的服务,以便它可以使用类似 MemoryReactor 的东西来自 twisted.test.proto_helpers (twisted.test 包中的一个公共(public)模块,尽管希望它最终会移出 twisted.test)。

您使用 MemoryReactor 的方式就是把它作为reactor传递到你的代码中去使用。如果您随后想查看连接成功时会发生什么,请查看它的一些公共(public)属性 - tcpClients对于 connectTCP , tcpServers对于 listenTCP等。然后您的测试可以提取传递给 connectTCP 的 Factory 实例。/listenTCP等,并调用 buildProtocol在他们身上 makeConnection在结果上。获得 ITransport您可以使用 twisted.test.proto_helpers.StringTransportWithDisconnection 实现.您甚至可以查看(私有(private) API!小心!它会在没有警告的情况下中断!尽管它是 really should be public )twisted.test.iosim.IOPump在客户端和服务器之间中继流量。

如果您真的需要进行整个系统的非确定性真实世界测试,以及所有复杂性和随机的无关故障,here's an article on actually shutting down a client and server all the way .

关于python - 扭曲的审判 : How to test a MultiService with a client in it -- Reactor was unclean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25415974/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com