~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/blackbox/test_switch.py

  • Committer: Aaron Bentley
  • Date: 2012-07-18 19:55:04 UTC
  • mto: This revision was merged to the branch mainline in revision 6540.
  • Revision ID: aaron@aaronbentley.com-20120718195504-hrl4w190lynohkhd
Cleanup

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2007-2012 Canonical Ltd
 
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
 
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
17
 
 
18
 
 
19
"""Tests for the switch command of bzr."""
 
20
 
 
21
import os
 
22
 
 
23
from bzrlib.controldir import ControlDir
 
24
from bzrlib import (
 
25
    osutils,
 
26
    urlutils,
 
27
    branch,
 
28
    )
 
29
from bzrlib.workingtree import WorkingTree
 
30
from bzrlib.tests import (
 
31
    TestCaseWithTransport,
 
32
    script,
 
33
    )
 
34
from bzrlib.tests.features import UnicodeFilenameFeature
 
35
from bzrlib.directory_service import directories
 
36
 
 
37
from bzrlib.tests.matchers import ContainsNoVfsCalls
 
38
 
 
39
 
 
40
class TestSwitch(TestCaseWithTransport):
 
41
 
 
42
    def _create_sample_tree(self):
 
43
        tree = self.make_branch_and_tree('branch-1')
 
44
        self.build_tree(['branch-1/file-1', 'branch-1/file-2'])
 
45
        tree.add('file-1')
 
46
        tree.commit('rev1')
 
47
        tree.add('file-2')
 
48
        tree.commit('rev2')
 
49
        return tree
 
50
 
 
51
    def test_switch_up_to_date_light_checkout(self):
 
52
        self.make_branch_and_tree('branch')
 
53
        self.run_bzr('branch branch branch2')
 
54
        self.run_bzr('checkout --lightweight branch checkout')
 
55
        os.chdir('checkout')
 
56
        out, err = self.run_bzr('switch ../branch2')
 
57
        self.assertContainsRe(err, 'Tree is up to date at revision 0.\n')
 
58
        self.assertContainsRe(err, 'Switched to branch: .*/branch2.\n')
 
59
        self.assertEqual('', out)
 
60
 
 
61
    def test_switch_out_of_date_light_checkout(self):
 
62
        self.make_branch_and_tree('branch')
 
63
        self.run_bzr('branch branch branch2')
 
64
        self.build_tree(['branch2/file'])
 
65
        self.run_bzr('add branch2/file')
 
66
        self.run_bzr('commit -m add-file branch2')
 
67
        self.run_bzr('checkout --lightweight branch checkout')
 
68
        os.chdir('checkout')
 
69
        out, err = self.run_bzr('switch ../branch2')
 
70
        #self.assertContainsRe(err, '\+N  file')
 
71
        self.assertContainsRe(err, 'Updated to revision 1.\n')
 
72
        self.assertContainsRe(err, 'Switched to branch: .*/branch2.\n')
 
73
        self.assertEqual('', out)
 
74
 
 
75
    def _test_switch_nick(self, lightweight):
 
76
        """Check that the nick gets switched too."""
 
77
        tree1 = self.make_branch_and_tree('branch1')
 
78
        tree2 = self.make_branch_and_tree('branch2')
 
79
        tree2.pull(tree1.branch)
 
80
        checkout =  tree1.branch.create_checkout('checkout',
 
81
            lightweight=lightweight)
 
82
        self.assertEqual(checkout.branch.nick, tree1.branch.nick)
 
83
        self.assertEqual(checkout.branch.get_config().has_explicit_nickname(),
 
84
            False)
 
85
        self.run_bzr('switch branch2', working_dir='checkout')
 
86
 
 
87
        # we need to get the tree again, otherwise we don't get the new branch
 
88
        checkout = WorkingTree.open('checkout')
 
89
        self.assertEqual(checkout.branch.nick, tree2.branch.nick)
 
90
        self.assertEqual(checkout.branch.get_config().has_explicit_nickname(),
 
91
            False)
 
