~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/branch_implementations/test_pull.py

  • Committer: Robert Collins
  • Date: 2007-07-04 08:08:13 UTC
  • mfrom: (2572 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2587.
  • Revision ID: robertc@robertcollins.net-20070704080813-wzebx0r88fvwj5rq
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2004, 2005 by Canonical Ltd
 
1
# Copyright (C) 2004, 2005, 2007 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
18
18
 
19
19
import os
20
20
 
21
 
from bzrlib.branch import Branch
22
 
from bzrlib.osutils import abspath, realpath
23
 
from bzrlib.tests import TestCaseWithTransport
24
 
 
25
 
 
26
 
class TestPull(TestCaseWithTransport):
 
21
from bzrlib.branch import Branch, BzrBranchFormat5
 
22
from bzrlib.bzrdir import BzrDir
 
23
from bzrlib import errors
 
24
from bzrlib.memorytree import MemoryTree
 
25
from bzrlib.revision import NULL_REVISION
 
26
from bzrlib.tests import TestSkipped
 
27
from bzrlib.tests.branch_implementations.test_branch import TestCaseWithBranch
 
28
 
 
29
 
 
30
class TestPull(TestCaseWithBranch):
27
31
 
28
32
    def test_pull_convergence_simple(self):
29
33
        # when revisions are pulled, the left-most accessible parents must 
53
57
        parent.commit('merge other', rev_id='P2')
54
58
        mine.pull(parent.branch)
55
59
        self.assertEqual(['P1', 'P2'], mine.branch.revision_history())
 
60
 
 
61
    def test_pull_updates_checkout_and_master(self):
 
62
        """Pulling into a checkout updates the checkout and the master branch"""
 
63
        master_tree = self.make_branch_and_tree('master')
 
64
        rev1 = master_tree.commit('master')
 
65
        checkout = master_tree.branch.create_checkout('checkout')
 
66
 
 
67
        other = master_tree.branch.bzrdir.sprout('other').open_workingtree()
 
68
        rev2 = other.commit('other commit')
 
69
        # now pull, which should update both checkout and master.
 
70
        checkout.branch.pull(other.branch)
 
71
        self.assertEqual([rev1, rev2], checkout.branch.revision_history())
 
72
        self.assertEqual([rev1, rev2], master_tree.branch.revision_history())
 
73
 
 
74
    def test_pull_raises_specific_error_on_master_connection_error(self):
 
75
        master_tree = self.make_branch_and_tree('master')
 
76
        checkout = master_tree.branch.create_checkout('checkout')
 
77
        other = master_tree.branch.bzrdir.sprout('other').open_workingtree()
 
78
        # move the branch out of the way on disk to cause a connection
 
79
        # error.
 
80
        os.rename('master', 'master_gone')
 
81
        # try to pull, which should raise a BoundBranchConnectionFailure.
 
82
        self.assertRaises(errors.BoundBranchConnectionFailure,
 
83
                checkout.branch.pull, other.branch)
 
84
 
 
85
    def test_pull_overwrite(self):
 
86
        tree_a = self.make_branch_and_tree('tree_a')
 
87
        tree_a.commit('message 1')
 
88
        tree_b = tree_a.bzrdir.sprout('tree_b').open_workingtree()
 
89
        tree_a.commit('message 2', rev_id='rev2a')
 
90
        tree_b.commit('message 2', rev_id='rev2b')
 
91
        self.assertRaises(errors.DivergedBranches, tree_a.pull, tree_b.branch)
 
92
        tree_a.branch.pull(tree_a.branch, overwrite=True,
 
93
                           stop_revision='rev2b')
 
94
        self.assertEqual('rev2b', tree_a.branch.last_revision())
 
95
        self.assertEqual(tree_b.branch.revision_history(),
 
96
                         tree_a.branch.revision_history())
 
97
 
 
98
 
 
99
class TestPullHook(TestCaseWithBranch):
 
100
 
 
101
    def setUp(self):
 
102
        self.hook_calls = []
 
103
        TestCaseWithBranch.setUp(self)
 
104
 
 
105
    def capture_post_pull_hook(self, result):
 
106
        """Capture post pull hook calls to self.hook_calls.
 
107
        
 
108
        The call is logged, as is some state of the two branches.
 
109
        """
 
110
        if result.local_branch:
 
111
            local_locked = result.local_branch.is_locked()
 
112
            local_base = result.local_branch.base
 
113
        else:
 
114
            local_locked = None
 
115
            local_base = None
 
116
        self.hook_calls.append(
 
117
            ('post_pull', result.source_branch, local_base,
 
118
             result.master_branch.base, result.old_revno,
 
119
             result.old_revid,
 
120
             result.new_revno, result.new_revid,
 
121
             result.source_branch.is_locked(), local_locked,
 
122
             result.master_branch.is_locked()))
 
123
 
 
124
    def test_post_pull_empty_history(self):
 
125
        target = self.make_branch('target')
 
126
        source = self.make_branch('source')
 
127
        Branch.hooks.install_hook('post_pull', self.capture_post_pull_hook)
 
128
        target.pull(source)
 
129
        # with nothing there we should still get a notification, and
 
130
        # have both branches locked at the notification time.
 
131
        self.assertEqual([
 
132
            ('post_pull', source, None, target.base, 0, NULL_REVISION,
 
133
             0, NULL_REVISION, True, None, True)
 
134
            ],
 
135
            self.hook_calls)
 
136
 
 
137
    def test_post_pull_bound_branch(self):
 
138
        # pulling to a bound branch should pass in the master branch to the
 
139
        # hook, allowing the correct number of emails to be sent, while still
 
140
        # allowing hooks that want to modify the target to do so to both 
 
141
        # instances.
 
142
        target = self.make_branch('target')
 
143
        local = self.make_branch('local')
 
144
        try:
 
145
            local.bind(target)
 
146
        except errors.UpgradeRequired:
 
147
            # We can't bind this format to itself- typically it is the local
 
148
            # branch that doesn't support binding.  As of May 2007
 
149
            # remotebranches can't be bound.  Let's instead make a new local
 
150
            # branch of the default type, which does allow binding.
 
151
            # See https://bugs.launchpad.net/bzr/+bug/112020
 
152
            local = BzrDir.create_branch_convenience('local2')
 
153
            local.bind(target)
 
154
        source = self.make_branch('source')
 
155
        Branch.hooks.install_hook('post_pull', self.capture_post_pull_hook)
 
156
        local.pull(source)
 
157
        # with nothing there we should still get a notification, and
 
158
        # have both branches locked at the notification time.
 
159
        self.assertEqual([
 
160
            ('post_pull', source, local.base, target.base, 0, NULL_REVISION,
 
161
             0, NULL_REVISION, True, True, True)
 
162
            ],
 
163
            self.hook_calls)
 
164
 
 
165
    def test_post_pull_nonempty_history(self):
 
166
        target = self.make_branch_and_memory_tree('target')
 
167
        target.lock_write()
 
168
        target.add('')
 
169
        rev1 = target.commit('rev 1')
 
170
        target.unlock()
 
171
        sourcedir = target.bzrdir.clone(self.get_url('source'))
 
172
        source = MemoryTree.create_on_branch(sourcedir.open_branch())
 
173
        rev2 = source.commit('rev 2')
 
174
        Branch.hooks.install_hook('post_pull', self.capture_post_pull_hook)
 
175
        target.branch.pull(source.branch)
 
176
        # with nothing there we should still get a notification, and
 
177
        # have both branches locked at the notification time.
 
178
        self.assertEqual([
 
179
            ('post_pull', source.branch, None, target.branch.base, 1, rev1,
 
180
             2, rev2, True, None, True)
 
181
            ],
 
182
            self.hook_calls)