instrumentation: add next-share/
[cs-p2p-next.git] / instrumentation / next-share / BaseLib / Core / DecentralizedTracking / kadtracker / test_bencode.py
1 # Copyright (C) 2009 Raul Jimenez
2 # Released under GNU LGPL 2.1
3 # See LICENSE.txt for more information
4
5 from nose.tools import assert_raises, raises
6
7 import cStringIO
8 import logging, logging_conf
9
10 from bencode import *
11
12 logging_conf.testing_setup(__name__)
13 logger = logging.getLogger('dht')
14
15 test_data = [
16     # strings
17     ('a', '1:a'),
18     ('1', '1:1'),
19     ('0123456789abcdef', '16:0123456789abcdef'),
20     ('A' * 100, '100:' + 'A' * 100),
21     ('{', '1:{'),
22     ('[', '1:['),
23     (chr(2), '1:' + chr(2)),
24     # integers
25     (0, 'i0e'),
26     (000, 'i0e'),
27     (1234567890, 'i1234567890e'),
28     (-1, 'i-1e'),
29     # lists
30     ([], 'le'),
31     ([[[[]]]], 'lllleeee'), # maximum recursivity depht
32     ([1, 2, 3], 'li1ei2ei3ee'),
33     (['A', 'B', 'C'], 'l1:A1:B1:Ce'),
34     (['A', 2, 'C'], 'l1:Ai2e1:Ce'),
35     ([1, ['X'], 2, 'Z'], 'li1el1:Xei2e1:Ze'),
36     # dictionaries
37     ({}, 'de'),
38     ({'key': 'a'}, 'd3:key1:ae'),
39     ({'ZZZ': 12345}, 'd3:ZZZi12345ee'),
40     # ordered dictionaries
41     ({'a':{'A':1, 'C':2, 'B':3}, 'b':2, 'z':3, 'c':[]},
42      'd1:ad1:Ai1e1:Bi3e1:Ci2ee1:bi2e1:cle1:zi3ee'),
43     # mixed types
44     ({'A': [], 'B': {'B': [1], 'C': [], 'D':{}}, 'C': 9},
45      'd1:Ale1:Bd1:Bli1ee1:Cle1:Ddee1:Ci9ee'),
46     ]
47
48 test_data_encode_error = [
49     (False, EncodeError),
50     # Using no-string types in dict
51     ({1:1}, EncodeError),
52     ({None:1}, EncodeError),
53     ({(1,2):1}, EncodeError),
54     # There is no recursion limit when encoding
55     ]
56
57 test_data_decode_error = [
58     ('', DecodeError), # empty bencode
59     ('leEXTRA', DecodeError), # extra characters after bencode
60     ('xWHATEVER', DecodeError), # start with invalid character
61     ('dxe', DecodeError), # invalid special character
62     ('ixe', DecodeError), # invalid integer 
63     ('li2e', DecodeError), # list end missing
64     ('li2eee', DecodeError), # extra end
65     ('d3:KEYe', DecodeError), # value missing
66     ('lllll', RecursionDepthError),
67     ('ddddd', DecodeError), # Notice that a dictionary is NOT a valid KEY.
68     ]
69
70
71 def debug_print(test_num, input_, expected, output):
72     logger.debug('''test_num: %d
73     input:    %s
74     expected: %s
75     output:   %s''' % (test_num, input_, expected, output))
76        
77
78 class TestEncode():
79
80     def setup(self):
81         pass
82
83     def test_encode(self):
84         for i, (data, expected) in enumerate(test_data):
85             bencoded = None
86             try:
87                 bencoded = encode(data)
88             except(Exception), e:
89                 debug_print(i, data, expected, e)
90                 raise
91             if bencoded != expected:
92                 debug_print(i, data, expected, bencoded)
93                 assert False
94
95     def test_encode_error(self):
96         for i, (data, expected) in enumerate(test_data_encode_error):
97             logger.debug(
98                 '>>>>>>>>>>>EXPECTED ERROR LOG: %r' % expected)
99             try:
100                 encode(data)
101             except expected:
102                 pass # Good. We got the expected exception.
103             except (Exception), e:
104                 debug_print(i, data, expected, e)
105                 raise # Fail. We got some other exception.
106             else:
107                 debug_print(i, data, expected, 'NO EXCEPTION RAISED')
108                 assert False # Fail. We got no exception at all.
109
110                 
111 class TestDecode:
112
113     def setup(self):
114         pass
115
116     def test_decode(self):
117         for i, (expected, bencoded) in enumerate(test_data):
118             data = None
119             try:
120                 data = decode(bencoded)
121             except (Exception), e:
122                 debug_print(i, bencoded, expected, e)
123                 raise
124             else:
125                 if data != expected:
126                     debug_print(i, bencoded, expected, data)
127                     assert False
128
129     def test_decode_error(self):
130         for i, (bencoded, expected) in enumerate(test_data_decode_error):
131             try:
132                 decode(bencoded)
133             except expected:
134                 pass
135             except (Exception), e:
136                 debug_print(i, bencoded, expected, e)
137                 raise
138             else:
139                 debug_print(i, bencoded, expected, 'NO EXCEPTION RAISED')
140                 assert False