~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Jonathan Lange
  • Date: 2009-05-01 06:42:30 UTC
  • mto: This revision was merged to the branch mainline in revision 4320.
  • Revision ID: jml@canonical.com-20090501064230-kyk7v49xt8cevd25
Remove InstallFailed, it's not needed anymore.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2008, 2009 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 (
23
 
    branch,
24
 
    bzrdir,
25
 
    errors,
26
 
    repository,
27
 
    revision as _mod_revision,
28
 
    )
 
22
from bzrlib import (branch, bzrdir, errors, repository)
29
23
from bzrlib.repofmt.knitrepo import RepositoryFormatKnit1
30
 
from bzrlib.tests import TestCaseWithTransport
31
 
from bzrlib.tests import (
32
 
    KnownFailure,
33
 
    HardlinkFeature,
34
 
    test_server,
35
 
    )
 
24
from bzrlib.tests.blackbox import ExternalBase
 
25
from bzrlib.tests import HardlinkFeature
36
26
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
37
27
from bzrlib.urlutils import local_path_to_url, strip_trailing_slash
38
28
from bzrlib.workingtree import WorkingTree
39
29
 
40
30
 
41
 
class TestBranch(TestCaseWithTransport):
 
31
class TestBranch(ExternalBase):
42
32
 
43
33
    def example_branch(self, path='.'):
44
34
        tree = self.make_branch_and_tree(path)
59
49
        self.assertFalse(b._transport.has('branch-name'))
60
50
        b.bzrdir.open_workingtree().commit(message='foo', allow_pointless=True)
61
51
 
62
 
    def test_branch_switch_no_branch(self):
63
 
        # No branch in the current directory:
64
 
        #  => new branch will be created, but switch fails
65
 
        self.example_branch('a')
66
 
        self.make_repository('current')
67
 
        self.run_bzr_error(['No WorkingTree exists for'],
68
 
            'branch --switch ../a ../b', working_dir='current')
69
 
        a = branch.Branch.open('a')
70
 
        b = branch.Branch.open('b')
71
 
        self.assertEqual(a.last_revision(), b.last_revision())
72
 
 
73
 
    def test_branch_switch_no_wt(self):
74
 
        # No working tree in the current directory:
75
 
        #  => new branch will be created, but switch fails and the current
76
 
        #     branch is unmodified
77
 
        self.example_branch('a')
78
 
        self.make_branch('current')
79
 
        self.run_bzr_error(['No WorkingTree exists for'],
80
 
            'branch --switch ../a ../b', working_dir='current')
81
 
        a = branch.Branch.open('a')
82
 
        b = branch.Branch.open('b')
83
 
        self.assertEqual(a.last_revision(), b.last_revision())
84
 
        work = branch.Branch.open('current')
85
 
        self.assertEqual(work.last_revision(), _mod_revision.NULL_REVISION)
86
 
 
87
 
    def test_branch_switch_no_checkout(self):
88
 
        # Standalone branch in the current directory:
89
 
        #  => new branch will be created, but switch fails and the current
90
 
        #     branch is unmodified
91
 
        self.example_branch('a')
92
 
        self.make_branch_and_tree('current')
93
 
        self.run_bzr_error(['Cannot switch a branch, only a checkout'],
94
 
            'branch --switch ../a ../b', working_dir='current')
95
 
        a = branch.Branch.open('a')
96
 
        b = branch.Branch.open('b')
97
 
        self.assertEqual(a.last_revision(), b.last_revision())
98
 
        work = branch.Branch.open('current')
99
 
        self.assertEqual(work.last_revision(), _mod_revision.NULL_REVISION)
100
 
 
101
 
    def test_branch_switch_checkout(self):
102
 
        # Checkout in the current directory:
103
 
        #  => new branch will be created and checkout bound to the new branch
104
 
        self.example_branch('a')
105
 
        self.run_bzr('checkout a current')
106
 
        out, err = self.run_bzr('branch --switch ../a ../b', working_dir='current')
107
 
        a = branch.Branch.open('a')
108
 
        b = branch.Branch.open('b')
109
 
        self.assertEqual(a.last_revision(), b.last_revision())
110
 
        work = WorkingTree.open('current')
