~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/per_pack_repository.py

merge 2.0 branch rev 4647

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2008 Canonical Ltd
 
1
# Copyright (C) 2008, 2009 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
38
38
    upgrade,
39
39
    workingtree,
40
40
    )
41
 
from bzrlib.repofmt.groupcompress_repo import RepositoryFormatCHK1
 
41
from bzrlib.repofmt import (
 
42
    pack_repo,
 
43
    groupcompress_repo,
 
44
    )
 
45
from bzrlib.repofmt.groupcompress_repo import RepositoryFormat2a
42
46
from bzrlib.smart import (
43
47
    client,
44
48
    server,
80
84
        """Packs reuse deltas."""
81
85
        format = self.get_format()
82
86
        repo = self.make_repository('.', format=format)
83
 
        if isinstance(format.repository_format, RepositoryFormatCHK1):
 
87
        if isinstance(format.repository_format, RepositoryFormat2a):
84
88
            # TODO: This is currently a workaround. CHK format repositories
85
89
            #       ignore the 'deltas' flag, but during conversions, we can't
86
90
            #       do unordered delta fetches. Remove this clause once we
234
238
        pack_names = [node[1][0] for node in index.iter_all_entries()]
235
239
        self.assertTrue(large_pack_name in pack_names)
236
240
 
 
241
    def test_commit_write_group_returns_new_pack_names(self):
 
242
        format = self.get_format()
 
243
        tree = self.make_branch_and_tree('foo', format=format)
 
244
        tree.commit('first post')
 
245
        repo = tree.branch.repository
 
246
        repo.lock_write()
 
247
        try:
 
248
            repo.start_write_group()
 
249
            try:
 
250
                inv = inventory.Inventory(revision_id="A")
 
251
                inv.root.revision = "A"
 
252
                repo.texts.add_lines((inv.root.file_id, "A"), [], [])
 
253
                rev = _mod_revision.Revision(timestamp=0, timezone=None,
 
254
                    committer="Foo Bar <foo@example.com>", message="Message",
 
255
                    revision_id="A")
 
256
                rev.parent_ids = ()
 
257
                repo.add_revision("A", rev, inv=inv)
 
258
            except:
 
259
                repo.abort_write_group()
 
260
                raise
 
261
            else:
 
262
                old_names = repo._pack_collection._names.keys()
 
263
                result = repo.commit_write_group()
 
264
                cur_names = repo._pack_collection._names.keys()
 
265
                new_names = list(set(cur_names) - set(old_names))
 
266
                self.assertEqual(new_names, result)
 
267
        finally:
 
268
            repo.unlock()
 
269
 
237
270
    def test_fail_obsolete_deletion(self):
238
271
        # failing to delete obsolete packs is not fatal
239
272
        format = self.get_format()
262
295
        self.assertEqual(1, len(list(index.iter_all_entries())))
263
296
        self.assertEqual(2, len(tree.branch.repository.all_revision_ids()))
264
297
 
 
298
    def test_pack_preserves_all_inventories(self):
 
299
        # This is related to bug:
 
300
        #   https://bugs.launchpad.net/bzr/+bug/412198
 
301
        # Stacked repositories need to keep the inventory for parents, even
 
302
        # after a pack operation. However, it is harder to test that, then just
 
303
        # test that all inventory texts are preserved.
 
304
        format = self.get_format()
 
305
        builder = self.make_branch_builder('source', format=format)
 
306
        builder.start_series()
 
307
        builder.build_snapshot('A-id', None, [
 
308
            ('add', ('', 'root-id', 'directory', None))])
 
309
        builder.build_snapshot('B-id', None, [
 
310
            ('add', ('file', 'file-id', 'file', 'B content\n'))])
 
311
        builder.build_snapshot('C-id', None, [
 
312
            ('modify', ('file-id', 'C content\n'))])
 
313
        builder.finish_series()
 
314
        b = builder.get_branch()
 
315
        b.lock_read()
 
316
        self.addCleanup(b.unlock)
 
317
        repo = self.make_repository('repo', shared=True, format=format)
 
318
        repo.lock_write()
 
319
        self.addCleanup(repo.unlock)
 
320
        repo.fetch(b.repository, revision_id='B-id')
 
321
        inv = b.repository.iter_inventories(['C-id']).next()
 
322
        repo.start_write_group()
 
323
        repo.add_inventory('C-id', inv, ['B-id'])
 
324
        repo.commit_write_group()
 
325
        self.assertEqual([('A-id',), ('B-id',), ('C-id',)],
 
326
                         sorted(repo.inventories.keys()))
 
327
        repo.pack()
 
328
        self.assertEqual([('A-id',), ('B-id',), ('C-id',)],
 
329
                         sorted(repo.inventories.keys()))
 
330
        # Content should be preserved as well
 
331
        self.assertEqual(inv, repo.iter_inventories(['C-id']).next())
 
332
 
265
333
    def test_pack_layout(self):
266
334
        # Test that the ordering of revisions in pack repositories is
267
335
        # tip->ancestor
278
346
        # revision access tends to be tip->ancestor, so ordering that way on
279
347
        # disk is a good idea.
280
348
        for _1, key, val, refs in pack.revision_index.iter_all_entries():
281
 
            if type(format.repository_format) is RepositoryFormatCHK1:
 
349
            if type(format.repository_format) is RepositoryFormat2a:
282
350
                # group_start, group_len, internal_start, internal_len
283
351
                pos = map(int, val.split())
284
352
            else:
484
552
        def restoreFactory():
485
553
            ui.ui_factory = old_factory
486
554
        self.addCleanup(restoreFactory)
487
 
        ui.ui_factory = ui.SilentUIFactory()
488
 
        ui.ui_factory.stdin = StringIO("y\n")
 
555
        ui.ui_factory = ui.CannedInputUIFactory([True])
489
556
 
490
557
    def test_break_lock_breaks_physical_lock(self):
491
558
        repo = self.make_repository('.', format=self.get_format())
556
623
            missing_ghost.get_inventory, 'ghost')
