~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_index.py

Change the order of index refs and values to make the no-graph knit index easier.

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
        contents = stream.read()
42
42
        self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=2\n\n", contents)
43
43
 
44
 
    def test_build_index_one_node(self):
45
 
        builder = GraphIndexBuilder()
46
 
        builder.add_node('akey', (), 'data')
 
44
    def test_build_index_one_node_no_refs(self):
 
45
        builder = GraphIndexBuilder()
 
46
        builder.add_node('akey', 'data')
 
47
        stream = builder.finish()
 
48
        contents = stream.read()
 
49
        self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=0\n"
 
50
            "akey\x00\x00\x00data\n\n", contents)
 
51
 
 
52
    def test_build_index_one_node_no_refs_accepts_empty_reflist(self):
 
53
        builder = GraphIndexBuilder()
 
54
        builder.add_node('akey', 'data', ())
47
55
        stream = builder.finish()
48
56
        contents = stream.read()
49
57
        self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=0\n"
51
59
 
52
60
    def test_add_node_empty_value(self):
53
61
        builder = GraphIndexBuilder()
54
 
        builder.add_node('akey', (), '')
 
62
        builder.add_node('akey', '')
55
63
        stream = builder.finish()
56
64
        contents = stream.read()
57
65
        self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=0\n"
63
71
        # use three to have a good chance of glitching dictionary hash
64
72
        # lookups etc. Insert in randomish order that is not correct
65
73
        # and not the reverse of the correct order.
66
 
        builder.add_node('2002', (), 'data')
67
 
        builder.add_node('2000', (), 'data')
68
 
        builder.add_node('2001', (), 'data')
 
74
        builder.add_node('2002', 'data')
 
75
        builder.add_node('2000', 'data')
 
76
        builder.add_node('2001', 'data')
69
77
        stream = builder.finish()
70
78
        contents = stream.read()
71
79
        self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=0\n"
76
84
 
77
85
    def test_build_index_reference_lists_are_included_one(self):
78
86
        builder = GraphIndexBuilder(reference_lists=1)
79
 
        builder.add_node('key', ([], ), 'data')
 
87
        builder.add_node('key', 'data', ([], ))
80
88
        stream = builder.finish()
81
89
        contents = stream.read()
82
90
        self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=1\n"
85
93
 
86
94
    def test_build_index_reference_lists_are_included_two(self):
87
95
        builder = GraphIndexBuilder(reference_lists=2)
88
 
        builder.add_node('key', ([], []), 'data')
 
96
        builder.add_node('key', 'data', ([], []))
89
97
        stream = builder.finish()
90
98
        contents = stream.read()
91
99
        self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=2\n"
94
102
 
95
103
    def test_node_references_are_byte_offsets(self):
96
104
        builder = GraphIndexBuilder(reference_lists=1)
97
 
        builder.add_node('reference', ([], ), 'data')
98
 
        builder.add_node('key', (['reference'], ), 'data')
 
105
        builder.add_node('reference', 'data', ([], ))
 
106
        builder.add_node('key', 'data', (['reference'], ))
99
107
        stream = builder.finish()
100
108
        contents = stream.read()
101
109
        self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=1\n"
105
113
 
106
114
    def test_node_references_are_cr_delimited(self):
107
115
        builder = GraphIndexBuilder(reference_lists=1)
108
 
        builder.add_node('reference', ([], ), 'data')
109
 
        builder.add_node('reference2', ([], ), 'data')
110
 
        builder.add_node('key', (['reference', 'reference2'], ), 'data')
 
116
        builder.add_node('reference', 'data', ([], ))
 
117
        builder.add_node('reference2', 'data', ([], ))
 
118
        builder.add_node('key', 'data', (['reference', 'reference2'], ))
111
119
        stream = builder.finish()
112
120
        contents = stream.read()
113
121
        self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=1\n"
118
126
 
119
127
    def test_multiple_reference_lists_are_tab_delimited(self):
