[Twisted-Python] @inlinecallbacks and AlreadyCalledError in test cases
Hi all I have recently started switching to trial.unittest from python's own. The trouble I'm experiencing is when a timeout occurs in my test, it errbacks(). Then the @inlineCallbacks decorator sees the error and errbacks(). But then a second @inlineCallback in the chain subsequently sees *that* errback and tries to errback itself. This results in AlreadyCalledError. In the test setup, various services are started. These are tracked and then shutdown again in the teardown. Also, there is some polling that happens as part of the tests (waiting on db activities, for example). These use deferLater calls, which are also tracked and torn down in the teardown. I've tried _suppressAlreadyCalled in various places to no avail. Below is a simple example that shows the problem. Many thanks Brad <code> from twisted.trial.unittest import TestCase from twisted.internet import task, reactor from twisted.internet.defer import inlineCallbacks #import twisted #twisted.internet.base.DelayedCall.debug = True #twisted.internet.defer.setDebugging(True) class Test1(TestCase): def setUp(self): # timeout test in 1 second self.timeout = 1 self.jobs = [] self.addCleanup(self._tearDown) def _tearDown(self): for d in self.jobs: if d and not d.called: d.cancel() @inlineCallbacks def _waitForChange(self): # do stuff d = task.deferLater(reactor, 0.5, lambda : None) self.jobs.append(d) yield d self.jobs.remove(d) # do more stuff @inlineCallbacks def testHere(self): # do stuff yield self._waitForChange() # do more stuff # This one passes OK #def testHere(self): # return self._waitForChange() if __name__ == "__main__": import sys from twisted.scripts import trial sys.argv.extend([sys.argv[0]]) trial.run() </code>
On 01:39 am, brad.milne@devx.runthered.com wrote:
Hi all
I have recently started switching to trial.unittest from python's own. The trouble I'm experiencing is when a timeout occurs in my test, it errbacks(). Then the @inlineCallbacks decorator sees the error and errbacks(). But then a second @inlineCallback in the chain subsequently sees *that* errback and tries to errback itself. This results in AlreadyCalledError.
In the test setup, various services are started. These are tracked and then shutdown again in the teardown. Also, there is some polling that happens as part of the tests (waiting on db activities, for example). These use deferLater calls, which are also tracked and torn down in the teardown.
I've tried _suppressAlreadyCalled in various places to no avail.
Below is a simple example that shows the problem.
I tried running the sample, it completes without error. I guess that's not what you're seeing? What version of Twisted do you have? Jean-Paul
On 5 April 2011 14:21, <exarkun@twistedmatrix.com> wrote:
On 01:39 am, brad.milne@devx.runthered.com wrote:
Hi all
I have recently started switching to trial.unittest from python's own. The trouble I'm experiencing is when a timeout occurs in my test, it errbacks(). Then the @inlineCallbacks decorator sees the error and errbacks(). But then a second @inlineCallback in the chain subsequently sees *that* errback and tries to errback itself. This results in AlreadyCalledError.
In the test setup, various services are started. These are tracked and then shutdown again in the teardown. Also, there is some polling that happens as part of the tests (waiting on db activities, for example). These use deferLater calls, which are also tracked and torn down in the teardown.
I've tried _suppressAlreadyCalled in various places to no avail.
Below is a simple example that shows the problem.
I tried running the sample, it completes without error. I guess that's not what you're seeing? What version of Twisted do you have?
Jean-Paul
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
Hi Jean-Paul I'm using 10.2.0 on a mac. Here's my interpreter (using buildout): #!/opt/local/Library/Frameworks/Python.framework/Versions/2.6/Resources/Python.app/Contents/MacOS/Python import sys sys.path[0:0] = [ '/Users/brad/Development/python/workspace/Python-Integration/src', '/Users/brad/Development/python/eggs/nose-0.11.4-py2.6.egg', '/Users/brad/Development/python/eggs/MiniMock-1.2.5-py2.6.egg', '/Users/brad/Development/python/eggs/suds-0.4-py2.6.egg', '/Users/brad/Development/python/eggs/SOAPpy-0.12.4-py2.6.egg', '/Users/brad/Development/python/eggs/wstools-0.3-py2.6.egg', '/Users/brad/Development/python/eggs/fpconst-0.7.2-py2.6.egg', '/Users/brad/Development/python/eggs/Twisted-10.2.0-py2.6-macosx-10.6-x86_64.egg', '/Users/brad/Development/python/eggs/zope.interface-3.6.1-py2.6-macosx-10.6-x86_64.egg', '/Users/brad/Development/python/eggs/pymongo-1.9-py2.6-macosx-10.6-x86_64.egg', '/Users/brad/Development/python/eggs/pytz-2010h-py2.6.egg', ] The python I have at that location (using MacPorts) is 2.6.6. Following your email I see that 11.0.0 is released so I tried that and got the same error: <snip> [ERROR] Traceback (most recent call last): File "/Users/brad/Development/python/eggs/Twisted-11.0.0-py2.6-macosx-10.6-x86_64.egg/twisted/internet/defer.py", line 1076, in gotResult _inlineCallbacks(r, g, deferred) File "/Users/brad/Development/python/eggs/Twisted-11.0.0-py2.6-macosx-10.6-x86_64.egg/twisted/internet/defer.py", line 1066, in _inlineCallbacks deferred.errback() File "/Users/brad/Development/python/eggs/Twisted-11.0.0-py2.6-macosx-10.6-x86_64.egg/twisted/internet/defer.py", line 388, in errback self._startRunCallbacks(fail) File "/Users/brad/Development/python/eggs/Twisted-11.0.0-py2.6-macosx-10.6-x86_64.egg/twisted/internet/defer.py", line 448, in _startRunCallbacks raise AlreadyCalledError twisted.internet.defer.AlreadyCalledError: </snip> Many thanks Brad
participants (2)
-
Brad Milne -
exarkun@twistedmatrix.com