~bzr-pqm/bzr/bzr.dev

4763.2.4 by John Arbash Meinel
merge bzr.2.1 in preparation for NEWS entry.
1
# Copyright (C) 2007, 2009, 2010 Canonical Ltd
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
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
5430.2.1 by Andrew Bennetts
Suppress 'maximum recursion depth exceeded in __subclasscheck__' warning triggered by test__bencode.
19
import sys
20
2694.5.8 by Jelmer Vernooij
Use standard infrastructure for testing python and pyrex bencode implementations.
21
from bzrlib import tests
22
23
def load_tests(standard_tests, module, loader):
4913.3.1 by John Arbash Meinel
Implement a permute_for_extension helper.
24
    suite, _ = tests.permute_tests_for_extension(standard_tests, loader,
25
        'bzrlib.util._bencode_py', 'bzrlib._bencode_pyx')
2694.5.8 by Jelmer Vernooij
Use standard infrastructure for testing python and pyrex bencode implementations.
26
    return suite
27
28
29
class TestBencodeDecode(tests.TestCase):
30
4913.3.8 by John Arbash Meinel
Rename test_bencode to test__bencode, and use self.module
31
    module = None
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
32
33
    def _check(self, expected, source):
4913.3.8 by John Arbash Meinel
Rename test_bencode to test__bencode, and use self.module
34
        self.assertEquals(expected, self.module.bdecode(source))
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
35
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
36
    def _run_check_error(self, exc, bad):
37
        """Check that bdecoding a string raises a particular exception."""
