~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_bzrdir.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2011-06-30 18:28:17 UTC
  • mfrom: (5967.10.2 test-cat)
  • Revision ID: pqm@pqm.ubuntu.com-20110630182817-83a5q9r9rxfkdn8r
(mbp) don't use subprocesses for testing cat (Martin Pool)

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
from bzrlib import (
27
27
    branch,
28
28
    bzrdir,
29
 
    config,
30
29
    controldir,
31
30
    errors,
32
31
    help_topics,
35
34
    revision as _mod_revision,
36
35
    osutils,
37
36
    remote,
 
37
    symbol_versioning,
38
38
    transport as _mod_transport,
39
39
    urlutils,
40
40
    win32utils,
42
42
    workingtree_4,
43
43
    )
44
44
import bzrlib.branch
45
 
from bzrlib.branchfmt.fullhistory import BzrBranchFormat5
46
45
from bzrlib.errors import (
47
46
    NotBranchError,
48
47
    NoColocatedBranchSupport,
170
169
        self.assertNotContainsRe(new, 'hidden')
171
170
 
172
171
    def test_set_default_repository(self):
173
 
        default_factory = controldir.format_registry.get('default')
174
 
        old_default = [k for k, v in controldir.format_registry.iteritems()
 
172
        default_factory = bzrdir.format_registry.get('default')
 
173
        old_default = [k for k, v in bzrdir.format_registry.iteritems()
175
174
                       if v == default_factory and k != 'default'][0]
176
 
        controldir.format_registry.set_default_repository('dirstate-with-subtree')
 
175
        bzrdir.format_registry.set_default_repository('dirstate-with-subtree')
177
176
        try:
178
 
            self.assertIs(controldir.format_registry.get('dirstate-with-subtree'),
179
 
                          controldir.format_registry.get('default'))
 
177
            self.assertIs(bzrdir.format_registry.get('dirstate-with-subtree'),
 
178
                          bzrdir.format_registry.get('default'))
180
179
            self.assertIs(
181
180
                repository.format_registry.get_default().__class__,
182
181
                knitrepo.RepositoryFormatKnit3)
183
182
        finally:
184
 
            controldir.format_registry.set_default_repository(old_default)
 
183
            bzrdir.format_registry.set_default_repository(old_default)
185
184
 
186
185
    def test_aliases(self):
187
186
        a_registry = controldir.ControlDirFormatRegistry()
212
211
    """A sample BzrDir implementation to allow testing static methods."""
213
212
 
214
213
    def create_repository(self, shared=False):
215
 
        """See ControlDir.create_repository."""
 
214
        """See BzrDir.create_repository."""
216
215
        return "A repository"
217
216
 
218
217
    def open_repository(self):
219
 
        """See ControlDir.open_repository."""
 
218
        """See BzrDir.open_repository."""
220
219
        return SampleRepository(self)
221
220
 
222
221
    def create_branch(self, name=None):
223
 
        """See ControlDir.create_branch."""
 
222
        """See BzrDir.create_branch."""
224
223
        if name is not None:
225
224
            raise NoColocatedBranchSupport(self)
226
225
        return SampleBranch(self)
227
226
 
228
227
    def create_workingtree(self):
229
 
        """See ControlDir.create_workingtree."""
 
228
        """See BzrDir.create_workingtree."""
230
229
        return "A tree"
231
230
 
232
231
 
253
252
    def open(self, transport, _found=None):
254
253
        return "opened branch."
255
254
 
256
 
    @classmethod
257
 
    def from_string(cls, format_string):
258
 
        return cls()
259
 
 
260
255
 
261
256
class BzrDirFormatTest1(bzrdir.BzrDirMetaFormat1):
262
257
 
290
285
        self.build_tree(["foo/", "bar/"], transport=t)
291
286
        def check_format(format, url):
292
287
            format.initialize(url)
293
 
            t = _mod_transport.get_transport_from_path(url)
 
288
            t = _mod_transport.get_transport(url)
294
289
            found_format = bzrdir.BzrDirFormat.find_format(t)
295
290
            self.assertIsInstance(found_format, format.__class__)
296
291
        check_format(BzrDirFormatTest1(), "foo")
299
294
    def test_find_format_nothing_there(self):
300
295
        self.assertRaises(NotBranchError,
301
296
                          bzrdir.BzrDirFormat.find_format,
302
 
                          _mod_transport.get_transport_from_path('.'))
 
297
                          _mod_transport.get_transport('.'))
303
298
 
304
299
    def test_find_format_unknown_format(self):
305
300
        t = self.get_transport()
307
302
        t.put_bytes('.bzr/branch-format', '')
308
303
        self.assertRaises(UnknownFormatError,
309
304
                          bzrdir.BzrDirFormat.find_format,
310
 
                          _mod_transport.get_transport_from_path('.'))
 
305
                          _mod_transport.get_transport('.'))
