~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_bencode.py

  • Committer: Alexander Belchenko
  • Date: 2007-08-12 01:53:05 UTC
  • mto: (4398.5.1 bencode_serializer)
  • mto: This revision was merged to the branch mainline in revision 4410.
  • Revision ID: bialix@ukr.net-20070812015305-1wzsgzrf8p7jtv6j
pyrex bencode (without benchmarks)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
"""Tests for bencode structured encoding"""
 
18
 
 
19
from bzrlib.tests import TestCase, Feature
 
20
 
 
21
from bzrlib import bencode as bencode_default
 
22
from bzrlib.util import bencode as bencode_py
 
23
try:
 
24
    from bzrlib import _bencode_c as bencode_c
 
25
except ImportError:
 
26
    bencode_c = None
 
27
 
 
28
 
 
29
class _BencodeCFeature(Feature):
 
30
 
 
31
    def _probe(self):
 
32
        return bencode_c is not None
 
33
 
 
34
    def feature_name(self):
 
35
        return 'bzrlib._bencode_c'
 
36
 
 
37
BencodeCFeature = _BencodeCFeature()
 
38
 
 
39
 
 
40
class TestBencodeDecode(TestCase):
 
41
 
 
42
    bencode = bencode_default
 
43
 
 
44
    def _check(self, expected, source):
 
45
        self.assertEquals(expected, self.bencode.bdecode(source))
 
46
 
 
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)
 
51
 
 
52
    def _check_error(self, x):
 
53
        self.assertRaises(ValueError, self.bencode.bdecode, x)
 
54
 
 
55
    def _run_check_error(self, bads):
 
56
        """Run _check_error for each x in bads list"""
 
57
        for x in bads:
 
58
            self._check_error(x)
 
59
 
 
60
    def test_int(self):
 
61
        self._run_check([(0, 'i0e'),
 
62
                         (4, 'i4e'),
 
63
                         (123456789, 'i123456789e'),
 
64
                         (-10, 'i-10e')])
 
65
 
 
66
    def test_long(self):
 
67
        self._run_check([(12345678901234567890L, 'i12345678901234567890e'),
 
68
                         (-12345678901234567890L, 'i-12345678901234567890e')])
 
69
 
 
70
    def test_malformed_int(self):
 
71
        self._run_check_error(['ie', 'i-e',
 
72
                               'i-0e', 'i00e', 'i01e', 'i-03e',
 
73
                               'i', 'i123',
 
74
                               'i341foo382e'])
 
75
 
 
76
    def test_string(self):
 
77
        self._run_check([('', '0:'),
 
78
                         ('abc', '3:abc'),
 
79
                         ('1234567890', '10:1234567890')])
 
80
 
 
81
    def test_malformed_string(self):
 
82
        self._run_check_error(['10:x', '10:', '10',
 
83
                               '01:x', '00:',
 
84
                               '35208734823ljdahflajhdf'])
 
85
 
 
86
    def test_list(self):
 
87
        self._run_check([
 
88
                         ([], 'le'),
 
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'),
 
94
                        ])
 
95
 
 
96
    def test_malformed_list(self):
 
97
        self._run_check_error(['l', 'l01:ae', 'l0:', 'li1e', 'l-3:e'])
 
98
 
 
99
    def test_dict(self):
 
100
        self._run_check([({}, 'de'),
 
101
                         ({'':3}, 'd0:i3ee'),
 
102
                         ({'age': 25, 'eyes': 'blue'},
 
103
                            'd3:agei25e4:eyes4:bluee'),
 
104
                         ({'spam.mp3': {'author': 'Alice', 'length': 100000}},
 
105
                            'd8:spam.mp3d6:author5:Alice6:lengthi100000eee')])
 
106
 
 
107
    def test_malformed_dict(self):
 
108
        self._run_check_error(['d', 'defoobar',
 
109
                               'd3:fooe', 'di1e0:e',
 
110
                               'd1:b0:1:a0:e',
 
111
                               'd1:a0:1:a0:e',
 
112
                               'd0:0:', 'd0:'])
 
