~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Patch Queue Manager
  • Date: 2014-02-12 18:22:22 UTC
  • mfrom: (6589.2.1 trunk)
  • Revision ID: pqm@pqm.ubuntu.com-20140212182222-beouo25gaf1cny76
(vila) The XDG Base Directory Specification uses the XDG_CACHE_HOME,
 not XDG_CACHE_DIR. (Andrew Starr-Bochicchio)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2008, 2009 Canonical Ltd
 
1
# Copyright (C) 2006-2012 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
19
19
 
20
20
import os
21
21
 
22
 
from bzrlib import (branch, bzrdir, errors, repository)
 
22
from bzrlib import (
 
23
    branch,
 
24
    bzrdir,
 
25
    controldir,
 
26
    errors,
 
27
    revision as _mod_revision,
 
28
    tests,
 
29
    )
23
30
from bzrlib.repofmt.knitrepo import RepositoryFormatKnit1
24
 
from bzrlib.tests.blackbox import ExternalBase
25
 
from bzrlib.tests import HardlinkFeature
 
31
from bzrlib.tests import (
 
32
    fixtures,
 
33
    test_server,
 
34
    )
 
35
from bzrlib.tests.features import (
 
36
    HardlinkFeature,
 
37
    )
 
38
from bzrlib.tests.blackbox import test_switch
 
39
from bzrlib.tests.matchers import ContainsNoVfsCalls
26
40
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
 
41
from bzrlib.tests.script import run_script
27
42
from bzrlib.urlutils import local_path_to_url, strip_trailing_slash
28
43
from bzrlib.workingtree import WorkingTree
29
44
 
30
45
 
31
 
class TestBranch(ExternalBase):
 
46
class TestBranch(tests.TestCaseWithTransport):
32
47
 
33
 
    def example_branch(self, path='.'):
34
 
        tree = self.make_branch_and_tree(path)
 
48
    def example_branch(self, path='.', format=None):
 
49
        tree = self.make_branch_and_tree(path, format=format)
35
50
        self.build_tree_contents([(path + '/hello', 'foo')])
36
51
        tree.add('hello')
37
52
        tree.commit(message='setup')
38
53
        self.build_tree_contents([(path + '/goodbye', 'baz')])
39
54
        tree.add('goodbye')
40
55
        tree.commit(message='setup')
 
56
        return tree
41
57
 
42
58
    def test_branch(self):
43
59
        """Branch from one branch to another."""
49
65
        self.assertFalse(b._transport.has('branch-name'))
50
66
        b.bzrdir.open_workingtree().commit(message='foo', allow_pointless=True)
51
67
 
 
68
    def test_branch_no_to_location(self):
 
69
        """The to_location is derived from the source branch name."""
 
70
        os.mkdir("something")
 
71
        a = self.example_branch('something/a').branch
 
72
        self.run_bzr('branch something/a')
 
73
        b = branch.Branch.open('a')
 
74
        self.assertEquals(b.last_revision_info(), a.last_revision_info())
 
75
 
 
76
    def test_into_colocated(self):
 
77
        """Branch from a branch into a colocated branch."""
 
78
        self.example_branch('a')
 
79
        out, err = self.run_bzr(
 
80
            'init --format=development-colo file:b,branch=orig')
 
81
        self.assertEqual(
 
82
            """Created a lightweight checkout (format: development-colo)\n""",
 
83
            out)
 
84
        self.assertEqual('', err)
 
85
        out, err = self.run_bzr(
 
86
            'branch a file:b,branch=thiswasa')
 
87
        self.assertEqual('', out)
 
88
        self.assertEqual('Branched 2 revisions.\n', err)
 
89
        out, err = self.run_bzr('branches b')
 
90
        self.assertEqual("  orig\n  thiswasa\n", out)
 
91
        self.assertEqual('', err)
 
92
        out,err = self.run_bzr('branch a file:b,branch=orig', retcode=3)
 