120
128
        builder = GraphIndexBuilder(reference_lists=2)
121
 
        builder.add_node('keference', ([], []), 'data')
122
 
        builder.add_node('rey', (['keference'], ['keference']), 'data')
 
129
        builder.add_node('keference', 'data', ([], []))
 
130
        builder.add_node('rey', 'data', (['keference'], ['keference']))
123
131
        stream = builder.finish()
124
132
        contents = stream.read()
125
133
        self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=2\n"
129
137
 
130
138
    def test_add_node_referencing_missing_key_makes_absent(self):
131
139
        builder = GraphIndexBuilder(reference_lists=1)
132
 
        builder.add_node('rey', (['beference', 'aeference2'], ), 'data')
 
140
        builder.add_node('rey', 'data', (['beference', 'aeference2'], ))
133
141
        stream = builder.finish()
134
142
        contents = stream.read()
135
143
        self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=1\n"
142
150
        # test the node digit expands as needed.
143
151
        builder = GraphIndexBuilder(reference_lists=1)
144
152
        references = map(str, reversed(range(9)))
145
 
        builder.add_node('2-key', (references, ), '')
 
153
        builder.add_node('2-key', '', (references, ))
146
154
        stream = builder.finish()
147
155
        contents = stream.read()
148
156
        self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=1\n"
162
170
        # the offsets after an absent record should be correct when there are
163
171
        # >1 reference lists.
164
172
        builder = GraphIndexBuilder(reference_lists=2)
165
 
        builder.add_node('parent', (['aail', 'zther'], []), '')
 
173
        builder.add_node('parent', '', (['aail', 'zther'], []))
166
174
        stream = builder.finish()
167
175
        contents = stream.read()
168
176
        self.assertEqual("Bazaar Graph Index 1\nnode_ref_lists=2\n"
175
183
        builder = GraphIndexBuilder()
176
184
        for bad_char in '\t\n\x0b\x0c\r\x00 ':
177
185
            self.assertRaises(errors.BadIndexKey, builder.add_node,
178
 
                'a%skey' % bad_char, (), 'data')
 
186
                'a%skey' % bad_char, 'data')
179
187
        self.assertRaises(errors.BadIndexKey, builder.add_node,
180
 
                '', (), 'data')
 
188
                '', 'data')
181
189
 
182
190
    def test_add_node_bad_data(self):
183
191
        builder = GraphIndexBuilder()
184
192
        self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
185
 
            (), 'data\naa')
 
193
            'data\naa')
186
194
        self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
187
 
            (), 'data\x00aa')
 
195
            'data\x00aa')
188
196
 
189
197
    def test_add_node_bad_mismatched_ref_lists_length(self):
190
198
        builder = GraphIndexBuilder()
191
199
        self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
192
 
            ([], ), 'data aa')
 
200
            'data aa', ([], ))
193
201
        builder = GraphIndexBuilder(reference_lists=1)
194
202
        self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
195
 
            (), 'data aa')
196
 
        self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
197
 
            ([], []), 'data aa')
 
203
            'data aa')
 
204
        self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
 
205
            'data aa', (), )
 
206
        self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
 
207
            'data aa', ([], []))
198
208
        builder = GraphIndexBuilder(reference_lists=2)
199
209
        self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
200
 
            (), 'data aa')
201
 
        self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
202
 
            ([], ), 'data aa')
203
 
        self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
204
 
            ([], [], []), 'data aa')
 
210
            'data aa')
 
211
        self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
 
212
            'data aa', ([], ))
 
213
        self.assertRaises(errors.BadIndexValue, builder.add_node, 'akey',
 
214
            'data aa', ([], [], []))
205
215
 
206
216
    def test_add_node_bad_key_in_reference_lists(self):
207
217
        # first list, first key - trivial
208
218
        builder = GraphIndexBuilder(reference_lists=1)
209
219
        self.assertRaises(errors.BadIndexKey, builder.add_node, 'akey',
210
 
            (['a key'], ), 'data aa')
 
