- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我继承了一个 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/
我是一名优秀的程序员,十分优秀!