1
# Copyright (C) 2010 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
"""Direct tests of the btree serializer extension"""
22
from bzrlib import tests
24
from bzrlib.tests.test_btree_index import compiled_btreeparser_feature
27
class TestBtreeSerializer(tests.TestCase):
29
_test_needs_features = [compiled_btreeparser_feature]
32
super(TestBtreeSerializer, self).setUp()
33
self.module = compiled_btreeparser_feature.module
36
class TestHexAndUnhex(TestBtreeSerializer):
38
def assertHexlify(self, as_binary):
39
self.assertEqual(binascii.hexlify(as_binary),
40
self.module._test_hexlify(as_binary))
42
def assertUnhexlify(self, as_hex):
43
ba_unhex = binascii.unhexlify(as_hex)
44
mod_unhex = self.module._test_unhexlify(as_hex)
45
if ba_unhex != mod_unhex:
49
mod_hex = binascii.hexlify(mod_unhex)
50
self.fail('_test_unhexlify returned a different answer'
51
' from binascii:\n %s\n != %s'
52
% (binascii.hexlify(ba_unhex), mod_hex))
54
def assertFailUnhexlify(self, as_hex):
56
self.assertIs(None, self.module._test_unhexlify(as_hex))
58
def test_to_hex(self):
59
raw_bytes = ''.join(map(chr, range(256)))
60
for i in range(0, 240, 20):
61
self.assertHexlify(raw_bytes[i:i+20])
62
self.assertHexlify(raw_bytes[240:]+raw_bytes[0:4])
64
def test_from_hex(self):
65
self.assertUnhexlify('0123456789abcdef0123456789abcdef01234567')
66
self.assertUnhexlify('123456789abcdef0123456789abcdef012345678')
67
self.assertUnhexlify('0123456789ABCDEF0123456789ABCDEF01234567')
68
self.assertUnhexlify('123456789ABCDEF0123456789ABCDEF012345678')
69
hex_chars = binascii.hexlify(''.join(map(chr, range(256))))
70
for i in range(0, 480, 40):
71
self.assertUnhexlify(hex_chars[i:i+40])
72
self.assertUnhexlify(hex_chars[480:]+hex_chars[0:8])
74
def test_from_invalid_hex(self):
75
self.assertFailUnhexlify('123456789012345678901234567890123456789X')
76
self.assertFailUnhexlify('12345678901234567890123456789012345678X9')
79
_hex_form = '123456789012345678901234567890abcdefabcd'
81
class Test_KeyToSha1(TestBtreeSerializer):
83
def assertKeyToSha1(self, expected, key):
87
expected_bin = binascii.unhexlify(expected)
88
actual_sha1 = self.module._test_key_to_sha1(key)
89
if expected_bin != actual_sha1:
90
actual_hex_sha1 = None
91
if actual_sha1 is not None:
92
actual_hex_sha1 = binascii.hexlify(actual_sha1)
93
self.fail('_key_to_sha1 returned:\n %s\n != %s'
94
% (actual_sha1, expected))
96
def test_simple(self):
97
self.assertKeyToSha1(_hex_form, ('sha1:' + _hex_form,))
99
def test_invalid_not_tuple(self):
100
self.assertKeyToSha1(None, _hex_form)
101
self.assertKeyToSha1(None, 'sha1:' + _hex_form)
103
def test_invalid_empty(self):
104
self.assertKeyToSha1(None, ())
106
def test_invalid_not_string(self):
107
self.assertKeyToSha1(None, (None,))
108
self.assertKeyToSha1(None, (list(_hex_form),))
110
def test_invalid_not_sha1(self):
111
self.assertKeyToSha1(None, (_hex_form,))
112
self.assertKeyToSha1(None, ('sha2:' + _hex_form,))
114
def test_invalid_not_hex(self):
115
self.assertKeyToSha1(None,
116
('sha1:abcdefghijklmnopqrstuvwxyz12345678901234',))
119
class Test_Sha1ToKey(TestBtreeSerializer):
121
def assertSha1ToKey(self, hex_sha1):
122
bin_sha1 = binascii.unhexlify(hex_sha1)
123
key = self.module._test_sha1_to_key(bin_sha1)
124
self.assertEqual(('sha1:' + hex_sha1,), key)
126
def test_simple(self):
127
self.assertSha1ToKey(_hex_form)
130
_one_key_content = """type=leaf
131
sha1:123456789012345678901234567890abcdefabcd\x00\x001 2 3 4
134
_large_offsets = """type=leaf
135
sha1:123456789012345678901234567890abcdefabcd\x00\x0012345678901 1234567890 0 1
136
sha1:abcd123456789012345678901234567890abcdef\x00\x002147483648 2147483647 0 1
137
sha1:abcdefabcd123456789012345678901234567890\x00\x004294967296 4294967295 4294967294 1
140
_multi_key_content = """type=leaf
141
sha1:70c881d4a26984ddce795f6f71817c9cf4480e79\x00\x000 0 0 0
142
sha1:7e240de74fb1ed08fa08d38063f6a6a91462a815\x00\x001 1 1 1
143
sha1:86f7e437faa5a7fce15d1ddcb9eaeaea377667b8\x00\x002 2 2 2
144
sha1:da39a3ee5e6b4b0d3255bfef95601890afd80709\x00\x003 3 3 3
145
sha1:df51e37c269aa94d38f93e537bf6e2020b21406c\x00\x004 4 4 4
146
sha1:e0c9035898dd52fc65c41454cec9c4d2611bfb37\x00\x005 5 5 5
147
sha1:e93b4e3c464ffd51732fbd6ded717e9efda28aad\x00\x006 6 6 6
148
sha1:f7a9e24777ec23212c54d7a350bc5bea5477fdbb\x00\x007 7 7 7
151
class TestGCCKHSHA1LeafNode(TestBtreeSerializer):
153
def assertInvalid(self, bytes):
154
"""Ensure that we get a proper error when trying to parse invalid bytes.
156
(mostly this is testing that bad input doesn't cause us to segfault)
158
self.assertRaises((ValueError, TypeError),
159
self.module._parse_into_chk, bytes, 1, 0)
161
def test_non_str(self):
162
self.assertInvalid(u'type=leaf\n')
164
def test_not_leaf(self):
165
self.assertInvalid('type=internal\n')
167
def test_empty_leaf(self):
168
leaf = self.module._parse_into_chk('type=leaf\n', 1, 0)
169
self.assertEqual(0, len(leaf))
170
self.assertEqual([], leaf.all_items())
171
self.assertEqual([], leaf.all_keys())
172
# It should allow any key to be queried
173
self.assertFalse(('key',) in leaf)
175
def test_one_key_leaf(self):
176
leaf = self.module._parse_into_chk(_one_key_content, 1, 0)
177
self.assertEqual(1, len(leaf))
178
sha_key = ('sha1:' + _hex_form,)
179
self.assertEqual([sha_key], leaf.all_keys())
180
self.assertEqual([(sha_key, ('1 2 3 4', ()))], leaf.all_items())
181
self.assertTrue(sha_key in leaf)
183
def test_large_offsets(self):
184
leaf = self.module._parse_into_chk(_large_offsets, 1, 0)
185
self.assertEqual(['12345678901 1234567890 0 1',
186
'2147483648 2147483647 0 1',
187
'4294967296 4294967295 4294967294 1',
188
], [x[1][0] for x in leaf.all_items()])
190
def test_many_key_leaf(self):
191
leaf = self.module._parse_into_chk(_multi_key_content, 1, 0)
192
self.assertEqual(8, len(leaf))
193
all_keys = leaf.all_keys()
194
self.assertEqual(8, len(leaf.all_keys()))
195
for idx, key in enumerate(all_keys):
196
self.assertEqual(str(idx), leaf[key][0].split()[0])