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

Side by Side Diff: third_party/twisted_8_1/twisted/test/test_internet.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 # Copyright (c) 2001-2007 Twisted Matrix Laboratories.
2 # See LICENSE for details.
3
4
5 from twisted.trial import unittest
6 from twisted.internet import reactor, protocol, error, abstract, defer
7 from twisted.internet import interfaces, base, task
8 from twisted.internet.tcp import Connection
9
10 from twisted.test.time_helpers import Clock
11
12 try:
13 from twisted.internet import ssl
14 except ImportError:
15 ssl = None
16 if ssl and not ssl.supported:
17 ssl = None
18
19 from twisted.internet.defer import Deferred, maybeDeferred
20 from twisted.python import util, runtime
21
22 import os
23 import sys
24 import time
25 import socket
26
27
28
29 class ThreePhaseEventTests(unittest.TestCase):
30 """
31 Tests for the private implementation helpers for system event triggers.
32 """
33 def setUp(self):
34 """
35 Create a trigger, an argument, and an event to be used by tests.
36 """
37 self.trigger = lambda x: None
38 self.arg = object()
39 self.event = base._ThreePhaseEvent()
40
41
42 def test_addInvalidPhase(self):
43 """
44 L{_ThreePhaseEvent.addTrigger} should raise L{KeyError} when called
45 with an invalid phase.
46 """
47 self.assertRaises(
48 KeyError,
49 self.event.addTrigger, 'xxx', self.trigger, self.arg)
50
51
52 def test_addBeforeTrigger(self):
53 """
54 L{_ThreePhaseEvent.addTrigger} should accept C{'before'} as a phase, a
55 callable, and some arguments and add the callable with the arguments to
56 the before list.
57 """
58 self.event.addTrigger('before', self.trigger, self.arg)
59 self.assertEqual(
60 self.event.before,
61 [(self.trigger, (self.arg,), {})])
62
63
64 def test_addDuringTrigger(self):
65 """
66 L{_ThreePhaseEvent.addTrigger} should accept C{'during'} as a phase, a
67 callable, and some arguments and add the callable with the arguments to
68 the during list.
69 """
70 self.event.addTrigger('during', self.trigger, self.arg)
71 self.assertEqual(
72 self.event.during,
73 [(self.trigger, (self.arg,), {})])
74
75
76 def test_addAfterTrigger(self):
77 """
78 L{_ThreePhaseEvent.addTrigger} should accept C{'after'} as a phase, a
79 callable, and some arguments and add the callable with the arguments to
80 the after list.
81 """
82 self.event.addTrigger('after', self.trigger, self.arg)
83 self.assertEqual(
84 self.event.after,
85 [(self.trigger, (self.arg,), {})])
86
87
88 def test_removeTrigger(self):
89 """
90 L{_ThreePhaseEvent.removeTrigger} should accept an opaque object
91 previously returned by L{_ThreePhaseEvent.addTrigger} and remove the
92 associated trigger.
93 """
94 handle = self.event.addTrigger('before', self.trigger, self.arg)
95 self.event.removeTrigger(handle)
96 self.assertEqual(self.event.before, [])
97
98
99 def test_removeNonexistentTrigger(self):
100 """
101 L{_ThreePhaseEvent.removeTrigger} should raise L{ValueError} when given
102 an object not previously returned by L{_ThreePhaseEvent.addTrigger}.
103 """
104 self.assertRaises(ValueError, self.event.removeTrigger, object())
105
106
107 def test_removeRemovedTrigger(self):
108 """
109 L{_ThreePhaseEvent.removeTrigger} should raise L{ValueError} the second
110 time it is called with an object returned by
111 L{_ThreePhaseEvent.addTrigger}.
112 """
113 handle = self.event.addTrigger('before', self.trigger, self.arg)
114 self.event.removeTrigger(handle)
115 self.assertRaises(ValueError, self.event.removeTrigger, handle)
116
117
118 def test_removeAlmostValidTrigger(self):
119 """
120 L{_ThreePhaseEvent.removeTrigger} should raise L{ValueError} if it is
121 given a trigger handle which resembles a valid trigger handle aside
122 from its phase being incorrect.
123 """
124 self.assertRaises(
125 KeyError,
126 self.event.removeTrigger, ('xxx', self.trigger, (self.arg,), {}))
127
128
129 def test_fireEvent(self):
130 """
131 L{_ThreePhaseEvent.fireEvent} should call I{before}, I{during}, and
132 I{after} phase triggers in that order.
133 """
134 events = []
135 self.event.addTrigger('after', events.append, ('first', 'after'))
136 self.event.addTrigger('during', events.append, ('first', 'during'))
137 self.event.addTrigger('before', events.append, ('first', 'before'))
138 self.event.addTrigger('before', events.append, ('second', 'before'))
139 self.event.addTrigger('during', events.append, ('second', 'during'))
140 self.event.addTrigger('after', events.append, ('second', 'after'))
141
142 self.assertEqual(events, [])
143 self.event.fireEvent()
144 self.assertEqual(events,
145 [('first', 'before'), ('second', 'before'),
146 ('first', 'during'), ('second', 'during'),
147 ('first', 'after'), ('second', 'after')])
148
149
150 def test_asynchronousBefore(self):
151 """
152 L{_ThreePhaseEvent.fireEvent} should wait for any L{Deferred} returned
153 by a I{before} phase trigger before proceeding to I{during} events.
154 """
155 events = []
156 beforeResult = Deferred()
157 self.event.addTrigger('before', lambda: beforeResult)
158 self.event.addTrigger('during', events.append, 'during')
159 self.event.addTrigger('after', events.append, 'after')
160
161 self.assertEqual(events, [])
162 self.event.fireEvent()
163 self.assertEqual(events, [])
164 beforeResult.callback(None)
165 self.assertEqual(events, ['during', 'after'])
166
167
168 def test_beforeTriggerException(self):
169 """
170 If a before-phase trigger raises a synchronous exception, it should be
171 logged and the remaining triggers should be run.
172 """
173 events = []
174
175 class DummyException(Exception):
176 pass
177
178 def raisingTrigger():
179 raise DummyException()
180
181 self.event.addTrigger('before', raisingTrigger)
182 self.event.addTrigger('before', events.append, 'before')
183 self.event.addTrigger('during', events.append, 'during')
184 self.event.fireEvent()
185 self.assertEqual(events, ['before', 'during'])
186 errors = self.flushLoggedErrors(DummyException)
187 self.assertEqual(len(errors), 1)
188
189
190 def test_duringTriggerException(self):
191 """
192 If a during-phase trigger raises a synchronous exception, it should be
193 logged and the remaining triggers should be run.
194 """
195 events = []
196
197 class DummyException(Exception):
198 pass
199
200 def raisingTrigger():
201 raise DummyException()
202
203 self.event.addTrigger('during', raisingTrigger)
204 self.event.addTrigger('during', events.append, 'during')
205 self.event.addTrigger('after', events.append, 'after')
206 self.event.fireEvent()
207 self.assertEqual(events, ['during', 'after'])
208 errors = self.flushLoggedErrors(DummyException)
209 self.assertEqual(len(errors), 1)
210
211
212 def test_synchronousRemoveAlreadyExecutedBefore(self):
213 """
214 If a before-phase trigger tries to remove another before-phase trigger
215 which has already run, a warning should be emitted.
216 """
217 events = []
218
219 def removeTrigger():
220 self.event.removeTrigger(beforeHandle)
221
222 beforeHandle = self.event.addTrigger('before', events.append, ('first', 'before'))
223 self.event.addTrigger('before', removeTrigger)
224 self.event.addTrigger('before', events.append, ('second', 'before'))
225 self.assertWarns(
226 DeprecationWarning,
227 "Removing already-fired system event triggers will raise an "
228 "exception in a future version of Twisted.",
229 __file__,
230 self.event.fireEvent)
231 self.assertEqual(events, [('first', 'before'), ('second', 'before')])
232
233
234 def test_synchronousRemovePendingBefore(self):
235 """
236 If a before-phase trigger removes another before-phase trigger which
237 has not yet run, the removed trigger should not be run.
238 """
239 events = []
240 self.event.addTrigger(
241 'before', lambda: self.event.removeTrigger(beforeHandle))
242 beforeHandle = self.event.addTrigger(
243 'before', events.append, ('first', 'before'))
244 self.event.addTrigger('before', events.append, ('second', 'before'))
245 self.event.fireEvent()
246 self.assertEqual(events, [('second', 'before')])
247
248
249 def test_synchronousBeforeRemovesDuring(self):
250 """
251 If a before-phase trigger removes a during-phase trigger, the
252 during-phase trigger should not be run.
253 """
254 events = []
255 self.event.addTrigger(
256 'before', lambda: self.event.removeTrigger(duringHandle))
257 duringHandle = self.event.addTrigger('during', events.append, 'during')
258 self.event.addTrigger('after', events.append, 'after')
259 self.event.fireEvent()
260 self.assertEqual(events, ['after'])
261
262
263 def test_asynchronousBeforeRemovesDuring(self):
264 """
265 If a before-phase trigger returns a L{Deferred} and later removes a
266 during-phase trigger before the L{Deferred} fires, the during-phase
267 trigger should not be run.
268 """
269 events = []
270 beforeResult = Deferred()
271 self.event.addTrigger('before', lambda: beforeResult)
272 duringHandle = self.event.addTrigger('during', events.append, 'during')
273 self.event.addTrigger('after', events.append, 'after')
274 self.event.fireEvent()
275 self.event.removeTrigger(duringHandle)
276 beforeResult.callback(None)
277 self.assertEqual(events, ['after'])
278
279
280 def test_synchronousBeforeRemovesConspicuouslySimilarDuring(self):
281 """
282 If a before-phase trigger removes a during-phase trigger which is
283 identical to an already-executed before-phase trigger aside from their
284 phases, no warning should be emitted and the during-phase trigger
285 should not be run.
286 """
287 events = []
288 def trigger():
289 events.append('trigger')
290 self.event.addTrigger('before', trigger)
291 self.event.addTrigger(
292 'before', lambda: self.event.removeTrigger(duringTrigger))
293 duringTrigger = self.event.addTrigger('during', trigger)
294 self.event.fireEvent()
295 self.assertEqual(events, ['trigger'])
296
297
298 def test_synchronousRemovePendingDuring(self):
299 """
300 If a during-phase trigger removes another during-phase trigger which
301 has not yet run, the removed trigger should not be run.
302 """
303 events = []
304 self.event.addTrigger(
305 'during', lambda: self.event.removeTrigger(duringHandle))
306 duringHandle = self.event.addTrigger(
307 'during', events.append, ('first', 'during'))
308 self.event.addTrigger(
309 'during', events.append, ('second', 'during'))
310 self.event.fireEvent()
311 self.assertEqual(events, [('second', 'during')])
312
313
314 def test_triggersRunOnce(self):
315 """
316 A trigger should only be called on the first call to
317 L{_ThreePhaseEvent.fireEvent}.
318 """
319 events = []
320 self.event.addTrigger('before', events.append, 'before')
321 self.event.addTrigger('during', events.append, 'during')
322 self.event.addTrigger('after', events.append, 'after')
323 self.event.fireEvent()
324 self.event.fireEvent()
325 self.assertEqual(events, ['before', 'during', 'after'])
326
327
328 def test_finishedBeforeTriggersCleared(self):
329 """
330 The temporary list L{_ThreePhaseEvent.finishedBefore} should be emptied
331 and the state reset to C{'BASE'} before the first during-phase trigger
332 executes.
333 """
334 events = []
335 def duringTrigger():
336 events.append('during')
337 self.assertEqual(self.event.finishedBefore, [])
338 self.assertEqual(self.event.state, 'BASE')
339 self.event.addTrigger('before', events.append, 'before')
340 self.event.addTrigger('during', duringTrigger)
341 self.event.fireEvent()
342 self.assertEqual(events, ['before', 'during'])
343
344
345
346 class SystemEventTestCase(unittest.TestCase):
347 """
348 Tests for the reactor's implementation of the C{fireSystemEvent},
349 C{addSystemEventTrigger}, and C{removeSystemEventTrigger} methods of the
350 L{IReactorCore} interface.
351
352 @ivar triggers: A list of the handles to triggers which have been added to
353 the reactor.
354 """
355 def setUp(self):
356 """
357 Create an empty list in which to store trigger handles.
358 """
359 self.triggers = []
360
361
362 def tearDown(self):
363 """
364 Remove all remaining triggers from the reactor.
365 """
366 while self.triggers:
367 trigger = self.triggers.pop()
368 try:
369 reactor.removeSystemEventTrigger(trigger)
370 except (ValueError, KeyError):
371 pass
372
373
374 def addTrigger(self, event, phase, func):
375 """
376 Add a trigger to the reactor and remember it in C{self.triggers}.
377 """
378 t = reactor.addSystemEventTrigger(event, phase, func)
379 self.triggers.append(t)
380 return t
381
382
383 def removeTrigger(self, trigger):
384 """
385 Remove a trigger by its handle from the reactor and from
386 C{self.triggers}.
387 """
388 reactor.removeSystemEventTrigger(trigger)
389 self.triggers.remove(trigger)
390
391
392 def _addSystemEventTriggerTest(self, phase):
393 eventType = 'test'
394 events = []
395 def trigger():
396 events.append(None)
397 self.addTrigger(phase, eventType, trigger)
398 self.assertEqual(events, [])
399 reactor.fireSystemEvent(eventType)
400 self.assertEqual(events, [None])
401
402
403 def test_beforePhase(self):
404 """
405 L{IReactorCore.addSystemEventTrigger} should accept the C{'before'}
406 phase and not call the given object until the right event is fired.
407 """
408 self._addSystemEventTriggerTest('before')
409
410
411 def test_duringPhase(self):
412 """
413 L{IReactorCore.addSystemEventTrigger} should accept the C{'during'}
414 phase and not call the given object until the right event is fired.
415 """
416 self._addSystemEventTriggerTest('during')
417
418
419 def test_afterPhase(self):
420 """
421 L{IReactorCore.addSystemEventTrigger} should accept the C{'after'}
422 phase and not call the given object until the right event is fired.
423 """
424 self._addSystemEventTriggerTest('after')
425
426
427 def test_unknownPhase(self):
428 """
429 L{IReactorCore.addSystemEventTrigger} should reject phases other than
430 C{'before'}, C{'during'}, or C{'after'}.
431 """
432 eventType = 'test'
433 self.assertRaises(
434 KeyError, self.addTrigger, 'xxx', eventType, lambda: None)
435
436
437 def test_beforePreceedsDuring(self):
438 """
439 L{IReactorCore.addSystemEventTrigger} should call triggers added to the
440 C{'before'} phase before it calls triggers added to the C{'during'}
441 phase.
442 """
443 eventType = 'test'
444 events = []
445 def beforeTrigger():
446 events.append('before')
447 def duringTrigger():
448 events.append('during')
449 self.addTrigger('before', eventType, beforeTrigger)
450 self.addTrigger('during', eventType, duringTrigger)
451 self.assertEqual(events, [])
452 reactor.fireSystemEvent(eventType)
453 self.assertEqual(events, ['before', 'during'])
454
455
456 def test_duringPreceedsAfter(self):
457 """
458 L{IReactorCore.addSystemEventTrigger} should call triggers added to the
459 C{'during'} phase before it calls triggers added to the C{'after'}
460 phase.
461 """
462 eventType = 'test'
463 events = []
464 def duringTrigger():
465 events.append('during')
466 def afterTrigger():
467 events.append('after')
468 self.addTrigger('during', eventType, duringTrigger)
469 self.addTrigger('after', eventType, afterTrigger)
470 self.assertEqual(events, [])
471 reactor.fireSystemEvent(eventType)
472 self.assertEqual(events, ['during', 'after'])
473
474
475 def test_beforeReturnsDeferred(self):
476 """
477 If a trigger added to the C{'before'} phase of an event returns a
478 L{Deferred}, the C{'during'} phase should be delayed until it is called
479 back.
480 """
481 triggerDeferred = Deferred()
482 eventType = 'test'
483 events = []
484 def beforeTrigger():
485 return triggerDeferred
486 def duringTrigger():
487 events.append('during')
488 self.addTrigger('before', eventType, beforeTrigger)
489 self.addTrigger('during', eventType, duringTrigger)
490 self.assertEqual(events, [])
491 reactor.fireSystemEvent(eventType)
492 self.assertEqual(events, [])
493 triggerDeferred.callback(None)
494 self.assertEqual(events, ['during'])
495
496
497 def test_multipleBeforeReturnDeferred(self):
498 """
499 If more than one trigger added to the C{'before'} phase of an event
500 return L{Deferred}s, the C{'during'} phase should be delayed until they
501 are all called back.
502 """
503 firstDeferred = Deferred()
504 secondDeferred = Deferred()
505 eventType = 'test'
506 events = []
507 def firstBeforeTrigger():
508 return firstDeferred
509 def secondBeforeTrigger():
510 return secondDeferred
511 def duringTrigger():
512 events.append('during')
513 self.addTrigger('before', eventType, firstBeforeTrigger)
514 self.addTrigger('before', eventType, secondBeforeTrigger)
515 self.addTrigger('during', eventType, duringTrigger)
516 self.assertEqual(events, [])
517 reactor.fireSystemEvent(eventType)
518 self.assertEqual(events, [])
519 firstDeferred.callback(None)
520 self.assertEqual(events, [])
521 secondDeferred.callback(None)
522 self.assertEqual(events, ['during'])
523
524
525 def test_subsequentBeforeTriggerFiresPriorBeforeDeferred(self):
526 """
527 If a trigger added to the C{'before'} phase of an event calls back a
528 L{Deferred} returned by an earlier trigger in the C{'before'} phase of
529 the same event, the remaining C{'before'} triggers for that event
530 should be run and any further L{Deferred}s waited on before proceeding
531 to the C{'during'} events.
532 """
533 eventType = 'test'
534 events = []
535 firstDeferred = Deferred()
536 secondDeferred = Deferred()
537 def firstBeforeTrigger():
538 return firstDeferred
539 def secondBeforeTrigger():
540 firstDeferred.callback(None)
541 def thirdBeforeTrigger():
542 events.append('before')
543 return secondDeferred
544 def duringTrigger():
545 events.append('during')
546 self.addTrigger('before', eventType, firstBeforeTrigger)
547 self.addTrigger('before', eventType, secondBeforeTrigger)
548 self.addTrigger('before', eventType, thirdBeforeTrigger)
549 self.addTrigger('during', eventType, duringTrigger)
550 self.assertEqual(events, [])
551 reactor.fireSystemEvent(eventType)
552 self.assertEqual(events, ['before'])
553 secondDeferred.callback(None)
554 self.assertEqual(events, ['before', 'during'])
555
556
557 def test_removeSystemEventTrigger(self):
558 """
559 A trigger removed with L{IReactorCore.removeSystemEventTrigger} should
560 not be called when the event fires.
561 """
562 eventType = 'test'
563 events = []
564 def firstBeforeTrigger():
565 events.append('first')
566 def secondBeforeTrigger():
567 events.append('second')
568 self.addTrigger('before', eventType, firstBeforeTrigger)
569 self.removeTrigger(
570 self.addTrigger('before', eventType, secondBeforeTrigger))
571 self.assertEqual(events, [])
572 reactor.fireSystemEvent(eventType)
573 self.assertEqual(events, ['first'])
574
575
576 def test_removeNonExistentSystemEventTrigger(self):
577 """
578 Passing an object to L{IReactorCore.removeSystemEventTrigger} which was
579 not returned by a previous call to
580 L{IReactorCore.addSystemEventTrigger} or which has already been passed
581 to C{removeSystemEventTrigger} should result in L{TypeError},
582 L{KeyError}, or L{ValueError} being raised.
583 """
584 b = self.addTrigger('during', 'test', lambda: None)
585 self.removeTrigger(b)
586 self.assertRaises(
587 TypeError, reactor.removeSystemEventTrigger, None)
588 self.assertRaises(
589 ValueError, reactor.removeSystemEventTrigger, b)
590 self.assertRaises(
591 KeyError,
592 reactor.removeSystemEventTrigger,
593 (b[0], ('xxx',) + b[1][1:]))
594
595
596 def test_interactionBetweenDifferentEvents(self):
597 """
598 L{IReactorCore.fireSystemEvent} should behave the same way for a
599 particular system event regardless of whether Deferreds are being
600 waited on for a different system event.
601 """
602 events = []
603
604 firstEvent = 'first-event'
605 firstDeferred = Deferred()
606 def beforeFirstEvent():
607 events.append(('before', 'first'))
608 return firstDeferred
609 def afterFirstEvent():
610 events.append(('after', 'first'))
611
612 secondEvent = 'second-event'
613 secondDeferred = Deferred()
614 def beforeSecondEvent():
615 events.append(('before', 'second'))
616 return secondDeferred
617 def afterSecondEvent():
618 events.append(('after', 'second'))
619
620 self.addTrigger('before', firstEvent, beforeFirstEvent)
621 self.addTrigger('after', firstEvent, afterFirstEvent)
622 self.addTrigger('before', secondEvent, beforeSecondEvent)
623 self.addTrigger('after', secondEvent, afterSecondEvent)
624
625 self.assertEqual(events, [])
626
627 # After this, firstEvent should be stuck before 'during' waiting for
628 # firstDeferred.
629 reactor.fireSystemEvent(firstEvent)
630 self.assertEqual(events, [('before', 'first')])
631
632 # After this, secondEvent should be stuck before 'during' waiting for
633 # secondDeferred.
634 reactor.fireSystemEvent(secondEvent)
635 self.assertEqual(events, [('before', 'first'), ('before', 'second')])
636
637 # After this, firstEvent should have finished completely, but
638 # secondEvent should be at the same place.
639 firstDeferred.callback(None)
640 self.assertEqual(events, [('before', 'first'), ('before', 'second'),
641 ('after', 'first')])
642
643 # After this, secondEvent should have finished completely.
644 secondDeferred.callback(None)
645 self.assertEqual(events, [('before', 'first'), ('before', 'second'),
646 ('after', 'first'), ('after', 'second')])
647
648
649
650 class TimeTestCase(unittest.TestCase):
651 """
652 Tests for the IReactorTime part of the reactor.
653 """
654
655
656 def test_seconds(self):
657 """
658 L{twisted.internet.reactor.seconds} should return something
659 like a number.
660
661 1. This test specifically does not assert any relation to the
662 "system time" as returned by L{time.time} or
663 L{twisted.python.runtime.seconds}, because at some point we
664 may find a better option for scheduling calls than
665 wallclock-time.
666 2. This test *also* does not assert anything about the type of
667 the result, because operations may not return ints or
668 floats: For example, datetime-datetime == timedelta(0).
669 """
670 now = reactor.seconds()
671 self.assertEquals(now-now+now, now)
672
673
674 def test_callLaterUsesReactorSecondsInDelayedCall(self):
675 """
676 L{reactor.callLater} should use the reactor's seconds factory
677 to produce the time at which the DelayedCall will be called.
678 """
679 oseconds = reactor.seconds
680 reactor.seconds = lambda: 100
681 try:
682 call = reactor.callLater(5, lambda: None)
683 self.assertEquals(call.getTime(), 105)
684 finally:
685 reactor.seconds = oseconds
686
687
688 def test_callLaterUsesReactorSecondsAsDelayedCallSecondsFactory(self):
689 """
690 L{reactor.callLater} should propagate its own seconds factory
691 to the DelayedCall to use as its own seconds factory.
692 """
693 oseconds = reactor.seconds
694 reactor.seconds = lambda: 100
695 try:
696 call = reactor.callLater(5, lambda: None)
697 self.assertEquals(call.seconds(), 100)
698 finally:
699 reactor.seconds = oseconds
700
701
702 def test_callLater(self):
703 """
704 Test that a DelayedCall really calls the function it is
705 supposed to call.
706 """
707 d = Deferred()
708 reactor.callLater(0, d.callback, None)
709 d.addCallback(self.assertEqual, None)
710 return d
711
712
713 def test_cancelDelayedCall(self):
714 """
715 Test that when a DelayedCall is cancelled it does not run.
716 """
717 called = []
718 def function():
719 called.append(None)
720 call = reactor.callLater(0, function)
721 call.cancel()
722
723 # Schedule a call in two "iterations" to check to make sure that the
724 # above call never ran.
725 d = Deferred()
726 def check():
727 try:
728 self.assertEqual(called, [])
729 except:
730 d.errback()
731 else:
732 d.callback(None)
733 reactor.callLater(0, reactor.callLater, 0, check)
734 return d
735
736
737 def test_cancelCancelledDelayedCall(self):
738 """
739 Test that cancelling a DelayedCall which has already been cancelled
740 raises the appropriate exception.
741 """
742 call = reactor.callLater(0, lambda: None)
743 call.cancel()
744 self.assertRaises(error.AlreadyCancelled, call.cancel)
745
746
747 def test_cancelCalledDelayedCallSynchronous(self):
748 """
749 Test that cancelling a DelayedCall in the DelayedCall's function as
750 that function is being invoked by the DelayedCall raises the
751 appropriate exception.
752 """
753 d = Deferred()
754 def later():
755 try:
756 self.assertRaises(error.AlreadyCalled, call.cancel)
757 except:
758 d.errback()
759 else:
760 d.callback(None)
761 call = reactor.callLater(0, later)
762 return d
763
764
765 def test_cancelCalledDelayedCallAsynchronous(self):
766 """
767 Test that cancelling a DelayedCall after it has run its function
768 raises the appropriate exception.
769 """
770 d = Deferred()
771 def check():
772 try:
773 self.assertRaises(error.AlreadyCalled, call.cancel)
774 except:
775 d.errback()
776 else:
777 d.callback(None)
778 def later():
779 reactor.callLater(0, check)
780 call = reactor.callLater(0, later)
781 return d
782
783
784 def testCallLaterDelayAndReset(self):
785 """
786 Test that the reactor handles DelayedCalls which have been
787 reset or delayed.
788 """
789 clock = Clock()
790 clock.install()
791 try:
792 callbackTimes = [None, None]
793
794 def resetCallback():
795 callbackTimes[0] = clock()
796
797 def delayCallback():
798 callbackTimes[1] = clock()
799
800 ireset = reactor.callLater(2, resetCallback)
801 idelay = reactor.callLater(3, delayCallback)
802
803 clock.pump(reactor, [0, 1])
804
805 self.assertIdentical(callbackTimes[0], None)
806 self.assertIdentical(callbackTimes[1], None)
807
808 ireset.reset(2) # (now)1 + 2 = 3
809 idelay.delay(3) # (orig)3 + 3 = 6
810
811 clock.pump(reactor, [0, 1])
812
813 self.assertIdentical(callbackTimes[0], None)
814 self.assertIdentical(callbackTimes[1], None)
815
816 clock.pump(reactor, [0, 1])
817
818 self.assertEquals(callbackTimes[0], 3)
819 self.assertEquals(callbackTimes[1], None)
820
821 clock.pump(reactor, [0, 3])
822 self.assertEquals(callbackTimes[1], 6)
823 finally:
824 clock.uninstall()
825
826
827 def testCallLaterTime(self):
828 d = reactor.callLater(10, lambda: None)
829 try:
830 self.failUnless(d.getTime() - (time.time() + 10) < 1)
831 finally:
832 d.cancel()
833
834 def testCallInNextIteration(self):
835 calls = []
836 def f1():
837 calls.append('f1')
838 reactor.callLater(0.0, f2)
839 def f2():
840 calls.append('f2')
841 reactor.callLater(0.0, f3)
842 def f3():
843 calls.append('f3')
844
845 reactor.callLater(0, f1)
846 self.assertEquals(calls, [])
847 reactor.iterate()
848 self.assertEquals(calls, ['f1'])
849 reactor.iterate()
850 self.assertEquals(calls, ['f1', 'f2'])
851 reactor.iterate()
852 self.assertEquals(calls, ['f1', 'f2', 'f3'])
853
854 def testCallLaterOrder(self):
855 l = []
856 l2 = []
857 def f(x):
858 l.append(x)
859 def f2(x):
860 l2.append(x)
861 def done():
862 self.assertEquals(l, range(20))
863 def done2():
864 self.assertEquals(l2, range(10))
865
866 for n in range(10):
867 reactor.callLater(0, f, n)
868 for n in range(10):
869 reactor.callLater(0, f, n+10)
870 reactor.callLater(0.1, f2, n)
871
872 reactor.callLater(0, done)
873 reactor.callLater(0.1, done2)
874 d = Deferred()
875 reactor.callLater(0.2, d.callback, None)
876 return d
877
878 testCallLaterOrder.todo = "See bug 1396"
879 testCallLaterOrder.skip = "Trial bug, todo doesn't work! See bug 1397"
880 def testCallLaterOrder2(self):
881 # This time destroy the clock resolution so that it fails reliably
882 # even on systems that don't have a crappy clock resolution.
883
884 def seconds():
885 return int(time.time())
886
887 base_original = base.seconds
888 runtime_original = runtime.seconds
889 base.seconds = seconds
890 runtime.seconds = seconds
891
892 def cleanup(x):
893 runtime.seconds = runtime_original
894 base.seconds = base_original
895 return x
896 return maybeDeferred(self.testCallLaterOrder).addBoth(cleanup)
897
898 testCallLaterOrder2.todo = "See bug 1396"
899 testCallLaterOrder2.skip = "Trial bug, todo doesn't work! See bug 1397"
900
901 def testDelayedCallStringification(self):
902 # Mostly just make sure str() isn't going to raise anything for
903 # DelayedCalls within reason.
904 dc = reactor.callLater(0, lambda x, y: None, 'x', y=10)
905 str(dc)
906 dc.reset(5)
907 str(dc)
908 dc.cancel()
909 str(dc)
910
911 dc = reactor.callLater(0, lambda: None, x=[({'hello': u'world'}, 10j), r eactor], *range(10))
912 str(dc)
913 dc.cancel()
914 str(dc)
915
916 def calledBack(ignored):
917 str(dc)
918 d = Deferred().addCallback(calledBack)
919 dc = reactor.callLater(0, d.callback, None)
920 str(dc)
921 return d
922
923
924 def testDelayedCallSecondsOverride(self):
925 """
926 Test that the C{seconds} argument to DelayedCall gets used instead of
927 the default timing function, if it is not None.
928 """
929 def seconds():
930 return 10
931 dc = base.DelayedCall(5, lambda: None, (), {}, lambda dc: None,
932 lambda dc: None, seconds)
933 self.assertEquals(dc.getTime(), 5)
934 dc.reset(3)
935 self.assertEquals(dc.getTime(), 13)
936
937
938 class CallFromThreadTests(unittest.TestCase):
939 def testWakeUp(self):
940 # Make sure other threads can wake up the reactor
941 d = Deferred()
942 def wake():
943 time.sleep(0.1)
944 # callFromThread will call wakeUp for us
945 reactor.callFromThread(d.callback, None)
946 reactor.callInThread(wake)
947 return d
948
949 if interfaces.IReactorThreads(reactor, None) is None:
950 testWakeUp.skip = "Nothing to wake up for without thread support"
951
952 def _stopCallFromThreadCallback(self):
953 self.stopped = True
954
955 def _callFromThreadCallback(self, d):
956 reactor.callFromThread(self._callFromThreadCallback2, d)
957 reactor.callLater(0, self._stopCallFromThreadCallback)
958
959 def _callFromThreadCallback2(self, d):
960 try:
961 self.assert_(self.stopped)
962 except:
963 # Send the error to the deferred
964 d.errback()
965 else:
966 d.callback(None)
967
968 def testCallFromThreadStops(self):
969 """
970 Ensure that callFromThread from inside a callFromThread
971 callback doesn't sit in an infinite loop and lets other
972 things happen too.
973 """
974 self.stopped = False
975 d = defer.Deferred()
976 reactor.callFromThread(self._callFromThreadCallback, d)
977 return d
978
979
980
981 class DummyReactor(base.ReactorBase):
982 """
983 A reactor faking the methods needed to make it starts.
984 """
985
986 def __init__(self, clock):
987 """
988 @param clock: the clock used to fake time.
989 @type clock: C{task.Clock}.
990 """
991 base.ReactorBase.__init__(self)
992 self.clock = clock
993
994
995 def installWaker(self):
996 """
997 Called by C{self._initThreads}: no waker is needed for the tests.
998 """
999
1000
1001 def callLater(self, _seconds, _f, *args, **kw):
1002 """
1003 Override callLater using the internal clock.
1004 """
1005 return self.clock.callLater( _seconds, _f, *args, **kw)
1006
1007
1008 def removeAll(self):
1009 """
1010 Needed during stop.
1011 """
1012 return []
1013
1014
1015
1016 class ReactorBaseTestCase(unittest.TestCase):
1017 """
1018 Tests for L{base.ReactorBase} object.
1019 """
1020
1021 def setUp(self):
1022 """
1023 Create a clock and a L{DummyReactor}.
1024 """
1025 self.clock = task.Clock()
1026 self.reactor = DummyReactor(self.clock)
1027
1028
1029 def test_stopWhenNotStarted(self):
1030 """
1031 Test that the reactor stop raises an error when the reactor is not
1032 started.
1033 """
1034 self.assertRaises(RuntimeError, self.reactor.stop)
1035
1036
1037 def test_stopWhenAlreadyStopped(self):
1038 """
1039 Test that the reactor stop raises an error when the reactor is already
1040 stopped.
1041 """
1042 self.reactor.startRunning()
1043 self.reactor.stop()
1044 self.assertRaises(RuntimeError, self.reactor.stop)
1045
1046
1047 def test_stopShutDownEvents(self):
1048 """
1049 Verify that reactor.stop fires shutdown events.
1050 """
1051 events = []
1052 self.reactor.addSystemEventTrigger(
1053 "before", "shutdown",
1054 lambda: events.append(("before", "shutdown")))
1055 self.reactor.addSystemEventTrigger(
1056 "during", "shutdown",
1057 lambda: events.append(("during", "shutdown")))
1058 self.reactor.startRunning()
1059 self.reactor.stop()
1060
1061 # Simulate the mainloop spinning a little bit. Do this to allow
1062 # reactor.stop() to schedule the shutdown event to be fired as opposed
1063 # to assuming reactor.stop() will fire the shutdown event before
1064 # returning.
1065
1066 # Generally, randomly scheduling things to happen instead of doing them
1067 # synchronously is wrong. However, this is finicky functionality which
1068 # was always poorly specified and was implemented such that most times
1069 # the shutdown event was fired asynchronously. If you're implementing
1070 # a new API, don't look at this advance(0) and think it's great and
1071 # copy it.
1072
1073 # See #3168, #3146, and #3198.
1074 self.reactor.clock.advance(0)
1075
1076 self.assertEquals(events, [("before", "shutdown"),
1077 ("during", "shutdown")])
1078
1079
1080 def test_multipleRun(self):
1081 """
1082 Verify that the reactor.startRunning raises an error when called
1083 multiple times.
1084 """
1085 self.reactor.startRunning()
1086 self.assertWarns(DeprecationWarning,
1087 "Reactor already running! This behavior is deprecated since "
1088 "Twisted 8.0",
1089 __file__,
1090 self.reactor.startRunning)
1091
1092
1093 def test_crash(self):
1094 """
1095 reactor.crash should NOT fire shutdown triggers.
1096 """
1097 events = []
1098 self.reactor.addSystemEventTrigger(
1099 "before", "shutdown",
1100 lambda: events.append(("before", "shutdown")))
1101
1102 self.reactor.callWhenRunning(
1103 self.reactor.callLater, 0, self.reactor.crash)
1104 self.reactor.startRunning()
1105 self.clock.advance(0.1)
1106 self.failIf(events, "reactor.crash invoked shutdown triggers, but it "
1107 "isn't supposed to.")
1108
1109
1110
1111 class ReactorCoreTestCase(unittest.TestCase):
1112 """
1113 Test core functionalities of the reactor.
1114 """
1115
1116 def test_run(self):
1117 """
1118 Test that reactor.crash terminates reactor.run
1119 """
1120 for i in xrange(3):
1121 reactor.callLater(0.01, reactor.crash)
1122 reactor.run()
1123
1124
1125 def test_iterate(self):
1126 """
1127 Test that reactor.iterate(0) doesn't block
1128 """
1129 start = time.time()
1130 # twisted timers are distinct from the underlying event loop's
1131 # timers, so this fail-safe probably won't keep a failure from
1132 # hanging the test
1133 t = reactor.callLater(10, reactor.crash)
1134 reactor.iterate(0) # shouldn't block
1135 stop = time.time()
1136 elapsed = stop - start
1137 self.failUnless(elapsed < 8)
1138 t.cancel()
1139
1140
1141
1142 class ReactorFDTestCase(unittest.TestCase):
1143 """
1144 Tests for L{interfaces.IReactorFDSet}.
1145 """
1146
1147 def test_getReaders(self):
1148 """
1149 Check that L{interfaces.IReactorFDSet.getReaders} reflects the actions
1150 made with L{interfaces.IReactorFDSet.addReader} and
1151 L{interfaces.IReactorFDSet.removeReader}.
1152 """
1153 s = socket.socket()
1154 self.addCleanup(s.close)
1155
1156 c = Connection(s, protocol.Protocol())
1157 self.assertNotIn(c, reactor.getReaders())
1158
1159 reactor.addReader(c)
1160 self.assertIn(c, reactor.getReaders())
1161
1162 reactor.removeReader(c)
1163 self.assertNotIn(c, reactor.getReaders())
1164
1165
1166 def test_getWriters(self):
1167 """
1168 Check that L{interfaces.IReactorFDSet.getWriters} reflects the actions
1169 made with L{interfaces.IReactorFDSet.addWriter} and
1170 L{interfaces.IReactorFDSet.removeWriter}.
1171 """
1172 s = socket.socket()
1173 self.addCleanup(s.close)
1174
1175 c = Connection(s, protocol.Protocol())
1176 self.assertNotIn(c, reactor.getWriters())
1177
1178 reactor.addWriter(c)
1179 self.assertIn(c, reactor.getWriters())
1180
1181 reactor.removeWriter(c)
1182 self.assertNotIn(c, reactor.getWriters())
1183
1184 if not interfaces.IReactorFDSet.providedBy(reactor):
1185 ReactorFDTestCase.skip = "Reactor not providing IReactorFDSet"
1186
1187
1188
1189 class DelayedTestCase(unittest.TestCase):
1190 def setUp(self):
1191 self.finished = 0
1192 self.counter = 0
1193 self.timers = {}
1194 self.deferred = defer.Deferred()
1195 # ick. Sometimes there are magic timers already running:
1196 # popsicle.Freezer.tick . Kill off all such timers now so they won't
1197 # interfere with the test. Of course, this kind of requires that
1198 # getDelayedCalls already works, so certain failure modes won't be
1199 # noticed.
1200 if not hasattr(reactor, "getDelayedCalls"):
1201 return
1202 for t in reactor.getDelayedCalls():
1203 t.cancel()
1204 reactor.iterate() # flush timers
1205
1206 def tearDown(self):
1207 for t in self.timers.values():
1208 t.cancel()
1209
1210 def checkTimers(self):
1211 l1 = self.timers.values()
1212 l2 = list(reactor.getDelayedCalls())
1213
1214 # There should be at least the calls we put in. There may be other
1215 # calls that are none of our business and that we should ignore,
1216 # though.
1217
1218 missing = []
1219 for dc in l1:
1220 if dc not in l2:
1221 missing.append(dc)
1222 if missing:
1223 self.finished = 1
1224 self.failIf(missing, "Should have been missing no calls, instead was mis sing " + repr(missing))
1225
1226 def callback(self, tag):
1227 del self.timers[tag]
1228 self.checkTimers()
1229
1230 def addCallback(self, tag):
1231 self.callback(tag)
1232 self.addTimer(15, self.callback)
1233
1234 def done(self, tag):
1235 self.finished = 1
1236 self.callback(tag)
1237 self.deferred.callback(None)
1238
1239 def addTimer(self, when, callback):
1240 self.timers[self.counter] = reactor.callLater(when * 0.01, callback,
1241 self.counter)
1242 self.counter += 1
1243 self.checkTimers()
1244
1245 def testGetDelayedCalls(self):
1246 if not hasattr(reactor, "getDelayedCalls"):
1247 return
1248 # This is not a race because we don't do anything which might call
1249 # the reactor until we have all the timers set up. If we did, this
1250 # test might fail on slow systems.
1251 self.checkTimers()
1252 self.addTimer(35, self.done)
1253 self.addTimer(20, self.callback)
1254 self.addTimer(30, self.callback)
1255 which = self.counter
1256 self.addTimer(29, self.callback)
1257 self.addTimer(25, self.addCallback)
1258 self.addTimer(26, self.callback)
1259
1260 self.timers[which].cancel()
1261 del self.timers[which]
1262 self.checkTimers()
1263
1264 self.deferred.addCallback(lambda x : self.checkTimers())
1265 return self.deferred
1266
1267 def testActive(self):
1268 dcall = reactor.callLater(0, lambda: None)
1269 self.assertEquals(dcall.active(), 1)
1270 reactor.iterate()
1271 self.assertEquals(dcall.active(), 0)
1272
1273 resolve_helper = """
1274 import %(reactor)s
1275 %(reactor)s.install()
1276 from twisted.internet import reactor
1277
1278 class Foo:
1279 def __init__(self):
1280 reactor.callWhenRunning(self.start)
1281 self.timer = reactor.callLater(3, self.failed)
1282 def start(self):
1283 reactor.resolve('localhost').addBoth(self.done)
1284 def done(self, res):
1285 print 'done', res
1286 reactor.stop()
1287 def failed(self):
1288 print 'failed'
1289 self.timer = None
1290 reactor.stop()
1291 f = Foo()
1292 reactor.run()
1293 """
1294
1295 class ChildResolveProtocol(protocol.ProcessProtocol):
1296 def __init__(self, onCompletion):
1297 self.onCompletion = onCompletion
1298
1299 def connectionMade(self):
1300 self.output = []
1301 self.error = []
1302
1303 def outReceived(self, out):
1304 self.output.append(out)
1305
1306 def errReceived(self, err):
1307 self.error.append(err)
1308
1309 def processEnded(self, reason):
1310 self.onCompletion.callback((reason, self.output, self.error))
1311 self.onCompletion = None
1312
1313
1314 class Resolve(unittest.TestCase):
1315 def testChildResolve(self):
1316 # I've seen problems with reactor.run under gtk2reactor. Spawn a
1317 # child which just does reactor.resolve after the reactor has
1318 # started, fail if it does not complete in a timely fashion.
1319 helperPath = os.path.abspath(self.mktemp())
1320 helperFile = open(helperPath, 'w')
1321
1322 # Eeueuuggg
1323 reactorName = reactor.__module__
1324
1325 helperFile.write(resolve_helper % {'reactor': reactorName})
1326 helperFile.close()
1327
1328 env = os.environ.copy()
1329 env['PYTHONPATH'] = os.pathsep.join(sys.path)
1330
1331 helperDeferred = Deferred()
1332 helperProto = ChildResolveProtocol(helperDeferred)
1333
1334 reactor.spawnProcess(helperProto, sys.executable, ("python", "-u", helpe rPath), env)
1335
1336 def cbFinished((reason, output, error)):
1337 # If the output is "done 127.0.0.1\n" we don't really care what
1338 # else happened.
1339 output = ''.join(output)
1340 if output != 'done 127.0.0.1\n':
1341 self.fail((
1342 "The child process failed to produce the desired results:\n"
1343 " Reason for termination was: %r\n"
1344 " Output stream was: %r\n"
1345 " Error stream was: %r\n") % (reason.getErrorMessage(), ou tput, ''.join(error)))
1346
1347 helperDeferred.addCallback(cbFinished)
1348 return helperDeferred
1349
1350 if not interfaces.IReactorProcess(reactor, None):
1351 Resolve.skip = "cannot run test: reactor doesn't support IReactorProcess"
1352
1353 class Counter:
1354 index = 0
1355
1356 def add(self):
1357 self.index = self.index + 1
1358
1359
1360 class Order:
1361
1362 stage = 0
1363
1364 def a(self):
1365 if self.stage != 0: raise RuntimeError
1366 self.stage = 1
1367
1368 def b(self):
1369 if self.stage != 1: raise RuntimeError
1370 self.stage = 2
1371
1372 def c(self):
1373 if self.stage != 2: raise RuntimeError
1374 self.stage = 3
1375
1376
1377 class CallFromThreadTestCase(unittest.TestCase):
1378 """Task scheduling from threads tests."""
1379
1380 if interfaces.IReactorThreads(reactor, None) is None:
1381 skip = "Nothing to test without thread support"
1382
1383 def schedule(self, *args, **kwargs):
1384 """Override in subclasses."""
1385 reactor.callFromThread(*args, **kwargs)
1386
1387 def testScheduling(self):
1388 c = Counter()
1389 for i in range(100):
1390 self.schedule(c.add)
1391 for i in range(100):
1392 reactor.iterate()
1393 self.assertEquals(c.index, 100)
1394
1395 def testCorrectOrder(self):
1396 o = Order()
1397 self.schedule(o.a)
1398 self.schedule(o.b)
1399 self.schedule(o.c)
1400 reactor.iterate()
1401 reactor.iterate()
1402 reactor.iterate()
1403 self.assertEquals(o.stage, 3)
1404
1405 def testNotRunAtOnce(self):
1406 c = Counter()
1407 self.schedule(c.add)
1408 # scheduled tasks should not be run at once:
1409 self.assertEquals(c.index, 0)
1410 reactor.iterate()
1411 self.assertEquals(c.index, 1)
1412
1413
1414 class MyProtocol(protocol.Protocol):
1415 """Sample protocol."""
1416
1417 class MyFactory(protocol.Factory):
1418 """Sample factory."""
1419
1420 protocol = MyProtocol
1421
1422
1423 class ProtocolTestCase(unittest.TestCase):
1424
1425 def testFactory(self):
1426 factory = MyFactory()
1427 protocol = factory.buildProtocol(None)
1428 self.assertEquals(protocol.factory, factory)
1429 self.assert_( isinstance(protocol, factory.protocol) )
1430
1431
1432 class DummyProducer(object):
1433 """
1434 Very uninteresting producer implementation used by tests to ensure the
1435 right methods are called by the consumer with which it is registered.
1436
1437 @type events: C{list} of C{str}
1438 @ivar events: The producer/consumer related events which have happened to
1439 this producer. Strings in this list may be C{'resume'}, C{'stop'}, or
1440 C{'pause'}. Elements are added as they occur.
1441 """
1442
1443 def __init__(self):
1444 self.events = []
1445
1446
1447 def resumeProducing(self):
1448 self.events.append('resume')
1449
1450
1451 def stopProducing(self):
1452 self.events.append('stop')
1453
1454
1455 def pauseProducing(self):
1456 self.events.append('pause')
1457
1458
1459
1460 class SillyDescriptor(abstract.FileDescriptor):
1461 """
1462 A descriptor whose data buffer gets filled very fast.
1463
1464 Useful for testing FileDescriptor's IConsumer interface, since
1465 the data buffer fills as soon as at least four characters are
1466 written to it, and gets emptied in a single doWrite() cycle.
1467 """
1468 bufferSize = 3
1469 connected = True
1470
1471 def writeSomeData(self, data):
1472 """
1473 Always write all data.
1474 """
1475 return len(data)
1476
1477
1478 def startWriting(self):
1479 """
1480 Do nothing: bypass the reactor.
1481 """
1482 stopWriting = startWriting
1483
1484
1485
1486 class ReentrantProducer(DummyProducer):
1487 """
1488 Similar to L{DummyProducer}, but with a resumeProducing method which calls
1489 back into an L{IConsumer} method of the consumer against which it is
1490 registered.
1491
1492 @ivar consumer: The consumer with which this producer has been or will
1493 be registered.
1494
1495 @ivar methodName: The name of the method to call on the consumer inside
1496 C{resumeProducing}.
1497
1498 @ivar methodArgs: The arguments to pass to the consumer method invoked in
1499 C{resumeProducing}.
1500 """
1501 def __init__(self, consumer, methodName, *methodArgs):
1502 super(ReentrantProducer, self).__init__()
1503 self.consumer = consumer
1504 self.methodName = methodName
1505 self.methodArgs = methodArgs
1506
1507
1508 def resumeProducing(self):
1509 super(ReentrantProducer, self).resumeProducing()
1510 getattr(self.consumer, self.methodName)(*self.methodArgs)
1511
1512
1513
1514 class TestProducer(unittest.TestCase):
1515 """
1516 Test abstract.FileDescriptor's consumer interface.
1517 """
1518 def test_doubleProducer(self):
1519 """
1520 Verify that registering a non-streaming producer invokes its
1521 resumeProducing() method and that you can only register one producer
1522 at a time.
1523 """
1524 fd = abstract.FileDescriptor()
1525 fd.connected = 1
1526 dp = DummyProducer()
1527 fd.registerProducer(dp, 0)
1528 self.assertEquals(dp.events, ['resume'])
1529 self.assertRaises(RuntimeError, fd.registerProducer, DummyProducer(), 0)
1530
1531
1532 def test_unconnectedFileDescriptor(self):
1533 """
1534 Verify that registering a producer when the connection has already
1535 been closed invokes its stopProducing() method.
1536 """
1537 fd = abstract.FileDescriptor()
1538 fd.disconnected = 1
1539 dp = DummyProducer()
1540 fd.registerProducer(dp, 0)
1541 self.assertEquals(dp.events, ['stop'])
1542
1543
1544 def _dontPausePullConsumerTest(self, methodName):
1545 descriptor = SillyDescriptor()
1546 producer = DummyProducer()
1547 descriptor.registerProducer(producer, streaming=False)
1548 self.assertEqual(producer.events, ['resume'])
1549 del producer.events[:]
1550
1551 # Fill up the descriptor's write buffer so we can observe whether or
1552 # not it pauses its producer in that case.
1553 getattr(descriptor, methodName)('1234')
1554
1555 self.assertEqual(producer.events, [])
1556
1557
1558 def test_dontPausePullConsumerOnWrite(self):
1559 """
1560 Verify that FileDescriptor does not call producer.pauseProducing() on a
1561 non-streaming pull producer in response to a L{IConsumer.write} call
1562 which results in a full write buffer. Issue #2286.
1563 """
1564 return self._dontPausePullConsumerTest('write')
1565
1566
1567 def test_dontPausePullConsumerOnWriteSequence(self):
1568 """
1569 Like L{test_dontPausePullConsumerOnWrite}, but for a call to
1570 C{writeSequence} rather than L{IConsumer.write}.
1571
1572 C{writeSequence} is not part of L{IConsumer}, but
1573 L{abstract.FileDescriptor} has supported consumery behavior in response
1574 to calls to L{writeSequence} forever.
1575 """
1576 return self._dontPausePullConsumerTest('writeSequence')
1577
1578
1579 def _reentrantStreamingProducerTest(self, methodName):
1580 descriptor = SillyDescriptor()
1581 producer = ReentrantProducer(descriptor, methodName, 'spam')
1582 descriptor.registerProducer(producer, streaming=True)
1583
1584 # Start things off by filling up the descriptor's buffer so it will
1585 # pause its producer.
1586 getattr(descriptor, methodName)('spam')
1587
1588 # Sanity check - make sure that worked.
1589 self.assertEqual(producer.events, ['pause'])
1590 del producer.events[:]
1591
1592 # After one call to doWrite, the buffer has been emptied so the
1593 # FileDescriptor should resume its producer. That will result in an
1594 # immediate call to FileDescriptor.write which will again fill the
1595 # buffer and result in the producer being paused.
1596 descriptor.doWrite()
1597 self.assertEqual(producer.events, ['resume', 'pause'])
1598 del producer.events[:]
1599
1600 # After a second call to doWrite, the exact same thing should have
1601 # happened. Prior to the bugfix for which this test was written,
1602 # FileDescriptor would have incorrectly believed its producer was
1603 # already resumed (it was paused) and so not resume it again.
1604 descriptor.doWrite()
1605 self.assertEqual(producer.events, ['resume', 'pause'])
1606
1607
1608 def test_reentrantStreamingProducerUsingWrite(self):
1609 """
1610 Verify that FileDescriptor tracks producer's paused state correctly.
1611 Issue #811, fixed in revision r12857.
1612 """
1613 return self._reentrantStreamingProducerTest('write')
1614
1615
1616 def test_reentrantStreamingProducerUsingWriteSequence(self):
1617 """
1618 Like L{test_reentrantStreamingProducerUsingWrite}, but for calls to
1619 C{writeSequence}.
1620
1621 C{writeSequence} is B{not} part of L{IConsumer}, however
1622 C{abstract.FileDescriptor} has supported consumery behavior in response
1623 to calls to C{writeSequence} forever.
1624 """
1625 return self._reentrantStreamingProducerTest('writeSequence')
1626
1627
1628
1629 class PortStringification(unittest.TestCase):
1630 if interfaces.IReactorTCP(reactor, None) is not None:
1631 def testTCP(self):
1632 p = reactor.listenTCP(0, protocol.ServerFactory())
1633 portNo = p.getHost().port
1634 self.assertNotEqual(str(p).find(str(portNo)), -1,
1635 "%d not found in %s" % (portNo, p))
1636 return p.stopListening()
1637
1638 if interfaces.IReactorUDP(reactor, None) is not None:
1639 def testUDP(self):
1640 p = reactor.listenUDP(0, protocol.DatagramProtocol())
1641 portNo = p.getHost().port
1642 self.assertNotEqual(str(p).find(str(portNo)), -1,
1643 "%d not found in %s" % (portNo, p))
1644 return p.stopListening()
1645
1646 if interfaces.IReactorSSL(reactor, None) is not None and ssl:
1647 def testSSL(self, ssl=ssl):
1648 pem = util.sibpath(__file__, 'server.pem')
1649 p = reactor.listenSSL(0, protocol.ServerFactory(), ssl.DefaultOpenSS LContextFactory(pem, pem))
1650 portNo = p.getHost().port
1651 self.assertNotEqual(str(p).find(str(portNo)), -1,
1652 "%d not found in %s" % (portNo, p))
1653 return p.stopListening()
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/test/test_import.py ('k') | third_party/twisted_8_1/twisted/test/test_iutils.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698