311
306
 
312
307
    def test_register_unregister_format(self):
313
308
        format = SampleBzrDirFormat()
321
316
        # which bzrdir.open_containing will refuse (not supported)
322
317
        self.assertRaises(UnsupportedFormatError, bzrdir.BzrDir.open_containing, url)
323
318
        # but open_downlevel will work
324
 
        t = _mod_transport.get_transport_from_url(url)
 
319
        t = _mod_transport.get_transport(url)
325
320
        self.assertEqual(format.open(t), bzrdir.BzrDir.open_unsupported(url))
326
321
        # unregister the format
327
322
        bzrdir.BzrProber.formats.remove(format.get_format_string())
337
332
    def test_create_branch_and_repo_under_shared(self):
338
333
        # creating a branch and repo in a shared repo uses the
339
334
        # shared repository
340
 
        format = controldir.format_registry.make_bzrdir('knit')
 
335
        format = bzrdir.format_registry.make_bzrdir('knit')
341
336
        self.make_repository('.', shared=True, format=format)
342
337
        branch = bzrdir.BzrDir.create_branch_and_repo(
343
338
            self.get_url('child'), format=format)
347
342
    def test_create_branch_and_repo_under_shared_force_new(self):
348
343
        # creating a branch and repo in a shared repo can be forced to
349
344
        # make a new repo
350
 
        format = controldir.format_registry.make_bzrdir('knit')
 
345
        format = bzrdir.format_registry.make_bzrdir('knit')
351
346
        self.make_repository('.', shared=True, format=format)
352
347
        branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url('child'),
353
348
                                                      force_new_repo=True,
367
362
 
368
363
    def test_create_standalone_working_tree_under_shared_repo(self):
369
364
        # create standalone working tree always makes a repo.
370
 
        format = controldir.format_registry.make_bzrdir('knit')
 
365
        format = bzrdir.format_registry.make_bzrdir('knit')
371
366
        self.make_repository('.', shared=True, format=format)
372
367
        # note this is deliberately readonly, as this failure should
373
368
        # occur before any writes.
380
375
 
381
376
    def test_create_branch_convenience(self):
382
377
        # outside a repo the default convenience output is a repo+branch_tree
383
 
        format = controldir.format_registry.make_bzrdir('knit')
 
378
        format = bzrdir.format_registry.make_bzrdir('knit')
384
379
        branch = bzrdir.BzrDir.create_branch_convenience('.', format=format)
385
380
        branch.bzrdir.open_workingtree()
386
381
        branch.bzrdir.open_repository()
387
382
 
388
383
    def test_create_branch_convenience_possible_transports(self):
389
384
        """Check that the optional 'possible_transports' is recognized"""
390
 
        format = controldir.format_registry.make_bzrdir('knit')
 
385
        format = bzrdir.format_registry.make_bzrdir('knit')
391
386
        t = self.get_transport()
392
387
        branch = bzrdir.BzrDir.create_branch_convenience(
393
388
            '.', format=format, possible_transports=[t])
398
393
        """Creating a branch at the root of a fs should work."""
399
394
        self.vfs_transport_factory = memory.MemoryServer
400
395
        # outside a repo the default convenience output is a repo+branch_tree
401
 
        format = controldir.format_registry.make_bzrdir('knit')
 
396
        format = bzrdir.format_registry.make_bzrdir('knit')
402
397
        branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(),
403
398
                                                         format=format)
