~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/per_controldir/test_controldir.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
17
17
"""Tests for control directory implementations - tests a controldir format."""
18
18
 
19
19
from itertools import izip
20
 
import os
21
20
 
22
21
import bzrlib.branch
23
22
from bzrlib import (
34
33
    )
35
34
import bzrlib.revision
36
35
from bzrlib.tests import (
37
 
                          ChrootedTestCase,
38
 
                          TestNotApplicable,
39
 
                          TestSkipped,
40
 
                          )
 
36
    fixtures,
 
37
    ChrootedTestCase,
 
38
    TestNotApplicable,
 
39
    TestSkipped,
 
40
    )
41
41
from bzrlib.tests.per_controldir import TestCaseWithControlDir
42
42
from bzrlib.transport.local import LocalTransport
43
43
from bzrlib.ui import (
44
44
    CannedInputUIFactory,
45
45
    )
46
 
from bzrlib.remote import RemoteBzrDir, RemoteRepository
47
 
from bzrlib.repofmt import weaverepo
 
46
from bzrlib.remote import (
 
47
    RemoteBzrDir,
 
48
    RemoteBzrDirFormat,
 
49
    RemoteRepository,
 
50
    )
48
51
 
49
52
 
50
53
class TestControlDir(TestCaseWithControlDir):
257
260
 
258
261
    def test_clone_bzrdir_branch_and_repo_fixed_user_id(self):
259
262
        # Bug #430868 is about an email containing '.sig'
260
 
        os.environ['BZR_EMAIL'] = 'murphy@host.sighup.org'
 
263
        self.overrideEnv('BZR_EMAIL', 'murphy@host.sighup.org')
261
264
        tree = self.make_branch_and_tree('commit_tree')
262
265
        self.build_tree(['commit_tree/foo'])
263
266
        tree.add('foo')
501
504
        self.assertNotEqual(dir.transport.base, target.transport.base)
502
505
        self.assertNotEqual(dir.transport.base, shared_repo.bzrdir.transport.base)
503
506
        branch = target.open_branch()
504
 
        self.assertTrue(branch.repository.has_revision('1'))
 
507
        # The sprouted bzrdir has a branch, so only revisions referenced by
 
508
        # that branch are copied, rather than the whole repository.  It's an
 
509
        # empty branch, so none are copied.
 
510
        self.assertEqual([], branch.repository.all_revision_ids())
505
511
        if branch.bzrdir._format.supports_workingtrees:
506
512
            self.assertTrue(branch.repository.make_working_trees())
507
513
        self.assertFalse(branch.repository.is_shared())
667
673
        target = dir.sprout(self.get_url('target'), revision_id='1')
668
674
        self.assertEqual('1', target.open_branch().last_revision())
669
675
 
 
676
    def test_sprout_bzrdir_branch_with_tags(self):
 
677
        # when sprouting a branch all revisions named in the tags are copied
 
678
        # too.
 
679
        builder = self.make_branch_builder('source')
 
680
        source = fixtures.build_branch_with_non_ancestral_rev(builder)
 
681
        try:
 
682
            source.tags.set_tag('tag-a', 'rev-2')
 
683
        except errors.TagsNotSupported:
 
684
            raise TestNotApplicable('Branch format does not support tags.')
 
685
        # Now source has a tag not in its ancestry.  Sprout its controldir.
 
686
        dir = source.bzrdir
 
687
        target = dir.sprout(self.get_url('target'))
 
688
        # The tag is present, and so is its revision.
 
689
        new_branch = target.open_branch()
 
690
        self.assertEqual('rev-2', new_branch.tags.lookup_tag('tag-a'))
 
691
        new_branch.repository.get_revision('rev-2')
 
692
 
 
693
    def test_sprout_bzrdir_branch_with_absent_tag(self):
 
694
        # tags referencing absent revisions are copied (and those absent
 
695
        # revisions do not prevent the sprout.)
 
696
        builder = self.make_branch_builder('source')
 
697
        builder.build_commit(message="Rev 1", rev_id='rev-1')
 
698
        source = builder.get_branch()
 
699
        try:
 
700
            source.tags.set_tag('tag-a', 'missing-rev')
 
701
        except errors.TagsNotSupported:
 
702
            raise TestNotApplicable('Branch format does not support tags.')
 
703
        # Now source has a tag pointing to an absent revision.  Sprout its
 
704
        # controldir.
 
705
        dir = source.bzrdir
 
706
        target = dir.sprout(self.get_url('target'))
 
707
        # The tag is present in the target
 
708
        new_branch = target.open_branch()
 