113
 
 
114
    def test_empty_string(self):
 
115
        self._check_error('')
 
116
 
 
117
    def test_junk(self):
 
118
        self._run_check_error(['i6easd', '2:abfdjslhfld',
 
119
                               '0:0:', 'leanfdldjfh'])
 
120
 
 
121
    def test_unknown_object(self):
 
122
        self._check_error('relwjhrlewjh')
 
123
 
 
124
 
 
125
class TestBencodeEncode(TestCase):
 
126
 
 
127
    bencode = bencode_default
 
128
 
 
129
    def _check(self, expected, source):
 
130
        self.assertEquals(expected, self.bencode.bencode(source))
 
131
 
 
132
    def _run_check(self, pairs):
 
133
        for expected, source in pairs:
 
134
            self._check(expected, source)
 
135
 
 
136
    def _check_error(self, x):
 
137
        self.assertRaises(TypeError, self.bencode.bencode, x)
 
138
 
 
139
    def test_int(self):
 
140
        self._run_check([('i4e', 4),
 
141
                         ('i0e', 0),
 
142
                         ('i-10e', -10)])
 
143
 
 
144
    def test_long(self):
 
145
        self._run_check([('i12345678901234567890e', 12345678901234567890L),
 
146
                         ('i-12345678901234567890e', -12345678901234567890L)])
 
147
 
 
148
    def test_string(self):
 
149
        self._run_check([('0:', ''),
 
150
                         ('3:abc', 'abc'),
 
151
                         ('10:1234567890', '1234567890')])
 
152
 
 
153
    def test_list(self):
 
154
        self._run_check([('le', []),
 
155
                         ('li1ei2ei3ee', [1, 2, 3]),
 
156
                         ('ll5:Alice3:Bobeli2ei3eee',
 
157
                            [['Alice', 'Bob'], [2, 3]])
 
158
                        ])
 
159
 
 
160
    def test_dict(self):
 
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',
 
166
                                          'length': 100000}})
 
167
                         ])
 
168
 
 
169
    def test_bencached(self):
 
170
        self._check('i3e', self.bencode.Bencached(self.bencode.bencode(3)))
 
171
 
 
172
    def test_invalid_dict(self):
 
173
        self._check_error({1: 'foo'})
 
174
 
 
175
    def test_bool(self):
 
176
        self._run_check([('i1e', True),
 
177
                         ('i0e', False)])
 
178
 
 
179
 
 
180
class TestBencodePyDecode(TestBencodeDecode):
 
181
    bencode = bencode_py
 
182
 
 
183
 
 
184
class TestBencodePyEncode(TestBencodeEncode):
 
185
    bencode = bencode_py
 
186
 
 
187
 
 
188
class TestBencodeCDecode(TestBencodeDecode):
 
189
    _test_needs_features = [BencodeCFeature]
 
190
    bencode = bencode_c
 
191
 
 
192
 
 
193
class TestBencodeCEncode(TestBencodeEncode):
 
194
    _test_needs_features = [BencodeCFeature]
 
195
    bencode = bencode_c
 
196
 
 
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)
 
202
 
 
203
 
 
204
class TestBencodeC(TestCase):
 
205
 
 
206
    _test_needs_features = [BencodeCFeature]
 
207
 
 
208
    def test_decoder_repr(self):
 
209
        self.assertEquals("Decoder('123')", repr(bencode_c.Decoder('123')))
 
210
 
 
211
    def test_decoder_type_error(self):
 
212
        self.assertRaises(TypeError, bencode_c.Decoder, 1)
 
213
 
 
214
    def test_encoder_buffer_overflow(self):
 
215
        e = bencode_c.Encoder(256)
 
216
        shouldbe = []
 
217
        for i in '1234567890':
 
218
            s = i * 124
 
219
            e.process(s)
 
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))
 
224
 
 
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))