~bzr-pqm/bzr/bzr.dev

1505.1.1 by John Arbash Meinel
Adding test for bound behavior
1
# Copyright (C) 2005 by Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
1997.1.5 by Robert Collins
``Branch.bind(other_branch)`` no longer takes a write lock on the
18
"""Tests of bound branches (binding, unbinding, commit, etc) command."""
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
19
20
import os
21
from cStringIO import StringIO
22
23
from bzrlib.branch import Branch
1694.2.6 by Martin Pool
[merge] bzr.dev
24
from bzrlib.bzrdir import (BzrDir, BzrDirFormat, BzrDirMetaFormat1)
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
25
from bzrlib.osutils import getcwd
26
from bzrlib.tests import TestCaseWithTransport
27
import bzrlib.urlutils as urlutils
1587.1.6 by Robert Collins
Update bound branch implementation to 0.8.
28
from bzrlib.workingtree import WorkingTree
29
30
31
class TestLegacyFormats(TestCaseWithTransport):
32
    
33
    def setUp(self):
34
        super(TestLegacyFormats, self).setUp()
35
        self.build_tree(['master/', 'child/'])
36
        self.run_bzr('init', 'master')
1857.1.20 by Aaron Bentley
Strip out all the EnumOption stuff
37
        self.run_bzr('init', '--format=weave', 'child')
1587.1.6 by Robert Collins
Update bound branch implementation to 0.8.
38
        os.chdir('child')
39
    
40
    def test_bind_format_6_bzrdir(self):
41
        # bind on a format 6 bzrdir should error
42
        out,err = self.run_bzr('bind', '../master', retcode=3)
43
        self.assertEqual('', out)
1685.1.34 by John Arbash Meinel
Another test which assumed the output was a local path not a url
44
        # TODO: jam 20060427 Probably something like this really should
45
        #       print out the actual path, rather than the URL
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
46
        cwd = urlutils.local_path_to_url(getcwd())
1587.1.6 by Robert Collins
Update bound branch implementation to 0.8.
47
        self.assertEqual('bzr: ERROR: To use this feature you must '
1685.1.34 by John Arbash Meinel
Another test which assumed the output was a local path not a url
48
                         'upgrade your branch at %s/.\n' % cwd, err)
1587.1.6 by Robert Collins
Update bound branch implementation to 0.8.
49
    
50
    def test_unbind_format_6_bzrdir(self):
51
        # bind on a format 6 bzrdir should error
52
        out,err = self.run_bzr('unbind', retcode=3)
53
        self.assertEqual('', out)
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
54
        cwd = urlutils.local_path_to_url(getcwd())
1587.1.6 by Robert Collins
Update bound branch implementation to 0.8.
55
        self.assertEqual('bzr: ERROR: To use this feature you must '
1685.1.34 by John Arbash Meinel
Another test which assumed the output was a local path not a url
56
                         'upgrade your branch at %s/.\n' % cwd, err)
1587.1.6 by Robert Collins
Update bound branch implementation to 0.8.
57
58
59
class TestBoundBranches(TestCaseWithTransport):
60
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
61
    def create_branches(self):
1505.1.6 by John Arbash Meinel
Cleaned up tests and code, all bound branch tests succeed.
62
        bzr = self.run_bzr
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
63
        self.build_tree(['base/', 'base/a', 'base/b'])
64
1607.1.14 by Robert Collins
Reduce lock thrashing somewhat - drops bound branch tests lock count from 6554 to 4456 locks.
65
        branch = self.init_meta_branch('base')
66
        tree = branch.bzrdir.open_workingtree()
67
        tree.lock_write()
68
        tree.add(['a', 'b'])
69
        tree.commit('init')
70
        tree.unlock()
71
72
        self.run_bzr('checkout', 'base', 'child')
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
73
1505.1.24 by John Arbash Meinel
Updated commit to handle bound branches. Included test to handle commit after merge
74
        self.check_revno(1, 'child')
1587.1.6 by Robert Collins
Update bound branch implementation to 0.8.
75
        d = BzrDir.open('child')
