~bzr-pqm/bzr/bzr.dev

4763.2.4 by John Arbash Meinel
merge bzr.2.1 in preparation for NEWS entry.
1
# Copyright (C) 2007-2010 Canonical Ltd
2999.1.4 by Ian Clatworthy
more review tweaks including commit of blackbox tests
2
# -*- coding: utf-8 -*-
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2999.1.4 by Ian Clatworthy
more review tweaks including commit of blackbox tests
17
18
19
"""Tests for the switch command of bzr."""
20
21
import os
22
5186.2.2 by Martin Pool
wrap os.rename to insert the source and destination filenames in any exception that may be raised
23
from bzrlib import osutils
3565.6.7 by Marius Kruger
* checkouts now use master nick when no explicit nick is set.
24
from bzrlib.workingtree import WorkingTree
5283.4.5 by Martin Pool
Update remaining subclasses of ExternalBase
25
from bzrlib.tests import TestCaseWithTransport
4879.2.1 by Neil Martinsen-Burrell
switch should use directory services when creating a branch
26
from bzrlib.directory_service import directories
2999.1.4 by Ian Clatworthy
more review tweaks including commit of blackbox tests
27
28
5283.4.5 by Martin Pool
Update remaining subclasses of ExternalBase
29
class TestSwitch(TestCaseWithTransport):
2999.1.4 by Ian Clatworthy
more review tweaks including commit of blackbox tests
30
3984.5.14 by Daniel Watkins
Extracted common setup code.
31
    def _create_sample_tree(self):
32
        tree = self.make_branch_and_tree('branch-1')
33
        self.build_tree(['branch-1/file-1', 'branch-1/file-2'])
34
        tree.add('file-1')
35
        tree.commit('rev1')
36
        tree.add('file-2')
37
        tree.commit('rev2')
38
        return tree
39
2999.1.4 by Ian Clatworthy
more review tweaks including commit of blackbox tests
40
    def test_switch_up_to_date_light_checkout(self):
41
        self.make_branch_and_tree('branch')
42
        self.run_bzr('branch branch branch2')
43
        self.run_bzr('checkout --lightweight branch checkout')
44
        os.chdir('checkout')
45
        out, err = self.run_bzr('switch ../branch2')
46
        self.assertContainsRe(err, 'Tree is up to date at revision 0.\n')
47
        self.assertContainsRe(err, 'Switched to branch: .*/branch2.\n')
48
        self.assertEqual('', out)
49
50
    def test_switch_out_of_date_light_checkout(self):
51
        self.make_branch_and_tree('branch')
52
        self.run_bzr('branch branch branch2')
53
        self.build_tree(['branch2/file'])
54
        self.run_bzr('add branch2/file')
55
        self.run_bzr('commit -m add-file branch2')
56
        self.run_bzr('checkout --lightweight branch checkout')
57
        os.chdir('checkout')
58
        out, err = self.run_bzr('switch ../branch2')
59
        #self.assertContainsRe(err, '\+N  file')
60
        self.assertContainsRe(err, 'Updated to revision 1.\n')
61
        self.assertContainsRe(err, 'Switched to branch: .*/branch2.\n')
62
        self.assertEqual('', out)
3246.5.1 by Robert Collins
* ``bzr switch`` will attempt to find branches to switch to relative to the
63
3565.6.7 by Marius Kruger
* checkouts now use master nick when no explicit nick is set.
64
    def _test_switch_nick(self, lightweight):
65
        """Check that the nick gets switched too."""
66
        tree1 = self.make_branch_and_tree('branch1')
67
        tree2 = self.make_branch_and_tree('branch2')
68
        tree2.pull(tree1.branch)
69
        checkout =  tree1.branch.create_checkout('checkout',
70
            lightweight=lightweight)
71
        self.assertEqual(checkout.branch.nick, tree1.branch.nick)
72
        self.assertEqual(checkout.branch.get_config().has_explicit_nickname(),
73
            False)
74
        self.run_bzr('switch branch2', working_dir='checkout')
75
76
        # we need to get the tree again, otherwise we don't get the new branch
77
        checkout = WorkingTree.open('checkout')
78
        self.assertEqual(checkout.branch.nick, tree2.branch.nick)