557
624
 
558
625
    def make_write_ready_repo(self):
559
 
        repo = self.make_repository('.', format=self.get_format())
 
626
        format = self.get_format()
 
627
        if isinstance(format.repository_format, RepositoryFormat2a):
 
628
            raise TestNotApplicable("No missing compression parents")
 
629
        repo = self.make_repository('.', format=format)
560
630
        repo.lock_write()
 
631
        self.addCleanup(repo.unlock)
561
632
        repo.start_write_group()
 
633
        self.addCleanup(repo.abort_write_group)
562
634
        return repo
563
635
 
564
636
    def test_missing_inventories_compression_parent_prevents_commit(self):
565
637
        repo = self.make_write_ready_repo()
566
638
        key = ('junk',)
567
 
        if not getattr(repo.inventories._index, '_missing_compression_parents',
568
 
            None):
569
 
            raise TestSkipped("No missing compression parents")
570
639
        repo.inventories._index._missing_compression_parents.add(key)
571
640
        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
572
641
        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
573
 
        repo.abort_write_group()
574
 
        repo.unlock()
575
642
 
576
643
    def test_missing_revisions_compression_parent_prevents_commit(self):
577
644
        repo = self.make_write_ready_repo()
578
645
        key = ('junk',)
579
 
        if not getattr(repo.inventories._index, '_missing_compression_parents',
580
 
            None):
581
 
            raise TestSkipped("No missing compression parents")
582
646
        repo.revisions._index._missing_compression_parents.add(key)
583
647
        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
584
648
        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
585
 
        repo.abort_write_group()
586
 
        repo.unlock()
587
649
 
588
650
    def test_missing_signatures_compression_parent_prevents_commit(self):
589
651
        repo = self.make_write_ready_repo()
590
652
        key = ('junk',)
591
 
        if not getattr(repo.inventories._index, '_missing_compression_parents',
592
 
            None):
593
 
            raise TestSkipped("No missing compression parents")
594
653
        repo.signatures._index._missing_compression_parents.add(key)
595
654
        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
596
655
        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
597
 
        repo.abort_write_group()
598
 
        repo.unlock()
599
656
 
600
657
    def test_missing_text_compression_parent_prevents_commit(self):
601
658
        repo = self.make_write_ready_repo()
602
659
        key = ('some', 'junk')
603
 
        if not getattr(repo.inventories._index, '_missing_compression_parents',
604
 
            None):
605
 
            raise TestSkipped("No missing compression parents")