76
        self.assertNotEqual(None, d.open_branch().get_master_branch())
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
77
1607.1.14 by Robert Collins
Reduce lock thrashing somewhat - drops bound branch tests lock count from 6554 to 4456 locks.
78
    def check_revno(self, val, loc='.'):
79
        self.assertEqual(
80
            val, len(BzrDir.open(loc).open_branch().revision_history()))
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
81
1505.1.4 by John Arbash Meinel
Wrote a simple test which actually makes a branch become bound, and made it work
82
    def test_simple_binding(self):
83
        self.build_tree(['base/', 'base/a', 'base/b'])
84
1587.1.6 by Robert Collins
Update bound branch implementation to 0.8.
85
        self.init_meta_branch('base')
86
        self.run_bzr('add', 'base')
87
        self.run_bzr('commit', '-m', 'init', 'base')
1505.1.4 by John Arbash Meinel
Wrote a simple test which actually makes a branch become bound, and made it work
88
1587.1.6 by Robert Collins
Update bound branch implementation to 0.8.
89
        self.run_bzr('branch', 'base', 'child')
1505.1.4 by John Arbash Meinel
Wrote a simple test which actually makes a branch become bound, and made it work
90
91
        os.chdir('child')
1587.1.6 by Robert Collins
Update bound branch implementation to 0.8.
92
        self.run_bzr('bind', '../base')
93
94
        d = BzrDir.open('')
95
        self.assertNotEqual(None, d.open_branch().get_master_branch())
96
97
        self.run_bzr('unbind')
98
        self.assertEqual(None, d.open_branch().get_master_branch())
99
100
        self.run_bzr('unbind', retcode=3)
101
102
    def init_meta_branch(self, path):
103
        old_format = BzrDirFormat.get_default_format()
104
        BzrDirFormat.set_default_format(BzrDirMetaFormat1())
105
        try:
1607.1.14 by Robert Collins
Reduce lock thrashing somewhat - drops bound branch tests lock count from 6554 to 4456 locks.
106
            return BzrDir.create_branch_convenience(
107
                path, BzrDirMetaFormat1())
1587.1.6 by Robert Collins
Update bound branch implementation to 0.8.
108
        finally:
109
            BzrDirFormat.set_default_format(old_format)
1505.1.5 by John Arbash Meinel
Added a test for the unbind command.
110
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
111
    def test_bound_commit(self):
112
        bzr = self.run_bzr
113
        self.create_branches()
114
115
        os.chdir('child')
116
        open('a', 'wb').write('new contents\n')
117
        bzr('commit', '-m', 'child')
118
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
119
        self.check_revno(2)
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
120
121
        # Make sure it committed on the parent
1505.1.24 by John Arbash Meinel
Updated commit to handle bound branches. Included test to handle commit after merge
122
        self.check_revno(2, '../base')
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
123
1505.1.4 by John Arbash Meinel
Wrote a simple test which actually makes a branch become bound, and made it work
124
    def test_bound_fail(self):
1505.1.26 by John Arbash Meinel
Created a set of tests which bind to an sftp branch. Found some bugs, need to fix commit.
125
        # Make sure commit fails if out of date.
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
126
        bzr = self.run_bzr
127
        self.create_branches()
128
129
        os.chdir('base')
130
        open('a', 'wb').write('new base contents\n')
131
        bzr('commit', '-m', 'base')
1587.1.11 by Robert Collins
Local commits appear to be working properly.
132
        self.check_revno(2)
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
133
134
        os.chdir('../child')
1587.1.11 by Robert Collins
Local commits appear to be working properly.
135
        self.check_revno(1)
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
136
        open('b', 'wb').write('new b child contents\n')
1505.1.16 by John Arbash Meinel
[merge] robertc's integration, updated tests to check for retcode=3
137
        bzr('commit', '-m', 'child', retcode=3)
1587.1.11 by Robert Collins
Local commits appear to be working properly.
138
        self.check_revno(1)
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
139
1505.1.13 by John Arbash Meinel
Adding the bzr update command, to update checkouts and bound branches.
140
        bzr('update')
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
141
        self.check_revno(2)
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
142
143
        bzr('commit', '-m', 'child')
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
144
        self.check_revno(3)
