~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Tarmac
  • Author(s): Vincent Ladeuil
  • Date: 2017-01-30 14:42:05 UTC
  • mfrom: (6620.1.1 trunk)
  • Revision ID: tarmac-20170130144205-r8fh2xpmiuxyozpv
Merge  2.7 into trunk including fix for bug #1657238 [r=vila]

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2011 Canonical Ltd
 
1
# Copyright (C) 2006-2012, 2016 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
22
22
from bzrlib import (
23
23
    branch,
24
24
    bzrdir,
 
25
    controldir,
25
26
    errors,
26
27
    revision as _mod_revision,
 
28
    tests,
27
29
    )
28
30
from bzrlib.repofmt.knitrepo import RepositoryFormatKnit1
29
 
from bzrlib.tests import TestCaseWithTransport
30
31
from bzrlib.tests import (
31
32
    fixtures,
 
33
    test_server,
 
34
    )
 
35
from bzrlib.tests.features import (
32
36
    HardlinkFeature,
33
 
    script,
34
 
    test_server,
35
37
    )
36
38
from bzrlib.tests.blackbox import test_switch
 
39
from bzrlib.tests.matchers import ContainsNoVfsCalls
37
40
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
38
41
from bzrlib.tests.script import run_script
39
42
from bzrlib.urlutils import local_path_to_url, strip_trailing_slash
40
43
from bzrlib.workingtree import WorkingTree
41
44
 
42
45
 
43
 
class TestBranch(TestCaseWithTransport):
 
46
class TestBranch(tests.TestCaseWithTransport):
44
47
 
45
 
    def example_branch(self, path='.'):
46
 
        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)
47
50
        self.build_tree_contents([(path + '/hello', 'foo')])
48
51
        tree.add('hello')
49
52
        tree.commit(message='setup')
50
53
        self.build_tree_contents([(path + '/goodbye', 'baz')])
51
54
        tree.add('goodbye')
52
55
        tree.commit(message='setup')
 
56
        return tree
53
57
 
54
58
    def test_branch(self):
55
59
        """Branch from one branch to another."""
61
65
        self.assertFalse(b._transport.has('branch-name'))
62
66
        b.bzrdir.open_workingtree().commit(message='foo', allow_pointless=True)
