~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_knit.py

  • Committer: Vincent Ladeuil
  • Date: 2011-02-10 12:37:27 UTC
  • mto: This revision was merged to the branch mainline in revision 5661.
  • Revision ID: v.ladeuil+lp@free.fr-20110210123727-8e0pu4wtlt6fj7nf
thread is already a python module, avoid confusion and use cethread instead.

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
    KnitVersionedFiles,
41
41
    PlainKnitContent,
42
42
    _VFContentMapGenerator,
 
43
    _DirectPackAccess,
43
44
    _KndxIndex,
44
45
    _KnitGraphIndex,
45
46
    _KnitKeyAccess,
46
47
    make_file_factory,
47
48
    )
48
49
from bzrlib.patiencediff import PatienceSequenceMatcher
49
 
from bzrlib.repofmt import (
50
 
    knitpack_repo,
51
 
    pack_repo,
52
 
    )
 
50
from bzrlib.repofmt import pack_repo
53
51
from bzrlib.tests import (
54
52
    TestCase,
55
53
    TestCaseWithMemoryTransport,
62
60
    network_bytes_to_kind_and_offset,
63
61
    RecordingVersionedFilesDecorator,
64
62
    )
65
 
from bzrlib.tests import (
66
 
    features,
67
 
    )
68
 
 
69
 
 
70
 
compiled_knit_feature = features.ModuleAvailableFeature(
71
 
    'bzrlib._knit_load_data_pyx')
 
63
 
 
64
 
 
65
compiled_knit_feature = tests.ModuleAvailableFeature(
 
66
                            'bzrlib._knit_load_data_pyx')
72
67
 
73
68
 
74
69
class KnitContentTestsMixin(object):
330
325
            transport.append_bytes(packname, bytes)
331
326
        writer = pack.ContainerWriter(write_data)
332
327
        writer.begin()
333
 
        access = pack_repo._DirectPackAccess({})
 
328
        access = _DirectPackAccess({})
334
329
        access.set_writer(writer, index, (transport, packname))
335
330
        return access, writer
336
331
 
402
397
        collection = repo._pack_collection
403
398
        collection.ensure_loaded()
404
399
        orig_packs = collection.packs
405
 
        packer = knitpack_repo.KnitPacker(collection, orig_packs, '.testpack')
 
400
        packer = pack_repo.Packer(collection, orig_packs, '.testpack')
406
401
        new_pack = packer.pack()
407
402
        # forget about the new pack
408
403
        collection.reset()
447
442
        except _TestException, e:
448
443
            retry_exc = errors.RetryWithNewPacks(None, reload_occurred=False,
449
444
                                                 exc_info=sys.exc_info())
450
 
        # GZ 2010-08-10: Cycle with exc_info affects 3 tests
451
445
        return retry_exc
452
446
 
453
447
    def test_read_from_several_packs(self):
462
456
        memos.extend(access.add_raw_records([('key', 5)], 'alpha'))
463
457
        writer.end()
464
458
        transport = self.get_transport()