93
        self.assertEqual('', out)
 
94
        self.assertEqual(
 
95
            'bzr: ERROR: Already a branch: "file:b,branch=orig".\n', err)
 
96
 
 
97
    def test_from_colocated(self):
 
98
        """Branch from a colocated branch into a regular branch."""
 
99
        tree = self.example_branch('a', format='development-colo')
 
100
        tree.bzrdir.create_branch(name='somecolo')
 
101
        out, err = self.run_bzr('branch %s,branch=somecolo' %
 
102
            local_path_to_url('a'))
 
103
        self.assertEqual('', out)
 
104
        self.assertEqual('Branched 0 revisions.\n', err)
 
105
        self.assertPathExists("somecolo")
 
106
 
 
107
    def test_branch_broken_pack(self):
 
108
        """branching with a corrupted pack file."""
 
109
        self.example_branch('a')
 
110
        # add some corruption
 
111
        packs_dir = 'a/.bzr/repository/packs/'
 
112
        fname = packs_dir + os.listdir(packs_dir)[0]
 
113
        with open(fname, 'rb+') as f:
 
114
            # Start from the end of the file to avoid choosing a place bigger
 
115
            # than the file itself.
 
116
            f.seek(-5, os.SEEK_END)
 
117
            c = f.read(1)
 
118
            f.seek(-5, os.SEEK_END)
 
119
            # Make sure we inject a value different than the one we just read
 
120
            if c == '\xFF':
 
121
                corrupt = '\x00'
 
122
            else:
 
123
                corrupt = '\xFF'
 
124
            f.write(corrupt) # make sure we corrupt something
 
125
        self.run_bzr_error(['Corruption while decompressing repository file'],
 
126
                            'branch a b', retcode=3)
 
127
 
 
128
    def test_branch_switch_no_branch(self):
 
129
        # No branch in the current directory:
 
130
        #  => new branch will be created, but switch fails
 
131
        self.example_branch('a')
 
132
        self.make_repository('current')
 
133
        self.run_bzr_error(['No WorkingTree exists for'],
 
134
            'branch --switch ../a ../b', working_dir='current')
 
135
        a = branch.Branch.open('a')
 
136
        b = branch.Branch.open('b')
 
137
        self.assertEqual(a.last_revision(), b.last_revision())
 
138
 
 
139
    def test_branch_switch_no_wt(self):
 
140
        # No working tree in the current directory:
 
141
        #  => new branch will be created, but switch fails and the current
 
142
        #     branch is unmodified
 
143
        self.example_branch('a')
 
144
        self.make_branch('current')
 
145
        self.run_bzr_error(['No WorkingTree exists for'],
 
146
            'branch --switch ../a ../b', working_dir='current')
 
147
        a = branch.Branch.open('a')
 
148
        b = branch.Branch.open('b')
 
149
        self.assertEqual(a.last_revision(), b.last_revision())
 
150
        work = branch.Branch.open('current')
 
151
        self.assertEqual(work.last_revision(), _mod_revision.NULL_REVISION)
 
152
 
 
153
    def test_branch_switch_no_checkout(self):
 
154
        # Standalone branch in the current directory:
 
155
        #  => new branch will be created, but switch fails and the current
 
156
        #     branch is unmodified
 
157
        self.example_branch('a')
 
158
        tree = self.make_branch_and_tree('current')
 
159
        c1 = tree.commit('some diverged change')
 
160
        self.run_bzr_error(['Cannot switch a branch, only a checkout'],
 
161
            'branch --switch ../a ../b', working_dir='current')
 
162
        a = branch.Branch.open('a')
 
163
        b = branch.Branch.open('b')
 
164
        self.assertEqual(a.last_revision(), b.last_revision())
 
165
        work = branch.Branch.open('current')
 
166
        self.assertEqual(work.last_revision(), c1)
 
167
 
 
168
    def test_branch_into_empty_dir(self):
 
169
        t = self.example_branch('source')
 
