~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Vincent Ladeuil
  • Date: 2012-01-09 20:55:07 UTC
  • mto: This revision was merged to the branch mainline in revision 6468.
  • Revision ID: v.ladeuil+lp@free.fr-20120109205507-2i3en5r4w4ohdchj
Use idioms coherently and add comments to make their purpose clearer.

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.bzrdir import BzrDir
 
24
from bzrlib import (
 
25
        osutils,
 
26
        urlutils,
 
27
        branch,
 
28
        )
24
29
from bzrlib.workingtree import WorkingTree
25
 
from bzrlib.tests.blackbox import ExternalBase
 
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
 
28
 
 
29
 
class TestSwitch(ExternalBase):
 
37
from bzrlib.tests.matchers import ContainsNoVfsCalls
 
38
 
 
39
 
 
40
class TestSwitch(TestCaseWithTransport):
30
41
 
31
42
    def _create_sample_tree(self):
32
43
        tree = self.make_branch_and_tree('branch-1')
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)
147
176
 
148
177
    def test_switch_revision(self):
149
178
        tree = self._create_sample_tree()
150
179
        checkout = tree.branch.create_checkout('checkout', lightweight=True)
151
180
        self.run_bzr(['switch', 'branch-1', '-r1'], working_dir='checkout')
152
 
        self.failUnlessExists('checkout/file-1')
153
 
        self.failIfExists('checkout/file-2')
 
181
        self.assertPathExists('checkout/file-1')
 
182
        self.assertPathDoesNotExist('checkout/file-2')
 
183
 
 
184
    def test_switch_existing_colocated(self):
 
185
        # Create a branch branch-1 that initially is a checkout of 'foo'
 
186
        # Use switch to change it to 'anotherbranch'
 
187
        repo = self.make_repository('branch-1', format='development-colo')
 
188
        target_branch = repo.bzrdir.create_branch(name='foo')
 
189
        branch.BranchReferenceFormat().initialize(
 
190
            repo.bzrdir, target_branch=target_branch)
 
191
        tree = repo.bzrdir.create_workingtree()
 
192
        self.build_tree(['branch-1/file-1', 'branch-1/file-2'])
 
193
        tree.add('file-1')
 
194
        revid1 = tree.commit('rev1')
 
195
        tree.add('file-2')
 
196
        revid2 = tree.commit('rev2')
 
197
        otherbranch = tree.bzrdir.create_branch(name='anotherbranch')
 
198
        otherbranch.generate_revision_history(revid1)
 
199
        self.run_bzr(['switch', 'anotherbranch'], working_dir='branch-1')
 
200
        tree = WorkingTree.open("branch-1")
 
201
        self.assertEquals(tree.last_revision(), revid1)
 
202
        self.assertEquals(tree.branch.control_url, otherbranch.control_url)
 
203
 
 
204
    def test_switch_new_colocated(self):
 
205
        # Create a branch branch-1 that initially is a checkout of 'foo'
 
206
        # Use switch to create 'anotherbranch' which derives from that
 
207
        repo = self.make_repository('branch-1', format='development-colo')
 
208
        target_branch = repo.bzrdir.create_branch(name='foo')
 
209
        branch.BranchReferenceFormat().initialize(
 
210
            repo.bzrdir, target_branch=target_branch)
 
211
        tree = repo.bzrdir.create_workingtree()
 
212
        self.build_tree(['branch-1/file-1', 'branch-1/file-2'])
 
213
        tree.add('file-1')
 
214
        revid1 = tree.commit('rev1')
 
215
        self.run_bzr(['switch', '-b', 'anotherbranch'], working_dir='branch-1')
 
216
        bzrdir = BzrDir.open("branch-1")
 
217
        self.assertEquals(
 
218
            set([b.name for b in bzrdir.list_branches()]),
 
219
            set(["foo", "anotherbranch"]))
 
220
        self.assertEquals(bzrdir.open_branch().name, "anotherbranch")
 
