17
17
"""Tests for indices."""
24
from ..sixish import int2byte
30
class ErrorTests(tests.TestCase):
32
def test_bad_index_format_signature(self):
33
error = _mod_index.BadIndexFormatSignature("foo", "bar")
34
self.assertEqual("foo is not an index of type bar.",
37
def test_bad_index_data(self):
38
error = _mod_index.BadIndexData("foo")
39
self.assertEqual("Error in data for index foo.",
42
def test_bad_index_duplicate_key(self):
43
error = _mod_index.BadIndexDuplicateKey("foo", "bar")
44
self.assertEqual("The key 'foo' is already in index 'bar'.",
47
def test_bad_index_key(self):
48
error = _mod_index.BadIndexKey("foo")
49
self.assertEqual("The key 'foo' is not a valid key.",
52
def test_bad_index_options(self):
53
error = _mod_index.BadIndexOptions("foo")
54
self.assertEqual("Could not parse options for index foo.",
57
def test_bad_index_value(self):
58
error = _mod_index.BadIndexValue("foo")
59
self.assertEqual("The value 'foo' is not a valid value.",
63
class TestGraphIndexBuilder(tests.TestCaseWithMemoryTransport):
19
from bzrlib import errors
20
from bzrlib.index import *
21
from bzrlib.tests import TestCaseWithMemoryTransport
22
from bzrlib.transport import get_transport
25
class TestGraphIndexBuilder(TestCaseWithMemoryTransport):
65
27
def test_build_index_empty(self):
66
builder = _mod_index.GraphIndexBuilder()
28
builder = GraphIndexBuilder()
67
29
stream = builder.finish()
68
30
contents = stream.read()
70
b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=0\n\n",
32
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=0\n\n",
73
35
def test_build_index_empty_two_element_keys(self):
74
builder = _mod_index.GraphIndexBuilder(key_elements=2)
36
builder = GraphIndexBuilder(key_elements=2)
75
37
stream = builder.finish()
76
38
contents = stream.read()
78
b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=0\n\n",
40
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=0\n\n",
81
43
def test_build_index_one_reference_list_empty(self):
82
builder = _mod_index.GraphIndexBuilder(reference_lists=1)
44
builder = GraphIndexBuilder(reference_lists=1)
83
45
stream = builder.finish()
84
46
contents = stream.read()
86
b"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=0\n\n",
48
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=0\n\n",
89
51
def test_build_index_two_reference_list_empty(self):
90
builder = _mod_index.GraphIndexBuilder(reference_lists=2)
52
builder = GraphIndexBuilder(reference_lists=2)
91
53
stream = builder.finish()
92
54
contents = stream.read()
94
b"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=0\n\n",
56
"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=0\n\n",
97
59
def test_build_index_one_node_no_refs(self):
98
builder = _mod_index.GraphIndexBuilder()
99
builder.add_node((b'akey', ), b'data')
60
builder = GraphIndexBuilder()
61
builder.add_node(('akey', ), 'data')
100
62
stream = builder.finish()
101
63
contents = stream.read()
103
b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
104
b"akey\x00\x00\x00data\n\n", contents)
65
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
66
"akey\x00\x00\x00data\n\n", contents)
106
68
def test_build_index_one_node_no_refs_accepts_empty_reflist(self):
107
builder = _mod_index.GraphIndexBuilder()
108
builder.add_node((b'akey', ), b'data', ())
69
builder = GraphIndexBuilder()
70
builder.add_node(('akey', ), 'data', ())
109
71
stream = builder.finish()
110
72
contents = stream.read()
112
b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
113
b"akey\x00\x00\x00data\n\n", contents)
74
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
75
"akey\x00\x00\x00data\n\n", contents)
115
77
def test_build_index_one_node_2_element_keys(self):
116
78
# multipart keys are separated by \x00 - because they are fixed length,
117
79
# not variable this does not cause any issues, and seems clearer to the
119
builder = _mod_index.GraphIndexBuilder(key_elements=2)
120
builder.add_node((b'akey', b'secondpart'), b'data')
81
builder = GraphIndexBuilder(key_elements=2)
82
builder.add_node(('akey', 'secondpart'), 'data')
121
83
stream = builder.finish()
122
84
contents = stream.read()
124
b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=1\n"
125
b"akey\x00secondpart\x00\x00\x00data\n\n", contents)
86
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=1\n"
87
"akey\x00secondpart\x00\x00\x00data\n\n", contents)
127
89
def test_add_node_empty_value(self):
128
builder = _mod_index.GraphIndexBuilder()
129
builder.add_node((b'akey', ), b'')
90
builder = GraphIndexBuilder()
91
builder.add_node(('akey', ), '')
130
92
stream = builder.finish()
131
93
contents = stream.read()
133
b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
134
b"akey\x00\x00\x00\n\n", contents)
95
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
96
"akey\x00\x00\x00\n\n", contents)
136
98
def test_build_index_nodes_sorted(self):
137
99
# the highest sorted node comes first.
138
builder = _mod_index.GraphIndexBuilder()
100
builder = GraphIndexBuilder()
139
101
# use three to have a good chance of glitching dictionary hash
140
102
# lookups etc. Insert in randomish order that is not correct
141
103
# and not the reverse of the correct order.
142
builder.add_node((b'2002', ), b'data')
143
builder.add_node((b'2000', ), b'data')
144
builder.add_node((b'2001', ), b'data')
104
builder.add_node(('2002', ), 'data')
105
builder.add_node(('2000', ), 'data')
106
builder.add_node(('2001', ), 'data')
145
107
stream = builder.finish()
146
108
contents = stream.read()
147
109
self.assertEqual(
148
b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=3\n"
149
b"2000\x00\x00\x00data\n"
150
b"2001\x00\x00\x00data\n"
151
b"2002\x00\x00\x00data\n"
110
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=3\n"
111
"2000\x00\x00\x00data\n"
112
"2001\x00\x00\x00data\n"
113
"2002\x00\x00\x00data\n"
154
116
def test_build_index_2_element_key_nodes_sorted(self):
155
117
# multiple element keys are sorted first-key, second-key.
156
builder = _mod_index.GraphIndexBuilder(key_elements=2)
118
builder = GraphIndexBuilder(key_elements=2)
157
119
# use three values of each key element, to have a good chance of
158
120
# glitching dictionary hash lookups etc. Insert in randomish order that
159
121
# is not correct and not the reverse of the correct order.
160
builder.add_node((b'2002', b'2002'), b'data')
161
builder.add_node((b'2002', b'2000'), b'data')
162
builder.add_node((b'2002', b'2001'), b'data')
163
builder.add_node((b'2000', b'2002'), b'data')
164
builder.add_node((b'2000', b'2000'), b'data')
165
builder.add_node((b'2000', b'2001'), b'data')
166
builder.add_node((b'2001', b'2002'), b'data')
167
builder.add_node((b'2001', b'2000'), b'data')
168
builder.add_node((b'2001', b'2001'), b'data')
122
builder.add_node(('2002', '2002'), 'data')
123
builder.add_node(('2002', '2000'), 'data')
124
builder.add_node(('2002', '2001'), 'data')
125
builder.add_node(('2000', '2002'), 'data')
126
builder.add_node(('2000', '2000'), 'data')
127
builder.add_node(('2000', '2001'), 'data')
128
builder.add_node(('2001', '2002'), 'data')
129
builder.add_node(('2001', '2000'), 'data')
130
builder.add_node(('2001', '2001'), 'data')
169
131
stream = builder.finish()
170
132
contents = stream.read()
171
133
self.assertEqual(
172
b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=9\n"
173
b"2000\x002000\x00\x00\x00data\n"
174
b"2000\x002001\x00\x00\x00data\n"
175
b"2000\x002002\x00\x00\x00data\n"
176
b"2001\x002000\x00\x00\x00data\n"
177
b"2001\x002001\x00\x00\x00data\n"
178
b"2001\x002002\x00\x00\x00data\n"
179
b"2002\x002000\x00\x00\x00data\n"
180
b"2002\x002001\x00\x00\x00data\n"
181
b"2002\x002002\x00\x00\x00data\n"
134
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=9\n"
135
"2000\x002000\x00\x00\x00data\n"
136
"2000\x002001\x00\x00\x00data\n"
137
"2000\x002002\x00\x00\x00data\n"
138
"2001\x002000\x00\x00\x00data\n"
139
"2001\x002001\x00\x00\x00data\n"
140
"2001\x002002\x00\x00\x00data\n"
141
"2002\x002000\x00\x00\x00data\n"
142
"2002\x002001\x00\x00\x00data\n"
143
"2002\x002002\x00\x00\x00data\n"
184
146
def test_build_index_reference_lists_are_included_one(self):
185
builder = _mod_index.GraphIndexBuilder(reference_lists=1)
186
builder.add_node((b'key', ), b'data', ([], ))
147
builder = GraphIndexBuilder(reference_lists=1)
148
builder.add_node(('key', ), 'data', ([], ))
187
149
stream = builder.finish()
188
150
contents = stream.read()
189
151
self.assertEqual(
190
b"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
191
b"key\x00\x00\x00data\n"
152
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
153
"key\x00\x00\x00data\n"
194
156
def test_build_index_reference_lists_with_2_element_keys(self):
195
builder = _mod_index.GraphIndexBuilder(
196
reference_lists=1, key_elements=2)
197
builder.add_node((b'key', b'key2'), b'data', ([], ))
157
builder = GraphIndexBuilder(reference_lists=1, key_elements=2)
158
builder.add_node(('key', 'key2'), 'data', ([], ))
198
159
stream = builder.finish()
199
160
contents = stream.read()
200
161
self.assertEqual(
201
b"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=2\nlen=1\n"
202
b"key\x00key2\x00\x00\x00data\n"
162
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=2\nlen=1\n"
163
"key\x00key2\x00\x00\x00data\n"
205
166
def test_build_index_reference_lists_are_included_two(self):
206
builder = _mod_index.GraphIndexBuilder(reference_lists=2)
207
builder.add_node((b'key', ), b'data', ([], []))
167
builder = GraphIndexBuilder(reference_lists=2)
168
builder.add_node(('key', ), 'data', ([], []))
208
169
stream = builder.finish()
209
170
contents = stream.read()
210
171
self.assertEqual(
211
b"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=1\n"
212
b"key\x00\x00\t\x00data\n"
172
"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=1\n"
173
"key\x00\x00\t\x00data\n"
215
176
def test_clear_cache(self):
216
builder = _mod_index.GraphIndexBuilder(reference_lists=2)
177
builder = GraphIndexBuilder(reference_lists=2)
217
178
# This is a no-op, but the api should exist
218
179
builder.clear_cache()
220
181
def test_node_references_are_byte_offsets(self):
221
builder = _mod_index.GraphIndexBuilder(reference_lists=1)
222
builder.add_node((b'reference', ), b'data', ([], ))
223
builder.add_node((b'key', ), b'data', ([(b'reference', )], ))
182
builder = GraphIndexBuilder(reference_lists=1)
183
builder.add_node(('reference', ), 'data', ([], ))
184
builder.add_node(('key', ), 'data', ([('reference', )], ))
224
185
stream = builder.finish()
225
186
contents = stream.read()
226
187
self.assertEqual(
227
b"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=2\n"
228
b"key\x00\x0072\x00data\n"
229
b"reference\x00\x00\x00data\n"
188
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=2\n"
189
"key\x00\x0072\x00data\n"
190
"reference\x00\x00\x00data\n"
232
193
def test_node_references_are_cr_delimited(self):
233
builder = _mod_index.GraphIndexBuilder(reference_lists=1)
234
builder.add_node((b'reference', ), b'data', ([], ))
235
builder.add_node((b'reference2', ), b'data', ([], ))
236
builder.add_node((b'key', ), b'data',
237
([(b'reference', ), (b'reference2', )], ))
194
builder = GraphIndexBuilder(reference_lists=1)
195
builder.add_node(('reference', ), 'data', ([], ))
196
builder.add_node(('reference2', ), 'data', ([], ))
197
builder.add_node(('key', ), 'data', ([('reference', ), ('reference2', )], ))
238
198
stream = builder.finish()
239
199
contents = stream.read()
240
200
self.assertEqual(
241
b"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=3\n"
242
b"key\x00\x00077\r094\x00data\n"
243
b"reference\x00\x00\x00data\n"
244
b"reference2\x00\x00\x00data\n"
201
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=3\n"
202
"key\x00\x00077\r094\x00data\n"
203
"reference\x00\x00\x00data\n"
204
"reference2\x00\x00\x00data\n"
247
207
def test_multiple_reference_lists_are_tab_delimited(self):
248
builder = _mod_index.GraphIndexBuilder(reference_lists=2)
249
builder.add_node((b'keference', ), b'data', ([], []))
250
builder.add_node((b'rey', ), b'data',
251
([(b'keference', )], [(b'keference', )]))
208
builder = GraphIndexBuilder(reference_lists=2)
209
builder.add_node(('keference', ), 'data', ([], []))
210
builder.add_node(('rey', ), 'data', ([('keference', )], [('keference', )]))
252
211
stream = builder.finish()
253
212
contents = stream.read()
254
213
self.assertEqual(
255
b"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=2\n"
256
b"keference\x00\x00\t\x00data\n"
257
b"rey\x00\x0059\t59\x00data\n"
214
"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=2\n"
215
"keference\x00\x00\t\x00data\n"
216
"rey\x00\x0059\t59\x00data\n"
260
219
def test_add_node_referencing_missing_key_makes_absent(self):
261
builder = _mod_index.GraphIndexBuilder(reference_lists=1)
262
builder.add_node((b'rey', ), b'data',
263
([(b'beference', ), (b'aeference2', )], ))
220
builder = GraphIndexBuilder(reference_lists=1)
221
builder.add_node(('rey', ), 'data', ([('beference', ), ('aeference2', )], ))
264
222
stream = builder.finish()
265
223
contents = stream.read()
266
224
self.assertEqual(
267
b"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
268
b"aeference2\x00a\x00\x00\n"
269
b"beference\x00a\x00\x00\n"
270
b"rey\x00\x00074\r059\x00data\n"
225
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
226
"aeference2\x00a\x00\x00\n"
227
"beference\x00a\x00\x00\n"
228
"rey\x00\x00074\r059\x00data\n"
273
231
def test_node_references_three_digits(self):
274
232
# test the node digit expands as needed.
275
builder = _mod_index.GraphIndexBuilder(reference_lists=1)
276
references = [((b"%d" % val), ) for val in range(8, -1, -1)]
277
builder.add_node((b'2-key', ), b'', (references, ))
233
builder = GraphIndexBuilder(reference_lists=1)
234
references = [(str(val), ) for val in reversed(range(9))]
235
builder.add_node(('2-key', ), '', (references, ))
278
236
stream = builder.finish()
279
237
contents = stream.read()
280
238
self.assertEqualDiff(
281
b"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
285
b"2-key\x00\x00151\r145\r139\r133\r127\r121\r071\r065\r059\x00\n"
239
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
243
"2-key\x00\x00151\r145\r139\r133\r127\r121\r071\r065\r059\x00\n"
294
252
def test_absent_has_no_reference_overhead(self):
295
253
# the offsets after an absent record should be correct when there are
296
254
# >1 reference lists.
297
builder = _mod_index.GraphIndexBuilder(reference_lists=2)
298
builder.add_node((b'parent', ), b'', ([(b'aail', ), (b'zther', )], []))
255
builder = GraphIndexBuilder(reference_lists=2)
256
builder.add_node(('parent', ), '', ([('aail', ), ('zther', )], []))
299
257
stream = builder.finish()
300
258
contents = stream.read()
301
259
self.assertEqual(
302
b"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=1\n"
303
b"aail\x00a\x00\x00\n"
304
b"parent\x00\x0059\r84\t\x00\n"
305
b"zther\x00a\x00\x00\n"
260
"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=1\n"
261
"aail\x00a\x00\x00\n"
262
"parent\x00\x0059\r84\t\x00\n"
263
"zther\x00a\x00\x00\n"
308
266
def test_add_node_bad_key(self):
309
builder = _mod_index.GraphIndexBuilder()
310
for bad_char in bytearray(b'\t\n\x0b\x0c\r\x00 '):
311
self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
312
(b'a%skey' % int2byte(bad_char), ), b'data')
313
self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
315
self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
316
b'not-a-tuple', b'data')
267
builder = GraphIndexBuilder()
268
for bad_char in '\t\n\x0b\x0c\r\x00 ':
269
self.assertRaises(errors.BadIndexKey, builder.add_node,
270
('a%skey' % bad_char, ), 'data')
271
self.assertRaises(errors.BadIndexKey, builder.add_node,
273
self.assertRaises(errors.BadIndexKey, builder.add_node,
274
'not-a-tuple', 'data')
317
275
# not enough length
318
self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
276
self.assertRaises(errors.BadIndexKey, builder.add_node,
321
self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
322
(b'primary', b'secondary'), b'data')
279
self.assertRaises(errors.BadIndexKey, builder.add_node,
280
('primary', 'secondary'), 'data')
323
281
# secondary key elements get checked too:
324
builder = _mod_index.GraphIndexBuilder(key_elements=2)
325
for bad_char in bytearray(b'\t\n\x0b\x0c\r\x00 '):
326
self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
327
(b'prefix', b'a%skey' % int2byte(bad_char)), b'data')
282
builder = GraphIndexBuilder(key_elements=2)
283
for bad_char in '\t\n\x0b\x0c\r\x00 ':
284
self.assertRaises(errors.BadIndexKey, builder.add_node,
285
('prefix', 'a%skey' % bad_char), 'data')
329
287
def test_add_node_bad_data(self):
330
builder = _mod_index.GraphIndexBuilder()
331
self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
333
self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
288
builder = GraphIndexBuilder()
289
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
291
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
336
294
def test_add_node_bad_mismatched_ref_lists_length(self):
337
builder = _mod_index.GraphIndexBuilder()
338
self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
340
builder = _mod_index.GraphIndexBuilder(reference_lists=1)
341
self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
343
self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
345
self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
346
b'data aa', ([], []))
347
builder = _mod_index.GraphIndexBuilder(reference_lists=2)
348
self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
350
self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
352
self.assertRaises(_mod_index.BadIndexValue, builder.add_node, (b'akey', ),
353
b'data aa', ([], [], []))
295
builder = GraphIndexBuilder()
296
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
298
builder = GraphIndexBuilder(reference_lists=1)
299
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
301
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
303
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
305
builder = GraphIndexBuilder(reference_lists=2)
306
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
308
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
310
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
311
'data aa', ([], [], []))
355
313
def test_add_node_bad_key_in_reference_lists(self):
356
314
# first list, first key - trivial
357
builder = _mod_index.GraphIndexBuilder(reference_lists=1)
358
self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
359
b'data aa', ([(b'a key', )], ))
315
builder = GraphIndexBuilder(reference_lists=1)
316
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
317
'data aa', ([('a key', )], ))
360
318
# references keys must be tuples too
361
self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
362
b'data aa', (['not-a-tuple'], ))
319
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
320
'data aa', (['not-a-tuple'], ))
363
321
# not enough length
364
self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
365
b'data aa', ([()], ))
322
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
367
self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
368
b'data aa', ([(b'primary', b'secondary')], ))
325
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
326
'data aa', ([('primary', 'secondary')], ))
369
327
# need to check more than the first key in the list
370
self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
371
b'data aa', ([(b'agoodkey', ), (b'that is a bad key', )], ))
328
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
329
'data aa', ([('agoodkey', ), ('that is a bad key', )], ))
372
330
# and if there is more than one list it should be getting checked
374
builder = _mod_index.GraphIndexBuilder(reference_lists=2)
375
self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
376
b'data aa', ([], ['a bad key']))
332
builder = GraphIndexBuilder(reference_lists=2)
333
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
334
'data aa', ([], ['a bad key']))
378
336
def test_add_duplicate_key(self):
379
builder = _mod_index.GraphIndexBuilder()
380
builder.add_node((b'key', ), b'data')
381
self.assertRaises(_mod_index.BadIndexDuplicateKey,
382
builder.add_node, (b'key', ), b'data')
337
builder = GraphIndexBuilder()
338
builder.add_node(('key', ), 'data')
339
self.assertRaises(errors.BadIndexDuplicateKey, builder.add_node, ('key', ),
384
342
def test_add_duplicate_key_2_elements(self):
385
builder = _mod_index.GraphIndexBuilder(key_elements=2)
386
builder.add_node((b'key', b'key'), b'data')
387
self.assertRaises(_mod_index.BadIndexDuplicateKey, builder.add_node,
388
(b'key', b'key'), b'data')
343
builder = GraphIndexBuilder(key_elements=2)
344
builder.add_node(('key', 'key'), 'data')
345
self.assertRaises(errors.BadIndexDuplicateKey, builder.add_node,
346
('key', 'key'), 'data')
390
348
def test_add_key_after_referencing_key(self):
391
builder = _mod_index.GraphIndexBuilder(reference_lists=1)
392
builder.add_node((b'key', ), b'data', ([(b'reference', )], ))
393
builder.add_node((b'reference', ), b'data', ([],))
349
builder = GraphIndexBuilder(reference_lists=1)
350
builder.add_node(('key', ), 'data', ([('reference', )], ))
351
builder.add_node(('reference', ), 'data', ([],))
395
353
def test_add_key_after_referencing_key_2_elements(self):
396
builder = _mod_index.GraphIndexBuilder(
397
reference_lists=1, key_elements=2)
398
builder.add_node((b'k', b'ey'), b'data',
399
([(b'reference', b'tokey')], ))
400
builder.add_node((b'reference', b'tokey'), b'data', ([],))
354
builder = GraphIndexBuilder(reference_lists=1, key_elements=2)
355
builder.add_node(('k', 'ey'), 'data', ([('reference', 'tokey')], ))
356
builder.add_node(('reference', 'tokey'), 'data', ([],))
402
358
def test_set_optimize(self):
403
builder = _mod_index.GraphIndexBuilder(
404
reference_lists=1, key_elements=2)
359
builder = GraphIndexBuilder(reference_lists=1, key_elements=2)
405
360
builder.set_optimize(for_size=True)
406
361
self.assertTrue(builder._optimize_for_size)
407
362
builder.set_optimize(for_size=False)
408
363
self.assertFalse(builder._optimize_for_size)
411
class TestGraphIndex(tests.TestCaseWithMemoryTransport):
366
class TestGraphIndex(TestCaseWithMemoryTransport):
413
368
def make_key(self, number):
414
return ((b'%d' % number) + b'X' * 100,)
369
return (str(number) + 'X'*100,)
416
371
def make_value(self, number):
417
return (b'%d' % number) + b'Y' * 100
372
return str(number) + 'Y'*100
419
374
def make_nodes(self, count=64):
420
375
# generate a big enough index that we only read some of it on a typical
421
376
# bisection lookup.
423
378
for counter in range(count):
425
(self.make_key(counter), self.make_value(counter), ()))
379
nodes.append((self.make_key(counter), self.make_value(counter), ()))
428
382
def make_index(self, ref_lists=0, key_elements=1, nodes=[]):
429
builder = _mod_index.GraphIndexBuilder(
430
ref_lists, key_elements=key_elements)
383
builder = GraphIndexBuilder(ref_lists, key_elements=key_elements)
431
384
for key, value, references in nodes:
432
385
builder.add_node(key, value, references)
433
386
stream = builder.finish()
434
trans = transport.get_transport_from_url('trace+' + self.get_url())
387
trans = get_transport('trace+' + self.get_url())
435
388
size = trans.put_file('index', stream)
436
return _mod_index.GraphIndex(trans, 'index', size)
389
return GraphIndex(trans, 'index', size)
438
391
def make_index_with_offset(self, ref_lists=0, key_elements=1, nodes=[],
440
builder = _mod_index.GraphIndexBuilder(
441
ref_lists, key_elements=key_elements)
393
builder = GraphIndexBuilder(ref_lists, key_elements=key_elements)
442
394
for key, value, references in nodes:
443
395
builder.add_node(key, value, references)
444
396
content = builder.finish().read()
445
397
size = len(content)
446
398
trans = self.get_transport()
447
trans.put_bytes('index', (b' ' * offset) + content)
448
return _mod_index.GraphIndex(trans, 'index', size, offset=offset)
399
trans.put_bytes('index', (' '*offset) + content)
400
return GraphIndex(trans, 'index', size, offset=offset)
450
402
def test_clear_cache(self):
451
403
index = self.make_index()
830
782
def test_iter_entries_references_resolved(self):
831
783
index = self.make_index(1, nodes=[
832
((b'name', ), b'data', ([(b'ref', ), (b'ref', )], )),
833
((b'ref', ), b'refdata', ([], ))])
834
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',), (b'ref',)),)),
835
(index, (b'ref', ), b'refdata', ((), ))},
836
set(index.iter_entries([(b'name',), (b'ref',)])))
784
(('name', ), 'data', ([('ref', ), ('ref', )], )),
785
(('ref', ), 'refdata', ([], ))])
786
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),('ref',)),)),
787
(index, ('ref', ), 'refdata', ((), ))]),
788
set(index.iter_entries([('name',), ('ref',)])))
838
790
def test_iter_entries_references_2_refs_resolved(self):
839
791
index = self.make_index(2, nodes=[
840
((b'name', ), b'data', ([(b'ref', )], [(b'ref', )])),
841
((b'ref', ), b'refdata', ([], []))])
842
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),), ((b'ref',),))),
843
(index, (b'ref', ), b'refdata', ((), ()))},
844
set(index.iter_entries([(b'name',), (b'ref',)])))
792
(('name', ), 'data', ([('ref', )], [('ref', )])),
793
(('ref', ), 'refdata', ([], []))])
794
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),), (('ref',),))),
795
(index, ('ref', ), 'refdata', ((), ()))]),
796
set(index.iter_entries([('name',), ('ref',)])))
846
798
def test_iteration_absent_skipped(self):
847
799
index = self.make_index(1, nodes=[
848
((b'name', ), b'data', ([(b'ref', )], ))])
849
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),))},
850
set(index.iter_all_entries()))
851
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),))},
852
set(index.iter_entries([(b'name', )])))
853
self.assertEqual([], list(index.iter_entries([(b'ref', )])))
800
(('name', ), 'data', ([('ref', )], ))])
801
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),))]),
802
set(index.iter_all_entries()))
803
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),))]),
804
set(index.iter_entries([('name', )])))
805
self.assertEqual([], list(index.iter_entries([('ref', )])))
855
807
def test_iteration_absent_skipped_2_element_keys(self):
856
808
index = self.make_index(1, key_elements=2, nodes=[
857
((b'name', b'fin'), b'data', ([(b'ref', b'erence')], ))])
858
self.assertEqual([(index, (b'name', b'fin'), b'data', (((b'ref', b'erence'),),))],
859
list(index.iter_all_entries()))
860
self.assertEqual([(index, (b'name', b'fin'), b'data', (((b'ref', b'erence'),),))],
861
list(index.iter_entries([(b'name', b'fin')])))
862
self.assertEqual([], list(index.iter_entries([(b'ref', b'erence')])))
809
(('name', 'fin'), 'data', ([('ref', 'erence')], ))])
810
self.assertEqual(set([(index, ('name', 'fin'), 'data', ((('ref', 'erence'),),))]),
811
set(index.iter_all_entries()))
812
self.assertEqual(set([(index, ('name', 'fin'), 'data', ((('ref', 'erence'),),))]),
813
set(index.iter_entries([('name', 'fin')])))
814
self.assertEqual([], list(index.iter_entries([('ref', 'erence')])))
864
816
def test_iter_all_keys(self):
865
817
index = self.make_index(1, nodes=[
866
((b'name', ), b'data', ([(b'ref', )], )),
867
((b'ref', ), b'refdata', ([], ))])
868
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),)),
869
(index, (b'ref', ), b'refdata', ((), ))},
870
set(index.iter_entries([(b'name', ), (b'ref', )])))
818
(('name', ), 'data', ([('ref', )], )),
819
(('ref', ), 'refdata', ([], ))])
820
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),
821
(index, ('ref', ), 'refdata', ((), ))]),
822
set(index.iter_entries([('name', ), ('ref', )])))
872
824
def test_iter_nothing_empty(self):
873
825
index = self.make_index()
876
828
def test_iter_missing_entry_empty(self):
877
829
index = self.make_index()
878
self.assertEqual([], list(index.iter_entries([(b'a', )])))
830
self.assertEqual([], list(index.iter_entries([('a', )])))
880
832
def test_iter_missing_entry_empty_no_size(self):
881
idx = self.make_index()
882
idx = _mod_index.GraphIndex(idx._transport, 'index', None)
883
self.assertEqual([], list(idx.iter_entries([(b'a', )])))
833
index = self.make_index()
834
index = GraphIndex(index._transport, 'index', None)
835
self.assertEqual([], list(index.iter_entries([('a', )])))
885
837
def test_iter_key_prefix_1_element_key_None(self):
886
838
index = self.make_index()
887
self.assertRaises(_mod_index.BadIndexKey, list,
888
index.iter_entries_prefix([(None, )]))
839
self.assertRaises(errors.BadIndexKey, list,
840
index.iter_entries_prefix([(None, )]))
890
842
def test_iter_key_prefix_wrong_length(self):
891
843
index = self.make_index()
892
self.assertRaises(_mod_index.BadIndexKey, list,
893
index.iter_entries_prefix([(b'foo', None)]))
844
self.assertRaises(errors.BadIndexKey, list,
845
index.iter_entries_prefix([('foo', None)]))
894
846
index = self.make_index(key_elements=2)
895
self.assertRaises(_mod_index.BadIndexKey, list,
896
index.iter_entries_prefix([(b'foo', )]))
897
self.assertRaises(_mod_index.BadIndexKey, list,
898
index.iter_entries_prefix([(b'foo', None, None)]))
847
self.assertRaises(errors.BadIndexKey, list,
848
index.iter_entries_prefix([('foo', )]))
849
self.assertRaises(errors.BadIndexKey, list,
850
index.iter_entries_prefix([('foo', None, None)]))
900
852
def test_iter_key_prefix_1_key_element_no_refs(self):
901
index = self.make_index(nodes=[
902
((b'name', ), b'data', ()),
903
((b'ref', ), b'refdata', ())])
904
self.assertEqual({(index, (b'name', ), b'data'),
905
(index, (b'ref', ), b'refdata')},
906
set(index.iter_entries_prefix([(b'name', ), (b'ref', )])))
853
index = self.make_index( nodes=[
854
(('name', ), 'data', ()),
855
(('ref', ), 'refdata', ())])
856
self.assertEqual(set([(index, ('name', ), 'data'),
857
(index, ('ref', ), 'refdata')]),
858
set(index.iter_entries_prefix([('name', ), ('ref', )])))
908
860
def test_iter_key_prefix_1_key_element_refs(self):
909
861
index = self.make_index(1, nodes=[
910
((b'name', ), b'data', ([(b'ref', )], )),
911
((b'ref', ), b'refdata', ([], ))])
912
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),)),
913
(index, (b'ref', ), b'refdata', ((), ))},
914
set(index.iter_entries_prefix([(b'name', ), (b'ref', )])))
862
(('name', ), 'data', ([('ref', )], )),
863
(('ref', ), 'refdata', ([], ))])
864
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),
865
(index, ('ref', ), 'refdata', ((), ))]),
866
set(index.iter_entries_prefix([('name', ), ('ref', )])))
916
868
def test_iter_key_prefix_2_key_element_no_refs(self):
917
869
index = self.make_index(key_elements=2, nodes=[
918
((b'name', b'fin1'), b'data', ()),
919
((b'name', b'fin2'), b'beta', ()),
920
((b'ref', b'erence'), b'refdata', ())])
921
self.assertEqual({(index, (b'name', b'fin1'), b'data'),
922
(index, (b'ref', b'erence'), b'refdata')},
923
set(index.iter_entries_prefix([(b'name', b'fin1'), (b'ref', b'erence')])))
924
self.assertEqual({(index, (b'name', b'fin1'), b'data'),
925
(index, (b'name', b'fin2'), b'beta')},
926
set(index.iter_entries_prefix([(b'name', None)])))
870
(('name', 'fin1'), 'data', ()),
871
(('name', 'fin2'), 'beta', ()),
872
(('ref', 'erence'), 'refdata', ())])
873
self.assertEqual(set([(index, ('name', 'fin1'), 'data'),
874
(index, ('ref', 'erence'), 'refdata')]),
875
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
876
self.assertEqual(set([(index, ('name', 'fin1'), 'data'),
877
(index, ('name', 'fin2'), 'beta')]),
878
set(index.iter_entries_prefix([('name', None)])))
928
880
def test_iter_key_prefix_2_key_element_refs(self):
929
881
index = self.make_index(1, key_elements=2, nodes=[
930
((b'name', b'fin1'), b'data', ([(b'ref', b'erence')], )),
931
((b'name', b'fin2'), b'beta', ([], )),
932
((b'ref', b'erence'), b'refdata', ([], ))])
933
self.assertEqual({(index, (b'name', b'fin1'), b'data', (((b'ref', b'erence'),),)),
934
(index, (b'ref', b'erence'), b'refdata', ((), ))},
935
set(index.iter_entries_prefix([(b'name', b'fin1'), (b'ref', b'erence')])))
936
self.assertEqual({(index, (b'name', b'fin1'), b'data', (((b'ref', b'erence'),),)),
937
(index, (b'name', b'fin2'), b'beta', ((), ))},
938
set(index.iter_entries_prefix([(b'name', None)])))
882
(('name', 'fin1'), 'data', ([('ref', 'erence')], )),
883
(('name', 'fin2'), 'beta', ([], )),
884
(('ref', 'erence'), 'refdata', ([], ))])
885
self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
886
(index, ('ref', 'erence'), 'refdata', ((), ))]),
887
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
888
self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
889
(index, ('name', 'fin2'), 'beta', ((), ))]),
890
set(index.iter_entries_prefix([('name', None)])))
940
892
def test_key_count_empty(self):
941
893
index = self.make_index()
942
894
self.assertEqual(0, index.key_count())
944
896
def test_key_count_one(self):
945
index = self.make_index(nodes=[((b'name', ), b'', ())])
897
index = self.make_index(nodes=[(('name', ), '', ())])
946
898
self.assertEqual(1, index.key_count())
948
900
def test_key_count_two(self):
949
901
index = self.make_index(nodes=[
950
((b'name', ), b'', ()), ((b'foo', ), b'', ())])
902
(('name', ), '', ()), (('foo', ), '', ())])
951
903
self.assertEqual(2, index.key_count())
953
905
def test_read_and_parse_tracks_real_read_value(self):
1180
1128
log.append(self._index)
1181
1129
return self._index.clear_cache()
1183
idx = _mod_index.CombinedGraphIndex([])
1184
idx1 = self.make_index('name', 0, nodes=[((b'key', ), b'', ())])
1185
idx.insert_index(0, ClearCacheProxy(idx1))
1186
idx2 = self.make_index('name', 0, nodes=[((b'key', ), b'', ())])
1187
idx.insert_index(1, ClearCacheProxy(idx2))
1131
index = CombinedGraphIndex([])
1132
index1 = self.make_index('name', 0, nodes=[(('key', ), '', ())])
1133
index.insert_index(0, ClearCacheProxy(index1))
1134
index2 = self.make_index('name', 0, nodes=[(('key', ), '', ())])
1135
index.insert_index(1, ClearCacheProxy(index2))
1188
1136
# CombinedGraphIndex should call 'clear_cache()' on all children
1190
self.assertEqual(sorted([idx1, idx2]), sorted(log))
1138
self.assertEqual(sorted([index1, index2]), sorted(log))
1192
1140
def test_iter_all_entries_empty(self):
1193
idx = _mod_index.CombinedGraphIndex([])
1194
self.assertEqual([], list(idx.iter_all_entries()))
1141
index = CombinedGraphIndex([])
1142
self.assertEqual([], list(index.iter_all_entries()))
1196
1144
def test_iter_all_entries_children_empty(self):
1197
idx1 = self.make_index('name')
1198
idx = _mod_index.CombinedGraphIndex([idx1])
1199
self.assertEqual([], list(idx.iter_all_entries()))
1145
index1 = self.make_index('name')
1146
index = CombinedGraphIndex([index1])
1147
self.assertEqual([], list(index.iter_all_entries()))
1201
1149
def test_iter_all_entries_simple(self):
1202
idx1 = self.make_index('name', nodes=[((b'name', ), b'data', ())])
1203
idx = _mod_index.CombinedGraphIndex([idx1])
1204
self.assertEqual([(idx1, (b'name', ), b'data')],
1205
list(idx.iter_all_entries()))
1150
index1 = self.make_index('name', nodes=[(('name', ), 'data', ())])
1151
index = CombinedGraphIndex([index1])
1152
self.assertEqual([(index1, ('name', ), 'data')],
1153
list(index.iter_all_entries()))
1207
1155
def test_iter_all_entries_two_indices(self):
1208
idx1 = self.make_index('name1', nodes=[((b'name', ), b'data', ())])
1209
idx2 = self.make_index('name2', nodes=[((b'2', ), b'', ())])
1210
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1211
self.assertEqual([(idx1, (b'name', ), b'data'),
1212
(idx2, (b'2', ), b'')],
1213
list(idx.iter_all_entries()))
1156
index1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
1157
index2 = self.make_index('name2', nodes=[(('2', ), '', ())])
1158
index = CombinedGraphIndex([index1, index2])
1159
self.assertEqual([(index1, ('name', ), 'data'),
1160
(index2, ('2', ), '')],
1161
list(index.iter_all_entries()))
1215
1163
def test_iter_entries_two_indices_dup_key(self):
1216
idx1 = self.make_index('name1', nodes=[((b'name', ), b'data', ())])
1217
idx2 = self.make_index('name2', nodes=[((b'name', ), b'data', ())])
1218
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1219
self.assertEqual([(idx1, (b'name', ), b'data')],
1220
list(idx.iter_entries([(b'name', )])))
1164
index1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
1165
index2 = self.make_index('name2', nodes=[(('name', ), 'data', ())])
1166
index = CombinedGraphIndex([index1, index2])
1167
self.assertEqual([(index1, ('name', ), 'data')],
1168
list(index.iter_entries([('name', )])))
1222
1170
def test_iter_all_entries_two_indices_dup_key(self):
1223
idx1 = self.make_index('name1', nodes=[((b'name', ), b'data', ())])
1224
idx2 = self.make_index('name2', nodes=[((b'name', ), b'data', ())])
1225
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1226
self.assertEqual([(idx1, (b'name', ), b'data')],
1227
list(idx.iter_all_entries()))
1171
index1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
1172
index2 = self.make_index('name2', nodes=[(('name', ), 'data', ())])
1173
index = CombinedGraphIndex([index1, index2])
1174
self.assertEqual([(index1, ('name', ), 'data')],
1175
list(index.iter_all_entries()))
1229
1177
def test_iter_key_prefix_2_key_element_refs(self):
1230
idx1 = self.make_index('1', 1, key_elements=2, nodes=[
1231
((b'name', b'fin1'), b'data', ([(b'ref', b'erence')], ))])
1232
idx2 = self.make_index('2', 1, key_elements=2, nodes=[
1233
((b'name', b'fin2'), b'beta', ([], )),
1234
((b'ref', b'erence'), b'refdata', ([], ))])
1235
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1236
self.assertEqual({(idx1, (b'name', b'fin1'), b'data',
1237
(((b'ref', b'erence'),),)),
1238
(idx2, (b'ref', b'erence'), b'refdata', ((), ))},
1239
set(idx.iter_entries_prefix([(b'name', b'fin1'),
1240
(b'ref', b'erence')])))
1241
self.assertEqual({(idx1, (b'name', b'fin1'), b'data',
1242
(((b'ref', b'erence'),),)),
1243
(idx2, (b'name', b'fin2'), b'beta', ((), ))},
1244
set(idx.iter_entries_prefix([(b'name', None)])))
1178
index1 = self.make_index('1', 1, key_elements=2, nodes=[
1179
(('name', 'fin1'), 'data', ([('ref', 'erence')], ))])
1180
index2 = self.make_index('2', 1, key_elements=2, nodes=[
1181
(('name', 'fin2'), 'beta', ([], )),
1182
(('ref', 'erence'), 'refdata', ([], ))])
1183
index = CombinedGraphIndex([index1, index2])
1184
self.assertEqual(set([(index1, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
1185
(index2, ('ref', 'erence'), 'refdata', ((), ))]),
1186
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
1187
self.assertEqual(set([(index1, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
1188
(index2, ('name', 'fin2'), 'beta', ((), ))]),
1189
set(index.iter_entries_prefix([('name', None)])))
1246
1191
def test_iter_nothing_empty(self):
1247
idx = _mod_index.CombinedGraphIndex([])
1248
self.assertEqual([], list(idx.iter_entries([])))
1192
index = CombinedGraphIndex([])
1193
self.assertEqual([], list(index.iter_entries([])))
1250
1195
def test_iter_nothing_children_empty(self):
1251
idx1 = self.make_index('name')
1252
idx = _mod_index.CombinedGraphIndex([idx1])
1253
self.assertEqual([], list(idx.iter_entries([])))
1196
index1 = self.make_index('name')
1197
index = CombinedGraphIndex([index1])
1198
self.assertEqual([], list(index.iter_entries([])))
1255
1200
def test_iter_all_keys(self):
1256
idx1 = self.make_index('1', 1, nodes=[((b'name', ), b'data',
1258
idx2 = self.make_index(
1259
'2', 1, nodes=[((b'ref', ), b'refdata', ((), ))])
1260
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1261
self.assertEqual({(idx1, (b'name', ), b'data', (((b'ref', ), ), )),
1262
(idx2, (b'ref', ), b'refdata', ((), ))},
1263
set(idx.iter_entries([(b'name', ), (b'ref', )])))
1201
index1 = self.make_index('1', 1, nodes=[
1202
(('name', ), 'data', ([('ref', )], ))])
1203
index2 = self.make_index('2', 1, nodes=[
1204
(('ref', ), 'refdata', ((), ))])
1205
index = CombinedGraphIndex([index1, index2])
1206
self.assertEqual(set([(index1, ('name', ), 'data', ((('ref', ), ), )),
1207
(index2, ('ref', ), 'refdata', ((), ))]),
1208
set(index.iter_entries([('name', ), ('ref', )])))
1265
1210
def test_iter_all_keys_dup_entry(self):
1266
idx1 = self.make_index('1', 1, nodes=[((b'name', ), b'data',
1268
((b'ref', ), b'refdata', ([], ))])
1269
idx2 = self.make_index(
1270
'2', 1, nodes=[((b'ref', ), b'refdata', ([], ))])
1271
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1272
self.assertEqual({(idx1, (b'name', ), b'data', (((b'ref',),),)),
1273
(idx1, (b'ref', ), b'refdata', ((), ))},
1274
set(idx.iter_entries([(b'name', ), (b'ref', )])))
1211
index1 = self.make_index('1', 1, nodes=[
1212
(('name', ), 'data', ([('ref', )], )),
1213
(('ref', ), 'refdata', ([], ))])
1214
index2 = self.make_index('2', 1, nodes=[
1215
(('ref', ), 'refdata', ([], ))])
1216
index = CombinedGraphIndex([index1, index2])
1217
self.assertEqual(set([(index1, ('name', ), 'data', ((('ref',),),)),
1218
(index1, ('ref', ), 'refdata', ((), ))]),
1219
set(index.iter_entries([('name', ), ('ref', )])))
1276
1221
def test_iter_missing_entry_empty(self):
1277
idx = _mod_index.CombinedGraphIndex([])
1278
self.assertEqual([], list(idx.iter_entries([('a', )])))
1222
index = CombinedGraphIndex([])
1223
self.assertEqual([], list(index.iter_entries([('a', )])))
1280
1225
def test_iter_missing_entry_one_index(self):
1281
idx1 = self.make_index('1')
1282
idx = _mod_index.CombinedGraphIndex([idx1])
1283
self.assertEqual([], list(idx.iter_entries([(b'a', )])))
1226
index1 = self.make_index('1')
1227
index = CombinedGraphIndex([index1])
1228
self.assertEqual([], list(index.iter_entries([('a', )])))
1285
1230
def test_iter_missing_entry_two_index(self):
1286
idx1 = self.make_index('1')
1287
idx2 = self.make_index('2')
1288
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1289
self.assertEqual([], list(idx.iter_entries([('a', )])))
1231
index1 = self.make_index('1')
1232
index2 = self.make_index('2')
1233
index = CombinedGraphIndex([index1, index2])
1234
self.assertEqual([], list(index.iter_entries([('a', )])))
1291
1236
def test_iter_entry_present_one_index_only(self):
1292
idx1 = self.make_index('1', nodes=[((b'key', ), b'', ())])
1293
idx2 = self.make_index('2', nodes=[])
1294
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1295
self.assertEqual([(idx1, (b'key', ), b'')],
1296
list(idx.iter_entries([(b'key', )])))
1237
index1 = self.make_index('1', nodes=[(('key', ), '', ())])
1238
index2 = self.make_index('2', nodes=[])
1239
index = CombinedGraphIndex([index1, index2])
1240
self.assertEqual([(index1, ('key', ), '')],
1241
list(index.iter_entries([('key', )])))
1297
1242
# and in the other direction
1298
idx = _mod_index.CombinedGraphIndex([idx2, idx1])
1299
self.assertEqual([(idx1, (b'key', ), b'')],
1300
list(idx.iter_entries([(b'key', )])))
1243
index = CombinedGraphIndex([index2, index1])
1244
self.assertEqual([(index1, ('key', ), '')],
1245
list(index.iter_entries([('key', )])))
1302
1247
def test_key_count_empty(self):
1303
idx1 = self.make_index('1', nodes=[])
1304
idx2 = self.make_index('2', nodes=[])
1305
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1306
self.assertEqual(0, idx.key_count())
1248
index1 = self.make_index('1', nodes=[])
1249
index2 = self.make_index('2', nodes=[])
1250
index = CombinedGraphIndex([index1, index2])
1251
self.assertEqual(0, index.key_count())
1308
1253
def test_key_count_sums_index_keys(self):
1309
idx1 = self.make_index('1', nodes=[
1311
((b'2',), b'', ())])
1312
idx2 = self.make_index('2', nodes=[((b'1',), b'', ())])
1313
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1314
self.assertEqual(3, idx.key_count())
1254
index1 = self.make_index('1', nodes=[
1257
index2 = self.make_index('2', nodes=[(('1',), '', ())])
1258
index = CombinedGraphIndex([index1, index2])
1259
self.assertEqual(3, index.key_count())
1316
1261
def test_validate_bad_child_index_errors(self):
1317
1262
trans = self.get_transport()
1318
trans.put_bytes('name', b"not an index\n")
1319
idx1 = _mod_index.GraphIndex(trans, 'name', 13)
1320
idx = _mod_index.CombinedGraphIndex([idx1])
1321
self.assertRaises(_mod_index.BadIndexFormatSignature, idx.validate)
1263
trans.put_bytes('name', "not an index\n")
1264
index1 = GraphIndex(trans, 'name', 13)
1265
index = CombinedGraphIndex([index1])
1266
self.assertRaises(errors.BadIndexFormatSignature, index.validate)
1323
1268
def test_validate_empty(self):
1324
idx = _mod_index.CombinedGraphIndex([])
1269
index = CombinedGraphIndex([])
1327
1272
def test_key_count_reloads(self):
1328
idx, reload_counter = self.make_combined_index_with_missing()
1329
self.assertEqual(2, idx.key_count())
1273
index, reload_counter = self.make_combined_index_with_missing()
1274
self.assertEqual(2, index.key_count())
1330
1275
self.assertEqual([1, 1, 0], reload_counter)
1332
1277
def test_key_count_no_reload(self):
1333
idx, reload_counter = self.make_combined_index_with_missing()
1334
idx._reload_func = None
1278
index, reload_counter = self.make_combined_index_with_missing()
1279
index._reload_func = None
1335
1280
# Without a _reload_func we just raise the exception
1336
self.assertRaises(errors.NoSuchFile, idx.key_count)
1281
self.assertRaises(errors.NoSuchFile, index.key_count)
1338
1283
def test_key_count_reloads_and_fails(self):
1339
1284
# We have deleted all underlying indexes, so we will try to reload, but
1340
1285
# still fail. This is mostly to test we don't get stuck in an infinite
1341
1286
# loop trying to reload
1342
idx, reload_counter = self.make_combined_index_with_missing(
1344
self.assertRaises(errors.NoSuchFile, idx.key_count)
1287
index, reload_counter = self.make_combined_index_with_missing(
1289
self.assertRaises(errors.NoSuchFile, index.key_count)
1345
1290
self.assertEqual([2, 1, 1], reload_counter)
1347
1292
def test_iter_entries_reloads(self):
1348
1293
index, reload_counter = self.make_combined_index_with_missing()
1349
result = list(index.iter_entries([(b'1',), (b'2',), (b'3',)]))
1294
result = list(index.iter_entries([('1',), ('2',), ('3',)]))
1350
1295
index3 = index._indices[0]
1351
self.assertEqual({(index3, (b'1',), b''), (index3, (b'2',), b'')},
1296
self.assertEqual([(index3, ('1',), ''), (index3, ('2',), '')],
1353
1298
self.assertEqual([1, 1, 0], reload_counter)
1355
1300
def test_iter_entries_reloads_midway(self):
1522
1468
self.assertEqual(set(), missing_keys)
1524
1470
def test_find_ancestors_missing_keys(self):
1529
1475
index1 = self.make_index('12', ref_lists=1, nodes=[
1530
(key1, b'value', ([],)),
1531
(key2, b'value', ([key1],)),
1476
(key1, 'value', ([],)),
1477
(key2, 'value', ([key1],)),
1533
1479
index2 = self.make_index('34', ref_lists=1, nodes=[
1534
(key3, b'value', ([key2],)),
1480
(key3, 'value', ([key2],)),
1536
c_index = _mod_index.CombinedGraphIndex([index1, index2])
1482
c_index = CombinedGraphIndex([index1, index2])
1537
1483
# Searching for a key which is actually not present at all should
1538
1484
# eventually converge
1539
1485
parent_map, missing_keys = c_index.find_ancestry([key4], 0)
1540
1486
self.assertEqual({}, parent_map)
1541
self.assertEqual({key4}, missing_keys)
1487
self.assertEqual(set([key4]), missing_keys)
1543
1489
def test_find_ancestors_no_indexes(self):
1544
c_index = _mod_index.CombinedGraphIndex([])
1490
c_index = CombinedGraphIndex([])
1546
1492
parent_map, missing_keys = c_index.find_ancestry([key1], 0)
1547
1493
self.assertEqual({}, parent_map)
1548
self.assertEqual({key1}, missing_keys)
1494
self.assertEqual(set([key1]), missing_keys)
1550
1496
def test_find_ancestors_ghost_parent(self):
1555
1501
index1 = self.make_index('12', ref_lists=1, nodes=[
1556
(key1, b'value', ([],)),
1557
(key2, b'value', ([key1],)),
1502
(key1, 'value', ([],)),
1503
(key2, 'value', ([key1],)),
1559
1505
index2 = self.make_index('34', ref_lists=1, nodes=[
1560
(key4, b'value', ([key2, key3],)),
1506
(key4, 'value', ([key2, key3],)),
1562
c_index = _mod_index.CombinedGraphIndex([index1, index2])
1508
c_index = CombinedGraphIndex([index1, index2])
1563
1509
# Searching for a key which is actually not present at all should
1564
1510
# eventually converge
1565
1511
parent_map, missing_keys = c_index.find_ancestry([key4], 0)
1566
1512
self.assertEqual({key4: (key2, key3), key2: (key1,), key1: ()},
1568
self.assertEqual({key3}, missing_keys)
1514
self.assertEqual(set([key3]), missing_keys)
1570
1516
def test__find_ancestors_empty_index(self):
1571
idx = self.make_index('test', ref_lists=1, key_elements=1, nodes=[])
1517
index = self.make_index('test', ref_lists=1, key_elements=1, nodes=[])
1572
1518
parent_map = {}
1573
1519
missing_keys = set()
1574
search_keys = idx._find_ancestors([(b'one',), (b'two',)], 0, parent_map,
1520
search_keys = index._find_ancestors([('one',), ('two',)], 0, parent_map,
1576
1522
self.assertEqual(set(), search_keys)
1577
1523
self.assertEqual({}, parent_map)
1578
self.assertEqual({(b'one',), (b'two',)}, missing_keys)
1581
class TestInMemoryGraphIndex(tests.TestCaseWithMemoryTransport):
1524
self.assertEqual(set([('one',), ('two',)]), missing_keys)
1527
class TestInMemoryGraphIndex(TestCaseWithMemoryTransport):
1583
1529
def make_index(self, ref_lists=0, key_elements=1, nodes=[]):
1584
result = _mod_index.InMemoryGraphIndex(
1585
ref_lists, key_elements=key_elements)
1530
result = InMemoryGraphIndex(ref_lists, key_elements=key_elements)
1586
1531
result.add_nodes(nodes)
1589
1534
def test_add_nodes_no_refs(self):
1590
1535
index = self.make_index(0)
1591
index.add_nodes([((b'name', ), b'data')])
1592
index.add_nodes([((b'name2', ), b''), ((b'name3', ), b'')])
1594
(index, (b'name', ), b'data'),
1595
(index, (b'name2', ), b''),
1596
(index, (b'name3', ), b''),
1597
}, set(index.iter_all_entries()))
1536
index.add_nodes([(('name', ), 'data')])
1537
index.add_nodes([(('name2', ), ''), (('name3', ), '')])
1538
self.assertEqual(set([
1539
(index, ('name', ), 'data'),
1540
(index, ('name2', ), ''),
1541
(index, ('name3', ), ''),
1542
]), set(index.iter_all_entries()))
1599
1544
def test_add_nodes(self):
1600
1545
index = self.make_index(1)
1601
index.add_nodes([((b'name', ), b'data', ([],))])
1602
index.add_nodes([((b'name2', ), b'', ([],)),
1603
((b'name3', ), b'', ([(b'r', )],))])
1605
(index, (b'name', ), b'data', ((),)),
1606
(index, (b'name2', ), b'', ((),)),
1607
(index, (b'name3', ), b'', (((b'r', ), ), )),
1608
}, set(index.iter_all_entries()))
1546
index.add_nodes([(('name', ), 'data', ([],))])
1547
index.add_nodes([(('name2', ), '', ([],)), (('name3', ), '', ([('r', )],))])
1548
self.assertEqual(set([
1549
(index, ('name', ), 'data', ((),)),
1550
(index, ('name2', ), '', ((),)),
1551
(index, ('name3', ), '', ((('r', ), ), )),
1552
]), set(index.iter_all_entries()))
1610
1554
def test_iter_all_entries_empty(self):
1611
1555
index = self.make_index()
1612
1556
self.assertEqual([], list(index.iter_all_entries()))
1614
1558
def test_iter_all_entries_simple(self):
1615
index = self.make_index(nodes=[((b'name', ), b'data')])
1616
self.assertEqual([(index, (b'name', ), b'data')],
1617
list(index.iter_all_entries()))
1559
index = self.make_index(nodes=[(('name', ), 'data')])
1560
self.assertEqual([(index, ('name', ), 'data')],
1561
list(index.iter_all_entries()))
1619
1563
def test_iter_all_entries_references(self):
1620
1564
index = self.make_index(1, nodes=[
1621
((b'name', ), b'data', ([(b'ref', )], )),
1622
((b'ref', ), b'refdata', ([], ))])
1623
self.assertEqual({(index, (b'name', ), b'data', (((b'ref', ),),)),
1624
(index, (b'ref', ), b'refdata', ((), ))},
1625
set(index.iter_all_entries()))
1565
(('name', ), 'data', ([('ref', )], )),
1566
(('ref', ), 'refdata', ([], ))])
1567
self.assertEqual(set([(index, ('name', ), 'data', ((('ref', ),),)),
1568
(index, ('ref', ), 'refdata', ((), ))]),
1569
set(index.iter_all_entries()))
1627
1571
def test_iteration_absent_skipped(self):
1628
1572
index = self.make_index(1, nodes=[
1629
((b'name', ), b'data', ([(b'ref', )], ))])
1630
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),))},
1631
set(index.iter_all_entries()))
1632
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),))},
1633
set(index.iter_entries([(b'name', )])))
1634
self.assertEqual([], list(index.iter_entries([(b'ref', )])))
1573
(('name', ), 'data', ([('ref', )], ))])
1574
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),))]),
1575
set(index.iter_all_entries()))
1576
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),))]),
1577
set(index.iter_entries([('name', )])))
1578
self.assertEqual([], list(index.iter_entries([('ref', )])))
1636
1580
def test_iter_all_keys(self):
1637
1581
index = self.make_index(1, nodes=[
1638
((b'name', ), b'data', ([(b'ref', )], )),
1639
((b'ref', ), b'refdata', ([], ))])
1640
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),)),
1641
(index, (b'ref', ), b'refdata', ((), ))},
1642
set(index.iter_entries([(b'name', ), (b'ref', )])))
1582
(('name', ), 'data', ([('ref', )], )),
1583
(('ref', ), 'refdata', ([], ))])
1584
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),
1585
(index, ('ref', ), 'refdata', ((), ))]),
1586
set(index.iter_entries([('name', ), ('ref', )])))
1644
1588
def test_iter_key_prefix_1_key_element_no_refs(self):
1645
index = self.make_index(nodes=[
1646
((b'name', ), b'data'),
1647
((b'ref', ), b'refdata')])
1648
self.assertEqual({(index, (b'name', ), b'data'),
1649
(index, (b'ref', ), b'refdata')},
1650
set(index.iter_entries_prefix([(b'name', ), (b'ref', )])))
1589
index = self.make_index( nodes=[
1590
(('name', ), 'data'),
1591
(('ref', ), 'refdata')])
1592
self.assertEqual(set([(index, ('name', ), 'data'),
1593
(index, ('ref', ), 'refdata')]),
1594
set(index.iter_entries_prefix([('name', ), ('ref', )])))
1652
1596
def test_iter_key_prefix_1_key_element_refs(self):
1653
1597
index = self.make_index(1, nodes=[
1654
((b'name', ), b'data', ([(b'ref', )], )),
1655
((b'ref', ), b'refdata', ([], ))])
1656
self.assertEqual({(index, (b'name', ), b'data', (((b'ref',),),)),
1657
(index, (b'ref', ), b'refdata', ((), ))},
1658
set(index.iter_entries_prefix([(b'name', ), (b'ref', )])))
1598
(('name', ), 'data', ([('ref', )], )),
1599
(('ref', ), 'refdata', ([], ))])
1600
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),
1601
(index, ('ref', ), 'refdata', ((), ))]),
1602
set(index.iter_entries_prefix([('name', ), ('ref', )])))
1660
1604
def test_iter_key_prefix_2_key_element_no_refs(self):
1661
1605
index = self.make_index(key_elements=2, nodes=[
1662
((b'name', b'fin1'), b'data'),
1663
((b'name', b'fin2'), b'beta'),
1664
((b'ref', b'erence'), b'refdata')])
1665
self.assertEqual({(index, (b'name', b'fin1'), b'data'),
1666
(index, (b'ref', b'erence'), b'refdata')},
1667
set(index.iter_entries_prefix([(b'name', b'fin1'), (b'ref', b'erence')])))
1668
self.assertEqual({(index, (b'name', b'fin1'), b'data'),
1669
(index, (b'name', b'fin2'), b'beta')},
1670
set(index.iter_entries_prefix([(b'name', None)])))
1606
(('name', 'fin1'), 'data'),
1607
(('name', 'fin2'), 'beta'),
1608
(('ref', 'erence'), 'refdata')])
1609
self.assertEqual(set([(index, ('name', 'fin1'), 'data'),
1610
(index, ('ref', 'erence'), 'refdata')]),
1611
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
1612
self.assertEqual(set([(index, ('name', 'fin1'), 'data'),
1613
(index, ('name', 'fin2'), 'beta')]),
1614
set(index.iter_entries_prefix([('name', None)])))
1672
1616
def test_iter_key_prefix_2_key_element_refs(self):
1673
1617
index = self.make_index(1, key_elements=2, nodes=[
1674
((b'name', b'fin1'), b'data', ([(b'ref', b'erence')], )),
1675
((b'name', b'fin2'), b'beta', ([], )),
1676
((b'ref', b'erence'), b'refdata', ([], ))])
1677
self.assertEqual({(index, (b'name', b'fin1'), b'data', (((b'ref', b'erence'),),)),
1678
(index, (b'ref', b'erence'), b'refdata', ((), ))},
1679
set(index.iter_entries_prefix([(b'name', b'fin1'), (b'ref', b'erence')])))
1680
self.assertEqual({(index, (b'name', b'fin1'), b'data', (((b'ref', b'erence'),),)),
1681
(index, (b'name', b'fin2'), b'beta', ((), ))},
1682
set(index.iter_entries_prefix([(b'name', None)])))
1618
(('name', 'fin1'), 'data', ([('ref', 'erence')], )),
1619
(('name', 'fin2'), 'beta', ([], )),
1620
(('ref', 'erence'), 'refdata', ([], ))])
1621
self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
1622
(index, ('ref', 'erence'), 'refdata', ((), ))]),
1623
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
1624
self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
1625
(index, ('name', 'fin2'), 'beta', ((), ))]),
1626
set(index.iter_entries_prefix([('name', None)])))
1684
1628
def test_iter_nothing_empty(self):
1685
1629
index = self.make_index()
1706
1650
index.validate()
1708
1652
def test_validate_no_refs_content(self):
1709
index = self.make_index(nodes=[((b'key', ), b'value')])
1653
index = self.make_index(nodes=[(('key', ), 'value')])
1710
1654
index.validate()
1713
class TestGraphIndexPrefixAdapter(tests.TestCaseWithMemoryTransport):
1657
class TestGraphIndexPrefixAdapter(TestCaseWithMemoryTransport):
1715
def make_index(self, ref_lists=1, key_elements=2, nodes=[],
1716
add_callback=False):
1717
result = _mod_index.InMemoryGraphIndex(
1718
ref_lists, key_elements=key_elements)
1659
def make_index(self, ref_lists=1, key_elements=2, nodes=[], add_callback=False):
1660
result = InMemoryGraphIndex(ref_lists, key_elements=key_elements)
1719
1661
result.add_nodes(nodes)
1720
1662
if add_callback:
1721
1663
add_nodes_callback = result.add_nodes
1723
1665
add_nodes_callback = None
1724
adapter = _mod_index.GraphIndexPrefixAdapter(
1725
result, (b'prefix', ), key_elements - 1,
1666
adapter = GraphIndexPrefixAdapter(result, ('prefix', ), key_elements - 1,
1726
1667
add_nodes_callback=add_nodes_callback)
1727
1668
return result, adapter
1729
1670
def test_add_node(self):
1730
1671
index, adapter = self.make_index(add_callback=True)
1731
adapter.add_node((b'key',), b'value', (((b'ref',),),))
1732
self.assertEqual({(index, (b'prefix', b'key'), b'value',
1733
(((b'prefix', b'ref'),),))},
1734
set(index.iter_all_entries()))
1672
adapter.add_node(('key',), 'value', ((('ref',),),))
1673
self.assertEqual(set([(index, ('prefix', 'key'), 'value', ((('prefix', 'ref'),),))]),
1674
set(index.iter_all_entries()))
1736
1676
def test_add_nodes(self):
1737
1677
index, adapter = self.make_index(add_callback=True)
1738
1678
adapter.add_nodes((
1739
((b'key',), b'value', (((b'ref',),),)),
1740
((b'key2',), b'value2', ((),)),
1679
(('key',), 'value', ((('ref',),),)),
1680
(('key2',), 'value2', ((),)),
1743
(index, (b'prefix', b'key2'), b'value2', ((),)),
1744
(index, (b'prefix', b'key'), b'value', (((b'prefix', b'ref'),),))
1682
self.assertEqual(set([
1683
(index, ('prefix', 'key2'), 'value2', ((),)),
1684
(index, ('prefix', 'key'), 'value', ((('prefix', 'ref'),),))
1746
1686
set(index.iter_all_entries()))
1748
1688
def test_construct(self):
1749
idx = _mod_index.InMemoryGraphIndex()
1750
adapter = _mod_index.GraphIndexPrefixAdapter(idx, (b'prefix', ), 1)
1689
index = InMemoryGraphIndex()
1690
adapter = GraphIndexPrefixAdapter(index, ('prefix', ), 1)
1752
1692
def test_construct_with_callback(self):
1753
idx = _mod_index.InMemoryGraphIndex()
1754
adapter = _mod_index.GraphIndexPrefixAdapter(idx, (b'prefix', ), 1,
1693
index = InMemoryGraphIndex()
1694
adapter = GraphIndexPrefixAdapter(index, ('prefix', ), 1, index.add_nodes)
1757
1696
def test_iter_all_entries_cross_prefix_map_errors(self):
1758
1697
index, adapter = self.make_index(nodes=[
1759
((b'prefix', b'key1'), b'data1', (((b'prefixaltered', b'key2'),),))])
1760
self.assertRaises(_mod_index.BadIndexData, list,
1761
adapter.iter_all_entries())
1698
(('prefix', 'key1'), 'data1', ((('prefixaltered', 'key2'),),))])
1699
self.assertRaises(errors.BadIndexData, list, adapter.iter_all_entries())
1763
1701
def test_iter_all_entries(self):
1764
1702
index, adapter = self.make_index(nodes=[
1765
((b'notprefix', b'key1'), b'data', ((), )),
1766
((b'prefix', b'key1'), b'data1', ((), )),
1767
((b'prefix', b'key2'), b'data2', (((b'prefix', b'key1'),),))])
1768
self.assertEqual({(index, (b'key1', ), b'data1', ((),)),
1769
(index, (b'key2', ), b'data2', (((b'key1',),),))},
1770
set(adapter.iter_all_entries()))
1703
(('notprefix', 'key1'), 'data', ((), )),
1704
(('prefix', 'key1'), 'data1', ((), )),
1705
(('prefix', 'key2'), 'data2', ((('prefix', 'key1'),),))])
1706
self.assertEqual(set([(index, ('key1', ), 'data1', ((),)),
1707
(index, ('key2', ), 'data2', ((('key1',),),))]),
1708
set(adapter.iter_all_entries()))
1772
1710
def test_iter_entries(self):
1773
1711
index, adapter = self.make_index(nodes=[
1774
((b'notprefix', b'key1'), b'data', ((), )),
1775
((b'prefix', b'key1'), b'data1', ((), )),
1776
((b'prefix', b'key2'), b'data2', (((b'prefix', b'key1'),),))])
1712
(('notprefix', 'key1'), 'data', ((), )),
1713
(('prefix', 'key1'), 'data1', ((), )),
1714
(('prefix', 'key2'), 'data2', ((('prefix', 'key1'),),))])
1777
1715
# ask for many - get all
1778
self.assertEqual({(index, (b'key1', ), b'data1', ((),)),
1779
(index, (b'key2', ), b'data2', (((b'key1', ),),))},
1780
set(adapter.iter_entries([(b'key1', ), (b'key2', )])))
1716
self.assertEqual(set([(index, ('key1', ), 'data1', ((),)),
1717
(index, ('key2', ), 'data2', ((('key1', ),),))]),
1718
set(adapter.iter_entries([('key1', ), ('key2', )])))
1781
1719
# ask for one, get one
1782
self.assertEqual({(index, (b'key1', ), b'data1', ((),))},
1783
set(adapter.iter_entries([(b'key1', )])))
1720
self.assertEqual(set([(index, ('key1', ), 'data1', ((),))]),
1721
set(adapter.iter_entries([('key1', )])))
1784
1722
# ask for missing, get none
1785
1723
self.assertEqual(set(),
1786
set(adapter.iter_entries([(b'key3', )])))
1724
set(adapter.iter_entries([('key3', )])))
1788
1726
def test_iter_entries_prefix(self):
1789
1727
index, adapter = self.make_index(key_elements=3, nodes=[
1790
((b'notprefix', b'foo', b'key1'), b'data', ((), )),
1791
((b'prefix', b'prefix2', b'key1'), b'data1', ((), )),
1792
((b'prefix', b'prefix2', b'key2'), b'data2', (((b'prefix', b'prefix2', b'key1'),),))])
1728
(('notprefix', 'foo', 'key1'), 'data', ((), )),
1729
(('prefix', 'prefix2', 'key1'), 'data1', ((), )),
1730
(('prefix', 'prefix2', 'key2'), 'data2', ((('prefix', 'prefix2', 'key1'),),))])
1793
1731
# ask for a prefix, get the results for just that prefix, adjusted.
1794
self.assertEqual({(index, (b'prefix2', b'key1', ), b'data1', ((),)),
1795
(index, (b'prefix2', b'key2', ), b'data2', (((b'prefix2', b'key1', ),),))},
1796
set(adapter.iter_entries_prefix([(b'prefix2', None)])))
1732
self.assertEqual(set([(index, ('prefix2', 'key1', ), 'data1', ((),)),
1733
(index, ('prefix2', 'key2', ), 'data2', ((('prefix2', 'key1', ),),))]),
1734
set(adapter.iter_entries_prefix([('prefix2', None)])))
1798
1736
def test_key_count_no_matching_keys(self):
1799
1737
index, adapter = self.make_index(nodes=[
1800
((b'notprefix', b'key1'), b'data', ((), ))])
1738
(('notprefix', 'key1'), 'data', ((), ))])
1801
1739
self.assertEqual(0, adapter.key_count())
1803
1741
def test_key_count_some_keys(self):
1804
1742
index, adapter = self.make_index(nodes=[
1805
((b'notprefix', b'key1'), b'data', ((), )),
1806
((b'prefix', b'key1'), b'data1', ((), )),
1807
((b'prefix', b'key2'), b'data2', (((b'prefix', b'key1'),),))])
1743
(('notprefix', 'key1'), 'data', ((), )),
1744
(('prefix', 'key1'), 'data1', ((), )),
1745
(('prefix', 'key2'), 'data2', ((('prefix', 'key1'),),))])
1808
1746
self.assertEqual(2, adapter.key_count())
1810
1748
def test_validate(self):
1811
1749
index, adapter = self.make_index()
1814
1751
def validate():
1815
1752
calls.append('called')
1816
1753
index.validate = validate