220
            'data aa', (['a key'], ))
211
221
        # need to check more than the first key in the list
212
222
        self.assertRaises(errors.BadIndexKey, builder.add_node, 'akey',
213
 
            (['agoodkey', 'this is a bad key'], ), 'data aa')
 
223
            'data aa', (['agoodkey', 'this is a bad key'], ))
214
224
        # and if there is more than one list it should be getting checked
215
225
        # too
216
226
        builder = GraphIndexBuilder(reference_lists=2)
217
227
        self.assertRaises(errors.BadIndexKey, builder.add_node, 'akey',
218
 
            ([], ['a bad key']), 'data aa')
 
228
            'data aa', ([], ['a bad key']))
219
229
 
220
230
    def test_add_duplicate_key(self):
221
231
        builder = GraphIndexBuilder()
222
 
        builder.add_node('key', (), 'data')
 
232
        builder.add_node('key', 'data')
223
233
        self.assertRaises(errors.BadIndexDuplicateKey, builder.add_node, 'key',
224
 
            (), 'data')
 
234
            'data')
225
235
 
226
236
    def test_add_key_after_referencing_key(self):
227
237
        builder = GraphIndexBuilder(reference_lists=1)
228
 
        builder.add_node('key', (['reference'], ), 'data')
229
 
        builder.add_node('reference', ([],), 'data')
 
238
        builder.add_node('key', 'data', (['reference'], ))
 
239
        builder.add_node('reference', 'data', ([],))
230
240
 
231
241
 
232
242
class TestGraphIndex(TestCaseWithMemoryTransport):
233
243
 
234
244
    def make_index(self, ref_lists=0, nodes=[]):
235
245
        builder = GraphIndexBuilder(ref_lists)
236
 
        for node, references, value in nodes:
237
 
            builder.add_node(node, references, value)
 
246
        for node, value, references in nodes:
 
247
            builder.add_node(node, value, references)
238
248
        stream = builder.finish()
239
249
        trans = self.get_transport()
240
250
        trans.put_file('index', stream)
250
260
        self.assertEqual([], list(index.iter_all_entries()))
251
261
 
252
262
    def test_iter_all_entries_simple(self):
253
 
        index = self.make_index(nodes=[('name', (), 'data')])
254
 
        self.assertEqual([('name', (), 'data')],
 
263
        index = self.make_index(nodes=[('name', 'data', ())])
 
264
        self.assertEqual([('name', 'data')],
255
265
            list(index.iter_all_entries()))
256
266
 
257
267
    def test_iter_all_entries_references_resolved(self):
258
268
        index = self.make_index(1, nodes=[
259
 
            ('name', (['ref'], ), 'data'),
260
 
            ('ref', ([], ), 'refdata')])
261
 
        self.assertEqual(set([('name', (('ref',),), 'data'),
262
 
            ('ref', ((), ), 'refdata')]),
 
269
            ('name', 'data', (['ref'], )),
 
270
            ('ref', 'refdata', ([], ))])
 
271
        self.assertEqual(set([('name', 'data', (('ref',),)),
 
272
            ('ref', 'refdata', ((), ))]),
263
273
            set(index.iter_all_entries()))
264
274
 
265
275
    def test_iteration_absent_skipped(self):
266
276
        index = self.make_index(1, nodes=[
267
 
            ('name', (['ref'], ), 'data')])
268
 
        self.assertEqual(set([('name', (('ref',),), 'data')]),
 
277
            ('name', 'data', (['ref'], ))])
 
278
        self.assertEqual(set([('name', 'data', (('ref',),))]),
269
279
            set(index.iter_all_entries()))
