~bzr-pqm/bzr/bzr.dev

2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
1
# Copyright (C) 2007 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
2694.5.14 by Jelmer Vernooij
Fix copyright headers, add _bencode_py.py to the list of files that do not have to have canonical copyright.
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
16
17
"""Tests for bencode structured encoding"""
18
2694.5.8 by Jelmer Vernooij
Use standard infrastructure for testing python and pyrex bencode implementations.
19
from bzrlib import tests
20
21
def load_tests(standard_tests, module, loader):
22
    # parameterize all tests in this module
23
    suite = loader.suiteClass()
4398.5.4 by John Arbash Meinel
A bit of code restructuring.
24
    import bzrlib.util._bencode_py as py_module
2694.5.8 by Jelmer Vernooij
Use standard infrastructure for testing python and pyrex bencode implementations.
25
    scenarios = [('python', {'bencode': py_module})]
26
    if CompiledBencodeFeature.available():
4398.5.4 by John Arbash Meinel
A bit of code restructuring.
27
        import bzrlib._bencode_pyx as c_module
2694.5.8 by Jelmer Vernooij
Use standard infrastructure for testing python and pyrex bencode implementations.
28
        scenarios.append(('C', {'bencode': c_module}))
29
    else:
30
        # the compiled module isn't available, so we add a failing test
31
        class FailWithoutFeature(tests.TestCase):
32
            def test_fail(self):
33
                self.requireFeature(CompiledBencodeFeature)
34
        suite.addTest(loader.loadTestsFromTestCase(FailWithoutFeature))
35
    tests.multiply_tests(standard_tests, scenarios, suite)
36
    return suite
37
38
39
class _CompiledBencodeFeature(tests.Feature):
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
40
41
    def _probe(self):
2694.5.8 by Jelmer Vernooij
Use standard infrastructure for testing python and pyrex bencode implementations.
42
        try:
4398.5.4 by John Arbash Meinel
A bit of code restructuring.
43
            import bzrlib._bencode_pyx
2694.5.8 by Jelmer Vernooij
Use standard infrastructure for testing python and pyrex bencode implementations.
44
        except ImportError:
45
            return False
46
        return True
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
47
48
    def feature_name(self):
4398.5.4 by John Arbash Meinel
A bit of code restructuring.
49
        return 'bzrlib._bencode_pyx'
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
50
2694.5.8 by Jelmer Vernooij
Use standard infrastructure for testing python and pyrex bencode implementations.
51
CompiledBencodeFeature = _CompiledBencodeFeature()
52
53
54
class TestBencodeDecode(tests.TestCase):
55
56
    bencode = None
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
57
58
    def _check(self, expected, source):
59
        self.assertEquals(expected, self.bencode.bdecode(source))
60
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
61
    def _run_check_error(self, exc, bad):
62
        """Check that bdecoding a string raises a particular exception."""