92
 
 
93
    def test_switch_nick(self):
 
94
        self._test_switch_nick(lightweight=False)
 
95
 
 
96
    def test_switch_nick_lightweight(self):
 
97
        self._test_switch_nick(lightweight=True)
 
98
 
 
99
    def _test_switch_explicit_nick(self, lightweight):
 
100
        """Check that the nick gets switched too."""
 
101
        tree1 = self.make_branch_and_tree('branch1')
 
102
        tree2 = self.make_branch_and_tree('branch2')
 
103
        tree2.pull(tree1.branch)
 
104
        checkout =  tree1.branch.create_checkout('checkout',
 
105
            lightweight=lightweight)
 
106
        self.assertEqual(checkout.branch.nick, tree1.branch.nick)
 
107
        checkout.branch.nick = "explicit_nick"
 
108
        self.assertEqual(checkout.branch.nick, "explicit_nick")
 
109
        self.assertEqual(checkout.branch.get_config()._get_explicit_nickname(),
 
110
            "explicit_nick")
 
111
        self.run_bzr('switch branch2', working_dir='checkout')
 
112
 
 
113
        # we need to get the tree again, otherwise we don't get the new branch
 
114
        checkout = WorkingTree.open('checkout')
 
115
        self.assertEqual(checkout.branch.nick, tree2.branch.nick)
 
116
        self.assertEqual(checkout.branch.get_config()._get_explicit_nickname(),
 
117
            tree2.branch.nick)
 
118
 
 
119
    def test_switch_explicit_nick(self):
 
120
        self._test_switch_explicit_nick(lightweight=False)
 
121
 
 
122
    def test_switch_explicit_nick_lightweight(self):
 
123
        self._test_switch_explicit_nick(lightweight=True)
 
124
 
 
125
    def test_switch_finds_relative_branch(self):
 
126
        """Switch will find 'foo' relative to the branch the checkout is of."""
 
127
        self.build_tree(['repo/'])
 
128
        tree1 = self.make_branch_and_tree('repo/brancha')
 
129
        tree1.commit('foo')
 
130
        tree2 = self.make_branch_and_tree('repo/branchb')
 
131
        tree2.pull(tree1.branch)
 
132
        branchb_id = tree2.commit('bar')
 
133
        checkout =  tree1.branch.create_checkout('checkout', lightweight=True)
 
134
        self.run_bzr(['switch', 'branchb'], working_dir='checkout')
 
135
        self.assertEqual(branchb_id, checkout.last_revision())
 
136
        checkout = checkout.bzrdir.open_workingtree()
 
137
        self.assertEqual(tree2.branch.base, checkout.branch.base)
 
138
 
 
139
    def test_switch_finds_relative_bound_branch(self):
 
140
        """Using switch on a heavy checkout should find master sibling
 
141
 
 
142
        The behaviour of lighweight and heavy checkouts should be
 
143
        consistent when using the convenient "switch to sibling" feature
 
144
        Both should switch to a sibling of the branch
 
145
        they are bound to, and not a sibling of themself"""
 
146
 
 
147
        self.build_tree(['repo/',
 
148
                         'heavyco/'])
 
149
        tree1 = self.make_branch_and_tree('repo/brancha')
 
150
        tree1.commit('foo')
 
151
        tree2 = self.make_branch_and_tree('repo/branchb')
 
152
        tree2.pull(tree1.branch)
 
153
        branchb_id = tree2.commit('bar')
 
154
        checkout = tree1.branch.create_checkout('heavyco/a', lightweight=False)
 
155
        self.run_bzr(['switch', 'branchb'], working_dir='heavyco/a')
 
156
        # Refresh checkout as 'switch' modified it
 
157
        checkout = checkout.bzrdir.open_workingtree()
 
158
        self.assertEqual(branchb_id, checkout.last_revision())
 
159
        self.assertEqual(tree2.branch.base,
 
160
                         checkout.branch.get_bound_location())
 
161
 
 
162
    def test_switch_finds_relative_unicode_branch(self):
 