709
        self.assertEqual('missing-rev', new_branch.tags.lookup_tag('tag-a'))
 
710
 
 
711
    def test_sprout_bzrdir_passing_source_branch_with_absent_tag(self):
 
712
        # tags referencing absent revisions are copied (and those absent
 
713
        # revisions do not prevent the sprout.)
 
714
        builder = self.make_branch_builder('source')
 
715
        builder.build_commit(message="Rev 1", rev_id='rev-1')
 
716
        source = builder.get_branch()
 
717
        try:
 
718
            source.tags.set_tag('tag-a', 'missing-rev')
 
719
        except errors.TagsNotSupported:
 
720
            raise TestNotApplicable('Branch format does not support tags.')
 
721
        # Now source has a tag pointing to an absent revision.  Sprout its
 
722
        # controldir.
 
723
        dir = source.bzrdir
 
724
        target = dir.sprout(self.get_url('target'), source_branch=source)
 
725
        # The tag is present in the target
 
726
        new_branch = target.open_branch()
 
727
        self.assertEqual('missing-rev', new_branch.tags.lookup_tag('tag-a'))
 
728
 
 
729
    def test_sprout_bzrdir_passing_rev_not_source_branch_copies_tags(self):
 
730
        # dir.sprout(..., revision_id='rev1') copies rev1, and all the tags of
 
731
        # the branch at that bzrdir, the ancestry of all of those, but no other
 
732
        # revs (not even the tip of the source branch).
 
733
        builder = self.make_branch_builder('source')
 
734
        builder.build_commit(message="Base", rev_id='base-rev')
 
735
        # Make three parallel lines of ancestry off this base.
 
736
        source = builder.get_branch()
 
737
        builder.build_commit(message="Rev A1", rev_id='rev-a1')
 
738
        builder.build_commit(message="Rev A2", rev_id='rev-a2')
 
739
        builder.build_commit(message="Rev A3", rev_id='rev-a3')
 
740
        source.set_last_revision_info(1, 'base-rev')
 
741
        builder.build_commit(message="Rev B1", rev_id='rev-b1')
 
742
        builder.build_commit(message="Rev B2", rev_id='rev-b2')
 
743
        builder.build_commit(message="Rev B3", rev_id='rev-b3')
 
744
        source.set_last_revision_info(1, 'base-rev')
 
745
        builder.build_commit(message="Rev C1", rev_id='rev-c1')
 
746
        builder.build_commit(message="Rev C2", rev_id='rev-c2')
 
747
        builder.build_commit(message="Rev C3", rev_id='rev-c3')
 
748
        # Set the branch tip to A2
 
749
        source.set_last_revision_info(3, 'rev-a2')
 
750
        try:
 
751
            # Create a tag for B2, and for an absent rev
 
752
            source.tags.set_tag('tag-non-ancestry', 'rev-b2')
 
753
            source.tags.set_tag('tag-absent', 'absent-rev')
 
754
        except errors.TagsNotSupported:
 
755
            raise TestNotApplicable('Branch format does not support tags.')
 
756
        # And ask sprout for C2
 
757
        dir = source.bzrdir
 
758
        target = dir.sprout(self.get_url('target'), revision_id='rev-c2')
 
759
        # The tags are present
 
760
        new_branch = target.open_branch()
 
761
        self.assertEqual(
 
762
            {'tag-absent': 'absent-rev', 'tag-non-ancestry': 'rev-b2'},
 
763
            new_branch.tags.get_tag_dict())
 
764
        # And the revs for A2, B2 and C2's ancestries are present, but no
 
765
        # others.
 
766
        self.assertEqual(
 
767
            ['base-rev', 'rev-b1', 'rev-b2', 'rev-c1', 'rev-c2'],
 
768
            sorted(new_branch.repository.all_revision_ids()))
 
769
 
670
770
    def test_sprout_bzrdir_tree_branch_reference(self):
671
771
        # sprouting should create a repository if needed and a sprouted branch.
672
772
        # the tree state should not be copied.
755
855
        tree.commit('revision 1', rev_id='1')
756
856
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
757
857
        dir = tree.bzrdir
758
 
        if isinstance(dir, (bzrdir.BzrDirPreSplitOut,)):
759
 
            self.assertRaises(errors.MustHaveWorkingTree, dir.sprout,
760
 
                              self.get_url('target'),
761
 
                              create_tree_if_local=False)
762
 
            return
763
 
        target = dir.sprout(self.get_url('target'), create_tree_if_local=False)
 
858
        try:
 
859
            target = dir.sprout(self.get_url('target'),
 
860
                create_tree_if_local=False)
 