63
        self.assertRaises(exc, self.bencode.bdecode, bad)
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
64
65
    def test_int(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
66
        self._check(0, 'i0e')
67
        self._check(4, 'i4e')
68
        self._check(123456789, 'i123456789e')
69
        self._check(-10, 'i-10e')
2694.5.19 by Jelmer Vernooij
Support longs in the pyrex extensions, avoid memcpy.
70
        self._check(int('1' * 1000), 'i' + ('1' * 1000) + 'e')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
71
72
    def test_long(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
73
        self._check(12345678901234567890L, 'i12345678901234567890e')
74
        self._check(-12345678901234567890L, 'i-12345678901234567890e')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
75
76
    def test_malformed_int(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
77
        self._run_check_error(ValueError, 'ie')
78
        self._run_check_error(ValueError, 'i-e')
79
        self._run_check_error(ValueError, 'i-010e')
80
        self._run_check_error(ValueError, 'i-0e')
81
        self._run_check_error(ValueError, 'i00e')
82
        self._run_check_error(ValueError, 'i01e')
83
        self._run_check_error(ValueError, 'i-03e')
84
        self._run_check_error(ValueError, 'i')
85
        self._run_check_error(ValueError, 'i123')
86
        self._run_check_error(ValueError, 'i341foo382e')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
87
88
    def test_string(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
89
        self._check('', '0:')
90
        self._check('abc', '3:abc')
91
        self._check('1234567890', '10:1234567890')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
92
2694.5.10 by Jelmer Vernooij
Add some more tests.
93
    def test_large_string(self):
94
        self.assertRaises(ValueError, self.bencode.bdecode, "2147483639:foo")
95
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
96
    def test_malformed_string(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
97
        self._run_check_error(ValueError, '10:x')
98
        self._run_check_error(ValueError, '10:')
99
        self._run_check_error(ValueError, '10')
100
        self._run_check_error(ValueError, '01:x')
101
        self._run_check_error(ValueError, '00:')
102
        self._run_check_error(ValueError, '35208734823ljdahflajhdf')
103
        self._run_check_error(ValueError, '432432432432432:foo')
4398.5.14 by John Arbash Meinel
Some small tweaks to decoding strings (avoid passing over the length 2x)
104
        self._run_check_error(ValueError, ' 1:x') # leading whitespace
105
        self._run_check_error(ValueError, '-1:x') # negative
106
        self._run_check_error(ValueError, '1 x') # space vs colon
107
        self._run_check_error(ValueError, '1x') # missing colon
108
        self._run_check_error(ValueError, ('1' * 1000) + ':')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
109
110
    def test_list(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
111
        self._check([], 'le')
112
        self._check(['', '', ''], 'l0:0:0:e')
113
        self._check([1, 2, 3], 'li1ei2ei3ee')
114
        self._check(['asd', 'xy'], 'l3:asd2:xye')
115
        self._check([['Alice', 'Bob'], [2, 3]], 'll5:Alice3:Bobeli2ei3eee')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
116
2694.5.20 by Jelmer Vernooij
add handling of deep nesting.
117
    def test_list_deepnested(self):
118
        self._run_check_error(RuntimeError, ("l" * 10000) + ("e" * 10000))
119
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
120
    def test_malformed_list(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
121
        self._run_check_error(ValueError, 'l')
122
        self._run_check_error(ValueError, 'l01:ae')
123
        self._run_check_error(ValueError, 'l0:')
124
        self._run_check_error(ValueError, 'li1e')
125
        self._run_check_error(ValueError, 'l-3:e')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
126
127
    def test_dict(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
128
        self._check({}, 'de')
129
        self._check({'':3}, 'd0:i3ee')
130
        self._check({'age': 25, 'eyes': 'blue'}, 'd3:agei25e4:eyes4:bluee')
131
        self._check({'spam.mp3': {'author': 'Alice', 'length': 100000}},
132
                            'd8:spam.mp3d6:author5:Alice6:lengthi100000eee')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
133
2694.5.20 by Jelmer Vernooij
add handling of deep nesting.
134
    def test_dict_deepnested(self):
135
        self._run_check_error(RuntimeError, ("d0:" * 10000) + 'i1e' + ("e" * 10000))
136
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
137
    def test_malformed_dict(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
138
        self._run_check_error(ValueError, 'd')
139
        self._run_check_error(ValueError, 'defoobar')
140
        self._run_check_error(ValueError, 'd3:fooe')
141
        self._run_check_error(ValueError, 'di1e0:e')
142
        self._run_check_error(ValueError, 'd1:b0:1:a0:e')
143
        self._run_check_error(ValueError, 'd1:a0:1:a0:e')
144
        self._run_check_error(ValueError, 'd0:0:')
145
        self._run_check_error(ValueError, 'd0:')
146
        self._run_check_error(ValueError, 'd432432432432432432:e')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
147
148
    def test_empty_string(self):
2694.5.9 by Jelmer Vernooij
Fix tests.
149
        self.assertRaises(ValueError, self.bencode.bdecode, '')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
150
151
    def test_junk(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
152
        self._run_check_error(ValueError, 'i6easd')
153
        self._run_check_error(ValueError, '2:abfdjslhfld')
154
        self._run_check_error(ValueError, '0:0:')
155
        self._run_check_error(ValueError, 'leanfdldjfh')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
156
157
    def test_unknown_object(self):
2694.5.9 by Jelmer Vernooij
Fix tests.
158
        self.assertRaises(ValueError, self.bencode.bdecode, 'relwjhrlewjh')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
159
2694.5.8 by Jelmer Vernooij
Use standard infrastructure for testing python and pyrex bencode implementations.
160
    def test_unsupported_type(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
161
        self._run_check_error(TypeError, float(1.5))
162
        self._run_check_error(TypeError, None)
163
        self._run_check_error(TypeError, lambda x: x)
164
        self._run_check_error(TypeError, object)
165
        self._run_check_error(TypeError, u"ie")
2694.5.9 by Jelmer Vernooij
Fix tests.
166
167
    def test_decoder_type_error(self):
168
        self.assertRaises(TypeError, self.bencode.bdecode, 1)
2694.5.8 by Jelmer Vernooij
Use standard infrastructure for testing python and pyrex bencode implementations.
169
170
171
class TestBencodeEncode(tests.TestCase):
172
173
    bencode = None
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
174
175
    def _check(self, expected, source):
176
        self.assertEquals(expected, self.bencode.bencode(source))
177
178
    def test_int(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
179
        self._check('i4e', 4)
180
        self._check('i0e', 0)
181
        self._check('i-10e', -10)
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
182
183
    def test_long(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
184
        self._check('i12345678901234567890e', 12345678901234567890L)
185
        self._check('i-12345678901234567890e', -12345678901234567890L)
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
186
187
    def test_string(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
188
        self._check('0:', '')
189
        self._check('3:abc', 'abc')
190
        self._check('10:1234567890', '1234567890')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
191
192
    def test_list(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
193
        self._check('le', [])
194
        self._check('li1ei2ei3ee', [1, 2, 3])
195
        self._check('ll5:Alice3:Bobeli2ei3eee', [['Alice', 'Bob'], [2, 3]])
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
196
2694.5.5 by Jelmer Vernooij
Support bdecode_as_tuple.
197
    def test_list_as_tuple(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
198
        self._check('le', ())
199
        self._check('li1ei2ei3ee', (1, 2, 3))
200
        self._check('ll5:Alice3:Bobeli2ei3eee', (('Alice', 'Bob'), (2, 3)))
2694.5.5 by Jelmer Vernooij
Support bdecode_as_tuple.
201
2694.5.20 by Jelmer Vernooij
add handling of deep nesting.
202
    def test_list_deep_nested(self):
203
        top = []
204
        l = top
205
        for i in range(10000):
206
            l.append([])
207
            l = l[0]
208
        self.assertRaises(RuntimeError, self.bencode.bencode, 
209
            top)
210
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
211
    def test_dict(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
212
        self._check('de', {})
213
        self._check('d3:agei25e4:eyes4:bluee', {'age': 25, 'eyes': 'blue'})
214
        self._check('d8:spam.mp3d6:author5:Alice6:lengthi100000eee',
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
215
                            {'spam.mp3': {'author': 'Alice',
216
                                          'length': 100000}})
217
2694.5.20 by Jelmer Vernooij
add handling of deep nesting.
218
    def test_dict_deep_nested(self):
219
        d = top = {}
220
        for i in range(10000):
221
            d[''] = {}
222
            d = d['']
223
        self.assertRaises(RuntimeError, self.bencode.bencode, 
224
            top)
225
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
226
    def test_bencached(self):
227
        self._check('i3e', self.bencode.Bencached(self.bencode.bencode(3)))
228
229
    def test_invalid_dict(self):
2694.5.10 by Jelmer Vernooij
Add some more tests.
230
        self.assertRaises(TypeError, self.bencode.bencode, {1:"foo"})
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
231
232
    def test_bool(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
233
        self._check('i1e', True)
234
        self._check('i0e', False)
2694.5.10 by Jelmer Vernooij
Add some more tests.
235