~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/per_repository/test_repository.py

merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006-2011 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
25
25
    delta as _mod_delta,
26
26
    errors,
27
27
    gpg,
28
 
    graph,
29
28
    info,
30
29
    inventory,
31
 
    osutils,
32
30
    remote,
33
31
    repository,
34
32
    revision as _mod_revision,
37
35
    upgrade,
38
36
    versionedfile,
39
37
    workingtree,
40
 
    xml_serializer,
41
38
    )
42
39
from bzrlib.repofmt import (
43
40
    pack_repo,
44
 
    weaverepo,
45
41
    )
46
42
from bzrlib.tests import (
47
43
    per_repository,
91
87
    def test_attribute_format_pack_compresses(self):
92
88
        self.assertFormatAttribute('pack_compresses', (True, False))
93
89
 
94
 
    def test_attribute_inventories_store(self):
95
 
        """Test the existence of the inventories attribute."""
96
 
        tree = self.make_branch_and_tree('tree')
97
 
        repo = tree.branch.repository
98
 
        self.assertIsInstance(repo.inventories, versionedfile.VersionedFiles)
99
 
 
100
 
    def test_attribute_inventories_basics(self):
101
 
        """Test basic aspects of the inventories attribute."""
102
 
        tree = self.make_branch_and_tree('tree')
103
 
        repo = tree.branch.repository
104
 
        rev_id = (tree.commit('a'),)
105
 
        tree.lock_read()
106
 
        self.addCleanup(tree.unlock)
107
 
        self.assertEqual(set([rev_id]), set(repo.inventories.keys()))
108
 
 
109
 
    def test_attribute_revision_store(self):
110
 
        """Test the existence of the revisions attribute."""
111
 
        tree = self.make_branch_and_tree('tree')
112
 
        repo = tree.branch.repository
113
 
        self.assertIsInstance(repo.revisions,
114
 
            versionedfile.VersionedFiles)
115
 
 
116
 
    def test_attribute_revision_store_basics(self):
117
 
        """Test the basic behaviour of the revisions attribute."""
118
 
        tree = self.make_branch_and_tree('tree')
119
 
        repo = tree.branch.repository
120
 
        repo.lock_write()
121
 
        try:
122
 
            self.assertEqual(set(), set(repo.revisions.keys()))
123
 
            revid = (tree.commit("foo"),)
124
 
            self.assertEqual(set([revid]), set(repo.revisions.keys()))
125
 
            self.assertEqual({revid:()},
126
 
                repo.revisions.get_parent_map([revid]))
127
 
        finally:
128
 
            repo.unlock()
129
 
        tree2 = self.make_branch_and_tree('tree2')
130
 
        tree2.pull(tree.branch)
131
 
        left_id = (tree2.commit('left'),)
132
 
        right_id = (tree.commit('right'),)
133
 
        tree.merge_from_branch(tree2.branch)
134
 
        merge_id = (tree.commit('merged'),)
135
 
        repo.lock_read()
136
 
        self.addCleanup(repo.unlock)
137
 
        self.assertEqual(set([revid, left_id, right_id, merge_id]),
138
 
            set(repo.revisions.keys()))
139
 
        self.assertEqual({revid:(), left_id:(revid,), right_id:(revid,),
140
 
             merge_id:(right_id, left_id)},
141
 
            repo.revisions.get_parent_map(repo.revisions.keys()))
142
 
 
143
 
    def test_attribute_signature_store(self):
144
 
        """Test the existence of the signatures attribute."""
145
 
        tree = self.make_branch_and_tree('tree')
146
 
        repo = tree.branch.repository
147
 
        self.assertIsInstance(repo.signatures,
148
 
            versionedfile.VersionedFiles)
 
90
    def test_attribute_format_supports_full_versioned_files(self):
 
91
        self.assertFormatAttribute('supports_full_versioned_files',
 
92
            (True, False))
 
93
 
 
94
    def test_attribute_format_supports_funky_characters(self):
 
95
        self.assertFormatAttribute('supports_funky_characters',
 
96
            (True, False))
 
97
 
 
98
    def test_attribute_format_supports_leaving_lock(self):
 
99
        self.assertFormatAttribute('supports_leaving_lock',
 
100
            (True, False))
 
101
 
 
102
    def test_format_is_deprecated(self):
 
103
        repo = self.make_repository('repo')
 
104
        self.assertSubset([repo._format.is_deprecated()], (True, False))
 
105
 
 
106
    def test_format_is_supported(self):
 
107
        repo = self.make_repository('repo')
 
108
        self.assertSubset([repo._format.is_supported()], (True, False))
149
109
 
150
110
    def test_attribute_text_store_basics(self):
151
111
        """Test the basic behaviour of the text store."""
210
170
        self.assertIsInstance(repo.texts,
211
171
            versionedfile.VersionedFiles)
212
172
 
213
 
    def test_exposed_versioned_files_are_marked_dirty(self):
214
 
        repo = self.make_repository('.')
215
 
        repo.lock_write()
216
 
        signatures = repo.signatures
217
 
        revisions = repo.revisions
218
 
        inventories = repo.inventories
219
 
        repo.unlock()
220
 
        self.assertRaises(errors.ObjectNotLocked,
221
 
            signatures.keys)
222
 
        self.assertRaises(errors.ObjectNotLocked,
223
 
            revisions.keys)
224
 
        self.assertRaises(errors.ObjectNotLocked,
225
 
            inventories.keys)
226
 
        self.assertRaises(errors.ObjectNotLocked,
227
 
            signatures.add_lines, ('foo',), [], [])
228
 
        self.assertRaises(errors.ObjectNotLocked,
229
 
            revisions.add_lines, ('foo',), [], [])
230
 
        self.assertRaises(errors.ObjectNotLocked,
231
 
            inventories.add_lines, ('foo',), [], [])
232
 
 
233
173
    def test_clone_to_default_format(self):
234
174
        #TODO: Test that cloning a repository preserves all the information
235
175
        # such as signatures[not tested yet] etc etc.
282
222
            # they may not be initializable.
283
223
            return
284
224
        # supported formats must be able to init and open
285
 
        t = transport.get_transport(self.get_url())
286
 
        readonly_t = transport.get_transport(self.get_readonly_url())
 
225
        t = self.get_transport()
 
226
        readonly_t = self.get_readonly_transport()
287
227
        made_control = self.bzrdir_format.initialize(t.base)
288
228
        made_repo = self.repository_format.initialize(made_control)
289
229
        self.assertEqual(made_control, made_repo.bzrdir)
342
282
            # because the default open will not open them and
343
283
            # they may not be initializable.
344
284
            return
345
 
        t = transport.get_transport(self.get_url())
 
285
        t = self.get_transport()
346
286
        made_control = self.bzrdir_format.initialize(t.base)
347
287
        made_repo = made_control.create_repository()
348
288
        # Check that we have a repository object.
356
296
            # because the default open will not open them and
357
297
            # they may not be initializable.
358
298
            return
359
 
        t = transport.get_transport(self.get_url())
 
299
        t = self.get_transport()
360
300
        made_control = self.bzrdir_format.initialize(t.base)
361
301
        try:
362
302
            made_repo = made_control.create_repository(shared=True)
599
539
        self.addCleanup(rev_tree.unlock)
600
540
        self.assertEqual('rev_id', rev_tree.inventory.root.revision)
601
541
 
602
 
    def test_upgrade_from_format4(self):
603
 
        from bzrlib.tests.test_upgrade import _upgrade_dir_template
604
 
        if isinstance(self.repository_format, remote.RemoteRepositoryFormat):
605
 
            return # local conversion to/from RemoteObjects is irrelevant.
606
 
        if self.repository_format.get_format_description() \
607
 
            == "Repository format 4":
608
 
            raise tests.TestSkipped('Cannot convert format-4 to itself')
609
 
        self.build_tree_contents(_upgrade_dir_template)
610
 
        old_repodir = bzrdir.BzrDir.open_unsupported('.')
611
 
        old_repo_format = old_repodir.open_repository()._format
612
 
        format = self.repository_format._matchingbzrdir
613
 
        try:
614
 
            format.repository_format = self.repository_format
615
 
        except AttributeError:
616
 
            pass
617
 
        upgrade.upgrade('.', format)
618
 
 
619
542
    def test_pointless_commit(self):
620
543
        tree = self.make_branch_and_tree('.')
621
544
        self.assertRaises(errors.PointlessCommit, tree.commit, 'pointless',
854
777
 
855
778
    def test_sprout_from_hpss_preserves_format(self):
856
779
        """repo.sprout from a smart server preserves the repository format."""
857
 
        if self.repository_format == weaverepo.RepositoryFormat7():
858
 
            raise tests.TestNotApplicable(
859
 
                "Cannot fetch weaves over smart protocol.")
860
780
        remote_repo = self.make_remote_repository('remote')
861
781
        local_bzrdir = self.make_bzrdir('local')
862
782
        try:
871
791
    def test_sprout_branch_from_hpss_preserves_repo_format(self):
872
792
        """branch.sprout from a smart server preserves the repository format.
873
793
        """
874
 
        weave_formats = [weaverepo.RepositoryFormat5(),
875
 
                         weaverepo.RepositoryFormat6(),
876
 
                         weaverepo.RepositoryFormat7()]
877
 
        if self.repository_format in weave_formats:
 
794
        if not self.repository_format.supports_leaving_lock:
878
795
            raise tests.TestNotApplicable(
879
 
                "Cannot fetch weaves over smart protocol.")
 
796
                "Format can not be used over HPSS")
880
797
        remote_repo = self.make_remote_repository('remote')
881
798
        remote_branch = remote_repo.bzrdir.create_branch()
882
799
        try:
893
810
        """branch.sprout from a smart server preserves the repository format of
894
811
        a branch from a shared repository.
895
812
        """
896
 
        weave_formats = [weaverepo.RepositoryFormat5(),
897
 
                         weaverepo.RepositoryFormat6(),
898
 
                         weaverepo.RepositoryFormat7()]
899
 
        if self.repository_format in weave_formats:
 
813
        if not self.repository_format.supports_leaving_lock:
900
814
            raise tests.TestNotApplicable(
901
 
                "Cannot fetch weaves over smart protocol.")
 
815
                "Format can not be used over HPSS")
