~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_knit.py

  • Committer: Robert Collins
  • Date: 2007-06-28 02:43:50 UTC
  • mfrom: (2553 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2558.
  • Revision ID: robertc@robertcollins.net-20070628024350-z8bdm0y6yz2uyf4o
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
from cStringIO import StringIO
20
20
import difflib
 
21
import gzip
 
22
import sha
21
23
 
22
24
from bzrlib import (
23
25
    errors,
33
35
    KnitVersionedFile,
34
36
    KnitPlainFactory,
35
37
    KnitAnnotateFactory,
 
38
    _KnitData,
36
39
    _KnitIndex,
37
40
    WeaveToKnit,
38
41
    )
109
112
        else:
110
113
            return StringIO("\n".join(self.file_lines))
111
114
 
 
115
    def readv(self, relpath, offsets):
 
116
        fp = self.get(relpath)
 
117
        for offset, size in offsets:
 
118
            fp.seek(offset)
 
119
            yield offset, fp.read(size)
 
120
 
112
121
    def __getattr__(self, name):
113
122
        def queue_call(*args, **kwargs):
114
123
            self.calls.append((name, args, kwargs))
115
124
        return queue_call
116
125
 
117
126
 
 
127
class LowLevelKnitDataTests(TestCase):
 
128
 
 
129
    def create_gz_content(self, text):
 
130
        sio = StringIO()
 
131
        gz_file = gzip.GzipFile(mode='wb', fileobj=sio)
 
132
        gz_file.write(text)
 
133
        gz_file.close()
 
134
        return sio.getvalue()
 
135
 
 
136
    def test_valid_knit_data(self):
 
137
        sha1sum = sha.new('foo\nbar\n').hexdigest()
 
138
        gz_txt = self.create_gz_content('version rev-id-1 2 %s\n'
 
139
                                        'foo\n'
 
140
                                        'bar\n'
 
141
                                        'end rev-id-1\n'
 
142
                                        % (sha1sum,))
 
143
        transport = MockTransport([gz_txt])
 
144
        data = _KnitData(transport, 'filename', mode='r')
 
145
        records = [('rev-id-1', 0, len(gz_txt))]
 
146
 
 
147
        contents = data.read_records(records)
 
148
        self.assertEqual({'rev-id-1':(['foo\n', 'bar\n'], sha1sum)}, contents)
 
149
 
 
150
        raw_contents = list(data.read_records_iter_raw(records))
 
151
        self.assertEqual([('rev-id-1', gz_txt)], raw_contents)
 
152
 
 
153
    def test_not_enough_lines(self):
 
154
        sha1sum = sha.new('foo\n').hexdigest()
 
155
        # record says 2 lines data says 1
 
156
        gz_txt = self.create_gz_content('version rev-id-1 2 %s\n'
 
157
                                        'foo\n'
 
158
                                        'end rev-id-1\n'
 
159
                                        % (sha1sum,))
 
160
        transport = MockTransport([gz_txt])
 
161
        data = _KnitData(transport, 'filename', mode='r')
 
162
        records = [('rev-id-1', 0, len(gz_txt))]
 
163
        self.assertRaises(errors.KnitCorrupt, data.read_records, records)
 
164
 
 
165
        # read_records_iter_raw won't detect that sort of mismatch/corruption
 
166
        raw_contents = list(data.read_records_iter_raw(records))
 
167
        self.assertEqual([('rev-id-1', gz_txt)], raw_contents)
 
168
 
 
169
    def test_too_many_lines(self):
 
170
        sha1sum = sha.new('foo\nbar\n').hexdigest()
 
171
        # record says 1 lines data says 2
 
172
        gz_txt = self.create_gz_content('version rev-id-1 1 %s\n'
 
173
                                        'foo\n'
 
174
                                        'bar\n'
 
175
                                        'end rev-id-1\n'
 
176
                                        % (sha1sum,))
 
177
        transport = MockTransport([gz_txt])
 
178
        data = _KnitData(transport, 'filename', mode='r')
 
179
        records = [('rev-id-1', 0, len(gz_txt))]
 
180
        self.assertRaises(errors.KnitCorrupt, data.read_records, records)
 
181
 
 
182
        # read_records_iter_raw won't detect that sort of mismatch/corruption
 
183
        raw_contents = list(data.read_records_iter_raw(records))
 
184
        self.assertEqual([('rev-id-1', gz_txt)], raw_contents)
 
185
 
 
186
    def test_mismatched_version_id(self):
 
187
        sha1sum = sha.new('foo\nbar\n').hexdigest()
 
188
        gz_txt = self.create_gz_content('version rev-id-1 2 %s\n'
 
189
                                        'foo\n'
 
190
                                        'bar\n'
 
191
                                        'end rev-id-1\n'
 
192
                                        % (sha1sum,))
 
193
        transport = MockTransport([gz_txt])
 
194
        data = _KnitData(transport, 'filename', mode='r')
 
195
        # We are asking for rev-id-2, but the data is rev-id-1
 
196
        records = [('rev-id-2', 0, len(gz_txt))]
 
197
        self.assertRaises(errors.KnitCorrupt, data.read_records, records)
 
198
 
 
199
        # read_records_iter_raw will notice if we request the wrong version.
 
200
        self.assertRaises(errors.KnitCorrupt, list,
 
201
                          data.read_records_iter_raw(records))
 
202
 
 
203
    def test_uncompressed_data(self):
 
204
        sha1sum = sha.new('foo\nbar\n').hexdigest()
 
205
        txt = ('version rev-id-1 2 %s\n'
 
206
               'foo\n'
 
207
               'bar\n'
 
208
               'end rev-id-1\n'
 
209
               % (sha1sum,))
 
210
        transport = MockTransport([txt])
 
211
        data = _KnitData(transport, 'filename', mode='r')
 
212
        records = [('rev-id-1', 0, len(txt))]
 
213
 
 
214
        # We don't have valid gzip data ==> corrupt
 
215
        self.assertRaises(errors.KnitCorrupt, data.read_records, records)
 
216
 
 
217
        # read_records_iter_raw will notice the bad data
 
218
        self.assertRaises(errors.KnitCorrupt, list,
 
219
                          data.read_records_iter_raw(records))
 
220
 
 
221
    def test_corrupted_data(self):
 
222
        sha1sum = sha.new('foo\nbar\n').hexdigest()
 
223
        gz_txt = self.create_gz_content('version rev-id-1 2 %s\n'
 
224
                                        'foo\n'
 
225
                                        'bar\n'
 
226
                                        'end rev-id-1\n'
 
227
                                        % (sha1sum,))
 
228
        # Change 2 bytes in the middle to \xff
 
229
        gz_txt = gz_txt[:10] + '\xff\xff' + gz_txt[12:]
 
230
        transport = MockTransport([gz_txt])
 
231
        data = _KnitData(transport, 'filename', mode='r')
 
232
        records = [('rev-id-1', 0, len(gz_txt))]
 
233
 
 
234
        self.assertRaises(errors.KnitCorrupt, data.read_records, records)
 
235
 
 
236
        # read_records_iter_raw will notice if we request the wrong version.
 
237
        self.assertRaises(errors.KnitCorrupt, list,
 
238
                          data.read_records_iter_raw(records))
 
239
 
 
240
 
118
241
class LowLevelKnitIndexTests(TestCase):
119
242
 
120
243
    def test_no_such_file(self):
156
279
            transport.calls.pop(0))