163
        """Switch will find 'foo' relative to the branch the checkout is of."""
 
164
        self.requireFeature(UnicodeFilenameFeature)
 
165
        self.build_tree(['repo/'])
 
166
        tree1 = self.make_branch_and_tree('repo/brancha')
 
167
        tree1.commit('foo')
 
168
        tree2 = self.make_branch_and_tree(u'repo/branch\xe9')
 
169
        tree2.pull(tree1.branch)
 
170
        branchb_id = tree2.commit('bar')
 
171
        checkout =  tree1.branch.create_checkout('checkout', lightweight=True)
 
172
        self.run_bzr(['switch', u'branch\xe9'], working_dir='checkout')
 
173
        self.assertEqual(branchb_id, checkout.last_revision())
 
174
        checkout = checkout.bzrdir.open_workingtree()
 
175
        self.assertEqual(tree2.branch.base, checkout.branch.base)
 
176
 
 
177
    def test_switch_finds_relative_unicode_branch(self):
 
178
        """Switch will find 'foo' relative to the branch the checkout is of."""
 
179
        self.requireFeature(UnicodeFilenameFeature)
 
180
        self.build_tree(['repo/'])
 
181
        tree1 = self.make_branch_and_tree('repo/brancha')
 
182
        tree1.commit('foo')
 
183
        tree2 = self.make_branch_and_tree(u'repo/branch\xe9')
 
184
        tree2.pull(tree1.branch)
 
185
        branchb_id = tree2.commit('bar')
 
186
        checkout =  tree1.branch.create_checkout('checkout', lightweight=True)
 
187
        self.run_bzr(['switch', u'branch\xe9'], working_dir='checkout')
 
188
        self.assertEqual(branchb_id, checkout.last_revision())
 
189
        checkout = checkout.bzrdir.open_workingtree()
 
190
        self.assertEqual(tree2.branch.base, checkout.branch.base)
 
191
 
 
192
    def test_switch_revision(self):
 
193
        tree = self._create_sample_tree()
 
194
        checkout = tree.branch.create_checkout('checkout', lightweight=True)
 
195
        self.run_bzr(['switch', 'branch-1', '-r1'], working_dir='checkout')
 
196
        self.assertPathExists('checkout/file-1')
 
197
        self.assertPathDoesNotExist('checkout/file-2')
 
198
 
 
199
    def test_switch_into_colocated(self):
 
200
        # Create a new colocated branch from an existing non-colocated branch.
 
201
        tree = self.make_branch_and_tree('.', format='development-colo')
 
202
        self.build_tree(['file-1', 'file-2'])
 
203
        tree.add('file-1')
 
204
        revid1 = tree.commit('rev1')
 
205
        tree.add('file-2')
 
206
        revid2 = tree.commit('rev2')
 
207
        self.run_bzr(['switch', '-b', 'anotherbranch'])
 
208
        self.assertEquals(
 
209
            set(['', 'anotherbranch']),
 
210
            set(tree.branch.bzrdir.get_branches().keys()))
 
211
 
 
212
    def test_switch_into_unrelated_colocated(self):
 
213
        # Create a new colocated branch from an existing non-colocated branch.
 
214
        tree = self.make_branch_and_tree('.', format='development-colo')
 
215
        self.build_tree(['file-1', 'file-2'])
 
216
        tree.add('file-1')
 
217
        revid1 = tree.commit('rev1')
 
218
        tree.add('file-2')
 
219
        revid2 = tree.commit('rev2')
 
220
        tree.bzrdir.create_branch(name='foo')
 
221
        self.run_bzr_error(['Cannot switch a branch, only a checkout.'],
 
222
            'switch foo')
 
223
        self.run_bzr(['switch', '--force', 'foo'])
 
224
 
 
225
    def test_switch_existing_colocated(self):
 
226
        # Create a branch branch-1 that initially is a checkout of 'foo'
 
227
        # Use switch to change it to 'anotherbranch'
 
228
        repo = self.make_repository('branch-1', format='development-colo')
 
229
        target_branch = repo.bzrdir.create_branch(name='foo')
 