170
        self.make_bzrdir('target')
 
171
        self.run_bzr("branch source target")
 
172
        self.assertEquals(2, len(t.branch.repository.all_revision_ids()))
 
173
 
 
174
    def test_branch_switch_checkout(self):
 
175
        # Checkout in the current directory:
 
176
        #  => new branch will be created and checkout bound to the new branch
 
177
        self.example_branch('a')
 
178
        self.run_bzr('checkout a current')
 
179
        out, err = self.run_bzr('branch --switch ../a ../b',
 
180
                                working_dir='current')
 
181
        a = branch.Branch.open('a')
 
182
        b = branch.Branch.open('b')
 
183
        self.assertEqual(a.last_revision(), b.last_revision())
 
184
        work = WorkingTree.open('current')
 
185
        self.assertEndsWith(work.branch.get_bound_location(), '/b/')
 
186
        self.assertContainsRe(err, "Switched to branch: .*/b/")
 
187
 
 
188
    def test_branch_switch_lightweight_checkout(self):
 
189
        # Lightweight checkout in the current directory:
 
190
        #  => new branch will be created and lightweight checkout pointed to
 
191
        #     the new branch
 
192
        self.example_branch('a')
 
193
        self.run_bzr('checkout --lightweight a current')
 
194
        out, err = self.run_bzr('branch --switch ../a ../b',
 
195
                                working_dir='current')
 
196
        a = branch.Branch.open('a')
 
197
        b = branch.Branch.open('b')
 
198
        self.assertEqual(a.last_revision(), b.last_revision())
 
199
        work = WorkingTree.open('current')
 
200
        self.assertEndsWith(work.branch.base, '/b/')
 
201
        self.assertContainsRe(err, "Switched to branch: .*/b/")
 
202
 
52
203
    def test_branch_only_copies_history(self):
53
204
        # Knit branches should only push the history for the current revision.
54
205
        format = bzrdir.BzrDirMetaFormat1()
58
209
 
59
210
        def make_shared_tree(path):
60
211
            shared_repo.bzrdir.root_transport.mkdir(path)
61
 
            shared_repo.bzrdir.create_branch_convenience('repo/' + path)
 
212
            controldir.ControlDir.create_branch_convenience('repo/' + path)
62
213
            return WorkingTree.open('repo/' + path)
63
214
        tree_a = make_shared_tree('a')
64
215
        self.build_tree(['repo/a/file'])
93
244
        self.build_tree(['source/file1'])
94
245
        source.add('file1')
95
246
        source.commit('added file')
96
 
        self.run_bzr(['branch', 'source', 'target', '--hardlink'])
 
247
        out, err = self.run_bzr(['branch', 'source', 'target', '--hardlink'])
97
248
        source_stat = os.stat('source/file1')
98
249
        target_stat = os.stat('target/file1')
99
250
        self.assertEqual(source_stat, target_stat)
100
251
 
 
252
    def test_branch_files_from(self):
 
253
        source = self.make_branch_and_tree('source')
 
254
        self.build_tree(['source/file1'])
 
255
        source.add('file1')
 
256
        source.commit('added file')
 
257
        out, err = self.run_bzr('branch source target --files-from source')
 
258
        self.assertPathExists('target/file1')
 
259
 
 
260
    def test_branch_files_from_hardlink(self):
 
261
        self.requireFeature(HardlinkFeature)
 
262
        source = self.make_branch_and_tree('source')
 
263
        self.build_tree(['source/file1'])
 
264
        source.add('file1')
 
265
        source.commit('added file')
 
266
        source.bzrdir.sprout('second')
 
267
        out, err = self.run_bzr('branch source target --files-from second'
 
268
                                ' --hardlink')
 
269
        source_stat = os.stat('source/file1')
 
270
        second_stat = os.stat('second/file1')
 
271
        target_stat = os.stat('target/file1')
 
272
        self.assertNotEqual(source_stat, target_stat)
 