4913.3.8 by John Arbash Meinel
Rename test_bencode to test__bencode, and use self.module
38
        self.assertRaises(exc, self.module.bdecode, bad)
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
39
40
    def test_int(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
41
        self._check(0, 'i0e')
42
        self._check(4, 'i4e')
43
        self._check(123456789, 'i123456789e')
44
        self._check(-10, 'i-10e')
2694.5.19 by Jelmer Vernooij
Support longs in the pyrex extensions, avoid memcpy.
45
        self._check(int('1' * 1000), 'i' + ('1' * 1000) + 'e')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
46
47
    def test_long(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
48
        self._check(12345678901234567890L, 'i12345678901234567890e')
49
        self._check(-12345678901234567890L, 'i-12345678901234567890e')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
50
51
    def test_malformed_int(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
52
        self._run_check_error(ValueError, 'ie')
53
        self._run_check_error(ValueError, 'i-e')
54
        self._run_check_error(ValueError, 'i-010e')
55
        self._run_check_error(ValueError, 'i-0e')
56
        self._run_check_error(ValueError, 'i00e')
57
        self._run_check_error(ValueError, 'i01e')
58
        self._run_check_error(ValueError, 'i-03e')
59
        self._run_check_error(ValueError, 'i')
60
        self._run_check_error(ValueError, 'i123')
61
        self._run_check_error(ValueError, 'i341foo382e')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
62
63
    def test_string(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
64
        self._check('', '0:')
65
        self._check('abc', '3:abc')
66
        self._check('1234567890', '10:1234567890')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
67
2694.5.10 by Jelmer Vernooij
Add some more tests.
68
    def test_large_string(self):
4913.3.8 by John Arbash Meinel
Rename test_bencode to test__bencode, and use self.module
69
        self.assertRaises(ValueError, self.module.bdecode, "2147483639:foo")
2694.5.10 by Jelmer Vernooij
Add some more tests.
70
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
71
    def test_malformed_string(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
72
        self._run_check_error(ValueError, '10:x')
73
        self._run_check_error(ValueError, '10:')
74
        self._run_check_error(ValueError, '10')
75
        self._run_check_error(ValueError, '01:x')
76
        self._run_check_error(ValueError, '00:')
77
        self._run_check_error(ValueError, '35208734823ljdahflajhdf')
78
        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)
79
        self._run_check_error(ValueError, ' 1:x') # leading whitespace
80
        self._run_check_error(ValueError, '-1:x') # negative
81
        self._run_check_error(ValueError, '1 x') # space vs colon
82
        self._run_check_error(ValueError, '1x') # missing colon
83
        self._run_check_error(ValueError, ('1' * 1000) + ':')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
84
85
    def test_list(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
86
        self._check([], 'le')
87
        self._check(['', '', ''], 'l0:0:0:e')
88
        self._check([1, 2, 3], 'li1ei2ei3ee')
89
        self._check(['asd', 'xy'], 'l3:asd2:xye')
90
        self._check([['Alice', 'Bob'], [2, 3]], 'll5:Alice3:Bobeli2ei3eee')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
91
2694.5.20 by Jelmer Vernooij
add handling of deep nesting.
92
    def test_list_deepnested(self):
93
        self._run_check_error(RuntimeError, ("l" * 10000) + ("e" * 10000))
94
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
95
    def test_malformed_list(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
96
        self._run_check_error(ValueError, 'l')
97
        self._run_check_error(ValueError, 'l01:ae')
98
        self._run_check_error(ValueError, 'l0:')
99
        self._run_check_error(ValueError, 'li1e')
100
        self._run_check_error(ValueError, 'l-3:e')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
101
102
    def test_dict(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
103
        self._check({}, 'de')
104
        self._check({'':3}, 'd0:i3ee')
105
        self._check({'age': 25, 'eyes': 'blue'}, 'd3:agei25e4:eyes4:bluee')
106
        self._check({'spam.mp3': {'author': 'Alice', 'length': 100000}},
107
                            'd8:spam.mp3d6:author5:Alice6:lengthi100000eee')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
108
2694.5.20 by Jelmer Vernooij
add handling of deep nesting.
109
    def test_dict_deepnested(self):
5430.2.1 by Andrew Bennetts
Suppress 'maximum recursion depth exceeded in __subclasscheck__' warning triggered by test__bencode.
110
        # The recursion here provokes CPython into emitting a warning on
111
        # stderr, "maximum recursion depth exceeded in __subclasscheck__", due
112
        # to running out of stack space while evaluating "except (...):" in
113
        # _bencode_py.  This is harmless, so we temporarily override stderr to
114
        # avoid distracting noise in the test output.
5430.2.2 by Andrew Bennetts
Reuse self._log_file rather than make new StringIO, and wrap pre-existing long line.
115
        self.overrideAttr(sys, 'stderr', self._log_file)
116
        self._run_check_error(
117
            RuntimeError, ("d0:" * 10000) + 'i1e' + ("e" * 10000))
2694.5.20 by Jelmer Vernooij
add handling of deep nesting.
118
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
119
    def test_malformed_dict(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
120
        self._run_check_error(ValueError, 'd')
121
        self._run_check_error(ValueError, 'defoobar')
122
        self._run_check_error(ValueError, 'd3:fooe')
123
        self._run_check_error(ValueError, 'di1e0:e')
124
        self._run_check_error(ValueError, 'd1:b0:1:a0:e')
125
        self._run_check_error(ValueError, 'd1:a0:1:a0:e')
126
        self._run_check_error(ValueError, 'd0:0:')
127
        self._run_check_error(ValueError, 'd0:')
128
        self._run_check_error(ValueError, 'd432432432432432432:e')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
129
130
    def test_empty_string(self):
4913.3.8 by John Arbash Meinel
Rename test_bencode to test__bencode, and use self.module
131
        self.assertRaises(ValueError, self.module.bdecode, '')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
132
133
    def test_junk(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
134
        self._run_check_error(ValueError, 'i6easd')
135
        self._run_check_error(ValueError, '2:abfdjslhfld')
136
        self._run_check_error(ValueError, '0:0:')
137
        self._run_check_error(ValueError, 'leanfdldjfh')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
138
139
    def test_unknown_object(self):
4913.3.8 by John Arbash Meinel
Rename test_bencode to test__bencode, and use self.module
140
        self.assertRaises(ValueError, self.module.bdecode, 'relwjhrlewjh')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
141
2694.5.8 by Jelmer Vernooij
Use standard infrastructure for testing python and pyrex bencode implementations.
142
    def test_unsupported_type(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
143
        self._run_check_error(TypeError, float(1.5))
144
        self._run_check_error(TypeError, None)
145
        self._run_check_error(TypeError, lambda x: x)
146
        self._run_check_error(TypeError, object)
147
        self._run_check_error(TypeError, u"ie")
2694.5.9 by Jelmer Vernooij
Fix tests.
148
149
    def test_decoder_type_error(self):
4913.3.8 by John Arbash Meinel
Rename test_bencode to test__bencode, and use self.module
150
        self.assertRaises(TypeError, self.module.bdecode, 1)
2694.5.8 by Jelmer Vernooij
Use standard infrastructure for testing python and pyrex bencode implementations.
151
152
153
class TestBencodeEncode(tests.TestCase):
154
4913.3.8 by John Arbash Meinel
Rename test_bencode to test__bencode, and use self.module
155
    module = None
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
156
157
    def _check(self, expected, source):
4913.3.8 by John Arbash Meinel
Rename test_bencode to test__bencode, and use self.module
158
        self.assertEquals(expected, self.module.bencode(source))
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
159
160
    def test_int(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
161
        self._check('i4e', 4)
162
        self._check('i0e', 0)
163
        self._check('i-10e', -10)
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
164
165
    def test_long(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
166
        self._check('i12345678901234567890e', 12345678901234567890L)
167
        self._check('i-12345678901234567890e', -12345678901234567890L)
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
168
169
    def test_string(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
170
        self._check('0:', '')
171
        self._check('3:abc', 'abc')
172
        self._check('10:1234567890', '1234567890')
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
173
174
    def test_list(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
175
        self._check('le', [])
176
        self._check('li1ei2ei3ee', [1, 2, 3])
177
        self._check('ll5:Alice3:Bobeli2ei3eee', [['Alice', 'Bob'], [2, 3]])
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
178
2694.5.5 by Jelmer Vernooij
Support bdecode_as_tuple.
179
    def test_list_as_tuple(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
180
        self._check('le', ())
181
        self._check('li1ei2ei3ee', (1, 2, 3))
182
        self._check('ll5:Alice3:Bobeli2ei3eee', (('Alice', 'Bob'), (2, 3)))
2694.5.5 by Jelmer Vernooij
Support bdecode_as_tuple.
183
2694.5.20 by Jelmer Vernooij
add handling of deep nesting.
184
    def test_list_deep_nested(self):
185
        top = []
186
        l = top
187
        for i in range(10000):
188
            l.append([])
189
            l = l[0]
4913.3.8 by John Arbash Meinel
Rename test_bencode to test__bencode, and use self.module
190
        self.assertRaises(RuntimeError, self.module.bencode, 
2694.5.20 by Jelmer Vernooij
add handling of deep nesting.
191
            top)
192
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
193
    def test_dict(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
194
        self._check('de', {})
195
        self._check('d3:agei25e4:eyes4:bluee', {'age': 25, 'eyes': 'blue'})
196
        self._check('d8:spam.mp3d6:author5:Alice6:lengthi100000eee',
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
197
                            {'spam.mp3': {'author': 'Alice',
198
                                          'length': 100000}})
199
2694.5.20 by Jelmer Vernooij
add handling of deep nesting.
200
    def test_dict_deep_nested(self):
201
        d = top = {}
202
        for i in range(10000):
203
            d[''] = {}
204
            d = d['']
4913.3.8 by John Arbash Meinel
Rename test_bencode to test__bencode, and use self.module
205
        self.assertRaises(RuntimeError, self.module.bencode, 
2694.5.20 by Jelmer Vernooij
add handling of deep nesting.
206
            top)
207
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
208
    def test_bencached(self):
4913.3.8 by John Arbash Meinel
Rename test_bencode to test__bencode, and use self.module
209
        self._check('i3e', self.module.Bencached(self.module.bencode(3)))
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
210
211
    def test_invalid_dict(self):
4913.3.8 by John Arbash Meinel
Rename test_bencode to test__bencode, and use self.module
212
        self.assertRaises(TypeError, self.module.bencode, {1:"foo"})
2694.5.1 by Alexander Belchenko
pyrex bencode (without benchmarks)
213
214
    def test_bool(self):
2694.5.16 by Jelmer Vernooij
Simplify the code a bit more.
215
        self._check('i1e', True)
216
        self._check('i0e', False)
2694.5.10 by Jelmer Vernooij
Add some more tests.
217