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)
74 class SimpleTest(unittest.TestCase):
77 self.a = AirhookConnection(StringIO(), (None, 'localhost', 4040), None)
78 self.b = AirhookConnection(StringIO(), (None, 'localhost', 4040), None)
79 def testReallySimple(self):
80 # connect to eachother and send a few packets, observe sequence incrementing
84 self.assertEqual(a.state, pending)
85 self.assertEqual(b.state, pending)
86 self.assertEqual(a.outSeq, 0)
87 self.assertEqual(b.outSeq, 0)
88 self.assertEqual(a.obSeq, -1)
89 self.assertEqual(b.obSeq, -1)
91 msg = swap(a, '>', self.noisy)
92 self.assertEqual(a.state, sent)
93 self.assertEqual(a.outSeq, 1)
94 self.assertEqual(a.obSeq, -1)
96 b.datagramReceived(msg)
97 self.assertEqual(b.state, sent)
98 self.assertEqual(b.inSeq, 0)
99 self.assertEqual(b.obSeq, -1)
100 msg = swap(b, '<', self.noisy)
101 self.assertEqual(b.outSeq, 1)
103 a.datagramReceived(msg)
104 self.assertEqual(a.state, confirmed)
105 self.assertEqual(a.obSeq, 0)
106 self.assertEqual(a.inSeq, 0)
107 msg = swap(a, '>', self.noisy)
108 self.assertEqual(a.outSeq, 2)
110 b.datagramReceived(msg)
111 self.assertEqual(b.state, confirmed)
112 self.assertEqual(b.obSeq, 0)
113 self.assertEqual(b.inSeq, 1)
114 msg = swap(b, '<', self.noisy)
115 self.assertEqual(b.outSeq, 2)
117 a.datagramReceived(msg)
118 self.assertEqual(a.outSeq, 2)
119 self.assertEqual(a.inSeq, 1)
120 self.assertEqual(a.obSeq, 1)
122 class BasicTests(unittest.TestCase):
124 self.a = AirhookConnection(StringIO(), (None, 'localhost', 4040), None)
125 self.b = AirhookConnection(StringIO(), (None, 'localhost', 4040), None)
127 def testSimple(self):
131 TESTMSG = "Howdy, Y'All!"
132 a.omsgq.append(TESTMSG)
134 msg = swap(a, '>', self.noisy)
136 b.datagramReceived(msg)
137 msg = swap(b, '<', self.noisy)
138 a.datagramReceived(msg)
139 msg = swap(a, '>', self.noisy)
140 b.datagramReceived(msg)
142 self.assertEqual(b.inMsg, 1)
143 self.assertEqual(len(b.imsgq), 1)
144 self.assertEqual(b.imsgq[0], TESTMSG)
146 msg = swap(b, '<', self.noisy)
148 a.datagramReceived(msg)
149 msg = swap(a, '>', self.noisy)
150 b.datagramReceived(msg)
152 def testLostFirst(self):
156 TESTMSG = "Howdy, Y'All!"
159 a.omsgq.append(TESTMSG)
160 msg = swap(a, '>', self.noisy)
161 b.datagramReceived(msg)
162 msg = swap(b, '<', self.noisy)
163 self.assertEqual(b.state, sent)
164 a.datagramReceived(msg)
165 msg = swap(a, '>', self.noisy)
167 del(msg) # dropping first message
169 a.omsgq.append(TESTMSG2)
170 msg = swap(a, '>', self.noisy)
172 b.datagramReceived(msg)
173 self.assertEqual(b.state, confirmed)
174 self.assertEqual(len(b.imsgq), 1)
175 self.assertEqual(b.imsgq[0], TESTMSG2)
176 self.assertEqual(b.weMissed, [(1, 0)])
177 msg = swap(b, '<', self.noisy)
179 a.datagramReceived(msg)
181 msg = swap(a, '>', self.noisy)
183 b.datagramReceived(msg)
184 self.assertEqual(len(b.imsgq), 2)
186 l = [TESTMSG2, TESTMSG]
188 self.assertEqual(b.imsgq,l)
190 msg = swap(b, '<', self.noisy)
192 a.datagramReceived(msg)
193 msg = swap(a, '>', self.noisy)
194 b.datagramReceived(msg)
196 msg = swap(b, '<', self.noisy)
197 a.datagramReceived(msg)
198 msg = swap(a, '>', self.noisy)
199 b.datagramReceived(msg)
201 msg = swap(b, '<', self.noisy)
202 a.datagramReceived(msg)
203 msg = swap(a, '>', self.noisy)
205 self.assertEqual(len(b.imsgq), 2)
207 l = [TESTMSG2, TESTMSG]
209 self.assertEqual(b.imsgq,l)
211 def testLostSecond(self):
215 TESTMSG = "Howdy, Y'All!"
218 a.omsgq.append(TESTMSG)
219 msg = swap(a, '>', self.noisy)
220 b.datagramReceived(msg)
221 msg = swap(b, '<', self.noisy)
222 self.assertEqual(b.state, sent)
223 a.datagramReceived(msg)
224 msg = swap(a, '>', self.noisy)
226 a.omsgq.append(TESTMSG2)
227 msg2 = swap(a, '>', self.noisy)
228 del(msg2) # dropping second message
230 assert(a.outMsgs[1] != None)
232 b.datagramReceived(msg)
233 self.assertEqual(b.state, confirmed)
234 self.assertEqual(len(b.imsgq), 1)
235 self.assertEqual(b.imsgq[0], TESTMSG)
236 self.assertEqual(b.inMsg, 1)
237 self.assertEqual(b.weMissed, [])
238 msg = swap(b, '<', self.noisy)
240 a.datagramReceived(msg)
241 assert(a.outMsgs[1] != None)
242 msg = swap(a, '>', self.noisy)
244 b.datagramReceived(msg)
245 self.assertEqual(b.state, confirmed)
246 self.assertEqual(len(b.imsgq), 1)
247 self.assertEqual(b.imsgq[0], TESTMSG)
248 self.assertEqual(b.weMissed, [(2, 1)])
249 msg = swap(b, '<', self.noisy)
251 a.datagramReceived(msg)
252 msg = swap(a, '>', self.noisy)
254 b.datagramReceived(msg)
255 self.assertEqual(len(b.imsgq), 2)
257 l = [TESTMSG2, TESTMSG]
259 self.assertEqual(b.imsgq,l)
261 msg = swap(b, '<', self.noisy)
263 a.datagramReceived(msg)
264 msg = swap(a, '>', self.noisy)
266 b.datagramReceived(msg)
268 msg = swap(b, '<', self.noisy)
270 a.datagramReceived(msg)
271 msg = swap(a, '>', self.noisy)
273 b.datagramReceived(msg)
275 msg = swap(b, '<', self.noisy)
277 a.datagramReceived(msg)
280 msg = swap(a, '>', self.noisy)
282 self.assertEqual(len(b.imsgq), 2)
284 l = [TESTMSG2, TESTMSG]
286 self.assertEqual(b.imsgq,l)
288 def testDoubleDouble(self):
292 TESTMSGA = "Howdy, Y'All!"
295 TESTMSGD = "WING WANG"
297 a.omsgq.append(TESTMSGA)
298 a.omsgq.append(TESTMSGB)
300 b.omsgq.append(TESTMSGC)
301 b.omsgq.append(TESTMSGD)
304 msg = swap(a, '>', self.noisy)
307 b.datagramReceived(msg)
308 self.assertEqual(b.state, sent)
310 msg = swap(b, '<', self.noisy)
311 a.datagramReceived(msg)
313 msg = swap(a, '>', self.noisy)
315 b.datagramReceived(msg)
316 self.assertEqual(len(b.imsgq), 2)
317 l = [TESTMSGA, TESTMSGB]
318 l.sort();b.imsgq.sort()
319 self.assertEqual(b.imsgq, l)
320 self.assertEqual(b.inMsg, 2)
322 msg = swap(b, '<', self.noisy)
323 a.datagramReceived(msg)
325 self.assertEqual(len(a.imsgq), 2)
326 l = [TESTMSGC, TESTMSGD]
327 l.sort();a.imsgq.sort()
328 self.assertEqual(a.imsgq, l)
329 self.assertEqual(a.inMsg, 2)
331 def testDoubleDoubleProb(self, prob=0.25):
334 TESTMSGA = "Howdy, Y'All!"
337 TESTMSGD = "WING WANG"
339 a.omsgq.append(TESTMSGA)
340 a.omsgq.append(TESTMSGB)
342 b.omsgq.append(TESTMSGC)
343 b.omsgq.append(TESTMSGD)
345 while a.state != confirmed or b.state != confirmed or ord(msga[0]) & FLAG_NEXT or ord(msgb[0]) & FLAG_NEXT :
346 msga = swap(a, '>', self.noisy)
349 b.datagramReceived(msga)
351 msgb = swap(b, '<', self.noisy)
354 a.datagramReceived(msgb)
356 self.assertEqual(a.state, confirmed)
357 self.assertEqual(b.state, confirmed)
358 self.assertEqual(len(b.imsgq), 2)
359 l = [TESTMSGA, TESTMSGB]
360 l.sort();b.imsgq.sort()
361 self.assertEqual(b.imsgq, l)
363 self.assertEqual(len(a.imsgq), 2)
364 l = [TESTMSGC, TESTMSGD]
365 l.sort();a.imsgq.sort()
366 self.assertEqual(a.imsgq, l)
368 def testOneWayBlast(self, num = 2**8):
374 for i in xrange(num):
375 a.omsgq.append(sha.sha(`i`).digest())
376 msg = swap(a, '>', self.noisy)
377 while a.state != confirmed or ord(msg[0]) & FLAG_NEXT:
378 b.datagramReceived(msg)
379 msg = swap(b, '<', self.noisy)
381 a.datagramReceived(msg)
382 msg = swap(a, '>', self.noisy)
384 self.assertEqual(len(b.imsgq), num)
386 def testTwoWayBlast(self, num = 2**9, prob=0.5):
392 for i in xrange(num):
393 a.omsgq.append(sha.sha('a' + `i`).digest())
394 b.omsgq.append(sha.sha('b' + `i`).digest())
396 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):
398 msga = swap(a, '>', self.noisy)
399 b.datagramReceived(msga)
401 msga = swap(a, '>', 0)
403 msgb = swap(b, '<', self.noisy)
404 a.datagramReceived(msgb)
406 msgb = swap(b, '<', 0)
410 self.assertEqual(len(a.imsgq), num)
411 self.assertEqual(len(b.imsgq), num)
413 def testLimitMessageNumbers(self):
418 msg = swap(a, noisy=self.noisy)
419 b.datagramReceived(msg)
421 msg = swap(b, noisy=self.noisy)
422 a.datagramReceived(msg)
425 for i in range(5000):
426 a.omsgq.append(sha.sha('a' + 'i').digest())
429 msg = swap(a, noisy=self.noisy)
430 self.assertEqual(a.obSeq, 0)
431 self.assertEqual(a.outMsgNums[a.obSeq], 0)
432 self.assertEqual(a.next, 254)
433 self.assertEqual(a.outMsgNums[19], 254)
435 class OrderedTests(unittest.TestCase):
441 def dataCameIn(self, host, port, data):
445 self.a = OrderedConnection(StringIO(), (None, 'localhost', 4040), self.A)
446 self.b = OrderedConnection(StringIO(), (None, 'localhost', 4040), self.B)
448 def testOrderedSimple(self, num = 2**17, prob=1.0):
449 f = open('/dev/urandom', 'r')
457 self.a.sendSomeData(MSGA)
458 self.b.sendSomeData(MSGB)
460 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):
462 msga = swap(a, '>', self.noisy)
463 b.datagramReceived(msga)
465 msga = swap(a, '>', 0)
467 msgb = swap(b, '<', self.noisy)
468 a.datagramReceived(msgb)
470 msgb = swap(b, '<', 0)
471 self.assertEqual(self.A.msg, MSGB)
472 self.assertEqual(self.B.msg, MSGA)
474 def testOrderedLossy(self, num = 2**17, prob=0.5):
475 self.testOrderedSimple(num, prob)