606
660
        repo.texts._index._missing_compression_parents.add(key)
607
661
        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
608
662
        e = self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
609
 
        repo.abort_write_group()
610
 
        repo.unlock()
611
663
 
612
664
    def test_supports_external_lookups(self):
613
665
        repo = self.make_repository('.', format=self.get_format())
791
843
                matching_format_name = 'pack-0.92-subtree'
792
844
            else:
793
845
                if repo._format.supports_chks:
794
 
                    matching_format_name = 'development6-rich-root'
 
846
                    matching_format_name = '2a'
795
847
                else:
796
848
                    matching_format_name = 'rich-root-pack'
797
849
            mismatching_format_name = 'pack-0.92'
824
876
        else:
825
877
            if repo.supports_rich_root():
826
878
                if repo._format.supports_chks:
827
 
                    matching_format_name = 'development6-rich-root'
 
879
                    matching_format_name = '2a'
828
880
                else:
829
881
                    matching_format_name = 'rich-root-pack'
830
882
                mismatching_format_name = 'pack-0.92-subtree'
848
900
        base.commit('foo')
849
901
        referencing = self.make_branch_and_tree('repo', format=self.get_format())
850
902
        referencing.branch.repository.add_fallback_repository(base.branch.repository)
851
 
        referencing.commit('bar')
 
903
        local_tree = referencing.branch.create_checkout('local')
 
904
        local_tree.commit('bar')
852
905
        new_instance = referencing.bzrdir.open_repository()
853
906
        new_instance.lock_read()
854
907
        self.addCleanup(new_instance.unlock)
867
920
        # and max packs policy - so we are checking the policy is honoured
868
921
        # in the test. But for now 11 commits is not a big deal in a single
869
922
        # test.
 
923
        local_tree = tree.branch.create_checkout('local')
870
924
        for x in range(9):
871
 
            tree.commit('commit %s' % x)
 
925
            local_tree.commit('commit %s' % x)
872
926
        # there should be 9 packs:
873
927
        index = self.index_class(trans, 'pack-names', None)
874
928
        self.assertEqual(9, len(list(index.iter_all_entries())))
875
929
        # committing one more should coalesce to 1 of 10.
876
 
        tree.commit('commit triggering pack')
 
930
        local_tree.commit('commit triggering pack')
877
931
        index = self.index_class(trans, 'pack-names', None)
878
932
        self.assertEqual(1, len(list(index.iter_all_entries())))
879
933
        # packing should not damage data
892
946
        # in the obsolete_packs directory.
893
947
        large_pack_name = list(index.iter_all_entries())[0][1][0]
894
948
        # finally, committing again should not touch the large pack.
895
 
        tree.commit('commit not triggering pack')
 
949
        local_tree.commit('commit not triggering pack')
896
950
        index = self.index_class(trans, 'pack-names', None)
897
951
        self.assertEqual(2, len(list(index.iter_all_entries())))
898
952
        pack_names = [node[1][0] for node in index.iter_all_entries()]
997
1051
        tree.branch.push(remote_branch)
998
1052
        autopack_calls = len([call for call in self.hpss_calls if call ==
999
1053
            'PackRepository.autopack'])
1000
 
        streaming_calls = len([call for call in self.hpss_calls if call ==
1001
 
            'Repository.insert_stream'])
 
1054
        streaming_calls = len([call for call in self.hpss_calls if call in
 
1055
            ('Repository.insert_stream', 'Repository.insert_stream_1.19')])
1002
1056
        if autopack_calls:
1003
1057
            # Non streaming server
1004
1058
            self.assertEqual(1, autopack_calls)
1043
1097
                  "(bzr 1.9)\n",
1044
1098
              format_supports_external_lookups=True,
1045
1099
              index_class=BTreeGraphIndex),
1046
 
         dict(format_name='development6-rich-root',
1047
 
              format_string='Bazaar development format - group compression '
1048
 
                  'and chk inventory (needs bzr.dev from 1.14)\n',
 
1100
         dict(format_name='2a',
 
1101
              format_string="Bazaar repository format 2a "
 
1102
                "(needs bzr 1.16 or later)\n",
1049
1103
              format_supports_external_lookups=True,
1050
1104
              index_class=BTreeGraphIndex),
1051
1105
         ]