~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
5816.6.7 by A. S. Budden
Moved test harnesses into test_switch and test_branch as these are the commands that are being tested.
23
from bzrlib import (
24
        osutils,
5816.6.11 by A. S. Budden
Refactored assertParentCorrect to check the full path.
25
        urlutils,
5816.6.7 by A. S. Budden
Moved test harnesses into test_switch and test_branch as these are the commands that are being tested.
26
        branch,
27
        )
3565.6.7 by Marius Kruger
* checkouts now use master nick when no explicit nick is set.
28
from bzrlib.workingtree import WorkingTree
5816.6.7 by A. S. Budden
Moved test harnesses into test_switch and test_branch as these are the commands that are being tested.
29
from bzrlib.tests import (
30
        TestCaseWithTransport,
31
        script,
32
        )
4879.2.1 by Neil Martinsen-Burrell
switch should use directory services when creating a branch
33
from bzrlib.directory_service import directories
2999.1.4 by Ian Clatworthy
more review tweaks including commit of blackbox tests
34
5816.6.15 by A. S. Budden
Added erroneously removed blank line.
35
5283.4.5 by Martin Pool
Update remaining subclasses of ExternalBase
36
class TestSwitch(TestCaseWithTransport):
2999.1.4 by Ian Clatworthy
more review tweaks including commit of blackbox tests
37
3984.5.14 by Daniel Watkins
Extracted common setup code.
38
    def _create_sample_tree(self):
39
        tree = self.make_branch_and_tree('branch-1')
40
        self.build_tree(['branch-1/file-1', 'branch-1/file-2'])
41
        tree.add('file-1')
42
        tree.commit('rev1')
43
        tree.add('file-2')
44
        tree.commit('rev2')
45
        return tree
46
2999.1.4 by Ian Clatworthy
more review tweaks including commit of blackbox tests
47
    def test_switch_up_to_date_light_checkout(self):
48
        self.make_branch_and_tree('branch')
49
        self.run_bzr('branch branch branch2')
50
        self.run_bzr('checkout --lightweight branch checkout')
51
        os.chdir('checkout')
52
        out, err = self.run_bzr('switch ../branch2')
53
        self.assertContainsRe(err, 'Tree is up to date at revision 0.\n')
54
        self.assertContainsRe(err, 'Switched to branch: .*/branch2.\n')
55
        self.assertEqual('', out)
56
57
    def test_switch_out_of_date_light_checkout(self):
58
        self.make_branch_and_tree('branch')
59
        self.run_bzr('branch branch branch2')
60
        self.build_tree(['branch2/file'])
61
        self.run_bzr('add branch2/file')
62
        self.run_bzr('commit -m add-file branch2')
63
        self.run_bzr('checkout --lightweight branch checkout')
64
        os.chdir('checkout')
65
        out, err = self.run_bzr('switch ../branch2')
66
        #self.assertContainsRe(err, '\+N  file')
67
        self.assertContainsRe(err, 'Updated to revision 1.\n')
68
        self.assertContainsRe(err, 'Switched to branch: .*/branch2.\n')
69
        self.assertEqual('', out)
3246.5.1 by Robert Collins
* ``bzr switch`` will attempt to find branches to switch to relative to the
70
3565.6.7 by Marius Kruger
* checkouts now use master nick when no explicit nick is set.
71
    def _test_switch_nick(self, lightweight):
72
        """Check that the nick gets switched too."""
73
        tree1 = self.make_branch_and_tree('branch1')
74
        tree2 = self.make_branch_and_tree('branch2')
75
        tree2.pull(tree1.branch)
76
        checkout =  tree1.branch.create_checkout('checkout',
77
            lightweight=lightweight)
78
        self.assertEqual(checkout.branch.nick, tree1.branch.nick)
79
        self.assertEqual(checkout.branch.get_config().has_explicit_nickname(),
80
            False)
81
        self.run_bzr('switch branch2', working_dir='checkout')
82
83
        # we need to get the tree again, otherwise we don't get the new branch