465
 
        access = pack_repo._DirectPackAccess({"FOO":(transport, 'packfile'),
 
459
        access = _DirectPackAccess({"FOO":(transport, 'packfile'),
466
460
            "FOOBAR":(transport, 'pack2'),
467
461
            "BAZ":(transport, 'pack3')})
468
462
        self.assertEqual(['1234567890', '12345', 'alpha'],
478
472
 
479
473
    def test_set_writer(self):
480
474
        """The writer should be settable post construction."""
481
 
        access = pack_repo._DirectPackAccess({})
 
475
        access = _DirectPackAccess({})
482
476
        transport = self.get_transport()
483
477
        packname = 'packfile'
484
478
        index = 'foo'
496
490
        transport = self.get_transport()
497
491
        reload_called, reload_func = self.make_reload_func()
498
492
        # Note that the index key has changed from 'foo' to 'bar'
499
 
        access = pack_repo._DirectPackAccess({'bar':(transport, 'packname')},
 
493
        access = _DirectPackAccess({'bar':(transport, 'packname')},
500
494
                                   reload_func=reload_func)
501
495
        e = self.assertListRaises(errors.RetryWithNewPacks,
502
496
                                  access.get_raw_records, memos)
511
505
        memos = self.make_pack_file()
512
506
        transport = self.get_transport()
513
507
        # Note that the index key has changed from 'foo' to 'bar'
514
 
        access = pack_repo._DirectPackAccess({'bar':(transport, 'packname')})
 
508
        access = _DirectPackAccess({'bar':(transport, 'packname')})
515
509
        e = self.assertListRaises(KeyError, access.get_raw_records, memos)
516
510
 
517
511
    def test_missing_file_raises_retry(self):
519
513
        transport = self.get_transport()
520
514
        reload_called, reload_func = self.make_reload_func()
521
515
        # Note that the 'filename' has been changed to 'different-packname'
522
 
        access = pack_repo._DirectPackAccess(
523
 
            {'foo':(transport, 'different-packname')},
524
 
            reload_func=reload_func)
 
516
        access = _DirectPackAccess({'foo':(transport, 'different-packname')},
 
517
                                   reload_func=reload_func)
525
518
        e = self.assertListRaises(errors.RetryWithNewPacks,
526
519
                                  access.get_raw_records, memos)
527
520
        # The file has gone missing, so we assume we need to reload
535
528
        memos = self.make_pack_file()
536
529
        transport = self.get_transport()
537
530
        # Note that the 'filename' has been changed to 'different-packname'
538
 
        access = pack_repo._DirectPackAccess(
539
 
            {'foo': (transport, 'different-packname')})
 
531
        access = _DirectPackAccess({'foo':(transport, 'different-packname')})
540
532
        e = self.assertListRaises(errors.NoSuchFile,
541
533
                                  access.get_raw_records, memos)
542
534
 
546
538
        failing_transport = MockReadvFailingTransport(
547
539
                                [transport.get_bytes('packname')])
548
540
        reload_called, reload_func = self.make_reload_func()
549
 
        access = pack_repo._DirectPackAccess(
550
 
            {'foo': (failing_transport, 'packname')},
551
 
            reload_func=reload_func)
 
541
        access = _DirectPackAccess({'foo':(failing_transport, 'packname')},
 
542
                                   reload_func=reload_func)
552
543
        # Asking for a single record will not trigger the Mock failure
553
544
        self.assertEqual(['1234567890'],
554
545
            list(access.get_raw_records(memos[:1])))
570
561
        failing_transport = MockReadvFailingTransport(
571
562
                                [transport.get_bytes('packname')])
572
563
        reload_called, reload_func = self.make_reload_func()
573
 
        access = pack_repo._DirectPackAccess(
574
 
            {'foo':(failing_transport, 'packname')})
 
564
        access = _DirectPackAccess({'foo':(failing_transport, 'packname')})
575
565
        # Asking for a single record will not trigger the Mock failure
576
566
        self.assertEqual(['1234567890'],
577
567
            list(access.get_raw_records(memos[:1])))
582
572
                                  access.get_raw_records, memos)
583
573
 
584
574
    def test_reload_or_raise_no_reload(self):
585
 
        access = pack_repo._DirectPackAccess({}, reload_func=None)
 
575
        access = _DirectPackAccess({}, reload_func=None)
586
576
        retry_exc = self.make_retry_exception()
587
577
        # Without a reload_func, we will just re-raise the original exception
588
578
        self.assertRaises(_TestException, access.reload_or_raise, retry_exc)
589
579
 
590
580
    def test_reload_or_raise_reload_changed(self):
591
581
        reload_called, reload_func = self.make_reload_func(return_val=True)
592
 
        access = pack_repo._DirectPackAccess({}, reload_func=reload_func)
 
582
        access = _DirectPackAccess({}, reload_func=reload_func)
593
583
        retry_exc = self.make_retry_exception()
594
584
        access.reload_or_raise(retry_exc)
595
585
        self.assertEqual([1], reload_called)
599
589
 
600
590
    def test_reload_or_raise_reload_no_change(self):
601
591
        reload_called, reload_func = self.make_reload_func(return_val=False)
602
 
        access = pack_repo._DirectPackAccess({}, reload_func=reload_func)
 
592
        access = _DirectPackAccess({}, reload_func=reload_func)
603
593
        retry_exc = self.make_retry_exception()
604
594
        # If reload_occurred is False, then we consider it an error to have
605
595
        # reload_func() return False (no changes).
736
726
 
737
727
    def make_multiple_records(self):
738
728
        """Create the content for multiple records."""
739
 
        sha1sum = osutils.sha_string('foo\nbar\n')
 
729
        sha1sum = osutils.sha('foo\nbar\n').hexdigest()
740
730
        total_txt = []
741
731
        gz_txt = self.create_gz_content('version rev-id-1 2 %s\n'
742
732
                                        'foo\n'
745
735
                                        % (sha1sum,))
746
736
        record_1 = (0, len(gz_txt), sha1sum)
747
737
        total_txt.append(gz_txt)
748
 
        sha1sum = osutils.sha_string('baz\n')
 
738
        sha1sum = osutils.sha('baz\n').hexdigest()
749
739
        gz_txt = self.create_gz_content('version rev-id-2 1 %s\n'
750
740
                                        'baz\n'
751
741
                                        'end rev-id-2\n'
755
745
        return total_txt, record_1, record_2
756
746
 
757
747
    def test_valid_knit_data(self):
758
 
        sha1sum = osutils.sha_string('foo\nbar\n')
 
748
        sha1sum = osutils.sha('foo\nbar\n').hexdigest()
759
749
        gz_txt = self.create_gz_content('version rev-id-1 2 %s\n'
760
750
                                        'foo\n'
761
751
                                        'bar\n'
792
782
                         raw_contents)
793
783
 
794
784
    def test_not_enough_lines(self):
795
 
        sha1sum = osutils.sha_string('foo\n')
 
785
        sha1sum = osutils.sha('foo\n').hexdigest()
796
786
        # record says 2 lines data says 1
797
787
        gz_txt = self.create_gz_content('version rev-id-1 2 %s\n'
798
788
                                        'foo\n'
810
800
        self.assertEqual([(('rev-id-1',),  gz_txt, sha1sum)], raw_contents)
811
801
 
812
802
    def test_too_many_lines(self):
813
 
        sha1sum = osutils.sha_string('foo\nbar\n')
 
803
        sha1sum = osutils.sha('foo\nbar\n').hexdigest()
814
804
        # record says 1 lines data says 2
815
805
        gz_txt = self.create_gz_content('version rev-id-1 1 %s\n'
816
806
                                        'foo\n'
829
819
        self.assertEqual([(('rev-id-1',), gz_txt, sha1sum)], raw_contents)
830
820
 
831
821
    def test_mismatched_version_id(self):
832
 
        sha1sum = osutils.sha_string('foo\nbar\n')
 
822
        sha1sum = osutils.sha('foo\nbar\n').hexdigest()
833
823
        gz_txt = self.create_gz_content('version rev-id-1 2 %s\n'
834
824
                                        'foo\n'
835
825
                                        'bar\n'
848
838
            knit._read_records_iter_raw(records))
849
839
 
850
840
    def test_uncompressed_data(self):
851
 
        sha1sum = osutils.sha_string('foo\nbar\n')
 
841
        sha1sum = osutils.sha('foo\nbar\n').hexdigest()
852
842
        txt = ('version rev-id-1 2 %s\n'
853
843
               'foo\n'
854
844
               'bar\n'
868
858
            knit._read_records_iter_raw(records))
869
859
 
870
860
    def test_corrupted_data(self):
871
 
        sha1sum = osutils.sha_string('foo\nbar\n')
 
861
        sha1sum = osutils.sha('foo\nbar\n').hexdigest()
872
862
        gz_txt = self.create_gz_content('version rev-id-1 2 %s\n'
873
863
                                        'foo\n'
874
864
                                        'bar\n'
1196
1186
            self.assertRaises(errors.KnitCorrupt, index.keys)
1197
1187
        except TypeError, e:
1198
1188
            if (str(e) == ('exceptions must be strings, classes, or instances,'
1199
 
                           ' not exceptions.IndexError')):
 
1189
                           ' not exceptions.IndexError')
 
1190
                and sys.version_info[0:2] >= (2,5)):
1200
1191
                self.knownFailure('Pyrex <0.9.5 fails with TypeError when'
1201
1192
                                  ' raising new style exceptions with python'
1202
1193
                                  ' >=2.5')
1215
1206
            self.assertRaises(errors.KnitCorrupt, index.keys)
1216
1207
        except TypeError, e:
1217
1208
            if (str(e) == ('exceptions must be strings, classes, or instances,'
1218
 
                           ' not exceptions.ValueError')):
 
1209
                           ' not exceptions.ValueError')
 
1210
                and sys.version_info[0:2] >= (2,5)):
1219
1211
                self.knownFailure('Pyrex <0.9.5 fails with TypeError when'
1220
1212
                                  ' raising new style exceptions with python'
1221
1213
                                  ' >=2.5')
1234
1226
            self.assertRaises(errors.KnitCorrupt, index.keys)
1235
1227
        except TypeError, e:
1236
1228
            if (str(e) == ('exceptions must be strings, classes, or instances,'
1237
 
                           ' not exceptions.ValueError')):
 
1229
                           ' not exceptions.ValueError')
 
1230
                and sys.version_info[0:2] >= (2,5)):
1238
1231
                self.knownFailure('Pyrex <0.9.5 fails with TypeError when'
1239
1232
                                  ' raising new style exceptions with python'
1240
1233
                                  ' >=2.5')
1251
1244
            self.assertRaises(errors.KnitCorrupt, index.keys)
1252
1245
        except TypeError, e:
1253
1246
            if (str(e) == ('exceptions must be strings, classes, or instances,'
1254
 
                           ' not exceptions.ValueError')):
 
1247
                           ' not exceptions.ValueError')
 