111
 
        self.assertEndsWith(work.branch.get_bound_location(), '/b/')
112
 
        self.assertContainsRe(err, "Switched to branch: .*/b/")
113
 
 
114
 
    def test_branch_switch_lightweight_checkout(self):
115
 
        # Lightweight checkout in the current directory:
116
 
        #  => new branch will be created and lightweight checkout pointed to
117
 
        #     the new branch
118
 
        self.example_branch('a')
119
 
        self.run_bzr('checkout --lightweight a current')
120
 
        out, err = self.run_bzr('branch --switch ../a ../b', working_dir='current')
121
 
        a = branch.Branch.open('a')
122
 
        b = branch.Branch.open('b')
123
 
        self.assertEqual(a.last_revision(), b.last_revision())
124
 
        work = WorkingTree.open('current')
125
 
        self.assertEndsWith(work.branch.base, '/b/')
126
 
        self.assertContainsRe(err, "Switched to branch: .*/b/")
127
 
 
128
52
    def test_branch_only_copies_history(self):
129
53
        # Knit branches should only push the history for the current revision.
130
54
        format = bzrdir.BzrDirMetaFormat1()
169
93
        self.build_tree(['source/file1'])
170
94
        source.add('file1')
171
95
        source.commit('added file')
172
 
        out, err = self.run_bzr(['branch', 'source', 'target', '--hardlink'])
 
96
        self.run_bzr(['branch', 'source', 'target', '--hardlink'])
173
97
        source_stat = os.stat('source/file1')
174
98
        target_stat = os.stat('target/file1')
175
99
        self.assertEqual(source_stat, target_stat)
176
100
 
177
 
    def test_branch_files_from(self):
178
 
        source = self.make_branch_and_tree('source')
179
 
        self.build_tree(['source/file1'])
180
 
        source.add('file1')
181
 
        source.commit('added file')
182
 
        out, err = self.run_bzr('branch source target --files-from source')
183
 
        self.failUnlessExists('target/file1')
184
 
 
185
 
    def test_branch_files_from_hardlink(self):
186
 
        self.requireFeature(HardlinkFeature)
187
 
        source = self.make_branch_and_tree('source')
188
 
        self.build_tree(['source/file1'])
189
 
        source.add('file1')
190
 
        source.commit('added file')
191
 
        source.bzrdir.sprout('second')
192
 
        out, err = self.run_bzr('branch source target --files-from second'
193
 
                                ' --hardlink')
194
 
        source_stat = os.stat('source/file1')
195
 
        second_stat = os.stat('second/file1')
196
 
        target_stat = os.stat('target/file1')
197
 
        self.assertNotEqual(source_stat, target_stat)
198
 
        self.assertEqual(second_stat, target_stat)
199
 
 
200
101
    def test_branch_standalone(self):
201
102
        shared_repo = self.make_repository('repo', shared=True)
202
103
        self.example_branch('source')
212
113
        self.failIfExists('target/hello')
213
114
        self.failIfExists('target/goodbye')
214
115
 
215
 
    def test_branch_into_existing_dir(self):
216
 
        self.example_branch('a')
217
 
        # existing dir with similar files but no .bzr dir
218
 
        self.build_tree_contents([('b/',)])
219
 
        self.build_tree_contents([('b/hello', 'bar')])  # different content
220
 
        self.build_tree_contents([('b/goodbye', 'baz')])# same content
221
 
        # fails without --use-existing-dir
222
 
        out,err = self.run_bzr('branch a b', retcode=3)
223
 
        self.assertEqual('', out)
224
 
        self.assertEqual('bzr: ERROR: Target directory "b" already exists.\n',
225
 
            err)
226
 
        # force operation
227
 
        self.run_bzr('branch a b --use-existing-dir')
228
 
        # check conflicts
229
 
        self.failUnlessExists('b/hello.moved')
230
 
        self.failIfExists('b/godbye.moved')
231
 
        # we can't branch into branch
232
 
        out,err = self.run_bzr('branch a b --use-existing-dir', retcode=3)
233
 
        self.assertEqual('', out)
234
 
        self.assertEqual('bzr: ERROR: Already a branch: "b".\n', err)
235
 
 
236
 
    def test_branch_bind(self):