270
 
        self.assertEqual(set([('name', (('ref',),), 'data')]),
 
280
        self.assertEqual(set([('name', 'data', (('ref',),))]),
271
281
            set(index.iter_entries(['name'])))
272
282
        self.assertEqual([], list(index.iter_entries(['ref'])))
273
283
 
274
284
    def test_iter_all_keys(self):
275
285
        index = self.make_index(1, nodes=[
276
 
            ('name', (['ref'], ), 'data'),
277
 
            ('ref', ([], ), 'refdata')])
278
 
        self.assertEqual(set([('name', (('ref',),), 'data'),
279
 
            ('ref', ((), ), 'refdata')]),
 
286
            ('name', 'data', (['ref'], )),
 
287
            ('ref', 'refdata', ([], ))])
 
288
        self.assertEqual(set([('name', 'data', (('ref',),)),
 
289
            ('ref', 'refdata', ((), ))]),
280
290
            set(index.iter_entries(['name', 'ref'])))
281
291
 
282
292
    def test_iter_nothing_empty(self):
311
321
        self.assertRaises(errors.BadIndexData, index.validate)
312
322
 
313
323
    def test_validate_missing_end_line_nonempty(self):
314
 
        index = self.make_index(2, [('key', ([], []), '')])
 
324
        index = self.make_index(2, [('key', '', ([], []))])
315
325
        trans = self.get_transport()
316
326
        content = trans.get_bytes('index')
317
327
        # truncate the last byte
323
333
        index.validate()
324
334
 
325
335
    def test_validate_no_refs_content(self):
326
 
        index = self.make_index(nodes=[('key', (), 'value')])
 
336
        index = self.make_index(nodes=[('key', 'value', ())])
327
337
        index.validate()
328
338
 
329
339
 
331
341
 
332
342
    def make_index(self, name, ref_lists=0, nodes=[]):
333
343
        builder = GraphIndexBuilder(ref_lists)
334
 
        for node, references, value in nodes:
335
 
            builder.add_node(node, references, value)
 
344
        for node, value, references in nodes:
 
345
            builder.add_node(node, value, references)
336
346
        stream = builder.finish()
337
347
        trans = self.get_transport()
338
348
        trans.put_file(name, stream)
345
355
 
346
356
    def test_add_index(self):
347
357
        index = CombinedGraphIndex([])
348
 
        index1 = self.make_index('name', nodes=[('key', (), '')])
 
358
        index1 = self.make_index('name', 0, nodes=[('key', '', ())])
349
359
        index.insert_index(0, index1)
350
 
        self.assertEqual([('key', (), '')], list(index.iter_all_entries()))
 
360
        self.assertEqual([('key', '')], list(index.iter_all_entries()))
351
361
 
352
362
    def test_iter_all_entries_empty(self):
353
363
        index = CombinedGraphIndex([])
359
369
        self.assertEqual([], list(index.iter_all_entries()))
360
370
 
361
371
    def test_iter_all_entries_simple(self):
362
 
        index1 = self.make_index('name', nodes=[('name', (), 'data')])
 
372
        index1 = self.make_index('name', nodes=[('name', 'data', ())])
363
373
        index = CombinedGraphIndex([index1])