861
        except errors.MustHaveWorkingTree:
 
862
            raise TestNotApplicable("control dir format requires working tree")
764
863
        self.failIfExists('target/foo')
765
864
        self.assertEqual(tree.branch.last_revision(),
766
865
                         target.open_branch().last_revision())
803
902
            '_network_name', None),
804
903
            None)
805
904
        # supported formats must be able to init and open
806
 
        t = transport.get_transport(self.get_url())
807
 
        readonly_t = transport.get_transport(self.get_readonly_url())
 
905
        t = self.get_transport()
 
906
        readonly_t = self.get_readonly_transport()
808
907
        made_control = self.bzrdir_format.initialize(t.base)
809
908
        self.failUnless(isinstance(made_control, controldir.ControlDir))
 
909
        if isinstance(self.bzrdir_format, RemoteBzrDirFormat):
 
910
            return
810
911
        self.assertEqual(self.bzrdir_format,
811
912
                         controldir.ControlDirFormat.find_format(readonly_t))
812
913
        direct_opened_dir = self.bzrdir_format.open(readonly_t)
873
974
        if control is None:
874
975
            # uninitialisable format
875
976
            return
876
 
        if not isinstance(control._format, (bzrdir.BzrDirFormat5,
877
 
            bzrdir.BzrDirFormat6,)):
 
977
        if not control._format.fixed_components:
878
978
            self.assertEqual(repo.bzrdir.root_transport.base,
879
979
                made_repo.bzrdir.root_transport.base)
880
980
 
942
1042
        if control is None:
943
1043
            # uninitialisable format
944
1044
            return
945
 
        if isinstance(self.bzrdir_format, (bzrdir.BzrDirFormat5,
946
 
            bzrdir.BzrDirFormat6)):
 
1045
        if self.bzrdir_format.fixed_components:
947
1046
            # must stay with the all-in-one-format.
948
1047
            repo_name = self.bzrdir_format.network_name()
949
1048
        self.assertEqual(repo_name, repo._format.network_name())
968
1067
            # Repositories are open write-locked
969
1068
            self.assertTrue(repo.is_write_locked())
970
1069
            self.addCleanup(repo.unlock)
971
 
        self.assertIsInstance(control, bzrdir.BzrDir)
 
1070
        self.assertIsInstance(control, controldir.ControlDir)
972
1071
        opened = bzrdir.BzrDir.open(t.base)
973
1072
        expected_format = self.bzrdir_format
974
 
        if isinstance(expected_format, bzrdir.RemoteBzrDirFormat):
975
 
            # Current RemoteBzrDirFormat's do not reliably get network_name
976
 
            # set, so we skip a number of tests for RemoteBzrDirFormat's.
977
 
            self.assertIsInstance(control, RemoteBzrDir)
978
 
        else:
979
 
            if need_meta and isinstance(expected_format, (bzrdir.BzrDirFormat5,
980
 
                bzrdir.BzrDirFormat6)):
981
 
                # Pre-metadir formats change when we are making something that
982
 
                # needs a metaformat, because clone is used for push.
983
 
                expected_format = bzrdir.BzrDirMetaFormat1()
 
1073
        if need_meta and expected_format.fixed_components:
 
1074
            # Pre-metadir formats change when we are making something that
 
1075
            # needs a metaformat, because clone is used for push.
 
1076
            expected_format = bzrdir.BzrDirMetaFormat1()
 
1077
        if not isinstance(expected_format, RemoteBzrDirFormat):
984
1078
            self.assertEqual(control._format.network_name(),
985
1079
                expected_format.network_name())