1248
                and sys.version_info[0:2] >= (2,5)):
1255
1249
                self.knownFailure('Pyrex <0.9.5 fails with TypeError when'
1256
1250
                                  ' raising new style exceptions with python'
1257
1251
                                  ' >=2.5')
1268
1262
            self.assertRaises(errors.KnitCorrupt, index.keys)
1269
1263
        except TypeError, e:
1270
1264
            if (str(e) == ('exceptions must be strings, classes, or instances,'
1271
 
                           ' not exceptions.ValueError')):
 
1265
                           ' not exceptions.ValueError')
 
1266
                and sys.version_info[0:2] >= (2,5)):
1272
1267
                self.knownFailure('Pyrex <0.9.5 fails with TypeError when'
1273
1268
                                  ' raising new style exceptions with python'
1274
1269
                                  ' >=2.5')
1603
1598
        # could leave an empty .kndx file, which bzr would later claim was a
1604
1599
        # corrupted file since the header was not present. In reality, the file
1605
1600
        # just wasn't created, so it should be ignored.
1606
 
        t = transport.get_transport_from_path('.')
 
1601
        t = transport.get_transport('.')
1607
1602
        t.put_bytes('test.kndx', '')
1608
1603
 
1609
1604
        knit = self.make_test_knit()
1610
1605
 