79
        self.assertEqual(checkout.branch.get_config().has_explicit_nickname(),
80
            False)
81
3565.6.1 by Marius Kruger
Let 'bzr switch' update the nick too.
82
    def test_switch_nick(self):
3565.6.7 by Marius Kruger
* checkouts now use master nick when no explicit nick is set.
83
        self._test_switch_nick(lightweight=False)
84
85
    def test_switch_nick_lightweight(self):
86
        self._test_switch_nick(lightweight=True)
87
88
    def _test_switch_explicit_nick(self, lightweight):
3565.6.1 by Marius Kruger
Let 'bzr switch' update the nick too.
89
        """Check that the nick gets switched too."""
90
        tree1 = self.make_branch_and_tree('branch1')
91
        tree2 = self.make_branch_and_tree('branch2')
92
        tree2.pull(tree1.branch)
3565.6.7 by Marius Kruger
* checkouts now use master nick when no explicit nick is set.
93
        checkout =  tree1.branch.create_checkout('checkout',
94
            lightweight=lightweight)
95
        self.assertEqual(checkout.branch.nick, tree1.branch.nick)
96
        checkout.branch.nick = "explicit_nick"
97
        self.assertEqual(checkout.branch.nick, "explicit_nick")
98
        self.assertEqual(checkout.branch.get_config()._get_explicit_nickname(),
99
            "explicit_nick")
100
        self.run_bzr('switch branch2', working_dir='checkout')
101
102
        # we need to get the tree again, otherwise we don't get the new branch
103
        checkout = WorkingTree.open('checkout')
104
        self.assertEqual(checkout.branch.nick, tree2.branch.nick)
105
        self.assertEqual(checkout.branch.get_config()._get_explicit_nickname(),
106
            tree2.branch.nick)
107
108
    def test_switch_explicit_nick(self):
109
        self._test_switch_explicit_nick(lightweight=False)
110
111
    def test_switch_explicit_nick_lightweight(self):
112
        self._test_switch_explicit_nick(lightweight=True)
3565.6.1 by Marius Kruger
Let 'bzr switch' update the nick too.
113
3246.5.1 by Robert Collins
* ``bzr switch`` will attempt to find branches to switch to relative to the
114
    def test_switch_finds_relative_branch(self):
3565.6.1 by Marius Kruger
Let 'bzr switch' update the nick too.
115
        """Switch will find 'foo' relative to the branch the checkout is of."""
3246.5.1 by Robert Collins
* ``bzr switch`` will attempt to find branches to switch to relative to the
116
        self.build_tree(['repo/'])
117
        tree1 = self.make_branch_and_tree('repo/brancha')
118
        tree1.commit('foo')
119
        tree2 = self.make_branch_and_tree('repo/branchb')
120
        tree2.pull(tree1.branch)
121
        branchb_id = tree2.commit('bar')
122
        checkout =  tree1.branch.create_checkout('checkout', lightweight=True)
123
        self.run_bzr(['switch', 'branchb'], working_dir='checkout')
124
        self.assertEqual(branchb_id, checkout.last_revision())
125
        checkout = checkout.bzrdir.open_workingtree()
126
        self.assertEqual(tree2.branch.base, checkout.branch.base)
3602.3.1 by Adrian Wilkins
Test that `bzr switch` finds the sibling of the bound branch of heavy checkout.
127
128
    def test_switch_finds_relative_bound_branch(self):
3602.3.4 by Adrian Wilkins
Improved comments and documentation
129
        """Using switch on a heavy checkout should find master sibling
130
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
131
        The behaviour of lighweight and heavy checkouts should be
3602.3.4 by Adrian Wilkins
Improved comments and documentation
132
        consistentwhen using the convenient "switch to sibling" feature
133
        Both should switch to a sibling of the branch
134
        they are bound to, and not a sibling of themself"""
135
3602.3.1 by Adrian Wilkins
Test that `bzr switch` finds the sibling of the bound branch of heavy checkout.
136
        self.build_tree(['repo/',
137
                         'heavyco/'])
138
        tree1 = self.make_branch_and_tree('repo/brancha')
139
        tree1.commit('foo')