1505.1.24 by John Arbash Meinel
Updated commit to handle bound branches. Included test to handle commit after merge
145
        self.check_revno(3, '../base')
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
146
1505.1.2 by John Arbash Meinel
(broken) working on implementing bound branches.
147
    def test_double_binding(self):
148
        bzr = self.run_bzr
149
        self.create_branches()
150
151
        bzr('branch', 'child', 'child2')
152
        os.chdir('child2')
153
1505.1.6 by John Arbash Meinel
Cleaned up tests and code, all bound branch tests succeed.
154
        # Double binding succeeds, but committing to child2 should fail
155
        bzr('bind', '../child')
1505.1.2 by John Arbash Meinel
(broken) working on implementing bound branches.
156
1505.1.16 by John Arbash Meinel
[merge] robertc's integration, updated tests to check for retcode=3
157
        bzr('commit', '-m', 'child2', '--unchanged', retcode=3)
1505.1.2 by John Arbash Meinel
(broken) working on implementing bound branches.
158
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
159
    def test_unbinding(self):
160
        bzr = self.run_bzr
161
        self.create_branches()
162
163
        os.chdir('base')
164
        open('a', 'wb').write('new base contents\n')
165
        bzr('commit', '-m', 'base')
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
166
        self.check_revno(2)
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
167
168
        os.chdir('../child')
169
        open('b', 'wb').write('new b child contents\n')
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
170
        self.check_revno(1)
1505.1.16 by John Arbash Meinel
[merge] robertc's integration, updated tests to check for retcode=3
171
        bzr('commit', '-m', 'child', retcode=3)
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
172
        self.check_revno(1)
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
173
        bzr('unbind')
174
        bzr('commit', '-m', 'child')
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
175
        self.check_revno(2)
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
176
1505.1.16 by John Arbash Meinel
[merge] robertc's integration, updated tests to check for retcode=3
177
        bzr('bind', retcode=3)
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
178
179
    def test_commit_remote_bound(self):
180
        # It is not possible to commit to a branch
181
        # which is bound to a branch which is bound
182
        bzr = self.run_bzr
1505.1.6 by John Arbash Meinel
Cleaned up tests and code, all bound branch tests succeed.
183
        self.create_branches()
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
184
        bzr('branch', 'base', 'newbase')
185
        os.chdir('base')
186
        
187
        # There is no way to know that B has already
188
        # been bound by someone else, otherwise it
189
        # might be nice if this would fail
190
        bzr('bind', '../newbase')
191
192
        os.chdir('../child')
1505.1.16 by John Arbash Meinel
[merge] robertc's integration, updated tests to check for retcode=3
193
        bzr('commit', '-m', 'failure', '--unchanged', retcode=3)
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
194
195
    def test_pull_updates_both(self):
196
        bzr = self.run_bzr
197
        self.create_branches()
198
        bzr('branch', 'base', 'newchild')
199
        os.chdir('newchild')
200
        open('b', 'wb').write('newchild b contents\n')
201
        bzr('commit', '-m', 'newchild')
202
        self.check_revno(2)
203
204
        os.chdir('../child')
205
        # The pull should succeed, and update
206
        # the bound parent branch
207
        bzr('pull', '../newchild')
208
        self.check_revno(2)
209
1505.1.24 by John Arbash Meinel
Updated commit to handle bound branches. Included test to handle commit after merge
210
        self.check_revno(2, '../base')
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
211
212
    def test_bind_diverged(self):
213
        bzr = self.run_bzr
214
        self.create_branches()
215
216
        os.chdir('child')
217
        bzr('unbind')
218
219
        bzr('commit', '-m', 'child', '--unchanged')
220
        self.check_revno(2)
221
222
        os.chdir('../base')
223
        self.check_revno(1)
224
        bzr('commit', '-m', 'base', '--unchanged')
225
        self.check_revno(2)
226
227
        os.chdir('../child')
228
        # These branches have diverged
1505.1.16 by John Arbash Meinel
[merge] robertc's integration, updated tests to check for retcode=3
229
        bzr('bind', '../base', retcode=3)
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
230
231
        # TODO: In the future, this might require actual changes
