27
27
builder = GraphIndexBuilder()
28
28
stream = builder.finish()
29
29
contents = stream.read()
30
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=0\n\n", contents)
30
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\n\n", contents)
32
def test_build_index_empty_two_element_keys(self):
33
builder = GraphIndexBuilder(key_elements=2)
34
stream = builder.finish()
35
contents = stream.read()
36
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\n\n", contents)
32
38
def test_build_index_one_reference_list_empty(self):
33
39
builder = GraphIndexBuilder(reference_lists=1)
34
40
stream = builder.finish()
35
41
contents = stream.read()
36
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=1\n\n", contents)
42
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\n\n", contents)
38
44
def test_build_index_two_reference_list_empty(self):
39
45
builder = GraphIndexBuilder(reference_lists=2)
40
46
stream = builder.finish()
41
47
contents = stream.read()
42
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=2\n\n", contents)
48
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\n\n", contents)
44
50
def test_build_index_one_node_no_refs(self):
45
51
builder = GraphIndexBuilder()
46
builder.add_node('akey', 'data')
52
builder.add_node(('akey', ), 'data')
47
53
stream = builder.finish()
48
54
contents = stream.read()
49
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=0\n"
55
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\n"
50
56
"akey\x00\x00\x00data\n\n", contents)
52
58
def test_build_index_one_node_no_refs_accepts_empty_reflist(self):
53
59
builder = GraphIndexBuilder()
54
builder.add_node('akey', 'data', ())
60
builder.add_node(('akey', ), 'data', ())
55
61
stream = builder.finish()
56
62
contents = stream.read()
57
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=0\n"
63
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\n"
58
64
"akey\x00\x00\x00data\n\n", contents)
66
def test_build_index_one_node_2_element_keys(self):
67
# multipart keys are separated by \x00 - because they are fixed length,
68
# not variable this does not cause any issues, and seems clearer to the
70
builder = GraphIndexBuilder(key_elements=2)
71
builder.add_node(('akey', 'secondpart'), 'data')
72
stream = builder.finish()
73
contents = stream.read()
74
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\n"
75
"akey\x00secondpart\x00\x00\x00data\n\n", contents)
60
77
def test_add_node_empty_value(self):
61
78
builder = GraphIndexBuilder()
62
builder.add_node('akey', '')
79
builder.add_node(('akey', ), '')
63
80
stream = builder.finish()
64
81
contents = stream.read()
65
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=0\n"
82
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\n"
66
83
"akey\x00\x00\x00\n\n", contents)
68
def test_build_index_two_nodes_sorted(self):
85
def test_build_index_nodes_sorted(self):
69
86
# the highest sorted node comes first.
70
87
builder = GraphIndexBuilder()
71
88
# use three to have a good chance of glitching dictionary hash
72
89
# lookups etc. Insert in randomish order that is not correct
73
90
# and not the reverse of the correct order.
74
builder.add_node('2002', 'data')
75
builder.add_node('2000', 'data')
76
builder.add_node('2001', 'data')
91
builder.add_node(('2002', ), 'data')
92
builder.add_node(('2000', ), 'data')
93
builder.add_node(('2001', ), 'data')
77
94
stream = builder.finish()
78
95
contents = stream.read()
79
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=0\n"
96
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=1\n"
80
97
"2000\x00\x00\x00data\n"
81
98
"2001\x00\x00\x00data\n"
82
99
"2002\x00\x00\x00data\n"
102
def test_build_index_2_element_key_nodes_sorted(self):
103
# multiple element keys are sorted first-key, second-key.
104
builder = GraphIndexBuilder(key_elements=2)
105
# use three values of each key element, to have a good chance of
106
# glitching dictionary hash lookups etc. Insert in randomish order that
107
# is not correct and not the reverse of the correct order.
108
builder.add_node(('2002', '2002'), 'data')
109
builder.add_node(('2002', '2000'), 'data')
110
builder.add_node(('2002', '2001'), 'data')
111
builder.add_node(('2000', '2002'), 'data')
112
builder.add_node(('2000', '2000'), 'data')
113
builder.add_node(('2000', '2001'), 'data')
114
builder.add_node(('2001', '2002'), 'data')
115
builder.add_node(('2001', '2000'), 'data')
116
builder.add_node(('2001', '2001'), 'data')
117
stream = builder.finish()
118
contents = stream.read()
119
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=0\nkey_elements=2\n"
120
"2000\x002000\x00\x00\x00data\n"
121
"2000\x002001\x00\x00\x00data\n"
122
"2000\x002002\x00\x00\x00data\n"
123
"2001\x002000\x00\x00\x00data\n"
124
"2001\x002001\x00\x00\x00data\n"
125
"2001\x002002\x00\x00\x00data\n"
126
"2002\x002000\x00\x00\x00data\n"
127
"2002\x002001\x00\x00\x00data\n"
128
"2002\x002002\x00\x00\x00data\n"
85
131
def test_build_index_reference_lists_are_included_one(self):
86
132
builder = GraphIndexBuilder(reference_lists=1)
87
builder.add_node('key', 'data', ([], ))
133
builder.add_node(('key', ), 'data', ([], ))
88
134
stream = builder.finish()
89
135
contents = stream.read()
90
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=1\n"
136
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\n"
91
137
"key\x00\x00\x00data\n"
140
def test_build_index_reference_lists_with_2_element_keys(self):
141
builder = GraphIndexBuilder(reference_lists=1, key_elements=2)
142
builder.add_node(('key', 'key2'), 'data', ([], ))
143
stream = builder.finish()
144
contents = stream.read()
145
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=2\n"
146
"key\x00key2\x00\x00\x00data\n"
94
149
def test_build_index_reference_lists_are_included_two(self):
95
150
builder = GraphIndexBuilder(reference_lists=2)
96
builder.add_node('key', 'data', ([], []))
151
builder.add_node(('key', ), 'data', ([], []))
97
152
stream = builder.finish()
98
153
contents = stream.read()
99
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=2\n"
154
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\n"
100
155
"key\x00\x00\t\x00data\n"
103
158
def test_node_references_are_byte_offsets(self):
104
159
builder = GraphIndexBuilder(reference_lists=1)
105
builder.add_node('reference', 'data', ([], ))
106
builder.add_node('key', 'data', (['reference'], ))
160
builder.add_node(('reference', ), 'data', ([], ))
161
builder.add_node(('key', ), 'data', ([('reference', )], ))
107
162
stream = builder.finish()
108
163
contents = stream.read()
109
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=1\n"
110
"key\x00\x0051\x00data\n"
164
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\n"
165
"key\x00\x0066\x00data\n"
111
166
"reference\x00\x00\x00data\n"
114
169
def test_node_references_are_cr_delimited(self):
115
170
builder = GraphIndexBuilder(reference_lists=1)
116
builder.add_node('reference', 'data', ([], ))
117
builder.add_node('reference2', 'data', ([], ))
118
builder.add_node('key', 'data', (['reference', 'reference2'], ))
171
builder.add_node(('reference', ), 'data', ([], ))
172
builder.add_node(('reference2', ), 'data', ([], ))
173
builder.add_node(('key', ), 'data', ([('reference', ), ('reference2', )], ))
119
174
stream = builder.finish()
120
175
contents = stream.read()
121
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=1\n"
122
"key\x00\x0054\r71\x00data\n"
176
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\n"
177
"key\x00\x00071\r088\x00data\n"
123
178
"reference\x00\x00\x00data\n"
124
179
"reference2\x00\x00\x00data\n"
127
182
def test_multiple_reference_lists_are_tab_delimited(self):
128
183
builder = GraphIndexBuilder(reference_lists=2)
129
builder.add_node('keference', 'data', ([], []))
130
builder.add_node('rey', 'data', (['keference'], ['keference']))
184
builder.add_node(('keference', ), 'data', ([], []))
185
builder.add_node(('rey', ), 'data', ([('keference', )], [('keference', )]))
131
186
stream = builder.finish()
132
187
contents = stream.read()
133
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=2\n"
188
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=2\nkey_elements=1\n"
134
189
"keference\x00\x00\t\x00data\n"
135
"rey\x00\x0038\t38\x00data\n"
190
"rey\x00\x0053\t53\x00data\n"
138
193
def test_add_node_referencing_missing_key_makes_absent(self):
139
194
builder = GraphIndexBuilder(reference_lists=1)
140
builder.add_node('rey', 'data', (['beference', 'aeference2'], ))
195
builder.add_node(('rey', ), 'data', ([('beference', ), ('aeference2', )], ))
141
196
stream = builder.finish()
142
197
contents = stream.read()
143
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=1\n"
198
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\n"
144
199
"aeference2\x00a\x00\x00\n"
145
200
"beference\x00a\x00\x00\n"
146
"rey\x00\x0053\r38\x00data\n"
201
"rey\x00\x0068\r53\x00data\n"
149
204
def test_node_references_three_digits(self):
150
205
# test the node digit expands as needed.
151
206
builder = GraphIndexBuilder(reference_lists=1)
152
references = map(str, reversed(range(9)))
153
builder.add_node('2-key', '', (references, ))
207
references = [(str(val), ) for val in reversed(range(9))]
208
builder.add_node(('2-key', ), '', (references, ))
154
209
stream = builder.finish()
155
210
contents = stream.read()
156
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=1\n"
211
self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=1\nkey_elements=1\n"
157
212
"0\x00a\x00\x00\n"
158
213
"1\x00a\x00\x00\n"
159
214
"2\x00a\x00\x00\n"
160
"2-key\x00\x00130\r124\r118\r112\r106\r100\r050\r044\r038\x00\n"
215
"2-key\x00\x00145\r139\r133\r127\r121\r115\r065\r059\r053\x00\n"
161
216
"3\x00a\x00\x00\n"
162
217
"4\x00a\x00\x00\n"
163
218
"5\x00a\x00\x00\n"
183
238
builder = GraphIndexBuilder()
184
239
for bad_char in '\t\n\x0b\x0c\r\x00 ':
185
240
self.assertRaises(errors.BadIndexKey, builder.add_node,
186
'a%skey' % bad_char, 'data')
187
self.assertRaises(errors.BadIndexKey, builder.add_node,
241
('a%skey' % bad_char, ), 'data')
242
self.assertRaises(errors.BadIndexKey, builder.add_node,
244
self.assertRaises(errors.BadIndexKey, builder.add_node,
245
'not-a-tuple', 'data')
247
self.assertRaises(errors.BadIndexKey, builder.add_node,
250
self.assertRaises(errors.BadIndexKey, builder.add_node,
251
('primary', 'secondary'), 'data')
252
# secondary key elements get checked too:
253
builder = GraphIndexBuilder(key_elements=2)
254
for bad_char in '\t\n\x0b\x0c\r\x00 ':
255
self.assertRaises(errors.BadIndexKey, builder.add_node,
256
('prefix', 'a%skey' % bad_char), 'data')
190
258
def test_add_node_bad_data(self):
191
259
builder = GraphIndexBuilder()
192
self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
260
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
194
self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
262
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
197
265
def test_add_node_bad_mismatched_ref_lists_length(self):
198
266
builder = GraphIndexBuilder()
199
self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
267
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
200
268
'data aa', ([], ))
201
269
builder = GraphIndexBuilder(reference_lists=1)
202
self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
270
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
204
self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
272
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
206
self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
274
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
207
275
'data aa', ([], []))
208
276
builder = GraphIndexBuilder(reference_lists=2)
209
self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
277
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
211
self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
279
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
212
280
'data aa', ([], ))
213
self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
281
self.assertRaises(errors.BadIndexValue, builder.add_node, ('akey', ),
214
282
'data aa', ([], [], []))
216
284
def test_add_node_bad_key_in_reference_lists(self):
217
285
# first list, first key - trivial
218
286
builder = GraphIndexBuilder(reference_lists=1)
219
self.assertRaises(errors.BadIndexKey, builder.add_node, 'akey',
220
'data aa', (['a key'], ))
287
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
288
'data aa', ([('a key', )], ))
289
# references keys must be tuples too
290
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
291
'data aa', (['not-a-tuple'], ))
293
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
296
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
297
'data aa', ([('primary', 'secondary')], ))
221
298
# need to check more than the first key in the list
222
self.assertRaises(errors.BadIndexKey, builder.add_node, 'akey',
223
'data aa', (['agoodkey', 'this is a bad key'], ))
299
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
300
'data aa', ([('agoodkey', ), ('that is a bad key', )], ))
224
301
# and if there is more than one list it should be getting checked
226
303
builder = GraphIndexBuilder(reference_lists=2)
227
self.assertRaises(errors.BadIndexKey, builder.add_node, 'akey',
304
self.assertRaises(errors.BadIndexKey, builder.add_node, ('akey', ),
228
305
'data aa', ([], ['a bad key']))
230
307
def test_add_duplicate_key(self):
231
308
builder = GraphIndexBuilder()
232
builder.add_node('key', 'data')
233
self.assertRaises(errors.BadIndexDuplicateKey, builder.add_node, 'key',
309
builder.add_node(('key', ), 'data')
310
self.assertRaises(errors.BadIndexDuplicateKey, builder.add_node, ('key', ),
313
def test_add_duplicate_key_2_elements(self):
314
builder = GraphIndexBuilder(key_elements=2)
315
builder.add_node(('key', 'key'), 'data')
316
self.assertRaises(errors.BadIndexDuplicateKey, builder.add_node,
317
('key', 'key'), 'data')
236
319
def test_add_key_after_referencing_key(self):
237
320
builder = GraphIndexBuilder(reference_lists=1)
238
builder.add_node('key', 'data', (['reference'], ))
239
builder.add_node('reference', 'data', ([],))
321
builder.add_node(('key', ), 'data', ([('reference', )], ))
322
builder.add_node(('reference', ), 'data', ([],))
324
def test_add_key_after_referencing_key_2_elements(self):
325
builder = GraphIndexBuilder(reference_lists=1, key_elements=2)
326
builder.add_node(('k', 'ey'), 'data', ([('reference', 'tokey')], ))
327
builder.add_node(('reference', 'tokey'), 'data', ([],))
242
330
class TestGraphIndex(TestCaseWithMemoryTransport):
244
def make_index(self, ref_lists=0, nodes=[]):
245
builder = GraphIndexBuilder(ref_lists)
332
def make_index(self, ref_lists=0, key_elements=1, nodes=[]):
333
builder = GraphIndexBuilder(ref_lists, key_elements=key_elements)
246
334
for node, value, references in nodes:
247
335
builder.add_node(node, value, references)
248
336
stream = builder.finish()
260
348
self.assertEqual([], list(index.iter_all_entries()))
262
350
def test_iter_all_entries_simple(self):
263
index = self.make_index(nodes=[('name', 'data', ())])
264
self.assertEqual([('name', 'data')],
351
index = self.make_index(nodes=[(('name', ), 'data', ())])
352
self.assertEqual([(('name', ), 'data')],
353
list(index.iter_all_entries()))
355
def test_iter_all_entries_simple_2_elements(self):
356
index = self.make_index(key_elements=2,
357
nodes=[(('name', 'surname'), 'data', ())])
358
self.assertEqual([(('name', 'surname'), 'data')],
265
359
list(index.iter_all_entries()))
267
361
def test_iter_all_entries_references_resolved(self):
268
362
index = self.make_index(1, nodes=[
269
('name', 'data', (['ref'], )),
270
('ref', 'refdata', ([], ))])
271
self.assertEqual(set([('name', 'data', (('ref',),)),
272
('ref', 'refdata', ((), ))]),
363
(('name', ), 'data', ([('ref', )], )),
364
(('ref', ), 'refdata', ([], ))])
365
self.assertEqual(set([(('name', ), 'data', ((('ref',),),)),
366
(('ref', ), 'refdata', ((), ))]),
273
367
set(index.iter_all_entries()))
275
369
def test_iteration_absent_skipped(self):
276
370
index = self.make_index(1, nodes=[
277
('name', 'data', (['ref'], ))])
278
self.assertEqual(set([('name', 'data', (('ref',),))]),
279
set(index.iter_all_entries()))
280
self.assertEqual(set([('name', 'data', (('ref',),))]),
281
set(index.iter_entries(['name'])))
282
self.assertEqual([], list(index.iter_entries(['ref'])))
371
(('name', ), 'data', ([('ref', )], ))])
372
self.assertEqual(set([(('name', ), 'data', ((('ref',),),))]),
373
set(index.iter_all_entries()))
374
self.assertEqual(set([(('name', ), 'data', ((('ref',),),))]),
375
set(index.iter_entries([('name', )])))
376
self.assertEqual([], list(index.iter_entries([('ref', )])))
378
def test_iteration_absent_skipped_2_element_keys(self):
379
index = self.make_index(1, key_elements=2, nodes=[
380
(('name', 'fin'), 'data', ([('ref', 'erence')], ))])
381
self.assertEqual(set([(('name', 'fin'), 'data', ((('ref', 'erence'),),))]),
382
set(index.iter_all_entries()))
383
self.assertEqual(set([(('name', 'fin'), 'data', ((('ref', 'erence'),),))]),
384
set(index.iter_entries([('name', 'fin')])))
385
self.assertEqual([], list(index.iter_entries([('ref', 'erence')])))
284
387
def test_iter_all_keys(self):
285
388
index = self.make_index(1, nodes=[
286
('name', 'data', (['ref'], )),
287
('ref', 'refdata', ([], ))])
288
self.assertEqual(set([('name', 'data', (('ref',),)),
289
('ref', 'refdata', ((), ))]),
290
set(index.iter_entries(['name', 'ref'])))
389
(('name', ), 'data', ([('ref', )], )),
390
(('ref', ), 'refdata', ([], ))])
391
self.assertEqual(set([(('name', ), 'data', ((('ref',),),)),
392
(('ref', ), 'refdata', ((), ))]),
393
set(index.iter_entries([('name', ), ('ref', )])))
292
395
def test_iter_nothing_empty(self):
293
396
index = self.make_index()
296
399
def test_iter_missing_entry_empty(self):
297
400
index = self.make_index()
298
self.assertEqual([], list(index.iter_entries(['a'])))
401
self.assertEqual([], list(index.iter_entries([('a', )])))
403
def test_iter_key_prefix_1_element_key_None(self):
404
index = self.make_index()
405
self.assertRaises(errors.BadIndexKey, list,
406
index.iter_entries_prefix([(None, )]))
408
def test_iter_key_prefix_wrong_length(self):
409
index = self.make_index()
410
self.assertRaises(errors.BadIndexKey, list,
411
index.iter_entries_prefix([('foo', None)]))
412
index = self.make_index(key_elements=2)
413
self.assertRaises(errors.BadIndexKey, list,
414
index.iter_entries_prefix([('foo', )]))
415
self.assertRaises(errors.BadIndexKey, list,
416
index.iter_entries_prefix([('foo', None, None)]))
418
def test_iter_key_prefix_1_key_element_no_refs(self):
419
index = self.make_index( nodes=[
420
(('name', ), 'data', ()),
421
(('ref', ), 'refdata', ())])
422
self.assertEqual(set([(('name', ), 'data'),
423
(('ref', ), 'refdata')]),
424
set(index.iter_entries_prefix([('name', ), ('ref', )])))
426
def test_iter_key_prefix_1_key_element_refs(self):
427
index = self.make_index(1, nodes=[
428
(('name', ), 'data', ([('ref', )], )),
429
(('ref', ), 'refdata', ([], ))])
430
self.assertEqual(set([(('name', ), 'data', ((('ref',),),)),
431
(('ref', ), 'refdata', ((), ))]),
432
set(index.iter_entries_prefix([('name', ), ('ref', )])))
434
def test_iter_key_prefix_2_key_element_no_refs(self):
435
index = self.make_index(key_elements=2, nodes=[
436
(('name', 'fin1'), 'data', ()),
437
(('name', 'fin2'), 'beta', ()),
438
(('ref', 'erence'), 'refdata', ())])
439
self.assertEqual(set([(('name', 'fin1'), 'data'),
440
(('ref', 'erence'), 'refdata')]),
441
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
442
self.assertEqual(set([(('name', 'fin1'), 'data'),
443
(('name', 'fin2'), 'beta')]),
444
set(index.iter_entries_prefix([('name', None)])))
446
def test_iter_key_prefix_2_key_element_refs(self):
447
index = self.make_index(1, key_elements=2, nodes=[
448
(('name', 'fin1'), 'data', ([('ref', 'erence')], )),
449
(('name', 'fin2'), 'beta', ([], )),
450
(('ref', 'erence'), 'refdata', ([], ))])
451
self.assertEqual(set([(('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
452
(('ref', 'erence'), 'refdata', ((), ))]),
453
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
454
self.assertEqual(set([(('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
455
(('name', 'fin2'), 'beta', ((), ))]),
456
set(index.iter_entries_prefix([('name', None)])))
300
458
def test_validate_bad_index_errors(self):
301
459
trans = self.get_transport()
369
527
self.assertEqual([], list(index.iter_all_entries()))
371
529
def test_iter_all_entries_simple(self):
372
index1 = self.make_index('name', nodes=[('name', 'data', ())])
530
index1 = self.make_index('name', nodes=[(('name', ), 'data', ())])
373
531
index = CombinedGraphIndex([index1])
374
self.assertEqual([('name', 'data')],
532
self.assertEqual([(('name', ), 'data')],
375
533
list(index.iter_all_entries()))
377
535
def test_iter_all_entries_two_indices(self):
378
index1 = self.make_index('name1', nodes=[('name', 'data', ())])
379
index2 = self.make_index('name2', nodes=[('2', '', ())])
536
index1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
537
index2 = self.make_index('name2', nodes=[(('2', ), '', ())])
380
538
index = CombinedGraphIndex([index1, index2])
381
self.assertEqual([('name', 'data'),
539
self.assertEqual([(('name', ), 'data'),
383
541
list(index.iter_all_entries()))
385
543
def test_iter_entries_two_indices_dup_key(self):
386
index1 = self.make_index('name1', nodes=[('name', 'data', ())])
387
index2 = self.make_index('name2', nodes=[('name', 'data', ())])
544
index1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
545
index2 = self.make_index('name2', nodes=[(('name', ), 'data', ())])
388
546
index = CombinedGraphIndex([index1, index2])
389
self.assertEqual([('name', 'data')],
390
list(index.iter_entries(['name'])))
547
self.assertEqual([(('name', ), 'data')],
548
list(index.iter_entries([('name', )])))
392
550
def test_iter_all_entries_two_indices_dup_key(self):
393
index1 = self.make_index('name1', nodes=[('name', 'data', ())])
394
index2 = self.make_index('name2', nodes=[('name', 'data', ())])
551
index1 = self.make_index('name1', nodes=[(('name', ), 'data', ())])
552
index2 = self.make_index('name2', nodes=[(('name', ), 'data', ())])
395
553
index = CombinedGraphIndex([index1, index2])
396
self.assertEqual([('name', 'data')],
554
self.assertEqual([(('name', ), 'data')],
397
555
list(index.iter_all_entries()))
557
def test_iter_key_prefix_2_key_element_refs(self):
558
index1 = self.make_index('1', 1, key_elements=2, nodes=[
559
(('name', 'fin1'), 'data', ([('ref', 'erence')], ))])
560
index2 = self.make_index('2', 1, key_elements=2, nodes=[
561
(('name', 'fin2'), 'beta', ([], )),
562
(('ref', 'erence'), 'refdata', ([], ))])
563
index = CombinedGraphIndex([index1, index2])
564
self.assertEqual(set([(('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
565
(('ref', 'erence'), 'refdata', ((), ))]),
566
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
567
self.assertEqual(set([(('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
568
(('name', 'fin2'), 'beta', ((), ))]),
569
set(index.iter_entries_prefix([('name', None)])))
399
571
def test_iter_nothing_empty(self):
400
572
index = CombinedGraphIndex([])
401
573
self.assertEqual([], list(index.iter_entries([])))
408
580
def test_iter_all_keys(self):
409
581
index1 = self.make_index('1', 1, nodes=[
410
('name', 'data', (['ref'], ))])
582
(('name', ), 'data', ([('ref', )], ))])
411
583
index2 = self.make_index('2', 1, nodes=[
412
('ref', 'refdata', ((), ))])
584
(('ref', ), 'refdata', ((), ))])
413
585
index = CombinedGraphIndex([index1, index2])
414
self.assertEqual(set([('name', 'data', (('ref', ), )),
415
('ref', 'refdata', ((), ))]),
416
set(index.iter_entries(['name', 'ref'])))
586
self.assertEqual(set([(('name', ), 'data', ((('ref', ), ), )),
587
(('ref', ), 'refdata', ((), ))]),
588
set(index.iter_entries([('name', ), ('ref', )])))
418
590
def test_iter_all_keys_dup_entry(self):
419
591
index1 = self.make_index('1', 1, nodes=[
420
('name', 'data', (['ref'], )),
421
('ref', 'refdata', ([], ))])
592
(('name', ), 'data', ([('ref', )], )),
593
(('ref', ), 'refdata', ([], ))])
422
594
index2 = self.make_index('2', 1, nodes=[
423
('ref', 'refdata', ([], ))])
595
(('ref', ), 'refdata', ([], ))])
424
596
index = CombinedGraphIndex([index1, index2])
425
self.assertEqual(set([('name', 'data', (('ref',),)),
426
('ref', 'refdata', ((), ))]),
427
set(index.iter_entries(['name', 'ref'])))
597
self.assertEqual(set([(('name', ), 'data', ((('ref',),),)),
598
(('ref', ), 'refdata', ((), ))]),
599
set(index.iter_entries([('name', ), ('ref', )])))
429
601
def test_iter_missing_entry_empty(self):
430
602
index = CombinedGraphIndex([])
431
self.assertEqual([], list(index.iter_entries(['a'])))
603
self.assertEqual([], list(index.iter_entries([('a', )])))
433
605
def test_iter_missing_entry_one_index(self):
434
606
index1 = self.make_index('1')
435
607
index = CombinedGraphIndex([index1])
436
self.assertEqual([], list(index.iter_entries(['a'])))
608
self.assertEqual([], list(index.iter_entries([('a', )])))
438
610
def test_iter_missing_entry_two_index(self):
439
611
index1 = self.make_index('1')
440
612
index2 = self.make_index('2')
441
613
index = CombinedGraphIndex([index1, index2])
442
self.assertEqual([], list(index.iter_entries(['a'])))
614
self.assertEqual([], list(index.iter_entries([('a', )])))
444
616
def test_iter_entry_present_one_index_only(self):
445
index1 = self.make_index('1', nodes=[('key', '', ())])
617
index1 = self.make_index('1', nodes=[(('key', ), '', ())])
446
618
index2 = self.make_index('2', nodes=[])
447
619
index = CombinedGraphIndex([index1, index2])
448
self.assertEqual([('key', '')],
449
list(index.iter_entries(['key'])))
620
self.assertEqual([(('key', ), '')],
621
list(index.iter_entries([('key', )])))
450
622
# and in the other direction
451
623
index = CombinedGraphIndex([index2, index1])
452
self.assertEqual([('key', '')],
453
list(index.iter_entries(['key'])))
624
self.assertEqual([(('key', ), '')],
625
list(index.iter_entries([('key', )])))
455
627
def test_validate_bad_child_index_errors(self):
456
628
trans = self.get_transport()
467
639
class TestInMemoryGraphIndex(TestCaseWithMemoryTransport):
469
def make_index(self, ref_lists=0, nodes=[]):
470
result = InMemoryGraphIndex(ref_lists)
641
def make_index(self, ref_lists=0, key_elements=1, nodes=[]):
642
result = InMemoryGraphIndex(ref_lists, key_elements=key_elements)
471
643
result.add_nodes(nodes)
646
def test_add_nodes_no_refs(self):
647
index = self.make_index(0)
648
index.add_nodes([(('name', ), 'data')])
649
index.add_nodes([(('name2', ), ''), (('name3', ), '')])
650
self.assertEqual(set([
651
(('name', ), 'data'),
654
]), set(index.iter_all_entries()))
474
656
def test_add_nodes(self):
475
657
index = self.make_index(1)
476
index.add_nodes([('name', 'data', ([],))])
477
index.add_nodes([('name2', '', ([],)), ('name3', '', (['r'],))])
658
index.add_nodes([(('name', ), 'data', ([],))])
659
index.add_nodes([(('name2', ), '', ([],)), (('name3', ), '', ([('r', )],))])
478
660
self.assertEqual(set([
479
('name', 'data', ((),)),
480
('name2', '', ((),)),
481
('name3', '', (('r',),)),
661
(('name', ), 'data', ((),)),
662
(('name2', ), '', ((),)),
663
(('name3', ), '', ((('r', ), ), )),
482
664
]), set(index.iter_all_entries()))
484
666
def test_iter_all_entries_empty(self):
486
668
self.assertEqual([], list(index.iter_all_entries()))
488
670
def test_iter_all_entries_simple(self):
489
index = self.make_index(nodes=[('name', 'data', ())])
490
self.assertEqual([('name', 'data')],
671
index = self.make_index(nodes=[(('name', ), 'data')])
672
self.assertEqual([(('name', ), 'data')],
491
673
list(index.iter_all_entries()))
493
675
def test_iter_all_entries_references(self):
494
676
index = self.make_index(1, nodes=[
495
('name', 'data', (['ref'], )),
496
('ref', 'refdata', ([], ))])
497
self.assertEqual(set([('name', 'data', (('ref',),)),
498
('ref', 'refdata', ((), ))]),
677
(('name', ), 'data', ([('ref', )], )),
678
(('ref', ), 'refdata', ([], ))])
679
self.assertEqual(set([(('name', ), 'data', ((('ref', ),),)),
680
(('ref', ), 'refdata', ((), ))]),
499
681
set(index.iter_all_entries()))
501
683
def test_iteration_absent_skipped(self):
502
684
index = self.make_index(1, nodes=[
503
('name', 'data', (['ref'], ))])
504
self.assertEqual(set([('name', 'data', (('ref',),))]),
685
(('name', ), 'data', ([('ref', )], ))])
686
self.assertEqual(set([(('name', ), 'data', ((('ref',),),))]),
505
687
set(index.iter_all_entries()))
506
self.assertEqual(set([('name', 'data', (('ref',),))]),
507
set(index.iter_entries(['name'])))
508
self.assertEqual([], list(index.iter_entries(['ref'])))
688
self.assertEqual(set([(('name', ), 'data', ((('ref',),),))]),
689
set(index.iter_entries([('name', )])))
690
self.assertEqual([], list(index.iter_entries([('ref', )])))
510
692
def test_iter_all_keys(self):
511
693
index = self.make_index(1, nodes=[
512
('name', 'data', (['ref'], )),
513
('ref', 'refdata', ([], ))])
514
self.assertEqual(set([('name', 'data', (('ref',),)),
515
('ref', 'refdata', ((), ))]),
516
set(index.iter_entries(['name', 'ref'])))
694
(('name', ), 'data', ([('ref', )], )),
695
(('ref', ), 'refdata', ([], ))])
696
self.assertEqual(set([(('name', ), 'data', ((('ref',),),)),
697
(('ref', ), 'refdata', ((), ))]),
698
set(index.iter_entries([('name', ), ('ref', )])))
700
def test_iter_key_prefix_1_key_element_no_refs(self):
701
index = self.make_index( nodes=[
702
(('name', ), 'data'),
703
(('ref', ), 'refdata')])
704
self.assertEqual(set([(('name', ), 'data'),
705
(('ref', ), 'refdata')]),
706
set(index.iter_entries_prefix([('name', ), ('ref', )])))
708
def test_iter_key_prefix_1_key_element_refs(self):
709
index = self.make_index(1, nodes=[
710
(('name', ), 'data', ([('ref', )], )),
711
(('ref', ), 'refdata', ([], ))])
712
self.assertEqual(set([(('name', ), 'data', ((('ref',),),)),
713
(('ref', ), 'refdata', ((), ))]),
714
set(index.iter_entries_prefix([('name', ), ('ref', )])))
716
def test_iter_key_prefix_2_key_element_no_refs(self):
717
index = self.make_index(key_elements=2, nodes=[
718
(('name', 'fin1'), 'data'),
719
(('name', 'fin2'), 'beta'),
720
(('ref', 'erence'), 'refdata')])
721
self.assertEqual(set([(('name', 'fin1'), 'data'),
722
(('ref', 'erence'), 'refdata')]),
723
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
724
self.assertEqual(set([(('name', 'fin1'), 'data'),
725
(('name', 'fin2'), 'beta')]),
726
set(index.iter_entries_prefix([('name', None)])))
728
def test_iter_key_prefix_2_key_element_refs(self):
729
index = self.make_index(1, key_elements=2, nodes=[
730
(('name', 'fin1'), 'data', ([('ref', 'erence')], )),
731
(('name', 'fin2'), 'beta', ([], )),
732
(('ref', 'erence'), 'refdata', ([], ))])
733
self.assertEqual(set([(('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
734
(('ref', 'erence'), 'refdata', ((), ))]),
735
set(index.iter_entries_prefix([('name', 'fin1'), ('ref', 'erence')])))
736
self.assertEqual(set([(('name', 'fin1'), 'data', ((('ref', 'erence'),),)),
737
(('name', 'fin2'), 'beta', ((), ))]),
738
set(index.iter_entries_prefix([('name', None)])))
518
740
def test_iter_nothing_empty(self):
519
741
index = self.make_index()