140
        tree2 = self.make_branch_and_tree('repo/branchb')
141
        tree2.pull(tree1.branch)
142
        branchb_id = tree2.commit('bar')
143
        checkout = tree1.branch.create_checkout('heavyco/a', lightweight=False)
144
        self.run_bzr(['switch', 'branchb'], working_dir='heavyco/a')
145
        self.assertEqual(branchb_id, checkout.last_revision())
146
        self.assertEqual(tree2.branch.base, checkout.branch.get_bound_location())
4354.2.2 by Aaron Bentley
Enable switch --force for lightweight checkouts after moves.
147
3984.5.2 by Daniel Watkins
Added blackbox test.
148
    def test_switch_revision(self):
3984.5.14 by Daniel Watkins
Extracted common setup code.
149
        tree = self._create_sample_tree()
3984.5.2 by Daniel Watkins
Added blackbox test.
150
        checkout = tree.branch.create_checkout('checkout', lightweight=True)
151
        self.run_bzr(['switch', 'branch-1', '-r1'], working_dir='checkout')
152
        self.failUnlessExists('checkout/file-1')
153
        self.failIfExists('checkout/file-2')
3984.5.9 by Daniel Watkins
Added test for allowing only revisions to be passed to switch.
154
155
    def test_switch_only_revision(self):
3984.5.14 by Daniel Watkins
Extracted common setup code.
156
        tree = self._create_sample_tree()
3984.5.9 by Daniel Watkins
Added test for allowing only revisions to be passed to switch.
157
        checkout = tree.branch.create_checkout('checkout', lightweight=True)
3984.5.10 by Daniel Watkins
Toughened test slightly.
158
        self.failUnlessExists('checkout/file-1')
159
        self.failUnlessExists('checkout/file-2')
3984.5.9 by Daniel Watkins
Added test for allowing only revisions to be passed to switch.
160
        self.run_bzr(['switch', '-r1'], working_dir='checkout')
161
        self.failUnlessExists('checkout/file-1')
162
        self.failIfExists('checkout/file-2')
3984.5.15 by Daniel Watkins
Add to test to ensure that we don't accept a range of revisions.
163
        # Check that we don't accept a range
3984.5.17 by Daniel Watkins
Fixed incorrect call of run_bzr_error.
164
        self.run_bzr_error(
165
            ['bzr switch --revision takes exactly one revision identifier'],
166
            ['switch', '-r0..2'], working_dir='checkout')
3984.5.19 by Andrew Bennetts
Merge lp:bzr, resolving conflicts.
167
4354.2.2 by Aaron Bentley
Enable switch --force for lightweight checkouts after moves.
168
    def prepare_lightweight_switch(self):
169
        branch = self.make_branch('branch')
170
        branch.create_checkout('tree', lightweight=True)
5186.2.2 by Martin Pool
wrap os.rename to insert the source and destination filenames in any exception that may be raised
171
        osutils.rename('branch', 'branch1')
4354.2.2 by Aaron Bentley
Enable switch --force for lightweight checkouts after moves.
172
173
    def test_switch_lightweight_after_branch_moved(self):
174
        self.prepare_lightweight_switch()
175
        self.run_bzr('switch --force ../branch1', working_dir='tree')
176
        branch_location = WorkingTree.open('tree').branch.base
177
        self.assertEndsWith(branch_location, 'branch1/')
178
179
    def test_switch_lightweight_after_branch_moved_relative(self):
180
        self.prepare_lightweight_switch()
181
        self.run_bzr('switch --force branch1', working_dir='tree')
182
        branch_location = WorkingTree.open('tree').branch.base
183
        self.assertEndsWith(branch_location, 'branch1/')
4520.1.1 by John Arbash Meinel
'bzr switch -b' can now be used to create the branch while you switch to it.
184
185
    def test_create_branch_no_branch(self):
186
        self.prepare_lightweight_switch()
187
        self.run_bzr_error(['cannot create branch without source branch'],
188
            'switch --create-branch ../branch2', working_dir='tree')
189
190
    def test_create_branch(self):
191
        branch = self.make_branch('branch')
192
        tree = branch.create_checkout('tree', lightweight=True)
193
        tree.commit('one', rev_id='rev-1')
