~bzr-pqm/bzr/bzr.dev

1505.1.1 by John Arbash Meinel
Adding test for bound behavior
1
# Copyright (C) 2005 by 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
18
"""Tests of bound branches (binding, unbinding, commit, etc) command.
19
"""
20
21
import os
22
from cStringIO import StringIO
23
1587.1.6 by Robert Collins
Update bound branch implementation to 0.8.
24
from bzrlib.tests import TestCaseWithTransport
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
25
from bzrlib.branch import Branch
1587.1.6 by Robert Collins
Update bound branch implementation to 0.8.
26
from bzrlib.bzrdir import (BzrDir,
27
                           BzrDirFormat,
28
                           BzrDirFormat6,
29
                           BzrDirMetaFormat1,
30
                           )
31
from bzrlib.workingtree import WorkingTree
32
33
34
class TestLegacyFormats(TestCaseWithTransport):
35
    
36
    def setUp(self):
37
        super(TestLegacyFormats, self).setUp()
38
        self.build_tree(['master/', 'child/'])
39
        self.run_bzr('init', 'master')
40
        old_format = BzrDirFormat.get_default_format()
41
        BzrDirFormat.set_default_format(BzrDirFormat6())
42
        try:
43
            self.run_bzr('init', 'child')
44
        finally:
45
            BzrDirFormat.set_default_format(old_format)
46
        os.chdir('child')
47
    
48
    def test_bind_format_6_bzrdir(self):
49
        # bind on a format 6 bzrdir should error
50
        out,err = self.run_bzr('bind', '../master', retcode=3)
51
        self.assertEqual('', out)
52
        self.assertEqual('bzr: ERROR: To use this feature you must '
53
                         'upgrade your branch at %s/.\n' % os.getcwdu(), err)
54
    
55
    def test_unbind_format_6_bzrdir(self):
56
        # bind on a format 6 bzrdir should error
57
        out,err = self.run_bzr('unbind', retcode=3)
58
        self.assertEqual('', out)
59
        self.assertEqual('bzr: ERROR: To use this feature you must '
60
                         'upgrade your branch at %s/.\n' % os.getcwdu(), err)
61
62
63
class TestBoundBranches(TestCaseWithTransport):
64
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
65
    def create_branches(self):
1505.1.6 by John Arbash Meinel
Cleaned up tests and code, all bound branch tests succeed.
66
        bzr = self.run_bzr
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
67
        self.build_tree(['base/', 'base/a', 'base/b'])
68
1587.1.6 by Robert Collins
Update bound branch implementation to 0.8.
69
        self.init_meta_branch('base')
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
70
        os.chdir('base')
1505.1.6 by John Arbash Meinel
Cleaned up tests and code, all bound branch tests succeed.
71
        bzr('add')
72
        bzr('commit', '-m', 'init')
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
73
74
        os.chdir('..')
75
1587.1.14 by Robert Collins
Make bound branch creation happen via 'checkout'
76
        bzr('checkout', 'base', 'child')
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
77
78
        self.failUnlessExists('child')
79
1505.1.24 by John Arbash Meinel
Updated commit to handle bound branches. Included test to handle commit after merge
80
        self.check_revno(1, 'child')
1587.1.6 by Robert Collins
Update bound branch implementation to 0.8.
81
        d = BzrDir.open('child')
82
        self.assertNotEqual(None, d.open_branch().get_master_branch())
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
83
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
84
    def check_revno(self, val, loc=None):
85
        if loc is not None:
86
            cwd = os.getcwd()
87
            os.chdir(loc)
1505.1.24 by John Arbash Meinel
Updated commit to handle bound branches. Included test to handle commit after merge
88
        self.assertEquals(str(val), self.run_bzr('revno')[0].strip())
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
89
        if loc is not None:
90
            os.chdir(cwd)
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
91
1505.1.4 by John Arbash Meinel
Wrote a simple test which actually makes a branch become bound, and made it work
92
    def test_simple_binding(self):
93
        self.build_tree(['base/', 'base/a', 'base/b'])
94
1587.1.6 by Robert Collins
Update bound branch implementation to 0.8.
95
        self.init_meta_branch('base')
96
        self.run_bzr('add', 'base')
97
        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
98
1587.1.6 by Robert Collins
Update bound branch implementation to 0.8.
99
        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
100
101
        os.chdir('child')
1587.1.6 by Robert Collins
Update bound branch implementation to 0.8.
102
        self.run_bzr('bind', '../base')
103
104
        d = BzrDir.open('')
105
        self.assertNotEqual(None, d.open_branch().get_master_branch())