404
399
        self.assertRaises(errors.NoWorkingTree,
408
403
    def test_create_branch_convenience_under_shared_repo(self):
409
404
        # inside a repo the default convenience output is a branch+ follow the
410
405
        # repo tree policy
411
 
        format = controldir.format_registry.make_bzrdir('knit')
 
406
        format = bzrdir.format_registry.make_bzrdir('knit')
412
407
        self.make_repository('.', shared=True, format=format)
413
408
        branch = bzrdir.BzrDir.create_branch_convenience('child',
414
409
            format=format)
419
414
    def test_create_branch_convenience_under_shared_repo_force_no_tree(self):
420
415
        # inside a repo the default convenience output is a branch+ follow the
421
416
        # repo tree policy but we can override that
422
 
        format = controldir.format_registry.make_bzrdir('knit')
 
417
        format = bzrdir.format_registry.make_bzrdir('knit')
423
418
        self.make_repository('.', shared=True, format=format)
424
419
        branch = bzrdir.BzrDir.create_branch_convenience('child',
425
420
            force_new_tree=False, format=format)
431
426
    def test_create_branch_convenience_under_shared_repo_no_tree_policy(self):
432
427
        # inside a repo the default convenience output is a branch+ follow the
433
428
        # repo tree policy
434
 
        format = controldir.format_registry.make_bzrdir('knit')
 
429
        format = bzrdir.format_registry.make_bzrdir('knit')
435
430
        repo = self.make_repository('.', shared=True, format=format)
436
431
        repo.set_make_working_trees(False)
437
432
        branch = bzrdir.BzrDir.create_branch_convenience('child',
444
439
    def test_create_branch_convenience_under_shared_repo_no_tree_policy_force_tree(self):
445
440
        # inside a repo the default convenience output is a branch+ follow the
446
441
        # repo tree policy but we can override that
447
 
        format = controldir.format_registry.make_bzrdir('knit')
 
442
        format = bzrdir.format_registry.make_bzrdir('knit')
448
443
        repo = self.make_repository('.', shared=True, format=format)
449
444
        repo.set_make_working_trees(False)
450
445
        branch = bzrdir.BzrDir.create_branch_convenience('child',
456
451
    def test_create_branch_convenience_under_shared_repo_force_new_repo(self):
457
452
        # inside a repo the default convenience output is overridable to give
458
453
        # repo+branch+tree
459
 
        format = controldir.format_registry.make_bzrdir('knit')
 
454
        format = bzrdir.format_registry.make_bzrdir('knit')
460
455
        self.make_repository('.', shared=True, format=format)
461
456
        branch = bzrdir.BzrDir.create_branch_convenience('child',
462
457
            force_new_repo=True, format=format)
517
512
        # Clone source into directory
518
513
        target = source_bzrdir.clone(self.get_url('parent/target'))
519
514
 
520
 
    def test_format_initialize_on_transport_ex_stacked_on(self):
521
 
        # trunk is a stackable format.  Note that its in the same server area
522
 
        # which is what launchpad does, but not sufficient to exercise the
523
 
        # general case.
524
 
        trunk = self.make_branch('trunk', format='1.9')
525
 
        t = self.get_transport('stacked')
526
 
        old_fmt = controldir.format_registry.make_bzrdir('pack-0.92')
527
 
        repo_name = old_fmt.repository_format.network_name()
528
 
        # Should end up with a 1.9 format (stackable)
529
 
        repo, control, require_stacking, repo_policy = \
530
 
            old_fmt.initialize_on_transport_ex(t,
531
 
                    repo_format_name=repo_name, stacked_on='../trunk',
532
 
                    stack_on_pwd=t.base)
533
 
        if repo is not None:
534
 
            # Repositories are open write-locked
535
 
            self.assertTrue(repo.is_write_locked())
536
 
            self.addCleanup(repo.unlock)
537
 
        else:
538
 
            repo = control.open_repository()
539
 
        self.assertIsInstance(control, bzrdir.BzrDir)
540
 
        opened = bzrdir.BzrDir.open(t.base)
541
 
        if not isinstance(old_fmt, remote.RemoteBzrDirFormat):
542
 
            self.assertEqual(control._format.network_name(),
543
 
                old_fmt.network_name())
544
 
            self.assertEqual(control._format.network_name(),
545
 
                opened._format.network_name())
546
 
        self.assertEqual(control.__class__, opened.__class__)
547
 
        self.assertLength(1, repo._fallback_repositories)
548
 
 
549
515
    def test_sprout_obeys_stacking_policy(self):
550
516
        child_branch, new_child_transport = self.prepare_default_stacking()
551
517
        new_child = child_branch.bzrdir.sprout(new_child_transport.base)
744
710
    def test_open_containing_from_transport(self):
745
711
        self.assertRaises(NotBranchError,
746
712
            bzrdir.BzrDir.open_containing_from_transport,
747
 
            _mod_transport.get_transport_from_url(self.get_readonly_url('')))
 
713
            _mod_transport.get_transport(self.get_readonly_url('')))
748
714
        self.assertRaises(NotBranchError,
749
715
            bzrdir.BzrDir.open_containing_from_transport,
750
 
            _mod_transport.get_transport_from_url(
751
 
                self.get_readonly_url('g/p/q')))
 
716
            _mod_transport.get_transport(self.get_readonly_url('g/p/q')))
752
717
        control = bzrdir.BzrDir.create(self.get_url())
753
718
        branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
754
 
            _mod_transport.get_transport_from_url(
755
 
                self.get_readonly_url('')))
 