237
 
        self.example_branch('a')
238
 
        out, err = self.run_bzr('branch a b --bind')
239
 
        self.assertEndsWith(err, "New branch bound to a\n")
240
 
        b = branch.Branch.open('b')
241
 
        self.assertEndsWith(b.get_bound_location(), '/a/')
242
 
 
243
 
    def test_branch_with_post_branch_init_hook(self):
244
 
        calls = []
245
 
        branch.Branch.hooks.install_named_hook('post_branch_init',
246
 
            calls.append, None)
247
 
        self.assertLength(0, calls)
248
 
        self.example_branch('a')
249
 
        self.assertLength(1, calls)
250
 
        self.run_bzr('branch a b')
251
 
        self.assertLength(2, calls)
252
 
 
253
 
    def test_checkout_with_post_branch_init_hook(self):
254
 
        calls = []
255
 
        branch.Branch.hooks.install_named_hook('post_branch_init',
256
 
            calls.append, None)
257
 
        self.assertLength(0, calls)
258
 
        self.example_branch('a')
259
 
        self.assertLength(1, calls)
260
 
        self.run_bzr('checkout a b')
261
 
        self.assertLength(2, calls)
262
 
 
263
 
    def test_lightweight_checkout_with_post_branch_init_hook(self):
264
 
        calls = []
265
 
        branch.Branch.hooks.install_named_hook('post_branch_init',
266
 
            calls.append, None)
267
 
        self.assertLength(0, calls)
268
 
        self.example_branch('a')
269
 
        self.assertLength(1, calls)
270
 
        self.run_bzr('checkout --lightweight a b')
271
 
        self.assertLength(2, calls)
272
 
 
273
 
 
274
 
class TestBranchStacked(TestCaseWithTransport):
 
116
 
 
117
class TestBranchStacked(ExternalBase):
275
118
    """Tests for branch --stacked"""
276
119
 
 
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
 
277
143
    def assertRevisionInRepository(self, repo_path, revid):
278
144
        """Check that a revision is in a repository, disregarding stacking."""
279
145
        repo = bzrdir.BzrDir.open(repo_path).open_repository()
300
166
            format='1.9')
301
167
        branch_tree.branch.set_stacked_on_url(trunk_tree.branch.base)
302
168
        # with some work on it
303
 
        work_tree = trunk_tree.branch.bzrdir.sprout('local').open_workingtree()
304
 
        work_tree.commit('moar work plz')
305
 
        work_tree.branch.push(branch_tree.branch)
 
169
        branch_tree.commit('moar work plz')
306
170
        # branching our local branch gives us a new stacked branch pointing at
307
171
        # mainline.
308
172
        out, err = self.run_bzr(['branch', 'branch', 'newbranch'])
309
173
        self.assertEqual('', out)
310
 
        self.assertEqual('Branched 2 revision(s).\n',
 
174
        self.assertEqual('Branched 1 revision(s).\n',
311
175
            err)
312
176
        # it should have preserved the branch format, and so it should be
313
177
        # capable of supporting stacking, but not actually have a stacked_on
326
190
            format='1.9')
327
191
        branch_tree.branch.set_stacked_on_url(trunk_tree.branch.base)
328
192
        # with some work on it
329
 
        work_tree = trunk_tree.branch.bzrdir.sprout('local').open_workingtree()
330
 
        branch_revid = work_tree.commit('moar work plz')
331
 
        work_tree.branch.push(branch_tree.branch)
 
193
        branch_revid = branch_tree.commit('moar work plz')
332
194
        # you can chain branches on from there
333
195
        out, err = self.run_bzr(['branch', 'branch', '--stacked', 'branch2'])
334
196
        self.assertEqual('', out)
337
199
        self.assertEqual(branch_tree.branch.base,
338
200
            branch.Branch.open('branch2').get_stacked_on_url())
339
201
        branch2_tree = WorkingTree.open('branch2')
340
 
        branch2_revid = work_tree.commit('work on second stacked branch')
341
 
        work_tree.branch.push(branch2_tree.branch)
 
202
        branch2_revid = branch2_tree.commit('work on second stacked branch')
342
203
        self.assertRevisionInRepository('branch2', branch2_revid)