230
        repo.bzrdir.set_branch_reference(target_branch)
 
231
        tree = repo.bzrdir.create_workingtree()
 
232
        self.build_tree(['branch-1/file-1', 'branch-1/file-2'])
 
233
        tree.add('file-1')
 
234
        revid1 = tree.commit('rev1')
 
235
        tree.add('file-2')
 
236
        revid2 = tree.commit('rev2')
 
237
        otherbranch = tree.bzrdir.create_branch(name='anotherbranch')
 
238
        otherbranch.generate_revision_history(revid1)
 
239
        self.run_bzr(['switch', 'anotherbranch'], working_dir='branch-1')
 
240
        tree = WorkingTree.open("branch-1")
 
241
        self.assertEquals(tree.last_revision(), revid1)
 
242
        self.assertEquals(tree.branch.control_url, otherbranch.control_url)
 
243
 
 
244
    def test_switch_new_colocated(self):
 
245
        # Create a branch branch-1 that initially is a checkout of 'foo'
 
246
        # Use switch to create 'anotherbranch' which derives from that
 
247
        repo = self.make_repository('branch-1', format='development-colo')
 
248
        target_branch = repo.bzrdir.create_branch(name='foo')
 
249
        repo.bzrdir.set_branch_reference(target_branch)
 
250
        tree = repo.bzrdir.create_workingtree()
 
251
        self.build_tree(['branch-1/file-1', 'branch-1/file-2'])
 
252
        tree.add('file-1')
 
253
        revid1 = tree.commit('rev1')
 
254
        self.run_bzr(['switch', '-b', 'anotherbranch'], working_dir='branch-1')
 
255
        bzrdir = ControlDir.open("branch-1")
 
256
        self.assertEquals(
 
257
            set([b.name for b in bzrdir.list_branches()]),
 
258
            set(["foo", "anotherbranch"]))
 
259
        self.assertEquals(bzrdir.open_branch().name, "anotherbranch")
 
260
        self.assertEquals(bzrdir.open_branch().last_revision(), revid1)
 
261
 
 
262
    def test_switch_new_colocated_unicode(self):
 
263
        # Create a branch branch-1 that initially is a checkout of 'foo'
 
264
        # Use switch to create 'branch\xe9' which derives from that
 
265
        self.requireFeature(UnicodeFilenameFeature)
 
266
        repo = self.make_repository('branch-1', format='development-colo')
 
267
        target_branch = repo.bzrdir.create_branch(name='foo')
 
268
        repo.bzrdir.set_branch_reference(target_branch)
 
269
        tree = repo.bzrdir.create_workingtree()
 
270
        self.build_tree(['branch-1/file-1', 'branch-1/file-2'])
 
271
        tree.add('file-1')
 
272
        revid1 = tree.commit('rev1')
 
273
        self.run_bzr(['switch', '-b', u'branch\xe9'], working_dir='branch-1')
 
274
        bzrdir = ControlDir.open("branch-1")
 
275
        self.assertEquals(
 
276
            set([b.name for b in bzrdir.list_branches()]),
 
277
            set(["foo", u"branch\xe9"]))
 
278
        self.assertEquals(bzrdir.open_branch().name, u"branch\xe9")
 
279
        self.assertEquals(bzrdir.open_branch().last_revision(), revid1)
 
280
 
 
281
    def test_switch_only_revision(self):
 
282
        tree = self._create_sample_tree()
 
283
        checkout = tree.branch.create_checkout('checkout', lightweight=True)
 
284
        self.assertPathExists('checkout/file-1')
 
285
        self.assertPathExists('checkout/file-2')
 
286
        self.run_bzr(['switch', '-r1'], working_dir='checkout')
 
287
        self.assertPathExists('checkout/file-1')
 
288
        self.assertPathDoesNotExist('checkout/file-2')
 
289
        # Check that we don't accept a range
 
290
        self.run_bzr_error(
 
291
            ['bzr switch --revision takes exactly one revision identifier'],
 
292
            ['switch', '-r0..2'], working_dir='checkout')
 