273
        self.assertEqual(second_stat, target_stat)
 
274
 
101
275
    def test_branch_standalone(self):
102
276
        shared_repo = self.make_repository('repo', shared=True)
103
277
        self.example_branch('source')
110
284
    def test_branch_no_tree(self):
111
285
        self.example_branch('source')
112
286
        self.run_bzr('branch --no-tree source target')
113
 
        self.failIfExists('target/hello')
114
 
        self.failIfExists('target/goodbye')
115
 
 
116
 
 
117
 
class TestBranchStacked(ExternalBase):
 
287
        self.assertPathDoesNotExist('target/hello')
 
288
        self.assertPathDoesNotExist('target/goodbye')
 
289
 
 
290
    def test_branch_into_existing_dir(self):
 
291
        self.example_branch('a')
 
292
        # existing dir with similar files but no .bzr dir
 
293
        self.build_tree_contents([('b/',)])
 
294
        self.build_tree_contents([('b/hello', 'bar')])  # different content
 
295
        self.build_tree_contents([('b/goodbye', 'baz')])# same content
 
296
        # fails without --use-existing-dir
 
297
        out,err = self.run_bzr('branch a b', retcode=3)
 
298
        self.assertEqual('', out)
 
299
        self.assertEqual('bzr: ERROR: Target directory "b" already exists.\n',
 
300
            err)
 
301
        # force operation
 
302
        self.run_bzr('branch a b --use-existing-dir')
 
303
        # check conflicts
 
304
        self.assertPathExists('b/hello.moved')
 
305
        self.assertPathDoesNotExist('b/godbye.moved')
 
306
        # we can't branch into branch
 
307
        out,err = self.run_bzr('branch a b --use-existing-dir', retcode=3)
 
308
        self.assertEqual('', out)
 
309
        self.assertEqual('bzr: ERROR: Already a branch: "b".\n', err)
 
310
 
 
311
    def test_branch_bind(self):
 
312
        self.example_branch('a')
 
313
        out, err = self.run_bzr('branch a b --bind')
 
314
        self.assertEndsWith(err, "New branch bound to a\n")
 
315
        b = branch.Branch.open('b')
 
316
        self.assertEndsWith(b.get_bound_location(), '/a/')
 
317
 
 
318
    def test_branch_with_post_branch_init_hook(self):
 
319
        calls = []
 
320
        branch.Branch.hooks.install_named_hook('post_branch_init',
 
321
            calls.append, None)
 
322
        self.assertLength(0, calls)
 
323
        self.example_branch('a')
 
324
        self.assertLength(1, calls)
 
325
        self.run_bzr('branch a b')
 
326
        self.assertLength(2, calls)
 
327
 
 
328
    def test_checkout_with_post_branch_init_hook(self):
 
329
        calls = []
 
330
        branch.Branch.hooks.install_named_hook('post_branch_init',
 
331
            calls.append, None)
 
332
        self.assertLength(0, calls)
 
333
        self.example_branch('a')
 
334
        self.assertLength(1, calls)
 
335
        self.run_bzr('checkout a b')
 
336
        self.assertLength(2, calls)
 
337
 
 
338
    def test_lightweight_checkout_with_post_branch_init_hook(self):
 
339
        calls = []
 
340
        branch.Branch.hooks.install_named_hook('post_branch_init',
 
341
            calls.append, None)
 
342
        self.assertLength(0, calls)
 
343
        self.example_branch('a')
 
344
        self.assertLength(1, calls)
 
345
        self.run_bzr('checkout --lightweight a b')
 
346
        self.assertLength(2, calls)
 
347
 
 
348
    def test_branch_fetches_all_tags(self):
 
349
        builder = self.make_branch_builder('source')
 
350
        source = fixtures.build_branch_with_non_ancestral_rev(builder)
 
351
        source.tags.set_tag('tag-a', 'rev-2')
 
352
        source.get_config_stack().set('branch.fetch_tags', True)
 