232
        # to have occurred, rather than just a new revision entry
233
        bzr('merge', '../base')
234
        bzr('commit', '-m', 'merged')
235
        self.check_revno(3)
236
1997.1.5 by Robert Collins
``Branch.bind(other_branch)`` no longer takes a write lock on the
237
        # After binding, the revision history should be unaltered
238
        base_branch = Branch.open('../base')
239
        child_branch = Branch.open('.')
240
        # take a copy before
241
        base_history = base_branch.revision_history()
242
        child_history = child_branch.revision_history()
243
1505.1.13 by John Arbash Meinel
Adding the bzr update command, to update checkouts and bound branches.
244
        # After a merge, trying to bind again should succeed
1997.1.5 by Robert Collins
``Branch.bind(other_branch)`` no longer takes a write lock on the
245
        # keeping the new change as a local commit.
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
246
        bzr('bind', '../base')
1505.1.13 by John Arbash Meinel
Adding the bzr update command, to update checkouts and bound branches.
247
        self.check_revno(3)
1997.1.5 by Robert Collins
``Branch.bind(other_branch)`` no longer takes a write lock on the
248
        self.check_revno(2, '../base')
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
249
1997.1.5 by Robert Collins
``Branch.bind(other_branch)`` no longer takes a write lock on the
250
        # and compare the revision history now
251
        self.assertEqual(base_history, base_branch.revision_history())
252
        self.assertEqual(child_history, child_branch.revision_history())
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
253
254
    def test_bind_parent_ahead(self):
255
        bzr = self.run_bzr
256
        self.create_branches()
257
258
        os.chdir('child')
259
        bzr('unbind')
260
261
        os.chdir('../base')
262
        bzr('commit', '-m', 'base', '--unchanged')
263
264
        os.chdir('../child')
265
        self.check_revno(1)
266
        bzr('bind', '../base')
267
1997.1.5 by Robert Collins
``Branch.bind(other_branch)`` no longer takes a write lock on the
268
        # binding does not pull data:
269
        self.check_revno(1)
1505.1.11 by John Arbash Meinel
Adding a little bit more to the test suite.
270
        bzr('unbind')
271
272
        # Check and make sure it also works if parent is ahead multiple
273
        os.chdir('../base')
274
        bzr('commit', '-m', 'base 3', '--unchanged')
275
        bzr('commit', '-m', 'base 4', '--unchanged')
276
        bzr('commit', '-m', 'base 5', '--unchanged')
277
        self.check_revno(5)
278
279
        os.chdir('../child')
1997.1.5 by Robert Collins
``Branch.bind(other_branch)`` no longer takes a write lock on the
280
        self.check_revno(1)
1587.1.14 by Robert Collins
Make bound branch creation happen via 'checkout'
281
        bzr('bind', '../base')
1997.1.5 by Robert Collins
``Branch.bind(other_branch)`` no longer takes a write lock on the
282
        self.check_revno(1)
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
283
284
    def test_bind_child_ahead(self):
1607.1.14 by Robert Collins
Reduce lock thrashing somewhat - drops bound branch tests lock count from 6554 to 4456 locks.
285
        # test binding when the master branches history is a prefix of the 
1997.1.5 by Robert Collins
``Branch.bind(other_branch)`` no longer takes a write lock on the
286
        # childs - it should bind ok but the revision histories should not
287
        # be altered
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
288
        bzr = self.run_bzr
289
        self.create_branches()
290
291
        os.chdir('child')
292
        bzr('unbind')
293
        bzr('commit', '-m', 'child', '--unchanged')
294
        self.check_revno(2)
295
        self.check_revno(1, '../base')
296
297
        bzr('bind', '../base')
1997.1.5 by Robert Collins
``Branch.bind(other_branch)`` no longer takes a write lock on the
298
        self.check_revno(1, '../base')
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
299
1505.1.11 by John Arbash Meinel
Adding a little bit more to the test suite.
300
        # Check and make sure it also works if child is ahead multiple
301
        bzr('unbind')