293
 
 
294
    def prepare_lightweight_switch(self):
 
295
        branch = self.make_branch('branch')
 
296
        branch.create_checkout('tree', lightweight=True)
 
297
        osutils.rename('branch', 'branch1')
 
298
 
 
299
    def test_switch_lightweight_after_branch_moved(self):
 
300
        self.prepare_lightweight_switch()
 
301
        self.run_bzr('switch --force --with-changes ../branch1',
 
302
                     working_dir='tree')
 
303
        branch_location = WorkingTree.open('tree').branch.base
 
304
        self.assertEndsWith(branch_location, 'branch1/')
 
305
 
 
306
    def test_switch_lightweight_after_branch_moved_relative(self):
 
307
        self.prepare_lightweight_switch()
 
308
        self.run_bzr('switch --force branch1 --with-changes',
 
309
                     working_dir='tree')
 
310
        branch_location = WorkingTree.open('tree').branch.base
 
311
        self.assertEndsWith(branch_location, 'branch1/')
 
312
 
 
313
    def test_create_branch_no_branch(self):
 
314
        self.prepare_lightweight_switch()
 
315
        self.run_bzr_error(['cannot create branch without source branch'],
 
316
            'switch --create-branch ../branch2', working_dir='tree')
 
317
 
 
318
    def test_create_branch(self):
 
319
        branch = self.make_branch('branch')
 
320
        tree = branch.create_checkout('tree', lightweight=True)
 
321
        tree.commit('one', rev_id='rev-1')
 
322
        self.run_bzr('switch --create-branch ../branch2', working_dir='tree')
 
323
        tree = WorkingTree.open('tree')
 
324
        self.assertEndsWith(tree.branch.base, '/branch2/')
 
325
 
 
326
    def test_create_branch_local(self):
 
327
        branch = self.make_branch('branch')
 
328
        tree = branch.create_checkout('tree', lightweight=True)
 
329
        tree.commit('one', rev_id='rev-1')
 
330
        self.run_bzr('switch --create-branch branch2', working_dir='tree')
 
331
        tree = WorkingTree.open('tree')
 
332
        # The new branch should have been created at the same level as
 
333
        # 'branch', because we did not have a '/' segment
 
334
        self.assertEqual(branch.base[:-1] + '2/', tree.branch.base)
 
335
 
 
336
    def test_create_branch_short_name(self):
 
337
        branch = self.make_branch('branch')
 
338
        tree = branch.create_checkout('tree', lightweight=True)
 
339
        tree.commit('one', rev_id='rev-1')
 
340
        self.run_bzr('switch -b branch2', working_dir='tree')
 
341
        tree = WorkingTree.open('tree')
 
342
        # The new branch should have been created at the same level as
 
343
        # 'branch', because we did not have a '/' segment
 
344
        self.assertEqual(branch.base[:-1] + '2/', tree.branch.base)
 
345
 
 
346
    def test_create_branch_directory_services(self):
 
347
        branch = self.make_branch('branch')
 
348
        tree = branch.create_checkout('tree', lightweight=True)
 
349
        class FooLookup(object):
 
350
            def look_up(self, name, url):
 
351
                return 'foo-'+name
 
352
        directories.register('foo:', FooLookup, 'Create branches named foo-')
 
353
        self.addCleanup(directories.remove, 'foo:')
 
354
        self.run_bzr('switch -b foo:branch2', working_dir='tree')
 
355
        tree = WorkingTree.open('tree')
 
356
        self.assertEndsWith(tree.branch.base, 'foo-branch2/')
 
357
 
 
358
    def test_switch_with_post_switch_hook(self):
 
359
        from bzrlib import branch as _mod_branch
 
360
        calls = []
 
361
        _mod_branch.Branch.hooks.install_named_hook('post_switch',
 
362
            calls.append, None)
 
363
        self.make_branch_and_tree('branch')
 
364
        self.run_bzr('branch branch branch2')
 
365
        self.run_bzr('checkout branch checkout')
 