353
        # Now source has a tag not in its ancestry.  Make a branch from it.
 
354
        self.run_bzr('branch source new-branch')
 
355
        new_branch = branch.Branch.open('new-branch')
 
356
        # The tag is present, and so is its revision.
 
357
        self.assertEqual('rev-2', new_branch.tags.lookup_tag('tag-a'))
 
358
        new_branch.repository.get_revision('rev-2')
 
359
 
 
360
 
 
361
class TestBranchStacked(tests.TestCaseWithTransport):
118
362
    """Tests for branch --stacked"""
119
363
 
120
 
    def check_shallow_branch(self, branch_revid, stacked_on):
121
 
        """Assert that the branch 'newbranch' has been published correctly.
122
 
 
123
 
        :param stacked_on: url of a branch this one is stacked upon.
124
 
        :param branch_revid: a revision id that should be the only
125
 
            revision present in the stacked branch, and it should not be in
126
 
            the reference branch.
127
 
        """
128
 
        new_branch = branch.Branch.open('newbranch')
129
 
        # The branch refers to the mainline
130
 
        self.assertEqual(stacked_on, new_branch.get_stacked_on_url())
131
 
        # and the branch's work was pushed
132
 
        self.assertTrue(new_branch.repository.has_revision(branch_revid))
133
 
        # The newly committed revision shoud be present in the stacked branch,
134
 
        # but not in the stacked-on branch.  Because stacking is set up by the
135
 
        # branch object, if we open the stacked branch's repository directly,
136
 
        # bypassing the branch, we see only what's in the stacked repository.
137
 
        stacked_repo = bzrdir.BzrDir.open('newbranch').open_repository()
138
 
        stacked_repo_revisions = set(stacked_repo.all_revision_ids())
139
 
        if len(stacked_repo_revisions) != 1:
140
 
            self.fail("wrong revisions in stacked repository: %r"
141
 
                % (stacked_repo_revisions,))
142
 
 
143
364
    def assertRevisionInRepository(self, repo_path, revid):
144
 
        """Check that a revision is in a repository, disregarding stacking."""
145
 
        repo = bzrdir.BzrDir.open(repo_path).open_repository()
 
365
        """Check that a revision is in a repo, disregarding stacking."""
 
366
        repo = controldir.ControlDir.open(repo_path).open_repository()
146
367
        self.assertTrue(repo.has_revision(revid))
147
368
 
148
369
    def assertRevisionNotInRepository(self, repo_path, revid):
149
 
        """Check that a revision is not in a repository, disregarding stacking."""
150
 
        repo = bzrdir.BzrDir.open(repo_path).open_repository()
 
370
        """Check that a revision is not in a repo, disregarding stacking."""
 
371
        repo = controldir.ControlDir.open(repo_path).open_repository()
151
372
        self.assertFalse(repo.has_revision(revid))
152
373
 
153
374
    def assertRevisionsInBranchRepository(self, revid_list, branch_path):
166
387
            format='1.9')
167
388
        branch_tree.branch.set_stacked_on_url(trunk_tree.branch.base)
168
389
        # with some work on it
169
 
        branch_tree.commit('moar work plz')
 
390
        work_tree = trunk_tree.branch.bzrdir.sprout('local').open_workingtree()
 
391
        work_tree.commit('moar work plz')
 
392
        work_tree.branch.push(branch_tree.branch)
170
393
        # branching our local branch gives us a new stacked branch pointing at
171
394
        # mainline.
172
395
        out, err = self.run_bzr(['branch', 'branch', 'newbranch'])
173
396
        self.assertEqual('', out)
174
 
        self.assertEqual('Branched 1 revision(s).\n',
 
397
        self.assertEqual('Branched 2 revisions.\n',
175
398
            err)
176
399
        # it should have preserved the branch format, and so it should be
177
400
        # capable of supporting stacking, but not actually have a stacked_on
178
401
        # branch configured
179
402
        self.assertRaises(errors.NotStacked,
180
 
            bzrdir.BzrDir.open('newbranch').open_branch().get_stacked_on_url)
 
403
            controldir.ControlDir.open('newbranch').open_branch().get_stacked_on_url)
