~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/per_bzrdir/test_bzrdir.py

Merge bzr.dev, update to use new hooks.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
import bzrlib.branch
23
23
from bzrlib import (
 
24
    branch,
 
25
    bzrdir,
24
26
    errors,
 
27
    repository,
25
28
    revision as _mod_revision,
26
29
    transport,
 
30
    workingtree,
27
31
    )
 
32
from bzrlib.remote import RemoteBzrDirFormat
28
33
from bzrlib.tests import (
 
34
    TestNotApplicable,
29
35
    TestSkipped,
30
36
    )
31
37
from bzrlib.tests.per_bzrdir import TestCaseWithBzrDir
34
40
    )
35
41
 
36
42
 
 
43
class AnonymousTestBranchFormat(bzrlib.branch.BranchFormat):
 
44
    """An anonymous branch format (does not have a format string)"""
 
45
 
 
46
    def get_format_string(self):
 
47
        raise NotImplementedError(self.get_format_string)
 
48
 
 
49
 
 
50
class IdentifiableTestBranchFormat(bzrlib.branch.BranchFormat):
 
51
    """An identifable branch format (has a format string)"""
 
52
 
 
53
    def get_format_string(self):
 
54
        return "I have an identity"
 
55
 
 
56
 
 
57
class AnonymousTestRepositoryFormat(repository.RepositoryFormat):
 
58
    """An anonymous branch format (does not have a format string)"""
 
59
 
 
60
    def get_format_string(self):
 
61
        raise NotImplementedError(self.get_format_string)
 
62
 
 
63
 
 
64
class IdentifiableTestRepositoryFormat(repository.RepositoryFormat):
 
65
    """An identifable branch format (has a format string)"""
 
66
 
 
67
    def get_format_string(self):
 
68
        return "I have an identity"
 
69
 
 
70
 
 
71
class AnonymousTestWorkingTreeFormat(workingtree.WorkingTreeFormat):
 
72
    """An anonymous branch format (does not have a format string)"""
 
73
 
 
74
    def get_format_string(self):
 
75
        raise NotImplementedError(self.get_format_string)
 
76
 
 
77
 
 
78
class IdentifiableTestWorkingTreeFormat(workingtree.WorkingTreeFormat):
 
79
    """An identifable branch format (has a format string)"""
 
80
 
 
81
    def get_format_string(self):
 
82
        return "I have an identity"
 
83
 
 
84
 
37
85
class TestBzrDir(TestCaseWithBzrDir):
38
86
 
39
87
    # Many of these tests test for disk equality rather than checking
115
163
                for file_id, revision_id in text_index.iterkeys():
116
164
                    desired_files.append(
117
165
                        (file_id, revision_id, (file_id, revision_id)))
118
 
                left_texts = list(left_repo.iter_files_bytes(desired_files))
119
 
                right_texts = list(right_repo.iter_files_bytes(desired_files))
 
166
                left_texts = [(identifier, "".join(bytes_iterator)) for
 
167
                        (identifier, bytes_iterator) in
 
168
                        left_repo.iter_files_bytes(desired_files)]
 
169
                right_texts = [(identifier, "".join(bytes_iterator)) for
 
170
                        (identifier, bytes_iterator) in
 
171
                        right_repo.iter_files_bytes(desired_files)]
120
172
                left_texts.sort()
121
173
                right_texts.sort()
122
174
                self.assertEqual(left_texts, right_texts)
169
221
        TestSkipped.  Returns the newly created working tree.