302
        bzr('commit', '-m', 'child 3', '--unchanged')
303
        bzr('commit', '-m', 'child 4', '--unchanged')
304
        bzr('commit', '-m', 'child 5', '--unchanged')
305
        self.check_revno(5)
306
1997.1.5 by Robert Collins
``Branch.bind(other_branch)`` no longer takes a write lock on the
307
        self.check_revno(1, '../base')
1587.1.14 by Robert Collins
Make bound branch creation happen via 'checkout'
308
        bzr('bind', '../base')
1997.1.5 by Robert Collins
``Branch.bind(other_branch)`` no longer takes a write lock on the
309
        self.check_revno(1, '../base')
1505.1.11 by John Arbash Meinel
Adding a little bit more to the test suite.
310
1505.1.24 by John Arbash Meinel
Updated commit to handle bound branches. Included test to handle commit after merge
311
    def test_commit_after_merge(self):
312
        bzr = self.run_bzr
313
        self.create_branches()
314
315
        # We want merge to be able to be a local only
316
        # operation, because it can be without violating
317
        # the binding invariants.
318
        # But we can't fail afterwards
319
320
        bzr('branch', 'child', 'other')
321
322
        os.chdir('other')
323
        open('c', 'wb').write('file c\n')
324
        bzr('add', 'c')
325
        bzr('commit', '-m', 'adding c')
326
        new_rev_id = bzr('revision-history')[0].strip().split('\n')[-1]
327
328
        os.chdir('../child')
329
        bzr('merge', '../other')
330
331
        self.failUnlessExists('c')
1908.6.11 by Robert Collins
Remove usage of tree.pending_merges().
332
        tree = WorkingTree.open('.') # opens child
333
        self.assertEqual([new_rev_id], tree.get_parent_ids()[1:])
1505.1.24 by John Arbash Meinel
Updated commit to handle bound branches. Included test to handle commit after merge
334
335
        # Make sure the local branch has the installed revision
336
        bzr('cat-revision', new_rev_id)
337
        
338
        # And make sure that the base tree does not
339
        os.chdir('../base')
340
        bzr('cat-revision', new_rev_id, retcode=3)
341
342
        # Commit should succeed, and cause merged revisions to
343
        # be pulled into base
344
        os.chdir('../child')
345
        bzr('commit', '-m', 'merge other')
346
347
        self.check_revno(2)
348
349
        os.chdir('../base')
350
        self.check_revno(2)
351
352
        bzr('cat-revision', new_rev_id)
353
1505.1.25 by John Arbash Meinel
Updated pull. Now all paths which call set_revision_history maintain the branch invariant. All tests pass.
354
    def test_pull_overwrite_fails(self):
355
        bzr = self.run_bzr
356
        self.create_branches()
357
358
        bzr('branch', 'child', 'other')
359
        
360
        os.chdir('other')
361
        open('a', 'wb').write('new contents\n')
362
        bzr('commit', '-m', 'changed a')
363
        self.check_revno(2)
364
        open('a', 'ab').write('and then some\n')
365
        bzr('commit', '-m', 'another a')
366
        self.check_revno(3)
367
        open('a', 'ab').write('and some more\n')
368
        bzr('commit', '-m', 'yet another a')
369
        self.check_revno(4)
370
371
        os.chdir('../child')
372
        open('a', 'wb').write('also changed a\n')
373
        bzr('commit', '-m', 'child modified a')
374
375
        self.check_revno(2)
376
        self.check_revno(2, '../base')
377
378
        # It might be possible that we want pull --overwrite to
379
        # actually succeed.
380
        # If we want it, just change this test to make sure that 
381
        # both base and child are updated properly
382
        bzr('pull', '--overwrite', '../other', retcode=3)
383
384
        # It should fail without changing the local revision
385
        self.check_revno(2)
386
        self.check_revno(2, '../base')
1505.1.24 by John Arbash Meinel
Updated commit to handle bound branches. Included test to handle commit after merge
387
1505.1.28 by John Arbash Meinel
todo
388
    # TODO: jam 20051230 Test that commit & pull fail when the branch we 
389
    #       are bound to is not available
390
391