106
107
        self.run_bzr('unbind')
108
        self.assertEqual(None, d.open_branch().get_master_branch())
109
110
        self.run_bzr('unbind', retcode=3)
111
112
    def init_meta_branch(self, path):
113
        old_format = BzrDirFormat.get_default_format()
114
        BzrDirFormat.set_default_format(BzrDirMetaFormat1())
115
        try:
116
            self.run_bzr('init', path)
117
        finally:
118
            BzrDirFormat.set_default_format(old_format)
1505.1.5 by John Arbash Meinel
Added a test for the unbind command.
119
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
120
    def test_bound_commit(self):
121
        bzr = self.run_bzr
122
        self.create_branches()
123
124
        os.chdir('child')
125
        open('a', 'wb').write('new contents\n')
126
        bzr('commit', '-m', 'child')
127
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
128
        self.check_revno(2)
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
129
130
        # 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
131
        self.check_revno(2, '../base')
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
132
1505.1.4 by John Arbash Meinel
Wrote a simple test which actually makes a branch become bound, and made it work
133
    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.
134
        # Make sure commit fails if out of date.
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
135
        bzr = self.run_bzr
136
        self.create_branches()
137
138
        os.chdir('base')
139
        open('a', 'wb').write('new base contents\n')
140
        bzr('commit', '-m', 'base')
1587.1.11 by Robert Collins
Local commits appear to be working properly.
141
        self.check_revno(2)
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
142
143
        os.chdir('../child')
1587.1.11 by Robert Collins
Local commits appear to be working properly.
144
        self.check_revno(1)
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
145
        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
146
        bzr('commit', '-m', 'child', retcode=3)
1587.1.11 by Robert Collins
Local commits appear to be working properly.
147
        self.check_revno(1)
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
148
1505.1.13 by John Arbash Meinel
Adding the bzr update command, to update checkouts and bound branches.
149
        bzr('update')
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
150
        self.check_revno(2)
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
151
152
        bzr('commit', '-m', 'child')
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
153
        self.check_revno(3)
1505.1.24 by John Arbash Meinel
Updated commit to handle bound branches. Included test to handle commit after merge
154
        self.check_revno(3, '../base')
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
155
1505.1.2 by John Arbash Meinel
(broken) working on implementing bound branches.
156
    def test_double_binding(self):
157
        bzr = self.run_bzr
158
        self.create_branches()
159
160
        bzr('branch', 'child', 'child2')
161
        os.chdir('child2')
162
1505.1.6 by John Arbash Meinel
Cleaned up tests and code, all bound branch tests succeed.
163
        # Double binding succeeds, but committing to child2 should fail
164
        bzr('bind', '../child')
1505.1.2 by John Arbash Meinel
(broken) working on implementing bound branches.
165
1505.1.16 by John Arbash Meinel
[merge] robertc's integration, updated tests to check for retcode=3
166
        bzr('commit', '-m', 'child2', '--unchanged', retcode=3)
1505.1.2 by John Arbash Meinel
(broken) working on implementing bound branches.
167
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
168
    def test_unbinding(self):
169
        bzr = self.run_bzr
170
        self.create_branches()
171
172
        os.chdir('base')
173
        open('a', 'wb').write('new base contents\n')
174
        bzr('commit', '-m', 'base')
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
177
        os.chdir('../child')
178
        open('b', 'wb').write('new b child contents\n')
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
179
        self.check_revno(1)
1505.1.16 by John Arbash Meinel
[merge] robertc's integration, updated tests to check for retcode=3
180
        bzr('commit', '-m', 'child', retcode=3)
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
181
        self.check_revno(1)
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
182
        bzr('unbind')
183
        bzr('commit', '-m', 'child')
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
184
        self.check_revno(2)
1505.1.1 by John Arbash Meinel
Adding test for bound behavior
185
1505.1.16 by John Arbash Meinel
[merge] robertc's integration, updated tests to check for retcode=3
186
        bzr('bind', retcode=3)
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
187
188
    def test_commit_remote_bound(self):
189
        # It is not possible to commit to a branch
190
        # which is bound to a branch which is bound
191
        bzr = self.run_bzr
1505.1.6 by John Arbash Meinel
Cleaned up tests and code, all bound branch tests succeed.
192
        self.create_branches()
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
193
        bzr('branch', 'base', 'newbase')
194
        os.chdir('base')
195
        
196
        # There is no way to know that B has already
197
        # been bound by someone else, otherwise it
198
        # might be nice if this would fail
199
        bzr('bind', '../newbase')
200
201
        os.chdir('../child')