221
        self.assertEquals(bzrdir.open_branch().last_revision(), revid1)
 
222
 
 
223
    def test_switch_new_colocated_unicode(self):
 
224
        # Create a branch branch-1 that initially is a checkout of 'foo'
 
225
        # Use switch to create 'branch\xe9' which derives from that
 
226
        self.requireFeature(UnicodeFilenameFeature)
 
227
        repo = self.make_repository('branch-1', format='development-colo')
 
228
        target_branch = repo.bzrdir.create_branch(name='foo')
 
229
        branch.BranchReferenceFormat().initialize(
 
230
            repo.bzrdir, target_branch=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
        self.run_bzr(['switch', '-b', u'branch\xe9'], working_dir='branch-1')
 
236
        bzrdir = BzrDir.open("branch-1")
 
237
        self.assertEquals(
 
238
            set([b.name for b in bzrdir.list_branches()]),
 
239
            set(["foo", u"branch\xe9"]))
 
240
        self.assertEquals(bzrdir.open_branch().name, u"branch\xe9")
 
241
        self.assertEquals(bzrdir.open_branch().last_revision(), revid1)
154
242
 
155
243
    def test_switch_only_revision(self):
156
244
        tree = self._create_sample_tree()
157
245
        checkout = tree.branch.create_checkout('checkout', lightweight=True)
158
 
        self.failUnlessExists('checkout/file-1')
159
 
        self.failUnlessExists('checkout/file-2')
 
246
        self.assertPathExists('checkout/file-1')
 
247
        self.assertPathExists('checkout/file-2')
160
248
        self.run_bzr(['switch', '-r1'], working_dir='checkout')
161
 
        self.failUnlessExists('checkout/file-1')
162
 
        self.failIfExists('checkout/file-2')
 
249
        self.assertPathExists('checkout/file-1')
 
250
        self.assertPathDoesNotExist('checkout/file-2')
163
251
        # Check that we don't accept a range
164
252
        self.run_bzr_error(
165
253
            ['bzr switch --revision takes exactly one revision identifier'],
252
340
        self.assertLength(0, calls)
253
341
        out, err = self.run_bzr('switch ../branch2')
254
342
        self.assertLength(1, calls)
 
343
 
 
344
    def test_switch_lightweight_directory(self):
 
345
        """Test --directory option"""
 
346
 
 
347
        # create a source branch
 
348
        a_tree = self.make_branch_and_tree('a')
 
349
        self.build_tree_contents([('a/a', 'initial\n')])
 
350
        a_tree.add('a')
 
351
        a_tree.commit(message='initial')
 
352
 
 
353
        # clone and add a differing revision
 
354
        b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
 
355
        self.build_tree_contents([('b/a', 'initial\nmore\n')])
 
356
        b_tree.commit(message='more')
 
357
 
 
358
        self.run_bzr('checkout --lightweight a checkout')
 
359
        self.run_bzr('switch --directory checkout b')
 
360
        self.assertFileEqual('initial\nmore\n', 'checkout/a')
 
361
 
 
362
 
 
363
class TestSwitchParentLocationBase(TestCaseWithTransport):
 
364
 
 
365
    def setUp(self):
 
366
        """Set up a repository and branch ready for testing."""
 
367
        super(TestSwitchParentLocationBase, self).setUp()
 
368
        self.script_runner = script.ScriptRunner()
 
369
        self.script_runner.run_script(self, '''
 
370
                $ bzr init-repo --no-trees repo
 
371
                Shared repository...
 
372
                Location:
 
373
                  shared repository: repo
 
374
                $ bzr init repo/trunk
 
375
                Created a repository branch...
 
376
                Using shared repository: ...
 
377
                ''')
 
378
 
 
379
    def assertParent(self, expected_parent, branch):
 
380
        """Verify that the parent is not None and is set correctly."""
 
381
        actual_parent = branch.get_parent()
 
382
        self.assertIsSameRealPath(urlutils.local_path_to_url(expected_parent),
 
383
                                  branch.get_parent())
 
384
 
 
385
 
 
386
class TestSwitchParentLocation(TestSwitchParentLocationBase):
 
387
 
 
388
    def _checkout_and_switch(self, option=''):
 
389
        self.script_runner.run_script(self, '''
 
390
                $ bzr checkout %(option)s repo/trunk checkout
 
391
                $ cd checkout
 
392
                $ bzr switch --create-branch switched
 
393
                2>Tree is up to date at revision 0.
 
394
                2>Switched to branch:...switched...
 
395
                $ cd ..
 
396
                ''' % locals())
 
397
        bound_branch = branch.Branch.open_containing('checkout')[0]
 
398
        master_branch = branch.Branch.open_containing('repo/switched')[0]
 
399
        return (bound_branch, master_branch)
 
400
 
 
401
    def test_switch_parent_lightweight(self):
 
402
        """Lightweight checkout using bzr switch."""
 
403
        bb, mb = self._checkout_and_switch(option='--lightweight')
 
404
        self.assertParent('repo/trunk', bb)
 
405
        self.assertParent('repo/trunk', mb)
 
406
 
 
407
    def test_switch_parent_heavyweight(self):
 
408
        """Heavyweight checkout using bzr switch."""
 
409
        bb, mb = self._checkout_and_switch()
 
410
        self.assertParent('repo/trunk', bb)
 
411
        self.assertParent('repo/trunk', mb)
 
412
 
 
413
 
 
414
class TestSwitchDoesntOpenMasterBranch(TestCaseWithTransport):
 
415
    # See https://bugs.launchpad.net/bzr/+bug/812285
 
416
    # "bzr switch --create-branch" can point the new branch's parent to the
 
417
    # master branch, but it doesn't have to open it to do so.
 
418
 
 
419
    def test_switch_create_doesnt_open_master_branch(self):
 
420
        master = self.make_branch_and_tree('master')
 
421
        master.commit('one')
 
422
        # Note: not a lightweight checkout
 
423
        checkout = master.branch.create_checkout('checkout')
 
424
        opened = []
 
425
        def open_hook(branch):
 
426
            # Just append the final directory of the branch
 
427
            name = branch.base.rstrip('/').rsplit('/', 1)[1]
 
428
            opened.append(name)
 
429
        branch.Branch.hooks.install_named_hook('open', open_hook,
 
430
                                               'open_hook_logger')
 
431
        self.run_bzr('switch --create-branch -d checkout feature')
 
432
        # We only open the master branch 1 time.
 
433
        # This test should be cleaner to write, but see bug:
 
434
        #  https://bugs.launchpad.net/bzr/+bug/812295
 
435
        self.assertEqual(1, opened.count('master'))
 
436
 
 
437
 
 
438
class TestSmartServerSwitch(TestCaseWithTransport):
 
439
 
 
440
    def test_switch_lightweight(self):
 
441
        self.setup_smart_server_with_call_log()
 
442
        t = self.make_branch_and_tree('from')
 
443
        for count in range(9):
 
444
            t.commit(message='commit %d' % count)
 
445
        out, err = self.run_bzr(['checkout', '--lightweight', self.get_url('from'),
 
446
            'target'])
 
447
        self.reset_smart_call_log()
 
448
        self.run_bzr(['switch', self.get_url('from')], working_dir='target')
 
449
        # This figure represent the amount of work to perform this use case. It
 
450
        # is entirely ok to reduce this number if a test fails due to rpc_count
 
451
        # being too low. If rpc_count increases, more network roundtrips have
 
452
        # become necessary for this use case. Please do not adjust this number
 
453
        # upwards without agreement from bzr's network support maintainers.
 
454
        self.assertLength(24, self.hpss_calls)
 
455
        self.assertLength(5, self.hpss_connections)
 
456
        self.assertThat(self.hpss_calls, ContainsNoVfsCalls)