181
404
 
182
405
    def test_branch_stacked_branch_stacked(self):
183
406
        """Asking to stack on a stacked branch does work"""
190
413
            format='1.9')
191
414
        branch_tree.branch.set_stacked_on_url(trunk_tree.branch.base)
192
415
        # with some work on it
193
 
        branch_revid = branch_tree.commit('moar work plz')
 
416
        work_tree = trunk_tree.branch.bzrdir.sprout('local').open_workingtree()
 
417
        branch_revid = work_tree.commit('moar work plz')
 
418
        work_tree.branch.push(branch_tree.branch)
194
419
        # you can chain branches on from there
195
420
        out, err = self.run_bzr(['branch', 'branch', '--stacked', 'branch2'])
196
421
        self.assertEqual('', out)
199
424
        self.assertEqual(branch_tree.branch.base,
200
425
            branch.Branch.open('branch2').get_stacked_on_url())
201
426
        branch2_tree = WorkingTree.open('branch2')
202
 
        branch2_revid = branch2_tree.commit('work on second stacked branch')
 
427
        branch2_revid = work_tree.commit('work on second stacked branch')
 
428
        work_tree.branch.push(branch2_tree.branch)
203
429
        self.assertRevisionInRepository('branch2', branch2_revid)
204
430
        self.assertRevisionsInBranchRepository(
205
431
            [trunk_revid, branch_revid, branch2_revid],
218
444
        self.assertEqual('Created new stacked branch referring to %s.\n' %
219
445
            trunk_tree.branch.base, err)
220
446
        self.assertRevisionNotInRepository('newbranch', original_revid)
221
 
        new_tree = WorkingTree.open('newbranch')
222
 
        new_revid = new_tree.commit('new work')
223
 
        self.check_shallow_branch(new_revid, trunk_tree.branch.base)
 
447
        new_branch = branch.Branch.open('newbranch')
 
448
        self.assertEqual(trunk_tree.branch.base,
 
449
                         new_branch.get_stacked_on_url())
224
450
 
225
451
    def test_branch_stacked_from_smart_server(self):
226
452
        # We can branch stacking on a smart server
227
 
        from bzrlib.smart.server import SmartTCPServer_for_testing
228
 
        self.transport_server = SmartTCPServer_for_testing
 
453
        self.transport_server = test_server.SmartTCPServer_for_testing
229
454
        trunk = self.make_branch('mainline', format='1.9')
230
455
        out, err = self.run_bzr(
231
456
            ['branch', '--stacked', self.get_url('mainline'), 'shallow'])
237
462
            ['branch', '--stacked', 'trunk', 'shallow'])
238
463
        # We should notify the user that we upgraded their format
239
464
        self.assertEqualDiff(
240
 
            'Source format does not support stacking, using format: \'1.6\'\n'
 
465
            'Source repository format does not support stacking, using format:\n'
241
466
            '  Packs 5 (adds stacking support, requires bzr 1.6)\n'
242
 
            '\n'
 
467
            'Source branch format does not support stacking, using format:\n'
 
468
            '  Branch format 7\n'
 
469
            'Doing on-the-fly conversion from RepositoryFormatKnitPack1() to RepositoryFormatKnitPack5().\n'
 
470
            'This may take some time. Upgrade the repositories to the same format for better performance.\n'
243
471
            'Created new stacked branch referring to %s.\n' % (trunk.base,),
244
472
            err)
245
473
 
249
477
            ['branch', '--stacked', 'trunk', 'shallow'])
250
478
        # We should notify the user that we upgraded their format