1505.1.16 by John Arbash Meinel
[merge] robertc's integration, updated tests to check for retcode=3
202
        bzr('commit', '-m', 'failure', '--unchanged', retcode=3)
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
203
204
    def test_pull_updates_both(self):
205
        bzr = self.run_bzr
206
        self.create_branches()
207
        bzr('branch', 'base', 'newchild')
208
        os.chdir('newchild')
209
        open('b', 'wb').write('newchild b contents\n')
210
        bzr('commit', '-m', 'newchild')
211
        self.check_revno(2)
212
213
        os.chdir('../child')
214
        # The pull should succeed, and update
215
        # the bound parent branch
216
        bzr('pull', '../newchild')
217
        self.check_revno(2)
218
1505.1.24 by John Arbash Meinel
Updated commit to handle bound branches. Included test to handle commit after merge
219
        self.check_revno(2, '../base')
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
220
221
    def test_bind_diverged(self):
222
        bzr = self.run_bzr
223
        self.create_branches()
224
225
        os.chdir('child')
226
        bzr('unbind')
227
228
        bzr('commit', '-m', 'child', '--unchanged')
229
        self.check_revno(2)
230
231
        os.chdir('../base')
232
        self.check_revno(1)
233
        bzr('commit', '-m', 'base', '--unchanged')
234
        self.check_revno(2)
235
236
        os.chdir('../child')
237
        # These branches have diverged
1505.1.16 by John Arbash Meinel
[merge] robertc's integration, updated tests to check for retcode=3
238
        bzr('bind', '../base', retcode=3)
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
239
240
        # TODO: In the future, this might require actual changes
241
        # to have occurred, rather than just a new revision entry
242
        bzr('merge', '../base')
243
        bzr('commit', '-m', 'merged')
244
        self.check_revno(3)
245
1505.1.13 by John Arbash Meinel
Adding the bzr update command, to update checkouts and bound branches.
246
        # After a merge, trying to bind again should succeed
247
        # by pushing the new change to base
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
248
        bzr('bind', '../base')
1505.1.13 by John Arbash Meinel
Adding the bzr update command, to update checkouts and bound branches.
249
        self.check_revno(3)
250
        self.check_revno(3, '../base')
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
251
252
        # After binding, the revision history should be identical
1505.1.24 by John Arbash Meinel
Updated commit to handle bound branches. Included test to handle commit after merge
253
        child_rh = bzr('revision-history')[0]
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
254
        os.chdir('../base')
1505.1.24 by John Arbash Meinel
Updated commit to handle bound branches. Included test to handle commit after merge
255
        base_rh = bzr('revision-history')[0]
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
256
        self.assertEquals(child_rh, base_rh)
257
258
    def test_bind_parent_ahead(self):
259
        bzr = self.run_bzr
260
        self.create_branches()
261
262
        os.chdir('child')
263
        bzr('unbind')
264
265
        os.chdir('../base')
266
        bzr('commit', '-m', 'base', '--unchanged')
267
268
        os.chdir('../child')
269
        self.check_revno(1)
270
        bzr('bind', '../base')
271
272
        self.check_revno(2)
1505.1.11 by John Arbash Meinel
Adding a little bit more to the test suite.
273
        bzr('unbind')
274
275
        # Check and make sure it also works if parent is ahead multiple
276
        os.chdir('../base')
277
        bzr('commit', '-m', 'base 3', '--unchanged')
278
        bzr('commit', '-m', 'base 4', '--unchanged')
279
        bzr('commit', '-m', 'base 5', '--unchanged')
280
        self.check_revno(5)
281
282
        os.chdir('../child')
283
        self.check_revno(2)
1587.1.14 by Robert Collins
Make bound branch creation happen via 'checkout'
284
        bzr('bind', '../base')
1505.1.11 by John Arbash Meinel
Adding a little bit more to the test suite.
285
        self.check_revno(5)
1505.1.3 by John Arbash Meinel
(broken) Adding more tests, and some functionality
286
287
    def test_bind_child_ahead(self):
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')
298
        self.check_revno(2, '../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
307
        self.check_revno(2, '../base')
1587.1.14 by Robert Collins
Make bound branch creation happen via 'checkout'
308
        bzr('bind', '../base')
1505.1.11 by John Arbash Meinel
Adding a little bit more to the test suite.
309
        self.check_revno(5, '../base')
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')
1587.1.6 by Robert Collins
Update bound branch implementation to 0.8.
332
        tree = WorkingTree.open('.')
333
        self.assertEqual([new_rev_id], tree.pending_merges())
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