~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Wouter van Heyst
  • Date: 2012-01-25 21:13:15 UTC
  • mto: (6437.3.27 2.5)
  • mto: This revision was merged to the branch mainline in revision 6451.
  • Revision ID: larstiq@larstiq.dyndns.org-20120125211315-ch74doua37bqet0i
mechanically replace file().write() pattern with a with-keyword version

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007, 2008, 2009 Canonical Ltd
 
1
# Copyright (C) 2007-2010 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.bzrdir import BzrDir
 
24
from bzrlib import (
 
25
        osutils,
 
26
        urlutils,
 
27
        branch,
 
28
        )
23
29
from bzrlib.workingtree import WorkingTree
24
 
from bzrlib.tests.blackbox import ExternalBase
 
30
from bzrlib.tests import (
 
31
        TestCaseWithTransport,
 
32
        script,
 
33
        )
 
34
from bzrlib.tests.features import UnicodeFilenameFeature
25
35
from bzrlib.directory_service import directories
26
36
 
27
 
 
28
 
class TestSwitch(ExternalBase):
 
37
from bzrlib.tests.matchers import ContainsNoVfsCalls
 
38
 
 
39
 
 
40
class TestSwitch(TestCaseWithTransport):
29
41
 
30
42
    def _create_sample_tree(self):
31
43
        tree = self.make_branch_and_tree('branch-1')
128
140
        """Using switch on a heavy checkout should find master sibling
129
141
 
130
142
        The behaviour of lighweight and heavy checkouts should be
131
 
        consistentwhen using the convenient "switch to sibling" feature
 
143
        consistent when using the convenient "switch to sibling" feature
132
144
        Both should switch to a sibling of the branch
133
145
        they are bound to, and not a sibling of themself"""
134
146
 
144
156
        self.assertEqual(branchb_id, checkout.last_revision())
145
157
        self.assertEqual(tree2.branch.base, checkout.branch.get_bound_location())
146
158
 
 
159
    def test_switch_finds_relative_unicode_branch(self):
 
160
        """Switch will find 'foo' relative to the branch the checkout is of."""
 
161
        self.requireFeature(UnicodeFilenameFeature)
 
162
        self.build_tree(['repo/'])
 
163
        tree1 = self.make_branch_and_tree('repo/brancha')
 
164
        tree1.commit('foo')
 
165
        tree2 = self.make_branch_and_tree(u'repo/branch\xe9')
 
166
        tree2.pull(tree1.branch)
 
167
        branchb_id = tree2.commit('bar')
 
168
        checkout =  tree1.branch.create_checkout('checkout', lightweight=True)
 
169
        self.run_bzr(['switch', u'branch\xe9'], working_dir='checkout')
 
170
        self.assertEqual(branchb_id, checkout.last_revision())
 
171
        checkout = checkout.bzrdir.open_workingtree()
 
172
        self.assertEqual(tree2.branch.base, checkout.branch.base)
 
173
 
147
174
    def test_switch_revision(self):
148
175
        tree = self._create_sample_tree()
149
176
        checkout = tree.branch.create_checkout('checkout', lightweight=True)
150
177
        self.run_bzr(['switch', 'branch-1', '-r1'], working_dir='checkout')
151
 
        self.failUnlessExists('checkout/file-1')
152
 
        self.failIfExists('checkout/file-2')
 
178
        self.assertPathExists('checkout/file-1')
 
179
        self.assertPathDoesNotExist('checkout/file-2')
 
180
 
 
181
    def test_switch_into_colocated(self):
 
182
        # Create a new colocated branch from an existing non-colocated branch.
 
183
        tree = self.make_branch_and_tree('.', format='development-colo')
 
184
        self.build_tree(['file-1', 'file-2'])
 
185
        tree.add('file-1')
 
186
        revid1 = tree.commit('rev1')
 
187
        tree.add('file-2')
 
188
        revid2 = tree.commit('rev2')
 
189
        self.run_bzr(['switch', '-b', 'anotherbranch'])
 
190
        self.assertEquals(
 
191
            ['', 'anotherbranch'],
 
192
            tree.branch.bzrdir.get_branches().keys())
 
193
 
 
194
    def test_switch_into_unrelated_colocated(self):
 