157
280
 
158
281
    def test_read_utf8_version_id(self):
 
282
        unicode_revision_id = u"version-\N{CYRILLIC CAPITAL LETTER A}"
 
283
        utf8_revision_id = unicode_revision_id.encode('utf-8')
159
284
        transport = MockTransport([
160
285
            _KnitIndex.HEADER,
161
 
            u"version-\N{CYRILLIC CAPITAL LETTER A}"
162
 
                u" option 0 1 :".encode("utf-8")
 
286
            '%s option 0 1 :' % (utf8_revision_id,)
163
287
            ])
164
288
        index = _KnitIndex(transport, "filename", "r")
165
 
        self.assertTrue(
166
 
            index.has_version(u"version-\N{CYRILLIC CAPITAL LETTER A}"))
 
289
        # _KnitIndex is a private class, and deals in utf8 revision_ids, not
 
290
        # Unicode revision_ids.
 
291
        self.assertTrue(index.has_version(utf8_revision_id))
 
292
        self.assertFalse(index.has_version(unicode_revision_id))
167
293
 
168
294
    def test_read_utf8_parents(self):
 
295
        unicode_revision_id = u"version-\N{CYRILLIC CAPITAL LETTER A}"
 
296
        utf8_revision_id = unicode_revision_id.encode('utf-8')
