Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: third_party/twisted_8_1/twisted/test/test_defer.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1
2 # Copyright (c) 2001-2007 Twisted Matrix Laboratories.
3 # See LICENSE for details.
4
5
6 """
7 Test cases for defer module.
8 """
9
10 import gc
11
12 from twisted.trial import unittest, util
13 from twisted.internet import reactor, defer
14 from twisted.python import failure, log
15
16 from twisted.internet.task import Clock
17
18 class GenericError(Exception):
19 pass
20
21
22 _setTimeoutSuppression = util.suppress(
23 message="Deferred.setTimeout is deprecated. Look for timeout "
24 "support specific to the API you are using instead.",
25 category=DeprecationWarning)
26
27 _firstErrorSuppression = util.suppress(
28 message="FirstError.__getitem__ is deprecated. Use attributes instead.",
29 category=DeprecationWarning)
30
31
32 class DeferredTestCase(unittest.TestCase):
33
34 def setUp(self):
35 self.callback_results = None
36 self.errback_results = None
37 self.callback2_results = None
38
39 def _callback(self, *args, **kw):
40 self.callback_results = args, kw
41 return args[0]
42
43 def _callback2(self, *args, **kw):
44 self.callback2_results = args, kw
45
46 def _errback(self, *args, **kw):
47 self.errback_results = args, kw
48
49 def testCallbackWithoutArgs(self):
50 deferred = defer.Deferred()
51 deferred.addCallback(self._callback)
52 deferred.callback("hello")
53 self.failUnlessEqual(self.errback_results, None)
54 self.failUnlessEqual(self.callback_results, (('hello',), {}))
55
56 def testCallbackWithArgs(self):
57 deferred = defer.Deferred()
58 deferred.addCallback(self._callback, "world")
59 deferred.callback("hello")
60 self.failUnlessEqual(self.errback_results, None)
61 self.failUnlessEqual(self.callback_results, (('hello', 'world'), {}))
62
63 def testCallbackWithKwArgs(self):
64 deferred = defer.Deferred()
65 deferred.addCallback(self._callback, world="world")
66 deferred.callback("hello")
67 self.failUnlessEqual(self.errback_results, None)
68 self.failUnlessEqual(self.callback_results,
69 (('hello',), {'world': 'world'}))
70
71 def testTwoCallbacks(self):
72 deferred = defer.Deferred()
73 deferred.addCallback(self._callback)
74 deferred.addCallback(self._callback2)
75 deferred.callback("hello")
76 self.failUnlessEqual(self.errback_results, None)
77 self.failUnlessEqual(self.callback_results,
78 (('hello',), {}))
79 self.failUnlessEqual(self.callback2_results,
80 (('hello',), {}))
81
82 def testDeferredList(self):
83 defr1 = defer.Deferred()
84 defr2 = defer.Deferred()
85 defr3 = defer.Deferred()
86 dl = defer.DeferredList([defr1, defr2, defr3])
87 result = []
88 def cb(resultList, result=result):
89 result.extend(resultList)
90 def catch(err):
91 return None
92 dl.addCallbacks(cb, cb)
93 defr1.callback("1")
94 defr2.addErrback(catch)
95 # "catch" is added to eat the GenericError that will be passed on by
96 # the DeferredList's callback on defr2. If left unhandled, the
97 # Failure object would cause a log.err() warning about "Unhandled
98 # error in Deferred". Twisted's pyunit watches for log.err calls and
99 # treats them as failures. So "catch" must eat the error to prevent
100 # it from flunking the test.
101 defr2.errback(GenericError("2"))
102 defr3.callback("3")
103 self.failUnlessEqual([result[0],
104 #result[1][1] is now a Failure instead of an Exception
105 (result[1][0], str(result[1][1].value)),
106 result[2]],
107
108 [(defer.SUCCESS, "1"),
109 (defer.FAILURE, "2"),
110 (defer.SUCCESS, "3")])
111
112 def testEmptyDeferredList(self):
113 result = []
114 def cb(resultList, result=result):
115 result.append(resultList)
116
117 dl = defer.DeferredList([])
118 dl.addCallbacks(cb)
119 self.failUnlessEqual(result, [[]])
120
121 result[:] = []
122 dl = defer.DeferredList([], fireOnOneCallback=1)
123 dl.addCallbacks(cb)
124 self.failUnlessEqual(result, [])
125
126 def testDeferredListFireOnOneError(self):
127 defr1 = defer.Deferred()
128 defr2 = defer.Deferred()
129 defr3 = defer.Deferred()
130 dl = defer.DeferredList([defr1, defr2, defr3], fireOnOneErrback=1)
131 result = []
132 dl.addErrback(result.append)
133
134 # consume errors after they pass through the DeferredList (to avoid
135 # 'Unhandled error in Deferred'.
136 def catch(err):
137 return None
138 defr2.addErrback(catch)
139
140 # fire one Deferred's callback, no result yet
141 defr1.callback("1")
142 self.failUnlessEqual(result, [])
143
144 # fire one Deferred's errback -- now we have a result
145 defr2.errback(GenericError("from def2"))
146 self.failUnlessEqual(len(result), 1)
147
148 # extract the result from the list
149 failure = result[0]
150
151 # the type of the failure is a FirstError
152 self.failUnless(issubclass(failure.type, defer.FirstError),
153 'issubclass(failure.type, defer.FirstError) failed: '
154 'failure.type is %r' % (failure.type,)
155 )
156
157 firstError = failure.value
158
159 # check that the GenericError("2") from the deferred at index 1
160 # (defr2) is intact inside failure.value
161 self.failUnlessEqual(firstError.subFailure.type, GenericError)
162 self.failUnlessEqual(firstError.subFailure.value.args, ("from def2",))
163 self.failUnlessEqual(firstError.index, 1)
164
165
166 def test_indexingFirstError(self):
167 """
168 L{FirstError} behaves a little like a tuple, for backwards
169 compatibility. Test that it can actually be indexed to retrieve
170 information about the failure.
171 """
172 subFailure = object()
173 index = object()
174 firstError = defer.FirstError(subFailure, index)
175 self.assertIdentical(firstError[0], firstError.subFailure)
176 self.assertIdentical(firstError[1], firstError.index)
177 test_indexingFirstError.suppress = [_firstErrorSuppression]
178
179
180 def testDeferredListDontConsumeErrors(self):
181 d1 = defer.Deferred()
182 dl = defer.DeferredList([d1])
183
184 errorTrap = []
185 d1.addErrback(errorTrap.append)
186
187 result = []
188 dl.addCallback(result.append)
189
190 d1.errback(GenericError('Bang'))
191 self.failUnlessEqual('Bang', errorTrap[0].value.args[0])
192 self.failUnlessEqual(1, len(result))
193 self.failUnlessEqual('Bang', result[0][0][1].value.args[0])
194
195 def testDeferredListConsumeErrors(self):
196 d1 = defer.Deferred()
197 dl = defer.DeferredList([d1], consumeErrors=True)
198
199 errorTrap = []
200 d1.addErrback(errorTrap.append)
201
202 result = []
203 dl.addCallback(result.append)
204
205 d1.errback(GenericError('Bang'))
206 self.failUnlessEqual([], errorTrap)
207 self.failUnlessEqual(1, len(result))
208 self.failUnlessEqual('Bang', result[0][0][1].value.args[0])
209
210 def testDeferredListFireOnOneErrorWithAlreadyFiredDeferreds(self):
211 # Create some deferreds, and errback one
212 d1 = defer.Deferred()
213 d2 = defer.Deferred()
214 d1.errback(GenericError('Bang'))
215
216 # *Then* build the DeferredList, with fireOnOneErrback=True
217 dl = defer.DeferredList([d1, d2], fireOnOneErrback=True)
218 result = []
219 dl.addErrback(result.append)
220 self.failUnlessEqual(1, len(result))
221
222 d1.addErrback(lambda e: None) # Swallow error
223
224 def testDeferredListWithAlreadyFiredDeferreds(self):
225 # Create some deferreds, and err one, call the other
226 d1 = defer.Deferred()
227 d2 = defer.Deferred()
228 d1.errback(GenericError('Bang'))
229 d2.callback(2)
230
231 # *Then* build the DeferredList
232 dl = defer.DeferredList([d1, d2])
233
234 result = []
235 dl.addCallback(result.append)
236
237 self.failUnlessEqual(1, len(result))
238
239 d1.addErrback(lambda e: None) # Swallow error
240
241 def testTimeOut(self):
242 """
243 Test that a Deferred which has setTimeout called on it and never has
244 C{callback} or C{errback} called on it eventually fails with a
245 L{error.TimeoutError}.
246 """
247 L = []
248 d = defer.Deferred()
249 d.setTimeout(0.01)
250 self.assertFailure(d, defer.TimeoutError)
251 d.addCallback(L.append)
252 self.failIf(L, "Deferred failed too soon.")
253 return d
254 testTimeOut.suppress = [_setTimeoutSuppression]
255
256
257 def testImmediateSuccess(self):
258 l = []
259 d = defer.succeed("success")
260 d.addCallback(l.append)
261 self.assertEquals(l, ["success"])
262
263
264 def test_immediateSuccessBeforeTimeout(self):
265 """
266 Test that a synchronously successful Deferred is not affected by a
267 C{setTimeout} call.
268 """
269 l = []
270 d = defer.succeed("success")
271 d.setTimeout(1.0)
272 d.addCallback(l.append)
273 self.assertEquals(l, ["success"])
274 test_immediateSuccessBeforeTimeout.suppress = [_setTimeoutSuppression]
275
276
277 def testImmediateFailure(self):
278 l = []
279 d = defer.fail(GenericError("fail"))
280 d.addErrback(l.append)
281 self.assertEquals(str(l[0].value), "fail")
282
283 def testPausedFailure(self):
284 l = []
285 d = defer.fail(GenericError("fail"))
286 d.pause()
287 d.addErrback(l.append)
288 self.assertEquals(l, [])
289 d.unpause()
290 self.assertEquals(str(l[0].value), "fail")
291
292 def testCallbackErrors(self):
293 l = []
294 d = defer.Deferred().addCallback(lambda _: 1/0).addErrback(l.append)
295 d.callback(1)
296 self.assert_(isinstance(l[0].value, ZeroDivisionError))
297 l = []
298 d = defer.Deferred().addCallback(
299 lambda _: failure.Failure(ZeroDivisionError())).addErrback(l.append)
300 d.callback(1)
301 self.assert_(isinstance(l[0].value, ZeroDivisionError))
302
303 def testUnpauseBeforeCallback(self):
304 d = defer.Deferred()
305 d.pause()
306 d.addCallback(self._callback)
307 d.unpause()
308
309 def testReturnDeferred(self):
310 d = defer.Deferred()
311 d2 = defer.Deferred()
312 d2.pause()
313 d.addCallback(lambda r, d2=d2: d2)
314 d.addCallback(self._callback)
315 d.callback(1)
316 assert self.callback_results is None, "Should not have been called yet."
317 d2.callback(2)
318 assert self.callback_results is None, "Still should not have been called yet."
319 d2.unpause()
320 assert self.callback_results[0][0] == 2, "Result should have been from s econd deferred:%s"% (self.callback_results,)
321
322 def testGatherResults(self):
323 # test successful list of deferreds
324 l = []
325 defer.gatherResults([defer.succeed(1), defer.succeed(2)]).addCallback(l. append)
326 self.assertEquals(l, [[1, 2]])
327 # test failing list of deferreds
328 l = []
329 dl = [defer.succeed(1), defer.fail(ValueError)]
330 defer.gatherResults(dl).addErrback(l.append)
331 self.assertEquals(len(l), 1)
332 self.assert_(isinstance(l[0], failure.Failure))
333 # get rid of error
334 dl[1].addErrback(lambda e: 1)
335
336
337 def test_maybeDeferredSync(self):
338 """
339 L{defer.maybeDeferred} should retrieve the result of a synchronous
340 function and pass it to its resulting L{defer.Deferred}.
341 """
342 S, E = [], []
343 d = defer.maybeDeferred((lambda x: x + 5), 10)
344 d.addCallbacks(S.append, E.append)
345 self.assertEquals(E, [])
346 self.assertEquals(S, [15])
347 return d
348
349
350 def test_maybeDeferredSyncError(self):
351 """
352 L{defer.maybeDeferred} should catch exception raised by a synchronous
353 function and errback its resulting L{defer.Deferred} with it.
354 """
355 S, E = [], []
356 try:
357 '10' + 5
358 except TypeError, e:
359 expected = str(e)
360 d = defer.maybeDeferred((lambda x: x + 5), '10')
361 d.addCallbacks(S.append, E.append)
362 self.assertEquals(S, [])
363 self.assertEquals(len(E), 1)
364 self.assertEquals(str(E[0].value), expected)
365 return d
366
367
368 def test_maybeDeferredAsync(self):
369 """
370 L{defer.maybeDeferred} should let L{defer.Deferred} instance pass by
371 so that original result is the same.
372 """
373 d = defer.Deferred()
374 d2 = defer.maybeDeferred(lambda: d)
375 d.callback('Success')
376 return d2.addCallback(self.assertEquals, 'Success')
377
378
379 def test_maybeDeferredAsyncError(self):
380 """
381 L{defer.maybeDeferred} should let L{defer.Deferred} instance pass by
382 so that L{failure.Failure} returned by the original instance is the
383 same.
384 """
385 d = defer.Deferred()
386 d2 = defer.maybeDeferred(lambda: d)
387 d.errback(failure.Failure(RuntimeError()))
388 return self.assertFailure(d2, RuntimeError)
389
390
391 def test_reentrantRunCallbacks(self):
392 """
393 A callback added to a L{Deferred} by a callback on that L{Deferred}
394 should be added to the end of the callback chain.
395 """
396 deferred = defer.Deferred()
397 called = []
398 def callback3(result):
399 called.append(3)
400 def callback2(result):
401 called.append(2)
402 def callback1(result):
403 called.append(1)
404 deferred.addCallback(callback3)
405 deferred.addCallback(callback1)
406 deferred.addCallback(callback2)
407 deferred.callback(None)
408 self.assertEqual(called, [1, 2, 3])
409
410
411 def test_nonReentrantCallbacks(self):
412 """
413 A callback added to a L{Deferred} by a callback on that L{Deferred}
414 should not be executed until the running callback returns.
415 """
416 deferred = defer.Deferred()
417 called = []
418 def callback2(result):
419 called.append(2)
420 def callback1(result):
421 called.append(1)
422 deferred.addCallback(callback2)
423 self.assertEquals(called, [1])
424 deferred.addCallback(callback1)
425 deferred.callback(None)
426 self.assertEqual(called, [1, 2])
427
428
429 def test_reentrantRunCallbacksWithFailure(self):
430 """
431 After an exception is raised by a callback which was added to a
432 L{Deferred} by a callback on that L{Deferred}, the L{Deferred} should
433 call the first errback with a L{Failure} wrapping that exception.
434 """
435 exceptionMessage = "callback raised exception"
436 deferred = defer.Deferred()
437 def callback2(result):
438 raise Exception(exceptionMessage)
439 def callback1(result):
440 deferred.addCallback(callback2)
441 deferred.addCallback(callback1)
442 deferred.callback(None)
443 self.assertFailure(deferred, Exception)
444 def cbFailed(exception):
445 self.assertEqual(exception.args, (exceptionMessage,))
446 deferred.addCallback(cbFailed)
447 return deferred
448
449
450
451 class AlreadyCalledTestCase(unittest.TestCase):
452 def setUp(self):
453 self._deferredWasDebugging = defer.getDebugging()
454 defer.setDebugging(True)
455
456 def tearDown(self):
457 defer.setDebugging(self._deferredWasDebugging)
458
459 def _callback(self, *args, **kw):
460 pass
461 def _errback(self, *args, **kw):
462 pass
463
464 def _call_1(self, d):
465 d.callback("hello")
466 def _call_2(self, d):
467 d.callback("twice")
468 def _err_1(self, d):
469 d.errback(failure.Failure(RuntimeError()))
470 def _err_2(self, d):
471 d.errback(failure.Failure(RuntimeError()))
472
473 def testAlreadyCalled_CC(self):
474 d = defer.Deferred()
475 d.addCallbacks(self._callback, self._errback)
476 self._call_1(d)
477 self.failUnlessRaises(defer.AlreadyCalledError, self._call_2, d)
478
479 def testAlreadyCalled_CE(self):
480 d = defer.Deferred()
481 d.addCallbacks(self._callback, self._errback)
482 self._call_1(d)
483 self.failUnlessRaises(defer.AlreadyCalledError, self._err_2, d)
484
485 def testAlreadyCalled_EE(self):
486 d = defer.Deferred()
487 d.addCallbacks(self._callback, self._errback)
488 self._err_1(d)
489 self.failUnlessRaises(defer.AlreadyCalledError, self._err_2, d)
490
491 def testAlreadyCalled_EC(self):
492 d = defer.Deferred()
493 d.addCallbacks(self._callback, self._errback)
494 self._err_1(d)
495 self.failUnlessRaises(defer.AlreadyCalledError, self._call_2, d)
496
497
498 def _count(self, linetype, func, lines, expected):
499 count = 0
500 for line in lines:
501 if (line.startswith(' %s:' % linetype) and
502 line.endswith(' %s' % func)):
503 count += 1
504 self.failUnless(count == expected)
505
506 def _check(self, e, caller, invoker1, invoker2):
507 # make sure the debugging information is vaguely correct
508 lines = e.args[0].split("\n")
509 # the creator should list the creator (testAlreadyCalledDebug) but not
510 # _call_1 or _call_2 or other invokers
511 self._count('C', caller, lines, 1)
512 self._count('C', '_call_1', lines, 0)
513 self._count('C', '_call_2', lines, 0)
514 self._count('C', '_err_1', lines, 0)
515 self._count('C', '_err_2', lines, 0)
516 # invoker should list the first invoker but not the second
517 self._count('I', invoker1, lines, 1)
518 self._count('I', invoker2, lines, 0)
519
520 def testAlreadyCalledDebug_CC(self):
521 d = defer.Deferred()
522 d.addCallbacks(self._callback, self._errback)
523 self._call_1(d)
524 try:
525 self._call_2(d)
526 except defer.AlreadyCalledError, e:
527 self._check(e, "testAlreadyCalledDebug_CC", "_call_1", "_call_2")
528 else:
529 self.fail("second callback failed to raise AlreadyCalledError")
530
531 def testAlreadyCalledDebug_CE(self):
532 d = defer.Deferred()
533 d.addCallbacks(self._callback, self._errback)
534 self._call_1(d)
535 try:
536 self._err_2(d)
537 except defer.AlreadyCalledError, e:
538 self._check(e, "testAlreadyCalledDebug_CE", "_call_1", "_err_2")
539 else:
540 self.fail("second errback failed to raise AlreadyCalledError")
541
542 def testAlreadyCalledDebug_EC(self):
543 d = defer.Deferred()
544 d.addCallbacks(self._callback, self._errback)
545 self._err_1(d)
546 try:
547 self._call_2(d)
548 except defer.AlreadyCalledError, e:
549 self._check(e, "testAlreadyCalledDebug_EC", "_err_1", "_call_2")
550 else:
551 self.fail("second callback failed to raise AlreadyCalledError")
552
553 def testAlreadyCalledDebug_EE(self):
554 d = defer.Deferred()
555 d.addCallbacks(self._callback, self._errback)
556 self._err_1(d)
557 try:
558 self._err_2(d)
559 except defer.AlreadyCalledError, e:
560 self._check(e, "testAlreadyCalledDebug_EE", "_err_1", "_err_2")
561 else:
562 self.fail("second errback failed to raise AlreadyCalledError")
563
564 def testNoDebugging(self):
565 defer.setDebugging(False)
566 d = defer.Deferred()
567 d.addCallbacks(self._callback, self._errback)
568 self._call_1(d)
569 try:
570 self._call_2(d)
571 except defer.AlreadyCalledError, e:
572 self.failIf(e.args)
573 else:
574 self.fail("second callback failed to raise AlreadyCalledError")
575
576
577 def testSwitchDebugging(self):
578 # Make sure Deferreds can deal with debug state flipping
579 # around randomly. This is covering a particular fixed bug.
580 defer.setDebugging(False)
581 d = defer.Deferred()
582 d.addBoth(lambda ign: None)
583 defer.setDebugging(True)
584 d.callback(None)
585
586 defer.setDebugging(False)
587 d = defer.Deferred()
588 d.callback(None)
589 defer.setDebugging(True)
590 d.addBoth(lambda ign: None)
591
592
593
594 class LogTestCase(unittest.TestCase):
595 """
596 Test logging of unhandled errors.
597 """
598
599 def setUp(self):
600 """
601 Add a custom observer to observer logging.
602 """
603 self.c = []
604 log.addObserver(self.c.append)
605
606 def tearDown(self):
607 """
608 Remove the observer.
609 """
610 log.removeObserver(self.c.append)
611
612 def _check(self):
613 """
614 Check the output of the log observer to see if the error is present.
615 """
616 c2 = [e for e in self.c if e["isError"]]
617 self.assertEquals(len(c2), 2)
618 c2[1]["failure"].trap(ZeroDivisionError)
619 self.flushLoggedErrors(ZeroDivisionError)
620
621 def test_errorLog(self):
622 """
623 Verify that when a Deferred with no references to it is fired, and its
624 final result (the one not handled by any callback) is an exception,
625 that exception will be logged immediately.
626 """
627 defer.Deferred().addCallback(lambda x: 1/0).callback(1)
628 self._check()
629
630 def test_errorLogWithInnerFrameRef(self):
631 """
632 Same as L{test_errorLog}, but with an inner frame.
633 """
634 def _subErrorLogWithInnerFrameRef():
635 d = defer.Deferred()
636 d.addCallback(lambda x: 1/0)
637 d.callback(1)
638
639 _subErrorLogWithInnerFrameRef()
640 gc.collect()
641 self._check()
642
643 def test_errorLogWithInnerFrameCycle(self):
644 """
645 Same as L{test_errorLogWithInnerFrameRef}, plus create a cycle.
646 """
647 def _subErrorLogWithInnerFrameCycle():
648 d = defer.Deferred()
649 d.addCallback(lambda x, d=d: 1/0)
650 d._d = d
651 d.callback(1)
652
653 _subErrorLogWithInnerFrameCycle()
654 gc.collect()
655 self._check()
656
657
658 class DeferredTestCaseII(unittest.TestCase):
659 def setUp(self):
660 self.callbackRan = 0
661
662 def testDeferredListEmpty(self):
663 """Testing empty DeferredList."""
664 dl = defer.DeferredList([])
665 dl.addCallback(self.cb_empty)
666
667 def cb_empty(self, res):
668 self.callbackRan = 1
669 self.failUnlessEqual([], res)
670
671 def tearDown(self):
672 self.failUnless(self.callbackRan, "Callback was never run.")
673
674 class OtherPrimitives(unittest.TestCase):
675 def _incr(self, result):
676 self.counter += 1
677
678 def setUp(self):
679 self.counter = 0
680
681 def testLock(self):
682 lock = defer.DeferredLock()
683 lock.acquire().addCallback(self._incr)
684 self.failUnless(lock.locked)
685 self.assertEquals(self.counter, 1)
686
687 lock.acquire().addCallback(self._incr)
688 self.failUnless(lock.locked)
689 self.assertEquals(self.counter, 1)
690
691 lock.release()
692 self.failUnless(lock.locked)
693 self.assertEquals(self.counter, 2)
694
695 lock.release()
696 self.failIf(lock.locked)
697 self.assertEquals(self.counter, 2)
698
699 self.assertRaises(TypeError, lock.run)
700
701 firstUnique = object()
702 secondUnique = object()
703
704 controlDeferred = defer.Deferred()
705 def helper(self, b):
706 self.b = b
707 return controlDeferred
708
709 resultDeferred = lock.run(helper, self=self, b=firstUnique)
710 self.failUnless(lock.locked)
711 self.assertEquals(self.b, firstUnique)
712
713 resultDeferred.addCallback(lambda x: setattr(self, 'result', x))
714
715 lock.acquire().addCallback(self._incr)
716 self.failUnless(lock.locked)
717 self.assertEquals(self.counter, 2)
718
719 controlDeferred.callback(secondUnique)
720 self.assertEquals(self.result, secondUnique)
721 self.failUnless(lock.locked)
722 self.assertEquals(self.counter, 3)
723
724 lock.release()
725 self.failIf(lock.locked)
726
727 def testSemaphore(self):
728 N = 13
729 sem = defer.DeferredSemaphore(N)
730
731 controlDeferred = defer.Deferred()
732 def helper(self, arg):
733 self.arg = arg
734 return controlDeferred
735
736 results = []
737 uniqueObject = object()
738 resultDeferred = sem.run(helper, self=self, arg=uniqueObject)
739 resultDeferred.addCallback(results.append)
740 resultDeferred.addCallback(self._incr)
741 self.assertEquals(results, [])
742 self.assertEquals(self.arg, uniqueObject)
743 controlDeferred.callback(None)
744 self.assertEquals(results.pop(), None)
745 self.assertEquals(self.counter, 1)
746
747 self.counter = 0
748 for i in range(1, 1 + N):
749 sem.acquire().addCallback(self._incr)
750 self.assertEquals(self.counter, i)
751
752 sem.acquire().addCallback(self._incr)
753 self.assertEquals(self.counter, N)
754
755 sem.release()
756 self.assertEquals(self.counter, N + 1)
757
758 for i in range(1, 1 + N):
759 sem.release()
760 self.assertEquals(self.counter, N + 1)
761
762 def testQueue(self):
763 N, M = 2, 2
764 queue = defer.DeferredQueue(N, M)
765
766 gotten = []
767
768 for i in range(M):
769 queue.get().addCallback(gotten.append)
770 self.assertRaises(defer.QueueUnderflow, queue.get)
771
772 for i in range(M):
773 queue.put(i)
774 self.assertEquals(gotten, range(i + 1))
775 for i in range(N):
776 queue.put(N + i)
777 self.assertEquals(gotten, range(M))
778 self.assertRaises(defer.QueueOverflow, queue.put, None)
779
780 gotten = []
781 for i in range(N):
782 queue.get().addCallback(gotten.append)
783 self.assertEquals(gotten, range(N, N + i + 1))
784
785 queue = defer.DeferredQueue()
786 gotten = []
787 for i in range(N):
788 queue.get().addCallback(gotten.append)
789 for i in range(N):
790 queue.put(i)
791 self.assertEquals(gotten, range(N))
792
793 queue = defer.DeferredQueue(size=0)
794 self.assertRaises(defer.QueueOverflow, queue.put, None)
795
796 queue = defer.DeferredQueue(backlog=0)
797 self.assertRaises(defer.QueueUnderflow, queue.get)
798
799
800
801 class DeferredFilesystemLockTestCase(unittest.TestCase):
802 """
803 Test the behavior of L{DeferredFilesystemLock}
804 """
805 def setUp(self):
806 self.clock = Clock()
807 self.lock = defer.DeferredFilesystemLock(self.mktemp(),
808 scheduler=self.clock)
809
810
811 def test_waitUntilLockedWithNoLock(self):
812 """
813 Test that the lock can be acquired when no lock is held
814 """
815 d = self.lock.deferUntilLocked(timeout=1)
816
817 return d
818
819
820 def test_waitUntilLockedWithTimeoutLocked(self):
821 """
822 Test that the lock can not be acquired when the lock is held
823 for longer than the timeout.
824 """
825 self.failUnless(self.lock.lock())
826
827 d = self.lock.deferUntilLocked(timeout=5.5)
828 self.assertFailure(d, defer.TimeoutError)
829
830 self.clock.pump([1]*10)
831
832 return d
833
834
835 def test_waitUntilLockedWithTimeoutUnlocked(self):
836 """
837 Test that a lock can be acquired while a lock is held
838 but the lock is unlocked before our timeout.
839 """
840 def onTimeout(f):
841 f.trap(defer.TimeoutError)
842 self.fail("Should not have timed out")
843
844 self.failUnless(self.lock.lock())
845
846 self.clock.callLater(1, self.lock.unlock)
847 d = self.lock.deferUntilLocked(timeout=10)
848 d.addErrback(onTimeout)
849
850 self.clock.pump([1]*10)
851
852 return d
853
854
855 def test_defaultScheduler(self):
856 """
857 Test that the default scheduler is set up properly.
858 """
859 lock = defer.DeferredFilesystemLock(self.mktemp())
860
861 self.assertEquals(lock._scheduler, reactor)
862
863
864 def test_concurrentUsage(self):
865 """
866 Test that an appropriate exception is raised when attempting
867 to use deferUntilLocked concurrently.
868 """
869 self.lock.lock()
870 self.clock.callLater(1, self.lock.unlock)
871
872 d = self.lock.deferUntilLocked()
873 d2 = self.lock.deferUntilLocked()
874
875 self.assertFailure(d2, defer.AlreadyTryingToLockError)
876
877 self.clock.advance(1)
878
879 return d
880
881
882 def test_multipleUsages(self):
883 """
884 Test that a DeferredFilesystemLock can be used multiple times
885 """
886 def lockAquired(ign):
887 self.lock.unlock()
888 d = self.lock.deferUntilLocked()
889 return d
890
891 self.lock.lock()
892 self.clock.callLater(1, self.lock.unlock)
893
894 d = self.lock.deferUntilLocked()
895 d.addCallback(lockAquired)
896
897 self.clock.advance(1)
898
899 return d
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/test/test_cooperator.py ('k') | third_party/twisted_8_1/twisted/test/test_defgen.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698