195
        # Create a new colocated branch from an existing non-colocated branch.
 
196
        tree = self.make_branch_and_tree('.', format='development-colo')
 
197
        self.build_tree(['file-1', 'file-2'])
 
198
        tree.add('file-1')
 
199
        revid1 = tree.commit('rev1')
 
200
        tree.add('file-2')
 
201
        revid2 = tree.commit('rev2')
 
202
        tree.bzrdir.create_branch(name='foo')
 
203
        self.run_bzr_error(['Cannot switch a branch, only a checkout.'],
 
204
            'switch foo')
 
205
        self.run_bzr(['switch', '--force', 'foo'])
 
206
 
 
207
    def test_switch_existing_colocated(self):
 
208
        # Create a branch branch-1 that initially is a checkout of 'foo'
 
209
        # Use switch to change it to 'anotherbranch'
 
210
        repo = self.make_repository('branch-1', format='development-colo')
 
211
        target_branch = repo.bzrdir.create_branch(name='foo')
 
212
        repo.bzrdir.set_branch_reference(target_branch)
 
213
        tree = repo.bzrdir.create_workingtree()
 
214
        self.build_tree(['branch-1/file-1', 'branch-1/file-2'])
 
215
        tree.add('file-1')
 
216
        revid1 = tree.commit('rev1')
 
217
        tree.add('file-2')
 
218
        revid2 = tree.commit('rev2')
 
219
        otherbranch = tree.bzrdir.create_branch(name='anotherbranch')
 
220
        otherbranch.generate_revision_history(revid1)
 
221
        self.run_bzr(['switch', 'anotherbranch'], working_dir='branch-1')
 
222
        tree = WorkingTree.open("branch-1")
 
223
        self.assertEquals(tree.last_revision(), revid1)
 
224
        self.assertEquals(tree.branch.control_url, otherbranch.control_url)
 
225
 
 
226
    def test_switch_new_colocated(self):
 
227
        # Create a branch branch-1 that initially is a checkout of 'foo'
 
228
        # Use switch to create 'anotherbranch' which derives from that
 
229
        repo = self.make_repository('branch-1', format='development-colo')
 
230
        target_branch = repo.bzrdir.create_branch(name='foo')
 
231
        repo.bzrdir.set_branch_reference(target_branch)
 
232
        tree = repo.bzrdir.create_workingtree()
 
233
        self.build_tree(['branch-1/file-1', 'branch-1/file-2'])
 
234
        tree.add('file-1')
 
235
        revid1 = tree.commit('rev1')
 
236
        self.run_bzr(['switch', '-b', 'anotherbranch'], working_dir='branch-1')
 
237
        bzrdir = BzrDir.open("branch-1")
 
238
        self.assertEquals(
 
239
            set([b.name for b in bzrdir.list_branches()]),
 
240
            set(["foo", "anotherbranch"]))
 
241
        self.assertEquals(bzrdir.open_branch().name, "anotherbranch")
 
242
        self.assertEquals(bzrdir.open_branch().last_revision(), revid1)
 
243
 
 
244
    def test_switch_new_colocated_unicode(self):
 
245
        # Create a branch branch-1 that initially is a checkout of 'foo'
 
246
        # Use switch to create 'branch\xe9' which derives from that
 
247
        self.requireFeature(UnicodeFilenameFeature)
 
248
        repo = self.make_repository('branch-1', format='development-colo')
 
249
        target_branch = repo.bzrdir.create_branch(name='foo')
 
250
        repo.bzrdir.set_branch_reference(target_branch)
 
251
        tree = repo.bzrdir.create_workingtree()
 
252
        self.build_tree(['branch-1/file-1', 'branch-1/file-2'])
 
253
        tree.add('file-1')
 
254
        revid1 = tree.commit('rev1')
 
255
        self.run_bzr(['switch', '-b', u'branch\xe9'], working_dir='branch-1')
 
256
        bzrdir = BzrDir.open("branch-1")
 
257
        self.assertEquals(
 
258
            set([b.name for b in bzrdir.list_branches()]),
 
259
            set(["foo", u"branch\xe9"]))
 
260
        self.assertEquals(bzrdir.open_branch().name, u"branch\xe9")
 
261
        self.assertEquals(bzrdir.open_branch().last_revision(), revid1)