1611
1606
    def test_knit_index_checks_header(self):
1612
 
        t = transport.get_transport_from_path('.')
 
1607
        t = transport.get_transport('.')
1613
1608
        t.put_bytes('test.kndx', '# not really a knit header\n\n')
1614
1609
        k = self.make_test_knit()
1615
1610
        self.assertRaises(KnitHeaderError, k.keys)
2443
2438
        key_basis = ('bar',)
2444
2439
        key_missing = ('missing',)
2445
2440
        test.add_lines(key, (), ['foo\n'])
2446
 
        key_sha1sum = osutils.sha_string('foo\n')
 
2441
        key_sha1sum = osutils.sha('foo\n').hexdigest()
2447
2442
        sha1s = test.get_sha1s([key])
2448
2443
        self.assertEqual({key: key_sha1sum}, sha1s)
2449
2444
        self.assertEqual([], basis.calls)
2451
2446
        # directly (rather than via text reconstruction) so that remote servers
2452
2447
        # etc don't have to answer with full content.
2453
2448
        basis.add_lines(key_basis, (), ['foo\n', 'bar\n'])
2454
 
        basis_sha1sum = osutils.sha_string('foo\nbar\n')
 
2449
        basis_sha1sum = osutils.sha('foo\nbar\n').hexdigest()
2455
2450
        basis.calls = []
2456
2451
        sha1s = test.get_sha1s([key, key_missing, key_basis])
2457
2452
        self.assertEqual({key: key_sha1sum,