/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/branch_implementations/test_stacking.py

  • Committer: Robert Collins
  • Date: 2009-03-13 02:25:46 UTC
  • mfrom: (4133 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4183.
  • Revision ID: robertc@robertcollins.net-20090313022546-e7de5zsdkbay5okf
MergeĀ .dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
"""Tests for Branch.get_stacked_on_url and set_stacked_on_url."""
18
18
 
19
19
from bzrlib import (
 
20
    branch,
20
21
    bzrdir,
21
22
    errors,
22
23
    )
23
24
from bzrlib.revision import NULL_REVISION
24
 
from bzrlib.tests import TestNotApplicable, KnownFailure
 
25
from bzrlib.smart import server
 
26
from bzrlib.tests import TestNotApplicable, KnownFailure, transport_util
25
27
from bzrlib.tests.branch_implementations import TestCaseWithBranch
 
28
from bzrlib.transport import get_transport
 
29
 
 
30
 
 
31
unstackable_format_errors = (
 
32
    errors.UnstackableBranchFormat,
 
33
    errors.UnstackableRepositoryFormat,
 
34
    )
26
35
 
27
36
 
28
37
class TestStacking(TestCaseWithBranch):
29
38
 
 
39
    def check_lines_added_or_present(self, stacked_branch, revid):
 
40
        # similar to a failure seen in bug 288751 by mbp 20081120
 
41
        stacked_repo = stacked_branch.repository
 
42
        stacked_repo.lock_read()
 
43
        try:
 
44
            list(stacked_repo.inventories.iter_lines_added_or_present_in_keys(
 
45
                    [(revid,)]))
 
46
        finally:
 
47
            stacked_repo.unlock()
 
48
 
30
49
    def test_get_set_stacked_on_url(self):
31
50
        # branches must either:
32
51
        # raise UnstackableBranchFormat or
34
53
        # permit stacking to be done and then return the stacked location.
35
54
        branch = self.make_branch('branch')
36
55
        target = self.make_branch('target')
37
 
        old_format_errors = (
38
 
            errors.UnstackableBranchFormat,
39
 
            errors.UnstackableRepositoryFormat,
40
 
            )
41
56
        try:
42
57
            branch.set_stacked_on_url(target.base)
43
 
        except old_format_errors:
 
58
        except unstackable_format_errors:
44
59
            # if the set failed, so must the get
45
 
            self.assertRaises(old_format_errors, branch.get_stacked_on_url)
 
60
            self.assertRaises(unstackable_format_errors, branch.get_stacked_on_url)
 
61
            self.assertFalse(branch._format.supports_stacking())
46
62
            return
 
63
        self.assertTrue(branch._format.supports_stacking())
47
64
        # now we have a stacked branch:
48
65
        self.assertEqual(target.base, branch.get_stacked_on_url())
49
66
        branch.set_stacked_on_url(None)
53
70
        # Branches can be stacked on other branches using relative paths.
54
71
        branch = self.make_branch('branch')
55
72
        target = self.make_branch('target')
56
 
        old_format_errors = (
57
 
            errors.UnstackableBranchFormat,
58
 
            errors.UnstackableRepositoryFormat,
59
 
            )
60
73
        try:
61
74
            branch.set_stacked_on_url('../target')
62
 
        except old_format_errors:
 
75
        except unstackable_format_errors:
63
76
            # if the set failed, so must the get
64
 
            self.assertRaises(old_format_errors, branch.get_stacked_on_url)
 
77
            self.assertRaises(unstackable_format_errors, branch.get_stacked_on_url)
65
78
            return
66
79
        self.assertEqual('../target', branch.get_stacked_on_url())
67
80
 
85
98
        new_branch = self.make_branch('new_branch')
86
99
        try:
87
100
            new_branch.set_stacked_on_url(trunk_tree.branch.base)
88
 
        except (errors.UnstackableBranchFormat,
89
 
            errors.UnstackableRepositoryFormat), e:
 
101
        except unstackable_format_errors, e:
90
102
            raise TestNotApplicable(e)
91
103
        # reading the graph from the stacked branch's repository should see
92
104
        # data from the stacked-on branch
105
117
        # and make branch from it which is stacked
106
118
        try:
107
119
            new_dir = trunk_tree.bzrdir.sprout('newbranch', stacked=True)
108
 
        except (errors.UnstackableBranchFormat,
109
 
            errors.UnstackableRepositoryFormat), e:
110
 
            raise TestNotApplicable(e)
 
120
        except unstackable_format_errors, e:
 
121
            raise TestNotApplicable(e)
 
122
        # stacked repository
 
123
        self.assertRevisionNotInRepository('newbranch', trunk_revid)
 
124
        new_tree = new_dir.open_workingtree()
 
125
        new_branch_revid = new_tree.commit('something local')
 
126
        self.assertRevisionNotInRepository('mainline', new_branch_revid)
 
127
        self.assertRevisionInRepository('newbranch', new_branch_revid)
 
128
 
 
129
    # XXX: this helper probably belongs on TestCaseWithTransport
 
130
    def make_smart_server(self, path):
 
131
        smart_server = server.SmartTCPServer_for_testing()
 
132
        smart_server.setUp(self.get_server())
 
133
        remote_transport = get_transport(smart_server.get_url()).clone(path)
 
134
        self.addCleanup(smart_server.tearDown)
 
135
        return remote_transport
 
136
 
 
137
    def test_sprout_stacked_from_smart_server(self):
 
138
        if isinstance(self.branch_format, branch.BzrBranchFormat4):
 
139
            raise TestNotApplicable('Branch format 4 is not usable via HPSS.')
 
140
        # We have a mainline
 
141
        trunk_tree = self.make_branch_and_tree('mainline')
 
142
        trunk_revid = trunk_tree.commit('mainline')
 
143
        # Make sure that we can make a stacked branch from it
 
144
        try:
 
145
            trunk_tree.bzrdir.sprout('testbranch', stacked=True)
 
146
        except unstackable_format_errors, e:
 
147
            raise TestNotApplicable(e)
 
148
        # Now serve the original mainline from a smart server
 
149
        remote_transport = self.make_smart_server('mainline')
 
150
        remote_bzrdir = bzrdir.BzrDir.open_from_transport(remote_transport)
 
151
        # and make branch from the smart server which is stacked
 
152
        new_dir = remote_bzrdir.sprout('newbranch', stacked=True)
111
153
        # stacked repository
112
154
        self.assertRevisionNotInRepository('newbranch', trunk_revid)
113
155
        new_tree = new_dir.open_workingtree()
123
165
        # and make branch from it which is stacked
124
166
        try:
125
167
            new_dir = trunk_tree.bzrdir.sprout('newbranch', stacked=True)
126
 
        except (errors.UnstackableBranchFormat,
127
 
            errors.UnstackableRepositoryFormat), e:
 
168
        except unstackable_format_errors, e:
128
169
            raise TestNotApplicable(e)
129
170
        # stacked repository
130
171
        self.assertRevisionNotInRepository('newbranch', trunk_revid)
163
204
        # same branch as the original.
164
205
        try:
165
206
            stacked_bzrdir = self.make_stacked_bzrdir()
166
 
        except (errors.UnstackableBranchFormat,
167
 
                errors.UnstackableRepositoryFormat), e:
168
 
            # not a testable combination.
 
207
        except unstackable_format_errors, e:
169
208
            raise TestNotApplicable(e)
170
209
        cloned_bzrdir = stacked_bzrdir.clone('cloned', preserve_stacking=True)
171
210
        try:
172
211
            self.assertEqual(
173
212
                stacked_bzrdir.open_branch().get_stacked_on_url(),
174
213
                cloned_bzrdir.open_branch().get_stacked_on_url())
175
 
        except (errors.UnstackableBranchFormat,
176
 
                errors.UnstackableRepositoryFormat):
 
214
        except unstackable_format_errors, e:
177
215
            pass
178
216
 
179
217
    def test_clone_from_branch_stacked_on_relative_url_preserve_stacking(self):
182
220
        # on an appropriately adjusted relative url.
183
221
        try:
184
222
            stacked_bzrdir = self.make_stacked_bzrdir(in_directory='dir')
185
 
        except (errors.UnstackableBranchFormat,
186
 
                errors.UnstackableRepositoryFormat), e:
187
 
            # not a testable combination.
 
223
        except unstackable_format_errors, e:
188
224
            raise TestNotApplicable(e)
189
225
        stacked_bzrdir.open_branch().set_stacked_on_url('../stacked-on')
190
226
        cloned_bzrdir = stacked_bzrdir.clone('cloned', preserve_stacking=True)
195
231
    def test_clone_from_stacked_branch_no_preserve_stacking(self):
196
232
        try:
197
233
            stacked_bzrdir = self.make_stacked_bzrdir()
198
 
        except (errors.UnstackableBranchFormat,
199
 
                errors.UnstackableRepositoryFormat), e:
 
234
        except unstackable_format_errors, e:
200
235
            # not a testable combination.
201
236
            raise TestNotApplicable(e)
202
237
        cloned_unstacked_bzrdir = stacked_bzrdir.clone('cloned-unstacked',
219
254
        parent_bzrdir.get_config().set_default_stack_on('stack-on')
220
255
        source = self.make_branch('source')
221
256
        target = source.bzrdir.sprout('target').open_branch()
222
 
        try:
 
257
        if self.branch_format.supports_stacking():
223
258
            self.assertEqual('../stack-on', target.get_stacked_on_url())
224
 
        except errors.UnstackableBranchFormat:
225
 
            pass
 
259
        else:
 
260
            self.assertRaises(
 
261
                errors.UnstackableBranchFormat, target.get_stacked_on_url)
226
262
 
227
263
    def test_clone_stacking_policy_handling(self):
228
264
        """Obey policy where possible, ignore otherwise."""
231
267
        parent_bzrdir.get_config().set_default_stack_on('stack-on')
232
268
        source = self.make_branch('source')
233
269
        target = source.bzrdir.clone('target').open_branch()
234
 
        try:
235
 
            self.assertEqual('../stack-on', target.get_stacked_on_url())
236
 
        except errors.UnstackableBranchFormat:
237
 
            pass
 
270
        if self.branch_format.supports_stacking():
 
271
            self.assertEqual('../stack-on', target.get_stacked_on_url())
 
272
        else:
 
273
            self.assertRaises(
 
274
                errors.UnstackableBranchFormat, target.get_stacked_on_url)
 
275
 
 
276
    def test_sprout_to_smart_server_stacking_policy_handling(self):
 
277
        """Obey policy where possible, ignore otherwise."""
 
278
        if isinstance(self.branch_format, branch.BzrBranchFormat4):
 
279
            raise TestNotApplicable('Branch format 4 is not usable via HPSS.')
 
280
        stack_on = self.make_branch('stack-on')
 
281
        parent_bzrdir = self.make_bzrdir('.', format='default')
 
282
        parent_bzrdir.get_config().set_default_stack_on('stack-on')
 
283
        source = self.make_branch('source')
 
284
        url = self.make_smart_server('target').base
 
285
        target = source.bzrdir.sprout(url).open_branch()
 
286
        if self.branch_format.supports_stacking():
 
287
            self.assertEqual('../stack-on', target.get_stacked_on_url())
 
288
        else:
 
289
            self.assertRaises(
 
290
                errors.UnstackableBranchFormat, target.get_stacked_on_url)
238
291
 
239
292
    def prepare_stacked_on_fetch(self):
240
293
        stack_on = self.make_branch_and_tree('stack-on')
241
294
        stack_on.commit('first commit', rev_id='rev1')
242
295
        try:
243
296
            stacked_dir = stack_on.bzrdir.sprout('stacked', stacked=True)
244
 
        except (errors.UnstackableRepositoryFormat,
245
 
                errors.UnstackableBranchFormat):
 
297
        except unstackable_format_errors, e:
246
298
            raise TestNotApplicable('Format does not support stacking.')
247
299
        unstacked = self.make_repository('unstacked')
248
300
        return stacked_dir.open_workingtree(), unstacked
258
310
        unstacked.fetch(stacked.branch.repository, 'rev2')
259
311
        unstacked.get_revision('rev1')
260
312
        unstacked.get_revision('rev2')
 
313
        self.check_lines_added_or_present(stacked.branch, 'rev1')
 
314
        self.check_lines_added_or_present(stacked.branch, 'rev2')
261
315
 
262
316
    def test_autopack_when_stacked(self):
263
317
        # in bzr.dev as of 20080730, autopack was reported to fail in stacked
299
353
        other_tree = other_dir.open_workingtree()
300
354
        text_lines[9] = 'changed in other\n'
301
355
        self.build_tree_contents([('other/a', ''.join(text_lines))])
302
 
        other_tree.commit('commit in other')
 
356
        stacked_revid = other_tree.commit('commit in other')
303
357
        # this should have generated a delta; try to pull that across
304
358
        # bug 252821 caused a RevisionNotPresent here...
305
359
        stacked_tree.pull(other_tree.branch)
306
360
        stacked_tree.branch.repository.pack()
307
361
        stacked_tree.branch.check()
 
362
        self.check_lines_added_or_present(stacked_tree.branch, stacked_revid)
308
363
 
309
364
    def test_fetch_revisions_with_file_changes(self):
310
365
        # Fetching revisions including file changes into a stacked branch
322
377
        target = self.make_branch('target')
323
378
        try:
324
379
            target.set_stacked_on_url('../stacked-on')
325
 
        except (errors.UnstackableRepositoryFormat,
326
 
                errors.UnstackableBranchFormat):
 
380
        except unstackable_format_errors, e:
327
381
            raise TestNotApplicable('Format does not support stacking.')
328
382
 
329
383
        # Change the source branch.
336
390
        rtree.lock_read()
337
391
        self.addCleanup(rtree.unlock)
338
392
        self.assertEqual('new content', rtree.get_file_by_path('a').read())
 
393
        self.check_lines_added_or_present(target, 'rev2')
 
394
 
 
395
    def test_transform_fallback_location_hook(self):
 
396
        # The 'transform_fallback_location' branch hook allows us to inspect
 
397
        # and transform the URL of the fallback location for the branch.
 
398
        stack_on = self.make_branch('stack-on')
 
399
        stacked = self.make_branch('stacked')
 
400
        try:
 
401
            stacked.set_stacked_on_url('../stack-on')
 
402
        except unstackable_format_errors, e:
 
403
            raise TestNotApplicable('Format does not support stacking.')
 
404
        self.get_transport().rename('stack-on', 'new-stack-on')
 
405
        hook_calls = []
 
406
        def hook(stacked_branch, url):
 
407
            hook_calls.append(url)
 
408
            return '../new-stack-on'
 
409
        branch.Branch.hooks.install_named_hook(
 
410
            'transform_fallback_location', hook, None)
 
411
        branch.Branch.open('stacked')
 
412
        self.assertEqual(['../stack-on'], hook_calls)
 
413
 
 
414
    def test_stack_on_repository_branch(self):
 
415
        # Stacking should work when the repo isn't co-located with the
 
416
        # stack-on branch.
 
417
        try:
 
418
            repo = self.make_repository('repo', shared=True)
 
419
        except errors.IncompatibleFormat:
 
420
            raise TestNotApplicable()
 
421
        # Avoid make_branch, which produces standalone branches.
 
422
        bzrdir = self.make_bzrdir('repo/stack-on')
 
423
        try:
 
424
            b = bzrdir.create_branch()
 
425
        except errors.UninitializableFormat:
 
426
            raise TestNotApplicable()
 
427
        transport = self.get_transport('stacked')
 
428
        b.bzrdir.clone_on_transport(transport, stacked_on=b.base)
 
429
        # Ensure that opening the branch doesn't raise.
 
430
        branch.Branch.open(transport.base)
 
431
 
 
432
 
 
433
class TestStackingConnections(
 
434
    transport_util.TestCaseWithConnectionHookedTransport):
 
435
 
 
436
    def setUp(self):
 
437
        super(TestStackingConnections, self).setUp()
 
438
        try:
 
439
            base_tree = self.make_branch_and_tree('base',
 
440
                                                  format=self.bzrdir_format)
 
441
        except errors.UninitializableFormat, e:
 
442
            raise TestNotApplicable(e)
 
443
        stacked = self.make_branch('stacked', format=self.bzrdir_format)
 
444
        try:
 
445
            stacked.set_stacked_on_url(base_tree.branch.base)
 
446
        except unstackable_format_errors, e:
 
447
            raise TestNotApplicable(e)
 
448
        base_tree.commit('first', rev_id='rev-base')
 
449
        stacked.set_last_revision_info(1, 'rev-base')
 
450
        stacked_relative = self.make_branch('stacked_relative',
 
451
                                            format=self.bzrdir_format)
 
452
        stacked_relative.set_stacked_on_url('../base')
 
453
        stacked.set_last_revision_info(1, 'rev-base')
 
454
        self.start_logging_connections()
 
455
 
 
456
    def test_open_stacked(self):
 
457
        b = branch.Branch.open(self.get_url('stacked'))
 
458
        rev = b.repository.get_revision('rev-base')
 
459
        self.assertEqual(1, len(self.connections))
 
460
 
 
461
    def test_open_stacked_relative(self):
 
462
        b = branch.Branch.open(self.get_url('stacked_relative'))
 
463
        rev = b.repository.get_revision('rev-base')
 
464
        self.assertEqual(1, len(self.connections))