364
 
        self.assertEqual([('name', (), 'data')],
 
374
        self.assertEqual([('name', 'data')],
365
375
            list(index.iter_all_entries()))
366
376
 
367
377
    def test_iter_all_entries_two_indices(self):
368
 
        index1 = self.make_index('name1', nodes=[('name', (), 'data')])
369
 
        index2 = self.make_index('name2', nodes=[('2', (), '')])
 
378
        index1 = self.make_index('name1', nodes=[('name', 'data', ())])
 
379
        index2 = self.make_index('name2', nodes=[('2', '', ())])
370
380
        index = CombinedGraphIndex([index1, index2])
371
 
        self.assertEqual([('name', (), 'data'),
372
 
            ('2', (), '')],
 
381
        self.assertEqual([('name', 'data'),
 
382
            ('2', '')],
373
383
            list(index.iter_all_entries()))
374
384
 
375
385
    def test_iter_entries_two_indices_dup_key(self):
376
 
        index1 = self.make_index('name1', nodes=[('name', (), 'data')])
377
 
        index2 = self.make_index('name2', nodes=[('name', (), 'data')])
 
386
        index1 = self.make_index('name1', nodes=[('name', 'data', ())])
 
387
        index2 = self.make_index('name2', nodes=[('name', 'data', ())])
378
388
        index = CombinedGraphIndex([index1, index2])
379
 
        self.assertEqual([('name', (), 'data')],
 
389
        self.assertEqual([('name', 'data')],
380
390
            list(index.iter_entries(['name'])))
381
391
 
382
392
    def test_iter_all_entries_two_indices_dup_key(self):
383
 
        index1 = self.make_index('name1', nodes=[('name', (), 'data')])
384
 
        index2 = self.make_index('name2', nodes=[('name', (), 'data')])
 
393
        index1 = self.make_index('name1', nodes=[('name', 'data', ())])
 
394
        index2 = self.make_index('name2', nodes=[('name', 'data', ())])
385
395
        index = CombinedGraphIndex([index1, index2])
386
 
        self.assertEqual([('name', (), 'data')],
 
396
        self.assertEqual([('name', 'data')],
387
397
            list(index.iter_all_entries()))
388
398
 
389
399
    def test_iter_nothing_empty(self):
397
407
 
398
408
    def test_iter_all_keys(self):
399
409
        index1 = self.make_index('1', 1, nodes=[
400
 
            ('name', (['ref'], ), 'data')])
 
410
            ('name', 'data', (['ref'], ))])
401
411
        index2 = self.make_index('2', 1, nodes=[
402
 
            ('ref', ([], ), 'refdata')])
 
412
            ('ref', 'refdata', ((), ))])
403
413
        index = CombinedGraphIndex([index1, index2])
404
 
        self.assertEqual(set([('name', (('ref',),), 'data'),
405
 
            ('ref', ((), ), 'refdata')]),
 
414
        self.assertEqual(set([('name', 'data', (('ref', ), )),
 
415
            ('ref', 'refdata', ((), ))]),
406
416
            set(index.iter_entries(['name', 'ref'])))
407
417
 
408
418
    def test_iter_all_keys_dup_entry(self):
409
419
        index1 = self.make_index('1', 1, nodes=[
410
 
            ('name', (['ref'], ), 'data'),
411
 
            ('ref', ([], ), 'refdata')])
 
420
            ('name', 'data', (['ref'], )),
 
421
            ('ref', 'refdata', ([], ))])
412
422
        index2 = self.make_index('2', 1, nodes=[
413
 
            ('ref', ([], ), 'refdata')])
 
423
            ('ref', 'refdata', ([], ))])
414
424
        index = CombinedGraphIndex([index1, index2])
