3 from random import uniform as rand
5 if __name__ =="__main__":
6 tests = unittest.defaultTestLoader.loadTestsFromNames(['test_airhook'])
7 result = unittest.TextTestRunner().run(tests)
11 def test_createStartPacket():
12 flags = 0 | FLAG_AIRHOOK | FLAG_SESSION
13 packet = chr(flags) + "\xff" + "\x00\x00" + pack("!L", long(rand(0, 2**32)))
16 def test_createReply(session, observed, obseq, seq):
17 flags = 0 | FLAG_AIRHOOK | FLAG_SESSION | FLAG_OBSERVED
18 packet = chr(flags) + pack("!H", seq)[1] + pack("!H", obseq + 1) + pack("!L", session) + pack("!L", observed)
22 def pscope(msg, noisy=0):
25 p = AirhookPacket(msg)
26 str += "oseq: %s seq: %s " % (p.oseq, p.seq)
28 str += "packet: %s \n" % (`p.datagram`)
31 if flags & FLAG_SESSION:
32 str += "FLAG_SESSION "
33 if flags & FLAG_OBSERVED:
34 str += "FLAG_OBSERVED "
35 if flags & FLAG_MISSED:
41 if p.observed != None:
42 str += "OBSERVED: %s\n" % p.observed
44 str += "SESSION: %s\n" % p.session
46 str += "NEXT: %s\n" % p.next
49 str += "MISSED: " + `p.missed`
51 str += "MISSED: " + `len(p.missed)`
55 str += "MSGS: " + `p.msgs` + "\n"
57 str += "MSGS: <%s> " % len(p.msgs)
62 def swap(a, dir="", noisy=0):
66 msg= a.transport.read()
67 a.transport = StringIO()
71 print 6*dir + " " + pscope(msg)
75 class UstrTests(unittest.TestCase):
77 return ustr("%s%s" % (pack("!H", seq), 'foobar'))
80 self.failUnless(self.u(0) < self.u(1))
81 self.failUnless(self.u(1) < self.u(2))
82 self.failUnless(self.u(2**16 - 1) < self.u(0))
83 self.failUnless(self.u(2**16 - 1) < self.u(1))
85 self.failIf(self.u(1) < self.u(0))
86 self.failIf(self.u(2) < self.u(1))
87 self.failIf(self.u(0) < self.u(2**16 - 1))
88 self.failIf(self.u(1) < self.u(2**16 - 1))
91 self.failUnless(self.u(0) <= self.u(1))
92 self.failUnless(self.u(1) <= self.u(2))
93 self.failUnless(self.u(2) <= self.u(2))
94 self.failUnless(self.u(2**16 - 1) <= self.u(0))
95 self.failUnless(self.u(2**16 - 1) <= self.u(1))
96 self.failUnless(self.u(2**16 - 1) <= self.u(2**16))
98 self.failIf(self.u(1) <= self.u(0))
99 self.failIf(self.u(2) <= self.u(1))
100 self.failIf(self.u(0) <= self.u(2**16 - 1))
101 self.failIf(self.u(1) <= self.u(2**16 - 1))
104 self.failUnless(self.u(1) > self.u(0))
105 self.failUnless(self.u(2) > self.u(1))
106 self.failUnless(self.u(0) > self.u(2**16 - 1))
107 self.failUnless(self.u(1) > self.u(2**16 - 1))
109 self.failIf(self.u(0) > self.u(1))
110 self.failIf(self.u(1) > self.u(2))
111 self.failIf(self.u(2**16 - 1) > self.u(0))
112 self.failIf(self.u(2**16 - 1) > self.u(1))
115 self.failUnless(self.u(1) >= self.u(0))
116 self.failUnless(self.u(2) >= self.u(1))
117 self.failUnless(self.u(2) >= self.u(2))
118 self.failUnless(self.u(0) >= self.u(0))
119 self.failUnless(self.u(1) >= self.u(1))
120 self.failUnless(self.u(2**16 - 1) >= self.u(2**16 - 1))
122 self.failIf(self.u(0) >= self.u(1))
123 self.failIf(self.u(1) >= self.u(2))
124 self.failIf(self.u(2**16 - 1) >= self.u(0))
125 self.failIf(self.u(2**16 - 1) >= self.u(1))
128 self.failUnless(self.u(0) == self.u(0))
129 self.failUnless(self.u(1) == self.u(1))
130 self.failUnless(self.u(2**16 - 1) == self.u(2**16-1))
132 self.failIf(self.u(0) == self.u(1))
133 self.failIf(self.u(1) == self.u(0))
134 self.failIf(self.u(2**16 - 1) == self.u(0))
137 self.failUnless(self.u(1) != self.u(0))
138 self.failUnless(self.u(2) != self.u(1))
139 self.failIf(self.u(2) != self.u(2))
140 self.failIf(self.u(0) != self.u(0))
141 self.failIf(self.u(1) != self.u(1))
142 self.failIf(self.u(2**16 - 1) != self.u(2**16 - 1))
145 class SimpleTest(unittest.TestCase):
148 self.a = AirhookConnection(StringIO(), (None, 'localhost', 4040), None)
149 self.b = AirhookConnection(StringIO(), (None, 'localhost', 4040), None)
150 def testReallySimple(self):
151 # connect to eachother and send a few packets, observe sequence incrementing
154 self.assertEqual(a.state, pending)
155 self.assertEqual(b.state, pending)
156 self.assertEqual(a.outSeq, 0)
157 self.assertEqual(b.outSeq, 0)
158 self.assertEqual(a.obSeq, 0)
159 self.assertEqual(b.obSeq, 0)
161 msg = swap(a, '>', self.noisy)
162 self.assertEqual(a.state, sent)
163 self.assertEqual(a.outSeq, 1)
164 self.assertEqual(a.obSeq, 0)
166 b.datagramReceived(msg)
167 self.assertEqual(b.state, sent)
168 self.assertEqual(b.inSeq, 0)
169 self.assertEqual(b.obSeq, 0)
170 msg = swap(b, '<', self.noisy)
171 self.assertEqual(b.outSeq, 1)
173 a.datagramReceived(msg)
174 self.assertEqual(a.state, confirmed)
175 self.assertEqual(a.obSeq, 0)
176 self.assertEqual(a.inSeq, 0)
177 msg = swap(a, '>', self.noisy)
178 self.assertEqual(a.outSeq, 2)
180 b.datagramReceived(msg)
181 self.assertEqual(b.state, confirmed)
182 self.assertEqual(b.obSeq, 0)
183 self.assertEqual(b.inSeq, 1)
184 msg = swap(b, '<', self.noisy)
185 self.assertEqual(b.outSeq, 2)
187 a.datagramReceived(msg)
188 self.assertEqual(a.outSeq, 2)
189 self.assertEqual(a.inSeq, 1)
190 self.assertEqual(a.obSeq, 1)
192 class BasicTests(unittest.TestCase):
195 self.a = AirhookConnection(StringIO(), (None, 'localhost', 4040), None)
196 self.b = AirhookConnection(StringIO(), (None, 'localhost', 4040), None)
197 def testSimple(self):
201 TESTMSG = "Howdy, Y'All!"
202 a.omsgq.append(TESTMSG)
204 msg = swap(a, '>', self.noisy)
206 b.datagramReceived(msg)
207 msg = swap(b, '<', self.noisy)
208 a.datagramReceived(msg)
209 msg = swap(a, '>', self.noisy)
210 b.datagramReceived(msg)
212 self.assertEqual(b.inMsg, 1)
213 self.assertEqual(len(b.imsgq), 1)
214 self.assertEqual(b.imsgq[0], TESTMSG)
216 msg = swap(b, '<', self.noisy)
218 a.datagramReceived(msg)
219 msg = swap(a, '>', self.noisy)
220 b.datagramReceived(msg)
222 def testLostFirst(self):
226 TESTMSG = "Howdy, Y'All!"
229 a.omsgq.append(TESTMSG)
230 msg = swap(a, '>', self.noisy)
231 b.datagramReceived(msg)
232 msg = swap(b, '<', self.noisy)
233 self.assertEqual(b.state, sent)
234 a.datagramReceived(msg)
235 msg = swap(a, '>', self.noisy)
237 del(msg) # dropping first message
239 a.omsgq.append(TESTMSG2)
240 msg = swap(a, '>', self.noisy)
242 b.datagramReceived(msg)
243 self.assertEqual(b.state, confirmed)
244 self.assertEqual(len(b.imsgq), 1)
245 self.assertEqual(b.imsgq[0], TESTMSG2)
246 self.assertEqual(b.weMissed, [(1, 0)])
247 msg = swap(b, '<', self.noisy)
249 a.datagramReceived(msg)
251 msg = swap(a, '>', self.noisy)
253 b.datagramReceived(msg)
254 self.assertEqual(len(b.imsgq), 2)
256 l = [TESTMSG2, TESTMSG]
258 self.assertEqual(b.imsgq,l)
260 msg = swap(b, '<', self.noisy)
262 a.datagramReceived(msg)
263 msg = swap(a, '>', self.noisy)
264 b.datagramReceived(msg)
266 msg = swap(b, '<', self.noisy)
267 a.datagramReceived(msg)
268 msg = swap(a, '>', self.noisy)
269 b.datagramReceived(msg)
271 msg = swap(b, '<', self.noisy)
272 a.datagramReceived(msg)
273 msg = swap(a, '>', self.noisy)
275 self.assertEqual(len(b.imsgq), 2)
277 l = [TESTMSG2, TESTMSG]
279 self.assertEqual(b.imsgq,l)
281 def testLostSecond(self):
285 TESTMSG = "Howdy, Y'All!"
288 a.omsgq.append(TESTMSG)
289 msg = swap(a, '>', self.noisy)
290 b.datagramReceived(msg)
291 msg = swap(b, '<', self.noisy)
292 self.assertEqual(b.state, sent)
293 a.datagramReceived(msg)
294 msg = swap(a, '>', self.noisy)
296 a.omsgq.append(TESTMSG2)
297 msg2 = swap(a, '>', self.noisy)
298 del(msg2) # dropping second message
300 assert(a.outMsgs[1] != None)
302 b.datagramReceived(msg)
303 self.assertEqual(b.state, confirmed)
304 self.assertEqual(len(b.imsgq), 1)
305 self.assertEqual(b.imsgq[0], TESTMSG)
306 self.assertEqual(b.inMsg, 1)
307 self.assertEqual(b.weMissed, [])
308 msg = swap(b, '<', self.noisy)
310 a.datagramReceived(msg)
311 assert(a.outMsgs[1] != None)
312 msg = swap(a, '>', self.noisy)
314 b.datagramReceived(msg)
315 self.assertEqual(b.state, confirmed)
316 self.assertEqual(len(b.imsgq), 1)
317 self.assertEqual(b.imsgq[0], TESTMSG)
318 self.assertEqual(b.weMissed, [(2, 1)])
319 msg = swap(b, '<', self.noisy)
321 a.datagramReceived(msg)
322 msg = swap(a, '>', self.noisy)
324 b.datagramReceived(msg)
325 self.assertEqual(len(b.imsgq), 2)
327 l = [TESTMSG2, TESTMSG]
329 self.assertEqual(b.imsgq,l)
331 msg = swap(b, '<', self.noisy)
333 a.datagramReceived(msg)
334 msg = swap(a, '>', self.noisy)
336 b.datagramReceived(msg)
338 msg = swap(b, '<', self.noisy)
340 a.datagramReceived(msg)
341 msg = swap(a, '>', self.noisy)
343 b.datagramReceived(msg)
345 msg = swap(b, '<', self.noisy)
347 a.datagramReceived(msg)
350 msg = swap(a, '>', self.noisy)
352 self.assertEqual(len(b.imsgq), 2)
354 l = [TESTMSG2, TESTMSG]
356 self.assertEqual(b.imsgq,l)
358 def testDoubleDouble(self):
362 TESTMSGA = "Howdy, Y'All!"
365 TESTMSGD = "WING WANG"
367 a.omsgq.append(TESTMSGA)
368 a.omsgq.append(TESTMSGB)
370 b.omsgq.append(TESTMSGC)
371 b.omsgq.append(TESTMSGD)
374 msg = swap(a, '>', self.noisy)
377 b.datagramReceived(msg)
378 self.assertEqual(b.state, sent)
380 msg = swap(b, '<', self.noisy)
381 a.datagramReceived(msg)
383 msg = swap(a, '>', self.noisy)
385 b.datagramReceived(msg)
386 self.assertEqual(len(b.imsgq), 2)
387 l = [TESTMSGA, TESTMSGB]
388 l.sort();b.imsgq.sort()
389 self.assertEqual(b.imsgq, l)
390 self.assertEqual(b.inMsg, 2)
392 msg = swap(b, '<', self.noisy)
393 a.datagramReceived(msg)
395 self.assertEqual(len(a.imsgq), 2)
396 l = [TESTMSGC, TESTMSGD]
397 l.sort();a.imsgq.sort()
398 self.assertEqual(a.imsgq, l)
399 self.assertEqual(a.inMsg, 2)
401 def testDoubleDoubleProb(self, prob=0.25):
404 TESTMSGA = "Howdy, Y'All!"
407 TESTMSGD = "WING WANG"
409 a.omsgq.append(TESTMSGA)
410 a.omsgq.append(TESTMSGB)
412 b.omsgq.append(TESTMSGC)
413 b.omsgq.append(TESTMSGD)
415 while a.state != confirmed or b.state != confirmed or ord(msga[0]) & FLAG_NEXT or ord(msgb[0]) & FLAG_NEXT :
416 msga = swap(a, '>', self.noisy)
419 b.datagramReceived(msga)
421 msgb = swap(b, '<', self.noisy)
424 a.datagramReceived(msgb)
426 self.assertEqual(a.state, confirmed)
427 self.assertEqual(b.state, confirmed)
428 self.assertEqual(len(b.imsgq), 2)
429 l = [TESTMSGA, TESTMSGB]
430 l.sort();b.imsgq.sort()
431 self.assertEqual(b.imsgq, l)
433 self.assertEqual(len(a.imsgq), 2)
434 l = [TESTMSGC, TESTMSGD]
435 l.sort();a.imsgq.sort()
436 self.assertEqual(a.imsgq, l)
438 def testOneWayBlast(self, num = 2**12):
444 for i in xrange(num):
445 a.omsgq.append(sha.sha(`i`).digest())
446 msga = swap(a, '>', self.noisy)
447 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):
448 b.datagramReceived(msga)
449 msgb = swap(b, '<', self.noisy)
451 a.datagramReceived(msgb)
452 msga = swap(a, '>', self.noisy)
454 self.assertEqual(len(b.imsgq), num)
456 def testTwoWayBlast(self, num = 2**12, prob=0.5):
462 for i in xrange(num):
463 a.omsgq.append(sha.sha('a' + `i`).digest())
464 b.omsgq.append(sha.sha('b' + `i`).digest())
466 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):
468 msga = swap(a, '>', self.noisy)
469 b.datagramReceived(msga)
471 msga = swap(a, '>', 0)
473 msgb = swap(b, '<', self.noisy)
474 a.datagramReceived(msgb)
476 msgb = swap(b, '<', 0)
480 self.assertEqual(len(a.imsgq), num)
481 self.assertEqual(len(b.imsgq), num)
483 def testLimitMessageNumbers(self):
488 msg = swap(a, noisy=self.noisy)
489 b.datagramReceived(msg)
491 msg = swap(b, noisy=self.noisy)
492 a.datagramReceived(msg)
495 for i in range(5000):
496 a.omsgq.append(sha.sha('a' + 'i').digest())
498 for i in range(5000 / 255):
499 msg = swap(a, noisy=self.noisy)
500 self.assertEqual(a.obSeq, 0)
501 self.assertEqual(a.next, 255)
502 self.assertEqual(a.outMsgNums[(a.outSeq-1) % 256], 254)
504 class OrderedTests(unittest.TestCase):
510 def dataCameIn(self, host, port, data):
514 self.a = OrderedConnection(StringIO(), (None, 'localhost', 4040), self.A)
515 self.b = OrderedConnection(StringIO(), (None, 'localhost', 4040), self.B)
517 def testOrderedSimple(self, num = 2**18, prob=1.0):
518 f = open('/dev/urandom', 'r')
526 self.a.sendSomeData(MSGA)
527 self.b.sendSomeData(MSGB)
529 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):
531 msga = swap(a, '>', self.noisy)
532 b.datagramReceived(msga)
534 msga = swap(a, '>', 0)
536 msgb = swap(b, '<', self.noisy)
537 a.datagramReceived(msgb)
539 msgb = swap(b, '<', 0)
540 self.assertEqual(len(self.A.msg), len(MSGB))
541 self.assertEqual(len(self.B.msg), len(MSGA))
542 self.assertEqual(self.A.msg, MSGB)
543 self.assertEqual(self.B.msg, MSGA)
545 def testOrderedLossy(self, num = 2**18, prob=0.5):
546 self.testOrderedSimple(num, prob)