3 from random import uniform as rand
4 from cStringIO import StringIO
7 if __name__ =="__main__":
8 tests = unittest.defaultTestLoader.loadTestsFromNames(['test_airhook'])
9 result = unittest.TextTestRunner().run(tests)
11 class Echo(protocol.Protocol):
12 def dataReceived(self, data):
13 self.transport.write(data)
15 class Noisy(protocol.Protocol):
16 def dataReceived(self, data):
19 class Receiver(protocol.Protocol):
22 def dataReceived(self, data):
25 class StreamReceiver(protocol.Protocol):
28 def dataReceived(self, data):
31 class EchoFactory(protocol.Factory):
32 def buildProtocol(self, addr):
34 class NoisyFactory(protocol.Factory):
35 def buildProtocol(self, addr):
37 class ReceiverFactory(protocol.Factory):
38 def buildProtocol(self, addr):
40 class StreamReceiverFactory(protocol.Factory):
41 def buildProtocol(self, addr):
42 return StreamReceiver()
45 return listenAirhookStream(port, EchoFactory())
47 return listenAirhookStream(port, NoisyFactory())
48 def makeReceiver(port):
49 return listenAirhookStream(port, ReceiverFactory())
50 def makeStreamReceiver(port):
51 return listenAirhookStream(port, StreamReceiverFactory())
56 def write(self, data, addr):
59 return self.s.seek(num)
63 def test_createStartPacket():
64 flags = 0 | FLAG_AIRHOOK | FLAG_SESSION
65 packet = chr(flags) + "\xff" + "\x00\x00" + pack("!L", long(rand(0, 2**32)))
68 def test_createReply(session, observed, obseq, seq):
69 flags = 0 | FLAG_AIRHOOK | FLAG_SESSION | FLAG_OBSERVED
70 packet = chr(flags) + pack("!H", seq)[1] + pack("!H", obseq + 1) + pack("!L", session) + pack("!L", observed)
73 def pscope(msg, noisy=0):
76 p = AirhookPacket(msg)
77 str += "oseq: %s seq: %s " % (p.oseq, p.seq)
79 str += "packet: %s \n" % (`p.datagram`)
82 if flags & FLAG_SESSION:
83 str += "FLAG_SESSION "
84 if flags & FLAG_OBSERVED:
85 str += "FLAG_OBSERVED "
86 if flags & FLAG_MISSED:
92 if p.observed != None:
93 str += "OBSERVED: %s\n" % p.observed
95 str += "SESSION: %s\n" % p.session
97 str += "NEXT: %s\n" % p.next
100 str += "MISSED: " + `p.missed`
102 str += "MISSED: " + `len(p.missed)`
106 str += "MSGS: " + `p.msgs` + "\n"
108 str += "MSGS: <%s> " % len(p.msgs)
113 def swap(a, dir="", noisy=0):
117 msg= a.transport.read()
118 a.transport = DummyTransport()
122 print 6*dir + " " + pscope(msg)
125 def runTillEmpty(a, b, prob=1.0, noisy=0):
128 while a.omsgq or b.omsgq or a.weMissed or b.weMissed or ord(msga[0]) & (FLAG_NEXT | FLAG_MISSED) or ord(msgb[0]) & (FLAG_NEXT | FLAG_MISSED):
130 msga = swap(a, '>', noisy)
131 b.datagramReceived(msga)
133 msga = swap(a, '>', 0)
135 msgb = swap(b, '<', noisy)
136 a.datagramReceived(msgb)
138 msgb = swap(b, '<', 0)
140 class UstrTests(unittest.TestCase):
142 return ustr("%s%s" % (pack("!H", seq), 'foobar'))
145 self.failUnless(self.u(0) < self.u(1))
146 self.failUnless(self.u(1) < self.u(2))
147 self.failUnless(self.u(2**16 - 1) < self.u(0))
148 self.failUnless(self.u(2**16 - 1) < self.u(1))
150 self.failIf(self.u(1) < self.u(0))
151 self.failIf(self.u(2) < self.u(1))
152 self.failIf(self.u(0) < self.u(2**16 - 1))
153 self.failIf(self.u(1) < self.u(2**16 - 1))
156 self.failUnless(self.u(0) <= self.u(1))
157 self.failUnless(self.u(1) <= self.u(2))
158 self.failUnless(self.u(2) <= self.u(2))
159 self.failUnless(self.u(2**16 - 1) <= self.u(0))
160 self.failUnless(self.u(2**16 - 1) <= self.u(1))
161 self.failUnless(self.u(2**16 - 1) <= self.u(2**16))
163 self.failIf(self.u(1) <= self.u(0))
164 self.failIf(self.u(2) <= self.u(1))
165 self.failIf(self.u(0) <= self.u(2**16 - 1))
166 self.failIf(self.u(1) <= self.u(2**16 - 1))
169 self.failUnless(self.u(1) > self.u(0))
170 self.failUnless(self.u(2) > self.u(1))
171 self.failUnless(self.u(0) > self.u(2**16 - 1))
172 self.failUnless(self.u(1) > self.u(2**16 - 1))
174 self.failIf(self.u(0) > self.u(1))
175 self.failIf(self.u(1) > self.u(2))
176 self.failIf(self.u(2**16 - 1) > self.u(0))
177 self.failIf(self.u(2**16 - 1) > self.u(1))
180 self.failUnless(self.u(1) >= self.u(0))
181 self.failUnless(self.u(2) >= self.u(1))
182 self.failUnless(self.u(2) >= self.u(2))
183 self.failUnless(self.u(0) >= self.u(0))
184 self.failUnless(self.u(1) >= self.u(1))
185 self.failUnless(self.u(2**16 - 1) >= self.u(2**16 - 1))
187 self.failIf(self.u(0) >= self.u(1))
188 self.failIf(self.u(1) >= self.u(2))
189 self.failIf(self.u(2**16 - 1) >= self.u(0))
190 self.failIf(self.u(2**16 - 1) >= self.u(1))
193 self.failUnless(self.u(0) == self.u(0))
194 self.failUnless(self.u(1) == self.u(1))
195 self.failUnless(self.u(2**16 - 1) == self.u(2**16-1))
197 self.failIf(self.u(0) == self.u(1))
198 self.failIf(self.u(1) == self.u(0))
199 self.failIf(self.u(2**16 - 1) == self.u(0))
202 self.failUnless(self.u(1) != self.u(0))
203 self.failUnless(self.u(2) != self.u(1))
204 self.failIf(self.u(2) != self.u(2))
205 self.failIf(self.u(0) != self.u(0))
206 self.failIf(self.u(1) != self.u(1))
207 self.failIf(self.u(2**16 - 1) != self.u(2**16 - 1))
210 class SimpleTest(unittest.TestCase):
213 self.a = AirhookConnection()
214 self.a.makeConnection(DummyTransport())
215 self.a.addr = ('127.0.0.1', 4444)
216 self.b = AirhookConnection()
217 self.b.makeConnection(DummyTransport())
218 self.b.addr = ('127.0.0.1', 4444)
220 def testReallySimple(self):
221 # connect to eachother and send a few packets, observe sequence incrementing
224 self.assertEqual(a.state, pending)
225 self.assertEqual(b.state, pending)
226 self.assertEqual(a.outSeq, 0)
227 self.assertEqual(b.outSeq, 0)
228 self.assertEqual(a.obSeq, 0)
229 self.assertEqual(b.obSeq, 0)
231 msg = swap(a, '>', self.noisy)
232 self.assertEqual(a.state, sent)
233 self.assertEqual(a.outSeq, 1)
234 self.assertEqual(a.obSeq, 0)
236 b.datagramReceived(msg)
237 self.assertEqual(b.state, sent)
238 self.assertEqual(b.inSeq, 0)
239 self.assertEqual(b.obSeq, 0)
240 msg = swap(b, '<', self.noisy)
241 self.assertEqual(b.outSeq, 1)
243 a.datagramReceived(msg)
244 self.assertEqual(a.state, confirmed)
245 self.assertEqual(a.obSeq, 0)
246 self.assertEqual(a.inSeq, 0)
247 msg = swap(a, '>', self.noisy)
248 self.assertEqual(a.outSeq, 2)
250 b.datagramReceived(msg)
251 self.assertEqual(b.state, confirmed)
252 self.assertEqual(b.obSeq, 0)
253 self.assertEqual(b.inSeq, 1)
254 msg = swap(b, '<', self.noisy)
255 self.assertEqual(b.outSeq, 2)
257 a.datagramReceived(msg)
258 self.assertEqual(a.outSeq, 2)
259 self.assertEqual(a.inSeq, 1)
260 self.assertEqual(a.obSeq, 1)
262 class BasicTests(unittest.TestCase):
265 self.a = AirhookConnection()
266 self.a.makeConnection(DummyTransport())
267 self.a.addr = ('127.0.0.1', 4444)
268 self.b = AirhookConnection()
269 self.b.makeConnection(DummyTransport())
270 self.b.addr = ('127.0.0.1', 4444)
271 self.a.protocol = Receiver()
272 self.b.protocol = Receiver()
274 def testSimple(self):
278 TESTMSG = "Howdy, Y'All!"
279 a.omsgq.append(TESTMSG)
281 msg = swap(a, '>', self.noisy)
283 b.datagramReceived(msg)
284 msg = swap(b, '<', self.noisy)
285 a.datagramReceived(msg)
286 msg = swap(a, '>', self.noisy)
287 b.datagramReceived(msg)
289 self.assertEqual(b.inMsg, 1)
290 self.assertEqual(len(b.protocol.q), 1)
291 self.assertEqual(b.protocol.q[0], TESTMSG)
293 msg = swap(b, '<', self.noisy)
295 a.datagramReceived(msg)
296 msg = swap(a, '>', self.noisy)
297 b.datagramReceived(msg)
299 def testLostFirst(self):
303 TESTMSG = "Howdy, Y'All!"
306 a.omsgq.append(TESTMSG)
307 msg = swap(a, '>', self.noisy)
308 b.datagramReceived(msg)
309 msg = swap(b, '<', self.noisy)
310 self.assertEqual(b.state, sent)
311 a.datagramReceived(msg)
312 msg = swap(a, '>', self.noisy)
314 del(msg) # dropping first message
316 a.omsgq.append(TESTMSG2)
317 msg = swap(a, '>', self.noisy)
319 b.datagramReceived(msg)
320 self.assertEqual(b.state, confirmed)
321 self.assertEqual(len(b.protocol.q), 1)
322 self.assertEqual(b.protocol.q[0], TESTMSG2)
323 self.assertEqual(b.weMissed, [(1, 0)])
324 msg = swap(b, '<', self.noisy)
326 a.datagramReceived(msg)
328 msg = swap(a, '>', self.noisy)
330 b.datagramReceived(msg)
331 self.assertEqual(len(b.protocol.q), 2)
333 l = [TESTMSG2, TESTMSG]
335 self.assertEqual(b.protocol.q,l)
337 msg = swap(b, '<', self.noisy)
339 a.datagramReceived(msg)
340 msg = swap(a, '>', self.noisy)
341 b.datagramReceived(msg)
343 msg = swap(b, '<', self.noisy)
344 a.datagramReceived(msg)
345 msg = swap(a, '>', self.noisy)
346 b.datagramReceived(msg)
348 msg = swap(b, '<', self.noisy)
349 a.datagramReceived(msg)
350 msg = swap(a, '>', self.noisy)
352 self.assertEqual(len(b.protocol.q), 2)
354 l = [TESTMSG2, TESTMSG]
356 self.assertEqual(b.protocol.q,l)
358 def testLostSecond(self):
362 TESTMSG = "Howdy, Y'All!"
365 a.omsgq.append(TESTMSG)
366 msg = swap(a, '>', self.noisy)
367 b.datagramReceived(msg)
368 msg = swap(b, '<', self.noisy)
369 self.assertEqual(b.state, sent)
370 a.datagramReceived(msg)
371 msg = swap(a, '>', self.noisy)
373 a.omsgq.append(TESTMSG2)
374 msg2 = swap(a, '>', self.noisy)
375 del(msg2) # dropping second message
377 assert(a.outMsgs[1] != None)
379 b.datagramReceived(msg)
380 self.assertEqual(b.state, confirmed)
381 self.assertEqual(len(b.protocol.q), 1)
382 self.assertEqual(b.protocol.q[0], TESTMSG)
383 self.assertEqual(b.inMsg, 1)
384 self.assertEqual(b.weMissed, [])
385 msg = swap(b, '<', self.noisy)
387 a.datagramReceived(msg)
388 assert(a.outMsgs[1] != None)
389 msg = swap(a, '>', self.noisy)
391 b.datagramReceived(msg)
392 self.assertEqual(b.state, confirmed)
393 self.assertEqual(len(b.protocol.q), 1)
394 self.assertEqual(b.protocol.q[0], TESTMSG)
395 self.assertEqual(b.weMissed, [(2, 1)])
396 msg = swap(b, '<', self.noisy)
398 a.datagramReceived(msg)
399 msg = swap(a, '>', self.noisy)
401 b.datagramReceived(msg)
402 self.assertEqual(len(b.protocol.q), 2)
404 l = [TESTMSG2, TESTMSG]
406 self.assertEqual(b.protocol.q,l)
408 msg = swap(b, '<', self.noisy)
410 a.datagramReceived(msg)
411 msg = swap(a, '>', self.noisy)
413 b.datagramReceived(msg)
415 msg = swap(b, '<', self.noisy)
417 a.datagramReceived(msg)
418 msg = swap(a, '>', self.noisy)
420 b.datagramReceived(msg)
422 msg = swap(b, '<', self.noisy)
424 a.datagramReceived(msg)
427 msg = swap(a, '>', self.noisy)
429 self.assertEqual(len(b.protocol.q), 2)
431 l = [TESTMSG2, TESTMSG]
433 self.assertEqual(b.protocol.q,l)
435 def testDoubleDouble(self):
439 TESTMSGA = "Howdy, Y'All!"
442 TESTMSGD = "WING WANG"
444 a.omsgq.append(TESTMSGA)
445 a.omsgq.append(TESTMSGB)
447 b.omsgq.append(TESTMSGC)
448 b.omsgq.append(TESTMSGD)
451 msg = swap(a, '>', self.noisy)
454 b.datagramReceived(msg)
455 self.assertEqual(b.state, sent)
457 msg = swap(b, '<', self.noisy)
458 a.datagramReceived(msg)
460 msg = swap(a, '>', self.noisy)
462 b.datagramReceived(msg)
463 self.assertEqual(len(b.protocol.q), 2)
464 l = [TESTMSGA, TESTMSGB]
465 l.sort();b.protocol.q.sort()
466 self.assertEqual(b.protocol.q, l)
467 self.assertEqual(b.inMsg, 2)
469 msg = swap(b, '<', self.noisy)
470 a.datagramReceived(msg)
472 self.assertEqual(len(a.protocol.q), 2)
473 l = [TESTMSGC, TESTMSGD]
474 l.sort();a.protocol.q.sort()
475 self.assertEqual(a.protocol.q, l)
476 self.assertEqual(a.inMsg, 2)
478 def testDoubleDoubleProb(self, prob=0.25):
482 TESTMSGA = "Howdy, Y'All!"
485 TESTMSGD = "WING WANG"
487 a.omsgq.append(TESTMSGA)
488 a.omsgq.append(TESTMSGB)
490 b.omsgq.append(TESTMSGC)
491 b.omsgq.append(TESTMSGD)
493 runTillEmpty(a, b, prob, self.noisy)
495 self.assertEqual(a.state, confirmed)
496 self.assertEqual(b.state, confirmed)
497 self.assertEqual(len(b.protocol.q), 2)
498 l = [TESTMSGA, TESTMSGB]
499 l.sort();b.protocol.q.sort()
500 self.assertEqual(b.protocol.q, l)
502 self.assertEqual(len(a.protocol.q), 2)
503 l = [TESTMSGC, TESTMSGD]
504 l.sort();a.protocol.q.sort()
505 self.assertEqual(a.protocol.q, l)
507 def testOneWayBlast(self, num = 2**12):
514 for i in xrange(num):
515 a.omsgq.append(sha.sha(`i`).digest())
516 runTillEmpty(a, b, noisy=self.noisy)
518 self.assertEqual(len(b.protocol.q), num)
520 def testTwoWayBlast(self, num = 2**12, prob=0.5):
527 for i in xrange(num):
528 a.omsgq.append(sha.sha('a' + `i`).digest())
529 b.omsgq.append(sha.sha('b' + `i`).digest())
531 runTillEmpty(a, b, prob, self.noisy)
534 self.assertEqual(len(a.protocol.q), num)
535 self.assertEqual(len(b.protocol.q), num)
537 def testLimitMessageNumbers(self):
542 msg = swap(a, noisy=self.noisy)
543 b.datagramReceived(msg)
545 msg = swap(b, noisy=self.noisy)
546 a.datagramReceived(msg)
549 for i in range(5000):
550 a.omsgq.append(sha.sha('a' + 'i').digest())
552 for i in range(5000 / 255):
553 msg = swap(a, noisy=self.noisy)
554 self.assertEqual(a.obSeq, 0)
555 self.assertEqual(a.next, 255)
556 self.assertEqual(a.outMsgNums[(a.outSeq-1) % 256], 254)
558 class StreamTests(unittest.TestCase):
561 self.a = StreamConnection()
562 self.a.makeConnection(DummyTransport())
563 self.a.addr = ('127.0.0.1', 4444)
564 self.b = StreamConnection()
565 self.b.makeConnection(DummyTransport())
566 self.b.addr = ('127.0.0.1', 4444)
567 self.a.protocol = StreamReceiver()
568 self.b.protocol = StreamReceiver()
570 def testStreamSimple(self, num = 2**12, prob=1.0):
571 f = open('/dev/urandom', 'r')
580 runTillEmpty(a, b, prob, self.noisy)
582 self.assertEqual(len(a.protocol.buf), len(MSGB))
583 self.assertEqual(len(b.protocol.buf), len(MSGA))
584 self.assertEqual(a.protocol.buf, MSGB)
585 self.assertEqual(b.protocol.buf, MSGA)
587 def testStreamLossy(self, num = 2**12, prob=0.5):
588 self.testStreamSimple(num, prob)
590 class SimpleReactor(unittest.TestCase):
593 self.a = makeReceiver(2020)
594 self.b = makeReceiver(2021)
595 self.ac = self.a.connectionForAddr(('127.0.0.1', 2021))
596 self.bc = self.b.connectionForAddr(('127.0.0.1', 2020))
597 def testSimple(self):
598 msg = "Testing 1, 2, 3"
603 self.assertEqual(self.bc.protocol.q, [msg])
605 class SimpleReactorEcho(unittest.TestCase):
608 self.a = makeReceiver(2022)
609 self.b = makeEcho(2023)
610 self.ac = self.a.connectionForAddr(('127.0.0.1', 2023))
611 self.bc = self.b.connectionForAddr(('127.0.0.1', 2022))
612 def testSimple(self):
613 msg = "Testing 1, 2, 3"
619 self.assertEqual(self.ac.protocol.q, [msg])
623 self.assertEqual(self.ac.protocol.q, [msg])
626 class SimpleReactorStream(unittest.TestCase):
629 self.a = makeStreamReceiver(2024)
630 self.b = makeStreamReceiver(2025)
631 self.ac = self.a.connectionForAddr(('127.0.0.1', 2025))
632 self.bc = self.b.connectionForAddr(('127.0.0.1', 2024))
633 def testSimple(self):
634 msg = "Testing 1, 2, 3"
639 self.assertEqual(self.bc.protocol.buf, msg)
641 class SimpleReactorStreamBig(unittest.TestCase):
644 self.a = makeStreamReceiver(2026)
645 self.b = makeStreamReceiver(2027)
646 self.ac = self.a.connectionForAddr(('127.0.0.1', 2027))
647 self.bc = self.b.connectionForAddr(('127.0.0.1', 2026))
649 msg = open('/dev/urandom').read(4096)
658 self.assertEqual(self.bc.protocol.buf, msg)
660 class EchoReactorStreamBig(unittest.TestCase):
663 self.a = makeStreamReceiver(2028)
664 self.b = makeEcho(2029)
665 self.ac = self.a.connectionForAddr(('127.0.0.1', 2028))
666 self.bc = self.b.connectionForAddr(('127.0.0.1', 2029))
668 msg = open('/dev/urandom').read(4096)
677 self.assertEqual(self.ac.protocol.buf, msg)