63
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.assertEqual(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
 
64
107
    def test_branch_broken_pack(self):
65
108
        """branching with a corrupted pack file."""
66
109
        self.example_branch('a')
67
 
        #now add some random corruption
68
 
        fname = 'a/.bzr/repository/packs/' + os.listdir('a/.bzr/repository/packs')[0]
 
110
        # add some corruption
 
111
        packs_dir = 'a/.bzr/repository/packs/'
 
112
        fname = packs_dir + os.listdir(packs_dir)[0]
69
113
        with open(fname, 'rb+') as f:
70
 
            f.seek(750)
71
 
            f.write("\xff")
72
 
        self.run_bzr_error(['Corruption while decompressing repository file'], 
 
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'],
73
126
                            'branch a b', retcode=3)
74
127
 
75
128
    def test_branch_switch_no_branch(self):
102
155
        #  => new branch will be created, but switch fails and the current
103
156
        #     branch is unmodified
104
157
        self.example_branch('a')
105
 
        self.make_branch_and_tree('current')
 
158
        tree = self.make_branch_and_tree('current')
 
159
        c1 = tree.commit('some diverged change')
106
160
        self.run_bzr_error(['Cannot switch a branch, only a checkout'],
107
161
            'branch --switch ../a ../b', working_dir='current')
108
162
        a = branch.Branch.open('a')
109
163
        b = branch.Branch.open('b')
110
164
        self.assertEqual(a.last_revision(), b.last_revision())
111
165
        work = branch.Branch.open('current')
112
 
        self.assertEqual(work.last_revision(), _mod_revision.NULL_REVISION)
 
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.assertEqual(2, len(t.branch.repository.all_revision_ids()))
113
173
 
114
174
    def test_branch_switch_checkout(self):
115
175
        # Checkout in the current directory:
116
176
        #  => new branch will be created and checkout bound to the new branch
117
177
        self.example_branch('a')
118
178
        self.run_bzr('checkout a current')
119
 
        out, err = self.run_bzr('branch --switch ../a ../b', working_dir='current')
 
179
        out, err = self.run_bzr('branch --switch ../a ../b',
 
180
                                working_dir='current')
120
181
        a = branch.Branch.open('a')
121
182
        b = branch.Branch.open('b')
122
183
        self.assertEqual(a.last_revision(), b.last_revision())
130
191
        #     the new branch
131
192
        self.example_branch('a')
132
193
        self.run_bzr('checkout --lightweight a current')
133
 
        out, err = self.run_bzr('branch --switch ../a ../b', working_dir='current')
 
194
        out, err = self.run_bzr('branch --switch ../a ../b',
 
195
                                working_dir='current')
134
196
        a = branch.Branch.open('a')
135
197
        b = branch.Branch.open('b')
136
198
        self.assertEqual(a.last_revision(), b.last_revision())
147
209
 
148
210
        def make_shared_tree(path):
149
211
            shared_repo.bzrdir.root_transport.mkdir(path)
150
 
            shared_repo.bzrdir.create_branch_convenience('repo/' + path)
 
212
            controldir.ControlDir.create_branch_convenience('repo/' + path)
151
213
            return WorkingTree.open('repo/' + path)
152
214
        tree_a = make_shared_tree('a')
153
215
        self.build_tree(['repo/a/file'])
287
349
        builder = self.make_branch_builder('source')
288
350
        source = fixtures.build_branch_with_non_ancestral_rev(builder)
289
351
        source.tags.set_tag('tag-a', 'rev-2')
 
352
        source.get_config_stack().set('branch.fetch_tags', True)
290
353
        # Now source has a tag not in its ancestry.  Make a branch from it.
291
354
        self.run_bzr('branch source new-branch')
292
355
        new_branch = branch.Branch.open('new-branch')
295
358
        new_branch.repository.get_revision('rev-2')
296
359
 
297
360
 
298
 
class TestBranchStacked(TestCaseWithTransport):
 
361
class TestBranchStacked(tests.TestCaseWithTransport):
299
362
    """Tests for branch --stacked"""
300
363
 
301
364
    def assertRevisionInRepository(self, repo_path, revid):
302
 
        """Check that a revision is in a repository, disregarding stacking."""
303
 
        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()
304
367
        self.assertTrue(repo.has_revision(revid))
305
368
 
306
369
    def assertRevisionNotInRepository(self, repo_path, revid):
307
 
        """Check that a revision is not in a repository, disregarding stacking."""
308
 
        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()
309
372
        self.assertFalse(repo.has_revision(revid))
310
373
 
311
374
    def assertRevisionsInBranchRepository(self, revid_list, branch_path):
331
394
        # mainline.
332
395
        out, err = self.run_bzr(['branch', 'branch', 'newbranch'])
333
396
        self.assertEqual('', out)
334
 
        self.assertEqual('Branched 2 revision(s).\n',
 
397
        self.assertEqual('Branched 2 revisions.\n',
335
398
            err)
336
399
        # it should have preserved the branch format, and so it should be
337
400
        # capable of supporting stacking, but not actually have a stacked_on
338
401
        # branch configured
339
402
        self.assertRaises(errors.NotStacked,
340
 
            bzrdir.BzrDir.open('newbranch').open_branch().get_stacked_on_url)
 
403
            controldir.ControlDir.open('newbranch').open_branch().get_stacked_on_url)
341
404
 
342
405
    def test_branch_stacked_branch_stacked(self):
343
406
        """Asking to stack on a stacked branch does work"""
382
445
            trunk_tree.branch.base, err)
383
446
        self.assertRevisionNotInRepository('newbranch', original_revid)
384
447
        new_branch = branch.Branch.open('newbranch')
385
 
        self.assertEqual(trunk_tree.branch.base, new_branch.get_stacked_on_url())
 
448
        self.assertEqual(trunk_tree.branch.base,
 
449
                         new_branch.get_stacked_on_url())
386
450
 
387
451
    def test_branch_stacked_from_smart_server(self):
388
452
        # We can branch stacking on a smart server
423
487
            err)
424
488
 
425
489
 
426
 
class TestSmartServerBranching(TestCaseWithTransport):
 
