magic-wormhole/src/wormhole/test/common.py

101 lines
3.9 KiB
Python
Raw Normal View History

2016-06-04 21:03:05 +00:00
# no unicode_literals untill twisted update
2015-09-27 00:59:39 +00:00
from twisted.application import service
from twisted.internet import defer, task, reactor
from twisted.python import log
from click.testing import CliRunner
import mock
from ..cli import cli
from ..transit import allocate_tcp_port
from ..server.server import RelayServer
2016-04-21 01:54:10 +00:00
from .. import __version__
2015-09-27 00:59:39 +00:00
class ServerBase:
def setUp(self):
self._setup_relay(None)
def _setup_relay(self, error):
2015-09-27 00:59:39 +00:00
self.sp = service.MultiService()
self.sp.startService()
self.relayport = allocate_tcp_port()
self.transitport = allocate_tcp_port()
# need to talk to twisted team about only using unicode in
# endpoints.serverFromString
s = RelayServer("tcp:%d:interface=127.0.0.1" % self.relayport,
"tcp:%s:interface=127.0.0.1" % self.transitport,
advertise_version=__version__,
signal_error=error)
s.setServiceParent(self.sp)
2016-04-19 00:57:14 +00:00
self._rendezvous = s._rendezvous
self._transit_server = s._transit
self.relayurl = u"ws://127.0.0.1:%d/v1" % self.relayport
self.rdv_ws_port = self.relayport
# ws://127.0.0.1:%d/wormhole-relay/ws
self.transit = u"tcp:127.0.0.1:%d" % self.transitport
2015-09-27 00:59:39 +00:00
def tearDown(self):
# Unit tests that spawn a (blocking) client in a thread might still
# have threads running at this point, if one is stuck waiting for a
# message from a companion which has exited with an error. Our
# relay's .stopService() drops all connections, which ought to
# encourage those threads to terminate soon. If they don't, print a
# warning to ease debugging.
2016-06-03 22:17:47 +00:00
# XXX FIXME there's something in _noclobber test that's not
# waiting for a close, I think -- was pretty relieably getting
# unclean-reactor, but adding a slight pause here stops it...
from twisted.internet import reactor
tp = reactor.getThreadPool()
if not tp.working:
2016-06-03 22:17:47 +00:00
d = defer.succeed(None)
d.addCallback(lambda _: self.sp.stopService())
d.addCallback(lambda _: task.deferLater(reactor, 0.1, lambda: None))
return d
return self.sp.stopService()
# disconnect all callers
d = defer.maybeDeferred(self.sp.stopService)
wait_d = defer.Deferred()
# wait a second, then check to see if it worked
reactor.callLater(1.0, wait_d.callback, None)
def _later(res):
if len(tp.working):
log.msg("wormhole.test.common.ServerBase.tearDown:"
" I was unable to convince all threads to exit.")
tp.dumpStats()
print("tearDown warning: threads are still active")
print("This test will probably hang until one of the"
" clients gives up of their own accord.")
else:
log.msg("wormhole.test.common.ServerBase.tearDown:"
" I convinced all threads to exit.")
return d
wait_d.addCallback(_later)
return wait_d
def config(*argv):
r = CliRunner()
with mock.patch("wormhole.cli.cli.go") as go:
res = r.invoke(cli.wormhole, argv, catch_exceptions=False)
if res.exit_code != 0:
print(res.exit_code)
print(res.output)
print(res)
assert 0
cfg = go.call_args[0][1]
return cfg
@defer.inlineCallbacks
def poll_until(predicate):
# return a Deferred that won't fire until the predicate is True
while not predicate():
d = defer.Deferred()
reactor.callLater(0.001, d.callback, None)
yield d
@defer.inlineCallbacks
def pause_one_tick():
# return a Deferred that won't fire until at least the next reactor tick
d = defer.Deferred()
reactor.callLater(0.001, d.callback, None)
yield d