169
297
        transport = MockTransport([
170
298
            _KnitIndex.HEADER,
171
 
            u"version option 0 1"
172
 
                u" .version-\N{CYRILLIC CAPITAL LETTER A} :".encode("utf-8")
 
299
            "version option 0 1 .%s :" % (utf8_revision_id,)
173
300
            ])
174
301
        index = _KnitIndex(transport, "filename", "r")
175
 
        self.assertEqual([u"version-\N{CYRILLIC CAPITAL LETTER A}"],
 
302
        self.assertEqual([utf8_revision_id],
176
303
            index.get_parents_with_ghosts("version"))
177
304
 
178
305
    def test_read_ignore_corrupted_lines(self):
184
311
            ])
185
312
        index = _KnitIndex(transport, "filename", "r")
186
313
        self.assertEqual(1, index.num_versions())
187
 
        self.assertTrue(index.has_version(u"version"))
 
314
        self.assertTrue(index.has_version("version"))
188
315
 
189
316
    def test_read_corrupted_header(self):
190
317
        transport = MockTransport(['not a bzr knit index header\n'])
201
328
            ])
202
329
        index = _KnitIndex(transport, "filename", "r")
203
330
        self.assertEqual(2, index.num_versions())
204
 
        self.assertEqual(1, index.lookup(u"version"))
205
 
        self.assertEqual((3, 4), index.get_position(u"version"))
206
 
        self.assertEqual(["options3"], index.get_options(u"version"))
207
 
        self.assertEqual([u"parent", u"other"],
208
 
            index.get_parents_with_ghosts(u"version"))
 
331
        self.assertEqual(1, index.lookup("version"))
 
332
        self.assertEqual((3, 4), index.get_position("version"))
 
333
        self.assertEqual(["options3"], index.get_options("version"))
 
334
        self.assertEqual(["parent", "other"],
 
335
            index.get_parents_with_ghosts("version"))
209
336
 
210
337
    def test_read_compressed_parents(self):
211
338
        transport = MockTransport([
215
342
            "c option 0 1 1 0 :",
216
343
            ])
217
344
        index = _KnitIndex(transport, "filename", "r")
218
 
        self.assertEqual([u"a"], index.get_parents(u"b"))
219
 
        self.assertEqual([u"b", u"a"], index.get_parents(u"c"))
 
345
        self.assertEqual(["a"], index.get_parents("b"))
 
346
        self.assertEqual(["b", "a"], index.get_parents("c"))
220
347
 
221
348
    def test_write_utf8_version_id(self):
 
349
        unicode_revision_id = u"version-\N{CYRILLIC CAPITAL LETTER A}"
 
350
        utf8_revision_id = unicode_revision_id.encode('utf-8')
222
351
        transport = MockTransport([
223
352
            _KnitIndex.HEADER
224
353
            ])
225
354
        index = _KnitIndex(transport, "filename", "r")
226
 
        index.add_version(u"version-\N{CYRILLIC CAPITAL LETTER A}",
227
 
            ["option"], 0, 1, [])
 
355
        index.add_version(utf8_revision_id, ["option"], 0, 1, [])
228
356
        self.assertEqual(("append_bytes", ("filename",
229
 
            u"\nversion-\N{CYRILLIC CAPITAL LETTER A}"
230
 
                u" option 0 1  :".encode("utf-8")),
 
357
            "\n%s option 0 1  :" % (utf8_revision_id,)),
231
358
            {}),
