~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

(vila) Forbid more operations on ReadonlyTransportDecorator (Vincent Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2010 Canonical Ltd
 
1
# Copyright (C) 2007-2012 Canonical Ltd
2
2
# -*- coding: utf-8 -*-
3
3
#
4
4
# This program is free software; you can redistribute it and/or modify
20
20
 
21
21
import os
22
22
 
23
 
from bzrlib import osutils
 
23
from bzrlib.controldir import ControlDir
 
24
from bzrlib import (
 
25
    osutils,
 
26
    urlutils,
 
27
    branch,
 
28
    )
24
29
from bzrlib.workingtree import WorkingTree
25
 
from bzrlib.tests import TestCaseWithTransport
 
30
from bzrlib.tests import (
 
31
    TestCaseWithTransport,
 
32
    script,
 
33
    )
 
34
from bzrlib.tests.features import UnicodeFilenameFeature
26
35
from bzrlib.directory_service import directories
27
36
 
 
37
from bzrlib.tests.matchers import ContainsNoVfsCalls
 
38
 
28
39
 
29
40
class TestSwitch(TestCaseWithTransport):
30
41
 
129
140
        """Using switch on a heavy checkout should find master sibling
130
141
 
131
142
        The behaviour of lighweight and heavy checkouts should be
132
 
        consistentwhen using the convenient "switch to sibling" feature
 
143
        consistent when using the convenient "switch to sibling" feature
133
144
        Both should switch to a sibling of the branch
134
145
        they are bound to, and not a sibling of themself"""
135
146
 
142
153
        branchb_id = tree2.commit('bar')
143
154
        checkout = tree1.branch.create_checkout('heavyco/a', lightweight=False)
144
155
        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())
 
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)
147
191
 
148
192
    def test_switch_revision(self):
149
193
        tree = self._create_sample_tree()
150
194
        checkout = tree.branch.create_checkout('checkout', lightweight=True)
151
195
        self.run_bzr(['switch', 'branch-1', '-r1'], working_dir='checkout')
152
 
        self.failUnlessExists('checkout/file-1')
153
 
        self.failIfExists('checkout/file-2')
 
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)
154
280
 
155
281
    def test_switch_only_revision(self):
156
282
        tree = self._create_sample_tree()
157
283
        checkout = tree.branch.create_checkout('checkout', lightweight=True)
158
 
        self.failUnlessExists('checkout/file-1')
159
 
        self.failUnlessExists('checkout/file-2')
 
284
        self.assertPathExists('checkout/file-1')
 
285
        self.assertPathExists('checkout/file-2')
160
286
        self.run_bzr(['switch', '-r1'], working_dir='checkout')
161
 
        self.failUnlessExists('checkout/file-1')
162
 
        self.failIfExists('checkout/file-2')
 
287
        self.assertPathExists('checkout/file-1')
 
288
        self.assertPathDoesNotExist('checkout/file-2')
163
289
        # Check that we don't accept a range