251
479
        self.assertEqualDiff(
252
 
            'Source format does not support stacking, using format:'
253
 
            ' \'1.6.1-rich-root\'\n'
 
480
            'Source repository format does not support stacking, using format:\n'
254
481
            '  Packs 5 rich-root (adds stacking support, requires bzr 1.6.1)\n'
255
 
            '\n'
 
482
            'Source branch format does not support stacking, using format:\n'
 
483
            '  Branch format 7\n'
 
484
            'Doing on-the-fly conversion from RepositoryFormatKnitPack4() to RepositoryFormatKnitPack5RichRoot().\n'
 
485
            'This may take some time. Upgrade the repositories to the same format for better performance.\n'
256
486
            'Created new stacked branch referring to %s.\n' % (trunk.base,),
257
487
            err)
258
488
 
259
489
 
260
 
class TestSmartServerBranching(ExternalBase):
 
490
class TestSmartServerBranching(tests.TestCaseWithTransport):
261
491
 
262
492
    def test_branch_from_trivial_branch_to_same_server_branch_acceptance(self):
263
493
        self.setup_smart_server_with_call_log()
272
502
        # being too low. If rpc_count increases, more network roundtrips have
273
503
        # become necessary for this use case. Please do not adjust this number
274
504
        # upwards without agreement from bzr's network support maintainers.
275
 
        self.assertLength(39, self.hpss_calls)
 
505
        self.assertLength(2, self.hpss_connections)
 
506
        self.assertLength(33, self.hpss_calls)
 
507
        self.expectFailure("branching to the same branch requires VFS access",
 
508
            self.assertThat, self.hpss_calls, ContainsNoVfsCalls)
276
509
 
277
510
    def test_branch_from_trivial_branch_streaming_acceptance(self):
278
511
        self.setup_smart_server_with_call_log()
287
520
        # being too low. If rpc_count increases, more network roundtrips have
288
521
        # become necessary for this use case. Please do not adjust this number
289
522
        # upwards without agreement from bzr's network support maintainers.
 
523
        self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
290
524
        self.assertLength(10, self.hpss_calls)
 
525
        self.assertLength(1, self.hpss_connections)
291
526
 
292
527
    def test_branch_from_trivial_stacked_branch_streaming_acceptance(self):
293
528
        self.setup_smart_server_with_call_log()
296
531
            t.commit(message='commit %d' % count)
297
532
        tree2 = t.branch.bzrdir.sprout('feature', stacked=True
298
533
            ).open_workingtree()
299
 
        tree2.commit('feature change')
 
534
        local_tree = t.branch.bzrdir.sprout('local-working').open_workingtree()
 
535
        local_tree.commit('feature change')
 
536
        local_tree.branch.push(tree2.branch)
300
537
        self.reset_smart_call_log()
301
538
        out, err = self.run_bzr(['branch', self.get_url('feature'),
302
539
            'local-target'])
306
543
        # become necessary for this use case. Please do not adjust this number
307
544
        # upwards without agreement from bzr's network support maintainers.
308
545
        self.assertLength(15, self.hpss_calls)
 
546
        self.assertLength(1, self.hpss_connections)
 
547
        self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
 
548
 
 
549
    def test_branch_from_branch_with_tags(self):
 
550
        self.setup_smart_server_with_call_log()
 
551
        builder = self.make_branch_builder('source')
 
552
        source = fixtures.build_branch_with_non_ancestral_rev(builder)
 
553
        source.get_config_stack().set('branch.fetch_tags', True)
 
554
        source.tags.set_tag('tag-a', 'rev-2')
 
555
        source.tags.set_tag('tag-missing', 'missing-rev')
 
556
        # Now source has a tag not in its ancestry.  Make a branch from it.
 
557
        self.reset_smart_call_log()
 
558
        out, err = self.run_bzr(['branch', self.get_url('source'), 'target'])
 
559
        # This figure represent the amount of work to perform this use case. It
 
560
        # is entirely ok to reduce this number if a test fails due to rpc_count
 
561
        # being too low. If rpc_count increases, more network roundtrips have
 
562
        # become necessary for this use case. Please do not adjust this number
 