232
359
            transport.calls.pop(0))
233
360
 
234
361
    def test_write_utf8_parents(self):
 
362
        unicode_revision_id = u"version-\N{CYRILLIC CAPITAL LETTER A}"
 
363
        utf8_revision_id = unicode_revision_id.encode('utf-8')
235
364
        transport = MockTransport([
236
365
            _KnitIndex.HEADER
237
366
            ])
238
367
        index = _KnitIndex(transport, "filename", "r")
239
 
        index.add_version(u"version", ["option"], 0, 1,
240
 
            [u"version-\N{CYRILLIC CAPITAL LETTER A}"])
 
368
        index.add_version("version", ["option"], 0, 1, [utf8_revision_id])
241
369
        self.assertEqual(("append_bytes", ("filename",
242
 
            u"\nversion option 0 1"
243
 
                u" .version-\N{CYRILLIC CAPITAL LETTER A} :".encode("utf-8")),
 
370
            "\nversion option 0 1 .%s :" % (utf8_revision_id,)),
244
371
            {}),
245
372
            transport.calls.pop(0))
246
373
 
249
376
        index = _KnitIndex(transport, "filename", "w", create=True)
250
377
        self.assertEqual([], index.get_graph())
251
378
 
252
 
        index.add_version(u"a", ["option"], 0, 1, [u"b"])
253
 
        self.assertEqual([(u"a", [u"b"])], index.get_graph())
 
379
        index.add_version("a", ["option"], 0, 1, ["b"])
 
380
        self.assertEqual([("a", ["b"])], index.get_graph())
254
381
 
255
 
        index.add_version(u"c", ["option"], 0, 1, [u"d"])