194
        self.run_bzr('switch --create-branch ../branch2', working_dir='tree')
195
        tree = WorkingTree.open('tree')
196
        self.assertEndsWith(tree.branch.base, '/branch2/')
197
198
    def test_create_branch_local(self):
199
        branch = self.make_branch('branch')
200
        tree = branch.create_checkout('tree', lightweight=True)
201
        tree.commit('one', rev_id='rev-1')
202
        self.run_bzr('switch --create-branch branch2', working_dir='tree')
203
        tree = WorkingTree.open('tree')
204
        # The new branch should have been created at the same level as
205
        # 'branch', because we did not have a '/' segment
206
        self.assertEqual(branch.base[:-1] + '2/', tree.branch.base)
207
208
    def test_create_branch_short_name(self):
209
        branch = self.make_branch('branch')
210
        tree = branch.create_checkout('tree', lightweight=True)
211
        tree.commit('one', rev_id='rev-1')
212
        self.run_bzr('switch -b branch2', working_dir='tree')
213
        tree = WorkingTree.open('tree')
214
        # The new branch should have been created at the same level as
215
        # 'branch', because we did not have a '/' segment
216
        self.assertEqual(branch.base[:-1] + '2/', tree.branch.base)
4879.2.1 by Neil Martinsen-Burrell
switch should use directory services when creating a branch
217
218
    def test_create_branch_directory_services(self):
219
        branch = self.make_branch('branch')
220
        tree = branch.create_checkout('tree', lightweight=True)
221
        class FooLookup(object):
222
            def look_up(self, name, url):
223
                return 'foo-'+name
224
        directories.register('foo:', FooLookup, 'Create branches named foo-')
4879.2.2 by Neil Martinsen-Burrell
add test cleanup per JAMs review
225
        self.addCleanup(directories.remove, 'foo:')
4879.2.1 by Neil Martinsen-Burrell
switch should use directory services when creating a branch
226
        self.run_bzr('switch -b foo:branch2', working_dir='tree')
227
        tree = WorkingTree.open('tree')
228
        self.assertEndsWith(tree.branch.base, 'foo-branch2/')
5107.3.6 by Marco Pantaleoni
Documented behaviour of 'post_branch_init' for lightweight checkouts.
229
230
    def test_switch_with_post_switch_hook(self):
231
        from bzrlib import branch as _mod_branch
232
        calls = []
233
        _mod_branch.Branch.hooks.install_named_hook('post_switch',
234
            calls.append, None)
235
        self.make_branch_and_tree('branch')
236
        self.run_bzr('branch branch branch2')
237
        self.run_bzr('checkout branch checkout')
238
        os.chdir('checkout')
239
        self.assertLength(0, calls)
240
        out, err = self.run_bzr('switch ../branch2')
241
        self.assertLength(1, calls)
242
243
    def test_switch_lightweight_co_with_post_switch_hook(self):
244
        from bzrlib import branch as _mod_branch
245
        calls = []
246
        _mod_branch.Branch.hooks.install_named_hook('post_switch',
247
            calls.append, None)
248
        self.make_branch_and_tree('branch')
249
        self.run_bzr('branch branch branch2')
250
        self.run_bzr('checkout --lightweight branch checkout')
251
        os.chdir('checkout')
252
        self.assertLength(0, calls)
253
        out, err = self.run_bzr('switch ../branch2')
254
        self.assertLength(1, calls)
5171.3.13 by Martin von Gagern
Add --directory option to 7 more commands.
255
256
    def test_switch_lightweight_directory(self):
257
        """Test --directory option"""
258
259
        # create a source branch
260
        a_tree = self.make_branch_and_tree('a')
261
        self.build_tree_contents([('a/a', 'initial\n')])
262
        a_tree.add('a')
263
        a_tree.commit(message='initial')
264
265
        # clone and add a differing revision
266
        b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
267
        self.build_tree_contents([('b/a', 'initial\nmore\n')])
268
        b_tree.commit(message='more')
269
270
        self.run_bzr('checkout --lightweight a checkout')
271
        self.run_bzr('switch --directory checkout b')
272
        self.assertFileEqual('initial\nmore\n', 'checkout/a')