415
 
        self.assertEqual(set([('name', (('ref',),), 'data'),
416
 
            ('ref', ((), ), 'refdata')]),
 
425
        self.assertEqual(set([('name', 'data', (('ref',),)),
 
426
            ('ref', 'refdata', ((), ))]),
417
427
            set(index.iter_entries(['name', 'ref'])))
418
428
 
419
429
    def test_iter_missing_entry_empty(self):
432
442
        self.assertEqual([], list(index.iter_entries(['a'])))
433
443
 
434
444
    def test_iter_entry_present_one_index_only(self):
435
 
        index1 = self.make_index('1', nodes=[('key', (), '')])
 
445
        index1 = self.make_index('1', nodes=[('key', '', ())])
436
446
        index2 = self.make_index('2', nodes=[])
437
447
        index = CombinedGraphIndex([index1, index2])
438
 
        self.assertEqual([('key', (), '')],
 
448
        self.assertEqual([('key', '')],
439
449
            list(index.iter_entries(['key'])))
440
450
        # and in the other direction
441
451
        index = CombinedGraphIndex([index2, index1])
442
 
        self.assertEqual([('key', (), '')],
 
452
        self.assertEqual([('key', '')],
443
453
            list(index.iter_entries(['key'])))
444
454
 
445
455
    def test_validate_bad_child_index_errors(self):
463
473
 
464
474
    def test_add_nodes(self):
465
475
        index = self.make_index(1)
466
 
        index.add_nodes([('name', ([],), 'data')])
467
 
        index.add_nodes([('name2', ([],), ''), ('name3', (['r'],), '')])
 
476
        index.add_nodes([('name', 'data', ([],))])
 
477
        index.add_nodes([('name2', '', ([],)), ('name3', '', (['r'],))])
468
478
        self.assertEqual(set([
469
 
            ('name', ((),), 'data'),
470
 
            ('name2', ((),), ''),
471
 
            ('name3', (('r',),), ''),
 
479
            ('name', 'data', ((),)),
 
480
            ('name2', '', ((),)),
 
481
            ('name3', '', (('r',),)),
472
482
            ]), set(index.iter_all_entries()))
473
483
 
474
484
    def test_iter_all_entries_empty(self):
476
486
        self.assertEqual([], list(index.iter_all_entries()))
477
487
 
478
488
    def test_iter_all_entries_simple(self):
479
 
        index = self.make_index(nodes=[('name', (), 'data')])
480
 
        self.assertEqual([('name', (), 'data')],
 
489
        index = self.make_index(nodes=[('name', 'data', ())])
 
490
        self.assertEqual([('name', 'data')],
481
491
            list(index.iter_all_entries()))
482
492
 
483
493
    def test_iter_all_entries_references(self):
484
494
        index = self.make_index(1, nodes=[
485
 
            ('name', (['ref'], ), 'data'),
486
 
            ('ref', ([], ), 'refdata')])
487
 
        self.assertEqual(set([('name', (('ref',),), 'data'),
488
 
            ('ref', ((), ), 'refdata')]),
 
495
            ('name', 'data', (['ref'], )),
 
496
            ('ref', 'refdata', ([], ))])
 
497
        self.assertEqual(set([('name', 'data', (('ref',),)),
 
498
            ('ref', 'refdata', ((), ))]),
489
499
            set(index.iter_all_entries()))
490
500
 
491
501
    def test_iteration_absent_skipped(self):
492
502
        index = self.make_index(1, nodes=[
493
 
            ('name', (['ref'], ), 'data')])
494
 
        self.assertEqual(set([('name', (('ref',),), 'data')]),
 
503
            ('name', 'data', (['ref'], ))])
 
504
        self.assertEqual(set([('name', 'data', (('ref',),))]),
495
505
            set(index.iter_all_entries()))
496
 
        self.assertEqual(set([('name', (('ref',),), 'data')]),
 
506
        self.assertEqual(set([('name', 'data', (('ref',),))]),
497
507
            set(index.iter_entries(['name'])))
498
508
        self.assertEqual([], list(index.iter_entries(['ref'])))
499
509
 
500
510
    def test_iter_all_keys(self):
501
511
        index = self.make_index(1, nodes=[
502
 
            ('name', (['ref'], ), 'data'),
503
 
            ('ref', ([], ), 'refdata')])
504
 
        self.assertEqual(set([('name', (('ref',),), 'data'),
505
 
            ('ref', ((), ), 'refdata')]),
 
512
            ('name', 'data', (['ref'], )),
 
513
            ('ref', 'refdata', ([], ))])
 
514
        self.assertEqual(set([('name', 'data', (('ref',),)),
 
515
            ('ref', 'refdata', ((), ))]),
506
516
            set(index.iter_entries(['name', 'ref'])))
507
517
 
508
518
    def test_iter_nothing_empty(self):
518
528
        index.validate()
519
529
 
520
530
    def test_validate_no_refs_content(self):
521
 
        index = self.make_index(nodes=[('key', (), 'value')])
 
531
        index = self.make_index(nodes=[('key', 'value', ())])
522
532
        index.validate()
523
533
 
524
534