1
# Copyright (C) 2007 Canonical Ltd
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.
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.
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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
"""Tests for bencode structured encoding"""
19
from bzrlib.tests import TestCase, Feature
21
from bzrlib import bencode as bencode_default
22
from bzrlib.util import bencode as bencode_py
24
from bzrlib import _bencode_c as bencode_c
29
class _BencodeCFeature(Feature):
32
return bencode_c is not None
34
def feature_name(self):
35
return 'bzrlib._bencode_c'
37
BencodeCFeature = _BencodeCFeature()
40
class TestBencodeDecode(TestCase):
42
bencode = bencode_default
44
def _check(self, expected, source):
45
self.assertEquals(expected, self.bencode.bdecode(source))
47
def _run_check(self, pairs):
48
"""Run _check for each (expected, source) in pairs list"""
49
for expected, source in pairs:
50
self._check(expected, source)
52
def _check_error(self, x):
53
self.assertRaises(ValueError, self.bencode.bdecode, x)
55
def _run_check_error(self, bads):
56
"""Run _check_error for each x in bads list"""
61
self._run_check([(0, 'i0e'),
63
(123456789, 'i123456789e'),
67
self._run_check([(12345678901234567890L, 'i12345678901234567890e'),
68
(-12345678901234567890L, 'i-12345678901234567890e')])
70
def test_malformed_int(self):
71
self._run_check_error(['ie', 'i-e',
72
'i-0e', 'i00e', 'i01e', 'i-03e',
76
def test_string(self):
77
self._run_check([('', '0:'),
79
('1234567890', '10:1234567890')])
81
def test_malformed_string(self):
82
self._run_check_error(['10:x', '10:', '10',
84
'35208734823ljdahflajhdf'])
89
(['', '', ''], 'l0:0:0:e'),
90
([1, 2, 3], 'li1ei2ei3ee'),
91
(['asd', 'xy'], 'l3:asd2:xye'),
92
([['Alice', 'Bob'], [2, 3]],
93
'll5:Alice3:Bobeli2ei3eee'),
96
def test_malformed_list(self):
97
self._run_check_error(['l', 'l01:ae', 'l0:', 'li1e', 'l-3:e'])
100
self._run_check([({}, 'de'),
102
({'age': 25, 'eyes': 'blue'},
103
'd3:agei25e4:eyes4:bluee'),
104
({'spam.mp3': {'author': 'Alice', 'length': 100000}},
105
'd8:spam.mp3d6:author5:Alice6:lengthi100000eee')])
107
def test_malformed_dict(self):
108
self._run_check_error(['d', 'defoobar',
109
'd3:fooe', 'di1e0:e',
114
def test_empty_string(self):
115
self._check_error('')
118
self._run_check_error(['i6easd', '2:abfdjslhfld',
119
'0:0:', 'leanfdldjfh'])
121
def test_unknown_object(self):
122
self._check_error('relwjhrlewjh')
125
class TestBencodeEncode(TestCase):
127
bencode = bencode_default
129
def _check(self, expected, source):
130
self.assertEquals(expected, self.bencode.bencode(source))
132
def _run_check(self, pairs):
133
for expected, source in pairs:
134
self._check(expected, source)
136
def _check_error(self, x):
137
self.assertRaises(TypeError, self.bencode.bencode, x)
140
self._run_check([('i4e', 4),
145
self._run_check([('i12345678901234567890e', 12345678901234567890L),
146
('i-12345678901234567890e', -12345678901234567890L)])
148
def test_string(self):
149
self._run_check([('0:', ''),
151
('10:1234567890', '1234567890')])
154
self._run_check([('le', []),
155
('li1ei2ei3ee', [1, 2, 3]),
156
('ll5:Alice3:Bobeli2ei3eee',
157
[['Alice', 'Bob'], [2, 3]])
161
self._run_check([('de', {}),
162
('d3:agei25e4:eyes4:bluee',
163
{'age': 25, 'eyes': 'blue'}),
164
('d8:spam.mp3d6:author5:Alice6:lengthi100000eee',
165
{'spam.mp3': {'author': 'Alice',
169
def test_bencached(self):
170
self._check('i3e', self.bencode.Bencached(self.bencode.bencode(3)))
172
def test_invalid_dict(self):
173
self._check_error({1: 'foo'})
176
self._run_check([('i1e', True),
180
class TestBencodePyDecode(TestBencodeDecode):
184
class TestBencodePyEncode(TestBencodeEncode):
188
class TestBencodeCDecode(TestBencodeDecode):
189
_test_needs_features = [BencodeCFeature]
193
class TestBencodeCEncode(TestBencodeEncode):
194
_test_needs_features = [BencodeCFeature]
197
def test_unsupported_type(self):
198
self._check_error(float(1.5))
199
self._check_error(None)
200
self._check_error(lambda x: x)
201
self._check_error(object)
204
class TestBencodeC(TestCase):
206
_test_needs_features = [BencodeCFeature]
208
def test_decoder_repr(self):
209
self.assertEquals("Decoder('123')", repr(bencode_c.Decoder('123')))
211
def test_decoder_type_error(self):
212
self.assertRaises(TypeError, bencode_c.Decoder, 1)
214
def test_encoder_buffer_overflow(self):
215
e = bencode_c.Encoder(256)
217
for i in '1234567890':
220
shouldbe.extend(('124:', s))
221
self.assertEquals(1280, len(str(e)))
222
self.assertEquals(2048, e.maxsize)
223
self.assertEquals(''.join(shouldbe), str(e))
225
def test_encoder_buffer_overflow2(self):
226
e = bencode_c.Encoder(4)
227
e.process('1234567890')
228
self.assertEquals(64, e.maxsize)
229
self.assertEquals('10:1234567890', str(e))