256
 
        self.assertEqual([(u"a", [u"b"]), (u"c", [u"d"])],
 
382
        index.add_version("c", ["option"], 0, 1, ["d"])
 
383
        self.assertEqual([("a", ["b"]), ("c", ["d"])],
257
384
            sorted(index.get_graph()))
258
385
 
259
386
    def test_get_ancestry(self):
267
394
        index = _KnitIndex(transport, "filename", "r")
268
395
 
269
396
        self.assertEqual([], index.get_ancestry([]))
270
 
        self.assertEqual([u"a"], index.get_ancestry([u"a"]))
271
 
        self.assertEqual([u"a", u"b"], index.get_ancestry([u"b"]))
272
 
        self.assertEqual([u"a", u"b", u"c"], index.get_ancestry([u"c"]))
273
 
        self.assertEqual([u"a", u"b", u"c", u"d"], index.get_ancestry([u"d"]))
274
 
        self.assertEqual([u"a", u"b"], index.get_ancestry([u"a", u"b"]))
275
 
        self.assertEqual([u"a", u"b", u"c"], index.get_ancestry([u"a", u"c"]))
 
397
        self.assertEqual(["a"], index.get_ancestry(["a"]))
 
398
        self.assertEqual(["a", "b"], index.get_ancestry(["b"]))
 
399
        self.assertEqual(["a", "b", "c"], index.get_ancestry(["c"]))
 
400
        self.assertEqual(["a", "b", "c", "d"], index.get_ancestry(["d"]))
 
401
        self.assertEqual(["a", "b"], index.get_ancestry(["a", "b"]))
 
402
        self.assertEqual(["a", "b", "c"], index.get_ancestry(["a", "c"]))
276
403
 
277
 
        self.assertRaises(RevisionNotPresent, index.get_ancestry, [u"e"])
 
404
        self.assertRaises(RevisionNotPresent, index.get_ancestry, ["e"])
278
405
 
279
406
    def test_get_ancestry_with_ghosts(self):
280
407
        transport = MockTransport([
287
414
        index = _KnitIndex(transport, "filename", "r")
288
415
 
289
416
        self.assertEqual([], index.get_ancestry_with_ghosts([]))
290
 
        self.assertEqual([u"a"], index.get_ancestry_with_ghosts([u"a"]))
291
 
        self.assertEqual([u"a", u"e", u"b"],
292
 
            index.get_ancestry_with_ghosts([u"b"]))
293
 
        self.assertEqual([u"a", u"g", u"f", u"c"],
294
 
            index.get_ancestry_with_ghosts([u"c"]))
295
 
        self.assertEqual([u"a", u"g", u"f", u"c", u"k", u"j", u"h", u"d"],
296
 
            index.get_ancestry_with_ghosts([u"d"]))
297
 
        self.assertEqual([u"a", u"e", u"b"],
298
 
            index.get_ancestry_with_ghosts([u"a", u"b"]))
299
 
        self.assertEqual([u"a", u"g", u"f", u"c"],
300
 
            index.get_ancestry_with_ghosts([u"a", u"c"]))
 
417
        self.assertEqual(["a"], index.get_ancestry_with_ghosts(["a"]))
 
418
        self.assertEqual(["a", "e", "b"],
 
419
            index.get_ancestry_with_ghosts(["b"]))
 
420
        self.assertEqual(["a", "g", "f", "c"],
 
421
            index.get_ancestry_with_ghosts(["c"]))
 
422
        self.assertEqual(["a", "g", "f", "c", "k", "j", "h", "d"],
 
423
            index.get_ancestry_with_ghosts(["d"]))
 
424
        self.assertEqual(["a", "e", "b"],
 
425
            index.get_ancestry_with_ghosts(["a", "b"]))
 
426
        self.assertEqual(["a", "g", "f", "c"],
 
427
            index.get_ancestry_with_ghosts(["a", "c"]))
301
428
        self.assertEqual(
302
 
            [u"a", u"g", u"f", u"c", u"e", u"b", u"k", u"j", u"h", u"d"],
303
 
            index.get_ancestry_with_ghosts([u"b", u"d"]))
 
429
            ["a", "g", "f", "c", "e", "b", "k", "j", "h", "d"],
 
430
            index.get_ancestry_with_ghosts(["b", "d"]))
304
431
 
305
432
        self.assertRaises(RevisionNotPresent,
306
 
            index.get_ancestry_with_ghosts, [u"e"])
 
433
            index.get_ancestry_with_ghosts, ["e"])
307
434
 
308
435
    def test_num_versions(self):
309
436
        transport = MockTransport([
314
441
        self.assertEqual(0, index.num_versions())
315
442
        self.assertEqual(0, len(index))
316
443
 
317
 
        index.add_version(u"a", ["option"], 0, 1, [])
318
 
        self.assertEqual(1, index.num_versions())
319
 
        self.assertEqual(1, len(index))
320
 
 
321
 
        index.add_version(u"a", ["option2"], 1, 2, [])
322
 
        self.assertEqual(1, index.num_versions())
323
 
        self.assertEqual(1, len(index))
324
 
 
325
 
        index.add_version(u"b", ["option"], 0, 1, [])
 
444
        index.add_version("a", ["option"], 0, 1, [])
 
445
        self.assertEqual(1, index.num_versions())
 
446
        self.assertEqual(1, len(index))
 
447
 
 
448
        index.add_version("a", ["option2"], 1, 2, [])
 
449
        self.assertEqual(1, index.num_versions())
 
450
        self.assertEqual(1, len(index))
 
451
 
 
452
        index.add_version("b", ["option"], 0, 1, [])
326
453
        self.assertEqual(2, index.num_versions())
327
454
        self.assertEqual(2, len(index))
328
455
 
334
461
 
335
462
        self.assertEqual([], index.get_versions())
336
463
 
337
 
        index.add_version(u"a", ["option"], 0, 1, [])
338
 
        self.assertEqual([u"a"], index.get_versions())
339
 
 
340
 
        index.add_version(u"a", ["option"], 0, 1, [])
341
 
        self.assertEqual([u"a"], index.get_versions())
342
 
 
343
 
        index.add_version(u"b", ["option"], 0, 1, [])
344
 
        self.assertEqual([u"a", u"b"], index.get_versions())
 
464
        index.add_version("a", ["option"], 0, 1, [])
 
465
        self.assertEqual(["a"], index.get_versions())
 
466
 
 
467
        index.add_version("a", ["option"], 0, 1, [])
 
468
        self.assertEqual(["a"], index.get_versions())
 
469
 
 
470
        index.add_version("b", ["option"], 0, 1, [])
 
471
        self.assertEqual(["a", "b"], index.get_versions())
345
472
 
346
473
    def test_idx_to_name(self):
347
474
        transport = MockTransport([
351
478
            ])
352
479
        index = _KnitIndex(transport, "filename", "r")
353
480
 
354
 
        self.assertEqual(u"a", index.idx_to_name(0))
355
 
        self.assertEqual(u"b", index.idx_to_name(1))
356
 
        self.assertEqual(u"b", index.idx_to_name(-1))
357
 
        self.assertEqual(u"a", index.idx_to_name(-2))
 
481
        self.assertEqual("a", index.idx_to_name(0))
 
482
        self.assertEqual("b", index.idx_to_name(1))
 
483
        self.assertEqual("b", index.idx_to_name(-1))
 
484
        self.assertEqual("a", index.idx_to_name(-2))
358
485
 
359
486
    def test_lookup(self):
360
487
        transport = MockTransport([
364
491
            ])
365
492
        index = _KnitIndex(transport, "filename", "r")
366
493
 
367
 
        self.assertEqual(0, index.lookup(u"a"))
368
 
        self.assertEqual(1, index.lookup(u"b"))
 
494
        self.assertEqual(0, index.lookup("a"))
 
495
        self.assertEqual(1, index.lookup("b"))
369
496
 
370
497
    def test_add_version(self):
371
498
        transport = MockTransport([
373
500
            ])
374
501
        index = _KnitIndex(transport, "filename", "r")
375
502
 
376
 
        index.add_version(u"a", ["option"], 0, 1, [u"b"])
 
503
        index.add_version("a", ["option"], 0, 1, ["b"])
377
504
        self.assertEqual(("append_bytes",
378
505
            ("filename", "\na option 0 1 .b :"),
379
506
            {}), transport.calls.pop(0))
380
 
        self.assertTrue(index.has_version(u"a"))
 
507
        self.assertTrue(index.has_version("a"))
381
508
        self.assertEqual(1, index.num_versions())
382
 
        self.assertEqual((0, 1), index.get_position(u"a"))
383
 
        self.assertEqual(["option"], index.get_options(u"a"))
384
 
        self.assertEqual([u"b"], index.get_parents_with_ghosts(u"a"))
 
509
        self.assertEqual((0, 1), index.get_position("a"))
 
510
        self.assertEqual(["option"], index.get_options("a"))
 
511
        self.assertEqual(["b"], index.get_parents_with_ghosts("a"))
385
512
 
386
 
        index.add_version(u"a", ["opt"], 1, 2, [u"c"])
 
513
        index.add_version("a", ["opt"], 1, 2, ["c"])
387
514
        self.assertEqual(("append_bytes",
388
515
            ("filename", "\na opt 1 2 .c :"),
389
516
            {}), transport.calls.pop(0))
390
 
        self.assertTrue(index.has_version(u"a"))
 
517
        self.assertTrue(index.has_version("a"))
391
518
        self.assertEqual(1, index.num_versions())
392
 
        self.assertEqual((1, 2), index.get_position(u"a"))
393
 
        self.assertEqual(["opt"], index.get_options(u"a"))
394
 
        self.assertEqual([u"c"], index.get_parents_with_ghosts(u"a"))
 
519
        self.assertEqual((1, 2), index.get_position("a"))
 
520
        self.assertEqual(["opt"], index.get_options("a"))
 
521
        self.assertEqual(["c"], index.get_parents_with_ghosts("a"))
395
522
 
396
 
        index.add_version(u"b", ["option"], 2, 3, [u"a"])
 
523
        index.add_version("b", ["option"], 2, 3, ["a"])
397
524
        self.assertEqual(("append_bytes",
398
525
            ("filename", "\nb option 2 3 0 :"),
399
526
            {}), transport.calls.pop(0))
400
 
        self.assertTrue(index.has_version(u"b"))
 
527
        self.assertTrue(index.has_version("b"))
401
528
        self.assertEqual(2, index.num_versions())
402
 
        self.assertEqual((2, 3), index.get_position(u"b"))
403
 
        self.assertEqual(["option"], index.get_options(u"b"))
404
 
        self.assertEqual([u"a"], index.get_parents_with_ghosts(u"b"))
 
529
        self.assertEqual((2, 3), index.get_position("b"))
 
530
        self.assertEqual(["option"], index.get_options("b"))
 
531
        self.assertEqual(["a"], index.get_parents_with_ghosts("b"))
405
532
 
406
533
    def test_add_versions(self):
407
534
        transport = MockTransport([
410
537
        index = _KnitIndex(transport, "filename", "r")
411
538
 
412
539
        index.add_versions([
413
 
            (u"a", ["option"], 0, 1, [u"b"]),
414
 
            (u"a", ["opt"], 1, 2, [u"c"]),
415
 
            (u"b", ["option"], 2, 3, [u"a"])
 
540
            ("a", ["option"], 0, 1, ["b"]),
 
541
            ("a", ["opt"], 1, 2, ["c"]),
 
542
            ("b", ["option"], 2, 3, ["a"])
416
543
            ])
417
544
        self.assertEqual(("append_bytes", ("filename",
418
545
            "\na option 0 1 .b :"
419
546
            "\na opt 1 2 .c :"
420
547
            "\nb option 2 3 0 :"
421
548
            ), {}), transport.calls.pop(0))
422
 
        self.assertTrue(index.has_version(u"a"))
423
 
        self.assertTrue(index.has_version(u"b"))
 
549
        self.assertTrue(index.has_version("a"))
 
550
        self.assertTrue(index.has_version("b"))
424
551
        self.assertEqual(2, index.num_versions())
425
 
        self.assertEqual((1, 2), index.get_position(u"a"))
426
 
        self.assertEqual((2, 3), index.get_position(u"b"))
427
 
        self.assertEqual(["opt"], index.get_options(u"a"))
428
 
        self.assertEqual(["option"], index.get_options(u"b"))
429
 
        self.assertEqual([u"c"], index.get_parents_with_ghosts(u"a"))
430
 
        self.assertEqual([u"a"], index.get_parents_with_ghosts(u"b"))
 
552
        self.assertEqual((1, 2), index.get_position("a"))
 
553
        self.assertEqual((2, 3), index.get_position("b"))
 
554
        self.assertEqual(["opt"], index.get_options("a"))
 
555
        self.assertEqual(["option"], index.get_options("b"))
 
556
        self.assertEqual(["c"], index.get_parents_with_ghosts("a"))
 
557
        self.assertEqual(["a"], index.get_parents_with_ghosts("b"))
431
558
 
432
559
    def test_delay_create_and_add_versions(self):
433
560
        transport = MockTransport()
438
565
        self.assertEqual([], transport.calls)
439
566
 
440
567
        index.add_versions([
441
 
            (u"a", ["option"], 0, 1, [u"b"]),
442
 
            (u"a", ["opt"], 1, 2, [u"c"]),
443
 
            (u"b", ["option"], 2, 3, [u"a"])
 
568
            ("a", ["option"], 0, 1, ["b"]),
 
569
            ("a", ["opt"], 1, 2, ["c"]),
 
570
            ("b", ["option"], 2, 3, ["a"])
444
571
            ])
445
572
        name, (filename, f), kwargs = transport.calls.pop(0)
446
573
        self.assertEqual("put_file_non_atomic", name)
462
589
            ])
463
590
        index = _KnitIndex(transport, "filename", "r")
464
591
 
465
 
        self.assertTrue(index.has_version(u"a"))
466
 
        self.assertFalse(index.has_version(u"b"))
 
592
        self.assertTrue(index.has_version("a"))
 
593
        self.assertFalse(index.has_version("b"))
467
594
 
468
595
    def test_get_position(self):
469
596
        transport = MockTransport([
473
600
            ])
474
601
        index = _KnitIndex(transport, "filename", "r")
475
602
 
476
 
        self.assertEqual((0, 1), index.get_position(u"a"))
477
 
        self.assertEqual((1, 2), index.get_position(u"b"))
 
603
        self.assertEqual((0, 1), index.get_position("a"))
 
604
        self.assertEqual((1, 2), index.get_position("b"))
478
605
 
479
606
    def test_get_method(self):
480
607
        transport = MockTransport([
485
612
            ])
486
613
        index = _KnitIndex(transport, "filename", "r")
487
614
 
488
 
        self.assertEqual("fulltext", index.get_method(u"a"))
489
 
        self.assertEqual("line-delta", index.get_method(u"b"))
490
 
        self.assertRaises(errors.KnitIndexUnknownMethod, index.get_method, u"c")
 
615
        self.assertEqual("fulltext", index.get_method("a"))
 
616
        self.assertEqual("line-delta", index.get_method("b"))
 
617
        self.assertRaises(errors.KnitIndexUnknownMethod, index.get_method, "c")
491
618
 
492
619
    def test_get_options(self):
493
620
        transport = MockTransport([
497
624
            ])
498
625
        index = _KnitIndex(transport, "filename", "r")
499
626
 
500
 
        self.assertEqual(["opt1"], index.get_options(u"a"))
501
 
        self.assertEqual(["opt2", "opt3"], index.get_options(u"b"))
 
627
        self.assertEqual(["opt1"], index.get_options("a"))
 
628
        self.assertEqual(["opt2", "opt3"], index.get_options("b"))
502
629
 
503
630
    def test_get_parents(self):
504
631
        transport = MockTransport([
509
636
            ])
510
637
        index = _KnitIndex(transport, "filename", "r")
511
638
 
512
 
        self.assertEqual([], index.get_parents(u"a"))
513
 
        self.assertEqual([u"a", u"c"], index.get_parents(u"b"))
514
 
        self.assertEqual([u"b", u"a"], index.get_parents(u"c"))
 
639
        self.assertEqual([], index.get_parents("a"))
 
640
        self.assertEqual(["a", "c"], index.get_parents("b"))
 
641
        self.assertEqual(["b", "a"], index.get_parents("c"))
515
642
 
516
643
    def test_get_parents_with_ghosts(self):
517
644
        transport = MockTransport([
522
649
            ])
523
650
        index = _KnitIndex(transport, "filename", "r")
524
651
 
525
 
        self.assertEqual([], index.get_parents_with_ghosts(u"a"))
526
 
        self.assertEqual([u"a", u"c"], index.get_parents_with_ghosts(u"b"))
527
 
        self.assertEqual([u"b", u"a", u"e"],
528
 
            index.get_parents_with_ghosts(u"c"))
 
652
        self.assertEqual([], index.get_parents_with_ghosts("a"))
 
653
        self.assertEqual(["a", "c"], index.get_parents_with_ghosts("b"))
 
654
        self.assertEqual(["b", "a", "e"],
 
655
            index.get_parents_with_ghosts("c"))
529
656
 
530
657
    def test_check_versions_present(self):
531
658
        transport = MockTransport([
538
665
        check = index.check_versions_present
539
666
 
540
667
        check([])
541
 
        check([u"a"])
542
 
        check([u"b"])
543
 
        check([u"a", u"b"])
544
 
        self.assertRaises(RevisionNotPresent, check, [u"c"])
545
 
        self.assertRaises(RevisionNotPresent, check, [u"a", u"b", u"c"])
 
668
        check(["a"])
 
669
        check(["b"])
 
670
        check(["a", "b"])
 
671
        self.assertRaises(RevisionNotPresent, check, ["c"])
 
672
        self.assertRaises(RevisionNotPresent, check, ["a", "b", "c"])
546
673
 
547
674
 
548
675
class KnitTests(TestCaseWithTransport):