[Twisted-Python] reactor.stop() doesn't stop the select reactor?
![](https://secure.gravatar.com/avatar/0ca6e5c33d7e7ff901d75ff0b13d9e1c.jpg?s=120&d=mm&r=g)
I have unittests where each test: def test_this .. setup reactor.run() # ... when test is done reactor.stop() will be called def test_that .. same as above does some setup, runs the reactor until test is complete, then stops the reactor, asserting all went as intended. However, second call to reactor.stop() doesn't stop the reactor. strace shows reactor going back into select(), blocking forever, but killable with sigquit. Is this really intentional? Example code and testrun follow. ~/w/engine % python t_reactor_stop.py 2.5.1 (r251:54863, May 2 2007, 16:27:44) [GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] [twisted, version 2.5.0] <twisted.internet.selectreactor.SelectReactor object at 0x2b684344a310> stopping reactor running? 1 reactor stopped stopping reactor running? 1 zsh: quit (core dumped) python t_reactor_stop.py ~/w/engine % cat t_reactor_stop.py import sys print sys.version from twisted.internet import reactor import twisted print twisted._version.version print reactor def stop_reactor(): print "stopping reactor running? " + repr(reactor.running) try: reactor.stop() except: print "stop died!" reactor.callWhenRunning(stop_reactor) reactor.run() print "reactor stopped" reactor.callWhenRunning(stop_reactor) reactor.run() # Unreachable, why? print "reactor stopped" reactor.callWhenRunning(stop_reactor) reactor.run() print "reactor stopped"
![](https://secure.gravatar.com/avatar/7ed9784cbb1ba1ef75454034b3a8e6a1.jpg?s=120&d=mm&r=g)
On Tue, 25 Sep 2007 12:45:07 -0700, Sam Roberts <sroberts@uniserve.com> wrote:
None of the reactors implemented in Twisted are restartable. You can call each of start and stop at most once. If you are writing unit tests which require the reactor to run, then you can either use trial and twisted.trial.unittest.TestCase or you can write tests which cover smaller units of functionality (and hence do not require the reactor to be running). I'd suggest the latter as better general unit testing practice. Jean-Paul
![](https://secure.gravatar.com/avatar/b942ea770729685105d6bd008be99056.jpg?s=120&d=mm&r=g)
This response won't be as elegant as some, but you can't start the reactor twice in the same process. You can stop the reactor when the service is ended (client or server), but with twistd, it starts and stops itself. So, is it necessary that you start and stop the reactor to run the tests in your code? Why not make each test a callback? Ben Henry -----Original Message----- From: twisted-python-bounces@twistedmatrix.com [mailto:twisted-python-bounces@twistedmatrix.com] On Behalf Of Sam Roberts Sent: Tuesday, September 25, 2007 12:45 PM To: twisted Subject: [Twisted-Python] reactor.stop() doesn't stop the select reactor? I have unittests where each test: def test_this .. setup reactor.run() # ... when test is done reactor.stop() will be called def test_that .. same as above does some setup, runs the reactor until test is complete, then stops the reactor, asserting all went as intended. However, second call to reactor.stop() doesn't stop the reactor. strace shows reactor going back into select(), blocking forever, but killable with sigquit. Is this really intentional? Example code and testrun follow. ~/w/engine % python t_reactor_stop.py 2.5.1 (r251:54863, May 2 2007, 16:27:44) [GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] [twisted, version 2.5.0] <twisted.internet.selectreactor.SelectReactor object at 0x2b684344a310> stopping reactor running? 1 reactor stopped stopping reactor running? 1 zsh: quit (core dumped) python t_reactor_stop.py ~/w/engine % cat t_reactor_stop.py import sys print sys.version from twisted.internet import reactor import twisted print twisted._version.version print reactor def stop_reactor(): print "stopping reactor running? " + repr(reactor.running) try: reactor.stop() except: print "stop died!" reactor.callWhenRunning(stop_reactor) reactor.run() print "reactor stopped" reactor.callWhenRunning(stop_reactor) reactor.run() # Unreachable, why? print "reactor stopped" reactor.callWhenRunning(stop_reactor) reactor.run() print "reactor stopped" _______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
![](https://secure.gravatar.com/avatar/0ca6e5c33d7e7ff901d75ff0b13d9e1c.jpg?s=120&d=mm&r=g)
Thank you both for your prompt help. On Tue, Sep 25, 2007 at 03:51:24PM -0400, Jean-Paul Calderone wrote:
Ok. Sorry to gripe, but it would have saved me some time had this rather significant and non-obvious limitation been mentioned in the docs.
If you are writing unit tests which require the reactor to run, then you can either use trial and twisted.trial.unittest.TestCase or you can write
Can you point me to any examples of using trial? The api is fairly opaque, I'm baffled as to where to start, though the description sounds like it was built to help with this problem.
I have unittests for the low-level code. The purpose of these unit tests is explicitly to ensure my implementation of the IWriteDescriptor interfaces correctly interworks with the reactor. For example, implementors of the IWriteDescriptor interface are required to implement logPrefix(). This is not documented, and I am happy to have discovered it now in my unit tests, rather than during later system tests with the entire application. On Tue, Sep 25, 2007 at 03:52:35PM -0400, Benjamin Henry wrote:
So, is it necessary that you start and stop the reactor to run the tests in your code? Why not make each test a callback?
No, not necessary. I am manually chaining my tests together as you suggest. It works OK, but from unittest's perspective, I now have only one testcase, with everything bundled into a single reactor.run(). There are some nice things about having multiple tests inside a unittest.TestCase, such as not having every test that uses the reactor coupled together, but I can do without this niceties. Cheers, Sam
![](https://secure.gravatar.com/avatar/0ca6e5c33d7e7ff901d75ff0b13d9e1c.jpg?s=120&d=mm&r=g)
On Tue, Sep 25, 2007 at 02:11:47PM -0700, Sam Roberts wrote:
Sorry, I was looking at http://twistedmatrix.com/documents/current/api/twisted.trial.html but I just found http://twistedmatrix.com/trac/wiki/TwistedTrial which has pointers to usage examples. Sam
![](https://secure.gravatar.com/avatar/7ed9784cbb1ba1ef75454034b3a8e6a1.jpg?s=120&d=mm&r=g)
On Tue, 25 Sep 2007 12:45:07 -0700, Sam Roberts <sroberts@uniserve.com> wrote:
None of the reactors implemented in Twisted are restartable. You can call each of start and stop at most once. If you are writing unit tests which require the reactor to run, then you can either use trial and twisted.trial.unittest.TestCase or you can write tests which cover smaller units of functionality (and hence do not require the reactor to be running). I'd suggest the latter as better general unit testing practice. Jean-Paul
![](https://secure.gravatar.com/avatar/b942ea770729685105d6bd008be99056.jpg?s=120&d=mm&r=g)
This response won't be as elegant as some, but you can't start the reactor twice in the same process. You can stop the reactor when the service is ended (client or server), but with twistd, it starts and stops itself. So, is it necessary that you start and stop the reactor to run the tests in your code? Why not make each test a callback? Ben Henry -----Original Message----- From: twisted-python-bounces@twistedmatrix.com [mailto:twisted-python-bounces@twistedmatrix.com] On Behalf Of Sam Roberts Sent: Tuesday, September 25, 2007 12:45 PM To: twisted Subject: [Twisted-Python] reactor.stop() doesn't stop the select reactor? I have unittests where each test: def test_this .. setup reactor.run() # ... when test is done reactor.stop() will be called def test_that .. same as above does some setup, runs the reactor until test is complete, then stops the reactor, asserting all went as intended. However, second call to reactor.stop() doesn't stop the reactor. strace shows reactor going back into select(), blocking forever, but killable with sigquit. Is this really intentional? Example code and testrun follow. ~/w/engine % python t_reactor_stop.py 2.5.1 (r251:54863, May 2 2007, 16:27:44) [GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] [twisted, version 2.5.0] <twisted.internet.selectreactor.SelectReactor object at 0x2b684344a310> stopping reactor running? 1 reactor stopped stopping reactor running? 1 zsh: quit (core dumped) python t_reactor_stop.py ~/w/engine % cat t_reactor_stop.py import sys print sys.version from twisted.internet import reactor import twisted print twisted._version.version print reactor def stop_reactor(): print "stopping reactor running? " + repr(reactor.running) try: reactor.stop() except: print "stop died!" reactor.callWhenRunning(stop_reactor) reactor.run() print "reactor stopped" reactor.callWhenRunning(stop_reactor) reactor.run() # Unreachable, why? print "reactor stopped" reactor.callWhenRunning(stop_reactor) reactor.run() print "reactor stopped" _______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
![](https://secure.gravatar.com/avatar/0ca6e5c33d7e7ff901d75ff0b13d9e1c.jpg?s=120&d=mm&r=g)
Thank you both for your prompt help. On Tue, Sep 25, 2007 at 03:51:24PM -0400, Jean-Paul Calderone wrote:
Ok. Sorry to gripe, but it would have saved me some time had this rather significant and non-obvious limitation been mentioned in the docs.
If you are writing unit tests which require the reactor to run, then you can either use trial and twisted.trial.unittest.TestCase or you can write
Can you point me to any examples of using trial? The api is fairly opaque, I'm baffled as to where to start, though the description sounds like it was built to help with this problem.
I have unittests for the low-level code. The purpose of these unit tests is explicitly to ensure my implementation of the IWriteDescriptor interfaces correctly interworks with the reactor. For example, implementors of the IWriteDescriptor interface are required to implement logPrefix(). This is not documented, and I am happy to have discovered it now in my unit tests, rather than during later system tests with the entire application. On Tue, Sep 25, 2007 at 03:52:35PM -0400, Benjamin Henry wrote:
So, is it necessary that you start and stop the reactor to run the tests in your code? Why not make each test a callback?
No, not necessary. I am manually chaining my tests together as you suggest. It works OK, but from unittest's perspective, I now have only one testcase, with everything bundled into a single reactor.run(). There are some nice things about having multiple tests inside a unittest.TestCase, such as not having every test that uses the reactor coupled together, but I can do without this niceties. Cheers, Sam
![](https://secure.gravatar.com/avatar/0ca6e5c33d7e7ff901d75ff0b13d9e1c.jpg?s=120&d=mm&r=g)
On Tue, Sep 25, 2007 at 02:11:47PM -0700, Sam Roberts wrote:
Sorry, I was looking at http://twistedmatrix.com/documents/current/api/twisted.trial.html but I just found http://twistedmatrix.com/trac/wiki/TwistedTrial which has pointers to usage examples. Sam
participants (3)
-
Benjamin Henry
-
Jean-Paul Calderone
-
Sam Roberts