170
222
        """
171
223
        try:
172
 
            return a_bzrdir.create_workingtree()
 
224
            # This passes in many named options to make sure they're
 
225
            # understood by subclasses: see
 
226
            # <https://bugs.launchpad.net/bzr/+bug/524627>.
 
227
            return a_bzrdir.create_workingtree(
 
228
                revision_id=None,
 
229
                from_branch=None,
 
230
                accelerator_tree=None,
 
231
                hardlink=False)
173
232
        except errors.NotLocalUrl:
174
233
            raise TestSkipped("cannot make working tree with transport %r"
175
234
                              % a_bzrdir.transport)
277
336
                                     './.bzr/repository',
278
337
                                     ])
279
338
        self.assertRepositoryHasSameItems(tree.branch.repository,
280
 
            target.open_repository())
 
339
            target.open_branch().repository)
281
340
        target.open_workingtree().revert()
282
341
 
283
342
    def test_revert_inventory(self):
297
356
                                     './.bzr/repository',
298
357
                                     ])
299
358
        self.assertRepositoryHasSameItems(tree.branch.repository,
300
 
            target.open_repository())
 
359
            target.open_branch().repository)
301
360
 
302
361
        target.open_workingtree().revert()
303
362
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
309
368
                                     './.bzr/repository',
310
369
                                     ])
311
370
        self.assertRepositoryHasSameItems(tree.branch.repository,
312
 
            target.open_repository())
 
371
            target.open_branch().repository)
313
372
 
314
373
    def test_clone_bzrdir_tree_branch_reference(self):
315
374
        # a tree with a branch reference (aka a checkout)
449
508
        self.assertNotEqual(dir.transport.base, target.transport.base)
450
509
        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
451
510
                                    [
452
 
                                     './.bzr/branch/branch.conf',
453
 
                                     './.bzr/branch/parent',
 
511
                                     './.bzr/branch',
454
512
                                     './.bzr/checkout/dirstate',
455
513
                                     './.bzr/checkout/stat-cache',
456
514
                                     './.bzr/checkout/inventory',
469
527
        # must not overwrite existing directories
470
528
        self.build_tree(['.bzr.retired.0/', '.bzr.retired.0/junk',],
471
529
            transport=transport)
472
 
        self.failUnless(transport.has('.bzr'))
 
530
        self.assertTrue(transport.has('.bzr'))
473
531
        bd.retire_bzrdir()
474
 
        self.failIf(transport.has('.bzr'))
475
 
        self.failUnless(transport.has('.bzr.retired.1'))
 
532
        self.assertFalse(transport.has('.bzr'))
 
533
        self.assertTrue(transport.has('.bzr.retired.1'))
476
534
 
477
535
    def test_retire_bzrdir_limited(self):
478
536
        bd = self.make_bzrdir('.')
480
538
        # must not overwrite existing directories
481
539
        self.build_tree(['.bzr.retired.0/', '.bzr.retired.0/junk',],
482
540
            transport=transport)
483
 
        self.failUnless(transport.has('.bzr'))
 
541
        self.assertTrue(transport.has('.bzr'))
484
542
        self.assertRaises((errors.FileExists, errors.DirectoryNotEmpty),
485
543
            bd.retire_bzrdir, limit=0)
 
544
 
 
545
    def test_get_branch_transport(self):
 
546
        dir = self.make_bzrdir('.')
 
547
        # without a format, get_branch_transport gives use a transport
 
548
        # which -may- point to an existing dir.
 
549
        self.assertTrue(isinstance(dir.get_branch_transport(None),
 
550
                                   transport.Transport))
 
551
        # with a given format, either the bzr dir supports identifiable
 
552
        # branches, or it supports anonymous branch formats, but not both.
 
553
        anonymous_format = AnonymousTestBranchFormat()
 
554
        identifiable_format = IdentifiableTestBranchFormat()
 
555
        try:
 
556
            found_transport = dir.get_branch_transport(anonymous_format)
 
557
            self.assertRaises(errors.IncompatibleFormat,
 
558
                              dir.get_branch_transport,
 
559
                              identifiable_format)
 
560
        except errors.IncompatibleFormat:
 
561
            found_transport = dir.get_branch_transport(identifiable_format)
 
562
        self.assertTrue(isinstance(found_transport, transport.Transport))
 
563
        # and the dir which has been initialized for us must exist.
 
564
        found_transport.list_dir('.')
 
565
 
 
566
    def test_get_repository_transport(self):
 
567
        dir = self.make_bzrdir('.')
 
568
        # without a format, get_repository_transport gives use a transport
 
569
        # which -may- point to an existing dir.
 
570
        self.assertTrue(isinstance(dir.get_repository_transport(None),
 
571
                                   transport.Transport))
 
572
        # with a given format, either the bzr dir supports identifiable
 
573
        # repositories, or it supports anonymous repository formats, but not both.
 
574
        anonymous_format = AnonymousTestRepositoryFormat()
 
575
        identifiable_format = IdentifiableTestRepositoryFormat()
 
576
        try:
 
577
            found_transport = dir.get_repository_transport(anonymous_format)
 
578
            self.assertRaises(errors.IncompatibleFormat,
 
579
                              dir.get_repository_transport,
 
580
                              identifiable_format)
 
581
        except errors.IncompatibleFormat:
 
582
            found_transport = dir.get_repository_transport(identifiable_format)
 
583
        self.assertTrue(isinstance(found_transport, transport.Transport))
 
584
        # and the dir which has been initialized for us must exist.
 
585
        found_transport.list_dir('.')
 
586
 
 
587
    def test_get_workingtree_transport(self):
 
588
        dir = self.make_bzrdir('.')
 
589
        # without a format, get_workingtree_transport gives use a transport
 
590
        # which -may- point to an existing dir.
 
591
        self.assertTrue(isinstance(dir.get_workingtree_transport(None),
 
592
                                   transport.Transport))
 
593
        # with a given format, either the bzr dir supports identifiable
 
594
        # trees, or it supports anonymous tree formats, but not both.
 
595
        anonymous_format = AnonymousTestWorkingTreeFormat()
 
596
        identifiable_format = IdentifiableTestWorkingTreeFormat()
 
597
        try:
 
598
            found_transport = dir.get_workingtree_transport(anonymous_format)
 
599
            self.assertRaises(errors.IncompatibleFormat,
 
600
                              dir.get_workingtree_transport,
 
601
                              identifiable_format)
 
602
        except errors.IncompatibleFormat:
 
603
            found_transport = dir.get_workingtree_transport(identifiable_format)
 
604
        self.assertTrue(isinstance(found_transport, transport.Transport))
 
605
        # and the dir which has been initialized for us must exist.
 
606
        found_transport.list_dir('.')
 
607
 
 
608
    def assertInitializeEx(self, t, need_meta=False, **kwargs):
 
609
        """Execute initialize_on_transport_ex and check it succeeded correctly.
 
