/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

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

  • Committer: John Arbash Meinel
  • Date: 2009-12-22 16:28:47 UTC
  • mto: This revision was merged to the branch mainline in revision 4922.
  • Revision ID: john@arbash-meinel.com-20091222162847-tvnsc69to4l4uf5r
Implement a permute_for_extension helper.

Use it for all of the 'simple' extension permutations.
It basically permutes all tests in the current module, by setting TestCase.module.
Which works well for most of our extension tests. Some had more advanced
handling of permutations (extra permutations, custom vars, etc.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005, 2006, 2008, 2009 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
 
 
18
"""Black-box tests for bzr branch."""
 
19
 
 
20
import os
 
21
 
 
22
from bzrlib import (
 
23
    branch,
 
24
    bzrdir,
 
25
    errors,
 
26
    repository,
 
27
    revision as _mod_revision,
 
28
    )
 
29
from bzrlib.repofmt.knitrepo import RepositoryFormatKnit1
 
30
from bzrlib.tests.blackbox import ExternalBase
 
31
from bzrlib.tests import (
 
32
    KnownFailure,
 
33
    HardlinkFeature,
 
34
    )
 
35
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
 
36
from bzrlib.urlutils import local_path_to_url, strip_trailing_slash
 
37
from bzrlib.workingtree import WorkingTree
 
38
 
 
39
 
 
40
class TestBranch(ExternalBase):
 
41
 
 
42
    def example_branch(self, path='.'):
 
43
        tree = self.make_branch_and_tree(path)
 
44
        self.build_tree_contents([(path + '/hello', 'foo')])
 
45
        tree.add('hello')
 
46
        tree.commit(message='setup')
 
47
        self.build_tree_contents([(path + '/goodbye', 'baz')])
 
48
        tree.add('goodbye')
 
49
        tree.commit(message='setup')
 
50
 
 
51
    def test_branch(self):
 
52
        """Branch from one branch to another."""
 
53
        self.example_branch('a')
 
54
        self.run_bzr('branch a b')
 
55
        b = branch.Branch.open('b')
 
56
        self.run_bzr('branch a c -r 1')
 
57
        # previously was erroneously created by branching
 
58
        self.assertFalse(b._transport.has('branch-name'))
 
59
        b.bzrdir.open_workingtree().commit(message='foo', allow_pointless=True)
 
60
 
 
61
    def test_branch_switch_no_branch(self):
 
62
        # No branch in the current directory:
 
63
        #  => new branch will be created, but switch fails
 
64
        self.example_branch('a')
 
65
        self.make_repository('current')
 
66
        self.run_bzr_error(['No WorkingTree exists for'],
 
67
            'branch --switch ../a ../b', working_dir='current')
 
68
        a = branch.Branch.open('a')
 
69
        b = branch.Branch.open('b')
 
70
        self.assertEqual(a.last_revision(), b.last_revision())
 
71
 
 
72
    def test_branch_switch_no_wt(self):
 
73
        # No working tree in the current directory:
 
74
        #  => new branch will be created, but switch fails and the current
 
75
        #     branch is unmodified
 
76
        self.example_branch('a')
 
77
        self.make_branch('current')
 
78
        self.run_bzr_error(['No WorkingTree exists for'],
 
79
            'branch --switch ../a ../b', working_dir='current')
 
80
        a = branch.Branch.open('a')
 
81
        b = branch.Branch.open('b')
 
82
        self.assertEqual(a.last_revision(), b.last_revision())
 
83
        work = branch.Branch.open('current')
 
84
        self.assertEqual(work.last_revision(), _mod_revision.NULL_REVISION)
 
85
 
 
86
    def test_branch_switch_no_checkout(self):
 
87
        # Standalone branch in the current directory:
 
88
        #  => new branch will be created, but switch fails and the current
 
89
        #     branch is unmodified
 
90
        self.example_branch('a')
 
91
        self.make_branch_and_tree('current')
 
92
        self.run_bzr_error(['Cannot switch a branch, only a checkout'],
 
93
            'branch --switch ../a ../b', working_dir='current')
 
94
        a = branch.Branch.open('a')
 
95
        b = branch.Branch.open('b')
 
96
        self.assertEqual(a.last_revision(), b.last_revision())
 
97
        work = branch.Branch.open('current')
 
98
        self.assertEqual(work.last_revision(), _mod_revision.NULL_REVISION)
 
99
 
 
100
    def test_branch_switch_checkout(self):
 
101
        # Checkout in the current directory:
 
102
        #  => new branch will be created and checkout bound to the new branch
 
103
        self.example_branch('a')
 
104
        self.run_bzr('checkout a current')
 
105
        out, err = self.run_bzr('branch --switch ../a ../b', working_dir='current')
 
106
        a = branch.Branch.open('a')
 
107
        b = branch.Branch.open('b')
 
108
        self.assertEqual(a.last_revision(), b.last_revision())
 
109
        work = WorkingTree.open('current')
 
110
        self.assertEndsWith(work.branch.get_bound_location(), '/b/')
 
111
        self.assertContainsRe(err, "Switched to branch: .*/b/")
 
112
 
 
113
    def test_branch_switch_lightweight_checkout(self):
 
114
        # Lightweight checkout in the current directory:
 
115
        #  => new branch will be created and lightweight checkout pointed to
 
116
        #     the new branch
 
117
        self.example_branch('a')
 
118
        self.run_bzr('checkout --lightweight a current')
 
119
        out, err = self.run_bzr('branch --switch ../a ../b', working_dir='current')
 
120
        a = branch.Branch.open('a')
 
121
        b = branch.Branch.open('b')
 
122
        self.assertEqual(a.last_revision(), b.last_revision())
 
123
        work = WorkingTree.open('current')
 
124
        self.assertEndsWith(work.branch.base, '/b/')
 
125
        self.assertContainsRe(err, "Switched to branch: .*/b/")
 
126
 
 
127
    def test_branch_only_copies_history(self):
 
128
        # Knit branches should only push the history for the current revision.
 
129
        format = bzrdir.BzrDirMetaFormat1()
 
130
        format.repository_format = RepositoryFormatKnit1()
 
131
        shared_repo = self.make_repository('repo', format=format, shared=True)
 
132
        shared_repo.set_make_working_trees(True)
 
133
 
 
134
        def make_shared_tree(path):
 
135
            shared_repo.bzrdir.root_transport.mkdir(path)
 
136
            shared_repo.bzrdir.create_branch_convenience('repo/' + path)
 
137
            return WorkingTree.open('repo/' + path)
 
138
        tree_a = make_shared_tree('a')
 
139
        self.build_tree(['repo/a/file'])
 
140
        tree_a.add('file')
 
141
        tree_a.commit('commit a-1', rev_id='a-1')
 
142
        f = open('repo/a/file', 'ab')
 
143
        f.write('more stuff\n')
 
144
        f.close()
 
145
        tree_a.commit('commit a-2', rev_id='a-2')
 
146
 
 
147
        tree_b = make_shared_tree('b')
 
148
        self.build_tree(['repo/b/file'])
 
149
        tree_b.add('file')
 
150
        tree_b.commit('commit b-1', rev_id='b-1')
 
151
 
 
152
        self.assertTrue(shared_repo.has_revision('a-1'))
 
153
        self.assertTrue(shared_repo.has_revision('a-2'))
 
154
        self.assertTrue(shared_repo.has_revision('b-1'))
 
155
 
 
156
        # Now that we have a repository with shared files, make sure
 
157
        # that things aren't copied out by a 'branch'
 
158
        self.run_bzr('branch repo/b branch-b')
 
159
        pushed_tree = WorkingTree.open('branch-b')
 
160
        pushed_repo = pushed_tree.branch.repository
 
161
        self.assertFalse(pushed_repo.has_revision('a-1'))
 
162
        self.assertFalse(pushed_repo.has_revision('a-2'))
 
163
        self.assertTrue(pushed_repo.has_revision('b-1'))
 
164
 
 
165
    def test_branch_hardlink(self):
 
166
        self.requireFeature(HardlinkFeature)
 
167
        source = self.make_branch_and_tree('source')
 
168
        self.build_tree(['source/file1'])
 
169
        source.add('file1')
 
170
        source.commit('added file')
 
171
        out, err = self.run_bzr(['branch', 'source', 'target', '--hardlink'])
 
172
        source_stat = os.stat('source/file1')
 
173
        target_stat = os.stat('target/file1')
 
174
        self.assertEqual(source_stat, target_stat)
 
175
 
 
176
    def test_branch_standalone(self):
 
177
        shared_repo = self.make_repository('repo', shared=True)
 
178
        self.example_branch('source')
 
179
        self.run_bzr('branch --standalone source repo/target')
 
180
        b = branch.Branch.open('repo/target')
 
181
        expected_repo_path = os.path.abspath('repo/target/.bzr/repository')
 
182
        self.assertEqual(strip_trailing_slash(b.repository.base),
 
183
            strip_trailing_slash(local_path_to_url(expected_repo_path)))
 
184
 
 
185
    def test_branch_no_tree(self):
 
186
        self.example_branch('source')
 
187
        self.run_bzr('branch --no-tree source target')
 
188
        self.failIfExists('target/hello')
 
189
        self.failIfExists('target/goodbye')
 
190
 
 
191
    def test_branch_into_existing_dir(self):
 
192
        self.example_branch('a')
 
193
        # existing dir with similar files but no .bzr dir
 
194
        self.build_tree_contents([('b/',)])
 
195
        self.build_tree_contents([('b/hello', 'bar')])  # different content
 
196
        self.build_tree_contents([('b/goodbye', 'baz')])# same content
 
197
        # fails without --use-existing-dir
 
198
        out,err = self.run_bzr('branch a b', retcode=3)
 
199
        self.assertEqual('', out)
 
200
        self.assertEqual('bzr: ERROR: Target directory "b" already exists.\n',
 
201
            err)
 
202
        # force operation
 
203
        self.run_bzr('branch a b --use-existing-dir')
 
204
        # check conflicts
 
205
        self.failUnlessExists('b/hello.moved')
 
206
        self.failIfExists('b/godbye.moved')
 
207
        # we can't branch into branch
 
208
        out,err = self.run_bzr('branch a b --use-existing-dir', retcode=3)
 
209
        self.assertEqual('', out)
 
210
        self.assertEqual('bzr: ERROR: Already a branch: "b".\n', err)
 
211
 
 
212
 
 
213
class TestBranchStacked(ExternalBase):
 
214
    """Tests for branch --stacked"""
 
215
 
 
216
    def assertRevisionInRepository(self, repo_path, revid):
 
217
        """Check that a revision is in a repository, disregarding stacking."""
 
218
        repo = bzrdir.BzrDir.open(repo_path).open_repository()
 
219
        self.assertTrue(repo.has_revision(revid))
 
220
 
 
221
    def assertRevisionNotInRepository(self, repo_path, revid):
 
222
        """Check that a revision is not in a repository, disregarding stacking."""
 
223
        repo = bzrdir.BzrDir.open(repo_path).open_repository()
 
224
        self.assertFalse(repo.has_revision(revid))
 
225
 
 
226
    def assertRevisionsInBranchRepository(self, revid_list, branch_path):
 
227
        repo = branch.Branch.open(branch_path).repository
 
228
        self.assertEqual(set(revid_list),
 
229
            repo.has_revisions(revid_list))
 
230
 
 
231
    def test_branch_stacked_branch_not_stacked(self):
 
232
        """Branching a stacked branch is not stacked by default"""
 
233
        # We have a mainline
 
234
        trunk_tree = self.make_branch_and_tree('target',
 
235
            format='1.9')
 
236
        trunk_tree.commit('mainline')
 
237
        # and a branch from it which is stacked
 
238
        branch_tree = self.make_branch_and_tree('branch',
 
239
            format='1.9')
 
240
        branch_tree.branch.set_stacked_on_url(trunk_tree.branch.base)
 
241
        # with some work on it
 
242
        work_tree = trunk_tree.branch.bzrdir.sprout('local').open_workingtree()
 
243
        work_tree.commit('moar work plz')
 
244
        work_tree.branch.push(branch_tree.branch)
 
245
        # branching our local branch gives us a new stacked branch pointing at
 
246
        # mainline.
 
247
        out, err = self.run_bzr(['branch', 'branch', 'newbranch'])
 
248
        self.assertEqual('', out)
 
249
        self.assertEqual('Branched 2 revision(s).\n',
 
250
            err)
 
251
        # it should have preserved the branch format, and so it should be
 
252
        # capable of supporting stacking, but not actually have a stacked_on
 
253
        # branch configured
 
254
        self.assertRaises(errors.NotStacked,
 
255
            bzrdir.BzrDir.open('newbranch').open_branch().get_stacked_on_url)
 
256
 
 
257
    def test_branch_stacked_branch_stacked(self):
 
258
        """Asking to stack on a stacked branch does work"""
 
259
        # We have a mainline
 
260
        trunk_tree = self.make_branch_and_tree('target',
 
261
            format='1.9')
 
262
        trunk_revid = trunk_tree.commit('mainline')
 
263
        # and a branch from it which is stacked
 
264
        branch_tree = self.make_branch_and_tree('branch',
 
265
            format='1.9')
 
266
        branch_tree.branch.set_stacked_on_url(trunk_tree.branch.base)
 
267
        # with some work on it
 
268
        work_tree = trunk_tree.branch.bzrdir.sprout('local').open_workingtree()
 
269
        branch_revid = work_tree.commit('moar work plz')
 
270
        work_tree.branch.push(branch_tree.branch)
 
271
        # you can chain branches on from there
 
272
        out, err = self.run_bzr(['branch', 'branch', '--stacked', 'branch2'])
 
273
        self.assertEqual('', out)
 
274
        self.assertEqual('Created new stacked branch referring to %s.\n' %
 
275
            branch_tree.branch.base, err)
 
276
        self.assertEqual(branch_tree.branch.base,
 
277
            branch.Branch.open('branch2').get_stacked_on_url())
 
278
        branch2_tree = WorkingTree.open('branch2')
 
279
        branch2_revid = work_tree.commit('work on second stacked branch')
 
280
        work_tree.branch.push(branch2_tree.branch)
 
281
        self.assertRevisionInRepository('branch2', branch2_revid)
 
282
        self.assertRevisionsInBranchRepository(
 
283
            [trunk_revid, branch_revid, branch2_revid],
 
284
            'branch2')
 
285
 
 
286
    def test_branch_stacked(self):
 
287
        # We have a mainline
 
288
        trunk_tree = self.make_branch_and_tree('mainline',
 
289
            format='1.9')
 
290
        original_revid = trunk_tree.commit('mainline')
 
291
        self.assertRevisionInRepository('mainline', original_revid)
 
292
        # and a branch from it which is stacked
 
293
        out, err = self.run_bzr(['branch', '--stacked', 'mainline',
 
294
            'newbranch'])
 
295
        self.assertEqual('', out)
 
296
        self.assertEqual('Created new stacked branch referring to %s.\n' %
 
297
            trunk_tree.branch.base, err)
 
298
        self.assertRevisionNotInRepository('newbranch', original_revid)
 
299
        new_branch = branch.Branch.open('newbranch')
 
300
        self.assertEqual(trunk_tree.branch.base, new_branch.get_stacked_on_url())
 
301
 
 
302
    def test_branch_stacked_from_smart_server(self):
 
303
        # We can branch stacking on a smart server
 
304
        from bzrlib.smart.server import SmartTCPServer_for_testing
 
305
        self.transport_server = SmartTCPServer_for_testing
 
306
        trunk = self.make_branch('mainline', format='1.9')
 
307
        out, err = self.run_bzr(
 
308
            ['branch', '--stacked', self.get_url('mainline'), 'shallow'])
 
309
 
 
310
    def test_branch_stacked_from_non_stacked_format(self):
 
311
        """The origin format doesn't support stacking"""
 
312
        trunk = self.make_branch('trunk', format='pack-0.92')
 
313
        out, err = self.run_bzr(
 
314
            ['branch', '--stacked', 'trunk', 'shallow'])
 
315
        # We should notify the user that we upgraded their format
 
316
        self.assertEqualDiff(
 
317
            'Source repository format does not support stacking, using format:\n'
 
318
            '  Packs 5 (adds stacking support, requires bzr 1.6)\n'
 
319
            'Source branch format does not support stacking, using format:\n'
 
320
            '  Branch format 7\n'
 
321
            'Created new stacked branch referring to %s.\n' % (trunk.base,),
 
322
            err)
 
323
 
 
324
    def test_branch_stacked_from_rich_root_non_stackable(self):
 
325
        trunk = self.make_branch('trunk', format='rich-root-pack')
 
326
        out, err = self.run_bzr(
 
327
            ['branch', '--stacked', 'trunk', 'shallow'])
 
328
        # We should notify the user that we upgraded their format
 
329
        self.assertEqualDiff(
 
330
            'Source repository format does not support stacking, using format:\n'
 
331
            '  Packs 5 rich-root (adds stacking support, requires bzr 1.6.1)\n'
 
332
            'Source branch format does not support stacking, using format:\n'
 
333
            '  Branch format 7\n'
 
334
            'Created new stacked branch referring to %s.\n' % (trunk.base,),
 
335
            err)
 
336
 
 
337
 
 
338
class TestSmartServerBranching(ExternalBase):
 
339
 
 
340
    def test_branch_from_trivial_branch_to_same_server_branch_acceptance(self):
 
341
        self.setup_smart_server_with_call_log()
 
342
        t = self.make_branch_and_tree('from')
 
343
        for count in range(9):
 
344
            t.commit(message='commit %d' % count)
 
345
        self.reset_smart_call_log()
 
346
        out, err = self.run_bzr(['branch', self.get_url('from'),
 
347
            self.get_url('target')])
 
348
        # This figure represent the amount of work to perform this use case. It
 
349
        # is entirely ok to reduce this number if a test fails due to rpc_count
 
350
        # being too low. If rpc_count increases, more network roundtrips have
 
351
        # become necessary for this use case. Please do not adjust this number
 
352
        # upwards without agreement from bzr's network support maintainers.
 
353
        self.assertLength(38, self.hpss_calls)
 
354
 
 
355
    def test_branch_from_trivial_branch_streaming_acceptance(self):
 
356
        self.setup_smart_server_with_call_log()
 
357
        t = self.make_branch_and_tree('from')
 
358
        for count in range(9):
 
359
            t.commit(message='commit %d' % count)
 
360
        self.reset_smart_call_log()
 
361
        out, err = self.run_bzr(['branch', self.get_url('from'),
 
362
            'local-target'])
 
363
        # This figure represent the amount of work to perform this use case. It
 
364
        # is entirely ok to reduce this number if a test fails due to rpc_count
 
365
        # being too low. If rpc_count increases, more network roundtrips have
 
366
        # become necessary for this use case. Please do not adjust this number
 
367
        # upwards without agreement from bzr's network support maintainers.
 
368
        self.assertLength(10, self.hpss_calls)
 
369
 
 
370
    def test_branch_from_trivial_stacked_branch_streaming_acceptance(self):
 
371
        self.setup_smart_server_with_call_log()
 
372
        t = self.make_branch_and_tree('trunk')
 
373
        for count in range(8):
 
374
            t.commit(message='commit %d' % count)
 
375
        tree2 = t.branch.bzrdir.sprout('feature', stacked=True
 
376
            ).open_workingtree()
 
377
        local_tree = t.branch.bzrdir.sprout('local-working').open_workingtree()
 
378
        local_tree.commit('feature change')
 
379
        local_tree.branch.push(tree2.branch)
 
380
        self.reset_smart_call_log()
 
381
        out, err = self.run_bzr(['branch', self.get_url('feature'),
 
382
            'local-target'])
 
383
        # This figure represent the amount of work to perform this use case. It
 
384
        # is entirely ok to reduce this number if a test fails due to rpc_count
 
385
        # being too low. If rpc_count increases, more network roundtrips have
 
386
        # become necessary for this use case. Please do not adjust this number
 
387
        # upwards without agreement from bzr's network support maintainers.
 
388
        self.assertLength(15, self.hpss_calls)
 
389
 
 
390
 
 
391
class TestRemoteBranch(TestCaseWithSFTPServer):
 
392
 
 
393
    def setUp(self):
 
394
        super(TestRemoteBranch, self).setUp()
 
395
        tree = self.make_branch_and_tree('branch')
 
396
        self.build_tree_contents([('branch/file', 'file content\n')])
 
397
        tree.add('file')
 
398
        tree.commit('file created')
 
399
 
 
400
    def test_branch_local_remote(self):
 
401
        self.run_bzr(['branch', 'branch', self.get_url('remote')])
 
402
        t = self.get_transport()
 
403
        # Ensure that no working tree what created remotely
 
404
        self.assertFalse(t.has('remote/file'))
 
405
 
 
406
    def test_branch_remote_remote(self):
 
407
        # Light cheat: we access the branch remotely
 
408
        self.run_bzr(['branch', self.get_url('branch'),
 
409
                      self.get_url('remote')])
 
410
        t = self.get_transport()
 
411
        # Ensure that no working tree what created remotely
 
412
        self.assertFalse(t.has('remote/file'))
 
413