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

Side by Side Diff: third_party/twisted_8_1/twisted/test/test_policies.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 Test code for policies.
6 """
7
8 from StringIO import StringIO
9
10 from twisted.trial import unittest
11 from twisted.test.proto_helpers import StringTransportWithDisconnection
12
13 from twisted.internet import protocol, reactor, address, defer, task
14 from twisted.protocols import policies
15
16
17
18 class StringIOWithoutClosing(StringIO):
19 def close(self): pass
20
21
22
23 class SimpleProtocol(protocol.Protocol):
24
25 connected = disconnected = 0
26 buffer = ""
27
28 def __init__(self):
29 self.dConnected = defer.Deferred()
30 self.dDisconnected = defer.Deferred()
31
32 def connectionMade(self):
33 self.connected = 1
34 self.dConnected.callback('')
35
36 def connectionLost(self, reason):
37 self.disconnected = 1
38 self.dDisconnected.callback('')
39
40 def dataReceived(self, data):
41 self.buffer += data
42
43
44
45 class SillyFactory(protocol.ClientFactory):
46
47 def __init__(self, p):
48 self.p = p
49
50 def buildProtocol(self, addr):
51 return self.p
52
53
54 class EchoProtocol(protocol.Protocol):
55 paused = False
56
57 def pauseProducing(self):
58 self.paused = True
59
60 def resumeProducing(self):
61 self.paused = False
62
63 def stopProducing(self):
64 pass
65
66 def dataReceived(self, data):
67 self.transport.write(data)
68
69
70
71 class Server(protocol.ServerFactory):
72 """
73 A simple server factory using L{EchoProtocol}.
74 """
75 protocol = EchoProtocol
76
77
78
79 class TestableThrottlingFactory(policies.ThrottlingFactory):
80 """
81 L{policies.ThrottlingFactory} using a L{task.Clock} for tests.
82 """
83
84 def __init__(self, clock, *args, **kwargs):
85 """
86 @param clock: object providing a callLater method that can be used
87 for tests.
88 @type clock: C{task.Clock} or alike.
89 """
90 policies.ThrottlingFactory.__init__(self, *args, **kwargs)
91 self.clock = clock
92
93
94 def callLater(self, period, func):
95 """
96 Forward to the testable clock.
97 """
98 return self.clock.callLater(period, func)
99
100
101
102 class TestableTimeoutFactory(policies.TimeoutFactory):
103 """
104 L{policies.TimeoutFactory} using a L{task.Clock} for tests.
105 """
106
107 def __init__(self, clock, *args, **kwargs):
108 """
109 @param clock: object providing a callLater method that can be used
110 for tests.
111 @type clock: C{task.Clock} or alike.
112 """
113 policies.TimeoutFactory.__init__(self, *args, **kwargs)
114 self.clock = clock
115
116
117 def callLater(self, period, func):
118 """
119 Forward to the testable clock.
120 """
121 return self.clock.callLater(period, func)
122
123
124
125 class PausableStringTransport(StringTransportWithDisconnection):
126 """
127 A string transport saving the current production state.
128
129 @ivar paused: whether the production is paused or not.
130 @type paused: C{bool}
131 """
132 paused = False
133
134 def pauseProducing(self):
135 """
136 Notification of production pause: set C{self.paused}.
137 """
138 self.paused = True
139
140
141 def resumeProducing(self):
142 """
143 Notification of production restart: unset C{self.paused}.
144 """
145 self.paused = False
146
147
148
149 class WrapperTestCase(unittest.TestCase):
150 def testProtocolFactoryAttribute(self):
151 """
152 Make sure protocol.factory is the wrapped factory, not the wrapping
153 factory.
154 """
155 f = Server()
156 wf = policies.WrappingFactory(f)
157 p = wf.buildProtocol(address.IPv4Address('TCP', '127.0.0.1', 35))
158 self.assertIdentical(p.wrappedProtocol.factory, f)
159
160
161
162 class WrappingFactory(policies.WrappingFactory):
163 protocol = lambda s, f, p: p
164
165 def startFactory(self):
166 policies.WrappingFactory.startFactory(self)
167 self.deferred.callback(None)
168
169
170
171 class ThrottlingTestCase(unittest.TestCase):
172 """
173 Tests for L{policies.ThrottlingFactory}.
174 """
175
176 def test_limit(self):
177 """
178 Full test using a custom server limiting number of connections.
179 """
180 server = Server()
181 c1, c2, c3, c4 = [SimpleProtocol() for i in range(4)]
182 tServer = policies.ThrottlingFactory(server, 2)
183 wrapTServer = WrappingFactory(tServer)
184 wrapTServer.deferred = defer.Deferred()
185
186 # Start listening
187 p = reactor.listenTCP(0, wrapTServer, interface="127.0.0.1")
188 n = p.getHost().port
189
190 def _connect123(results):
191 reactor.connectTCP("127.0.0.1", n, SillyFactory(c1))
192 c1.dConnected.addCallback(
193 lambda r: reactor.connectTCP("127.0.0.1", n, SillyFactory(c2)))
194 c2.dConnected.addCallback(
195 lambda r: reactor.connectTCP("127.0.0.1", n, SillyFactory(c3)))
196 return c3.dDisconnected
197
198 def _check123(results):
199 self.assertEquals([c.connected for c in c1, c2, c3], [1, 1, 1])
200 self.assertEquals([c.disconnected for c in c1, c2, c3], [0, 0, 1])
201 self.assertEquals(len(tServer.protocols.keys()), 2)
202 return results
203
204 def _lose1(results):
205 # disconnect one protocol and now another should be able to connect
206 c1.transport.loseConnection()
207 return c1.dDisconnected
208
209 def _connect4(results):
210 reactor.connectTCP("127.0.0.1", n, SillyFactory(c4))
211 return c4.dConnected
212
213 def _check4(results):
214 self.assertEquals(c4.connected, 1)
215 self.assertEquals(c4.disconnected, 0)
216 return results
217
218 def _cleanup(results):
219 for c in c2, c4:
220 c.transport.loseConnection()
221 return defer.DeferredList([
222 defer.maybeDeferred(p.stopListening),
223 c2.dDisconnected,
224 c4.dDisconnected])
225
226 wrapTServer.deferred.addCallback(_connect123)
227 wrapTServer.deferred.addCallback(_check123)
228 wrapTServer.deferred.addCallback(_lose1)
229 wrapTServer.deferred.addCallback(_connect4)
230 wrapTServer.deferred.addCallback(_check4)
231 wrapTServer.deferred.addCallback(_cleanup)
232 return wrapTServer.deferred
233
234
235 def test_writeLimit(self):
236 """
237 Check the writeLimit parameter: write data, and check for the pause
238 status.
239 """
240 server = Server()
241 tServer = TestableThrottlingFactory(task.Clock(), server, writeLimit=10)
242 port = tServer.buildProtocol(address.IPv4Address('TCP', '127.0.0.1', 0))
243 tr = PausableStringTransport()
244 tr.protocol = port
245 port.makeConnection(tr)
246 port.producer = port.wrappedProtocol
247
248 port.dataReceived("0123456789")
249 port.dataReceived("abcdefghij")
250 self.assertEquals(tr.value(), "0123456789abcdefghij")
251 self.assertEquals(tServer.writtenThisSecond, 20)
252 self.assertFalse(port.wrappedProtocol.paused)
253
254 # at this point server should've written 20 bytes, 10 bytes
255 # above the limit so writing should be paused around 1 second
256 # from 'now', and resumed a second after that
257 tServer.clock.advance(1.05)
258 self.assertEquals(tServer.writtenThisSecond, 0)
259 self.assertTrue(port.wrappedProtocol.paused)
260
261 tServer.clock.advance(1.05)
262 self.assertEquals(tServer.writtenThisSecond, 0)
263 self.assertFalse(port.wrappedProtocol.paused)
264
265
266 def test_readLimit(self):
267 """
268 Check the readLimit parameter: read data and check for the pause
269 status.
270 """
271 server = Server()
272 tServer = TestableThrottlingFactory(task.Clock(), server, readLimit=10)
273 port = tServer.buildProtocol(address.IPv4Address('TCP', '127.0.0.1', 0))
274 tr = PausableStringTransport()
275 tr.protocol = port
276 port.makeConnection(tr)
277
278 port.dataReceived("0123456789")
279 port.dataReceived("abcdefghij")
280 self.assertEquals(tr.value(), "0123456789abcdefghij")
281 self.assertEquals(tServer.readThisSecond, 20)
282
283 tServer.clock.advance(1.05)
284 self.assertEquals(tServer.readThisSecond, 0)
285 self.assertTrue(tr.paused)
286
287 tServer.clock.advance(1.05)
288 self.assertEquals(tServer.readThisSecond, 0)
289 self.assertFalse(tr.paused)
290
291 tr.clear()
292 port.dataReceived("0123456789")
293 port.dataReceived("abcdefghij")
294 self.assertEquals(tr.value(), "0123456789abcdefghij")
295 self.assertEquals(tServer.readThisSecond, 20)
296
297 tServer.clock.advance(1.05)
298 self.assertEquals(tServer.readThisSecond, 0)
299 self.assertTrue(tr.paused)
300
301 tServer.clock.advance(1.05)
302 self.assertEquals(tServer.readThisSecond, 0)
303 self.assertFalse(tr.paused)
304
305
306
307 class TimeoutTestCase(unittest.TestCase):
308 """
309 Tests for L{policies.TimeoutFactory}.
310 """
311
312 def setUp(self):
313 """
314 Create a testable, deterministic clock, and a set of
315 server factory/protocol/transport.
316 """
317 self.clock = task.Clock()
318 wrappedFactory = protocol.ServerFactory()
319 wrappedFactory.protocol = SimpleProtocol
320 self.factory = TestableTimeoutFactory(self.clock, wrappedFactory, 3)
321 self.proto = self.factory.buildProtocol(
322 address.IPv4Address('TCP', '127.0.0.1', 12345))
323 self.transport = StringTransportWithDisconnection()
324 self.transport.protocol = self.proto
325 self.proto.makeConnection(self.transport)
326
327
328 def test_timeout(self):
329 """
330 Make sure that when a TimeoutFactory accepts a connection, it will
331 time out that connection if no data is read or written within the
332 timeout period.
333 """
334 # Let almost 3 time units pass
335 self.clock.pump([0.0, 0.5, 1.0, 1.0, 0.4])
336 self.failIf(self.proto.wrappedProtocol.disconnected)
337
338 # Now let the timer elapse
339 self.clock.pump([0.0, 0.2])
340 self.failUnless(self.proto.wrappedProtocol.disconnected)
341
342
343 def test_sendAvoidsTimeout(self):
344 """
345 Make sure that writing data to a transport from a protocol
346 constructed by a TimeoutFactory resets the timeout countdown.
347 """
348 # Let half the countdown period elapse
349 self.clock.pump([0.0, 0.5, 1.0])
350 self.failIf(self.proto.wrappedProtocol.disconnected)
351
352 # Send some data (self.proto is the /real/ proto's transport, so this
353 # is the write that gets called)
354 self.proto.write('bytes bytes bytes')
355
356 # More time passes, putting us past the original timeout
357 self.clock.pump([0.0, 1.0, 1.0])
358 self.failIf(self.proto.wrappedProtocol.disconnected)
359
360 # Make sure writeSequence delays timeout as well
361 self.proto.writeSequence(['bytes'] * 3)
362
363 # Tick tock
364 self.clock.pump([0.0, 1.0, 1.0])
365 self.failIf(self.proto.wrappedProtocol.disconnected)
366
367 # Don't write anything more, just let the timeout expire
368 self.clock.pump([0.0, 2.0])
369 self.failUnless(self.proto.wrappedProtocol.disconnected)
370
371
372 def test_receiveAvoidsTimeout(self):
373 """
374 Make sure that receiving data also resets the timeout countdown.
375 """
376 # Let half the countdown period elapse
377 self.clock.pump([0.0, 1.0, 0.5])
378 self.failIf(self.proto.wrappedProtocol.disconnected)
379
380 # Some bytes arrive, they should reset the counter
381 self.proto.dataReceived('bytes bytes bytes')
382
383 # We pass the original timeout
384 self.clock.pump([0.0, 1.0, 1.0])
385 self.failIf(self.proto.wrappedProtocol.disconnected)
386
387 # Nothing more arrives though, the new timeout deadline is passed,
388 # the connection should be dropped.
389 self.clock.pump([0.0, 1.0, 1.0])
390 self.failUnless(self.proto.wrappedProtocol.disconnected)
391
392
393
394 class TimeoutTester(protocol.Protocol, policies.TimeoutMixin):
395 """
396 A testable protocol with timeout facility.
397
398 @ivar timedOut: set to C{True} if a timeout has been detected.
399 @type timedOut: C{bool}
400 """
401 timeOut = 3
402 timedOut = False
403
404 def __init__(self, clock):
405 """
406 Initialize the protocol with a C{task.Clock} object.
407 """
408 self.clock = clock
409
410
411 def connectionMade(self):
412 """
413 Upon connection, set the timeout.
414 """
415 self.setTimeout(self.timeOut)
416
417
418 def dataReceived(self, data):
419 """
420 Reset the timeout on data.
421 """
422 self.resetTimeout()
423 protocol.Protocol.dataReceived(self, data)
424
425
426 def connectionLost(self, reason=None):
427 """
428 On connection lost, cancel all timeout operations.
429 """
430 self.setTimeout(None)
431
432
433 def timeoutConnection(self):
434 """
435 Flags the timedOut variable to indicate the timeout of the connection.
436 """
437 self.timedOut = True
438
439
440 def callLater(self, timeout, func, *args, **kwargs):
441 """
442 Override callLater to use the deterministic clock.
443 """
444 return self.clock.callLater(timeout, func, *args, **kwargs)
445
446
447
448 class TestTimeout(unittest.TestCase):
449 """
450 Tests for L{policies.TimeoutMixin}.
451 """
452
453 def setUp(self):
454 """
455 Create a testable, deterministic clock and a C{TimeoutTester} instance.
456 """
457 self.clock = task.Clock()
458 self.proto = TimeoutTester(self.clock)
459
460
461 def test_overriddenCallLater(self):
462 """
463 Test that the callLater of the clock is used instead of
464 C{reactor.callLater}.
465 """
466 self.proto.setTimeout(10)
467 self.assertEquals(len(self.clock.calls), 1)
468
469
470 def test_timeout(self):
471 """
472 Check that the protocol does timeout at the time specified by its
473 C{timeOut} attribute.
474 """
475 s = StringIOWithoutClosing()
476 self.proto.makeConnection(protocol.FileWrapper(s))
477
478 # timeOut value is 3
479 self.clock.pump([0, 0.5, 1.0, 1.0])
480 self.failIf(self.proto.timedOut)
481 self.clock.pump([0, 1.0])
482 self.failUnless(self.proto.timedOut)
483
484
485 def test_noTimeout(self):
486 """
487 Check that receiving data is delaying the timeout of the connection.
488 """
489 s = StringIOWithoutClosing()
490 self.proto.makeConnection(protocol.FileWrapper(s))
491
492 self.clock.pump([0, 0.5, 1.0, 1.0])
493 self.failIf(self.proto.timedOut)
494 self.proto.dataReceived('hello there')
495 self.clock.pump([0, 1.0, 1.0, 0.5])
496 self.failIf(self.proto.timedOut)
497 self.clock.pump([0, 1.0])
498 self.failUnless(self.proto.timedOut)
499
500
501 def test_resetTimeout(self):
502 """
503 Check that setting a new value for timeout cancel the previous value
504 and install a new timeout.
505 """
506 self.proto.timeOut = None
507 s = StringIOWithoutClosing()
508 self.proto.makeConnection(protocol.FileWrapper(s))
509
510 self.proto.setTimeout(1)
511 self.assertEquals(self.proto.timeOut, 1)
512
513 self.clock.pump([0, 0.9])
514 self.failIf(self.proto.timedOut)
515 self.clock.pump([0, 0.2])
516 self.failUnless(self.proto.timedOut)
517
518
519 def test_cancelTimeout(self):
520 """
521 Setting the timeout to C{None} cancel any timeout operations.
522 """
523 self.proto.timeOut = 5
524 s = StringIOWithoutClosing()
525 self.proto.makeConnection(protocol.FileWrapper(s))
526
527 self.proto.setTimeout(None)
528 self.assertEquals(self.proto.timeOut, None)
529
530 self.clock.pump([0, 5, 5, 5])
531 self.failIf(self.proto.timedOut)
532
533
534 def test_return(self):
535 """
536 setTimeout should return the value of the previous timeout.
537 """
538 self.proto.timeOut = 5
539
540 self.assertEquals(self.proto.setTimeout(10), 5)
541 self.assertEquals(self.proto.setTimeout(None), 10)
542 self.assertEquals(self.proto.setTimeout(1), None)
543 self.assertEquals(self.proto.timeOut, 1)
544
545 # Clean up the DelayedCall
546 self.proto.setTimeout(None)
547
548
549
550 class LimitTotalConnectionsFactoryTestCase(unittest.TestCase):
551 """Tests for policies.LimitTotalConnectionsFactory"""
552 def testConnectionCounting(self):
553 # Make a basic factory
554 factory = policies.LimitTotalConnectionsFactory()
555 factory.protocol = protocol.Protocol
556
557 # connectionCount starts at zero
558 self.assertEqual(0, factory.connectionCount)
559
560 # connectionCount increments as connections are made
561 p1 = factory.buildProtocol(None)
562 self.assertEqual(1, factory.connectionCount)
563 p2 = factory.buildProtocol(None)
564 self.assertEqual(2, factory.connectionCount)
565
566 # and decrements as they are lost
567 p1.connectionLost(None)
568 self.assertEqual(1, factory.connectionCount)
569 p2.connectionLost(None)
570 self.assertEqual(0, factory.connectionCount)
571
572 def testConnectionLimiting(self):
573 # Make a basic factory with a connection limit of 1
574 factory = policies.LimitTotalConnectionsFactory()
575 factory.protocol = protocol.Protocol
576 factory.connectionLimit = 1
577
578 # Make a connection
579 p = factory.buildProtocol(None)
580 self.assertNotEqual(None, p)
581 self.assertEqual(1, factory.connectionCount)
582
583 # Try to make a second connection, which will exceed the connection
584 # limit. This should return None, because overflowProtocol is None.
585 self.assertEqual(None, factory.buildProtocol(None))
586 self.assertEqual(1, factory.connectionCount)
587
588 # Define an overflow protocol
589 class OverflowProtocol(protocol.Protocol):
590 def connectionMade(self):
591 factory.overflowed = True
592 factory.overflowProtocol = OverflowProtocol
593 factory.overflowed = False
594
595 # Try to make a second connection again, now that we have an overflow
596 # protocol. Note that overflow connections count towards the connection
597 # count.
598 op = factory.buildProtocol(None)
599 op.makeConnection(None) # to trigger connectionMade
600 self.assertEqual(True, factory.overflowed)
601 self.assertEqual(2, factory.connectionCount)
602
603 # Close the connections.
604 p.connectionLost(None)
605 self.assertEqual(1, factory.connectionCount)
606 op.connectionLost(None)
607 self.assertEqual(0, factory.connectionCount)
608
609
610 class WriteSequenceEchoProtocol(EchoProtocol):
611 def dataReceived(self, bytes):
612 if bytes.find('vector!') != -1:
613 self.transport.writeSequence([bytes])
614 else:
615 EchoProtocol.dataReceived(self, bytes)
616
617 class TestLoggingFactory(policies.TrafficLoggingFactory):
618 openFile = None
619 def open(self, name):
620 assert self.openFile is None, "open() called too many times"
621 self.openFile = StringIO()
622 return self.openFile
623
624
625
626 class LoggingFactoryTestCase(unittest.TestCase):
627 """
628 Tests for L{policies.TrafficLoggingFactory}.
629 """
630
631 def test_thingsGetLogged(self):
632 """
633 Check the output produced by L{policies.TrafficLoggingFactory}.
634 """
635 wrappedFactory = Server()
636 wrappedFactory.protocol = WriteSequenceEchoProtocol
637 t = StringTransportWithDisconnection()
638 f = TestLoggingFactory(wrappedFactory, 'test')
639 p = f.buildProtocol(('1.2.3.4', 5678))
640 t.protocol = p
641 p.makeConnection(t)
642
643 v = f.openFile.getvalue()
644 self.failUnless('*' in v, "* not found in %r" % (v,))
645 self.failIf(t.value())
646
647 p.dataReceived('here are some bytes')
648
649 v = f.openFile.getvalue()
650 self.assertIn("C 1: 'here are some bytes'", v)
651 self.assertIn("S 1: 'here are some bytes'", v)
652 self.assertEquals(t.value(), 'here are some bytes')
653
654 t.clear()
655 p.dataReceived('prepare for vector! to the extreme')
656 v = f.openFile.getvalue()
657 self.assertIn("SV 1: ['prepare for vector! to the extreme']", v)
658 self.assertEquals(t.value(), 'prepare for vector! to the extreme')
659
660 p.loseConnection()
661
662 v = f.openFile.getvalue()
663 self.assertIn('ConnectionDone', v)
664
665
666 def test_counter(self):
667 """
668 Test counter management with the resetCounter method.
669 """
670 wrappedFactory = Server()
671 f = TestLoggingFactory(wrappedFactory, 'test')
672 self.assertEqual(f._counter, 0)
673 f.buildProtocol(('1.2.3.4', 5678))
674 self.assertEqual(f._counter, 1)
675 # Reset log file
676 f.openFile = None
677 f.buildProtocol(('1.2.3.4', 5679))
678 self.assertEqual(f._counter, 2)
679
680 f.resetCounter()
681 self.assertEqual(f._counter, 0)
682
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/test/test_plugin.py ('k') | third_party/twisted_8_1/twisted/test/test_postfix.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698