]> git.mxchange.org Git - quix0rs-apt-p2p.git/blob - test_airhook.py
669bee5a202adfb103b9a0e3ed751abf176c2cce
[quix0rs-apt-p2p.git] / test_airhook.py
1 import unittest
2 from airhook import *
3 from random import uniform as rand
4
5 if __name__ =="__main__":
6         tests = unittest.defaultTestLoader.loadTestsFromNames(['test_airhook'])
7         result = unittest.TextTestRunner().run(tests)
8
9
10
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)))
14         return packet
15
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)
19         return packet
20
21
22 def pscope(msg, noisy=0):
23         # packet scope
24         str = ""
25         p = AirhookPacket(msg)
26         str += "oseq: %s  seq: %s " %  (p.oseq, p.seq)
27         if noisy:
28                 str += "packet: %s  \n" % (`p.datagram`)
29         flags = p.flags
30         str += "flags: "
31         if flags & FLAG_SESSION:
32                 str += "FLAG_SESSION "
33         if flags & FLAG_OBSERVED:
34                 str += "FLAG_OBSERVED "
35         if flags & FLAG_MISSED:
36                 str += "FLAG_MISSED "
37         if flags & FLAG_NEXT:
38                 str += "FLAG_NEXT "
39         str += "\n"
40         
41         if p.observed != None:
42                 str += "OBSERVED: %s\n" % p.observed
43         if p.session != None:
44                 str += "SESSION: %s\n" % p.session
45         if p.next != None:
46                 str += "NEXT: %s\n" % p.next
47         if p.missed:
48                 if noisy:
49                         str += "MISSED: " + `p.missed`
50                 else:
51                         str += "MISSED: " + `len(p.missed)`
52                 str += "\n"
53         if p.msgs:
54                 if noisy:
55                         str += "MSGS: " + `p.msgs` + "\n"
56                 else:
57                         str += "MSGS: <%s> " % len(p.msgs)
58                 str += "\n"
59         return str
60                         
61 # testing function
62 def swap(a, dir="", noisy=0):
63         msg = ""
64         while not msg:
65                 a.transport.seek(0)
66                 msg= a.transport.read()
67                 a.transport = StringIO()
68                 if not msg:
69                         a.sendNext()
70         if noisy:
71                                 print 6*dir + " " + pscope(msg)
72         return msg
73         
74 class SimpleTest(unittest.TestCase):
75         def setUp(self):
76                 self.noisy = 0
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
81                 self.noisy = 0
82                 a = self.a
83                 b = self.b
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)
90
91                 msg = swap(a, '>', self.noisy)          
92                 self.assertEqual(a.state, sent)
93                 self.assertEqual(a.outSeq, 1)
94                 self.assertEqual(a.obSeq, -1)
95
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)
102
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)
109
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)
116
117                 a.datagramReceived(msg)
118                 self.assertEqual(a.outSeq, 2)
119                 self.assertEqual(a.inSeq, 1)
120                 self.assertEqual(a.obSeq, 1)
121
122 class BasicTests(unittest.TestCase):
123         def setUp(self):
124                 self.a = AirhookConnection(StringIO(), (None, 'localhost', 4040), None)
125                 self.b = AirhookConnection(StringIO(), (None, 'localhost', 4040), None)
126                 self.noisy = 0
127         def testSimple(self):
128                 a = self.a
129                 b = self.b
130                 
131                 TESTMSG = "Howdy, Y'All!"
132                 a.omsgq.append(TESTMSG)
133                 a.sendNext()
134                 msg = swap(a, '>', self.noisy)
135                 
136                 b.datagramReceived(msg)
137                 msg = swap(b, '<', self.noisy)
138                 a.datagramReceived(msg)
139                 msg = swap(a, '>', self.noisy)
140                 b.datagramReceived(msg)
141                 
142                 self.assertEqual(b.inMsg, 1)
143                 self.assertEqual(len(b.imsgq), 1)
144                 self.assertEqual(b.imsgq[0], TESTMSG)
145                 
146                 msg = swap(b, '<', self.noisy)
147                 
148                 a.datagramReceived(msg)
149                 msg = swap(a, '>', self.noisy)
150                 b.datagramReceived(msg)
151                 
152         def testLostFirst(self):
153                 a = self.a
154                 b = self.b
155                 
156                 TESTMSG = "Howdy, Y'All!"
157                 TESTMSG2 = "Yee Haw"
158                 
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)
166
167                 del(msg) # dropping first message
168                 
169                 a.omsgq.append(TESTMSG2)
170                 msg = swap(a, '>', self.noisy)
171         
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)
178                 
179                 a.datagramReceived(msg)
180                                                                 
181                 msg = swap(a, '>', self.noisy)
182                 
183                 b.datagramReceived(msg)
184                 self.assertEqual(len(b.imsgq), 2)
185                 b.imsgq.sort()
186                 l = [TESTMSG2, TESTMSG]
187                 l.sort()
188                 self.assertEqual(b.imsgq,l)
189                 
190                 msg = swap(b, '<', self.noisy)
191                 
192                 a.datagramReceived(msg)
193                 msg = swap(a, '>', self.noisy)
194                 b.datagramReceived(msg)
195                 
196                 msg = swap(b, '<', self.noisy)
197                 a.datagramReceived(msg)
198                 msg = swap(a, '>', self.noisy)
199                 b.datagramReceived(msg)
200
201                 msg = swap(b, '<', self.noisy)
202                 a.datagramReceived(msg)
203                 msg = swap(a, '>', self.noisy)
204
205                 self.assertEqual(len(b.imsgq), 2)
206                 b.imsgq.sort()
207                 l = [TESTMSG2, TESTMSG]
208                 l.sort()
209                 self.assertEqual(b.imsgq,l)
210
211         def testLostSecond(self):
212                 a = self.a
213                 b = self.b
214                 
215                 TESTMSG = "Howdy, Y'All!"
216                 TESTMSG2 = "Yee Haw"
217                 
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)
225
226                 a.omsgq.append(TESTMSG2)
227                 msg2 = swap(a, '>', self.noisy)
228                 del(msg2) # dropping second message
229
230                 assert(a.outMsgs[1] != None)
231
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)
239                 
240                 a.datagramReceived(msg)
241                 assert(a.outMsgs[1] != None)
242                 msg = swap(a, '>', self.noisy)
243
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)
250
251                 a.datagramReceived(msg)
252                 msg = swap(a, '>', self.noisy)
253
254                 b.datagramReceived(msg)
255                 self.assertEqual(len(b.imsgq), 2)
256                 b.imsgq.sort()
257                 l = [TESTMSG2, TESTMSG]
258                 l.sort()
259                 self.assertEqual(b.imsgq,l)
260                 
261                 msg = swap(b, '<', self.noisy)
262
263                 a.datagramReceived(msg)
264                 msg = swap(a, '>', self.noisy)
265
266                 b.datagramReceived(msg)
267                 
268                 msg = swap(b, '<', self.noisy)
269
270                 a.datagramReceived(msg)
271                 msg = swap(a, '>', self.noisy)
272
273                 b.datagramReceived(msg)
274
275                 msg = swap(b, '<', self.noisy)
276
277                 a.datagramReceived(msg)
278
279
280                 msg = swap(a, '>', self.noisy)
281
282                 self.assertEqual(len(b.imsgq), 2)
283                 b.imsgq.sort()
284                 l = [TESTMSG2, TESTMSG]
285                 l.sort()
286                 self.assertEqual(b.imsgq,l)
287
288         def testDoubleDouble(self):
289                 a = self.a
290                 b = self.b
291                 
292                 TESTMSGA = "Howdy, Y'All!"
293                 TESTMSGB = "Yee Haw"
294                 TESTMSGC = "FOO BAR"
295                 TESTMSGD = "WING WANG"
296                 
297                 a.omsgq.append(TESTMSGA)
298                 a.omsgq.append(TESTMSGB)
299
300                 b.omsgq.append(TESTMSGC)
301                 b.omsgq.append(TESTMSGD)
302                 
303                 
304                 msg = swap(a, '>', self.noisy)
305                         
306
307                 b.datagramReceived(msg)
308                 self.assertEqual(b.state, sent)
309                 
310                 msg = swap(b, '<', self.noisy)
311                 a.datagramReceived(msg)
312
313                 msg = swap(a, '>', self.noisy)
314
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)
321
322                 msg = swap(b, '<', self.noisy)
323                 a.datagramReceived(msg)
324                 
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)
330
331         def testDoubleDoubleProb(self, prob=0.25):
332                 a = self.a
333                 b = self.b
334                 TESTMSGA = "Howdy, Y'All!"
335                 TESTMSGB = "Yee Haw"
336                 TESTMSGC = "FOO BAR"
337                 TESTMSGD = "WING WANG"
338                 
339                 a.omsgq.append(TESTMSGA)
340                 a.omsgq.append(TESTMSGB)
341
342                 b.omsgq.append(TESTMSGC)
343                 b.omsgq.append(TESTMSGD)
344                 
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)
347         
348                         if rand(0,1) < prob:
349                                 b.datagramReceived(msga)
350                         
351                         msgb = swap(b, '<', self.noisy)
352
353                         if rand(0,1) < prob:
354                                 a.datagramReceived(msgb)
355
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)
362                                 
363                 self.assertEqual(len(a.imsgq), 2)
364                 l = [TESTMSGC, TESTMSGD]
365                 l.sort();a.imsgq.sort()
366                 self.assertEqual(a.imsgq, l)
367
368         def testOneWayBlast(self, num = 2**8):
369                 a = self.a
370                 b = self.b
371                 import sha
372                 
373                 
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)
380
381                         a.datagramReceived(msg)
382                         msg = swap(a, '>', self.noisy)
383
384                 self.assertEqual(len(b.imsgq), num)
385                 
386         def testTwoWayBlast(self, num = 2**9, prob=0.5):
387                 a = self.a
388                 b = self.b
389                 import sha
390                 
391                 
392                 for i in xrange(num):
393                         a.omsgq.append(sha.sha('a' + `i`).digest())
394                         b.omsgq.append(sha.sha('b' + `i`).digest())
395                         
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):
397                         if rand(0,1) < prob:
398                                 msga = swap(a, '>', self.noisy)
399                                 b.datagramReceived(msga)
400                         else:
401                                 msga = swap(a, '>', 0)
402                         if rand(0,1) < prob:
403                                 msgb = swap(b, '<', self.noisy)
404                                 a.datagramReceived(msgb)
405                         else:
406                                 msgb = swap(b, '<', 0)
407                                         
408
409
410                 self.assertEqual(len(a.imsgq), num)
411                 self.assertEqual(len(b.imsgq), num)
412                 
413         def testLimitMessageNumbers(self):
414                 a = self.a
415                 b = self.b
416                 import sha
417
418                 msg = swap(a, noisy=self.noisy)
419                 b.datagramReceived(msg)
420
421                 msg = swap(b, noisy=self.noisy)
422                 a.datagramReceived(msg)
423                 
424                 
425                 for i in range(5000):
426                         a.omsgq.append(sha.sha('a' + 'i').digest())
427                 
428                 for i in range(31):
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)
434
435 class OrderedTests(unittest.TestCase):
436         def setUp(self):
437                 self.noisy = 0
438                 class queuer:
439                         def __init__(self):
440                                 self.msg = ""
441                         def dataCameIn(self, host, port, data):
442                                 self.msg+= data
443                 self.A = queuer()
444                 self.B = queuer()
445                 self.a = OrderedConnection(StringIO(), (None, 'localhost', 4040), self.A)
446                 self.b = OrderedConnection(StringIO(), (None, 'localhost', 4040), self.B)
447
448         def testOrderedSimple(self, num = 2**17, prob=1.0):
449                 f = open('/dev/urandom', 'r')
450                 a = self.a
451                 b = self.b
452                 A = self.A
453                 B = self.B
454
455                 MSGA = f.read(num)
456                 MSGB = f.read(num)
457                 self.a.sendSomeData(MSGA)
458                 self.b.sendSomeData(MSGB)
459                 
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):
461                         if rand(0,1) < prob:
462                                 msga = swap(a, '>', self.noisy)
463                                 b.datagramReceived(msga)
464                         else:
465                                 msga = swap(a, '>', 0)
466                         if rand(0,1) < prob:
467                                 msgb = swap(b, '<', self.noisy)
468                                 a.datagramReceived(msgb)
469                         else:
470                                 msgb = swap(b, '<', 0)
471                 self.assertEqual(self.A.msg, MSGB)
472                 self.assertEqual(self.B.msg, MSGA)
473                 
474         def testOrderedLossy(self, num = 2**17, prob=0.5):
475                 self.testOrderedSimple(num, prob)