/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

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

  • Committer: John Arbash Meinel
  • Date: 2007-02-08 21:57:04 UTC
  • mfrom: (2273 +trunk) (2276 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2277.
  • Revision ID: john@arbash-meinel.com-20070208215704-87s4qnsjfqi4x83w
[merge] bzr.dev 2276

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2004, 2005, 2007 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
"""Tests for branch.push behaviour."""
 
18
 
 
19
import os
 
20
 
 
21
from bzrlib.branch import Branch
 
22
from bzrlib import errors
 
23
from bzrlib.memorytree import MemoryTree
 
24
from bzrlib.revision import NULL_REVISION
 
25
from bzrlib.tests.branch_implementations.test_branch import TestCaseWithBranch
 
26
 
 
27
 
 
28
class TestPush(TestCaseWithBranch):
 
29
 
 
30
    def test_push_convergence_simple(self):
 
31
        # when revisions are pushed, the left-most accessible parents must 
 
32
        # become the revision-history.
 
33
        mine = self.make_branch_and_tree('mine')
 
34
        mine.commit('1st post', rev_id='P1', allow_pointless=True)
 
35
        other = mine.bzrdir.sprout('other').open_workingtree()
 
36
        other.commit('my change', rev_id='M1', allow_pointless=True)
 
37
        mine.merge_from_branch(other.branch)
 
38
        mine.commit('merge my change', rev_id='P2')
 
39
        mine.branch.push(other.branch)
 
40
        self.assertEqual(['P1', 'P2'], other.branch.revision_history())
 
41
 
 
42
    def test_push_merged_indirect(self):
 
43
        # it should be possible to do a push from one branch into another
 
44
        # when the tip of the target was merged into the source branch
 
45
        # via a third branch - so its buried in the ancestry and is not
 
46
        # directly accessible.
 
47
        mine = self.make_branch_and_tree('mine')
 
48
        mine.commit('1st post', rev_id='P1', allow_pointless=True)
 
49
        target = mine.bzrdir.sprout('target').open_workingtree()
 
50
        target.commit('my change', rev_id='M1', allow_pointless=True)
 
51
        other = mine.bzrdir.sprout('other').open_workingtree()
 
52
        other.merge_from_branch(target.branch)
 
53
        other.commit('merge my change', rev_id='O2')
 
54
        mine.merge_from_branch(other.branch)
 
55
        mine.commit('merge other', rev_id='P2')
 
56
        mine.branch.push(target.branch)
 
57
        self.assertEqual(['P1', 'P2'], target.branch.revision_history())
 
58
 
 
59
    def test_push_to_checkout_updates_master(self):
 
60
        """Pushing into a checkout updates the checkout and the master branch"""
 
61
        master_tree = self.make_branch_and_tree('master')
 
62
        checkout = self.make_branch_and_tree('checkout')
 
63
        try:
 
64
            checkout.branch.bind(master_tree.branch)
 
65
        except errors.UpgradeRequired:
 
66
            # cant bind this format, the test is irrelevant.
 
67
            return
 
68
        rev1 = checkout.commit('master')
 
69
 
 
70
        other = master_tree.branch.bzrdir.sprout('other').open_workingtree()
 
71
        rev2 = other.commit('other commit')
 
72
        # now push, which should update both checkout and master.
 
73
        other.branch.push(checkout.branch)
 
74
        self.assertEqual([rev1, rev2], checkout.branch.revision_history())
 
75
        self.assertEqual([rev1, rev2], master_tree.branch.revision_history())
 
76
 
 
77
    def test_push_raises_specific_error_on_master_connection_error(self):
 
78
        master_tree = self.make_branch_and_tree('master')
 
79
        checkout = self.make_branch_and_tree('checkout')
 
80
        try:
 
81
            checkout.branch.bind(master_tree.branch)
 
82
        except errors.UpgradeRequired:
 
83
            # cant bind this format, the test is irrelevant.
 
84
            return
 
85
        other = master_tree.branch.bzrdir.sprout('other').open_workingtree()
 
86
        # move the branch out of the way on disk to cause a connection
 
87
        # error.
 
88
        os.rename('master', 'master_gone')
 
89
        # try to push, which should raise a BoundBranchConnectionFailure.
 
90
        self.assertRaises(errors.BoundBranchConnectionFailure,
 
91
                other.branch.push, checkout.branch)
 
92
 
 
93
 
 
94
class TestPushHook(TestCaseWithBranch):
 
95
 
 
96
    def setUp(self):
 
97
        self.hook_calls = []
 
98
        TestCaseWithBranch.setUp(self)
 
99
 
 
100
    def capture_post_push_hook(self, source, local, master, old_revno,
 
101
        old_revid, new_revno, new_revid):
 
102
        """Capture post push hook calls to self.hook_calls.
 
103
        
 
104
        The call is logged, as is some state of the two branches.
 
105
        """
 
106
        if local:
 
107
            local_locked = local.is_locked()
 
108
            local_base = local.base
 
109
        else:
 
110
            local_locked = None
 
111
            local_base = None
 
112
        self.hook_calls.append(
 
113
            ('post_push', source, local_base, master.base, old_revno, old_revid,
 
114
             new_revno, new_revid, source.is_locked(), local_locked,
 
115
             master.is_locked()))
 
116
 
 
117
    def test_post_push_empty_history(self):
 
118
        target = self.make_branch('target')
 
119
        source = self.make_branch('source')
 
120
        Branch.hooks.install_hook('post_push', self.capture_post_push_hook)
 
121
        source.push(target)
 
122
        # with nothing there we should still get a notification, and
 
123
        # have both branches locked at the notification time.
 
124
        self.assertEqual([
 
125
            ('post_push', source, None, target.base, 0, NULL_REVISION,
 
126
             0, NULL_REVISION, True, None, True)
 
127
            ],
 
128
            self.hook_calls)
 
129
 
 
130
    def test_post_push_bound_branch(self):
 
131
        # pushing to a bound branch should pass in the master branch to the
 
132
        # hook, allowing the correct number of emails to be sent, while still
 
133
        # allowing hooks that want to modify the target to do so to both 
 
134
        # instances.
 
135
        target = self.make_branch('target')
 
136
        local = self.make_branch('local')
 
137
        try:
 
138
            local.bind(target)
 
139
        except errors.UpgradeRequired:
 
140
            # cant bind this format, the test is irrelevant.
 
141
            return
 
142
        source = self.make_branch('source')
 
143
        Branch.hooks.install_hook('post_push', self.capture_post_push_hook)
 
144
        source.push(local)
 
145
        # with nothing there we should still get a notification, and
 
146
        # have both branches locked at the notification time.
 
147
        self.assertEqual([
 
148
            ('post_push', source, local.base, target.base, 0, NULL_REVISION,
 
149
             0, NULL_REVISION, True, True, True)
 
150
            ],
 
151
            self.hook_calls)
 
152
 
 
153
    def test_post_push_nonempty_history(self):
 
154
        target = self.make_branch_and_memory_tree('target')
 
155
        target.lock_write()
 
156
        target.add('')
 
157
        rev1 = target.commit('rev 1')
 
158
        target.unlock()
 
159
        sourcedir = target.bzrdir.clone(self.get_url('source'))
 
160
        source = MemoryTree.create_on_branch(sourcedir.open_branch())
 
161
        rev2 = source.commit('rev 2')
 
162
        Branch.hooks.install_hook('post_push', self.capture_post_push_hook)
 
163
        source.branch.push(target.branch)
 
164
        # with nothing there we should still get a notification, and
 
165
        # have both branches locked at the notification time.
 
166
        self.assertEqual([
 
167
            ('post_push', source.branch, None, target.branch.base, 1, rev1,
 
168
             2, rev2, True, None, True)
 
169
            ],
 
170
            self.hook_calls)