84
        checkout = WorkingTree.open('checkout')
85
        self.assertEqual(checkout.branch.nick, tree2.branch.nick)
86
        self.assertEqual(checkout.branch.get_config().has_explicit_nickname(),
87
            False)
88
3565.6.1 by Marius Kruger
Let 'bzr switch' update the nick too.
89
    def test_switch_nick(self):
3565.6.7 by Marius Kruger
* checkouts now use master nick when no explicit nick is set.
90
        self._test_switch_nick(lightweight=False)
91
92
    def test_switch_nick_lightweight(self):
93
        self._test_switch_nick(lightweight=True)
94
95
    def _test_switch_explicit_nick(self, lightweight):
3565.6.1 by Marius Kruger
Let 'bzr switch' update the nick too.
96
        """Check that the nick gets switched too."""
97
        tree1 = self.make_branch_and_tree('branch1')
98
        tree2 = self.make_branch_and_tree('branch2')
99
        tree2.pull(tree1.branch)
3565.6.7 by Marius Kruger
* checkouts now use master nick when no explicit nick is set.
100
        checkout =  tree1.branch.create_checkout('checkout',
101
            lightweight=lightweight)
102
        self.assertEqual(checkout.branch.nick, tree1.branch.nick)
103
        checkout.branch.nick = "explicit_nick"
104
        self.assertEqual(checkout.branch.nick, "explicit_nick")
105
        self.assertEqual(checkout.branch.get_config()._get_explicit_nickname(),
106
            "explicit_nick")
107
        self.run_bzr('switch branch2', working_dir='checkout')
108
109
        # we need to get the tree again, otherwise we don't get the new branch
110
        checkout = WorkingTree.open('checkout')
111
        self.assertEqual(checkout.branch.nick, tree2.branch.nick)
112
        self.assertEqual(checkout.branch.get_config()._get_explicit_nickname(),
113
            tree2.branch.nick)
114
115
    def test_switch_explicit_nick(self):
116
        self._test_switch_explicit_nick(lightweight=False)
117
118
    def test_switch_explicit_nick_lightweight(self):
119
        self._test_switch_explicit_nick(lightweight=True)
3565.6.1 by Marius Kruger
Let 'bzr switch' update the nick too.
120
3246.5.1 by Robert Collins
* ``bzr switch`` will attempt to find branches to switch to relative to the
121
    def test_switch_finds_relative_branch(self):
3565.6.1 by Marius Kruger
Let 'bzr switch' update the nick too.
122
        """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
123
        self.build_tree(['repo/'])
124
        tree1 = self.make_branch_and_tree('repo/brancha')
125
        tree1.commit('foo')
126
        tree2 = self.make_branch_and_tree('repo/branchb')
127
        tree2.pull(tree1.branch)
128
        branchb_id = tree2.commit('bar')
129
        checkout =  tree1.branch.create_checkout('checkout', lightweight=True)
130
        self.run_bzr(['switch', 'branchb'], working_dir='checkout')
131
        self.assertEqual(branchb_id, checkout.last_revision())
132
        checkout = checkout.bzrdir.open_workingtree()
133
        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.
134
135
    def test_switch_finds_relative_bound_branch(self):
3602.3.4 by Adrian Wilkins
Improved comments and documentation
136
        """Using switch on a heavy checkout should find master sibling
137
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
138
        The behaviour of lighweight and heavy checkouts should be
5816.6.1 by A. S. Budden
Test harness to stimulate Bug #513709: parent being set incorrectly in switch --create-branch.
139
        consistent when using the convenient "switch to sibling" feature
3602.3.4 by Adrian Wilkins
Improved comments and documentation
140
        Both should switch to a sibling of the branch
