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
27
class TestGraphIndexBuilder(tests.TestCaseWithMemoryTransport):
65
29
def test_build_index_empty(self):
66
builder = _mod_index.GraphIndexBuilder()
30
builder = index.GraphIndexBuilder()
67
31
stream = builder.finish()
68
32
contents = stream.read()
70
b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=0\n\n",
34
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=0\n\n",
73
37
def test_build_index_empty_two_element_keys(self):
74
builder = _mod_index.GraphIndexBuilder(key_elements=2)
38
builder = index.GraphIndexBuilder(key_elements=2)
75
39
stream = builder.finish()
76
40
contents = stream.read()
78
b"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=0\n\n",
42
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=0\n\n",
81
45
def test_build_index_one_reference_list_empty(self):
82
builder = _mod_index.GraphIndexBuilder(reference_lists=1)
46
builder = index.GraphIndexBuilder(reference_lists=1)
83
47
stream = builder.finish()
84
48
contents = stream.read()
86
b"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=0\n\n",
50
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=0\n\n",
89
53
def test_build_index_two_reference_list_empty(self):
90
builder = _mod_index.GraphIndexBuilder(reference_lists=2)
54
builder = index.GraphIndexBuilder(reference_lists=2)
91
55
stream = builder.finish()
92
56
contents = stream.read()
94
b"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=0\n\n",
58
"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=0\n\n",
97
61
def test_build_index_one_node_no_refs(self):
98
builder = _mod_index.GraphIndexBuilder()
99
builder.add_node((b'akey', ), b'data')
62
builder = index.GraphIndexBuilder()
63
builder.add_node(('akey', ), 'data')
100
64
stream = builder.finish()
101
65
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)
67
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
68
"akey\x00\x00\x00data\n\n", contents)
106
70
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', ())
71
builder = index.GraphIndexBuilder()
72
builder.add_node(('akey', ), 'data', ())
109
73
stream = builder.finish()
110
74
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)
76
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
77
"akey\x00\x00\x00data\n\n", contents)
115
79
def test_build_index_one_node_2_element_keys(self):
116
80
# multipart keys are separated by \x00 - because they are fixed length,
117
81
# 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')
83
builder = index.GraphIndexBuilder(key_elements=2)
84
builder.add_node(('akey', 'secondpart'), 'data')
121
85
stream = builder.finish()
122
86
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)
88
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=1\n"
89
"akey\x00secondpart\x00\x00\x00data\n\n", contents)
127
91
def test_add_node_empty_value(self):
128
builder = _mod_index.GraphIndexBuilder()
129
builder.add_node((b'akey', ), b'')
92
builder = index.GraphIndexBuilder()
93
builder.add_node(('akey', ), '')
130
94
stream = builder.finish()
131
95
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)
97
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=1\n"
98
"akey\x00\x00\x00\n\n", contents)
136
100
def test_build_index_nodes_sorted(self):
137
101
# the highest sorted node comes first.
138
builder = _mod_index.GraphIndexBuilder()
102
builder = index.GraphIndexBuilder()
139
103
# use three to have a good chance of glitching dictionary hash
140
104
# lookups etc. Insert in randomish order that is not correct
141
105
# 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')
106
builder.add_node(('2002', ), 'data')
107
builder.add_node(('2000', ), 'data')
108
builder.add_node(('2001', ), 'data')
145
109
stream = builder.finish()
146
110
contents = stream.read()
147
111
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"
112
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\nlen=3\n"
113
"2000\x00\x00\x00data\n"
114
"2001\x00\x00\x00data\n"
115
"2002\x00\x00\x00data\n"
154
118
def test_build_index_2_element_key_nodes_sorted(self):
155
119
# multiple element keys are sorted first-key, second-key.
156
builder = _mod_index.GraphIndexBuilder(key_elements=2)
120
builder = index.GraphIndexBuilder(key_elements=2)
157
121
# use three values of each key element, to have a good chance of
158
122
# glitching dictionary hash lookups etc. Insert in randomish order that
159
123
# 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')
124
builder.add_node(('2002', '2002'), 'data')
125
builder.add_node(('2002', '2000'), 'data')
126
builder.add_node(('2002', '2001'), 'data')
127
builder.add_node(('2000', '2002'), 'data')
128
builder.add_node(('2000', '2000'), 'data')
129
builder.add_node(('2000', '2001'), 'data')
130
builder.add_node(('2001', '2002'), 'data')
131
builder.add_node(('2001', '2000'), 'data')
132
builder.add_node(('2001', '2001'), 'data')
169
133
stream = builder.finish()
170
134
contents = stream.read()
171
135
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"
136
"Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\nlen=9\n"
137
"2000\x002000\x00\x00\x00data\n"
138
"2000\x002001\x00\x00\x00data\n"
139
"2000\x002002\x00\x00\x00data\n"
140
"2001\x002000\x00\x00\x00data\n"
141
"2001\x002001\x00\x00\x00data\n"
142
"2001\x002002\x00\x00\x00data\n"
143
"2002\x002000\x00\x00\x00data\n"
144
"2002\x002001\x00\x00\x00data\n"
145
"2002\x002002\x00\x00\x00data\n"
184
148
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', ([], ))
149
builder = index.GraphIndexBuilder(reference_lists=1)
150
builder.add_node(('key', ), 'data', ([], ))
187
151
stream = builder.finish()
188
152
contents = stream.read()
189
153
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"
154
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
155
"key\x00\x00\x00data\n"
194
158
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', ([], ))
159
builder = index.GraphIndexBuilder(reference_lists=1, key_elements=2)
160
builder.add_node(('key', 'key2'), 'data', ([], ))
198
161
stream = builder.finish()
199
162
contents = stream.read()
200
163
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"
164
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=2\nlen=1\n"
165
"key\x00key2\x00\x00\x00data\n"
205
168
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', ([], []))
169
builder = index.GraphIndexBuilder(reference_lists=2)
170
builder.add_node(('key', ), 'data', ([], []))
208
171
stream = builder.finish()
209
172
contents = stream.read()
210
173
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"
174
"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=1\n"
175
"key\x00\x00\t\x00data\n"
215
178
def test_clear_cache(self):
216
builder = _mod_index.GraphIndexBuilder(reference_lists=2)
179
builder = index.GraphIndexBuilder(reference_lists=2)
217
180
# This is a no-op, but the api should exist
218
181
builder.clear_cache()
220
183
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', )], ))
184
builder = index.GraphIndexBuilder(reference_lists=1)
185
builder.add_node(('reference', ), 'data', ([], ))
186
builder.add_node(('key', ), 'data', ([('reference', )], ))
224
187
stream = builder.finish()
225
188
contents = stream.read()
226
189
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"
190
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=2\n"
191
"key\x00\x0072\x00data\n"
192
"reference\x00\x00\x00data\n"
232
195
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', )], ))
196
builder = index.GraphIndexBuilder(reference_lists=1)
197
builder.add_node(('reference', ), 'data', ([], ))
198
builder.add_node(('reference2', ), 'data', ([], ))
199
builder.add_node(('key', ), 'data',
200
([('reference', ), ('reference2', )], ))
238
201
stream = builder.finish()
239
202
contents = stream.read()
240
203
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"
204
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=3\n"
205
"key\x00\x00077\r094\x00data\n"
206
"reference\x00\x00\x00data\n"
207
"reference2\x00\x00\x00data\n"
247
210
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', )]))
211
builder = index.GraphIndexBuilder(reference_lists=2)
212
builder.add_node(('keference', ), 'data', ([], []))
213
builder.add_node(('rey', ), 'data',
214
([('keference', )], [('keference', )]))
252
215
stream = builder.finish()
253
216
contents = stream.read()
254
217
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"
218
"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=2\n"
219
"keference\x00\x00\t\x00data\n"
220
"rey\x00\x0059\t59\x00data\n"
260
223
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', )], ))
224
builder = index.GraphIndexBuilder(reference_lists=1)
225
builder.add_node(('rey', ), 'data',
226
([('beference', ), ('aeference2', )], ))
264
227
stream = builder.finish()
265
228
contents = stream.read()
266
229
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"
230
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
231
"aeference2\x00a\x00\x00\n"
232
"beference\x00a\x00\x00\n"
233
"rey\x00\x00074\r059\x00data\n"
273
236
def test_node_references_three_digits(self):
274
237
# 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, ))
238
builder = index.GraphIndexBuilder(reference_lists=1)
239
references = [(str(val), ) for val in reversed(range(9))]
240
builder.add_node(('2-key', ), '', (references, ))
278
241
stream = builder.finish()
279
242
contents = stream.read()
280
243
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"
244
"Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\nlen=1\n"
248
"2-key\x00\x00151\r145\r139\r133\r127\r121\r071\r065\r059\x00\n"
294
257
def test_absent_has_no_reference_overhead(self):
295
258
# the offsets after an absent record should be correct when there are
296
259
# >1 reference lists.
297
builder = _mod_index.GraphIndexBuilder(reference_lists=2)
298
builder.add_node((b'parent', ), b'', ([(b'aail', ), (b'zther', )], []))
260
builder = index.GraphIndexBuilder(reference_lists=2)
261
builder.add_node(('parent', ), '', ([('aail', ), ('zther', )], []))
299
262
stream = builder.finish()
300
263
contents = stream.read()
301
264
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"
265
"Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\nlen=1\n"
266
"aail\x00a\x00\x00\n"
267
"parent\x00\x0059\r84\t\x00\n"
268
"zther\x00a\x00\x00\n"
308
271
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')
272
builder = index.GraphIndexBuilder()
273
for bad_char in '\t\n\x0b\x0c\r\x00 ':
274
self.assertRaises(errors.BadIndexKey, builder.add_node,
275
('a%skey' % bad_char, ), 'data')
276
self.assertRaises(errors.BadIndexKey, builder.add_node,
278
self.assertRaises(errors.BadIndexKey, builder.add_node,
279
'not-a-tuple', 'data')
317
280
# not enough length
318
self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
281
self.assertRaises(errors.BadIndexKey, builder.add_node,
321
self.assertRaises(_mod_index.BadIndexKey, builder.add_node,
322
(b'primary', b'secondary'), b'data')
284
self.assertRaises(errors.BadIndexKey, builder.add_node,
285
('primary', 'secondary'), 'data')
323
286
# 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')
287
builder = index.GraphIndexBuilder(key_elements=2)
288
for bad_char in '\t\n\x0b\x0c\r\x00 ':
289
self.assertRaises(errors.BadIndexKey, builder.add_node,
290
('prefix', 'a%skey' % bad_char), 'data')
329
292
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', ),
293
builder = index.GraphIndexBuilder()
294
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
296
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
336
299
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', ([], [], []))
300
builder = index.GraphIndexBuilder()
301
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
303
builder = index.GraphIndexBuilder(reference_lists=1)
304
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
306
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
308
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
310
builder = index.GraphIndexBuilder(reference_lists=2)
311
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
313
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
315
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
316
'data aa', ([], [], []))
355
318
def test_add_node_bad_key_in_reference_lists(self):
356
319
# 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', )], ))
320
builder = index.GraphIndexBuilder(reference_lists=1)
321
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
322
'data aa', ([('a key', )], ))
360
323
# references keys must be tuples too
361
self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
362
b'data aa', (['not-a-tuple'], ))
324
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
325
'data aa', (['not-a-tuple'], ))
363
326
# not enough length
364
self.assertRaises(_mod_index.BadIndexKey, builder.add_node, (b'akey', ),
365
b'data aa', ([()], ))
327
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')], ))
330
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
331
'data aa', ([('primary', 'secondary')], ))
369
332
# 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', )], ))
333
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
334
'data aa', ([('agoodkey', ), ('that is a bad key', )], ))
372
335
# 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']))
337
builder = index.GraphIndexBuilder(reference_lists=2)
338
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
339
'data aa', ([], ['a bad key']))
378
341
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')
342
builder = index.GraphIndexBuilder()
343
builder.add_node(('key', ), 'data')
344
self.assertRaises(errors.BadIndexDuplicateKey,
345
builder.add_node, ('key', ), 'data')
384
347
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')
348
builder = index.GraphIndexBuilder(key_elements=2)
349
builder.add_node(('key', 'key'), 'data')
350
self.assertRaises(errors.BadIndexDuplicateKey, builder.add_node,
351
('key', 'key'), 'data')
390
353
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', ([],))
354
builder = index.GraphIndexBuilder(reference_lists=1)
355
builder.add_node(('key', ), 'data', ([('reference', )], ))
356
builder.add_node(('reference', ), 'data', ([],))
395
358
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', ([],))
359
builder = index.GraphIndexBuilder(reference_lists=1, key_elements=2)
360
builder.add_node(('k', 'ey'), 'data', ([('reference', 'tokey')], ))
361
builder.add_node(('reference', 'tokey'), 'data', ([],))
402
363
def test_set_optimize(self):
403
builder = _mod_index.GraphIndexBuilder(
404
reference_lists=1, key_elements=2)
364
builder = index.GraphIndexBuilder(reference_lists=1, key_elements=2)
405
365
builder.set_optimize(for_size=True)
406
366
self.assertTrue(builder._optimize_for_size)
407
367
builder.set_optimize(for_size=False)
830
787
def test_iter_entries_references_resolved(self):
831
788
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',)])))
789
(('name', ), 'data', ([('ref', ), ('ref', )], )),
790
(('ref', ), 'refdata', ([], ))])
791
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),('ref',)),)),
792
(index, ('ref', ), 'refdata', ((), ))]),
793
set(index.iter_entries([('name',), ('ref',)])))
838
795
def test_iter_entries_references_2_refs_resolved(self):
839
796
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',)])))
797
(('name', ), 'data', ([('ref', )], [('ref', )])),
798
(('ref', ), 'refdata', ([], []))])
799
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),), (('ref',),))),
800
(index, ('ref', ), 'refdata', ((), ()))]),
801
set(index.iter_entries([('name',), ('ref',)])))
846
803
def test_iteration_absent_skipped(self):
847
804
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', )])))
805
(('name', ), 'data', ([('ref', )], ))])
806
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),))]),
807
set(index.iter_all_entries()))
808
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),))]),
809
set(index.iter_entries([('name', )])))
810
self.assertEqual([], list(index.iter_entries([('ref', )])))
855
812
def test_iteration_absent_skipped_2_element_keys(self):
856
813
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')])))
814
(('name', 'fin'), 'data', ([('ref', 'erence')], ))])
815
self.assertEqual(set([(index, ('name', 'fin'), 'data', ((('ref', 'erence'),),))]),
816
set(index.iter_all_entries()))
817
self.assertEqual(set([(index, ('name', 'fin'), 'data', ((('ref', 'erence'),),))]),
818
set(index.iter_entries([('name', 'fin')])))
819
self.assertEqual([], list(index.iter_entries([('ref', 'erence')])))
864
821
def test_iter_all_keys(self):
865
822
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', )])))
823
(('name', ), 'data', ([('ref', )], )),
824
(('ref', ), 'refdata', ([], ))])
825
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),
826
(index, ('ref', ), 'refdata', ((), ))]),
827
set(index.iter_entries([('name', ), ('ref', )])))
872
829
def test_iter_nothing_empty(self):
873
830
index = self.make_index()
876
833
def test_iter_missing_entry_empty(self):
877
834
index = self.make_index()
878
self.assertEqual([], list(index.iter_entries([(b'a', )])))
835
self.assertEqual([], list(index.iter_entries([('a', )])))
880
837
def test_iter_missing_entry_empty_no_size(self):
881
838
idx = self.make_index()
882
idx = _mod_index.GraphIndex(idx._transport, 'index', None)
883
self.assertEqual([], list(idx.iter_entries([(b'a', )])))
839
idx = index.GraphIndex(idx._transport, 'index', None)
840
self.assertEqual([], list(idx.iter_entries([('a', )])))
885
842
def test_iter_key_prefix_1_element_key_None(self):
886
843
index = self.make_index()
887
self.assertRaises(_mod_index.BadIndexKey, list,
888
index.iter_entries_prefix([(None, )]))
844
self.assertRaises(errors.BadIndexKey, list,
845
index.iter_entries_prefix([(None, )]))
890
847
def test_iter_key_prefix_wrong_length(self):
891
848
index = self.make_index()
892
self.assertRaises(_mod_index.BadIndexKey, list,
893
index.iter_entries_prefix([(b'foo', None)]))
849
self.assertRaises(errors.BadIndexKey, list,
850
index.iter_entries_prefix([('foo', None)]))
894
851
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)]))
852
self.assertRaises(errors.BadIndexKey, list,
853
index.iter_entries_prefix([('foo', )]))
854
self.assertRaises(errors.BadIndexKey, list,
855
index.iter_entries_prefix([('foo', None, None)]))
900
857
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', )])))
858
index = self.make_index( nodes=[
859
(('name', ), 'data', ()),
860
(('ref', ), 'refdata', ())])
861
self.assertEqual(set([(index, ('name', ), 'data'),
862
(index, ('ref', ), 'refdata')]),
863
set(index.iter_entries_prefix([('name', ), ('ref', )])))
908
865
def test_iter_key_prefix_1_key_element_refs(self):
909
866
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', )])))
867
(('name', ), 'data', ([('ref', )], )),
868
(('ref', ), 'refdata', ([], ))])
869
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),
870
(index, ('ref', ), 'refdata', ((), ))]),
871
set(index.iter_entries_prefix([('name', ), ('ref', )])))
916
873
def test_iter_key_prefix_2_key_element_no_refs(self):
917
874
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)])))
875
(('name', 'fin1'), 'data', ()),
876
(('name', 'fin2'), 'beta', ()),
877
(('ref', 'erence'), 'refdata', ())])
878
self.assertEqual(set([(index, ('name', 'fin1'), 'data'),
879
(index, ('ref', 'erence'), 'refdata')]),
880
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
881
self.assertEqual(set([(index, ('name', 'fin1'), 'data'),
882
(index, ('name', 'fin2'), 'beta')]),
883
set(index.iter_entries_prefix([('name', None)])))
928
885
def test_iter_key_prefix_2_key_element_refs(self):
929
886
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)])))
887
(('name', 'fin1'), 'data', ([('ref', 'erence')], )),
888
(('name', 'fin2'), 'beta', ([], )),
889
(('ref', 'erence'), 'refdata', ([], ))])
890
self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
891
(index, ('ref', 'erence'), 'refdata', ((), ))]),
892
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
893
self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
894
(index, ('name', 'fin2'), 'beta', ((), ))]),
895
set(index.iter_entries_prefix([('name', None)])))
940
897
def test_key_count_empty(self):
941
898
index = self.make_index()
942
899
self.assertEqual(0, index.key_count())
944
901
def test_key_count_one(self):
945
index = self.make_index(nodes=[((b'name', ), b'', ())])
902
index = self.make_index(nodes=[(('name', ), '', ())])
946
903
self.assertEqual(1, index.key_count())
948
905
def test_key_count_two(self):
949
906
index = self.make_index(nodes=[
950
((b'name', ), b'', ()), ((b'foo', ), b'', ())])
907
(('name', ), '', ()), (('foo', ), '', ())])
951
908
self.assertEqual(2, index.key_count())
953
910
def test_read_and_parse_tracks_real_read_value(self):
1180
1134
log.append(self._index)
1181
1135
return self._index.clear_cache()
1183
idx = _mod_index.CombinedGraphIndex([])
1184
idx1 = self.make_index('name', 0, nodes=[((b'key', ), b'', ())])
1137
idx = index.CombinedGraphIndex([])
1138
idx1 = self.make_index('name', 0, nodes=[(('key', ), '', ())])
1185
1139
idx.insert_index(0, ClearCacheProxy(idx1))
1186
idx2 = self.make_index('name', 0, nodes=[((b'key', ), b'', ())])
1140
idx2 = self.make_index('name', 0, nodes=[(('key', ), '', ())])
1187
1141
idx.insert_index(1, ClearCacheProxy(idx2))
1188
1142
# CombinedGraphIndex should call 'clear_cache()' on all children
1189
1143
idx.clear_cache()
1190
1144
self.assertEqual(sorted([idx1, idx2]), sorted(log))
1192
1146
def test_iter_all_entries_empty(self):
1193
idx = _mod_index.CombinedGraphIndex([])
1147
idx = index.CombinedGraphIndex([])
1194
1148
self.assertEqual([], list(idx.iter_all_entries()))
1196
1150
def test_iter_all_entries_children_empty(self):
1197
1151
idx1 = self.make_index('name')
1198
idx = _mod_index.CombinedGraphIndex([idx1])
1152
idx = index.CombinedGraphIndex([idx1])
1199
1153
self.assertEqual([], list(idx.iter_all_entries()))
1201
1155
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()))
1156
idx1 = self.make_index('name', nodes=[(('name', ), 'data', ())])
1157
idx = index.CombinedGraphIndex([idx1])
1158
self.assertEqual([(idx1, ('name', ), 'data')],
1159
list(idx.iter_all_entries()))
1207
1161
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'')],
1162
idx1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
1163
idx2 = self.make_index('name2', nodes=[(('2', ), '', ())])
1164
idx = index.CombinedGraphIndex([idx1, idx2])
1165
self.assertEqual([(idx1, ('name', ), 'data'),
1166
(idx2, ('2', ), '')],
1213
1167
list(idx.iter_all_entries()))
1215
1169
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', )])))
1170
idx1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
1171
idx2 = self.make_index('name2', nodes=[(('name', ), 'data', ())])
1172
idx = index.CombinedGraphIndex([idx1, idx2])
1173
self.assertEqual([(idx1, ('name', ), 'data')],
1174
list(idx.iter_entries([('name', )])))
1222
1176
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')],
1177
idx1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
1178
idx2 = self.make_index('name2', nodes=[(('name', ), 'data', ())])
1179
idx = index.CombinedGraphIndex([idx1, idx2])
1180
self.assertEqual([(idx1, ('name', ), 'data')],
1227
1181
list(idx.iter_all_entries()))
1229
1183
def test_iter_key_prefix_2_key_element_refs(self):
1230
1184
idx1 = self.make_index('1', 1, key_elements=2, nodes=[
1231
((b'name', b'fin1'), b'data', ([(b'ref', b'erence')], ))])
1185
(('name', 'fin1'), 'data', ([('ref', 'erence')], ))])
1232
1186
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)])))
1187
(('name', 'fin2'), 'beta', ([], )),
1188
(('ref', 'erence'), 'refdata', ([], ))])
1189
idx = index.CombinedGraphIndex([idx1, idx2])
1190
self.assertEqual(set([(idx1, ('name', 'fin1'), 'data',
1191
((('ref', 'erence'),),)),
1192
(idx2, ('ref', 'erence'), 'refdata', ((), ))]),
1193
set(idx.iter_entries_prefix([('name', 'fin1'),
1194
('ref', 'erence')])))
1195
self.assertEqual(set([(idx1, ('name', 'fin1'), 'data',
1196
((('ref', 'erence'),),)),
1197
(idx2, ('name', 'fin2'), 'beta', ((), ))]),
1198
set(idx.iter_entries_prefix([('name', None)])))
1246
1200
def test_iter_nothing_empty(self):
1247
idx = _mod_index.CombinedGraphIndex([])
1201
idx = index.CombinedGraphIndex([])
1248
1202
self.assertEqual([], list(idx.iter_entries([])))
1250
1204
def test_iter_nothing_children_empty(self):
1251
1205
idx1 = self.make_index('name')
1252
idx = _mod_index.CombinedGraphIndex([idx1])
1206
idx = index.CombinedGraphIndex([idx1])
1253
1207
self.assertEqual([], list(idx.iter_entries([])))
1255
1209
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', )])))
1210
idx1 = self.make_index('1', 1, nodes=[(('name', ), 'data',
1212
idx2 = self.make_index('2', 1, nodes=[(('ref', ), 'refdata', ((), ))])
1213
idx = index.CombinedGraphIndex([idx1, idx2])
1214
self.assertEqual(set([(idx1, ('name', ), 'data', ((('ref', ), ), )),
1215
(idx2, ('ref', ), 'refdata', ((), ))]),
1216
set(idx.iter_entries([('name', ), ('ref', )])))
1265
1218
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', )])))
1219
idx1 = self.make_index('1', 1, nodes=[(('name', ), 'data',
1221
(('ref', ), 'refdata', ([], ))])
1222
idx2 = self.make_index('2', 1, nodes=[(('ref', ), 'refdata', ([], ))])
1223
idx = index.CombinedGraphIndex([idx1, idx2])
1224
self.assertEqual(set([(idx1, ('name', ), 'data', ((('ref',),),)),
1225
(idx1, ('ref', ), 'refdata', ((), ))]),
1226
set(idx.iter_entries([('name', ), ('ref', )])))
1276
1228
def test_iter_missing_entry_empty(self):
1277
idx = _mod_index.CombinedGraphIndex([])
1229
idx = index.CombinedGraphIndex([])
1278
1230
self.assertEqual([], list(idx.iter_entries([('a', )])))
1280
1232
def test_iter_missing_entry_one_index(self):
1281
1233
idx1 = self.make_index('1')
1282
idx = _mod_index.CombinedGraphIndex([idx1])
1283
self.assertEqual([], list(idx.iter_entries([(b'a', )])))
1234
idx = index.CombinedGraphIndex([idx1])
1235
self.assertEqual([], list(idx.iter_entries([('a', )])))
1285
1237
def test_iter_missing_entry_two_index(self):
1286
1238
idx1 = self.make_index('1')
1287
1239
idx2 = self.make_index('2')
1288
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1240
idx = index.CombinedGraphIndex([idx1, idx2])
1289
1241
self.assertEqual([], list(idx.iter_entries([('a', )])))
1291
1243
def test_iter_entry_present_one_index_only(self):
1292
idx1 = self.make_index('1', nodes=[((b'key', ), b'', ())])
1244
idx1 = self.make_index('1', nodes=[(('key', ), '', ())])
1293
1245
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', )])))
1246
idx = index.CombinedGraphIndex([idx1, idx2])
1247
self.assertEqual([(idx1, ('key', ), '')],
1248
list(idx.iter_entries([('key', )])))
1297
1249
# 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', )])))
1250
idx = index.CombinedGraphIndex([idx2, idx1])
1251
self.assertEqual([(idx1, ('key', ), '')],
1252
list(idx.iter_entries([('key', )])))
1302
1254
def test_key_count_empty(self):
1303
1255
idx1 = self.make_index('1', nodes=[])
1304
1256
idx2 = self.make_index('2', nodes=[])
1305
idx = _mod_index.CombinedGraphIndex([idx1, idx2])
1257
idx = index.CombinedGraphIndex([idx1, idx2])
1306
1258
self.assertEqual(0, idx.key_count())
1308
1260
def test_key_count_sums_index_keys(self):
1309
1261
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])
1264
idx2 = self.make_index('2', nodes=[(('1',), '', ())])
1265
idx = index.CombinedGraphIndex([idx1, idx2])
1314
1266
self.assertEqual(3, idx.key_count())
1316
1268
def test_validate_bad_child_index_errors(self):
1317
1269
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)
1270
trans.put_bytes('name', "not an index\n")
1271
idx1 = index.GraphIndex(trans, 'name', 13)
1272
idx = index.CombinedGraphIndex([idx1])
1273
self.assertRaises(errors.BadIndexFormatSignature, idx.validate)
1323
1275
def test_validate_empty(self):
1324
idx = _mod_index.CombinedGraphIndex([])
1276
idx = index.CombinedGraphIndex([])
1327
1279
def test_key_count_reloads(self):
1522
1475
self.assertEqual(set(), missing_keys)
1524
1477
def test_find_ancestors_missing_keys(self):
1529
1482
index1 = self.make_index('12', ref_lists=1, nodes=[
1530
(key1, b'value', ([],)),
1531
(key2, b'value', ([key1],)),
1483
(key1, 'value', ([],)),
1484
(key2, 'value', ([key1],)),
1533
1486
index2 = self.make_index('34', ref_lists=1, nodes=[
1534
(key3, b'value', ([key2],)),
1487
(key3, 'value', ([key2],)),
1536
c_index = _mod_index.CombinedGraphIndex([index1, index2])
1489
c_index = index.CombinedGraphIndex([index1, index2])
1537
1490
# Searching for a key which is actually not present at all should
1538
1491
# eventually converge
1539
1492
parent_map, missing_keys = c_index.find_ancestry([key4], 0)
1540
1493
self.assertEqual({}, parent_map)
1541
self.assertEqual({key4}, missing_keys)
1494
self.assertEqual(set([key4]), missing_keys)
1543
1496
def test_find_ancestors_no_indexes(self):
1544
c_index = _mod_index.CombinedGraphIndex([])
1497
c_index = index.CombinedGraphIndex([])
1546
1499
parent_map, missing_keys = c_index.find_ancestry([key1], 0)
1547
1500
self.assertEqual({}, parent_map)
1548
self.assertEqual({key1}, missing_keys)
1501
self.assertEqual(set([key1]), missing_keys)
1550
1503
def test_find_ancestors_ghost_parent(self):
1555
1508
index1 = self.make_index('12', ref_lists=1, nodes=[
1556
(key1, b'value', ([],)),
1557
(key2, b'value', ([key1],)),
1509
(key1, 'value', ([],)),
1510
(key2, 'value', ([key1],)),
1559
1512
index2 = self.make_index('34', ref_lists=1, nodes=[
1560
(key4, b'value', ([key2, key3],)),
1513
(key4, 'value', ([key2, key3],)),
1562
c_index = _mod_index.CombinedGraphIndex([index1, index2])
1515
c_index = index.CombinedGraphIndex([index1, index2])
1563
1516
# Searching for a key which is actually not present at all should
1564
1517
# eventually converge
1565
1518
parent_map, missing_keys = c_index.find_ancestry([key4], 0)
1566
1519
self.assertEqual({key4: (key2, key3), key2: (key1,), key1: ()},
1568
self.assertEqual({key3}, missing_keys)
1521
self.assertEqual(set([key3]), missing_keys)
1570
1523
def test__find_ancestors_empty_index(self):
1571
1524
idx = self.make_index('test', ref_lists=1, key_elements=1, nodes=[])
1572
1525
parent_map = {}
1573
1526
missing_keys = set()
1574
search_keys = idx._find_ancestors([(b'one',), (b'two',)], 0, parent_map,
1527
search_keys = idx._find_ancestors([('one',), ('two',)], 0, parent_map,
1576
1529
self.assertEqual(set(), search_keys)
1577
1530
self.assertEqual({}, parent_map)
1578
self.assertEqual({(b'one',), (b'two',)}, missing_keys)
1531
self.assertEqual(set([('one',), ('two',)]), missing_keys)
1581
1534
class TestInMemoryGraphIndex(tests.TestCaseWithMemoryTransport):
1583
1536
def make_index(self, ref_lists=0, key_elements=1, nodes=[]):
1584
result = _mod_index.InMemoryGraphIndex(
1585
ref_lists, key_elements=key_elements)
1537
result = index.InMemoryGraphIndex(ref_lists, key_elements=key_elements)
1586
1538
result.add_nodes(nodes)
1589
1541
def test_add_nodes_no_refs(self):
1590
1542
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()))
1543
index.add_nodes([(('name', ), 'data')])
1544
index.add_nodes([(('name2', ), ''), (('name3', ), '')])
1545
self.assertEqual(set([
1546
(index, ('name', ), 'data'),
1547
(index, ('name2', ), ''),
1548
(index, ('name3', ), ''),
1549
]), set(index.iter_all_entries()))
1599
1551
def test_add_nodes(self):
1600
1552
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()))
1553
index.add_nodes([(('name', ), 'data', ([],))])
1554
index.add_nodes([(('name2', ), '', ([],)), (('name3', ), '', ([('r', )],))])
1555
self.assertEqual(set([
1556
(index, ('name', ), 'data', ((),)),
1557
(index, ('name2', ), '', ((),)),
1558
(index, ('name3', ), '', ((('r', ), ), )),
1559
]), set(index.iter_all_entries()))
1610
1561
def test_iter_all_entries_empty(self):
1611
1562
index = self.make_index()
1612
1563
self.assertEqual([], list(index.iter_all_entries()))
1614
1565
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()))
1566
index = self.make_index(nodes=[(('name', ), 'data')])
1567
self.assertEqual([(index, ('name', ), 'data')],
1568
list(index.iter_all_entries()))
1619
1570
def test_iter_all_entries_references(self):
1620
1571
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()))
1572
(('name', ), 'data', ([('ref', )], )),
1573
(('ref', ), 'refdata', ([], ))])
1574
self.assertEqual(set([(index, ('name', ), 'data', ((('ref', ),),)),
1575
(index, ('ref', ), 'refdata', ((), ))]),
1576
set(index.iter_all_entries()))
1627
1578
def test_iteration_absent_skipped(self):
1628
1579
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', )])))
1580
(('name', ), 'data', ([('ref', )], ))])
1581
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),))]),
1582
set(index.iter_all_entries()))
1583
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),))]),
1584
set(index.iter_entries([('name', )])))
1585
self.assertEqual([], list(index.iter_entries([('ref', )])))
1636
1587
def test_iter_all_keys(self):
1637
1588
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', )])))
1589
(('name', ), 'data', ([('ref', )], )),
1590
(('ref', ), 'refdata', ([], ))])
1591
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),
1592
(index, ('ref', ), 'refdata', ((), ))]),
1593
set(index.iter_entries([('name', ), ('ref', )])))
1644
1595
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', )])))
1596
index = self.make_index( nodes=[
1597
(('name', ), 'data'),
1598
(('ref', ), 'refdata')])
1599
self.assertEqual(set([(index, ('name', ), 'data'),
1600
(index, ('ref', ), 'refdata')]),
1601
set(index.iter_entries_prefix([('name', ), ('ref', )])))
1652
1603
def test_iter_key_prefix_1_key_element_refs(self):
1653
1604
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', )])))
1605
(('name', ), 'data', ([('ref', )], )),
1606
(('ref', ), 'refdata', ([], ))])
1607
self.assertEqual(set([(index, ('name', ), 'data', ((('ref',),),)),
1608
(index, ('ref', ), 'refdata', ((), ))]),
1609
set(index.iter_entries_prefix([('name', ), ('ref', )])))
1660
1611
def test_iter_key_prefix_2_key_element_no_refs(self):
1661
1612
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)])))
1613
(('name', 'fin1'), 'data'),
1614
(('name', 'fin2'), 'beta'),
1615
(('ref', 'erence'), 'refdata')])
1616
self.assertEqual(set([(index, ('name', 'fin1'), 'data'),
1617
(index, ('ref', 'erence'), 'refdata')]),
1618
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
1619
self.assertEqual(set([(index, ('name', 'fin1'), 'data'),
1620
(index, ('name', 'fin2'), 'beta')]),
1621
set(index.iter_entries_prefix([('name', None)])))
1672
1623
def test_iter_key_prefix_2_key_element_refs(self):
1673
1624
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)])))
1625
(('name', 'fin1'), 'data', ([('ref', 'erence')], )),
1626
(('name', 'fin2'), 'beta', ([], )),
1627
(('ref', 'erence'), 'refdata', ([], ))])
1628
self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
1629
(index, ('ref', 'erence'), 'refdata', ((), ))]),
1630
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
1631
self.assertEqual(set([(index, ('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
1632
(index, ('name', 'fin2'), 'beta', ((), ))]),
1633
set(index.iter_entries_prefix([('name', None)])))
1684
1635
def test_iter_nothing_empty(self):
1685
1636
index = self.make_index()
1715
1666
def make_index(self, ref_lists=1, key_elements=2, nodes=[],
1716
1667
add_callback=False):
1717
result = _mod_index.InMemoryGraphIndex(
1718
ref_lists, key_elements=key_elements)
1668
result = index.InMemoryGraphIndex(ref_lists, key_elements=key_elements)
1719
1669
result.add_nodes(nodes)
1720
1670
if add_callback:
1721
1671
add_nodes_callback = result.add_nodes
1723
1673
add_nodes_callback = None
1724
adapter = _mod_index.GraphIndexPrefixAdapter(
1725
result, (b'prefix', ), key_elements - 1,
1674
adapter = index.GraphIndexPrefixAdapter(
1675
result, ('prefix', ), key_elements - 1,
1726
1676
add_nodes_callback=add_nodes_callback)
1727
1677
return result, adapter
1729
1679
def test_add_node(self):
1730
1680
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()))
1681
adapter.add_node(('key',), 'value', ((('ref',),),))
1682
self.assertEqual(set([(index, ('prefix', 'key'), 'value',
1683
((('prefix', 'ref'),),))]),
1684
set(index.iter_all_entries()))
1736
1686
def test_add_nodes(self):
1737
1687
index, adapter = self.make_index(add_callback=True)
1738
1688
adapter.add_nodes((
1739
((b'key',), b'value', (((b'ref',),),)),
1740
((b'key2',), b'value2', ((),)),
1689
(('key',), 'value', ((('ref',),),)),
1690
(('key2',), 'value2', ((),)),
1743
(index, (b'prefix', b'key2'), b'value2', ((),)),
1744
(index, (b'prefix', b'key'), b'value', (((b'prefix', b'ref'),),))
1692
self.assertEqual(set([
1693
(index, ('prefix', 'key2'), 'value2', ((),)),
1694
(index, ('prefix', 'key'), 'value', ((('prefix', 'ref'),),))
1746
1696
set(index.iter_all_entries()))
1748
1698
def test_construct(self):
1749
idx = _mod_index.InMemoryGraphIndex()
1750
adapter = _mod_index.GraphIndexPrefixAdapter(idx, (b'prefix', ), 1)
1699
idx = index.InMemoryGraphIndex()
1700
adapter = index.GraphIndexPrefixAdapter(idx, ('prefix', ), 1)
1752
1702
def test_construct_with_callback(self):
1753
idx = _mod_index.InMemoryGraphIndex()
1754
adapter = _mod_index.GraphIndexPrefixAdapter(idx, (b'prefix', ), 1,
1703
idx = index.InMemoryGraphIndex()
1704
adapter = index.GraphIndexPrefixAdapter(idx, ('prefix', ), 1,
1757
1707
def test_iter_all_entries_cross_prefix_map_errors(self):
1758
1708
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())
1709
(('prefix', 'key1'), 'data1', ((('prefixaltered', 'key2'),),))])
1710
self.assertRaises(errors.BadIndexData, list, adapter.iter_all_entries())
1763
1712
def test_iter_all_entries(self):
1764
1713
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()))
1714
(('notprefix', 'key1'), 'data', ((), )),
1715
(('prefix', 'key1'), 'data1', ((), )),
1716
(('prefix', 'key2'), 'data2', ((('prefix', 'key1'),),))])
1717
self.assertEqual(set([(index, ('key1', ), 'data1', ((),)),
1718
(index, ('key2', ), 'data2', ((('key1',),),))]),
1719
set(adapter.iter_all_entries()))
1772
1721
def test_iter_entries(self):
1773
1722
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'),),))])
1723
(('notprefix', 'key1'), 'data', ((), )),
1724
(('prefix', 'key1'), 'data1', ((), )),
1725
(('prefix', 'key2'), 'data2', ((('prefix', 'key1'),),))])
1777
1726
# 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', )])))
1727
self.assertEqual(set([(index, ('key1', ), 'data1', ((),)),
1728
(index, ('key2', ), 'data2', ((('key1', ),),))]),
1729
set(adapter.iter_entries([('key1', ), ('key2', )])))
1781
1730
# ask for one, get one
1782
self.assertEqual({(index, (b'key1', ), b'data1', ((),))},
1783
set(adapter.iter_entries([(b'key1', )])))
1731
self.assertEqual(set([(index, ('key1', ), 'data1', ((),))]),
1732
set(adapter.iter_entries([('key1', )])))
1784
1733
# ask for missing, get none
1785
1734
self.assertEqual(set(),
1786
set(adapter.iter_entries([(b'key3', )])))
1735
set(adapter.iter_entries([('key3', )])))
1788
1737
def test_iter_entries_prefix(self):
1789
1738
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'),),))])
1739
(('notprefix', 'foo', 'key1'), 'data', ((), )),
1740
(('prefix', 'prefix2', 'key1'), 'data1', ((), )),
1741
(('prefix', 'prefix2', 'key2'), 'data2', ((('prefix', 'prefix2', 'key1'),),))])
1793
1742
# 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)])))
1743
self.assertEqual(set([(index, ('prefix2', 'key1', ), 'data1', ((),)),
1744
(index, ('prefix2', 'key2', ), 'data2', ((('prefix2', 'key1', ),),))]),
1745
set(adapter.iter_entries_prefix([('prefix2', None)])))
1798
1747
def test_key_count_no_matching_keys(self):
1799
1748
index, adapter = self.make_index(nodes=[
1800
((b'notprefix', b'key1'), b'data', ((), ))])
1749
(('notprefix', 'key1'), 'data', ((), ))])
1801
1750
self.assertEqual(0, adapter.key_count())
1803
1752
def test_key_count_some_keys(self):
1804
1753
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'),),))])
1754
(('notprefix', 'key1'), 'data', ((), )),
1755
(('prefix', 'key1'), 'data1', ((), )),
1756
(('prefix', 'key2'), 'data2', ((('prefix', 'key1'),),))])
1808
1757
self.assertEqual(2, adapter.key_count())
1810
1759
def test_validate(self):
1811
1760
index, adapter = self.make_index()
1814
1762
def validate():
1815
1763
calls.append('called')
1816
1764
index.validate = validate