563
        # upwards without agreement from bzr's network support maintainers.
 
564
        self.assertLength(10, self.hpss_calls)
 
565
        self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
 
566
        self.assertLength(1, self.hpss_connections)
 
567
 
 
568
    def test_branch_to_stacked_from_trivial_branch_streaming_acceptance(self):
 
569
        self.setup_smart_server_with_call_log()
 
570
        t = self.make_branch_and_tree('from')
 
571
        for count in range(9):
 
572
            t.commit(message='commit %d' % count)
 
573
        self.reset_smart_call_log()
 
574
        out, err = self.run_bzr(['branch', '--stacked', self.get_url('from'),
 
575
            'local-target'])
 
576
        # XXX: the number of hpss calls for this case isn't deterministic yet,
 
577
        # so we can't easily assert about the number of calls.
 
578
        #self.assertLength(XXX, self.hpss_calls)
 
579
        # We can assert that none of the calls were readv requests for rix
 
580
        # files, though (demonstrating that at least get_parent_map calls are
 
581
        # not using VFS RPCs).
 
582
        readvs_of_rix_files = [
 
583
            c for c in self.hpss_calls
 
584
            if c.call.method == 'readv' and c.call.args[-1].endswith('.rix')]
 
585
        self.assertLength(1, self.hpss_connections)
 
586
        self.assertLength(0, readvs_of_rix_files)
 
587
        self.expectFailure("branching to stacked requires VFS access",
 
588
            self.assertThat, self.hpss_calls, ContainsNoVfsCalls)
309
589
 
310
590
 
311
591
class TestRemoteBranch(TestCaseWithSFTPServer):
331
611
        # Ensure that no working tree what created remotely
332
612
        self.assertFalse(t.has('remote/file'))
333
613
 
 
614
 
 
615
class TestDeprecatedAliases(tests.TestCaseWithTransport):
 
616
 
 
617
    def test_deprecated_aliases(self):
 
618
        """bzr branch can be called clone or get, but those names are
 
619
        deprecated.
 
620
 
 
621
        See bug 506265.
 
622
        """
 
623
        for command in ['clone', 'get']:
 
624
            run_script(self, """
 
625
            $ bzr %(command)s A B
 
626
            2>The command 'bzr %(command)s' has been deprecated in bzr 2.4. Please use 'bzr branch' instead.
 
627
            2>bzr: ERROR: Not a branch...
 
628
            """ % locals())
 
629
 
 
630
 
 
631
class TestBranchParentLocation(test_switch.TestSwitchParentLocationBase):
 
632
 
 
633
    def _checkout_and_branch(self, option=''):
 
634
        self.script_runner.run_script(self, '''
 
635
                $ bzr checkout %(option)s repo/trunk checkout
 
636
                $ cd checkout
 
637
                $ bzr branch --switch ../repo/trunk ../repo/branched
 
638
                2>Branched 0 revisions.
 
639
                2>Tree is up to date at revision 0.
 
640
                2>Switched to branch:...branched...
 
641
                $ cd ..
 
642
                ''' % locals())
 
643
        bound_branch = branch.Branch.open_containing('checkout')[0]
 
644
        master_branch = branch.Branch.open_containing('repo/branched')[0]
 
645
        return (bound_branch, master_branch)
 
646
 
 
647
    def test_branch_switch_parent_lightweight(self):
 
648
        """Lightweight checkout using bzr branch --switch."""
 
649
        bb, mb = self._checkout_and_branch(option='--lightweight')
 
650
        self.assertParent('repo/trunk', bb)
 
651
        self.assertParent('repo/trunk', mb)
 
652
 
 
653
    def test_branch_switch_parent_heavyweight(self):
 
654
        """Heavyweight checkout using bzr branch --switch."""
 
655
        bb, mb = self._checkout_and_branch()
 
656
        self.assertParent('repo/trunk', bb)
 
657
        self.assertParent('repo/trunk', mb)