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):
32 f = protocol.Factory(); f.protocol = Echo
33 return listenAirhookStream(port, f)
35 f = protocol.Factory(); f.protocol = Noisy
36 return listenAirhookStream(port, f)
37 def makeReceiver(port):
38 f = protocol.Factory(); f.protocol = Receiver
39 return listenAirhookStream(port, f)
40 def makeStreamReceiver(port):
41 f = protocol.Factory(); f.protocol = StreamReceiver
42 return listenAirhookStream(port, f)
47 def write(self, data, addr):
50 return self.s.seek(num)
54 def test_createStartPacket():
55 flags = 0 | FLAG_AIRHOOK | FLAG_SESSION
56 packet = chr(flags) + "\xff" + "\x00\x00" + pack("!L", long(rand(0, 2**32)))
59 def test_createReply(session, observed, obseq, seq):
60 flags = 0 | FLAG_AIRHOOK | FLAG_SESSION | FLAG_OBSERVED
61 packet = chr(flags) + pack("!H", seq)[1] + pack("!H", obseq + 1) + pack("!L", session) + pack("!L", observed)
64 def pscope(msg, noisy=0):
67 p = AirhookPacket(msg)
68 str += "oseq: %s seq: %s " % (p.oseq, p.seq)
70 str += "packet: %s \n" % (`p.datagram`)
73 if flags & FLAG_SESSION:
74 str += "FLAG_SESSION "
75 if flags & FLAG_OBSERVED:
76 str += "FLAG_OBSERVED "
77 if flags & FLAG_MISSED:
83 if p.observed != None:
84 str += "OBSERVED: %s\n" % p.observed
86 str += "SESSION: %s\n" % p.session
88 str += "NEXT: %s\n" % p.next
91 str += "MISSED: " + `p.missed`
93 str += "MISSED: " + `len(p.missed)`
97 str += "MSGS: " + `p.msgs` + "\n"
99 str += "MSGS: <%s> " % len(p.msgs)
104 def swap(a, dir="", noisy=0):
108 msg= a.transport.read()
109 a.transport = DummyTransport()
113 print 6*dir + " " + pscope(msg)
116 def runTillEmpty(a, b, prob=1.0, noisy=0):
119 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):
121 msga = swap(a, '>', noisy)
122 b.datagramReceived(msga)
124 msga = swap(a, '>', 0)
126 msgb = swap(b, '<', noisy)
127 a.datagramReceived(msgb)
129 msgb = swap(b, '<', 0)
131 class UstrTests(unittest.TestCase):
133 return ustr("%s%s" % (pack("!H", seq), 'foobar'))
136 self.failUnless(self.u(0) < self.u(1))
137 self.failUnless(self.u(1) < self.u(2))
138 self.failUnless(self.u(2**16 - 1) < self.u(0))
139 self.failUnless(self.u(2**16 - 1) < self.u(1))
141 self.failIf(self.u(1) < self.u(0))
142 self.failIf(self.u(2) < self.u(1))
143 self.failIf(self.u(0) < self.u(2**16 - 1))
144 self.failIf(self.u(1) < self.u(2**16 - 1))
147 self.failUnless(self.u(0) <= self.u(1))
148 self.failUnless(self.u(1) <= self.u(2))
149 self.failUnless(self.u(2) <= self.u(2))
150 self.failUnless(self.u(2**16 - 1) <= self.u(0))
151 self.failUnless(self.u(2**16 - 1) <= self.u(1))
152 self.failUnless(self.u(2**16 - 1) <= self.u(2**16))
154 self.failIf(self.u(1) <= self.u(0))
155 self.failIf(self.u(2) <= self.u(1))
156 self.failIf(self.u(0) <= self.u(2**16 - 1))
157 self.failIf(self.u(1) <= self.u(2**16 - 1))
160 self.failUnless(self.u(1) > self.u(0))
161 self.failUnless(self.u(2) > self.u(1))
162 self.failUnless(self.u(0) > self.u(2**16 - 1))
163 self.failUnless(self.u(1) > self.u(2**16 - 1))
165 self.failIf(self.u(0) > self.u(1))
166 self.failIf(self.u(1) > self.u(2))
167 self.failIf(self.u(2**16 - 1) > self.u(0))
168 self.failIf(self.u(2**16 - 1) > self.u(1))
171 self.failUnless(self.u(1) >= self.u(0))
172 self.failUnless(self.u(2) >= self.u(1))
173 self.failUnless(self.u(2) >= self.u(2))
174 self.failUnless(self.u(0) >= self.u(0))
175 self.failUnless(self.u(1) >= self.u(1))
176 self.failUnless(self.u(2**16 - 1) >= self.u(2**16 - 1))
178 self.failIf(self.u(0) >= self.u(1))
179 self.failIf(self.u(1) >= self.u(2))
180 self.failIf(self.u(2**16 - 1) >= self.u(0))
181 self.failIf(self.u(2**16 - 1) >= self.u(1))
184 self.failUnless(self.u(0) == self.u(0))
185 self.failUnless(self.u(1) == self.u(1))
186 self.failUnless(self.u(2**16 - 1) == self.u(2**16-1))
188 self.failIf(self.u(0) == self.u(1))
189 self.failIf(self.u(1) == self.u(0))
190 self.failIf(self.u(2**16 - 1) == self.u(0))
193 self.failUnless(self.u(1) != self.u(0))
194 self.failUnless(self.u(2) != self.u(1))
195 self.failIf(self.u(2) != self.u(2))
196 self.failIf(self.u(0) != self.u(0))
197 self.failIf(self.u(1) != self.u(1))
198 self.failIf(self.u(2**16 - 1) != self.u(2**16 - 1))
201 class SimpleTest(unittest.TestCase):
204 self.a = AirhookConnection()
205 self.a.makeConnection(DummyTransport())
206 self.a.addr = ('127.0.0.1', 4444)
207 self.b = AirhookConnection()
208 self.b.makeConnection(DummyTransport())
209 self.b.addr = ('127.0.0.1', 4444)
211 def testReallySimple(self):
212 # connect to eachother and send a few packets, observe sequence incrementing
215 self.assertEqual(a.state, pending)
216 self.assertEqual(b.state, pending)
217 self.assertEqual(a.outSeq, 0)
218 self.assertEqual(b.outSeq, 0)
219 self.assertEqual(a.obSeq, 0)
220 self.assertEqual(b.obSeq, 0)
222 msg = swap(a, '>', self.noisy)
223 self.assertEqual(a.state, sent)
224 self.assertEqual(a.outSeq, 1)
225 self.assertEqual(a.obSeq, 0)
227 b.datagramReceived(msg)
228 self.assertEqual(b.state, sent)
229 self.assertEqual(b.inSeq, 0)
230 self.assertEqual(b.obSeq, 0)
231 msg = swap(b, '<', self.noisy)
232 self.assertEqual(b.outSeq, 1)
234 a.datagramReceived(msg)
235 self.assertEqual(a.state, confirmed)
236 self.assertEqual(a.obSeq, 0)
237 self.assertEqual(a.inSeq, 0)
238 msg = swap(a, '>', self.noisy)
239 self.assertEqual(a.outSeq, 2)
241 b.datagramReceived(msg)
242 self.assertEqual(b.state, confirmed)
243 self.assertEqual(b.obSeq, 0)
244 self.assertEqual(b.inSeq, 1)
245 msg = swap(b, '<', self.noisy)
246 self.assertEqual(b.outSeq, 2)
248 a.datagramReceived(msg)
249 self.assertEqual(a.outSeq, 2)
250 self.assertEqual(a.inSeq, 1)
251 self.assertEqual(a.obSeq, 1)
253 class BasicTests(unittest.TestCase):
256 self.a = AirhookConnection()
257 self.a.makeConnection(DummyTransport())
258 self.a.addr = ('127.0.0.1', 4444)
259 self.b = AirhookConnection()
260 self.b.makeConnection(DummyTransport())
261 self.b.addr = ('127.0.0.1', 4444)
262 self.a.protocol = Receiver()
263 self.b.protocol = Receiver()
265 def testSimple(self):
269 TESTMSG = "Howdy, Y'All!"
270 a.omsgq.append(TESTMSG)
272 msg = swap(a, '>', self.noisy)
274 b.datagramReceived(msg)
275 msg = swap(b, '<', self.noisy)
276 a.datagramReceived(msg)
277 msg = swap(a, '>', self.noisy)
278 b.datagramReceived(msg)
280 self.assertEqual(b.inMsg, 1)
281 self.assertEqual(len(b.protocol.q), 1)
282 self.assertEqual(b.protocol.q[0], TESTMSG)
284 msg = swap(b, '<', self.noisy)
286 a.datagramReceived(msg)
287 msg = swap(a, '>', self.noisy)
288 b.datagramReceived(msg)
290 def testLostFirst(self):
294 TESTMSG = "Howdy, Y'All!"
297 a.omsgq.append(TESTMSG)
298 msg = swap(a, '>', self.noisy)
299 b.datagramReceived(msg)
300 msg = swap(b, '<', self.noisy)
301 self.assertEqual(b.state, sent)
302 a.datagramReceived(msg)
303 msg = swap(a, '>', self.noisy)
305 del(msg) # dropping first message
307 a.omsgq.append(TESTMSG2)
308 msg = swap(a, '>', self.noisy)
310 b.datagramReceived(msg)
311 self.assertEqual(b.state, confirmed)
312 self.assertEqual(len(b.protocol.q), 1)
313 self.assertEqual(b.protocol.q[0], TESTMSG2)
314 self.assertEqual(b.weMissed, [(1, 0)])
315 msg = swap(b, '<', self.noisy)
317 a.datagramReceived(msg)
319 msg = swap(a, '>', self.noisy)
321 b.datagramReceived(msg)
322 self.assertEqual(len(b.protocol.q), 2)
324 l = [TESTMSG2, TESTMSG]
326 self.assertEqual(b.protocol.q,l)
328 msg = swap(b, '<', self.noisy)
330 a.datagramReceived(msg)
331 msg = swap(a, '>', self.noisy)
332 b.datagramReceived(msg)
334 msg = swap(b, '<', self.noisy)
335 a.datagramReceived(msg)
336 msg = swap(a, '>', self.noisy)
337 b.datagramReceived(msg)
339 msg = swap(b, '<', self.noisy)
340 a.datagramReceived(msg)
341 msg = swap(a, '>', self.noisy)
343 self.assertEqual(len(b.protocol.q), 2)
345 l = [TESTMSG2, TESTMSG]
347 self.assertEqual(b.protocol.q,l)
349 def testLostSecond(self):
353 TESTMSG = "Howdy, Y'All!"
356 a.omsgq.append(TESTMSG)
357 msg = swap(a, '>', self.noisy)
358 b.datagramReceived(msg)
359 msg = swap(b, '<', self.noisy)
360 self.assertEqual(b.state, sent)
361 a.datagramReceived(msg)
362 msg = swap(a, '>', self.noisy)
364 a.omsgq.append(TESTMSG2)
365 msg2 = swap(a, '>', self.noisy)
366 del(msg2) # dropping second message
368 assert(a.outMsgs[1] != None)
370 b.datagramReceived(msg)
371 self.assertEqual(b.state, confirmed)
372 self.assertEqual(len(b.protocol.q), 1)
373 self.assertEqual(b.protocol.q[0], TESTMSG)
374 self.assertEqual(b.inMsg, 1)
375 self.assertEqual(b.weMissed, [])
376 msg = swap(b, '<', self.noisy)
378 a.datagramReceived(msg)
379 assert(a.outMsgs[1] != None)
380 msg = swap(a, '>', self.noisy)
382 b.datagramReceived(msg)
383 self.assertEqual(b.state, confirmed)
384 self.assertEqual(len(b.protocol.q), 1)
385 self.assertEqual(b.protocol.q[0], TESTMSG)
386 self.assertEqual(b.weMissed, [(2, 1)])
387 msg = swap(b, '<', self.noisy)
389 a.datagramReceived(msg)
390 msg = swap(a, '>', self.noisy)
392 b.datagramReceived(msg)
393 self.assertEqual(len(b.protocol.q), 2)
395 l = [TESTMSG2, TESTMSG]
397 self.assertEqual(b.protocol.q,l)
399 msg = swap(b, '<', self.noisy)
401 a.datagramReceived(msg)
402 msg = swap(a, '>', self.noisy)
404 b.datagramReceived(msg)
406 msg = swap(b, '<', self.noisy)
408 a.datagramReceived(msg)
409 msg = swap(a, '>', self.noisy)
411 b.datagramReceived(msg)
413 msg = swap(b, '<', self.noisy)
415 a.datagramReceived(msg)
418 msg = swap(a, '>', self.noisy)
420 self.assertEqual(len(b.protocol.q), 2)
422 l = [TESTMSG2, TESTMSG]
424 self.assertEqual(b.protocol.q,l)
426 def testDoubleDouble(self):
430 TESTMSGA = "Howdy, Y'All!"
433 TESTMSGD = "WING WANG"
435 a.omsgq.append(TESTMSGA)
436 a.omsgq.append(TESTMSGB)
438 b.omsgq.append(TESTMSGC)
439 b.omsgq.append(TESTMSGD)
442 msg = swap(a, '>', self.noisy)
445 b.datagramReceived(msg)
446 self.assertEqual(b.state, sent)
448 msg = swap(b, '<', self.noisy)
449 a.datagramReceived(msg)
451 msg = swap(a, '>', self.noisy)
453 b.datagramReceived(msg)
454 self.assertEqual(len(b.protocol.q), 2)
455 l = [TESTMSGA, TESTMSGB]
456 l.sort();b.protocol.q.sort()
457 self.assertEqual(b.protocol.q, l)
458 self.assertEqual(b.inMsg, 2)
460 msg = swap(b, '<', self.noisy)
461 a.datagramReceived(msg)
463 self.assertEqual(len(a.protocol.q), 2)
464 l = [TESTMSGC, TESTMSGD]
465 l.sort();a.protocol.q.sort()
466 self.assertEqual(a.protocol.q, l)
467 self.assertEqual(a.inMsg, 2)
469 def testDoubleDoubleProb(self, prob=0.25):
473 TESTMSGA = "Howdy, Y'All!"
476 TESTMSGD = "WING WANG"
478 a.omsgq.append(TESTMSGA)
479 a.omsgq.append(TESTMSGB)
481 b.omsgq.append(TESTMSGC)
482 b.omsgq.append(TESTMSGD)
484 runTillEmpty(a, b, prob, self.noisy)
486 self.assertEqual(a.state, confirmed)
487 self.assertEqual(b.state, confirmed)
488 self.assertEqual(len(b.protocol.q), 2)
489 l = [TESTMSGA, TESTMSGB]
490 l.sort();b.protocol.q.sort()
491 self.assertEqual(b.protocol.q, l)
493 self.assertEqual(len(a.protocol.q), 2)
494 l = [TESTMSGC, TESTMSGD]
495 l.sort();a.protocol.q.sort()
496 self.assertEqual(a.protocol.q, l)
498 def testOneWayBlast(self, num = 2**12):
505 for i in xrange(num):
506 a.omsgq.append(sha.sha(`i`).digest())
507 runTillEmpty(a, b, noisy=self.noisy)
509 self.assertEqual(len(b.protocol.q), num)
511 def testTwoWayBlast(self, num = 2**12, prob=0.5):
518 for i in xrange(num):
519 a.omsgq.append(sha.sha('a' + `i`).digest())
520 b.omsgq.append(sha.sha('b' + `i`).digest())
522 runTillEmpty(a, b, prob, self.noisy)
525 self.assertEqual(len(a.protocol.q), num)
526 self.assertEqual(len(b.protocol.q), num)
528 def testLimitMessageNumbers(self):
533 msg = swap(a, noisy=self.noisy)
534 b.datagramReceived(msg)
536 msg = swap(b, noisy=self.noisy)
537 a.datagramReceived(msg)
540 for i in range(5000):
541 a.omsgq.append(sha.sha('a' + 'i').digest())
543 for i in range(5000 / 255):
544 msg = swap(a, noisy=self.noisy)
545 self.assertEqual(a.obSeq, 0)
546 self.assertEqual(a.next, 255)
547 self.assertEqual(a.outMsgNums[(a.outSeq-1) % 256], 254)
549 class StreamTests(unittest.TestCase):
552 self.a = StreamConnection()
553 self.a.makeConnection(DummyTransport())
554 self.a.addr = ('127.0.0.1', 4444)
555 self.b = StreamConnection()
556 self.b.makeConnection(DummyTransport())
557 self.b.addr = ('127.0.0.1', 4444)
558 self.a.protocol = StreamReceiver()
559 self.b.protocol = StreamReceiver()
561 def testStreamSimple(self, num = 2**12, prob=1.0):
562 f = open('/dev/urandom', 'r')
571 runTillEmpty(a, b, prob, self.noisy)
573 self.assertEqual(len(a.protocol.buf), len(MSGB))
574 self.assertEqual(len(b.protocol.buf), len(MSGA))
575 self.assertEqual(a.protocol.buf, MSGB)
576 self.assertEqual(b.protocol.buf, MSGA)
578 def testStreamLossy(self, num = 2**12, prob=0.5):
579 self.testStreamSimple(num, prob)
581 class SimpleReactor(unittest.TestCase):
584 self.a = makeReceiver(2020)
585 self.b = makeReceiver(2021)
586 self.ac = self.a.connectionForAddr(('127.0.0.1', 2021))
587 self.bc = self.b.connectionForAddr(('127.0.0.1', 2020))
588 def testSimple(self):
589 msg = "Testing 1, 2, 3"
594 self.assertEqual(self.bc.protocol.q, [msg])
596 class SimpleReactorEcho(unittest.TestCase):
599 self.a = makeReceiver(2022)
600 self.b = makeEcho(2023)
601 self.ac = self.a.connectionForAddr(('127.0.0.1', 2023))
602 self.bc = self.b.connectionForAddr(('127.0.0.1', 2022))
603 def testSimple(self):
604 msg = "Testing 1, 2, 3"
610 self.assertEqual(self.ac.protocol.q, [msg])
614 self.assertEqual(self.ac.protocol.q, [msg])
617 class SimpleReactorStream(unittest.TestCase):
620 self.a = makeStreamReceiver(2024)
621 self.b = makeStreamReceiver(2025)
622 self.ac = self.a.connectionForAddr(('127.0.0.1', 2025))
623 self.bc = self.b.connectionForAddr(('127.0.0.1', 2024))
624 def testSimple(self):
625 msg = "Testing 1, 2, 3"
630 self.assertEqual(self.bc.protocol.buf, msg)
632 class SimpleReactorStreamBig(unittest.TestCase):
635 self.a = makeStreamReceiver(2026)
636 self.b = makeStreamReceiver(2027)
637 self.ac = self.a.connectionForAddr(('127.0.0.1', 2027))
638 self.bc = self.b.connectionForAddr(('127.0.0.1', 2026))
640 msg = open('/dev/urandom').read(4096)
649 self.assertEqual(self.bc.protocol.buf, msg)
651 class EchoReactorStreamBig(unittest.TestCase):
654 self.a = makeStreamReceiver(2028)
655 self.b = makeEcho(2029)
656 self.ac = self.a.connectionForAddr(('127.0.0.1', 2029))
658 msg = open('/dev/urandom').read(256)
665 self.assertEqual(self.ac.protocol.buf, msg)