343
204
        self.assertRevisionsInBranchRepository(
344
205
            [trunk_revid, branch_revid, branch2_revid],
357
218
        self.assertEqual('Created new stacked branch referring to %s.\n' %
358
219
            trunk_tree.branch.base, err)
359
220
        self.assertRevisionNotInRepository('newbranch', original_revid)
360
 
        new_branch = branch.Branch.open('newbranch')
361
 
        self.assertEqual(trunk_tree.branch.base, new_branch.get_stacked_on_url())
 
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)
362
224
 
363
225
    def test_branch_stacked_from_smart_server(self):
364
226
        # We can branch stacking on a smart server
365
 
        self.transport_server = test_server.SmartTCPServer_for_testing
 
227
        from bzrlib.smart.server import SmartTCPServer_for_testing
 
228
        self.transport_server = SmartTCPServer_for_testing
366
229
        trunk = self.make_branch('mainline', format='1.9')
367
230
        out, err = self.run_bzr(
368
231
            ['branch', '--stacked', self.get_url('mainline'), 'shallow'])
374
237
            ['branch', '--stacked', 'trunk', 'shallow'])
375
238
        # We should notify the user that we upgraded their format
376
239
        self.assertEqualDiff(
377
 
            'Source repository format does not support stacking, using format:\n'
 
240
            'Source format does not support stacking, using format: \'1.6\'\n'
378
241
            '  Packs 5 (adds stacking support, requires bzr 1.6)\n'
379
 
            'Source branch format does not support stacking, using format:\n'
380
 
            '  Branch format 7\n'
381
 
            'Doing on-the-fly conversion from RepositoryFormatKnitPack1() to RepositoryFormatKnitPack5().\n'
382
 
            'This may take some time. Upgrade the repositories to the same format for better performance.\n'
 
242
            '\n'
383
243
            'Created new stacked branch referring to %s.\n' % (trunk.base,),
384
244
            err)
385
245
 
389
249
            ['branch', '--stacked', 'trunk', 'shallow'])
390
250
        # We should notify the user that we upgraded their format
391
251
        self.assertEqualDiff(
392
 
            'Source repository format does not support stacking, using format:\n'
 
252
            'Source format does not support stacking, using format:'
 
253
            ' \'1.6.1-rich-root\'\n'
393
254
            '  Packs 5 rich-root (adds stacking support, requires bzr 1.6.1)\n'
394
 
            'Source branch format does not support stacking, using format:\n'
395
 
            '  Branch format 7\n'
396
 
            'Doing on-the-fly conversion from RepositoryFormatKnitPack4() to RepositoryFormatKnitPack5RichRoot().\n'
397
 
            'This may take some time. Upgrade the repositories to the same format for better performance.\n'
 
255
            '\n'
398
256
            'Created new stacked branch referring to %s.\n' % (trunk.base,),
399
257
            err)
400
258
 
401
259
 
402
 
class TestSmartServerBranching(TestCaseWithTransport):
 
260
class TestSmartServerBranching(ExternalBase):
403
261
 
404
262
    def test_branch_from_trivial_branch_to_same_server_branch_acceptance(self):
405
263
        self.setup_smart_server_with_call_log()
414
272
        # being too low. If rpc_count increases, more network roundtrips have
415
273
        # become necessary for this use case. Please do not adjust this number
416
274
        # upwards without agreement from bzr's network support maintainers.
417
 
        self.assertLength(38, self.hpss_calls)
 
275
        self.assertLength(39, self.hpss_calls)
418
276
 
419
277
    def test_branch_from_trivial_branch_streaming_acceptance(self):
420
278
        self.setup_smart_server_with_call_log()
438
296
            t.commit(message='commit %d' % count)
439
297
        tree2 = t.branch.bzrdir.sprout('feature', stacked=True
440
298
            ).open_workingtree()
441
 
        local_tree = t.branch.bzrdir.sprout('local-working').open_workingtree()
442
 
        local_tree.commit('feature change')
443
 
        local_tree.branch.push(tree2.branch)
 
299
        tree2.commit('feature change')
444
300
        self.reset_smart_call_log()
445
301
        out, err = self.run_bzr(['branch', self.get_url('feature'),
446
302
            'local-target'])