719
            _mod_transport.get_transport(self.get_readonly_url('')))
756
720
        self.assertEqual('', relpath)
757
721
        branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
758
 
            _mod_transport.get_transport_from_url(
759
 
                self.get_readonly_url('g/p/q')))
 
722
            _mod_transport.get_transport(self.get_readonly_url('g/p/q')))
760
723
        self.assertEqual('g/p/q', relpath)
761
724
 
762
725
    def test_open_containing_tree_or_branch(self):
824
787
 
825
788
    def test_sprout_recursive(self):
826
789
        tree = self.make_branch_and_tree('tree1',
827
 
                                         format='development-subtree')
 
790
                                         format='dirstate-with-subtree')
828
791
        sub_tree = self.make_branch_and_tree('tree1/subtree',
829
 
            format='development-subtree')
 
792
            format='dirstate-with-subtree')
830
793
        sub_tree.set_root_id('subtree-root')
831
794
        tree.add_reference(sub_tree)
832
795
        self.build_tree(['tree1/subtree/file'])
849
812
 
850
813
    def test_sprout_recursive_treeless(self):
851
814
        tree = self.make_branch_and_tree('tree1',
852
 
            format='development-subtree')
 
815
            format='dirstate-with-subtree')
853
816
        sub_tree = self.make_branch_and_tree('tree1/subtree',
854
 
            format='development-subtree')
 
817
            format='dirstate-with-subtree')
855
818
        tree.add_reference(sub_tree)
856
819
        self.build_tree(['tree1/subtree/file'])
857
820
        sub_tree.add('file')
858
821
        tree.commit('Initial commit')
859
822
        # The following line force the orhaning to reveal bug #634470
860
 
        tree.branch.get_config_stack().set(
 
823
        tree.branch.get_config().set_user_option(
861
824
            'bzr.transform.orphan_policy', 'move')
862
825
        tree.bzrdir.destroy_workingtree()
863
826
        # FIXME: subtree/.bzr is left here which allows the test to pass (or
864
827
        # fail :-( ) -- vila 20100909
865
828
        repo = self.make_repository('repo', shared=True,
866
 
            format='development-subtree')
 
829
            format='dirstate-with-subtree')
867
830
        repo.set_make_working_trees(False)
868
831
        # FIXME: we just deleted the workingtree and now we want to use it ????
869
832
        # At a minimum, we should use tree.branch below (but this fails too
935
898
        def evaluate(bzrdir):
936
899
            try:
937
900
                repo = bzrdir.open_repository()
938
 
            except errors.NoRepositoryPresent:
 
901
            except NoRepositoryPresent:
939
902
                return True, bzrdir.root_transport.base
940
903
            else:
941
904
                return False, bzrdir.root_transport.base
