[Twisted-Python] @inlinecallbacks and AlreadyCalledError in test cases
Brad Milne
brad.milne at devx.runthered.com
Mon Apr 4 19:39:05 MDT 2011
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>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/twisted-python/attachments/20110405/cd2f964c/attachment.html>
More information about the Twisted-Python
mailing list