986
1080
            self.assertEqual(control._format.network_name(),
997
1091
        # key in the registry gives back the same format. For remote obects
998
1092
        # we check that the network_name of the RemoteBzrDirFormat we have
999
1093
        # locally matches the actual format present on disk.
1000
 
        if isinstance(format, bzrdir.RemoteBzrDirFormat):
 
1094
        if isinstance(format, RemoteBzrDirFormat):
1001
1095
            dir._ensure_real()
1002
1096
            real_dir = dir._real_bzrdir
1003
1097
            network_name = format.network_name()
1024
1118
            # because the default open will not open them and
1025
1119
            # they may not be initializable.
1026
1120
            return
1027
 
        t = transport.get_transport(self.get_url())
 
1121
        t = self.get_transport()
1028
1122
        made_control = self.bzrdir_format.initialize(t.base)
1029
1123
        made_repo = made_control.create_repository()
1030
1124
        made_branch = made_control.create_branch()
1037
1131
            # because the default open will not open them and
1038
1132
            # they may not be initializable.
1039
1133
            return
1040
 
        t = transport.get_transport(self.get_url())
 
1134
        t = self.get_transport()
1041
1135
        made_control = self.bzrdir_format.initialize(t.base)
1042
1136
        made_repo = made_control.create_repository()
1043
1137
        made_branch = made_control.create_branch()
1052
1146
            # because the default open will not open them and
1053
1147
            # they may not be initializable.
1054
1148
            return
1055
 
        t = transport.get_transport(self.get_url())
 
1149
        t = self.get_transport()
1056
1150
        made_control = self.bzrdir_format.initialize(t.base)
1057
1151
        made_repo = made_control.create_repository()
1058
1152
        made_branch = made_control.create_branch()
1073
1167
            # because the default open will not open them and
1074
1168
            # they may not be initializable.
1075
1169
            return
1076
 
        t = transport.get_transport(self.get_url())
 
1170
        t = self.get_transport()
1077
1171
        made_control = self.bzrdir_format.initialize(t.base)
1078
1172
        made_repo = made_control.create_repository()
1079
1173
        # Check that we have a repository object.
1088
1182
            # because the default open will not open them and
1089
1183
            # they may not be initializable.
1090
1184
            return
1091
 
        t = transport.get_transport(self.get_url())
 
1185
        t = self.get_transport()
1092
1186
        made_control = self.bzrdir_format.initialize(t.base)
1093
1187
        try:
1094
1188
            made_repo = made_control.create_repository(shared=True)
1105
1199
            # because the default open will not open them and
1106
1200
            # they may not be initializable.
1107
1201
            return
1108
 
        t = transport.get_transport(self.get_url())
 
1202
        t = self.get_transport()
1109
1203
        made_control = self.bzrdir_format.initialize(t.base)
1110
1204
        made_repo = made_control.create_repository(shared=False)
1111
1205
        self.assertFalse(made_repo.is_shared())
1116
1210
            # because the default open will not open them and
1117
1211
            # they may not be initializable.
1118
1212
            return
1119
 
        t = transport.get_transport(self.get_url())
 
1213
        t = self.get_transport()
1120
1214
        made_control = self.bzrdir_format.initialize(t.base)
1121
1215
        made_repo = made_control.create_repository()
1122
1216
        opened_repo = made_control.open_repository()
1178
1272
        self.failUnless(isinstance(opened_tree, made_tree.__class__))
1179
1273
        self.failUnless(isinstance(opened_tree._format, made_tree._format.__class__))
1180
1274
 
1181
 
    def test_get_branch_transport(self):
1182
 
        dir = self.make_bzrdir('.')
1183
 
        # without a format, get_branch_transport gives use a transport
1184
 
        # which -may- point to an existing dir.
1185
 
        self.assertTrue(isinstance(dir.get_branch_transport(None),
1186
 
                                   transport.Transport))
1187
 
        # with a given format, either the bzr dir supports identifiable
1188
 
        # branches, or it supports anonymous  branch formats, but not both.
1189
 
        anonymous_format = bzrlib.branch.BzrBranchFormat4()
1190
 
        identifiable_format = bzrlib.branch.BzrBranchFormat5()
1191
 
        try:
1192
 
            found_transport = dir.get_branch_transport(anonymous_format)
1193
 
            self.assertRaises(errors.IncompatibleFormat,
1194
 
                              dir.get_branch_transport,
1195
 
                              identifiable_format)
1196
 
        except errors.IncompatibleFormat:
1197
 
            found_transport = dir.get_branch_transport(identifiable_format)
1198
 
        self.assertTrue(isinstance(found_transport, transport.Transport))
1199
 
        # and the dir which has been initialized for us must exist.
1200
 
        found_transport.list_dir('.')
1201
 
 
1202
 
    def test_get_repository_transport(self):
1203
 
        dir = self.make_bzrdir('.')
1204
 
        # without a format, get_repository_transport gives use a transport
1205
 
        # which -may- point to an existing dir.
1206
 
        self.assertTrue(isinstance(dir.get_repository_transport(None),
1207
 
                                   transport.Transport))
1208
 
        # with a given format, either the bzr dir supports identifiable
1209
 
        # repositories, or it supports anonymous  repository formats, but not both.
1210
 
        anonymous_format = weaverepo.RepositoryFormat6()
1211
 
        identifiable_format = weaverepo.RepositoryFormat7()
1212
 
        try:
1213
 
            found_transport = dir.get_repository_transport(anonymous_format)
1214
 
            self.assertRaises(errors.IncompatibleFormat,
1215
 
                              dir.get_repository_transport,
1216
 
                              identifiable_format)
1217
 
        except errors.IncompatibleFormat:
1218
 
            found_transport = dir.get_repository_transport(identifiable_format)
1219
 
        self.assertTrue(isinstance(found_transport, transport.Transport))
1220
 
        # and the dir which has been initialized for us must exist.
1221
 
        found_transport.list_dir('.')
1222
 
 
1223
 
    def test_get_workingtree_transport(self):
1224
 
        dir = self.make_bzrdir('.')
1225
 
        # without a format, get_workingtree_transport gives use a transport
1226
 
        # which -may- point to an existing dir.
1227
 
        self.assertTrue(isinstance(dir.get_workingtree_transport(None),
1228
 
                                   transport.Transport))
1229
 
        # with a given format, either the bzr dir supports identifiable
1230
 
        # trees, or it supports anonymous tree formats, but not both.
1231
 
        anonymous_format = workingtree.WorkingTreeFormat2()
1232
 
        identifiable_format = workingtree.WorkingTreeFormat3()
1233
 
        try:
1234
 
            found_transport = dir.get_workingtree_transport(anonymous_format)
1235
 
            self.assertRaises(errors.IncompatibleFormat,
1236
 
                              dir.get_workingtree_transport,
1237
 
                              identifiable_format)
1238
 
        except errors.IncompatibleFormat:
1239
 
            found_transport = dir.get_workingtree_transport(identifiable_format)
1240
 
        self.assertTrue(isinstance(found_transport, transport.Transport))
1241
 
        # and the dir which has been initialized for us must exist.
1242
 
        found_transport.list_dir('.')
1243
 
 
1244
1275
    def test_root_transport(self):
1245
1276
        dir = self.make_bzrdir('.')
1246
1277
        self.assertEqual(dir.root_transport.base,
1247
 
                         transport.get_transport(self.get_url('.')).base)
 
1278
                         self.get_transport().base)