992
955
        branch_base = t.clone('branch').base
993
956
        self.assertEqual(branch_base, dir.get_branch_transport(None).base)
994
957
        self.assertEqual(branch_base,
995
 
                         dir.get_branch_transport(BzrBranchFormat5()).base)
 
958
                         dir.get_branch_transport(bzrlib.branch.BzrBranchFormat5()).base)
996
959
        repository_base = t.clone('repository').base
997
960
        self.assertEqual(repository_base, dir.get_repository_transport(None).base)
998
961
        repository_format = repository.format_registry.get_default()
1015
978
        Metadirs should compare equal iff they have the same repo, branch and
1016
979
        tree formats.
1017
980
        """
1018
 
        mydir = controldir.format_registry.make_bzrdir('knit')
 
981
        mydir = bzrdir.format_registry.make_bzrdir('knit')
1019
982
        self.assertEqual(mydir, mydir)
1020
983
        self.assertFalse(mydir != mydir)
1021
 
        otherdir = controldir.format_registry.make_bzrdir('knit')
 
984
        otherdir = bzrdir.format_registry.make_bzrdir('knit')
1022
985
        self.assertEqual(otherdir, mydir)
1023
986
        self.assertFalse(otherdir != mydir)
1024
 
        otherdir2 = controldir.format_registry.make_bzrdir('development-subtree')
 
987
        otherdir2 = bzrdir.format_registry.make_bzrdir('dirstate-with-subtree')
1025
988
        self.assertNotEqual(otherdir2, mydir)
1026
989
        self.assertFalse(otherdir2 == mydir)
1027
990
 
1028
 
    def test_with_features(self):
1029
 
        tree = self.make_branch_and_tree('tree', format='2a')
1030
 
        tree.bzrdir.update_feature_flags({"bar": "required"})
1031
 
        self.assertRaises(errors.MissingFeature, bzrdir.BzrDir.open, 'tree')
1032
 
        bzrdir.BzrDirMetaFormat1.register_feature('bar')
1033
 
        self.addCleanup(bzrdir.BzrDirMetaFormat1.unregister_feature, 'bar')
1034
 
        dir = bzrdir.BzrDir.open('tree')
1035
 
        self.assertEquals("required", dir._format.features.get("bar"))
1036
 
        tree.bzrdir.update_feature_flags({"bar": None, "nonexistant": None})
1037
 
        dir = bzrdir.BzrDir.open('tree')
1038
 
        self.assertEquals({}, dir._format.features)
1039
 
 
1040
991
    def test_needs_conversion_different_working_tree(self):
1041
992
        # meta1dirs need an conversion if any element is not the default.
1042
 
        new_format = controldir.format_registry.make_bzrdir('dirstate')
 
993
        new_format = bzrdir.format_registry.make_bzrdir('dirstate')
1043
994
        tree = self.make_branch_and_tree('tree', format='knit')
1044
995
        self.assertTrue(tree.bzrdir.needs_format_conversion(
1045
996
            new_format))
1046
997
 
1047
998
    def test_initialize_on_format_uses_smart_transport(self):
1048
999
        self.setup_smart_server_with_call_log()
1049
 
        new_format = controldir.format_registry.make_bzrdir('dirstate')
 
1000
        new_format = bzrdir.format_registry.make_bzrdir('dirstate')
1050
1001
        transport = self.get_transport('target')
1051
1002
        transport.ensure_base()
1052
1003
        self.reset_smart_call_log()
1070
1021
 
1071
1022
    def test_create_branch_convenience(self):
1072
1023
        # outside a repo the default convenience output is a repo+branch_tree
1073
 
        format = controldir.format_registry.make_bzrdir('knit')
 
1024
        format = bzrdir.format_registry.make_bzrdir('knit')
1074
1025
        branch = bzrdir.BzrDir.create_branch_convenience(
1075
1026
            self.get_url('foo'), format=format)
1076
1027
        self.assertRaises(errors.NoWorkingTree,
1079
1030
 
1080
1031
    def test_create_branch_convenience_force_tree_not_local_fails(self):
1081
1032
        # outside a repo the default convenience output is a repo+branch_tree
1082
 
        format = controldir.format_registry.make_bzrdir('knit')
 
1033
        format = bzrdir.format_registry.make_bzrdir('knit')
1083
1034
        self.assertRaises(errors.NotLocalUrl,
1084
1035
            bzrdir.BzrDir.create_branch_convenience,
1085
1036
            self.get_url('foo'),
1090
1041
 
1091
1042
    def test_clone(self):
1092
1043
        # clone into a nonlocal path works
1093
 
        format = controldir.format_registry.make_bzrdir('knit')
 
1044
        format = bzrdir.format_registry.make_bzrdir('knit')
1094
1045
        branch = bzrdir.BzrDir.create_branch_convenience('local',
1095
1046
                                                         format=format)
1096
1047
        branch.bzrdir.open_workingtree()
1257
1208
 
1258
1209
    def __init__(self, *args, **kwargs):
1259
1210
        super(_TestBzrDir, self).__init__(*args, **kwargs)
1260
 
        self.test_branch = _TestBranch(self.transport)
 
1211
        self.test_branch = _TestBranch()
1261
1212
        self.test_branch.repository = self.create_repository()
1262
1213
 
1263
 
    def open_branch(self, unsupported=False, possible_transports=None):
 
1214
    def open_branch(self, unsupported=False):
1264
1215
        return self.test_branch
1265
1216
 
1266
1217
    def cloning_metadir(self, require_stacking=False):
1274
1225
class _TestBranch(bzrlib.branch.Branch):
1275
1226
    """Test Branch implementation for TestBzrDirSprout."""
1276
1227
 
1277
 
    def __init__(self, transport, *args, **kwargs):
 
1228
    def __init__(self, *args, **kwargs):
1278
1229
        self._format = _TestBranchFormat()
1279
 
        self._transport = transport
1280
 
        self.base = transport.base
1281
1230
        super(_TestBranch, self).__init__(*args, **kwargs)
1282
1231
        self.calls = []
1283
1232
        self._parent = None
1284
1233
 
1285
1234
    def sprout(self, *args, **kwargs):
1286
1235
        self.calls.append('sprout')
1287
 
        return _TestBranch(self._transport)
 
1236
        return _TestBranch()
1288
1237
 
1289
1238
    def copy_content_into(self, destination, revision_id=None):
1290
1239
        self.calls.append('copy_content_into')
1295
1244
    def get_parent(self):
1296
1245
        return self._parent
1297
1246
 
1298
 
    def _get_config(self):
1299
 
        return config.TransportConfig(self._transport, 'branch.conf')
1300
 
 
1301
 
    def _get_config_store(self):
1302
 
        return config.BranchStore(self)
1303
 
 
1304
1247
    def set_parent(self, parent):
1305
1248
        self._parent = parent
1306
1249
 
1371
1314
        self.assertEqual('fail', err._preformatted_string)
1372
1315
 
1373
1316
    def test_post_repo_init(self):
1374
 
        from bzrlib.controldir import RepoInitHookParams
 
1317
        from bzrlib.bzrdir import RepoInitHookParams
1375
1318
        calls = []
1376
1319
        bzrdir.BzrDir.hooks.install_named_hook('post_repo_init',
1377
1320
            calls.append, None)
1404
1347
            possible_transports=[self._transport])
1405
1348
        self._bzrdir = bzrdir.BzrDir.open_from_transport(self._transport)
1406
1349
 
 
1350
    def test_deprecated_generate_backup_name(self):
 
1351
        res = self.applyDeprecated(
 
1352
                symbol_versioning.deprecated_in((2, 3, 0)),
 
1353
                self._bzrdir.generate_backup_name, 'whatever')
 
1354
 
1407
1355
    def test_new(self):
1408
1356
        self.assertEqual("a.~1~", self._bzrdir._available_backup_name("a"))
1409
1357
 
1411
1359
        self._transport.put_bytes("a.~1~", "some content")
1412
1360
        self.assertEqual("a.~2~", self._bzrdir._available_backup_name("a"))
1413
1361
 
1414
 
 
1415
 
class TestMeta1DirColoFormat(TestCaseWithTransport):
1416
 
    """Tests specific to the meta1 dir with colocated branches format."""
1417
 
 
1418
 
    def test_supports_colo(self):
1419
 
        format = bzrdir.BzrDirMetaFormat1Colo()
1420
 
        self.assertTrue(format.colocated_branches)
1421
 
 
1422
 
    def test_upgrade_from_2a(self):
1423
 
        tree = self.make_branch_and_tree('.', format='2a')
1424
 
        format = bzrdir.BzrDirMetaFormat1Colo()
1425
 
        self.assertTrue(tree.bzrdir.needs_format_conversion(format))
1426
 
        converter = tree.bzrdir._format.get_converter(format)
1427
 
        result = converter.convert(tree.bzrdir, None)
1428
 
        self.assertIsInstance(result._format, bzrdir.BzrDirMetaFormat1Colo)
1429
 
        self.assertFalse(result.needs_format_conversion(format))
1430
 
 
1431
 
    def test_downgrade_to_2a(self):
1432
 
        tree = self.make_branch_and_tree('.', format='development-colo')
1433
 
        format = bzrdir.BzrDirMetaFormat1()
1434
 
        self.assertTrue(tree.bzrdir.needs_format_conversion(format))
1435
 
        converter = tree.bzrdir._format.get_converter(format)
1436
 
        result = converter.convert(tree.bzrdir, None)
1437
 
        self.assertIsInstance(result._format, bzrdir.BzrDirMetaFormat1)
1438
 
        self.assertFalse(result.needs_format_conversion(format))
1439
 
 
1440
 
    def test_downgrade_to_2a_too_many_branches(self):
1441
 
        tree = self.make_branch_and_tree('.', format='development-colo')
1442
 
        tree.bzrdir.create_branch(name="another-colocated-branch")
1443
 
        converter = tree.bzrdir._format.get_converter(
1444
 
            bzrdir.BzrDirMetaFormat1())
1445
 
        result = converter.convert(tree.bzrdir, bzrdir.BzrDirMetaFormat1())
1446
 
        self.assertIsInstance(result._format, bzrdir.BzrDirMetaFormat1)
1447
 
 
1448
 
    def test_nested(self):
1449
 
        tree = self.make_branch_and_tree('.', format='development-colo')
1450
 
        tree.bzrdir.create_branch(name='foo')
1451
 
        tree.bzrdir.create_branch(name='fool/bla')
1452
 
        self.assertRaises(
1453
 
            errors.ParentBranchExists, tree.bzrdir.create_branch,
1454
 
            name='foo/bar')
1455
 
 
1456
 
    def test_parent(self):
1457
 
        tree = self.make_branch_and_tree('.', format='development-colo')
1458
 
        tree.bzrdir.create_branch(name='fool/bla')
1459
 
        tree.bzrdir.create_branch(name='foo/bar')
1460
 
        self.assertRaises(
1461
 
            errors.AlreadyBranchError, tree.bzrdir.create_branch,
1462
 
            name='foo')
1463
 
 
1464
 
 
1465
 
class SampleBzrFormat(bzrdir.BzrFormat):
1466
 
 
1467
 
    @classmethod
1468
 
    def get_format_string(cls):
1469
 
        return "First line\n"
1470
 
 
1471
 
 
1472
 
class TestBzrFormat(TestCase):
1473
 
    """Tests for BzrFormat."""
1474
 
 
1475
 
    def test_as_string(self):
1476
 
        format = SampleBzrFormat()
1477
 
        format.features = {"foo": "required"}
1478
 
        self.assertEquals(format.as_string(),
1479
 
            "First line\n"
1480
 
            "required foo\n")
1481
 
        format.features["another"] = "optional"
1482
 
        self.assertEquals(format.as_string(),
1483
 
            "First line\n"
1484
 
            "required foo\n"
1485
 
            "optional another\n")
1486
 
 
1487
 
    def test_network_name(self):
1488
 
        # The network string should include the feature info
1489
 
        format = SampleBzrFormat()
1490
 
        format.features = {"foo": "required"}
1491
 
        self.assertEquals(
1492
 
            "First line\nrequired foo\n",
1493
 
            format.network_name())
1494
 
 
1495
 
    def test_from_string_no_features(self):
1496
 
        # No features
1497
 
        format = SampleBzrFormat.from_string(
1498
 
            "First line\n")
1499
 
        self.assertEquals({}, format.features)
1500
 
 
1501
 
    def test_from_string_with_feature(self):
1502
 
        # Proper feature
1503
 
        format = SampleBzrFormat.from_string(
1504
 
            "First line\nrequired foo\n")
1505
 
        self.assertEquals("required", format.features.get("foo"))
1506
 
 
1507
 
    def test_from_string_format_string_mismatch(self):
1508
 
        # The first line has to match the format string
1509
 
        self.assertRaises(AssertionError, SampleBzrFormat.from_string,
1510
 
            "Second line\nrequired foo\n")
1511
 
 
1512
 
    def test_from_string_missing_space(self):
1513
 
        # At least one space is required in the feature lines
1514
 
        self.assertRaises(errors.ParseFormatError, SampleBzrFormat.from_string,
1515
 
            "First line\nfoo\n")
1516
 
 
1517
 
    def test_from_string_with_spaces(self):
1518
 
        # Feature with spaces (in case we add stuff like this in the future)
1519
 
        format = SampleBzrFormat.from_string(
1520
 
            "First line\nrequired foo with spaces\n")
1521
 
        self.assertEquals("required", format.features.get("foo with spaces"))
1522
 
 
1523
 
    def test_eq(self):
1524
 
        format1 = SampleBzrFormat()
1525
 
        format1.features = {"nested-trees": "optional"}
1526
 
        format2 = SampleBzrFormat()
1527
 
        format2.features = {"nested-trees": "optional"}
1528
 
        self.assertEquals(format1, format1)
1529
 
        self.assertEquals(format1, format2)
1530
 
        format3 = SampleBzrFormat()
1531
 
        self.assertNotEquals(format1, format3)
1532
 
 
1533
 
    def test_check_support_status_optional(self):
1534
 
        # Optional, so silently ignore
1535
 
        format = SampleBzrFormat()
1536
 
        format.features = {"nested-trees": "optional"}
1537
 
        format.check_support_status(True)
1538
 
        self.addCleanup(SampleBzrFormat.unregister_feature, "nested-trees")
1539
 
        SampleBzrFormat.register_feature("nested-trees")
1540
 
        format.check_support_status(True)
1541
 
 
1542
 
    def test_check_support_status_required(self):
1543
 
        # Optional, so trigger an exception
1544
 
        format = SampleBzrFormat()
1545
 
        format.features = {"nested-trees": "required"}
1546
 
        self.assertRaises(errors.MissingFeature, format.check_support_status,
1547
 
            True)
1548
 
        self.addCleanup(SampleBzrFormat.unregister_feature, "nested-trees")
1549
 
        SampleBzrFormat.register_feature("nested-trees")
1550
 
        format.check_support_status(True)
1551
 
 
1552
 
    def test_check_support_status_unknown(self):
1553
 
        # treat unknown necessity as required
1554
 
        format = SampleBzrFormat()
1555
 
        format.features = {"nested-trees": "unknown"}
1556
 
        self.assertRaises(errors.MissingFeature, format.check_support_status,
1557
 
            True)
1558
 
        self.addCleanup(SampleBzrFormat.unregister_feature, "nested-trees")
1559
 
        SampleBzrFormat.register_feature("nested-trees")
1560
 
        format.check_support_status(True)
1561
 
 
1562
 
    def test_feature_already_registered(self):
1563
 
        # a feature can only be registered once
1564
 
        self.addCleanup(SampleBzrFormat.unregister_feature, "nested-trees")
1565
 
        SampleBzrFormat.register_feature("nested-trees")
1566
 
        self.assertRaises(errors.FeatureAlreadyRegistered,
1567
 
            SampleBzrFormat.register_feature, "nested-trees")
1568
 
 
1569
 
    def test_feature_with_space(self):
1570
 
        # spaces are not allowed in feature names
1571
 
        self.assertRaises(ValueError, SampleBzrFormat.register_feature,
1572
 
            "nested trees")