366
        os.chdir('checkout')
 
367
        self.assertLength(0, calls)
 
368
        out, err = self.run_bzr('switch ../branch2')
 
369
        self.assertLength(1, calls)
 
370
 
 
371
    def test_switch_lightweight_co_with_post_switch_hook(self):
 
372
        from bzrlib import branch as _mod_branch
 
373
        calls = []
 
374
        _mod_branch.Branch.hooks.install_named_hook('post_switch',
 
375
            calls.append, None)
 
376
        self.make_branch_and_tree('branch')
 
377
        self.run_bzr('branch branch branch2')
 
378
        self.run_bzr('checkout --lightweight branch checkout')
 
379
        os.chdir('checkout')
 
380
        self.assertLength(0, calls)
 
381
        out, err = self.run_bzr('switch ../branch2')
 
382
        self.assertLength(1, calls)
 
383
 
 
384
    def test_switch_lightweight_directory(self):
 
385
        """Test --directory option"""
 
386
 
 
387
        # create a source branch
 
388
        a_tree = self.make_branch_and_tree('a')
 
389
        self.build_tree_contents([('a/a', 'initial\n')])
 
390
        a_tree.add('a')
 
391
        a_tree.commit(message='initial')
 
392
 
 
393
        # clone and add a differing revision
 
394
        b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
 
395
        self.build_tree_contents([('b/a', 'initial\nmore\n')])
 
396
        b_tree.commit(message='more')
 
397
 
 
398
        self.run_bzr('checkout --lightweight a checkout')
 
399
        self.run_bzr('switch --directory checkout b')
 
400
        self.assertFileEqual('initial\nmore\n', 'checkout/a')
 
401
 
 
402
 
 
403
class TestSwitchParentLocationBase(TestCaseWithTransport):
 
404
 
 
405
    def setUp(self):
 
406
        """Set up a repository and branch ready for testing."""
 
407
        super(TestSwitchParentLocationBase, self).setUp()
 
408
        self.script_runner = script.ScriptRunner()
 
409
        self.script_runner.run_script(self, '''
 
410
                $ bzr init-repo --no-trees repo
 
411
                Shared repository...
 
412
                Location:
 
413
                  shared repository: repo
 
414
                $ bzr init repo/trunk
 
415
                Created a repository branch...
 
416
                Using shared repository: ...
 
417
                ''')
 
418
 
 
419
    def assertParent(self, expected_parent, branch):
 
420
        """Verify that the parent is not None and is set correctly."""
 
421
        actual_parent = branch.get_parent()
 
422
        self.assertIsSameRealPath(urlutils.local_path_to_url(expected_parent),
 
423
                                  branch.get_parent())
 
424
 
 
425
 
 
426
class TestSwitchParentLocation(TestSwitchParentLocationBase):
 
427
 
 
428
    def _checkout_and_switch(self, option=''):
 
429
        self.script_runner.run_script(self, '''
 
430
                $ bzr checkout %(option)s repo/trunk checkout
 
431
                $ cd checkout
 
432
                $ bzr switch --create-branch switched
 
433
                2>Tree is up to date at revision 0.
 
434
                2>Switched to branch:...switched...
 
435
                $ cd ..
 
436
                ''' % locals())
 
437
        bound_branch = branch.Branch.open_containing('checkout')[0]
 
438
        master_branch = branch.Branch.open_containing('repo/switched')[0]
 
439
        return (bound_branch, master_branch)
 
440
 
 
441
    def test_switch_parent_lightweight(self):
 
442
        """Lightweight checkout using bzr switch."""
 
443
        bb, mb = self._checkout_and_switch(option='--lightweight')
 
444
        self.assertParent('repo/trunk', bb)
 
445
        self.assertParent('repo/trunk', mb)
 
446
 
 
447
    def test_switch_parent_heavyweight(self):
 
448
        """Heavyweight checkout using bzr switch."""
 
449
        bb, mb = self._checkout_and_switch()
 
450
        self.assertParent('repo/trunk', bb)
 
451
        self.assertParent('repo/trunk', mb)
 