902
816
        # Make a shared repo
903
817
        remote_repo = self.make_remote_repository('remote', shared=True)
904
818
        remote_backing_repo = bzrdir.BzrDir.open(
922
836
        self.assertEqual(remote_backing_repo._format, local_repo._format)
923
837
 
924
838
    def test_clone_to_hpss(self):
925
 
        pre_metadir_formats = [weaverepo.RepositoryFormat5(),
926
 
                               weaverepo.RepositoryFormat6()]
927
 
        if self.repository_format in pre_metadir_formats:
 
839
        if not self.repository_format.supports_leaving_lock:
928
840
            raise tests.TestNotApplicable(
929
841
                "Cannot lock pre_metadir_formats remotely.")
930
842
        remote_transport = self.make_smart_server('remote')
943
855
            repo = self.make_repository('repo', shared=True)
944
856
        except errors.IncompatibleFormat:
945
857
            raise tests.TestNotApplicable('Cannot make a shared repository')
946
 
        if isinstance(repo.bzrdir, bzrdir.BzrDirPreSplitOut):
 
858
        if repo.bzrdir._format.fixed_components:
947
859
            raise tests.KnownFailure(
948
860
                "pre metadir branches do not upgrade on push "
949
861
                "with stacking policy")
1151
1063
        self.assertThat(repo.lock_write, ReturnsUnlockable(repo))
1152
1064
 
1153
1065
 
1154
 
class TestCaseWithComplexRepository(per_repository.TestCaseWithRepository):
1155
 
 
1156
 
    def setUp(self):
1157
 
        super(TestCaseWithComplexRepository, self).setUp()
1158
 
        tree_a = self.make_branch_and_tree('a')
1159
 
        self.bzrdir = tree_a.branch.bzrdir
1160
 
        # add a corrupt inventory 'orphan'
1161
 
        # this may need some generalising for knits.
1162
 
        tree_a.lock_write()
1163
 
        try:
1164
 
            tree_a.branch.repository.start_write_group()
1165
 
            try:
1166
 
                inv_file = tree_a.branch.repository.inventories
1167
 
                inv_file.add_lines(('orphan',), [], [])
1168
 
            except:
1169
 
                tree_a.branch.repository.commit_write_group()
1170
 
                raise
1171
 
            else:
1172
 
                tree_a.branch.repository.abort_write_group()
1173
 
        finally:
1174
 
            tree_a.unlock()
1175
 
        # add a real revision 'rev1'
1176
 
        tree_a.commit('rev1', rev_id='rev1', allow_pointless=True)
1177
 
        # add a real revision 'rev2' based on rev1
1178
 
        tree_a.commit('rev2', rev_id='rev2', allow_pointless=True)
1179
 
        # add a reference to a ghost
1180
 
        tree_a.add_parent_tree_id('ghost1')
1181
 
        try:
1182
 
            tree_a.commit('rev3', rev_id='rev3', allow_pointless=True)
1183
 
        except errors.RevisionNotPresent:
1184
 
            raise tests.TestNotApplicable(
1185
 
                "Cannot test with ghosts for this format.")
1186
 
        # add another reference to a ghost, and a second ghost.
1187
 
        tree_a.add_parent_tree_id('ghost1')
1188
 
        tree_a.add_parent_tree_id('ghost2')
1189
 
        tree_a.commit('rev4', rev_id='rev4', allow_pointless=True)
1190
 
 
1191
 
    def test_revision_trees(self):
1192
 
        revision_ids = ['rev1', 'rev2', 'rev3', 'rev4']
1193
 
        repository = self.bzrdir.open_repository()
1194
 
        repository.lock_read()
1195
 
        self.addCleanup(repository.unlock)
1196
 
        trees1 = list(repository.revision_trees(revision_ids))
1197
 
        trees2 = [repository.revision_tree(t) for t in revision_ids]
1198
 
        self.assertEqual(len(trees1), len(trees2))
1199
 
        for tree1, tree2 in zip(trees1, trees2):
1200
 
            self.assertFalse(tree2.changes_from(tree1).has_changed())
1201
 
 
1202
 
    def test_get_deltas_for_revisions(self):
1203
 
        repository = self.bzrdir.open_repository()
1204
 
        repository.lock_read()
1205
 
        self.addCleanup(repository.unlock)
1206
 
        revisions = [repository.get_revision(r) for r in
1207
 
                     ['rev1', 'rev2', 'rev3', 'rev4']]
1208
 
        deltas1 = list(repository.get_deltas_for_revisions(revisions))
1209
 
        deltas2 = [repository.get_revision_delta(r.revision_id) for r in
1210
 
                   revisions]
1211
 
        self.assertEqual(deltas1, deltas2)
1212
 
 
1213
 
    def test_all_revision_ids(self):
1214
 
        # all_revision_ids -> all revisions
1215
 
        self.assertEqual(set(['rev1', 'rev2', 'rev3', 'rev4']),
1216
 
            set(self.bzrdir.open_repository().all_revision_ids()))
1217
 
 
1218
 
    def test_get_ancestry_missing_revision(self):
1219
 
        # get_ancestry(revision that is in some data but not fully installed
1220
 
        # -> NoSuchRevision
1221
 
        self.assertRaises(errors.NoSuchRevision,
1222
 
                          self.bzrdir.open_repository().get_ancestry, 'orphan')
1223
 
 
1224
 
    def test_get_unordered_ancestry(self):
1225
 
        repo = self.bzrdir.open_repository()
1226
 
        self.assertEqual(set(repo.get_ancestry('rev3')),
1227
 
                         set(repo.get_ancestry('rev3', topo_sorted=False)))
1228
 
 
1229
 
    def test_reserved_id(self):
1230
 
        repo = self.make_repository('repository')
1231
 
        repo.lock_write()
1232
 
        repo.start_write_group()
1233
 
        try:
1234
 
            self.assertRaises(errors.ReservedId, repo.add_inventory, 'reserved:',
1235
 
                              None, None)
1236
 
            self.assertRaises(errors.ReservedId, repo.add_inventory_by_delta,
1237
 
                "foo", [], 'reserved:', None)
1238
 
            self.assertRaises(errors.ReservedId, repo.add_revision, 'reserved:',
1239
 
                              None)
1240
 
        finally:
1241
 
            repo.abort_write_group()
1242
 
            repo.unlock()
1243
 
 
1244
 
 
1245
1066
class TestCaseWithCorruptRepository(per_repository.TestCaseWithRepository):
1246
1067
 
1247
1068
    def setUp(self):
1353
1174
            'rev1', _mod_revision.NULL_REVISION, fileobj)
1354
1175
 
1355
1176
 
1356
 
 
1357
 
 
1358
1177
class TestRepositoryControlComponent(per_repository.TestCaseWithRepository):
1359
1178
    """Repository implementations adequately implement ControlComponent."""
1360
 
    
 
1179
 
1361
1180
    def test_urls(self):
1362
1181
        repo = self.make_repository('repo')
1363
1182
        self.assertIsInstance(repo.user_url, str)