141
        they are bound to, and not a sibling of themself"""
142
3602.3.1 by Adrian Wilkins
Test that `bzr switch` finds the sibling of the bound branch of heavy checkout.
143
        self.build_tree(['repo/',
144
                         'heavyco/'])
145
        tree1 = self.make_branch_and_tree('repo/brancha')
146
        tree1.commit('foo')
147
        tree2 = self.make_branch_and_tree('repo/branchb')
148
        tree2.pull(tree1.branch)
149
        branchb_id = tree2.commit('bar')
150
        checkout = tree1.branch.create_checkout('heavyco/a', lightweight=False)
151
        self.run_bzr(['switch', 'branchb'], working_dir='heavyco/a')
152
        self.assertEqual(branchb_id, checkout.last_revision())
153
        self.assertEqual(tree2.branch.base, checkout.branch.get_bound_location())
4354.2.2 by Aaron Bentley
Enable switch --force for lightweight checkouts after moves.
154
3984.5.2 by Daniel Watkins
Added blackbox test.
155
    def test_switch_revision(self):
3984.5.14 by Daniel Watkins
Extracted common setup code.
156
        tree = self._create_sample_tree()
3984.5.2 by Daniel Watkins
Added blackbox test.
157
        checkout = tree.branch.create_checkout('checkout', lightweight=True)
158
        self.run_bzr(['switch', 'branch-1', '-r1'], working_dir='checkout')
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
159
        self.assertPathExists('checkout/file-1')
160
        self.assertPathDoesNotExist('checkout/file-2')
3984.5.9 by Daniel Watkins
Added test for allowing only revisions to be passed to switch.
161
162
    def test_switch_only_revision(self):
3984.5.14 by Daniel Watkins
Extracted common setup code.
163
        tree = self._create_sample_tree()
3984.5.9 by Daniel Watkins
Added test for allowing only revisions to be passed to switch.
164
        checkout = tree.branch.create_checkout('checkout', lightweight=True)
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
165
        self.assertPathExists('checkout/file-1')
166
        self.assertPathExists('checkout/file-2')
3984.5.9 by Daniel Watkins
Added test for allowing only revisions to be passed to switch.
167
        self.run_bzr(['switch', '-r1'], working_dir='checkout')
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
168
        self.assertPathExists('checkout/file-1')
169
        self.assertPathDoesNotExist('checkout/file-2')
3984.5.15 by Daniel Watkins
Add to test to ensure that we don't accept a range of revisions.
170
        # Check that we don't accept a range
3984.5.17 by Daniel Watkins
Fixed incorrect call of run_bzr_error.
171
        self.run_bzr_error(
172
            ['bzr switch --revision takes exactly one revision identifier'],
173
            ['switch', '-r0..2'], working_dir='checkout')
3984.5.19 by Andrew Bennetts
Merge lp:bzr, resolving conflicts.
174
4354.2.2 by Aaron Bentley
Enable switch --force for lightweight checkouts after moves.
175
    def prepare_lightweight_switch(self):
176
        branch = self.make_branch('branch')
177
        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
178
        osutils.rename('branch', 'branch1')
4354.2.2 by Aaron Bentley
Enable switch --force for lightweight checkouts after moves.
179
180
    def test_switch_lightweight_after_branch_moved(self):
181
        self.prepare_lightweight_switch()
182
        self.run_bzr('switch --force ../branch1', working_dir='tree')
183
        branch_location = WorkingTree.open('tree').branch.base
184
        self.assertEndsWith(branch_location, 'branch1/')
185
186
    def test_switch_lightweight_after_branch_moved_relative(self):
187
        self.prepare_lightweight_switch()
188
        self.run_bzr('switch --force branch1', working_dir='tree')
189
        branch_location = WorkingTree.open('tree').branch.base
190
        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.
191
192
    def test_create_branch_no_branch(self):
193
        self.prepare_lightweight_switch()
194
        self.run_bzr_error(['cannot create branch without source branch'],
195
            'switch --create-branch ../branch2', working_dir='tree')
196
197
    def test_create_branch(self):
198
        branch = self.make_branch('branch')
199
        tree = branch.create_checkout('tree', lightweight=True)
200
        tree.commit('one', rev_id='rev-1')
201
        self.run_bzr('switch --create-branch ../branch2', working_dir='tree')
202
        tree = WorkingTree.open('tree')
203
        self.assertEndsWith(tree.branch.base, '/branch2/')
204
205
    def test_create_branch_local(self):
206
        branch = self.make_branch('branch')
207
        tree = branch.create_checkout('tree', lightweight=True)
208
        tree.commit('one', rev_id='rev-1')
209
        self.run_bzr('switch --create-branch branch2', working_dir='tree')
210
        tree = WorkingTree.open('tree')
211
        # The new branch should have been created at the same level as
212
        # 'branch', because we did not have a '/' segment
213
        self.assertEqual(branch.base[:-1] + '2/', tree.branch.base)
214
215
    def test_create_branch_short_name(self):
216
        branch = self.make_branch('branch')
217
        tree = branch.create_checkout('tree', lightweight=True)
218
        tree.commit('one', rev_id='rev-1')
219
        self.run_bzr('switch -b branch2', working_dir='tree')
220
        tree = WorkingTree.open('tree')
221
        # The new branch should have been created at the same level as
222
        # 'branch', because we did not have a '/' segment
223
        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
224
225
    def test_create_branch_directory_services(self):
226
        branch = self.make_branch('branch')
227
        tree = branch.create_checkout('tree', lightweight=True)
228
        class FooLookup(object):
229
            def look_up(self, name, url):
230
                return 'foo-'+name
231
        directories.register('foo:', FooLookup, 'Create branches named foo-')
4879.2.2 by Neil Martinsen-Burrell
add test cleanup per JAMs review
232
        self.addCleanup(directories.remove, 'foo:')
4879.2.1 by Neil Martinsen-Burrell
switch should use directory services when creating a branch
233
        self.run_bzr('switch -b foo:branch2', working_dir='tree')
234
        tree = WorkingTree.open('tree')
235
        self.assertEndsWith(tree.branch.base, 'foo-branch2/')
5107.3.6 by Marco Pantaleoni
Documented behaviour of 'post_branch_init' for lightweight checkouts.
236
237
    def test_switch_with_post_switch_hook(self):
238
        from bzrlib import branch as _mod_branch
239
        calls = []
240
        _mod_branch.Branch.hooks.install_named_hook('post_switch',
241
            calls.append, None)
242
        self.make_branch_and_tree('branch')
243
        self.run_bzr('branch branch branch2')
244
        self.run_bzr('checkout branch checkout')
245
        os.chdir('checkout')
246
        self.assertLength(0, calls)
247
        out, err = self.run_bzr('switch ../branch2')
248
        self.assertLength(1, calls)
249
250
    def test_switch_lightweight_co_with_post_switch_hook(self):
251
        from bzrlib import branch as _mod_branch
252
        calls = []
253
        _mod_branch.Branch.hooks.install_named_hook('post_switch',
254
            calls.append, None)
255
        self.make_branch_and_tree('branch')
256
        self.run_bzr('branch branch branch2')
257
        self.run_bzr('checkout --lightweight branch checkout')
258
        os.chdir('checkout')
259
        self.assertLength(0, calls)
260
        out, err = self.run_bzr('switch ../branch2')
261
        self.assertLength(1, calls)
5171.3.13 by Martin von Gagern
Add --directory option to 7 more commands.
262
263
    def test_switch_lightweight_directory(self):
264
        """Test --directory option"""
265
266
        # create a source branch
267
        a_tree = self.make_branch_and_tree('a')
268
        self.build_tree_contents([('a/a', 'initial\n')])
269
        a_tree.add('a')
270
        a_tree.commit(message='initial')
271
272
        # clone and add a differing revision
273
        b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
274
        self.build_tree_contents([('b/a', 'initial\nmore\n')])
275
        b_tree.commit(message='more')
276
277
        self.run_bzr('checkout --lightweight a checkout')
278
        self.run_bzr('switch --directory checkout b')
279
        self.assertFileEqual('initial\nmore\n', 'checkout/a')
5816.6.7 by A. S. Budden
Moved test harnesses into test_switch and test_branch as these are the commands that are being tested.
280
5816.7.1 by Vincent Ladeuil
Remove duplication and simplify.
281
class TestSwitchParentLocationBase(TestCaseWithTransport):
5816.6.7 by A. S. Budden
Moved test harnesses into test_switch and test_branch as these are the commands that are being tested.
282
283
    def setUp(self):
284
        """Set up a repository and branch ready for testing."""
5816.7.1 by Vincent Ladeuil
Remove duplication and simplify.
285
        super(TestSwitchParentLocationBase, self).setUp()
5816.6.7 by A. S. Budden
Moved test harnesses into test_switch and test_branch as these are the commands that are being tested.
286
        self.script_runner = script.ScriptRunner()
287
        self.script_runner.run_script(self, '''
288
                $ bzr init-repo --no-trees repo
289
                Shared repository...
290
                Location:
291
                  shared repository: repo
292
                $ bzr init repo/trunk
293
                Created a repository branch...
294
                Using shared repository: ...
295
                ''')
296
5816.7.1 by Vincent Ladeuil
Remove duplication and simplify.
297
    def assertParent(self, expected_parent, branch):
5816.6.11 by A. S. Budden
Refactored assertParentCorrect to check the full path.
298
        """Verify that the parent is not None and is set correctly."""
299
        actual_parent = branch.get_parent()
5816.7.1 by Vincent Ladeuil
Remove duplication and simplify.
300
        self.assertIsSameRealPath(urlutils.local_path_to_url(expected_parent),
301
                                  branch.get_parent())
302
303
304
class TestSwitchParentLocation(TestSwitchParentLocationBase):
305
306
    def _checkout_and_switch(self, option=''):
5816.6.8 by A. S. Budden
Refactored to use common generation code for lightweight and heavyweight.
307
        self.script_runner.run_script(self, '''
5816.7.1 by Vincent Ladeuil
Remove duplication and simplify.
308
                $ bzr checkout %(option)s repo/trunk checkout
309
                $ cd checkout
310
                $ bzr switch --create-branch switched
5816.6.8 by A. S. Budden
Refactored to use common generation code for lightweight and heavyweight.
311
                2>Tree is up to date at revision 0.
5816.7.1 by Vincent Ladeuil
Remove duplication and simplify.
312
                2>Switched to branch:...switched...
5816.6.11 by A. S. Budden
Refactored assertParentCorrect to check the full path.
313
                $ cd ..
5816.6.9 by A. S. Budden
Use locals() instead of kwargs so that parameters are more explicit.
314
                ''' % locals())
5816.7.1 by Vincent Ladeuil
Remove duplication and simplify.
315
        bound_branch = branch.Branch.open_containing('checkout')[0]
316
        master_branch = branch.Branch.open_containing('repo/switched')[0]
5816.6.12 by A. S. Budden
Check parent branch of both the checkout (light or heavy) and the branch to which it is connected.
317
        return (bound_branch, master_branch)
5816.6.8 by A. S. Budden
Refactored to use common generation code for lightweight and heavyweight.
318
5816.6.7 by A. S. Budden
Moved test harnesses into test_switch and test_branch as these are the commands that are being tested.
319
    def test_switch_parent_lightweight(self):
5816.7.1 by Vincent Ladeuil
Remove duplication and simplify.
320
        """Lightweight checkout using bzr switch."""
321
        bb, mb = self._checkout_and_switch(option='--lightweight')
322
        self.assertParent('repo/trunk', bb)
323
        self.assertParent('repo/trunk', mb)
5816.6.7 by A. S. Budden
Moved test harnesses into test_switch and test_branch as these are the commands that are being tested.
324
325
    def test_switch_parent_heavyweight(self):
5816.7.1 by Vincent Ladeuil
Remove duplication and simplify.
326
        """Heavyweight checkout using bzr switch."""
327
        bb, mb = self._checkout_and_switch()
328
        self.assertParent('repo/trunk', bb)
329
        self.assertParent('repo/trunk', mb)
5816.6.11 by A. S. Budden
Refactored assertParentCorrect to check the full path.
330