153
262
 
154
263
    def test_switch_only_revision(self):
155
264
        tree = self._create_sample_tree()
156
265
        checkout = tree.branch.create_checkout('checkout', lightweight=True)
157
 
        self.failUnlessExists('checkout/file-1')
158
 
        self.failUnlessExists('checkout/file-2')
 
266
        self.assertPathExists('checkout/file-1')
 
267
        self.assertPathExists('checkout/file-2')
159
268
        self.run_bzr(['switch', '-r1'], working_dir='checkout')
160
 
        self.failUnlessExists('checkout/file-1')
161
 
        self.failIfExists('checkout/file-2')
 
269
        self.assertPathExists('checkout/file-1')
 
270
        self.assertPathDoesNotExist('checkout/file-2')
162
271
        # Check that we don't accept a range
163
272
        self.run_bzr_error(
164
273
            ['bzr switch --revision takes exactly one revision identifier'],
167
276
    def prepare_lightweight_switch(self):
168
277
        branch = self.make_branch('branch')
169
278
        branch.create_checkout('tree', lightweight=True)
170
 
        os.rename('branch', 'branch1')
 
279
        osutils.rename('branch', 'branch1')
171
280
 
172
281
    def test_switch_lightweight_after_branch_moved(self):
173
282
        self.prepare_lightweight_switch()
225
334
        self.run_bzr('switch -b foo:branch2', working_dir='tree')
226
335
        tree = WorkingTree.open('tree')
227
336
        self.assertEndsWith(tree.branch.base, 'foo-branch2/')
 
337
 
 
338
    def test_switch_with_post_switch_hook(self):
 
339
        from bzrlib import branch as _mod_branch
 
340
        calls = []
 
341
        _mod_branch.Branch.hooks.install_named_hook('post_switch',
 
342
            calls.append, None)
 
343
        self.make_branch_and_tree('branch')
 
344
        self.run_bzr('branch branch branch2')
 
345
        self.run_bzr('checkout branch checkout')
 
346
        os.chdir('checkout')
 
347
        self.assertLength(0, calls)
 
348
        out, err = self.run_bzr('switch ../branch2')
 
349
        self.assertLength(1, calls)
 
350
 
 
351
    def test_switch_lightweight_co_with_post_switch_hook(self):
 
352
        from bzrlib import branch as _mod_branch
 
353
        calls = []
 
354
        _mod_branch.Branch.hooks.install_named_hook('post_switch',
 
355
            calls.append, None)
 
356
        self.make_branch_and_tree('branch')
 
357
        self.run_bzr('branch branch branch2')
 
358
        self.run_bzr('checkout --lightweight branch checkout')
 
359
        os.chdir('checkout')
 
360
        self.assertLength(0, calls)
 
361
        out, err = self.run_bzr('switch ../branch2')
 
362
        self.assertLength(1, calls)
 
363
 
 
364
    def test_switch_lightweight_directory(self):
 
365
        """Test --directory option"""
 
366
 
 
367
        # create a source branch
 
368
        a_tree = self.make_branch_and_tree('a')
 
369
        self.build_tree_contents([('a/a', 'initial\n')])
 
370
        a_tree.add('a')
 
371
        a_tree.commit(message='initial')
 
372
 
 
373
        # clone and add a differing revision
 
374
        b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
 
375
        self.build_tree_contents([('b/a', 'initial\nmore\n')])
 
376
        b_tree.commit(message='more')
 
377
 
 
378
        self.run_bzr('checkout --lightweight a checkout')
 
379
        self.run_bzr('switch --directory checkout b')
 
380
        self.assertFileEqual('initial\nmore\n', 'checkout/a')
 
381
 
 
382
 
 
383
class TestSwitchParentLocationBase(TestCaseWithTransport):
 
384
 
 
385
    def setUp(self):
 
386
        """Set up a repository and branch ready for testing."""
 
387
        super(TestSwitchParentLocationBase, self).setUp()
 
388
        self.script_runner = script.ScriptRunner()
 
389
        self.script_runner.run_script(self, '''
 
390
                $ bzr init-repo --no-trees repo
 
391
                Shared repository...
 
392
                Location:
 
393
                  shared repository: repo
 
394
                $ bzr init repo/trunk
 
395
                Created a repository branch...
 
396
                Using shared repository: ...
 
397
                ''')
 
398
 
 
399
    def assertParent(self, expected_parent, branch):
 
400
        """Verify that the parent is not None and is set correctly."""
 
401
        actual_parent = branch.get_parent()
 
402
        self.assertIsSameRealPath(urlutils.local_path_to_url(expected_parent),
 
403
                                  branch.get_parent())
 
404
 
 
405
 
 
406
class TestSwitchParentLocation(TestSwitchParentLocationBase):
 
407
 
 
408
    def _checkout_and_switch(self, option=''):
 
409
        self.script_runner.run_script(self, '''
 
410
                $ bzr checkout %(option)s repo/trunk checkout
 
411
                $ cd checkout
 
412
                $ bzr switch --create-branch switched
 
413
                2>Tree is up to date at revision 0.
 
414
                2>Switched to branch:...switched...
 
415
                $ cd ..
 
416
                ''' % locals())
 
417
        bound_branch = branch.Branch.open_containing('checkout')[0]
 
418
        master_branch = branch.Branch.open_containing('repo/switched')[0]
 
419
        return (bound_branch, master_branch)
 
420
 
 
421
    def test_switch_parent_lightweight(self):
 
422
        """Lightweight checkout using bzr switch."""
 
423
        bb, mb = self._checkout_and_switch(option='--lightweight')
 
424
        self.assertParent('repo/trunk', bb)
 
425
        self.assertParent('repo/trunk', mb)
 
426
 
 
427
    def test_switch_parent_heavyweight(self):
 
428
        """Heavyweight checkout using bzr switch."""
 
429
        bb, mb = self._checkout_and_switch()
 
430
        self.assertParent('repo/trunk', bb)
 
431
        self.assertParent('repo/trunk', mb)
 
432
 
 
433
 
 
434
class TestSwitchDoesntOpenMasterBranch(TestCaseWithTransport):
 
435
    # See https://bugs.launchpad.net/bzr/+bug/812285
 
436
    # "bzr switch --create-branch" can point the new branch's parent to the
 
437
    # master branch, but it doesn't have to open it to do so.
 
438
 
 
439
    def test_switch_create_doesnt_open_master_branch(self):
 
440
        master = self.make_branch_and_tree('master')
 
441
        master.commit('one')
 
442
        # Note: not a lightweight checkout
 
443
        checkout = master.branch.create_checkout('checkout')
 
444
        opened = []
 
445
        def open_hook(branch):
 
446
            # Just append the final directory of the branch
 
447
            name = branch.base.rstrip('/').rsplit('/', 1)[1]
 
448
            opened.append(name)
 
449
        branch.Branch.hooks.install_named_hook('open', open_hook,
 
450
                                               'open_hook_logger')
 
451
        self.run_bzr('switch --create-branch -d checkout feature')
 
452
        # We only open the master branch 1 time.
 
453
        # This test should be cleaner to write, but see bug:
 
454
        #  https://bugs.launchpad.net/bzr/+bug/812295
 
455
        self.assertEqual(1, opened.count('master'))
 
456
 
 
457
 
 
458
class TestSmartServerSwitch(TestCaseWithTransport):
 
459
 
 
460
    def test_switch_lightweight(self):
 
461
        self.setup_smart_server_with_call_log()
 
462
        t = self.make_branch_and_tree('from')
 
463
        for count in range(9):
 
464
            t.commit(message='commit %d' % count)
 
465
        out, err = self.run_bzr(['checkout', '--lightweight', self.get_url('from'),
 
466
            'target'])
 
467
        self.reset_smart_call_log()
 
468
        self.run_bzr(['switch', self.get_url('from')], working_dir='target')
 
469
        # This figure represent the amount of work to perform this use case. It
 
470
        # is entirely ok to reduce this number if a test fails due to rpc_count
 
471
        # being too low. If rpc_count increases, more network roundtrips have
 
472
        # become necessary for this use case. Please do not adjust this number
 
473
        # upwards without agreement from bzr's network support maintainers.
 
474
        self.assertLength(24, self.hpss_calls)
 
475
        self.assertLength(5, self.hpss_connections)
 
476
        self.assertThat(self.hpss_calls, ContainsNoVfsCalls)