~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_repository.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-10-24 06:48:13 UTC
  • mfrom: (2592.3.241 mbp-packrepo-as-knits)
  • Revision ID: pqm@pqm.ubuntu.com-20071024064813-wjcmv8ofabf6kdrb
Pack repositories!

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
also see this file.
23
23
"""
24
24
 
 
25
import md5
25
26
from stat import S_ISDIR
26
27
from StringIO import StringIO
27
28
 
31
32
                           UnknownFormatError,
32
33
                           UnsupportedFormatError,
33
34
                           )
 
35
from bzrlib.index import GraphIndex, InMemoryGraphIndex
34
36
from bzrlib.repository import RepositoryFormat
35
37
from bzrlib.smart import server
36
38
from bzrlib.tests import (
51
53
    upgrade,
52
54
    workingtree,
53
55
    )
54
 
from bzrlib.repofmt import knitrepo, weaverepo
 
56
from bzrlib.repofmt import knitrepo, weaverepo, pack_repo
55
57
 
56
58
 
57
59
class TestDefaultFormat(TestCase):
670
672
 
671
673
 
672
674
class TestWithBrokenRepo(TestCaseWithTransport):
 
675
    """These tests seem to be more appropriate as interface tests?"""
673
676
 
674
677
    def make_broken_repository(self):
675
678
        # XXX: This function is borrowed from Aaron's "Reconcile can fix bad
749
752
        broken_repo = self.make_broken_repository()
750
753
        empty_repo = self.make_repository('empty-repo')
751
754
        stream = broken_repo.get_data_stream(['rev1a', 'rev2', 'rev3'])
752
 
        self.assertRaises(
753
 
            errors.KnitCorrupt, empty_repo.insert_data_stream, stream)
754
 
 
 
755
        empty_repo.lock_write()
 
756
        self.addCleanup(empty_repo.unlock)
 
757
        empty_repo.start_write_group()
 
758
        try:
 
759
            self.assertRaises(
 
760
                errors.KnitCorrupt, empty_repo.insert_data_stream, stream)
 
761
        finally:
 
762
            empty_repo.abort_write_group()
 
763
 
 
764
 
 
765
class TestExperimentalNoSubtrees(TestCaseWithTransport):
 
766
 
 
767
    def get_format(self):
 
768
        return bzrdir.format_registry.make_bzrdir('experimental')
 
769
 
 
770
    def test_disk_layout(self):
 
771
        format = self.get_format()
 
772
        repo = self.make_repository('.', format=format)
 
773
        # in case of side effects of locking.
 
774
        repo.lock_write()
 
775
        repo.unlock()
 
776
        t = repo.bzrdir.get_repository_transport(None)
 
777
        self.check_format(t)
 
778
        # XXX: no locks left when unlocked at the moment
 
779
        # self.assertEqualDiff('', t.get('lock').read())
 
780
        self.check_databases(t)
 
781
 
 
782
    def check_format(self, t):
 
783
        self.assertEqualDiff('Bazaar Experimental no-subtrees\n',
 
784
                             t.get('format').read())
 
785
 
 
786
    def assertHasKndx(self, t, knit_name):
 
787
        """Assert that knit_name exists on t."""
 
788
        self.assertEqualDiff('# bzr knit index 8\n',
 
789
                             t.get(knit_name + '.kndx').read())
 
790
 
 
791
    def assertHasNoKndx(self, t, knit_name):
 
792
        """Assert that knit_name has no index on t."""
 
793
        self.assertFalse(t.has(knit_name + '.kndx'))
 
794
 
 
795
    def assertHasNoKnit(self, t, knit_name):
 
796
        """Assert that knit_name exists on t."""
 
797
        # no default content
 
798
        self.assertFalse(t.has(knit_name + '.knit'))
 
799
 
 
800
    def check_databases(self, t):
 
801
        """check knit content for a repository."""
 
802
        # check conversion worked
 
803
        self.assertHasNoKndx(t, 'inventory')
 
804
        self.assertHasNoKnit(t, 'inventory')
 
805
        self.assertHasNoKndx(t, 'revisions')
 
806
        self.assertHasNoKnit(t, 'revisions')
 
807
        self.assertHasNoKndx(t, 'signatures')
 
808
        self.assertHasNoKnit(t, 'signatures')
 
809
        self.assertFalse(t.has('knits'))
 
810
        # revision-indexes file-container directory
 
811
        self.assertEqual([],
 
812
            list(GraphIndex(t, 'pack-names', None).iter_all_entries()))
 
813
        self.assertTrue(S_ISDIR(t.stat('packs').st_mode))
 
814
        self.assertTrue(S_ISDIR(t.stat('upload').st_mode))
 
815
        self.assertTrue(S_ISDIR(t.stat('indices').st_mode))
 
816
        self.assertTrue(S_ISDIR(t.stat('obsolete_packs').st_mode))
 
817
 
 
818
    def test_shared_disk_layout(self):
 
819
        format = self.get_format()
 
820
        repo = self.make_repository('.', shared=True, format=format)
 
821
        # we want:
 
822
        t = repo.bzrdir.get_repository_transport(None)
 
823
        self.check_format(t)
 
824
        # XXX: no locks left when unlocked at the moment
 
825
        # self.assertEqualDiff('', t.get('lock').read())
 
826
        # We should have a 'shared-storage' marker file.
 
827
        self.assertEqualDiff('', t.get('shared-storage').read())
 
828
        self.check_databases(t)
 
829
 
 
830
    def test_shared_no_tree_disk_layout(self):
 
831
        format = self.get_format()
 
832
        repo = self.make_repository('.', shared=True, format=format)
 
833
        repo.set_make_working_trees(False)
 
834
        # we want:
 
835
        t = repo.bzrdir.get_repository_transport(None)
 
836
        self.check_format(t)
 
837
        # XXX: no locks left when unlocked at the moment
 
838
        # self.assertEqualDiff('', t.get('lock').read())
 
839
        # We should have a 'shared-storage' marker file.
 
840
        self.assertEqualDiff('', t.get('shared-storage').read())
 
841
        # We should have a marker for the no-working-trees flag.
 
842
        self.assertEqualDiff('', t.get('no-working-trees').read())
 
843
        # The marker should go when we toggle the setting.
 
844
        repo.set_make_working_trees(True)
 
845
        self.assertFalse(t.has('no-working-trees'))
 
846
        self.check_databases(t)
 
847
 
 
848
    def test_adding_revision_creates_pack_indices(self):
 
849
        format = self.get_format()
 
850
        tree = self.make_branch_and_tree('.', format=format)
 
851
        trans = tree.branch.repository.bzrdir.get_repository_transport(None)
 
852
        self.assertEqual([],
 
853
            list(GraphIndex(trans, 'pack-names', None).iter_all_entries()))
 
854
        tree.commit('foobarbaz')
 
855
        index = GraphIndex(trans, 'pack-names', None)
 
856
        index_nodes = list(index.iter_all_entries())
 
857
        self.assertEqual(1, len(index_nodes))
 
858
        node = index_nodes[0]
 
859
        name = node[1][0]
 
860
        # the pack sizes should be listed in the index
 
861
        pack_value = node[2]
 
862
        sizes = [int(digits) for digits in pack_value.split(' ')]
 
863
        for size, suffix in zip(sizes, ['.rix', '.iix', '.tix', '.six']):
 
864
            stat = trans.stat('indices/%s%s' % (name, suffix))
 
865
            self.assertEqual(size, stat.st_size)
 
866
 
 
867
    def test_pulling_nothing_leads_to_no_new_names(self):
 
868
        format = self.get_format()
 
869
        tree1 = self.make_branch_and_tree('1', format=format)
 
870
        tree2 = self.make_branch_and_tree('2', format=format)
 
871
        tree1.branch.repository.fetch(tree2.branch.repository)
 
872
        trans = tree1.branch.repository.bzrdir.get_repository_transport(None)
 
873
        self.assertEqual([],
 
874
            list(GraphIndex(trans, 'pack-names', None).iter_all_entries()))
 
875
 
 
876
    def test_commit_across_pack_shape_boundary_autopacks(self):
 
877
        format = self.get_format()
 
878
        tree = self.make_branch_and_tree('.', format=format)
 
879
        trans = tree.branch.repository.bzrdir.get_repository_transport(None)
 
880
        # This test could be a little cheaper by replacing the packs
 
881
        # attribute on the repository to allow a different pack distribution
 
882
        # and max packs policy - so we are checking the policy is honoured
 
883
        # in the test. But for now 11 commits is not a big deal in a single
 
884
        # test.
 
885
        for x in range(9):
 
886
            tree.commit('commit %s' % x)
 
887
        # there should be 9 packs:
 
888
        index = GraphIndex(trans, 'pack-names', None)
 
889
        self.assertEqual(9, len(list(index.iter_all_entries())))
 
890
        # committing one more should coalesce to 1 of 10.
 
891
        tree.commit('commit triggering pack')
 
892
        index = GraphIndex(trans, 'pack-names', None)
 
893
        self.assertEqual(1, len(list(index.iter_all_entries())))
 
894
        # packing should not damage data
 
895
        tree = tree.bzrdir.open_workingtree()
 
896
        check_result = tree.branch.repository.check(
 
897
            [tree.branch.last_revision()])
 
898
        # XXX: Todo check packs obsoleted correctly - old packs and indices
 
899
        # in the obsolete_packs directory.
 
900
        large_pack_name = list(index.iter_all_entries())[0][1][0]
 
901
        # finally, committing again should not touch the large pack.
 
902
        tree.commit('commit not triggering pack')
 
903
        index = GraphIndex(trans, 'pack-names', None)
 
904
        self.assertEqual(2, len(list(index.iter_all_entries())))
 
905
        pack_names = [node[1][0] for node in index.iter_all_entries()]
 
906
        self.assertTrue(large_pack_name in pack_names)
 
907
 
 
908
    def test_pack_after_two_commits_packs_everything(self):
 
909
        format = self.get_format()
 
910
        tree = self.make_branch_and_tree('.', format=format)
 
911
        trans = tree.branch.repository.bzrdir.get_repository_transport(None)
 
912
        tree.commit('start')
 
913
        tree.commit('more work')
 
914
        tree.branch.repository.pack()
 
915
        # there should be 1 pack:
 
916
        index = GraphIndex(trans, 'pack-names', None)
 
917
        self.assertEqual(1, len(list(index.iter_all_entries())))
 
918
        self.assertEqual(2, len(tree.branch.repository.all_revision_ids()))
 
919
 
 
920
    def test_pack_repositories_support_multiple_write_locks(self):
 
921
        format = self.get_format()
 
922
        self.make_repository('.', shared=True, format=format)
 
923
        r1 = repository.Repository.open('.')
 
924
        r2 = repository.Repository.open('.')
 
925
        r1.lock_write()
 
926
        self.addCleanup(r1.unlock)
 
927
        r2.lock_write()
 
928
        r2.unlock()
 
929
 
 
930
    def _add_text(self, repo, fileid):
 
931
        """Add a text to the repository within a write group."""
 
932
        vf =repo.weave_store.get_weave(fileid, repo.get_transaction())
 
933
        vf.add_lines('samplerev+' + fileid, [], [])
 
934
 
 
935
    def test_concurrent_writers_merge_new_packs(self):
 
936
        format = self.get_format()
 
937
        self.make_repository('.', shared=True, format=format)
 
938
        r1 = repository.Repository.open('.')
 
939
        r2 = repository.Repository.open('.')
 
940
        r1.lock_write()
 
941
        try:
 
942
            # access enough data to load the names list
 
943
            list(r1.all_revision_ids())
 
944
            r2.lock_write()
 
945
            try:
 
946
                # access enough data to load the names list
 
947
                list(r2.all_revision_ids())
 
948
                r1.start_write_group()
 
949
                try:
 
950
                    r2.start_write_group()
 
951
                    try:
 
952
                        self._add_text(r1, 'fileidr1')
 
953
                        self._add_text(r2, 'fileidr2')
 
954
                    except:
 
955
                        r2.abort_write_group()
 
956
                        raise
 
957
                except:
 
958
                    r1.abort_write_group()
 
959
                    raise
 
960
                # both r1 and r2 have open write groups with data in them
 
961
                # created while the other's write group was open.
 
962
                # Commit both which requires a merge to the pack-names.
 
963
                try:
 
964
                    r1.commit_write_group()
 
965
                except:
 
966
                    r1.abort_write_group()
 
967
                    r2.abort_write_group()
 
968
                    raise
 
969
                r2.commit_write_group()
 
970
                # tell r1 to reload from disk
 
971
                r1._pack_collection.reset()
 
972
                # Now both repositories should know about both names
 
973
                r1._pack_collection.ensure_loaded()
 
974
                r2._pack_collection.ensure_loaded()
 
975
                self.assertEqual(r1._pack_collection.names(), r2._pack_collection.names())
 
976
                self.assertEqual(2, len(r1._pack_collection.names()))
 
977
            finally:
 
978
                r1.unlock()
 
979
        finally:
 
980
            r2.unlock()
 
981
 
 
982
    def test_concurrent_writer_second_preserves_dropping_a_pack(self):
 
983
        format = self.get_format()
 
984
        self.make_repository('.', shared=True, format=format)
 
985
        r1 = repository.Repository.open('.')
 
986
        r2 = repository.Repository.open('.')
 
987
        # add a pack to drop
 
988
        r1.lock_write()
 
989
        try:
 
990
            r1.start_write_group()
 
991
            try:
 
992
                self._add_text(r1, 'fileidr1')
 
993
            except:
 
994
                r1.abort_write_group()
 
995
                raise
 
996
            else:
 
997
                r1.commit_write_group()
 
998
            r1._pack_collection.ensure_loaded()
 
999
            name_to_drop = r1._pack_collection.all_packs()[0].name
 
1000
        finally:
 
1001
            r1.unlock()
 
1002
        r1.lock_write()
 
1003
        try:
 
1004
            # access enough data to load the names list
 
1005
            list(r1.all_revision_ids())
 
1006
            r2.lock_write()
 
1007
            try:
 
1008
                # access enough data to load the names list
 
1009
                list(r2.all_revision_ids())
 
1010
                r1._pack_collection.ensure_loaded()
 
1011
                try:
 
1012
                    r2.start_write_group()
 
1013
                    try:
 
1014
                        # in r1, drop the pack
 
1015
                        r1._pack_collection._remove_pack_from_memory(
 
1016
                            r1._pack_collection.get_pack_by_name(name_to_drop))
 
1017
                        # in r2, add a pack
 
1018
                        self._add_text(r2, 'fileidr2')
 
1019
                    except:
 
1020
                        r2.abort_write_group()
 
1021
                        raise
 
1022
                except:
 
1023
                    r1._pack_collection.reset()
 
1024
                    raise
 
1025
                # r1 has a changed names list, and r2 an open write groups with
 
1026
                # changes.
 
1027
                # save r1, and then commit the r2 write group, which requires a
 
1028
                # merge to the pack-names, which should not reinstate
 
1029
                # name_to_drop
 
1030
                try:
 
1031
                    r1._pack_collection._save_pack_names()
 
1032
                    r1._pack_collection.reset()
 
1033
                except:
 
1034
                    r2.abort_write_group()
 
1035
                    raise
 
1036
                try:
 
1037
                    r2.commit_write_group()
 
1038
                except:
 
1039
                    r2.abort_write_group()
 
1040
                    raise
 
1041
                # Now both repositories should now about just one name.
 
1042
                r1._pack_collection.ensure_loaded()
 
1043
                r2._pack_collection.ensure_loaded()
 
1044
                self.assertEqual(r1._pack_collection.names(), r2._pack_collection.names())
 
1045
                self.assertEqual(1, len(r1._pack_collection.names()))
 
1046
                self.assertFalse(name_to_drop in r1._pack_collection.names())
 
1047
            finally:
 
1048
                r1.unlock()
 
1049
        finally:
 
1050
            r2.unlock()
 
1051
 
 
1052
    def test_lock_write_does_not_physically_lock(self):
 
1053
        repo = self.make_repository('.', format=self.get_format())
 
1054
        repo.lock_write()
 
1055
        self.addCleanup(repo.unlock)
 
1056
        self.assertFalse(repo.get_physical_lock_status())
 
1057
 
 
1058
    def prepare_for_break_lock(self):
 
1059
        # Setup the global ui factory state so that a break-lock method call
 
1060
        # will find usable input in the input stream.
 
1061
        old_factory = bzrlib.ui.ui_factory
 
1062
        def restoreFactory():
 
1063
            bzrlib.ui.ui_factory = old_factory
 
1064
        self.addCleanup(restoreFactory)
 
1065
        bzrlib.ui.ui_factory = bzrlib.ui.SilentUIFactory()
 
1066
        bzrlib.ui.ui_factory.stdin = StringIO("y\n")
 
1067
 
 
1068
    def test_break_lock_breaks_physical_lock(self):
 
1069
        repo = self.make_repository('.', format=self.get_format())
 
1070
        repo._pack_collection.lock_names()
 
1071
        repo2 = repository.Repository.open('.')
 
1072
        self.assertTrue(repo.get_physical_lock_status())
 
1073
        self.prepare_for_break_lock()
 
1074
        repo2.break_lock()
 
1075
        self.assertFalse(repo.get_physical_lock_status())
 
1076
 
 
1077
    def test_broken_physical_locks_error_on__unlock_names_lock(self):
 
1078
        repo = self.make_repository('.', format=self.get_format())
 
1079
        repo._pack_collection.lock_names()
 
1080
        self.assertTrue(repo.get_physical_lock_status())
 
1081
        repo2 = repository.Repository.open('.')
 
1082
        self.prepare_for_break_lock()
 
1083
        repo2.break_lock()
 
1084
        self.assertRaises(errors.LockBroken, repo._pack_collection._unlock_names)
 
1085
 
 
1086
 
 
1087
class TestExperimentalSubtrees(TestExperimentalNoSubtrees):
 
1088
 
 
1089
    def get_format(self):
 
1090
        return bzrdir.format_registry.make_bzrdir('experimental-subtree')
 
1091
 
 
1092
    def check_format(self, t):
 
1093
        self.assertEqualDiff('Bazaar Experimental subtrees\n',
 
1094
                             t.get('format').read())
 
1095
 
 
1096
 
 
1097
class TestRepositoryPackCollection(TestCaseWithTransport):
 
1098
 
 
1099
    def get_format(self):
 
1100
        return bzrdir.format_registry.make_bzrdir('experimental')
 
1101
 
 
1102
    def test__max_pack_count(self):
 
1103
        """The maximum pack count is a function of the number of revisions."""
 
1104
        format = self.get_format()
 
1105
        repo = self.make_repository('.', format=format)
 
1106
        packs = repo._pack_collection
 
1107
        # no revisions - one pack, so that we can have a revision free repo
 
1108
        # without it blowing up
 
1109
        self.assertEqual(1, packs._max_pack_count(0))
 
1110
        # after that the sum of the digits, - check the first 1-9
 
1111
        self.assertEqual(1, packs._max_pack_count(1))
 
1112
        self.assertEqual(2, packs._max_pack_count(2))
 
1113
        self.assertEqual(3, packs._max_pack_count(3))
 
1114
        self.assertEqual(4, packs._max_pack_count(4))
 
1115
        self.assertEqual(5, packs._max_pack_count(5))
 
1116
        self.assertEqual(6, packs._max_pack_count(6))
 
1117
        self.assertEqual(7, packs._max_pack_count(7))
 
1118
        self.assertEqual(8, packs._max_pack_count(8))
 
1119
        self.assertEqual(9, packs._max_pack_count(9))
 
1120
        # check the boundary cases with two digits for the next decade
 
1121
        self.assertEqual(1, packs._max_pack_count(10))
 
1122
        self.assertEqual(2, packs._max_pack_count(11))
 
1123
        self.assertEqual(10, packs._max_pack_count(19))
 
1124
        self.assertEqual(2, packs._max_pack_count(20))
 
1125
        self.assertEqual(3, packs._max_pack_count(21))
 
1126
        # check some arbitrary big numbers
 
1127
        self.assertEqual(25, packs._max_pack_count(112894))
 
1128
 
 
1129
    def test_pack_distribution_zero(self):
 
1130
        format = self.get_format()
 
1131
        repo = self.make_repository('.', format=format)
 
1132
        packs = repo._pack_collection
 
1133
        self.assertEqual([0], packs.pack_distribution(0))
 
1134
        
 
1135
    def test_pack_distribution_one_to_nine(self):
 
1136
        format = self.get_format()
 
1137
        repo = self.make_repository('.', format=format)
 
1138
        packs = repo._pack_collection
 
1139
        self.assertEqual([1],
 
1140
            packs.pack_distribution(1))
 
1141
        self.assertEqual([1, 1],
 
1142
            packs.pack_distribution(2))
 
1143
        self.assertEqual([1, 1, 1],
 
1144
            packs.pack_distribution(3))
 
1145
        self.assertEqual([1, 1, 1, 1],
 
1146
            packs.pack_distribution(4))
 
1147
        self.assertEqual([1, 1, 1, 1, 1],
 
1148
            packs.pack_distribution(5))
 
1149
        self.assertEqual([1, 1, 1, 1, 1, 1],
 
1150
            packs.pack_distribution(6))
 
1151
        self.assertEqual([1, 1, 1, 1, 1, 1, 1],
 
1152
            packs.pack_distribution(7))
 
1153
        self.assertEqual([1, 1, 1, 1, 1, 1, 1, 1],
 
1154
            packs.pack_distribution(8))
 
1155
        self.assertEqual([1, 1, 1, 1, 1, 1, 1, 1, 1],
 
1156
            packs.pack_distribution(9))
 
1157
 
 
1158
    def test_pack_distribution_stable_at_boundaries(self):
 
1159
        """When there are multi-rev packs the counts are stable."""
 
1160
        format = self.get_format()
 
1161
        repo = self.make_repository('.', format=format)
 
1162
        packs = repo._pack_collection
 
1163
        # in 10s:
 
1164
        self.assertEqual([10], packs.pack_distribution(10))
 
1165
        self.assertEqual([10, 1], packs.pack_distribution(11))
 
1166
        self.assertEqual([10, 10], packs.pack_distribution(20))
 
1167
        self.assertEqual([10, 10, 1], packs.pack_distribution(21))
 
1168
        # 100s
 
1169
        self.assertEqual([100], packs.pack_distribution(100))
 
1170
        self.assertEqual([100, 1], packs.pack_distribution(101))
 
1171
        self.assertEqual([100, 10, 1], packs.pack_distribution(111))
 
1172
        self.assertEqual([100, 100], packs.pack_distribution(200))
 
1173
        self.assertEqual([100, 100, 1], packs.pack_distribution(201))
 
1174
        self.assertEqual([100, 100, 10, 1], packs.pack_distribution(211))
 
1175
 
 
1176
    def test_plan_pack_operations_2009_revisions_skip_all_packs(self):
 
1177
        format = self.get_format()
 
1178
        repo = self.make_repository('.', format=format)
 
1179
        packs = repo._pack_collection
 
1180
        existing_packs = [(2000, "big"), (9, "medium")]
 
1181
        # rev count - 2009 -> 2x1000 + 9x1
 
1182
        pack_operations = packs.plan_autopack_combinations(
 
1183
            existing_packs, [1000, 1000, 1, 1, 1, 1, 1, 1, 1, 1, 1])
 
1184
        self.assertEqual([], pack_operations)
 
1185
 
 
1186
    def test_plan_pack_operations_2010_revisions_skip_all_packs(self):
 
1187
        format = self.get_format()
 
1188
        repo = self.make_repository('.', format=format)
 
1189
        packs = repo._pack_collection
 
1190
        existing_packs = [(2000, "big"), (9, "medium"), (1, "single")]
 
1191
        # rev count - 2010 -> 2x1000 + 1x10
 
1192
        pack_operations = packs.plan_autopack_combinations(
 
1193
            existing_packs, [1000, 1000, 10])
 
1194
        self.assertEqual([], pack_operations)
 
1195
 
 
1196
    def test_plan_pack_operations_2010_combines_smallest_two(self):
 
1197
        format = self.get_format()
 
1198
        repo = self.make_repository('.', format=format)
 
1199
        packs = repo._pack_collection
 
1200
        existing_packs = [(1999, "big"), (9, "medium"), (1, "single2"),
 
1201
            (1, "single1")]
 
1202
        # rev count - 2010 -> 2x1000 + 1x10 (3)
 
1203
        pack_operations = packs.plan_autopack_combinations(
 
1204
            existing_packs, [1000, 1000, 10])
 
1205
        self.assertEqual([[2, ["single2", "single1"]], [0, []]], pack_operations)
 
1206
 
 
1207
    def test_all_packs_none(self):
 
1208
        format = self.get_format()
 
1209
        tree = self.make_branch_and_tree('.', format=format)
 
1210
        tree.lock_read()
 
1211
        self.addCleanup(tree.unlock)
 
1212
        packs = tree.branch.repository._pack_collection
 
1213
        packs.ensure_loaded()
 
1214
        self.assertEqual([], packs.all_packs())
 
1215
 
 
1216
    def test_all_packs_one(self):
 
1217
        format = self.get_format()
 
1218
        tree = self.make_branch_and_tree('.', format=format)
 
1219
        tree.commit('start')
 
1220
        tree.lock_read()
 
1221
        self.addCleanup(tree.unlock)
 
1222
        packs = tree.branch.repository._pack_collection
 
1223
        packs.ensure_loaded()
 
1224
        self.assertEqual([
 
1225
            packs.get_pack_by_name(packs.names()[0])],
 
1226
            packs.all_packs())
 
1227
 
 
1228
    def test_all_packs_two(self):
 
1229
        format = self.get_format()
 
1230
        tree = self.make_branch_and_tree('.', format=format)
 
1231
        tree.commit('start')
 
1232
        tree.commit('continue')
 
1233
        tree.lock_read()
 
1234
        self.addCleanup(tree.unlock)
 
1235
        packs = tree.branch.repository._pack_collection
 
1236
        packs.ensure_loaded()
 
1237
        self.assertEqual([
 
1238
            packs.get_pack_by_name(packs.names()[0]),
 
1239
            packs.get_pack_by_name(packs.names()[1]),
 
1240
            ], packs.all_packs())
 
1241
 
 
1242
    def test_get_pack_by_name(self):
 
1243
        format = self.get_format()
 
1244
        tree = self.make_branch_and_tree('.', format=format)
 
1245
        tree.commit('start')
 
1246
        tree.lock_read()
 
1247
        self.addCleanup(tree.unlock)
 
1248
        packs = tree.branch.repository._pack_collection
 
1249
        packs.ensure_loaded()
 
1250
        name = packs.names()[0]
 
1251
        pack_1 = packs.get_pack_by_name(name)
 
1252
        # the pack should be correctly initialised
 
1253
        rev_index = GraphIndex(packs._index_transport, name + '.rix',
 
1254
            packs._names[name][0])
 
1255
        inv_index = GraphIndex(packs._index_transport, name + '.iix',
 
1256
            packs._names[name][1])
 
1257
        txt_index = GraphIndex(packs._index_transport, name + '.tix',
 
1258
            packs._names[name][2])
 
1259
        sig_index = GraphIndex(packs._index_transport, name + '.six',
 
1260
            packs._names[name][3])
 
1261
        self.assertEqual(pack_repo.ExistingPack(packs._pack_transport,
 
1262
            name, rev_index, inv_index, txt_index, sig_index), pack_1)
 
1263
        # and the same instance should be returned on successive calls.
 
1264
        self.assertTrue(pack_1 is packs.get_pack_by_name(name))
 
1265
 
 
1266
 
 
1267
class TestPack(TestCaseWithTransport):
 
1268
    """Tests for the Pack object."""
 
1269
 
 
1270
    def assertCurrentlyEqual(self, left, right):
 
1271
        self.assertTrue(left == right)
 
1272
        self.assertTrue(right == left)
 
1273
        self.assertFalse(left != right)
 
1274
        self.assertFalse(right != left)
 
1275
 
 
1276
    def assertCurrentlyNotEqual(self, left, right):
 
1277
        self.assertFalse(left == right)
 
1278
        self.assertFalse(right == left)
 
1279
        self.assertTrue(left != right)
 
1280
        self.assertTrue(right != left)
 
1281
 
 
1282
    def test___eq____ne__(self):
 
1283
        left = pack_repo.ExistingPack('', '', '', '', '', '')
 
1284
        right = pack_repo.ExistingPack('', '', '', '', '', '')
 
1285
        self.assertCurrentlyEqual(left, right)
 
1286
        # change all attributes and ensure equality changes as we do.
 
1287
        left.revision_index = 'a'
 
1288
        self.assertCurrentlyNotEqual(left, right)
 
1289
        right.revision_index = 'a'
 
1290
        self.assertCurrentlyEqual(left, right)
 
1291
        left.inventory_index = 'a'
 
1292
        self.assertCurrentlyNotEqual(left, right)
 
1293
        right.inventory_index = 'a'
 
1294
        self.assertCurrentlyEqual(left, right)
 
1295
        left.text_index = 'a'
 
1296
        self.assertCurrentlyNotEqual(left, right)
 
1297
        right.text_index = 'a'
 
1298
        self.assertCurrentlyEqual(left, right)
 
1299
        left.signature_index = 'a'
 
1300
        self.assertCurrentlyNotEqual(left, right)
 
1301
        right.signature_index = 'a'
 
1302
        self.assertCurrentlyEqual(left, right)
 
1303
        left.name = 'a'
 
1304
        self.assertCurrentlyNotEqual(left, right)
 
1305
        right.name = 'a'
 
1306
        self.assertCurrentlyEqual(left, right)
 
1307
        left.transport = 'a'
 
1308
        self.assertCurrentlyNotEqual(left, right)
 
1309
        right.transport = 'a'
 
1310
        self.assertCurrentlyEqual(left, right)
 
1311
 
 
1312
    def test_file_name(self):
 
1313
        pack = pack_repo.ExistingPack('', 'a_name', '', '', '', '')
 
1314
        self.assertEqual('a_name.pack', pack.file_name())
 
1315
 
 
1316
 
 
1317
class TestNewPack(TestCaseWithTransport):
 
1318
    """Tests for pack_repo.NewPack."""
 
1319
 
 
1320
    def test_new_instance_attributes(self):
 
1321
        upload_transport = self.get_transport('upload')
 
1322
        pack_transport = self.get_transport('pack')
 
1323
        index_transport = self.get_transport('index')
 
1324
        upload_transport.mkdir('.')
 
1325
        pack = pack_repo.NewPack(upload_transport, index_transport,
 
1326
            pack_transport)
 
1327
        self.assertIsInstance(pack.revision_index, InMemoryGraphIndex)
 
1328
        self.assertIsInstance(pack.inventory_index, InMemoryGraphIndex)
 
1329
        self.assertIsInstance(pack._hash, type(md5.new()))
 
1330
        self.assertTrue(pack.upload_transport is upload_transport)
 
1331
        self.assertTrue(pack.index_transport is index_transport)
 
1332
        self.assertTrue(pack.pack_transport is pack_transport)
 
1333
        self.assertEqual(None, pack.index_sizes)
 
1334
        self.assertEqual(20, len(pack.random_name))
 
1335
        self.assertIsInstance(pack.random_name, str)
 
1336
        self.assertIsInstance(pack.start_time, float)