164
290
        self.run_bzr_error(
165
291
            ['bzr switch --revision takes exactly one revision identifier'],
178
304
 
179
305
    def test_switch_lightweight_after_branch_moved_relative(self):
180
306
        self.prepare_lightweight_switch()
181
 
        self.run_bzr('switch --force branch1', working_dir='tree')
 
307
        self.run_bzr('switch --force branch1',
 
308
                     working_dir='tree')
182
309
        branch_location = WorkingTree.open('tree').branch.base
183
310
        self.assertEndsWith(branch_location, 'branch1/')
184
311
 
270
397
        self.run_bzr('checkout --lightweight a checkout')
271
398
        self.run_bzr('switch --directory checkout b')
272
399
        self.assertFileEqual('initial\nmore\n', 'checkout/a')
 
400
 
 
401
 
 
402
class TestSwitchParentLocationBase(TestCaseWithTransport):
 
403
 
 
404
    def setUp(self):
 
405
        """Set up a repository and branch ready for testing."""
 
406
        super(TestSwitchParentLocationBase, self).setUp()
 
407
        self.script_runner = script.ScriptRunner()
 
408
        self.script_runner.run_script(self, '''
 
409
                $ bzr init-repo --no-trees repo
 
410
                Shared repository...
 
411
                Location:
 
412
                  shared repository: repo
 
413
                $ bzr init repo/trunk
 
414
                Created a repository branch...
 
415
                Using shared repository: ...
 
416
                ''')
 
417
 
 
418
    def assertParent(self, expected_parent, branch):
 
419
        """Verify that the parent is not None and is set correctly."""
 
420
        actual_parent = branch.get_parent()
 
421
        self.assertIsSameRealPath(urlutils.local_path_to_url(expected_parent),
 
422
                                  branch.get_parent())
 
423
 
 
424
 
 
425
class TestSwitchParentLocation(TestSwitchParentLocationBase):
 
426
 
 
427
    def _checkout_and_switch(self, option=''):
 
428
        self.script_runner.run_script(self, '''
 
429
                $ bzr checkout %(option)s repo/trunk checkout
 
430
                $ cd checkout
 
431
                $ bzr switch --create-branch switched
 
432
                2>Tree is up to date at revision 0.
 
433
                2>Switched to branch:...switched...
 
434
                $ cd ..
 
435
                ''' % locals())
 
436
        bound_branch = branch.Branch.open_containing('checkout')[0]
 
437
        master_branch = branch.Branch.open_containing('repo/switched')[0]
 
438
        return (bound_branch, master_branch)
 
439
 
 
440
    def test_switch_parent_lightweight(self):
 
441
        """Lightweight checkout using bzr switch."""
 
442
        bb, mb = self._checkout_and_switch(option='--lightweight')
 
443
        self.assertParent('repo/trunk', bb)
 
444
        self.assertParent('repo/trunk', mb)
 
445
 
 
446
    def test_switch_parent_heavyweight(self):
 
447
        """Heavyweight checkout using bzr switch."""
 
448
        bb, mb = self._checkout_and_switch()
 
449
        self.assertParent('repo/trunk', bb)
 
450
        self.assertParent('repo/trunk', mb)
 
451
 
 
452
 
 
453
class TestSwitchDoesntOpenMasterBranch(TestCaseWithTransport):
 
454
    # See https://bugs.launchpad.net/bzr/+bug/812285
 
455
    # "bzr switch --create-branch" can point the new branch's parent to the
 
456
    # master branch, but it doesn't have to open it to do so.
 
457
 
 
458
    def test_switch_create_doesnt_open_master_branch(self):
 
459
        master = self.make_branch_and_tree('master')
 
460
        master.commit('one')
 
461
        # Note: not a lightweight checkout
 
462
        checkout = master.branch.create_checkout('checkout')
 
463
        opened = []
 
464
        def open_hook(branch):
 
465
            # Just append the final directory of the branch
 
466
            name = branch.base.rstrip('/').rsplit('/', 1)[1]
 
467
            opened.append(name)
 
468
        branch.Branch.hooks.install_named_hook('open', open_hook,
 
469
                                               'open_hook_logger')
 
470
        self.run_bzr('switch --create-branch -d checkout feature')
 
471
        # We only open the master branch 1 time.
 
472
        # This test should be cleaner to write, but see bug:
 
473
        #  https://bugs.launchpad.net/bzr/+bug/812295
 
474
        self.assertEqual(1, opened.count('master'))
 
475
 
 
476
 
 
477
class TestSmartServerSwitch(TestCaseWithTransport):
 
478
 
 
479
    def test_switch_lightweight(self):
 
480
        self.setup_smart_server_with_call_log()
 
481
        t = self.make_branch_and_tree('from')
 
482
        for count in range(9):
 
483
            t.commit(message='commit %d' % count)
 
484
        out, err = self.run_bzr(['checkout', '--lightweight', self.get_url('from'),
 
485
            'target'])
 
486
        self.reset_smart_call_log()
 
487
        self.run_bzr(['switch', self.get_url('from')], working_dir='target')
 
488
        # This figure represent the amount of work to perform this use case. It
 
489
        # is entirely ok to reduce this number if a test fails due to rpc_count
 
490
        # being too low. If rpc_count increases, more network roundtrips have
 
491
        # become necessary for this use case. Please do not adjust this number
 
492
        # upwards without agreement from bzr's network support maintainers.
 
493
        self.assertLength(24, self.hpss_calls)
 
494
        self.assertLength(4, self.hpss_connections)
 
495
        self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
 
496
 
 
497
 
 
498
class TestSwitchUncommitted(TestCaseWithTransport):
 
499
 
 
500
    def prepare(self):
 
501
        tree = self.make_branch_and_tree('orig')
 
502
        tree.commit('')
 
503
        tree.branch.bzrdir.sprout('new')
 
504
        checkout = tree.branch.create_checkout('checkout', lightweight=True)
 
505
        self.build_tree(['checkout/a'])
 
506
        self.assertPathExists('checkout/a')
 
507
        checkout.add('a')
 
508
        return checkout
 
509
 
 
510
    def test_store_and_restore_uncommitted(self):
 
511
        checkout = self.prepare()
 
512
        self.run_bzr(['switch', '--store', '-d', 'checkout', 'new'])
 
513
        self.build_tree(['checkout/b'])
 
514
        checkout.add('b')
 
515
        self.assertPathDoesNotExist('checkout/a')
 
516
        self.assertPathExists('checkout/b')
 
517
        self.run_bzr(['switch', '--store', '-d', 'checkout', 'orig'])
 
518
        self.assertPathExists('checkout/a')
 
519
        self.assertPathDoesNotExist('checkout/b')
 
520
 
 
521
    def test_does_not_store(self):
 
522
        self.prepare()
 
523
        self.run_bzr(['switch', '-d', 'checkout', 'new'])
 
524
        self.assertPathExists('checkout/a')
 
525
 
 
526
    def test_does_not_restore_changes(self):
 
527
        self.prepare()
 
528
        self.run_bzr(['switch', '--store', '-d', 'checkout', 'new'])
 
529
        self.assertPathDoesNotExist('checkout/a')
 
530
        self.run_bzr(['switch', '-d', 'checkout', 'orig'])
 
531
        self.assertPathDoesNotExist('checkout/a')