From 1264faa33d8f593bdf8c8e7e20185e6edae3044f Mon Sep 17 00:00:00 2001 From: Ben Darnell Date: Sun, 17 Jul 2011 14:03:42 -0700 Subject: [PATCH] Run parts of twisted's test suite on the tornado reactor --- tornado/platform/twistedreactor.py | 26 +++++++++++++++++++++- tornado/test/twistedreactor_test.py | 34 +++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/tornado/platform/twistedreactor.py b/tornado/platform/twistedreactor.py index 57a598621..acf2844c4 100644 --- a/tornado/platform/twistedreactor.py +++ b/tornado/platform/twistedreactor.py @@ -93,7 +93,7 @@ class TornadoReactor(PosixReactorBase): """ implements(IReactorTime, IReactorFDSet) - def __init__(self, ioloop): + def __init__(self, ioloop=None): if not ioloop: ioloop = tornado.ioloop.IOLoop.instance() self._ioloop = ioloop @@ -102,6 +102,7 @@ class TornadoReactor(PosixReactorBase): self._fds = {} # a map of fd to a (reader, writer) tuple self._delayedCalls = {} self._running = False + self._closed = False PosixReactorBase.__init__(self) # IReactorTime @@ -195,6 +196,7 @@ class TornadoReactor(PosixReactorBase): fd = reader.fileno() if reader in self._readers: del self._readers[reader] + if self._closed: return (_, writer) = self._fds[fd] if writer: # We have a writer so we need to update the IOLoop for @@ -215,6 +217,7 @@ class TornadoReactor(PosixReactorBase): fd = writer.fileno() if writer in self._writers: del self._writers[writer] + if self._closed: return (reader, _) = self._fds[fd] if reader: # We have a reader so we need to update the IOLoop for @@ -250,6 +253,7 @@ class TornadoReactor(PosixReactorBase): except: # Ignore any exceptions thrown by IOLoop pass + self._closed = True def crash(self): if not self._running: @@ -263,6 +267,7 @@ class TornadoReactor(PosixReactorBase): except: # Ignore any exceptions thrown by IOLoop pass + self._closed = True def doIteration(self, delay): raise NotImplementedError("doIteration") @@ -271,6 +276,25 @@ class TornadoReactor(PosixReactorBase): self._running = True self._ioloop.start() +class _TestReactor(TornadoReactor): + """Subclass of TornadoReactor for use in unittests. + + This can't go in the test.py file because of import-order dependencies + with the twisted reactor test builder. + """ + def __init__(self): + # always use a new ioloop + super(_TestReactor, self).__init__(IOLoop()) + + def listenTCP(self, port, factory, backlog=50, interface=''): + # default to localhost to avoid firewall prompts on the mac + if not interface: + interface = '127.0.0.1' + return super(_TestReactor, self).listenTCP( + port, factory, backlog=backlog, interface=interface) + + + def install(ioloop=None): """ Install the Tornado reactor. diff --git a/tornado/test/twistedreactor_test.py b/tornado/test/twistedreactor_test.py index dc26cbfcf..8d3738c96 100644 --- a/tornado/test/twistedreactor_test.py +++ b/tornado/test/twistedreactor_test.py @@ -36,6 +36,7 @@ except ImportError: from tornado.ioloop import IOLoop from tornado.platform.auto import set_close_exec +from tornado.util import import_object class ReactorWhenRunningTest(unittest.TestCase): def setUp(self): @@ -273,6 +274,39 @@ if twisted is None: del ReactorCallFromThreadTest del ReactorCallInThread del ReactorReaderWriterTest +else: + # Import and run as much of twisted's test suite as possible. + # This is unfortunately rather dependent on implementation details, + # but there doesn't appear to be a clean all-in-one conformance test + # suite for reactors. + # This is a list of all test suites using the ReactorBuilder + # available in Twisted 11.0.0. Tests that do not currently pass + # with the TornadoReactor are commented out. + twisted_tests = [ + 'twisted.internet.test.test_core.ObjectModelIntegrationTest', + #'twisted.internet.test.test_core.SystemEventTestsBuilder', + 'twisted.internet.test.test_fdset.ReactorFDSetTestsBuilder', + #'twisted.internet.test.test_process.ProcessTestsBuilder', + #'twisted.internet.test.test_process.PTYProcessTestsBuilder', + #'twisted.internet.test.test_tcp.TCPClientTestsBuilder', + 'twisted.internet.test.test_tcp.TCPPortTestsBuilder', + 'twisted.internet.test.test_tcp.TCPConnectionTestsBuilder', + 'twisted.internet.test.test_threads.ThreadTestsBuilder', + 'twisted.internet.test.test_time.TimeTestsBuilder', + #'twisted.internet.test.test_tls.SSLClientTestsMixin', + 'twisted.internet.test.test_udp.UDPServerTestsBuilder', + #'twisted.internet.test.test_unix.UNIXTestsBuilder', + #'twisted.internet.test.test_unix.UNIXDatagramTestsBuilder', + ] + for test_name in twisted_tests: + try: + test = import_object(test_name) + except (ImportError, AttributeError): + continue + class TornadoTest(test): + _reactors = ["tornado.platform.twistedreactor._TestReactor"] + TornadoTest.__name__ = test.__name__ + globals().update(TornadoTest.makeTestCaseClasses()) if __name__ == "__main__": unittest.main() -- 2.47.2