1 # Copyright (c) Twisted Matrix Laboratories.
2 # See LICENSE for details.
5 Test cases for defer module.
10 from twisted.trial import unittest
11 from twisted.internet import reactor, defer
12 from twisted.internet.task import Clock
13 from twisted.python import failure, log
14 from twisted.python.util import unsignedID
16 class GenericError(Exception):
21 class DeferredTestCase(unittest.TestCase):
24 self.callbackResults = None
25 self.errbackResults = None
26 self.callback2Results = None
27 # Restore the debug flag to its original state when done.
28 self.addCleanup(defer.setDebugging, defer.getDebugging())
30 def _callback(self, *args, **kw):
31 self.callbackResults = args, kw
34 def _callback2(self, *args, **kw):
35 self.callback2Results = args, kw
37 def _errback(self, *args, **kw):
38 self.errbackResults = args, kw
40 def testCallbackWithoutArgs(self):
41 deferred = defer.Deferred()
42 deferred.addCallback(self._callback)
43 deferred.callback("hello")
44 self.assertEqual(self.errbackResults, None)
45 self.assertEqual(self.callbackResults, (('hello',), {}))
47 def testCallbackWithArgs(self):
48 deferred = defer.Deferred()
49 deferred.addCallback(self._callback, "world")
50 deferred.callback("hello")
51 self.assertEqual(self.errbackResults, None)
52 self.assertEqual(self.callbackResults, (('hello', 'world'), {}))
54 def testCallbackWithKwArgs(self):
55 deferred = defer.Deferred()
56 deferred.addCallback(self._callback, world="world")
57 deferred.callback("hello")
58 self.assertEqual(self.errbackResults, None)
59 self.assertEqual(self.callbackResults,
60 (('hello',), {'world': 'world'}))
62 def testTwoCallbacks(self):
63 deferred = defer.Deferred()
64 deferred.addCallback(self._callback)
65 deferred.addCallback(self._callback2)
66 deferred.callback("hello")
67 self.assertEqual(self.errbackResults, None)
68 self.assertEqual(self.callbackResults,
70 self.assertEqual(self.callback2Results,
73 def testDeferredList(self):
74 defr1 = defer.Deferred()
75 defr2 = defer.Deferred()
76 defr3 = defer.Deferred()
77 dl = defer.DeferredList([defr1, defr2, defr3])
79 def cb(resultList, result=result):
80 result.extend(resultList)
83 dl.addCallbacks(cb, cb)
85 defr2.addErrback(catch)
86 # "catch" is added to eat the GenericError that will be passed on by
87 # the DeferredList's callback on defr2. If left unhandled, the
88 # Failure object would cause a log.err() warning about "Unhandled
89 # error in Deferred". Twisted's pyunit watches for log.err calls and
90 # treats them as failures. So "catch" must eat the error to prevent
91 # it from flunking the test.
92 defr2.errback(GenericError("2"))
94 self.assertEqual([result[0],
95 #result[1][1] is now a Failure instead of an Exception
96 (result[1][0], str(result[1][1].value)),
99 [(defer.SUCCESS, "1"),
100 (defer.FAILURE, "2"),
101 (defer.SUCCESS, "3")])
103 def testEmptyDeferredList(self):
105 def cb(resultList, result=result):
106 result.append(resultList)
108 dl = defer.DeferredList([])
110 self.assertEqual(result, [[]])
113 dl = defer.DeferredList([], fireOnOneCallback=1)
115 self.assertEqual(result, [])
117 def testDeferredListFireOnOneError(self):
118 defr1 = defer.Deferred()
119 defr2 = defer.Deferred()
120 defr3 = defer.Deferred()
121 dl = defer.DeferredList([defr1, defr2, defr3], fireOnOneErrback=1)
123 dl.addErrback(result.append)
125 # consume errors after they pass through the DeferredList (to avoid
126 # 'Unhandled error in Deferred'.
129 defr2.addErrback(catch)
131 # fire one Deferred's callback, no result yet
133 self.assertEqual(result, [])
135 # fire one Deferred's errback -- now we have a result
136 defr2.errback(GenericError("from def2"))
137 self.assertEqual(len(result), 1)
139 # extract the result from the list
142 # the type of the failure is a FirstError
143 self.failUnless(issubclass(aFailure.type, defer.FirstError),
144 'issubclass(aFailure.type, defer.FirstError) failed: '
145 "failure's type is %r" % (aFailure.type,)
148 firstError = aFailure.value
150 # check that the GenericError("2") from the deferred at index 1
151 # (defr2) is intact inside failure.value
152 self.assertEqual(firstError.subFailure.type, GenericError)
153 self.assertEqual(firstError.subFailure.value.args, ("from def2",))
154 self.assertEqual(firstError.index, 1)
157 def testDeferredListDontConsumeErrors(self):
158 d1 = defer.Deferred()
159 dl = defer.DeferredList([d1])
162 d1.addErrback(errorTrap.append)
165 dl.addCallback(result.append)
167 d1.errback(GenericError('Bang'))
168 self.assertEqual('Bang', errorTrap[0].value.args[0])
169 self.assertEqual(1, len(result))
170 self.assertEqual('Bang', result[0][0][1].value.args[0])
172 def testDeferredListConsumeErrors(self):
173 d1 = defer.Deferred()
174 dl = defer.DeferredList([d1], consumeErrors=True)
177 d1.addErrback(errorTrap.append)
180 dl.addCallback(result.append)
182 d1.errback(GenericError('Bang'))
183 self.assertEqual([], errorTrap)
184 self.assertEqual(1, len(result))
185 self.assertEqual('Bang', result[0][0][1].value.args[0])
187 def testDeferredListFireOnOneErrorWithAlreadyFiredDeferreds(self):
188 # Create some deferreds, and errback one
189 d1 = defer.Deferred()
190 d2 = defer.Deferred()
191 d1.errback(GenericError('Bang'))
193 # *Then* build the DeferredList, with fireOnOneErrback=True
194 dl = defer.DeferredList([d1, d2], fireOnOneErrback=True)
196 dl.addErrback(result.append)
197 self.assertEqual(1, len(result))
199 d1.addErrback(lambda e: None) # Swallow error
201 def testDeferredListWithAlreadyFiredDeferreds(self):
202 # Create some deferreds, and err one, call the other
203 d1 = defer.Deferred()
204 d2 = defer.Deferred()
205 d1.errback(GenericError('Bang'))
208 # *Then* build the DeferredList
209 dl = defer.DeferredList([d1, d2])
212 dl.addCallback(result.append)
214 self.assertEqual(1, len(result))
216 d1.addErrback(lambda e: None) # Swallow error
219 def testImmediateSuccess(self):
221 d = defer.succeed("success")
222 d.addCallback(l.append)
223 self.assertEqual(l, ["success"])
226 def testImmediateFailure(self):
228 d = defer.fail(GenericError("fail"))
229 d.addErrback(l.append)
230 self.assertEqual(str(l[0].value), "fail")
232 def testPausedFailure(self):
234 d = defer.fail(GenericError("fail"))
236 d.addErrback(l.append)
237 self.assertEqual(l, [])
239 self.assertEqual(str(l[0].value), "fail")
241 def testCallbackErrors(self):
243 d = defer.Deferred().addCallback(lambda _: 1 / 0).addErrback(l.append)
245 self.assert_(isinstance(l[0].value, ZeroDivisionError))
247 d = defer.Deferred().addCallback(
248 lambda _: failure.Failure(ZeroDivisionError())).addErrback(l.append)
250 self.assert_(isinstance(l[0].value, ZeroDivisionError))
252 def testUnpauseBeforeCallback(self):
255 d.addCallback(self._callback)
258 def testReturnDeferred(self):
260 d2 = defer.Deferred()
262 d.addCallback(lambda r, d2=d2: d2)
263 d.addCallback(self._callback)
265 assert self.callbackResults is None, "Should not have been called yet."
267 assert self.callbackResults is None, "Still should not have been called yet."
269 assert self.callbackResults[0][0] == 2, "Result should have been from second deferred:%s" % (self.callbackResults,)
272 def test_chainedPausedDeferredWithResult(self):
274 When a paused Deferred with a result is returned from a callback on
275 another Deferred, the other Deferred is chained to the first and waits
276 for it to be unpaused.
279 paused = defer.Deferred()
280 paused.callback(expected)
282 chained = defer.Deferred()
283 chained.addCallback(lambda ignored: paused)
284 chained.callback(None)
287 chained.addCallback(result.append)
288 self.assertEqual(result, [])
290 self.assertEqual(result, [expected])
293 def test_pausedDeferredChained(self):
295 A paused Deferred encountered while pushing a result forward through a
296 chain does not prevent earlier Deferreds from continuing to execute
299 first = defer.Deferred()
300 second = defer.Deferred()
301 first.addCallback(lambda ignored: second)
304 second.callback(None)
306 second.addCallback(result.append)
307 self.assertEqual(result, [None])
310 def test_gatherResults(self):
311 # test successful list of deferreds
313 defer.gatherResults([defer.succeed(1), defer.succeed(2)]).addCallback(l.append)
314 self.assertEqual(l, [[1, 2]])
315 # test failing list of deferreds
317 dl = [defer.succeed(1), defer.fail(ValueError)]
318 defer.gatherResults(dl).addErrback(l.append)
319 self.assertEqual(len(l), 1)
320 self.assert_(isinstance(l[0], failure.Failure))
322 dl[1].addErrback(lambda e: 1)
325 def test_gatherResultsWithConsumeErrors(self):
327 If a L{Deferred} in the list passed to L{gatherResults} fires with a
328 failure and C{consumerErrors} is C{True}, the failure is converted to a
329 C{None} result on that L{Deferred}.
331 # test successful list of deferreds
332 dgood = defer.succeed(1)
333 dbad = defer.fail(RuntimeError("oh noes"))
334 d = defer.gatherResults([dgood, dbad], consumeErrors=True)
335 unconsumedErrors = []
336 dbad.addErrback(unconsumedErrors.append)
338 d.addErrback(gatheredErrors.append)
340 self.assertEqual((len(unconsumedErrors), len(gatheredErrors)),
342 self.assertIsInstance(gatheredErrors[0].value, defer.FirstError)
343 firstError = gatheredErrors[0].value.subFailure
344 self.assertIsInstance(firstError.value, RuntimeError)
347 def test_maybeDeferredSync(self):
349 L{defer.maybeDeferred} should retrieve the result of a synchronous
350 function and pass it to its resulting L{defer.Deferred}.
353 d = defer.maybeDeferred((lambda x: x + 5), 10)
354 d.addCallbacks(S.append, E.append)
355 self.assertEqual(E, [])
356 self.assertEqual(S, [15])
360 def test_maybeDeferredSyncError(self):
362 L{defer.maybeDeferred} should catch exception raised by a synchronous
363 function and errback its resulting L{defer.Deferred} with it.
370 d = defer.maybeDeferred((lambda x: x + 5), '10')
371 d.addCallbacks(S.append, E.append)
372 self.assertEqual(S, [])
373 self.assertEqual(len(E), 1)
374 self.assertEqual(str(E[0].value), expected)
378 def test_maybeDeferredAsync(self):
380 L{defer.maybeDeferred} should let L{defer.Deferred} instance pass by
381 so that original result is the same.
384 d2 = defer.maybeDeferred(lambda: d)
385 d.callback('Success')
386 return d2.addCallback(self.assertEqual, 'Success')
389 def test_maybeDeferredAsyncError(self):
391 L{defer.maybeDeferred} should let L{defer.Deferred} instance pass by
392 so that L{failure.Failure} returned by the original instance is the
396 d2 = defer.maybeDeferred(lambda: d)
397 d.errback(failure.Failure(RuntimeError()))
398 return self.assertFailure(d2, RuntimeError)
401 def test_innerCallbacksPreserved(self):
403 When a L{Deferred} encounters a result which is another L{Deferred}
404 which is waiting on a third L{Deferred}, the middle L{Deferred}'s
405 callbacks are executed after the third L{Deferred} fires and before the
406 first receives a result.
410 inner = defer.Deferred()
412 results.append(('start-of-cb', result))
413 d = defer.succeed('inner')
414 def firstCallback(result):
415 results.append(('firstCallback', 'inner'))
417 def secondCallback(result):
418 results.append(('secondCallback', result))
420 d.addCallback(firstCallback).addCallback(secondCallback)
421 d.addErrback(failures.append)
423 outer = defer.succeed('outer')
424 outer.addCallback(cb)
425 inner.callback('orange')
426 outer.addCallback(results.append)
427 inner.addErrback(failures.append)
428 outer.addErrback(failures.append)
429 self.assertEqual([], failures)
432 [('start-of-cb', 'outer'),
433 ('firstCallback', 'inner'),
434 ('secondCallback', 'orange'),
438 def test_continueCallbackNotFirst(self):
440 The continue callback of a L{Deferred} waiting for another L{Deferred}
441 is not necessarily the first one. This is somewhat a whitebox test
442 checking that we search for that callback among the whole list of
450 results.append(('cb', result))
453 def firstCallback(ignored):
454 results.append(('firstCallback', ignored))
455 return defer.gatherResults([a])
457 def secondCallback(result):
458 results.append(('secondCallback', result))
460 d.addCallback(firstCallback)
461 d.addCallback(secondCallback)
462 d.addErrback(failures.append)
466 outer = defer.succeed('outer')
467 outer.addCallback(cb)
468 outer.addErrback(failures.append)
469 self.assertEqual([('cb', 'outer'), ('firstCallback', None)], results)
470 a.callback('withers')
471 self.assertEqual([], failures)
475 ('firstCallback', None),
476 ('secondCallback', ['withers'])])
479 def test_callbackOrderPreserved(self):
481 A callback added to a L{Deferred} after a previous callback attached
482 another L{Deferred} as a result is run after the callbacks of the other
490 results.append(('cb', result))
493 def firstCallback(ignored):
494 results.append(('firstCallback', ignored))
495 return defer.gatherResults([a])
497 def secondCallback(result):
498 results.append(('secondCallback', result))
500 d.addCallback(firstCallback)
501 d.addCallback(secondCallback)
502 d.addErrback(failures.append)
506 outer = defer.Deferred()
507 outer.addCallback(cb)
508 outer.addCallback(lambda x: results.append('final'))
509 outer.addErrback(failures.append)
510 outer.callback('outer')
511 self.assertEqual([('cb', 'outer'), ('firstCallback', None)], results)
512 a.callback('withers')
513 self.assertEqual([], failures)
517 ('firstCallback', None),
518 ('secondCallback', ['withers']), 'final'])
521 def test_reentrantRunCallbacks(self):
523 A callback added to a L{Deferred} by a callback on that L{Deferred}
524 should be added to the end of the callback chain.
526 deferred = defer.Deferred()
528 def callback3(result):
530 def callback2(result):
532 def callback1(result):
534 deferred.addCallback(callback3)
535 deferred.addCallback(callback1)
536 deferred.addCallback(callback2)
537 deferred.callback(None)
538 self.assertEqual(called, [1, 2, 3])
541 def test_nonReentrantCallbacks(self):
543 A callback added to a L{Deferred} by a callback on that L{Deferred}
544 should not be executed until the running callback returns.
546 deferred = defer.Deferred()
548 def callback2(result):
550 def callback1(result):
552 deferred.addCallback(callback2)
553 self.assertEqual(called, [1])
554 deferred.addCallback(callback1)
555 deferred.callback(None)
556 self.assertEqual(called, [1, 2])
559 def test_reentrantRunCallbacksWithFailure(self):
561 After an exception is raised by a callback which was added to a
562 L{Deferred} by a callback on that L{Deferred}, the L{Deferred} should
563 call the first errback with a L{Failure} wrapping that exception.
565 exceptionMessage = "callback raised exception"
566 deferred = defer.Deferred()
567 def callback2(result):
568 raise Exception(exceptionMessage)
569 def callback1(result):
570 deferred.addCallback(callback2)
571 deferred.addCallback(callback1)
572 deferred.callback(None)
573 self.assertFailure(deferred, Exception)
574 def cbFailed(exception):
575 self.assertEqual(exception.args, (exceptionMessage,))
576 deferred.addCallback(cbFailed)
580 def test_synchronousImplicitChain(self):
582 If a first L{Deferred} with a result is returned from a callback on a
583 second L{Deferred}, the result of the second L{Deferred} becomes the
584 result of the first L{Deferred} and the result of the first L{Deferred}
588 first = defer.succeed(result)
589 second = defer.Deferred()
590 second.addCallback(lambda ign: first)
591 second.callback(None)
594 first.addCallback(results.append)
595 self.assertIdentical(results[0], None)
596 second.addCallback(results.append)
597 self.assertIdentical(results[1], result)
600 def test_asynchronousImplicitChain(self):
602 If a first L{Deferred} without a result is returned from a callback on
603 a second L{Deferred}, the result of the second L{Deferred} becomes the
604 result of the first L{Deferred} as soon as the first L{Deferred} has
605 one and the result of the first L{Deferred} becomes C{None}.
607 first = defer.Deferred()
608 second = defer.Deferred()
609 second.addCallback(lambda ign: first)
610 second.callback(None)
613 first.addCallback(firstResult.append)
615 second.addCallback(secondResult.append)
617 self.assertEqual(firstResult, [])
618 self.assertEqual(secondResult, [])
621 first.callback(result)
623 self.assertEqual(firstResult, [None])
624 self.assertEqual(secondResult, [result])
627 def test_synchronousImplicitErrorChain(self):
629 If a first L{Deferred} with a L{Failure} result is returned from a
630 callback on a second L{Deferred}, the first L{Deferred}'s result is
631 converted to L{None} and no unhandled error is logged when it is
634 first = defer.fail(RuntimeError("First Deferred's Failure"))
635 second = defer.Deferred()
636 second.addCallback(lambda ign, first=first: first)
637 self.assertFailure(second, RuntimeError)
638 second.callback(None)
640 first.addCallback(firstResult.append)
641 self.assertIdentical(firstResult[0], None)
645 def test_asynchronousImplicitErrorChain(self):
647 Let C{a} and C{b} be two L{Deferred}s.
649 If C{a} has no result and is returned from a callback on C{b} then when
650 C{a} fails, C{b}'s result becomes the L{Failure} that was C{a}'s result,
651 the result of C{a} becomes C{None} so that no unhandled error is logged
652 when it is garbage collected.
654 first = defer.Deferred()
655 second = defer.Deferred()
656 second.addCallback(lambda ign: first)
657 second.callback(None)
658 self.assertFailure(second, RuntimeError)
661 first.addCallback(firstResult.append)
663 second.addCallback(secondResult.append)
665 self.assertEqual(firstResult, [])
666 self.assertEqual(secondResult, [])
668 first.errback(RuntimeError("First Deferred's Failure"))
670 self.assertEqual(firstResult, [None])
671 self.assertEqual(len(secondResult), 1)
674 def test_doubleAsynchronousImplicitChaining(self):
676 L{Deferred} chaining is transitive.
678 In other words, let A, B, and C be Deferreds. If C is returned from a
679 callback on B and B is returned from a callback on A then when C fires,
682 first = defer.Deferred()
683 second = defer.Deferred()
684 second.addCallback(lambda ign: first)
685 third = defer.Deferred()
686 third.addCallback(lambda ign: second)
689 third.addCallback(thirdResult.append)
692 # After this, second is waiting for first to tell it to continue.
693 second.callback(None)
694 # And after this, third is waiting for second to tell it to continue.
698 self.assertEqual(thirdResult, [])
700 # This will tell second to continue which will tell third to continue.
701 first.callback(result)
703 self.assertEqual(thirdResult, [result])
706 def test_nestedAsynchronousChainedDeferreds(self):
708 L{Deferred}s can have callbacks that themselves return L{Deferred}s.
709 When these "inner" L{Deferred}s fire (even asynchronously), the
710 callback chain continues.
715 # A Deferred returned in the inner callback.
716 inner = defer.Deferred()
719 results.append(('start-of-cb', result))
720 d = defer.succeed('inner')
722 def firstCallback(result):
723 results.append(('firstCallback', 'inner'))
724 # Return a Deferred that definitely has not fired yet, so we
725 # can fire the Deferreds out of order.
728 def secondCallback(result):
729 results.append(('secondCallback', result))
732 d.addCallback(firstCallback).addCallback(secondCallback)
733 d.addErrback(failures.append)
736 # Create a synchronous Deferred that has a callback 'cb' that returns
737 # a Deferred 'd' that has fired but is now waiting on an unfired
739 outer = defer.succeed('outer')
740 outer.addCallback(cb)
741 outer.addCallback(results.append)
742 # At this point, the callback 'cb' has been entered, and the first
743 # callback of 'd' has been called.
745 results, [('start-of-cb', 'outer'), ('firstCallback', 'inner')])
747 # Once the inner Deferred is fired, processing of the outer Deferred's
748 # callback chain continues.
749 inner.callback('orange')
751 # Make sure there are no errors.
752 inner.addErrback(failures.append)
753 outer.addErrback(failures.append)
755 [], failures, "Got errbacks but wasn't expecting any.")
759 [('start-of-cb', 'outer'),
760 ('firstCallback', 'inner'),
761 ('secondCallback', 'orange'),
765 def test_nestedAsynchronousChainedDeferredsWithExtraCallbacks(self):
767 L{Deferred}s can have callbacks that themselves return L{Deferred}s.
768 These L{Deferred}s can have other callbacks added before they are
769 returned, which subtly changes the callback chain. When these "inner"
770 L{Deferred}s fire (even asynchronously), the outer callback chain
776 # A Deferred returned in the inner callback after a callback is
777 # added explicitly and directly to it.
778 inner = defer.Deferred()
781 results.append(('start-of-cb', result))
782 d = defer.succeed('inner')
784 def firstCallback(ignored):
785 results.append(('firstCallback', ignored))
786 # Return a Deferred that definitely has not fired yet with a
787 # result-transforming callback so we can fire the Deferreds
788 # out of order and see how the callback affects the ultimate
790 return inner.addCallback(lambda x: [x])
792 def secondCallback(result):
793 results.append(('secondCallback', result))
796 d.addCallback(firstCallback)
797 d.addCallback(secondCallback)
798 d.addErrback(failures.append)
801 # Create a synchronous Deferred that has a callback 'cb' that returns
802 # a Deferred 'd' that has fired but is now waiting on an unfired
804 outer = defer.succeed('outer')
805 outer.addCallback(cb)
806 outer.addCallback(results.append)
807 # At this point, the callback 'cb' has been entered, and the first
808 # callback of 'd' has been called.
810 results, [('start-of-cb', 'outer'), ('firstCallback', 'inner')])
812 # Once the inner Deferred is fired, processing of the outer Deferred's
813 # callback chain continues.
814 inner.callback('withers')
816 # Make sure there are no errors.
817 outer.addErrback(failures.append)
818 inner.addErrback(failures.append)
820 [], failures, "Got errbacks but wasn't expecting any.")
824 [('start-of-cb', 'outer'),
825 ('firstCallback', 'inner'),
826 ('secondCallback', ['withers']),
827 ['withers', 'withers']])
830 def test_chainDeferredRecordsExplicitChain(self):
832 When we chain a L{Deferred}, that chaining is recorded explicitly.
837 self.assertIdentical(a._chainedTo, b)
840 def test_explicitChainClearedWhenResolved(self):
842 Any recorded chaining is cleared once the chaining is resolved, since
845 In other words, if one L{Deferred} is recorded as depending on the
846 result of another, and I{that} L{Deferred} has fired, then the
847 dependency is resolved and we no longer benefit from recording it.
853 self.assertIdentical(a._chainedTo, None)
856 def test_chainDeferredRecordsImplicitChain(self):
858 We can chain L{Deferred}s implicitly by adding callbacks that return
859 L{Deferred}s. When this chaining happens, we record it explicitly as
860 soon as we can find out about it.
864 a.addCallback(lambda ignored: b)
866 self.assertIdentical(a._chainedTo, b)
871 The C{repr()} of a L{Deferred} contains the class name and a
872 representation of the internal Python ID.
875 address = hex(unsignedID(d))
877 repr(d), '<Deferred at %s>' % (address,))
880 def test_reprWithResult(self):
882 If a L{Deferred} has been fired, then its C{repr()} contains its
888 repr(d), "<Deferred at %s current result: 'orange'>" % (
892 def test_reprWithChaining(self):
894 If a L{Deferred} C{a} has been fired, but is waiting on another
895 L{Deferred} C{b} that appears in its callback chain, then C{repr(a)}
896 says that it is waiting on C{b}.
902 repr(a), "<Deferred at %s waiting on Deferred at %s>" % (
903 hex(unsignedID(a)), hex(unsignedID(b))))
906 def test_boundedStackDepth(self):
908 The depth of the call stack does not grow as more L{Deferred} instances
909 are chained together.
911 def chainDeferreds(howMany):
913 def recordStackDepth(ignored):
914 stack.append(len(traceback.extract_stack()))
916 top = defer.Deferred()
917 innerDeferreds = [defer.Deferred() for ignored in range(howMany)]
918 originalInners = innerDeferreds[:]
919 last = defer.Deferred()
921 inner = innerDeferreds.pop()
922 top.addCallback(lambda ign, inner=inner: inner)
923 top.addCallback(recordStackDepth)
925 while innerDeferreds:
926 newInner = innerDeferreds.pop()
927 inner.addCallback(lambda ign, inner=newInner: inner)
929 inner.addCallback(lambda ign: last)
932 for inner in originalInners:
935 # Sanity check - the record callback is not intended to have
937 self.assertEqual(stack, [])
939 # Now fire the last thing and return the stack depth at which the
940 # callback was invoked.
944 # Callbacks should be invoked at the same stack depth regardless of
945 # how many Deferreds are chained.
946 self.assertEqual(chainDeferreds(1), chainDeferreds(2))
949 def test_resultOfDeferredResultOfDeferredOfFiredDeferredCalled(self):
951 Given three Deferreds, one chained to the next chained to the next,
952 callbacks on the middle Deferred which are added after the chain is
953 created are called once the last Deferred fires.
955 This is more of a regression-style test. It doesn't exercise any
956 particular code path through the current implementation of Deferred, but
957 it does exercise a broken codepath through one of the variations of the
958 implementation proposed as a resolution to ticket #411.
960 first = defer.Deferred()
961 second = defer.Deferred()
962 third = defer.Deferred()
963 first.addCallback(lambda ignored: second)
964 second.addCallback(lambda ignored: third)
965 second.callback(None)
969 second.addCallback(L.append)
970 self.assertEqual(L, [None])
973 def test_errbackWithNoArgsNoDebug(self):
975 C{Deferred.errback()} creates a failure from the current Python
976 exception. When Deferred.debug is not set no globals or locals are
977 captured in that failure.
979 defer.setDebugging(False)
982 exc = GenericError("Bang")
987 d.addErrback(l.append)
989 self.assertEqual(fail.value, exc)
990 localz, globalz = fail.frames[0][-2:]
991 self.assertEqual([], localz)
992 self.assertEqual([], globalz)
995 def test_errbackWithNoArgs(self):
997 C{Deferred.errback()} creates a failure from the current Python
998 exception. When Deferred.debug is set globals and locals are captured
1001 defer.setDebugging(True)
1002 d = defer.Deferred()
1004 exc = GenericError("Bang")
1009 d.addErrback(l.append)
1011 self.assertEqual(fail.value, exc)
1012 localz, globalz = fail.frames[0][-2:]
1013 self.assertNotEquals([], localz)
1014 self.assertNotEquals([], globalz)
1017 def test_errorInCallbackDoesNotCaptureVars(self):
1019 An error raised by a callback creates a Failure. The Failure captures
1020 locals and globals if and only if C{Deferred.debug} is set.
1022 d = defer.Deferred()
1024 defer.setDebugging(False)
1025 def raiseError(ignored):
1026 raise GenericError("Bang")
1027 d.addCallback(raiseError)
1029 d.addErrback(l.append)
1031 localz, globalz = fail.frames[0][-2:]
1032 self.assertEqual([], localz)
1033 self.assertEqual([], globalz)
1036 def test_errorInCallbackCapturesVarsWhenDebugging(self):
1038 An error raised by a callback creates a Failure. The Failure captures
1039 locals and globals if and only if C{Deferred.debug} is set.
1041 d = defer.Deferred()
1043 defer.setDebugging(True)
1044 def raiseError(ignored):
1045 raise GenericError("Bang")
1046 d.addCallback(raiseError)
1048 d.addErrback(l.append)
1050 localz, globalz = fail.frames[0][-2:]
1051 self.assertNotEquals([], localz)
1052 self.assertNotEquals([], globalz)
1056 class FirstErrorTests(unittest.TestCase):
1058 Tests for L{FirstError}.
1060 def test_repr(self):
1062 The repr of a L{FirstError} instance includes the repr of the value of
1063 the sub-failure and the index which corresponds to the L{FirstError}.
1065 exc = ValueError("some text")
1069 f = failure.Failure()
1071 error = defer.FirstError(f, 3)
1074 "FirstError[#3, %s]" % (repr(exc),))
1079 The str of a L{FirstError} instance includes the str of the
1080 sub-failure and the index which corresponds to the L{FirstError}.
1082 exc = ValueError("some text")
1086 f = failure.Failure()
1088 error = defer.FirstError(f, 5)
1091 "FirstError[#5, %s]" % (str(f),))
1094 def test_comparison(self):
1096 L{FirstError} instances compare equal to each other if and only if
1097 their failure and index compare equal. L{FirstError} instances do not
1098 compare equal to instances of other types.
1103 firstFailure = failure.Failure()
1105 one = defer.FirstError(firstFailure, 13)
1106 anotherOne = defer.FirstError(firstFailure, 13)
1109 raise ValueError("bar")
1111 secondFailure = failure.Failure()
1113 another = defer.FirstError(secondFailure, 9)
1115 self.assertTrue(one == anotherOne)
1116 self.assertFalse(one == another)
1117 self.assertTrue(one != another)
1118 self.assertFalse(one != anotherOne)
1120 self.assertFalse(one == 10)
1124 class AlreadyCalledTestCase(unittest.TestCase):
1126 self._deferredWasDebugging = defer.getDebugging()
1127 defer.setDebugging(True)
1130 defer.setDebugging(self._deferredWasDebugging)
1132 def _callback(self, *args, **kw):
1134 def _errback(self, *args, **kw):
1137 def _call_1(self, d):
1139 def _call_2(self, d):
1141 def _err_1(self, d):
1142 d.errback(failure.Failure(RuntimeError()))
1143 def _err_2(self, d):
1144 d.errback(failure.Failure(RuntimeError()))
1146 def testAlreadyCalled_CC(self):
1147 d = defer.Deferred()
1148 d.addCallbacks(self._callback, self._errback)
1150 self.failUnlessRaises(defer.AlreadyCalledError, self._call_2, d)
1152 def testAlreadyCalled_CE(self):
1153 d = defer.Deferred()
1154 d.addCallbacks(self._callback, self._errback)
1156 self.failUnlessRaises(defer.AlreadyCalledError, self._err_2, d)
1158 def testAlreadyCalled_EE(self):
1159 d = defer.Deferred()
1160 d.addCallbacks(self._callback, self._errback)
1162 self.failUnlessRaises(defer.AlreadyCalledError, self._err_2, d)
1164 def testAlreadyCalled_EC(self):
1165 d = defer.Deferred()
1166 d.addCallbacks(self._callback, self._errback)
1168 self.failUnlessRaises(defer.AlreadyCalledError, self._call_2, d)
1171 def _count(self, linetype, func, lines, expected):
1174 if (line.startswith(' %s:' % linetype) and
1175 line.endswith(' %s' % func)):
1177 self.failUnless(count == expected)
1179 def _check(self, e, caller, invoker1, invoker2):
1180 # make sure the debugging information is vaguely correct
1181 lines = e.args[0].split("\n")
1182 # the creator should list the creator (testAlreadyCalledDebug) but not
1183 # _call_1 or _call_2 or other invokers
1184 self._count('C', caller, lines, 1)
1185 self._count('C', '_call_1', lines, 0)
1186 self._count('C', '_call_2', lines, 0)
1187 self._count('C', '_err_1', lines, 0)
1188 self._count('C', '_err_2', lines, 0)
1189 # invoker should list the first invoker but not the second
1190 self._count('I', invoker1, lines, 1)
1191 self._count('I', invoker2, lines, 0)
1193 def testAlreadyCalledDebug_CC(self):
1194 d = defer.Deferred()
1195 d.addCallbacks(self._callback, self._errback)
1199 except defer.AlreadyCalledError, e:
1200 self._check(e, "testAlreadyCalledDebug_CC", "_call_1", "_call_2")
1202 self.fail("second callback failed to raise AlreadyCalledError")
1204 def testAlreadyCalledDebug_CE(self):
1205 d = defer.Deferred()
1206 d.addCallbacks(self._callback, self._errback)
1210 except defer.AlreadyCalledError, e:
1211 self._check(e, "testAlreadyCalledDebug_CE", "_call_1", "_err_2")
1213 self.fail("second errback failed to raise AlreadyCalledError")
1215 def testAlreadyCalledDebug_EC(self):
1216 d = defer.Deferred()
1217 d.addCallbacks(self._callback, self._errback)
1221 except defer.AlreadyCalledError, e:
1222 self._check(e, "testAlreadyCalledDebug_EC", "_err_1", "_call_2")
1224 self.fail("second callback failed to raise AlreadyCalledError")
1226 def testAlreadyCalledDebug_EE(self):
1227 d = defer.Deferred()
1228 d.addCallbacks(self._callback, self._errback)
1232 except defer.AlreadyCalledError, e:
1233 self._check(e, "testAlreadyCalledDebug_EE", "_err_1", "_err_2")
1235 self.fail("second errback failed to raise AlreadyCalledError")
1237 def testNoDebugging(self):
1238 defer.setDebugging(False)
1239 d = defer.Deferred()
1240 d.addCallbacks(self._callback, self._errback)
1244 except defer.AlreadyCalledError, e:
1247 self.fail("second callback failed to raise AlreadyCalledError")
1250 def testSwitchDebugging(self):
1251 # Make sure Deferreds can deal with debug state flipping
1252 # around randomly. This is covering a particular fixed bug.
1253 defer.setDebugging(False)
1254 d = defer.Deferred()
1255 d.addBoth(lambda ign: None)
1256 defer.setDebugging(True)
1259 defer.setDebugging(False)
1260 d = defer.Deferred()
1262 defer.setDebugging(True)
1263 d.addBoth(lambda ign: None)
1267 class DeferredCancellerTest(unittest.TestCase):
1269 self.callbackResults = None
1270 self.errbackResults = None
1271 self.callback2Results = None
1272 self.cancellerCallCount = 0
1276 # Sanity check that the canceller was called at most once.
1277 self.assertTrue(self.cancellerCallCount in (0, 1))
1280 def _callback(self, data):
1281 self.callbackResults = data
1285 def _callback2(self, data):
1286 self.callback2Results = data
1289 def _errback(self, data):
1290 self.errbackResults = data
1293 def test_noCanceller(self):
1295 A L{defer.Deferred} without a canceller must errback with a
1296 L{defer.CancelledError} and not callback.
1298 d = defer.Deferred()
1299 d.addCallbacks(self._callback, self._errback)
1301 self.assertEqual(self.errbackResults.type, defer.CancelledError)
1302 self.assertEqual(self.callbackResults, None)
1305 def test_raisesAfterCancelAndCallback(self):
1307 A L{defer.Deferred} without a canceller, when cancelled must allow
1308 a single extra call to callback, and raise
1309 L{defer.AlreadyCalledError} if callbacked or errbacked thereafter.
1311 d = defer.Deferred()
1312 d.addCallbacks(self._callback, self._errback)
1315 # A single extra callback should be swallowed.
1318 # But a second call to callback or errback is not.
1319 self.assertRaises(defer.AlreadyCalledError, d.callback, None)
1320 self.assertRaises(defer.AlreadyCalledError, d.errback, Exception())
1323 def test_raisesAfterCancelAndErrback(self):
1325 A L{defer.Deferred} without a canceller, when cancelled must allow
1326 a single extra call to errback, and raise
1327 L{defer.AlreadyCalledError} if callbacked or errbacked thereafter.
1329 d = defer.Deferred()
1330 d.addCallbacks(self._callback, self._errback)
1333 # A single extra errback should be swallowed.
1334 d.errback(Exception())
1336 # But a second call to callback or errback is not.
1337 self.assertRaises(defer.AlreadyCalledError, d.callback, None)
1338 self.assertRaises(defer.AlreadyCalledError, d.errback, Exception())
1341 def test_noCancellerMultipleCancelsAfterCancelAndCallback(self):
1343 A L{Deferred} without a canceller, when cancelled and then
1344 callbacked, ignores multiple cancels thereafter.
1346 d = defer.Deferred()
1347 d.addCallbacks(self._callback, self._errback)
1349 currentFailure = self.errbackResults
1350 # One callback will be ignored
1352 # Cancel should have no effect.
1354 self.assertIdentical(currentFailure, self.errbackResults)
1357 def test_noCancellerMultipleCancelsAfterCancelAndErrback(self):
1359 A L{defer.Deferred} without a canceller, when cancelled and then
1360 errbacked, ignores multiple cancels thereafter.
1362 d = defer.Deferred()
1363 d.addCallbacks(self._callback, self._errback)
1365 self.assertEqual(self.errbackResults.type, defer.CancelledError)
1366 currentFailure = self.errbackResults
1367 # One errback will be ignored
1368 d.errback(GenericError())
1369 # I.e., we should still have a CancelledError.
1370 self.assertEqual(self.errbackResults.type, defer.CancelledError)
1372 self.assertIdentical(currentFailure, self.errbackResults)
1375 def test_noCancellerMultipleCancel(self):
1377 Calling cancel multiple times on a deferred with no canceller
1378 results in a L{defer.CancelledError}. Subsequent calls to cancel
1379 do not cause an error.
1381 d = defer.Deferred()
1382 d.addCallbacks(self._callback, self._errback)
1384 self.assertEqual(self.errbackResults.type, defer.CancelledError)
1385 currentFailure = self.errbackResults
1387 self.assertIdentical(currentFailure, self.errbackResults)
1390 def test_cancellerMultipleCancel(self):
1392 Verify that calling cancel multiple times on a deferred with a
1393 canceller that does not errback results in a
1394 L{defer.CancelledError} and that subsequent calls to cancel do not
1395 cause an error and that after all that, the canceller was only
1399 self.cancellerCallCount += 1
1401 d = defer.Deferred(canceller=cancel)
1402 d.addCallbacks(self._callback, self._errback)
1404 self.assertEqual(self.errbackResults.type, defer.CancelledError)
1405 currentFailure = self.errbackResults
1407 self.assertIdentical(currentFailure, self.errbackResults)
1408 self.assertEqual(self.cancellerCallCount, 1)
1411 def test_simpleCanceller(self):
1413 Verify that a L{defer.Deferred} calls its specified canceller when
1414 it is cancelled, and that further call/errbacks raise
1415 L{defer.AlreadyCalledError}.
1418 self.cancellerCallCount += 1
1420 d = defer.Deferred(canceller=cancel)
1421 d.addCallbacks(self._callback, self._errback)
1423 self.assertEqual(self.cancellerCallCount, 1)
1424 self.assertEqual(self.errbackResults.type, defer.CancelledError)
1426 # Test that further call/errbacks are *not* swallowed
1427 self.assertRaises(defer.AlreadyCalledError, d.callback, None)
1428 self.assertRaises(defer.AlreadyCalledError, d.errback, Exception())
1431 def test_cancellerArg(self):
1433 Verify that a canceller is given the correct deferred argument.
1436 self.assertIdentical(d1, d)
1437 d = defer.Deferred(canceller=cancel)
1438 d.addCallbacks(self._callback, self._errback)
1442 def test_cancelAfterCallback(self):
1444 Test that cancelling a deferred after it has been callbacked does
1448 self.cancellerCallCount += 1
1449 d.errback(GenericError())
1450 d = defer.Deferred(canceller=cancel)
1451 d.addCallbacks(self._callback, self._errback)
1454 self.assertEqual(self.cancellerCallCount, 0)
1455 self.assertEqual(self.errbackResults, None)
1456 self.assertEqual(self.callbackResults, 'biff!')
1459 def test_cancelAfterErrback(self):
1461 Test that cancelling a L{Deferred} after it has been errbacked does
1462 not result in a L{defer.CancelledError}.
1465 self.cancellerCallCount += 1
1466 d.errback(GenericError())
1467 d = defer.Deferred(canceller=cancel)
1468 d.addCallbacks(self._callback, self._errback)
1469 d.errback(GenericError())
1471 self.assertEqual(self.cancellerCallCount, 0)
1472 self.assertEqual(self.errbackResults.type, GenericError)
1473 self.assertEqual(self.callbackResults, None)
1476 def test_cancellerThatErrbacks(self):
1478 Test a canceller which errbacks its deferred.
1481 self.cancellerCallCount += 1
1482 d.errback(GenericError())
1483 d = defer.Deferred(canceller=cancel)
1484 d.addCallbacks(self._callback, self._errback)
1486 self.assertEqual(self.cancellerCallCount, 1)
1487 self.assertEqual(self.errbackResults.type, GenericError)
1490 def test_cancellerThatCallbacks(self):
1492 Test a canceller which calls its deferred.
1495 self.cancellerCallCount += 1
1496 d.callback('hello!')
1497 d = defer.Deferred(canceller=cancel)
1498 d.addCallbacks(self._callback, self._errback)
1500 self.assertEqual(self.cancellerCallCount, 1)
1501 self.assertEqual(self.callbackResults, 'hello!')
1502 self.assertEqual(self.errbackResults, None)
1505 def test_cancelNestedDeferred(self):
1507 Verify that a Deferred, a, which is waiting on another Deferred, b,
1508 returned from one of its callbacks, will propagate
1509 L{defer.CancelledError} when a is cancelled.
1512 self.cancellerCallCount += 1
1516 b = defer.Deferred(canceller=innerCancel)
1517 a = defer.Deferred(canceller=cancel)
1519 a.addCallback(lambda data: b)
1521 a.addCallbacks(self._callback, self._errback)
1522 # The cancel count should be one (the cancellation done by B)
1523 self.assertEqual(self.cancellerCallCount, 1)
1524 # B's canceller didn't errback, so defer.py will have called errback
1525 # with a CancelledError.
1526 self.assertEqual(self.errbackResults.type, defer.CancelledError)
1530 class LogTestCase(unittest.TestCase):
1532 Test logging of unhandled errors.
1537 Add a custom observer to observer logging.
1540 log.addObserver(self.c.append)
1544 Remove the observer.
1546 log.removeObserver(self.c.append)
1549 def _loggedErrors(self):
1550 return [e for e in self.c if e["isError"]]
1555 Check the output of the log observer to see if the error is present.
1557 c2 = self._loggedErrors()
1558 self.assertEqual(len(c2), 2)
1559 c2[1]["failure"].trap(ZeroDivisionError)
1560 self.flushLoggedErrors(ZeroDivisionError)
1562 def test_errorLog(self):
1564 Verify that when a L{Deferred} with no references to it is fired,
1565 and its final result (the one not handled by any callback) is an
1566 exception, that exception will be logged immediately.
1568 defer.Deferred().addCallback(lambda x: 1 / 0).callback(1)
1572 def test_errorLogWithInnerFrameRef(self):
1574 Same as L{test_errorLog}, but with an inner frame.
1576 def _subErrorLogWithInnerFrameRef():
1577 d = defer.Deferred()
1578 d.addCallback(lambda x: 1 / 0)
1581 _subErrorLogWithInnerFrameRef()
1585 def test_errorLogWithInnerFrameCycle(self):
1587 Same as L{test_errorLogWithInnerFrameRef}, plus create a cycle.
1589 def _subErrorLogWithInnerFrameCycle():
1590 d = defer.Deferred()
1591 d.addCallback(lambda x, d=d: 1 / 0)
1595 _subErrorLogWithInnerFrameCycle()
1600 def test_chainedErrorCleanup(self):
1602 If one Deferred with an error result is returned from a callback on
1603 another Deferred, when the first Deferred is garbage collected it does
1606 d = defer.Deferred()
1607 d.addCallback(lambda ign: defer.fail(RuntimeError("zoop")))
1610 # Sanity check - this isn't too interesting, but we do want the original
1611 # Deferred to have gotten the failure.
1614 d.addCallbacks(results.append, errors.append)
1615 self.assertEqual(results, [])
1616 self.assertEqual(len(errors), 1)
1617 errors[0].trap(Exception)
1619 # Get rid of any references we might have to the inner Deferred (none of
1620 # these should really refer to it, but we're just being safe).
1621 del results, errors, d
1622 # Force a collection cycle so that there's a chance for an error to be
1623 # logged, if it's going to be logged.
1625 # And make sure it is not.
1626 self.assertEqual(self._loggedErrors(), [])
1629 def test_errorClearedByChaining(self):
1631 If a Deferred with a failure result has an errback which chains it to
1632 another Deferred, the initial failure is cleared by the errback so it is
1635 # Start off with a Deferred with a failure for a result
1636 bad = defer.fail(Exception("oh no"))
1637 good = defer.Deferred()
1638 # Give it a callback that chains it to another Deferred
1639 bad.addErrback(lambda ignored: good)
1640 # That's all, clean it up. No Deferred here still has a failure result,
1641 # so nothing should be logged.
1644 self.assertEqual(self._loggedErrors(), [])
1648 class DeferredTestCaseII(unittest.TestCase):
1650 self.callbackRan = 0
1652 def testDeferredListEmpty(self):
1653 """Testing empty DeferredList."""
1654 dl = defer.DeferredList([])
1655 dl.addCallback(self.cb_empty)
1657 def cb_empty(self, res):
1658 self.callbackRan = 1
1659 self.assertEqual([], res)
1662 self.failUnless(self.callbackRan, "Callback was never run.")
1664 class OtherPrimitives(unittest.TestCase):
1665 def _incr(self, result):
1672 lock = defer.DeferredLock()
1673 lock.acquire().addCallback(self._incr)
1674 self.failUnless(lock.locked)
1675 self.assertEqual(self.counter, 1)
1677 lock.acquire().addCallback(self._incr)
1678 self.failUnless(lock.locked)
1679 self.assertEqual(self.counter, 1)
1682 self.failUnless(lock.locked)
1683 self.assertEqual(self.counter, 2)
1686 self.failIf(lock.locked)
1687 self.assertEqual(self.counter, 2)
1689 self.assertRaises(TypeError, lock.run)
1691 firstUnique = object()
1692 secondUnique = object()
1694 controlDeferred = defer.Deferred()
1695 def helper(self, b):
1697 return controlDeferred
1699 resultDeferred = lock.run(helper, self=self, b=firstUnique)
1700 self.failUnless(lock.locked)
1701 self.assertEqual(self.b, firstUnique)
1703 resultDeferred.addCallback(lambda x: setattr(self, 'result', x))
1705 lock.acquire().addCallback(self._incr)
1706 self.failUnless(lock.locked)
1707 self.assertEqual(self.counter, 2)
1709 controlDeferred.callback(secondUnique)
1710 self.assertEqual(self.result, secondUnique)
1711 self.failUnless(lock.locked)
1712 self.assertEqual(self.counter, 3)
1714 d = lock.acquire().addBoth(lambda x: setattr(self, 'result', x))
1716 self.assertEqual(self.result.type, defer.CancelledError)
1719 self.failIf(lock.locked)
1722 def test_cancelLockAfterAcquired(self):
1724 When canceling a L{Deferred} from a L{DeferredLock} that already
1725 has the lock, the cancel should have no effect.
1727 def _failOnErrback(_):
1728 self.fail("Unexpected errback call!")
1729 lock = defer.DeferredLock()
1731 d.addErrback(_failOnErrback)
1735 def test_cancelLockBeforeAcquired(self):
1737 When canceling a L{Deferred} from a L{DeferredLock} that does not
1738 yet have the lock (i.e., the L{Deferred} has not fired), the cancel
1739 should cause a L{defer.CancelledError} failure.
1741 lock = defer.DeferredLock()
1744 self.assertFailure(d, defer.CancelledError)
1748 def testSemaphore(self):
1750 sem = defer.DeferredSemaphore(N)
1752 controlDeferred = defer.Deferred()
1753 def helper(self, arg):
1755 return controlDeferred
1758 uniqueObject = object()
1759 resultDeferred = sem.run(helper, self=self, arg=uniqueObject)
1760 resultDeferred.addCallback(results.append)
1761 resultDeferred.addCallback(self._incr)
1762 self.assertEqual(results, [])
1763 self.assertEqual(self.arg, uniqueObject)
1764 controlDeferred.callback(None)
1765 self.assertEqual(results.pop(), None)
1766 self.assertEqual(self.counter, 1)
1769 for i in range(1, 1 + N):
1770 sem.acquire().addCallback(self._incr)
1771 self.assertEqual(self.counter, i)
1776 success.append(False)
1778 success.append(True)
1779 d = sem.acquire().addCallbacks(fail, succeed)
1781 self.assertEqual(success, [True])
1783 sem.acquire().addCallback(self._incr)
1784 self.assertEqual(self.counter, N)
1787 self.assertEqual(self.counter, N + 1)
1789 for i in range(1, 1 + N):
1791 self.assertEqual(self.counter, N + 1)
1794 def test_semaphoreInvalidTokens(self):
1796 If the token count passed to L{DeferredSemaphore} is less than one
1797 then L{ValueError} is raised.
1799 self.assertRaises(ValueError, defer.DeferredSemaphore, 0)
1800 self.assertRaises(ValueError, defer.DeferredSemaphore, -1)
1803 def test_cancelSemaphoreAfterAcquired(self):
1805 When canceling a L{Deferred} from a L{DeferredSemaphore} that
1806 already has the semaphore, the cancel should have no effect.
1808 def _failOnErrback(_):
1809 self.fail("Unexpected errback call!")
1811 sem = defer.DeferredSemaphore(1)
1813 d.addErrback(_failOnErrback)
1817 def test_cancelSemaphoreBeforeAcquired(self):
1819 When canceling a L{Deferred} from a L{DeferredSemaphore} that does
1820 not yet have the semaphore (i.e., the L{Deferred} has not fired),
1821 the cancel should cause a L{defer.CancelledError} failure.
1823 sem = defer.DeferredSemaphore(1)
1826 self.assertFailure(d, defer.CancelledError)
1831 def testQueue(self):
1833 queue = defer.DeferredQueue(N, M)
1838 queue.get().addCallback(gotten.append)
1839 self.assertRaises(defer.QueueUnderflow, queue.get)
1843 self.assertEqual(gotten, range(i + 1))
1846 self.assertEqual(gotten, range(M))
1847 self.assertRaises(defer.QueueOverflow, queue.put, None)
1851 queue.get().addCallback(gotten.append)
1852 self.assertEqual(gotten, range(N, N + i + 1))
1854 queue = defer.DeferredQueue()
1857 queue.get().addCallback(gotten.append)
1860 self.assertEqual(gotten, range(N))
1862 queue = defer.DeferredQueue(size=0)
1863 self.assertRaises(defer.QueueOverflow, queue.put, None)
1865 queue = defer.DeferredQueue(backlog=0)
1866 self.assertRaises(defer.QueueUnderflow, queue.get)
1869 def test_cancelQueueAfterSynchronousGet(self):
1871 When canceling a L{Deferred} from a L{DeferredQueue} that already has
1872 a result, the cancel should have no effect.
1874 def _failOnErrback(_):
1875 self.fail("Unexpected errback call!")
1877 queue = defer.DeferredQueue()
1879 d.addErrback(_failOnErrback)
1884 def test_cancelQueueAfterGet(self):
1886 When canceling a L{Deferred} from a L{DeferredQueue} that does not
1887 have a result (i.e., the L{Deferred} has not fired), the cancel
1888 causes a L{defer.CancelledError} failure. If the queue has a result
1889 later on, it doesn't try to fire the deferred.
1891 queue = defer.DeferredQueue()
1893 self.assertFailure(d, defer.CancelledError)
1896 # If the deferred is still linked with the deferred queue, it will
1897 # fail with an AlreadyCalledError
1899 return queue.get().addCallback(self.assertIdentical, None)
1900 return d.addCallback(cb)
1904 class DeferredFilesystemLockTestCase(unittest.TestCase):
1906 Test the behavior of L{DeferredFilesystemLock}
1909 self.clock = Clock()
1910 self.lock = defer.DeferredFilesystemLock(self.mktemp(),
1911 scheduler=self.clock)
1914 def test_waitUntilLockedWithNoLock(self):
1916 Test that the lock can be acquired when no lock is held
1918 d = self.lock.deferUntilLocked(timeout=1)
1923 def test_waitUntilLockedWithTimeoutLocked(self):
1925 Test that the lock can not be acquired when the lock is held
1926 for longer than the timeout.
1928 self.failUnless(self.lock.lock())
1930 d = self.lock.deferUntilLocked(timeout=5.5)
1931 self.assertFailure(d, defer.TimeoutError)
1933 self.clock.pump([1] * 10)
1938 def test_waitUntilLockedWithTimeoutUnlocked(self):
1940 Test that a lock can be acquired while a lock is held
1941 but the lock is unlocked before our timeout.
1944 f.trap(defer.TimeoutError)
1945 self.fail("Should not have timed out")
1947 self.failUnless(self.lock.lock())
1949 self.clock.callLater(1, self.lock.unlock)
1950 d = self.lock.deferUntilLocked(timeout=10)
1951 d.addErrback(onTimeout)
1953 self.clock.pump([1] * 10)
1958 def test_defaultScheduler(self):
1960 Test that the default scheduler is set up properly.
1962 lock = defer.DeferredFilesystemLock(self.mktemp())
1964 self.assertEqual(lock._scheduler, reactor)
1967 def test_concurrentUsage(self):
1969 Test that an appropriate exception is raised when attempting
1970 to use deferUntilLocked concurrently.
1973 self.clock.callLater(1, self.lock.unlock)
1975 d = self.lock.deferUntilLocked()
1976 d2 = self.lock.deferUntilLocked()
1978 self.assertFailure(d2, defer.AlreadyTryingToLockError)
1980 self.clock.advance(1)
1985 def test_multipleUsages(self):
1987 Test that a DeferredFilesystemLock can be used multiple times
1989 def lockAquired(ign):
1991 d = self.lock.deferUntilLocked()
1995 self.clock.callLater(1, self.lock.unlock)
1997 d = self.lock.deferUntilLocked()
1998 d.addCallback(lockAquired)
2000 self.clock.advance(1)