1248
1279
 
1249
1280
    def test_find_repository_no_repo_under_standalone_branch(self):
1250
1281
        # finding a repo stops at standalone branches even if there is a
1255
1286
            # need a shared repository to test this.
1256
1287
            return
1257
1288
        url = self.get_url('intermediate')
1258
 
        transport.get_transport(self.get_url()).mkdir('intermediate')
1259
 
        transport.get_transport(self.get_url()).mkdir('intermediate/child')
 
1289
        t = self.get_transport()
 
1290
        t.mkdir('intermediate')
 
1291
        t.mkdir('intermediate/child')
1260
1292
        made_control = self.bzrdir_format.initialize(url)
1261
1293
        made_control.create_repository()
1262
1294
        innermost_control = self.bzrdir_format.initialize(
1280
1312
            # need a shared repository to test this.
1281
1313
            return
1282
1314
        url = self.get_url('childbzrdir')
1283
 
        transport.get_transport(self.get_url()).mkdir('childbzrdir')
 
1315
        self.get_transport().mkdir('childbzrdir')
1284
1316
        made_control = self.bzrdir_format.initialize(url)
1285
1317
        try:
1286
1318
            child_repo = made_control.open_repository()
1314
1346
            # need a shared repository to test this.
1315
1347
            return
1316
1348
        url = self.get_url('childrepo')
1317
 
        transport.get_transport(self.get_url()).mkdir('childrepo')
 
1349
        self.get_transport().mkdir('childrepo')
1318
1350
        child_control = self.bzrdir_format.initialize(url)
1319
1351
        child_repo = child_control.create_repository(shared=True)
1320
1352
        opened_control = bzrdir.BzrDir.open(self.get_url('childrepo'))
1333
1365
            # need a shared repository to test this.
1334
1366
            return
1335
1367
        url = self.get_url('intermediate')
1336
 
        transport.get_transport(self.get_url()).mkdir('intermediate')
1337
 
        transport.get_transport(self.get_url()).mkdir('intermediate/child')
 
1368
        t = self.get_transport()
 
1369
        t.mkdir('intermediate')
 
1370
        t.mkdir('intermediate/child')
1338
1371
        made_control = self.bzrdir_format.initialize(url)
1339
1372
        try:
1340
1373
            child_repo = made_control.open_repository()
1364
1397
            # (we force the latest known format as downgrades may not be
1365
1398
            # available
1366
1399
            self.assertTrue(isinstance(dir._format.get_converter(
1367
 
                format=dir._format), bzrdir.Converter))
 
1400
                format=dir._format), controldir.Converter))
1368
1401
        dir.needs_format_conversion(
1369
1402
            controldir.ControlDirFormat.get_default_format())
1370
1403