610
 
 
611
        This involves checking that the disk objects were created, open with
 
612
        the same format returned, and had the expected disk format.
 
613
 
 
614
        :param t: The transport to initialize on.
 
615
        :param **kwargs: Additional arguments to pass to
 
616
            initialize_on_transport_ex.
 
617
        :return: the resulting repo, control dir tuple.
 
618
        """
 
619
        if not self.bzrdir_format.is_initializable():
 
620
            raise TestNotApplicable("control dir format is not "
 
621
                "initializable")
 
622
        repo, control, require_stacking, repo_policy = \
 
623
            self.bzrdir_format.initialize_on_transport_ex(t, **kwargs)
 
624
        if repo is not None:
 
625
            # Repositories are open write-locked
 
626
            self.assertTrue(repo.is_write_locked())
 
627
            self.addCleanup(repo.unlock)
 
628
        self.assertIsInstance(control, bzrdir.BzrDir)
 
629
        opened = bzrdir.BzrDir.open(t.base)
 
630
        expected_format = self.bzrdir_format
 
631
        if need_meta and expected_format.fixed_components:
 
632
            # Pre-metadir formats change when we are making something that
 
633
            # needs a metaformat, because clone is used for push.
 
634
            expected_format = bzrdir.BzrDirMetaFormat1()
 
635
        if not isinstance(expected_format, RemoteBzrDirFormat):
 
636
            self.assertEqual(control._format.network_name(),
 
637
                expected_format.network_name())
 
638
            self.assertEqual(control._format.network_name(),
 
639
                opened._format.network_name())
 
640
        self.assertEqual(control.__class__, opened.__class__)
 
641
        return repo, control
 
642
 
 
643
    def test_format_initialize_on_transport_ex_default_stack_on(self):
 
644
        # When initialize_on_transport_ex uses a stacked-on branch because of
 
645
        # a stacking policy on the target, the location of the fallback
 
646
        # repository is the same as the external location of the stacked-on
 
647
        # branch.
 
648
        balloon = self.make_bzrdir('balloon')
 
649
        if isinstance(balloon._format, bzrdir.BzrDirMetaFormat1):
 
650
            stack_on = self.make_branch('stack-on', format='1.9')
 
651
        else:
 
652
            stack_on = self.make_branch('stack-on')
 
653
        if not stack_on.repository._format.supports_nesting_repositories:
 
654
            raise TestNotApplicable("requires nesting repositories")
 
655
        config = self.make_bzrdir('.').get_config()
 
656
        try:
 
657
            config.set_default_stack_on('stack-on')
 
658
        except errors.BzrError:
 
659
            raise TestNotApplicable('Only relevant for stackable formats.')
 
660
        # Initialize a bzrdir subject to the policy.
 
661
        t = self.get_transport('stacked')
 
662
        repo_fmt = bzrdir.format_registry.make_bzrdir('1.9')
 
663
        repo_name = repo_fmt.repository_format.network_name()
 
664
        repo, control = self.assertInitializeEx(
 
665
            t, need_meta=True, repo_format_name=repo_name, stacked_on=None)
 
666
        # self.addCleanup(repo.unlock)
 
667
        # There's one fallback repo, with a public location.
 
668
        self.assertLength(1, repo._fallback_repositories)
 
669
        fallback_repo = repo._fallback_repositories[0]
 
670
        self.assertEqual(
 
671
            stack_on.base, fallback_repo.bzrdir.root_transport.base)
 
672
        # The bzrdir creates a branch in stacking-capable format.
 
673
        new_branch = control.create_branch()
 
674
        self.assertTrue(new_branch._format.supports_stacking())
 
675
 
 
676
    def test_no_leftover_dirs(self):
 
677
        # bug 886196: development-colo uses a branch-lock directory
 
678
        # in the user directory rather than the control directory.
 
679
        if not self.bzrdir_format.colocated_branches:
 
680
            raise TestNotApplicable(
 
681
                "format does not support colocated branches")
 
682
        branch = self.make_branch('.', format='development-colo')
 
683
        branch.bzrdir.create_branch(name="another-colocated-branch")
 
684
        self.assertEquals(
 
685
            branch.bzrdir.user_transport.list_dir("."),
 
686
            [".bzr"])
 
687
 
 
688
    def test_get_branches(self):
 
689
        repo = self.make_repository('branch-1')
 
690
        try:
 
691
            target_branch = repo.bzrdir.create_branch(name='foo')
 
692
        except errors.NoColocatedBranchSupport:
 
693
            raise TestNotApplicable('Format does not support colocation')
 
694
        reference = branch.BranchReferenceFormat().initialize(
 
695
            repo.bzrdir, target_branch=target_branch)
 
696
        self.assertEqual(set([None, 'foo']),
 
697
                         set(repo.bzrdir.get_branches().keys()))