490
class TestSmartServerBranching(tests.TestCaseWithTransport):
427
491
 
428
492
    def test_branch_from_trivial_branch_to_same_server_branch_acceptance(self):
429
493
        self.setup_smart_server_with_call_log()
438
502
        # being too low. If rpc_count increases, more network roundtrips have
439
503
        # become necessary for this use case. Please do not adjust this number
440
504
        # upwards without agreement from bzr's network support maintainers.
441
 
        self.assertLength(36, 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)
442
509
 
443
510
    def test_branch_from_trivial_branch_streaming_acceptance(self):
444
511
        self.setup_smart_server_with_call_log()
453
520
        # being too low. If rpc_count increases, more network roundtrips have
454
521
        # become necessary for this use case. Please do not adjust this number
455
522
        # upwards without agreement from bzr's network support maintainers.
456
 
        self.assertLength(9, self.hpss_calls)
 
523
        self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
 
524
        self.assertLength(10, self.hpss_calls)
 
525
        self.assertLength(1, self.hpss_connections)
457
526
 
458
527
    def test_branch_from_trivial_stacked_branch_streaming_acceptance(self):
459
528
        self.setup_smart_server_with_call_log()
473
542
        # being too low. If rpc_count increases, more network roundtrips have
474
543
        # become necessary for this use case. Please do not adjust this number
475
544
        # upwards without agreement from bzr's network support maintainers.
476
 
        self.assertLength(14, self.hpss_calls)
 
545
        self.assertLength(15, self.hpss_calls)
 
546
        self.assertLength(1, self.hpss_connections)
 
547
        self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
477
548
 
478
549
    def test_branch_from_branch_with_tags(self):
479
550
        self.setup_smart_server_with_call_log()
480
551
        builder = self.make_branch_builder('source')
481
552
        source = fixtures.build_branch_with_non_ancestral_rev(builder)
 
553
        source.get_config_stack().set('branch.fetch_tags', True)
482
554
        source.tags.set_tag('tag-a', 'rev-2')
483
555
        source.tags.set_tag('tag-missing', 'missing-rev')
484
556
        # Now source has a tag not in its ancestry.  Make a branch from it.
489
561
        # being too low. If rpc_count increases, more network roundtrips have
490
562
        # become necessary for this use case. Please do not adjust this number
491
563
        # upwards without agreement from bzr's network support maintainers.
492
 
        self.assertLength(9, self.hpss_calls)
 
564
        self.assertLength(10, self.hpss_calls)
 
565
        self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
 
566
        self.assertLength(1, self.hpss_connections)
493
567
 
494
568
    def test_branch_to_stacked_from_trivial_branch_streaming_acceptance(self):
495
569
        self.setup_smart_server_with_call_log()
508
582
        readvs_of_rix_files = [
509
583
            c for c in self.hpss_calls
510
584
            if c.call.method == 'readv' and c.call.args[-1].endswith('.rix')]
 
585
        self.assertLength(1, self.hpss_connections)
511
586
        self.assertLength(0, readvs_of_rix_files)
 
587
        self.expectFailure("branching to stacked requires VFS access",
 
588
            self.assertThat, self.hpss_calls, ContainsNoVfsCalls)
512
589
 
513
590
 
514
591
class TestRemoteBranch(TestCaseWithSFTPServer):
535
612
        self.assertFalse(t.has('remote/file'))
536
613
 
537
614
 
538
 
class TestDeprecatedAliases(TestCaseWithTransport):
 
615
class TestDeprecatedAliases(tests.TestCaseWithTransport):
539
616
 
540
617
    def test_deprecated_aliases(self):
541
 
        """bzr branch can be called clone or get, but those names are deprecated.
 
618
        """bzr branch can be called clone or get, but those names are
 
619
        deprecated.
542
620
 
543
621
        See bug 506265.
544
622
        """
557
635
                $ bzr checkout %(option)s repo/trunk checkout
558
636
                $ cd checkout
559
637
                $ bzr branch --switch ../repo/trunk ../repo/branched
560
 
                2>Branched 0 revision(s).
 
638
                2>Branched 0 revisions.
561
639
                2>Tree is up to date at revision 0.
562
640
                2>Switched to branch:...branched...
563
641
                $ cd ..