452
 
 
453
 
 
454
class TestSwitchDoesntOpenMasterBranch(TestCaseWithTransport):
 
455
    # See https://bugs.launchpad.net/bzr/+bug/812285
 
456
    # "bzr switch --create-branch" can point the new branch's parent to the
 
457
    # master branch, but it doesn't have to open it to do so.
 
458
 
 
459
    def test_switch_create_doesnt_open_master_branch(self):
 
460
        master = self.make_branch_and_tree('master')
 
461
        master.commit('one')
 
462
        # Note: not a lightweight checkout
 
463
        checkout = master.branch.create_checkout('checkout')
 
464
        opened = []
 
465
        def open_hook(branch):
 
466
            # Just append the final directory of the branch
 
467
            name = branch.base.rstrip('/').rsplit('/', 1)[1]
 
468
            opened.append(name)
 
469
        branch.Branch.hooks.install_named_hook('open', open_hook,
 
470
                                               'open_hook_logger')
 
471
        self.run_bzr('switch --create-branch -d checkout feature')
 
472
        # We only open the master branch 1 time.
 
473
        # This test should be cleaner to write, but see bug:
 
474
        #  https://bugs.launchpad.net/bzr/+bug/812295
 
475
        self.assertEqual(1, opened.count('master'))
 
476
 
 
477
 
 
478
class TestSmartServerSwitch(TestCaseWithTransport):
 
479
 
 
480
    def test_switch_lightweight(self):
 
481
        self.setup_smart_server_with_call_log()
 
482
        t = self.make_branch_and_tree('from')
 
483
        for count in range(9):
 
484
            t.commit(message='commit %d' % count)
 
485
        out, err = self.run_bzr(['checkout', '--lightweight', self.get_url('from'),
 
486
            'target'])
 
487
        self.reset_smart_call_log()
 
488
        self.run_bzr(['switch', '--with-changes',
 
489
                      self.get_url('from')], working_dir='target')
 
490
        # This figure represent the amount of work to perform this use case. It
 
491
        # is entirely ok to reduce this number if a test fails due to rpc_count
 
492
        # being too low. If rpc_count increases, more network roundtrips have
 
493
        # become necessary for this use case. Please do not adjust this number
 
494
        # upwards without agreement from bzr's network support maintainers.
 
495
        self.assertLength(24, self.hpss_calls)
 
496
        self.assertLength(4, self.hpss_connections)
 
497
        self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
 
498
 
 
499
 
 
500
class TestSwitchUncommitted(TestCaseWithTransport):
 
501
 
 
502
    def prepare(self):
 
503
        tree = self.make_branch_and_tree('orig')
 
504
        tree.commit('')
 
505
        tree.branch.bzrdir.sprout('new')
 
506
        checkout = tree.branch.create_checkout('checkout', lightweight=True)
 
507
        self.build_tree(['checkout/a'])
 
508
        self.assertPathExists('checkout/a')
 
509
        checkout.add('a')
 
510
 
 
511
    def test_switch_stores_local(self):
 
512
        self.prepare()
 
513
        self.run_bzr(['switch', '-d', 'checkout', 'new'])
 
514
        self.assertPathDoesNotExist('checkout/a')
 
515
        self.run_bzr(['switch', '-d', 'checkout', 'orig'])
 
516
        self.assertPathExists('checkout/a')
 
517
 
 
518
    def test_with_changes_does_not_store(self):
 
519
        self.prepare()
 
520
        self.run_bzr(['switch', '-d', 'checkout', '--with-changes', 'new'])
 
521
        self.assertPathExists('checkout/a')
 
522
 
 
523
    def test_with_changes_does_not_restore(self):
 
524
        self.prepare()
 
525
        self.run_bzr(['switch', '-d', 'checkout', 'new'])
 
526
        self.assertPathDoesNotExist('checkout/a')
 
527
        self.run_bzr(['switch', '-d', 'checkout', '--with-changes', 'orig'])
 
528
        self.assertPathDoesNotExist('checkout/a')