~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: 2011-09-22 14:12:18 UTC
  • mfrom: (6155.3.1 jam)
  • Revision ID: pqm@pqm.ubuntu.com-20110922141218-86s4uu6nqvourw4f
(jameinel) Cleanup comments bzrlib/smart/__init__.py (John A Meinel)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005,2006 by Canonical Ltd
 
1
# Copyright (C) 2006-2011 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
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
 
18
18
"""Black-box tests for bzr branch."""
19
19
 
20
20
import os
21
21
 
22
 
import bzrlib.branch
23
 
import bzrlib.bzrdir
24
 
from bzrlib.repository import RepositoryFormatKnit1
25
 
from bzrlib.tests.blackbox import ExternalBase
 
22
from bzrlib import (
 
23
    branch,
 
24
    bzrdir,
 
25
    errors,
 
26
    revision as _mod_revision,
 
27
    )
 
28
from bzrlib.repofmt.knitrepo import RepositoryFormatKnit1
 
29
from bzrlib.tests import TestCaseWithTransport
 
30
from bzrlib.tests import (
 
31
    fixtures,
 
32
    script,
 
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.test_sftp_transport import TestCaseWithSFTPServer
 
40
from bzrlib.tests.script import run_script
 
41
from bzrlib.urlutils import local_path_to_url, strip_trailing_slash
26
42
from bzrlib.workingtree import WorkingTree
27
43
 
28
44
 
29
 
class TestBranch(ExternalBase):
 
45
class TestBranch(TestCaseWithTransport):
30
46
 
31
 
    def example_branch(test):
32
 
        test.runbzr('init')
33
 
        file('hello', 'wt').write('foo')
34
 
        test.runbzr('add hello')
35
 
        test.runbzr('commit -m setup hello')
36
 
        file('goodbye', 'wt').write('baz')
37
 
        test.runbzr('add goodbye')
38
 
        test.runbzr('commit -m setup goodbye')
 
47
    def example_branch(self, path='.'):
 
48
        tree = self.make_branch_and_tree(path)
 
49
        self.build_tree_contents([(path + '/hello', 'foo')])
 
50
        tree.add('hello')
 
51
        tree.commit(message='setup')
 
52
        self.build_tree_contents([(path + '/goodbye', 'baz')])
 
53
        tree.add('goodbye')
 
54
        tree.commit(message='setup')
39
55
 
40
56
    def test_branch(self):
41
57
        """Branch from one branch to another."""
42
 
        os.mkdir('a')
43
 
        os.chdir('a')
44
 
        self.example_branch()
45
 
        os.chdir('..')
46
 
        self.runbzr('branch a b')
47
 
        b = bzrlib.branch.Branch.open('b')
48
 
        self.assertEqual('b\n', b.control_files.get_utf8('branch-name').read())
49
 
        self.runbzr('branch a c -r 1')
50
 
        os.chdir('b')
51
 
        self.runbzr('commit -m foo --unchanged')
52
 
        os.chdir('..')
53
 
 
54
 
    def test_branch_basis(self):
55
 
        # ensure that basis really does grab from the basis by having incomplete source
56
 
        tree = self.make_branch_and_tree('commit_tree')
57
 
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
58
 
        tree.add('foo')
59
 
        tree.commit('revision 1', rev_id='1')
60
 
        source = self.make_branch_and_tree('source')
61
 
        # this gives us an incomplete repository
62
 
        tree.bzrdir.open_repository().copy_content_into(source.branch.repository)
63
 
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
64
 
        tree.bzrdir.open_branch().copy_content_into(source.branch)
65
 
        tree.copy_content_into(source)
66
 
        self.assertFalse(source.branch.repository.has_revision('2'))
67
 
        dir = source.bzrdir
68
 
        self.runbzr('branch source target --basis commit_tree')
69
 
        target = bzrlib.bzrdir.BzrDir.open('target')
70
 
        self.assertEqual('2', target.open_branch().last_revision())
71
 
        self.assertEqual('2', target.open_workingtree().last_revision())
72
 
        self.assertTrue(target.open_branch().repository.has_revision('2'))
 
58
        self.example_branch('a')
 
59
        self.run_bzr('branch a b')
 
60
        b = branch.Branch.open('b')
 
61
        self.run_bzr('branch a c -r 1')
 
62
        # previously was erroneously created by branching
 
63
        self.assertFalse(b._transport.has('branch-name'))
 
64
        b.bzrdir.open_workingtree().commit(message='foo', allow_pointless=True)
 
65
 
 
66
    def test_branch_broken_pack(self):
 
67
        """branching with a corrupted pack file."""
 
68
        self.example_branch('a')
 
69
        #now add some random corruption
 
70
        fname = 'a/.bzr/repository/packs/' + os.listdir('a/.bzr/repository/packs')[0]
 
71
        with open(fname, 'rb+') as f:
 
72
            f.seek(750)
 
73
            f.write("\xff")
 
74
        self.run_bzr_error(['Corruption while decompressing repository file'], 
 
75
                            'branch a b', retcode=3)
 
76
 
 
77
    def test_branch_switch_no_branch(self):
 
78
        # No branch in the current directory:
 
79
        #  => new branch will be created, but switch fails
 
80
        self.example_branch('a')
 
81
        self.make_repository('current')
 
82
        self.run_bzr_error(['No WorkingTree exists for'],
 
83
            'branch --switch ../a ../b', working_dir='current')
 
84
        a = branch.Branch.open('a')
 
85
        b = branch.Branch.open('b')
 
86
        self.assertEqual(a.last_revision(), b.last_revision())
 
87
 
 
88
    def test_branch_switch_no_wt(self):
 
89
        # No working tree in the current directory:
 
90
        #  => new branch will be created, but switch fails and the current
 
91
        #     branch is unmodified
 
92
        self.example_branch('a')
 
93
        self.make_branch('current')
 
94
        self.run_bzr_error(['No WorkingTree exists for'],
 
95
            'branch --switch ../a ../b', working_dir='current')
 
96
        a = branch.Branch.open('a')
 
97
        b = branch.Branch.open('b')
 
98
        self.assertEqual(a.last_revision(), b.last_revision())
 
99
        work = branch.Branch.open('current')
 
100
        self.assertEqual(work.last_revision(), _mod_revision.NULL_REVISION)
 
101
 
 
102
    def test_branch_switch_no_checkout(self):
 
103
        # Standalone branch in the current directory:
 
104
        #  => new branch will be created, but switch fails and the current
 
105
        #     branch is unmodified
 
106
        self.example_branch('a')
 
107
        self.make_branch_and_tree('current')
 
108
        self.run_bzr_error(['Cannot switch a branch, only a checkout'],
 
109
            'branch --switch ../a ../b', working_dir='current')
 
110
        a = branch.Branch.open('a')
 
111
        b = branch.Branch.open('b')
 
112
        self.assertEqual(a.last_revision(), b.last_revision())
 
113
        work = branch.Branch.open('current')
 
114
        self.assertEqual(work.last_revision(), _mod_revision.NULL_REVISION)
 
115
 
 
116
    def test_branch_switch_checkout(self):
 
117
        # Checkout in the current directory:
 
118
        #  => new branch will be created and checkout bound to the new branch
 
119
        self.example_branch('a')
 
120
        self.run_bzr('checkout a current')
 
121
        out, err = self.run_bzr('branch --switch ../a ../b', working_dir='current')
 
122
        a = branch.Branch.open('a')
 
123
        b = branch.Branch.open('b')
 
124
        self.assertEqual(a.last_revision(), b.last_revision())
 
125
        work = WorkingTree.open('current')
 
126
        self.assertEndsWith(work.branch.get_bound_location(), '/b/')
 
127
        self.assertContainsRe(err, "Switched to branch: .*/b/")
 
128
 
 
129
    def test_branch_switch_lightweight_checkout(self):
 
130
        # Lightweight checkout in the current directory:
 
131
        #  => new branch will be created and lightweight checkout pointed to
 
132
        #     the new branch
 
133
        self.example_branch('a')
 
134
        self.run_bzr('checkout --lightweight a current')
 
135
        out, err = self.run_bzr('branch --switch ../a ../b', working_dir='current')
 
136
        a = branch.Branch.open('a')
 
137
        b = branch.Branch.open('b')
 
138
        self.assertEqual(a.last_revision(), b.last_revision())
 
139
        work = WorkingTree.open('current')
 
140
        self.assertEndsWith(work.branch.base, '/b/')
 
141
        self.assertContainsRe(err, "Switched to branch: .*/b/")
73
142
 
74
143
    def test_branch_only_copies_history(self):
75
144
        # Knit branches should only push the history for the current revision.
76
 
        format = bzrlib.bzrdir.BzrDirMetaFormat1()
 
145
        format = bzrdir.BzrDirMetaFormat1()
77
146
        format.repository_format = RepositoryFormatKnit1()
78
147
        shared_repo = self.make_repository('repo', format=format, shared=True)
79
148
        shared_repo.set_make_working_trees(True)
102
171
 
103
172
        # Now that we have a repository with shared files, make sure
104
173
        # that things aren't copied out by a 'branch'
105
 
        self.run_bzr('branch', 'repo/b', 'branch-b')
 
174
        self.run_bzr('branch repo/b branch-b')
106
175
        pushed_tree = WorkingTree.open('branch-b')
107
176
        pushed_repo = pushed_tree.branch.repository
108
177
        self.assertFalse(pushed_repo.has_revision('a-1'))
109
178
        self.assertFalse(pushed_repo.has_revision('a-2'))
110
179
        self.assertTrue(pushed_repo.has_revision('b-1'))
111
180
 
112
 
 
 
181
    def test_branch_hardlink(self):
 
182
        self.requireFeature(HardlinkFeature)
 
183
        source = self.make_branch_and_tree('source')
 
184
        self.build_tree(['source/file1'])
 
185
        source.add('file1')
 
186
        source.commit('added file')
 
187
        out, err = self.run_bzr(['branch', 'source', 'target', '--hardlink'])
 
188
        source_stat = os.stat('source/file1')
 
189
        target_stat = os.stat('target/file1')
 
190
        self.assertEqual(source_stat, target_stat)
 
191
 
 
192
    def test_branch_files_from(self):
 
193
        source = self.make_branch_and_tree('source')
 
194
        self.build_tree(['source/file1'])
 
195
        source.add('file1')
 
196
        source.commit('added file')
 
197
        out, err = self.run_bzr('branch source target --files-from source')
 
198
        self.assertPathExists('target/file1')
 
199
 
 
200
    def test_branch_files_from_hardlink(self):
 
201
        self.requireFeature(HardlinkFeature)
 
202
        source = self.make_branch_and_tree('source')
 
203
        self.build_tree(['source/file1'])
 
204
        source.add('file1')
 
205
        source.commit('added file')
 
206
        source.bzrdir.sprout('second')
 
207
        out, err = self.run_bzr('branch source target --files-from second'
 
208
                                ' --hardlink')
 
209
        source_stat = os.stat('source/file1')
 
210
        second_stat = os.stat('second/file1')
 
211
        target_stat = os.stat('target/file1')
 
212
        self.assertNotEqual(source_stat, target_stat)
 
213
        self.assertEqual(second_stat, target_stat)
 
214
 
 
215
    def test_branch_standalone(self):
 
216
        shared_repo = self.make_repository('repo', shared=True)
 
217
        self.example_branch('source')
 
218
        self.run_bzr('branch --standalone source repo/target')
 
219
        b = branch.Branch.open('repo/target')
 
220
        expected_repo_path = os.path.abspath('repo/target/.bzr/repository')
 
221
        self.assertEqual(strip_trailing_slash(b.repository.base),
 
222
            strip_trailing_slash(local_path_to_url(expected_repo_path)))
 
223
 
 
224
    def test_branch_no_tree(self):
 
225
        self.example_branch('source')
 
226
        self.run_bzr('branch --no-tree source target')
 
227
        self.assertPathDoesNotExist('target/hello')
 
228
        self.assertPathDoesNotExist('target/goodbye')
 
229
 
 
230
    def test_branch_into_existing_dir(self):
 
231
        self.example_branch('a')
 
232
        # existing dir with similar files but no .bzr dir
 
233
        self.build_tree_contents([('b/',)])
 
234
        self.build_tree_contents([('b/hello', 'bar')])  # different content
 
235
        self.build_tree_contents([('b/goodbye', 'baz')])# same content
 
236
        # fails without --use-existing-dir
 
237
        out,err = self.run_bzr('branch a b', retcode=3)
 
238
        self.assertEqual('', out)
 
239
        self.assertEqual('bzr: ERROR: Target directory "b" already exists.\n',
 
240
            err)
 
241
        # force operation
 
242
        self.run_bzr('branch a b --use-existing-dir')
 
243
        # check conflicts
 
244
        self.assertPathExists('b/hello.moved')
 
245
        self.assertPathDoesNotExist('b/godbye.moved')
 
246
        # we can't branch into branch
 
247
        out,err = self.run_bzr('branch a b --use-existing-dir', retcode=3)
 
248
        self.assertEqual('', out)
 
249
        self.assertEqual('bzr: ERROR: Already a branch: "b".\n', err)
 
250
 
 
251
    def test_branch_bind(self):
 
252
        self.example_branch('a')
 
253
        out, err = self.run_bzr('branch a b --bind')
 
254
        self.assertEndsWith(err, "New branch bound to a\n")
 
255
        b = branch.Branch.open('b')
 
256
        self.assertEndsWith(b.get_bound_location(), '/a/')
 
257
 
 
258
    def test_branch_with_post_branch_init_hook(self):
 
259
        calls = []
 
260
        branch.Branch.hooks.install_named_hook('post_branch_init',
 
261
            calls.append, None)
 
262
        self.assertLength(0, calls)
 
263
        self.example_branch('a')
 
264
        self.assertLength(1, calls)
 
265
        self.run_bzr('branch a b')
 
266
        self.assertLength(2, calls)
 
267
 
 
268
    def test_checkout_with_post_branch_init_hook(self):
 
269
        calls = []
 
270
        branch.Branch.hooks.install_named_hook('post_branch_init',
 
271
            calls.append, None)
 
272
        self.assertLength(0, calls)
 
273
        self.example_branch('a')
 
274
        self.assertLength(1, calls)
 
275
        self.run_bzr('checkout a b')
 
276
        self.assertLength(2, calls)
 
277
 
 
278
    def test_lightweight_checkout_with_post_branch_init_hook(self):
 
279
        calls = []
 
280
        branch.Branch.hooks.install_named_hook('post_branch_init',
 
281
            calls.append, None)
 
282
        self.assertLength(0, calls)
 
283
        self.example_branch('a')
 
284
        self.assertLength(1, calls)
 
285
        self.run_bzr('checkout --lightweight a b')
 
286
        self.assertLength(2, calls)
 
287
 
 
288
    def test_branch_fetches_all_tags(self):
 
289
        builder = self.make_branch_builder('source')
 
290
        source = fixtures.build_branch_with_non_ancestral_rev(builder)
 
291
        source.tags.set_tag('tag-a', 'rev-2')
 
292
        source.get_config().set_user_option('branch.fetch_tags', 'True')
 
293
        # Now source has a tag not in its ancestry.  Make a branch from it.
 
294
        self.run_bzr('branch source new-branch')
 
295
        new_branch = branch.Branch.open('new-branch')
 
296
        # The tag is present, and so is its revision.
 
297
        self.assertEqual('rev-2', new_branch.tags.lookup_tag('tag-a'))
 
298
        new_branch.repository.get_revision('rev-2')
 
299
 
 
300
 
 
301
class TestBranchStacked(TestCaseWithTransport):
 
302
    """Tests for branch --stacked"""
 
303
 
 
304
    def assertRevisionInRepository(self, repo_path, revid):
 
305
        """Check that a revision is in a repository, disregarding stacking."""
 
306
        repo = bzrdir.BzrDir.open(repo_path).open_repository()
 
307
        self.assertTrue(repo.has_revision(revid))
 
308
 
 
309
    def assertRevisionNotInRepository(self, repo_path, revid):
 
310
        """Check that a revision is not in a repository, disregarding stacking."""
 
311
        repo = bzrdir.BzrDir.open(repo_path).open_repository()
 
312
        self.assertFalse(repo.has_revision(revid))
 
313
 
 
314
    def assertRevisionsInBranchRepository(self, revid_list, branch_path):
 
315
        repo = branch.Branch.open(branch_path).repository
 
316
        self.assertEqual(set(revid_list),
 
317
            repo.has_revisions(revid_list))
 
318
 
 
319
    def test_branch_stacked_branch_not_stacked(self):
 
320
        """Branching a stacked branch is not stacked by default"""
 
321
        # We have a mainline
 
322
        trunk_tree = self.make_branch_and_tree('target',
 
323
            format='1.9')
 
324
        trunk_tree.commit('mainline')
 
325
        # and a branch from it which is stacked
 
326
        branch_tree = self.make_branch_and_tree('branch',
 
327
            format='1.9')
 
328
        branch_tree.branch.set_stacked_on_url(trunk_tree.branch.base)
 
329
        # with some work on it
 
330
        work_tree = trunk_tree.branch.bzrdir.sprout('local').open_workingtree()
 
331
        work_tree.commit('moar work plz')
 
332
        work_tree.branch.push(branch_tree.branch)
 
333
        # branching our local branch gives us a new stacked branch pointing at
 
334
        # mainline.
 
335
        out, err = self.run_bzr(['branch', 'branch', 'newbranch'])
 
336
        self.assertEqual('', out)
 
337
        self.assertEqual('Branched 2 revisions.\n',
 
338
            err)
 
339
        # it should have preserved the branch format, and so it should be
 
340
        # capable of supporting stacking, but not actually have a stacked_on
 
341
        # branch configured
 
342
        self.assertRaises(errors.NotStacked,
 
343
            bzrdir.BzrDir.open('newbranch').open_branch().get_stacked_on_url)
 
344
 
 
345
    def test_branch_stacked_branch_stacked(self):
 
346
        """Asking to stack on a stacked branch does work"""
 
347
        # We have a mainline
 
348
        trunk_tree = self.make_branch_and_tree('target',
 
349
            format='1.9')
 
350
        trunk_revid = trunk_tree.commit('mainline')
 
351
        # and a branch from it which is stacked
 
352
        branch_tree = self.make_branch_and_tree('branch',
 
353
            format='1.9')
 
354
        branch_tree.branch.set_stacked_on_url(trunk_tree.branch.base)
 
355
        # with some work on it
 
356
        work_tree = trunk_tree.branch.bzrdir.sprout('local').open_workingtree()
 
357
        branch_revid = work_tree.commit('moar work plz')
 
358
        work_tree.branch.push(branch_tree.branch)
 
359
        # you can chain branches on from there
 
360
        out, err = self.run_bzr(['branch', 'branch', '--stacked', 'branch2'])
 
361
        self.assertEqual('', out)
 
362
        self.assertEqual('Created new stacked branch referring to %s.\n' %
 
363
            branch_tree.branch.base, err)
 
364
        self.assertEqual(branch_tree.branch.base,
 
365
            branch.Branch.open('branch2').get_stacked_on_url())
 
366
        branch2_tree = WorkingTree.open('branch2')
 
367
        branch2_revid = work_tree.commit('work on second stacked branch')
 
368
        work_tree.branch.push(branch2_tree.branch)
 
369
        self.assertRevisionInRepository('branch2', branch2_revid)
 
370
        self.assertRevisionsInBranchRepository(
 
371
            [trunk_revid, branch_revid, branch2_revid],
 
372
            'branch2')
 
373
 
 
374
    def test_branch_stacked(self):
 
375
        # We have a mainline
 
376
        trunk_tree = self.make_branch_and_tree('mainline',
 
377
            format='1.9')
 
378
        original_revid = trunk_tree.commit('mainline')
 
379
        self.assertRevisionInRepository('mainline', original_revid)
 
380
        # and a branch from it which is stacked
 
381
        out, err = self.run_bzr(['branch', '--stacked', 'mainline',
 
382
            'newbranch'])
 
383
        self.assertEqual('', out)
 
384
        self.assertEqual('Created new stacked branch referring to %s.\n' %
 
385
            trunk_tree.branch.base, err)
 
386
        self.assertRevisionNotInRepository('newbranch', original_revid)
 
387
        new_branch = branch.Branch.open('newbranch')
 
388
        self.assertEqual(trunk_tree.branch.base, new_branch.get_stacked_on_url())
 
389
 
 
390
    def test_branch_stacked_from_smart_server(self):
 
391
        # We can branch stacking on a smart server
 
392
        self.transport_server = test_server.SmartTCPServer_for_testing
 
393
        trunk = self.make_branch('mainline', format='1.9')
 
394
        out, err = self.run_bzr(
 
395
            ['branch', '--stacked', self.get_url('mainline'), 'shallow'])
 
396
 
 
397
    def test_branch_stacked_from_non_stacked_format(self):
 
398
        """The origin format doesn't support stacking"""
 
399
        trunk = self.make_branch('trunk', format='pack-0.92')
 
400
        out, err = self.run_bzr(
 
401
            ['branch', '--stacked', 'trunk', 'shallow'])
 
402
        # We should notify the user that we upgraded their format
 
403
        self.assertEqualDiff(
 
404
            'Source repository format does not support stacking, using format:\n'
 
405
            '  Packs 5 (adds stacking support, requires bzr 1.6)\n'
 
406
            'Source branch format does not support stacking, using format:\n'
 
407
            '  Branch format 7\n'
 
408
            'Doing on-the-fly conversion from RepositoryFormatKnitPack1() to RepositoryFormatKnitPack5().\n'
 
409
            'This may take some time. Upgrade the repositories to the same format for better performance.\n'
 
410
            'Created new stacked branch referring to %s.\n' % (trunk.base,),
 
411
            err)
 
412
 
 
413
    def test_branch_stacked_from_rich_root_non_stackable(self):
 
414
        trunk = self.make_branch('trunk', format='rich-root-pack')
 
415
        out, err = self.run_bzr(
 
416
            ['branch', '--stacked', 'trunk', 'shallow'])
 
417
        # We should notify the user that we upgraded their format
 
418
        self.assertEqualDiff(
 
419
            'Source repository format does not support stacking, using format:\n'
 
420
            '  Packs 5 rich-root (adds stacking support, requires bzr 1.6.1)\n'
 
421
            'Source branch format does not support stacking, using format:\n'
 
422
            '  Branch format 7\n'
 
423
            'Doing on-the-fly conversion from RepositoryFormatKnitPack4() to RepositoryFormatKnitPack5RichRoot().\n'
 
424
            'This may take some time. Upgrade the repositories to the same format for better performance.\n'
 
425
            'Created new stacked branch referring to %s.\n' % (trunk.base,),
 
426
            err)
 
427
 
 
428
 
 
429
class TestSmartServerBranching(TestCaseWithTransport):
 
430
 
 
431
    def test_branch_from_trivial_branch_to_same_server_branch_acceptance(self):
 
432
        self.setup_smart_server_with_call_log()
 
433
        t = self.make_branch_and_tree('from')
 
434
        for count in range(9):
 
435
            t.commit(message='commit %d' % count)
 
436
        self.reset_smart_call_log()
 
437
        out, err = self.run_bzr(['branch', self.get_url('from'),
 
438
            self.get_url('target')])
 
439
        # This figure represent the amount of work to perform this use case. It
 
440
        # is entirely ok to reduce this number if a test fails due to rpc_count
 
441
        # being too low. If rpc_count increases, more network roundtrips have
 
442
        # become necessary for this use case. Please do not adjust this number
 
443
        # upwards without agreement from bzr's network support maintainers.
 
444
        self.assertLength(39, self.hpss_calls)
 
445
 
 
446
    def test_branch_from_trivial_branch_streaming_acceptance(self):
 
447
        self.setup_smart_server_with_call_log()
 
448
        t = self.make_branch_and_tree('from')
 
449
        for count in range(9):
 
450
            t.commit(message='commit %d' % count)
 
451
        self.reset_smart_call_log()
 
452
        out, err = self.run_bzr(['branch', self.get_url('from'),
 
453
            'local-target'])
 
454
        # This figure represent the amount of work to perform this use case. It
 
455
        # is entirely ok to reduce this number if a test fails due to rpc_count
 
456
        # being too low. If rpc_count increases, more network roundtrips have
 
457
        # become necessary for this use case. Please do not adjust this number
 
458
        # upwards without agreement from bzr's network support maintainers.
 
459
        self.assertLength(10, self.hpss_calls)
 
460
 
 
461
    def test_branch_from_trivial_stacked_branch_streaming_acceptance(self):
 
462
        self.setup_smart_server_with_call_log()
 
463
        t = self.make_branch_and_tree('trunk')
 
464
        for count in range(8):
 
465
            t.commit(message='commit %d' % count)
 
466
        tree2 = t.branch.bzrdir.sprout('feature', stacked=True
 
467
            ).open_workingtree()
 
468
        local_tree = t.branch.bzrdir.sprout('local-working').open_workingtree()
 
469
        local_tree.commit('feature change')
 
470
        local_tree.branch.push(tree2.branch)
 
471
        self.reset_smart_call_log()
 
472
        out, err = self.run_bzr(['branch', self.get_url('feature'),
 
473
            'local-target'])
 
474
        # This figure represent the amount of work to perform this use case. It
 
475
        # is entirely ok to reduce this number if a test fails due to rpc_count
 
476
        # being too low. If rpc_count increases, more network roundtrips have
 
477
        # become necessary for this use case. Please do not adjust this number
 
478
        # upwards without agreement from bzr's network support maintainers.
 
479
        self.assertLength(15, self.hpss_calls)
 
480
 
 
481
    def test_branch_from_branch_with_tags(self):
 
482
        self.setup_smart_server_with_call_log()
 
483
        builder = self.make_branch_builder('source')
 
484
        source = fixtures.build_branch_with_non_ancestral_rev(builder)
 
485
        source.get_config().set_user_option('branch.fetch_tags', 'True')
 
486
        source.tags.set_tag('tag-a', 'rev-2')
 
487
        source.tags.set_tag('tag-missing', 'missing-rev')
 
488
        # Now source has a tag not in its ancestry.  Make a branch from it.
 
489
        self.reset_smart_call_log()
 
490
        out, err = self.run_bzr(['branch', self.get_url('source'), 'target'])
 
491
        # This figure represent the amount of work to perform this use case. It
 
492
        # is entirely ok to reduce this number if a test fails due to rpc_count
 
493
        # being too low. If rpc_count increases, more network roundtrips have
 
494
        # become necessary for this use case. Please do not adjust this number
 
495
        # upwards without agreement from bzr's network support maintainers.
 
496
        self.assertLength(10, self.hpss_calls)
 
497
 
 
498
    def test_branch_to_stacked_from_trivial_branch_streaming_acceptance(self):
 
499
        self.setup_smart_server_with_call_log()
 
500
        t = self.make_branch_and_tree('from')
 
501
        for count in range(9):
 
502
            t.commit(message='commit %d' % count)
 
503
        self.reset_smart_call_log()
 
504
        out, err = self.run_bzr(['branch', '--stacked', self.get_url('from'),
 
505
            'local-target'])
 
506
        # XXX: the number of hpss calls for this case isn't deterministic yet,
 
507
        # so we can't easily assert about the number of calls.
 
508
        #self.assertLength(XXX, self.hpss_calls)
 
509
        # We can assert that none of the calls were readv requests for rix
 
510
        # files, though (demonstrating that at least get_parent_map calls are
 
511
        # not using VFS RPCs).
 
512
        readvs_of_rix_files = [
 
513
            c for c in self.hpss_calls
 
514
            if c.call.method == 'readv' and c.call.args[-1].endswith('.rix')]
 
515
        self.assertLength(0, readvs_of_rix_files)
 
516
 
 
517
 
 
518
class TestRemoteBranch(TestCaseWithSFTPServer):
 
519
 
 
520
    def setUp(self):
 
521
        super(TestRemoteBranch, self).setUp()
 
522
        tree = self.make_branch_and_tree('branch')
 
523
        self.build_tree_contents([('branch/file', 'file content\n')])
 
524
        tree.add('file')
 
525
        tree.commit('file created')
 
526
 
 
527
    def test_branch_local_remote(self):
 
528
        self.run_bzr(['branch', 'branch', self.get_url('remote')])
 
529
        t = self.get_transport()
 
530
        # Ensure that no working tree what created remotely
 
531
        self.assertFalse(t.has('remote/file'))
 
532
 
 
533
    def test_branch_remote_remote(self):
 
534
        # Light cheat: we access the branch remotely
 
535
        self.run_bzr(['branch', self.get_url('branch'),
 
536
                      self.get_url('remote')])
 
537
        t = self.get_transport()
 
538
        # Ensure that no working tree what created remotely
 
539
        self.assertFalse(t.has('remote/file'))
 
540
 
 
541
 
 
542
class TestDeprecatedAliases(TestCaseWithTransport):
 
543
 
 
544
    def test_deprecated_aliases(self):
 
545
        """bzr branch can be called clone or get, but those names are deprecated.
 
546
 
 
547
        See bug 506265.
 
548
        """
 
549
        for command in ['clone', 'get']:
 
550
            run_script(self, """
 
551
            $ bzr %(command)s A B
 
552
            2>The command 'bzr %(command)s' has been deprecated in bzr 2.4. Please use 'bzr branch' instead.
 
553
            2>bzr: ERROR: Not a branch...
 
554
            """ % locals())
 
555
 
 
556
 
 
557
class TestBranchParentLocation(test_switch.TestSwitchParentLocationBase):
 
558
 
 
559
    def _checkout_and_branch(self, option=''):
 
560
        self.script_runner.run_script(self, '''
 
561
                $ bzr checkout %(option)s repo/trunk checkout
 
562
                $ cd checkout
 
563
                $ bzr branch --switch ../repo/trunk ../repo/branched
 
564
                2>Branched 0 revisions.
 
565
                2>Tree is up to date at revision 0.
 
566
                2>Switched to branch:...branched...
 
567
                $ cd ..
 
568
                ''' % locals())
 
569
        bound_branch = branch.Branch.open_containing('checkout')[0]
 
570
        master_branch = branch.Branch.open_containing('repo/branched')[0]
 
571
        return (bound_branch, master_branch)
 
572
 
 
573
    def test_branch_switch_parent_lightweight(self):
 
574
        """Lightweight checkout using bzr branch --switch."""
 
575
        bb, mb = self._checkout_and_branch(option='--lightweight')
 
576
        self.assertParent('repo/trunk', bb)
 
577
        self.assertParent('repo/trunk', mb)
 
578
 
 
579
    def test_branch_switch_parent_heavyweight(self):
 
580
        """Heavyweight checkout using bzr branch --switch."""
 
581
        bb, mb = self._checkout_and_branch()
 
582
        self.assertParent('repo/trunk', bb)
 
583
        self.assertParent('repo/trunk', mb)