~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Vincent Ladeuil
  • Date: 2012-01-05 14:26:58 UTC
  • mto: This revision was merged to the branch mainline in revision 6468.
  • Revision ID: v.ladeuil+lp@free.fr-20120105142658-vek3v6pzlxb751s2
Tests passing for a first rough version of a cached branch config store. The changes here are too invasive and several parallel proposals have been made. 

@only_raises is evil and gave a hard time since any exception during
save_changes() was swallowed.

Possible improvements: 

- add some needs_write_lock decorators to crucial
  methods (_set_config_location ?) but keep locking the branch at higher levels

- decorate branch.unlock to call stack.save if last_lock() it True
  outside of @only_raises scope (evil decorator)

- add @needs_write_lock to stack.set and stack.remove (will probably get
  rid of most testing issues) we probably need a specialized decorator
  that can relay to the store and from there to the branch or whatever is
  needed. This will also helps bzr config to get it right. The
  get_mutable_section trick should not be needed anymore either.

- decorate branch.unlock to call stack.save if last_lock() it True outside
  of @only_raises scope (evil decorator)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005-2012 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
60
60
 
61
61
        tree.bzrdir.sprout('child')
62
62
 
63
 
        os.chdir('child')
64
 
        self.run_bzr('bind ../base')
 
63
        self.run_bzr('bind ../base', working_dir='child')
65
64
 
66
 
        d = BzrDir.open('')
 
65
        d = BzrDir.open('child')
67
66
        self.assertNotEqual(None, d.open_branch().get_master_branch())
68
67
 
69
 
        self.run_bzr('unbind')
 
68
        self.run_bzr('unbind', working_dir='child')
70
69
        self.assertEqual(None, d.open_branch().get_master_branch())
71
70
 
72
 
        self.run_bzr('unbind', retcode=3)
 
71
        self.run_bzr('unbind', retcode=3, working_dir='child')
73
72
 
74
73
    def test_bind_branch6(self):
75
74
        branch1 = self.make_branch('branch1', format='dirstate-tags')
76
 
        os.chdir('branch1')
77
 
        error = self.run_bzr('bind', retcode=3)[1]
 
75
        error = self.run_bzr('bind', retcode=3, working_dir='branch1')[1]
78
76
        self.assertContainsRe(error, 'no previous location known')
79
77
 
80
78
    def setup_rebind(self, format):
85
83
 
86
84
    def test_rebind_branch6(self):
87
85
        self.setup_rebind('dirstate-tags')
88
 
        os.chdir('branch2')
89
 
        self.run_bzr('bind')
90
 
        b = Branch.open('.')
 
86
        self.run_bzr('bind', working_dir='branch2')
 
87
        b = Branch.open('branch2')
91
88
        self.assertContainsRe(b.get_bound_location(), '\/branch1\/$')
92
89
 
93
90
    def test_rebind_branch5(self):
94
91
        self.setup_rebind('knit')
95
 
        os.chdir('branch2')
96
 
        error = self.run_bzr('bind', retcode=3)[1]
 
92
        error = self.run_bzr('bind', retcode=3, working_dir='branch2')[1]
97
93
        self.assertContainsRe(error, 'old locations')
98
94
 
99
95
    def test_bound_commit(self):
132
128
    def test_double_binding(self):
133
129
        child_tree = self.create_branches()[1]
134
130
 
135
 
        child2_tree = child_tree.bzrdir.sprout('child2').open_workingtree()
 
131
        child_tree.bzrdir.sprout('child2')
136
132
 
137
 
        os.chdir('child2')
138
133
        # Double binding succeeds, but committing to child2 should fail
139
 
        self.run_bzr('bind ../child')
 
134
        self.run_bzr('bind ../child', working_dir='child2')
 
135
 
 
136
        child2_tree = BzrDir.open('child2').open_workingtree()
140
137
 
141
138
        self.assertRaises(errors.CommitToDoubleBoundBranch,
142
139
                child2_tree.commit, message='child2', allow_pointless=True)
152
149
        self.check_revno(2, 'base')
153
150
 
154
151
        self.check_revno(1, 'child')
155
 
        os.chdir('child')
156
 
        self.run_bzr("commit -m child", retcode=3)
157
 
        self.check_revno(1)
158
 
        self.run_bzr('unbind')
 
152
        self.run_bzr("commit -m child", retcode=3, working_dir='child')
 
153
        self.check_revno(1, 'child')
 
154
        self.run_bzr('unbind', working_dir='child')
 
155
        child_tree = BzrDir.open('child').open_workingtree()
159
156
        child_tree.commit(message='child')
160
 
        self.check_revno(2)
 
157
        self.check_revno(2, 'child')
161
158
 
162
159
    def test_commit_remote_bound(self):
163
160
        # It is not possible to commit to a branch
165
162
        base_tree, child_tree = self.create_branches()
166
163
        base_tree.bzrdir.sprout('newbase')
167
164
 
168
 
        os.chdir('base')
169
165
        # There is no way to know that B has already
170
166
        # been bound by someone else, otherwise it
171
167
        # might be nice if this would fail
172
 
        self.run_bzr('bind ../newbase')
 
168
        self.run_bzr('bind ../newbase', working_dir='base')
173
169
 
174
 
        os.chdir('../child')
175
 
        self.run_bzr('commit -m failure --unchanged', retcode=3)
 
170
        self.run_bzr('commit -m failure --unchanged', retcode=3,
 
171
                     working_dir='child')
176
172
 
177
173
    def test_pull_updates_both(self):
178
174
        base_tree = self.create_branches()[0]
181
177
        newchild_tree.commit(message='newchild')
182
178
        self.check_revno(2, 'newchild')
183
179
 
184
 
        os.chdir('child')
185
180
        # The pull should succeed, and update
186
181
        # the bound parent branch
187
 
        self.run_bzr('pull ../newchild')
188
 
        self.check_revno(2)
 
182
        self.run_bzr('pull ../newchild', working_dir='child')
 
183
        self.check_revno(2, 'child')
189
184
 
190
 
        self.check_revno(2, '../base')
 
185
        self.check_revno(2, 'base')
191
186
 
192
187
    def test_pull_local_updates_local(self):
193
188
        base_tree = self.create_branches()[0]
196
191
        newchild_tree.commit(message='newchild')
197
192
        self.check_revno(2, 'newchild')
198
193
 
199
 
        os.chdir('child')
200
194
        # The pull should succeed, and update
201
195
        # the bound parent branch
202
 
        self.run_bzr('pull ../newchild --local')
203
 
        self.check_revno(2)
 
196
        self.run_bzr('pull ../newchild --local', working_dir='child')
 
197
        self.check_revno(2, 'child')
204
198
 
205
 
        self.check_revno(1, '../base')
 
199
        self.check_revno(1, 'base')
206
200
 
207
201
    def test_bind_diverged(self):
208
202
        base_tree, child_tree = self.create_branches()
209
203
        base_branch = base_tree.branch
210
204
        child_branch = child_tree.branch
211
205
 
212
 
        os.chdir('child')
213
 
        self.run_bzr('unbind')
 
206
        self.run_bzr('unbind', working_dir='child')
214
207
 
 
208
        child_tree = BzrDir.open('child').open_workingtree()
215
209
        child_tree.commit(message='child', allow_pointless=True)
216
 
        self.check_revno(2)
 
210
        self.check_revno(2, 'child')
217
211
 
218
 
        os.chdir('..')
219
212
        self.check_revno(1, 'base')
220
213
        base_tree.commit(message='base', allow_pointless=True)
221
214
        self.check_revno(2, 'base')
222
215
 
223
 
        os.chdir('child')
224
216
        # These branches have diverged, but bind should succeed anyway
225
 
        self.run_bzr('bind ../base')
 
217
        self.run_bzr('bind ../base', working_dir='child')
226
218
 
227
219
        # This should turn the local commit into a merge
 
220
        child_tree = BzrDir.open('child').open_workingtree()
228
221
        child_tree.update()
229
222
        child_tree.commit(message='merged')
230
 
        self.check_revno(3)
 
223
        self.check_revno(3, 'child')
231
224
 
232
225
        self.assertEquals(
233
226
            child_tree.branch.last_revision(),
236
229
    def test_bind_parent_ahead(self):
237
230
        base_tree = self.create_branches()[0]
238
231
 
239
 
        os.chdir('child')
240
 
        self.run_bzr('unbind')
 
232
        self.run_bzr('unbind', working_dir='child')
241
233
 
242
234
        base_tree.commit(message='base', allow_pointless=True)
243
235
 
244
 
        self.check_revno(1)
245
 
        self.run_bzr('bind ../base')
 
236
        self.check_revno(1, 'child')
 
237
        self.run_bzr('bind ../base', working_dir='child')
246
238
 
247
239
        # binding does not pull data:
248
 
        self.check_revno(1)
249
 
        self.run_bzr('unbind')
 
240
        self.check_revno(1, 'child')
 
241
        self.run_bzr('unbind', working_dir='child')
250
242
 
251
243
        # Check and make sure it also works if parent is ahead multiple
252
244
        base_tree.commit(message='base 3', allow_pointless=True)
253
245
        base_tree.commit(message='base 4', allow_pointless=True)
254
246
        base_tree.commit(message='base 5', allow_pointless=True)
255
 
        self.check_revno(5, '../base')
 
247
        self.check_revno(5, 'base')
256
248
 
257
 
        self.check_revno(1)
258
 
        self.run_bzr('bind ../base')
259
 
        self.check_revno(1)
 
249
        self.check_revno(1, 'child')
 
250
        self.run_bzr('bind ../base', working_dir='child')
 
251
        self.check_revno(1, 'child')
260
252
 
261
253
    def test_bind_child_ahead(self):
262
254
        # test binding when the master branches history is a prefix of the
264
256
        # be altered
265
257
        child_tree = self.create_branches()[1]
266
258
 
267
 
        os.chdir('child')
268
 
        self.run_bzr('unbind')
 
259
        self.run_bzr('unbind', working_dir='child')
 
260
        # Refresh the child tree/branch objects as 'bind' modified them
 
261
        child_tree = BzrDir.open('child').open_workingtree()
269
262
        child_tree.commit(message='child', allow_pointless=True)
270
 
        self.check_revno(2)
271
 
        self.check_revno(1, '../base')
 
263
        self.check_revno(2, 'child')
 
264
        self.check_revno(1, 'base')
272
265
 
273
 
        self.run_bzr('bind ../base')
274
 
        self.check_revno(1, '../base')
 
266
        self.run_bzr('bind ../base', working_dir='child')
 
267
        self.check_revno(1, 'base')
275
268
 
276
269
        # Check and make sure it also works if child is ahead multiple
277
 
        self.run_bzr('unbind')
 
270
        self.run_bzr('unbind', working_dir='child')
278
271
        child_tree.commit(message='child 3', allow_pointless=True)
279
272
        child_tree.commit(message='child 4', allow_pointless=True)
280
273
        child_tree.commit(message='child 5', allow_pointless=True)
281
 
        self.check_revno(5)
 
274
        self.check_revno(5, 'child')
282
275
 
283
 
        self.check_revno(1, '../base')
284
 
        self.run_bzr('bind ../base')
285
 
        self.check_revno(1, '../base')
 
276
        self.check_revno(1, 'base')
 
277
        self.run_bzr('bind ../base', working_dir='child')
 
278
        self.check_revno(1, 'base')
286
279
 
287
280
    def test_bind_fail_if_missing(self):
288
281
        """We should not be able to bind to a missing branch."""
289
282
        tree = self.make_branch_and_tree('tree_1')
290
283
        tree.commit('dummy commit')
291
 
        self.run_bzr_error(['Not a branch.*no-such-branch/'], ['bind', '../no-such-branch'],
292
 
                            working_dir='tree_1')
 
284
        self.run_bzr_error(['Not a branch.*no-such-branch/'],
 
285
                           ['bind', '../no-such-branch'],
 
286
                           working_dir='tree_1')
293
287
        self.assertIs(None, tree.branch.get_bound_location())
294
288
 
295
289
    def test_bind_nick(self):
296
290
        """Bind should not update implicit nick."""
297
291
        base = self.make_branch_and_tree('base')
298
292
        child = self.make_branch_and_tree('child')
299
 
        os.chdir('child')
300
293
        self.assertEqual(child.branch.nick, 'child')
301
 
        self.assertEqual(child.branch.get_config().has_explicit_nickname(),
302
 
            False)
303
 
        self.run_bzr('bind ../base')
 
294
        self.assertEqual(False,
 
295
                         child.branch.get_config().has_explicit_nickname())
 
296
        self.run_bzr('bind ../base', working_dir='child')
 
297
        # Refresh the child tree/branch objects as 'bind' modified them
 
298
        child = BzrDir.open('child').open_workingtree()
304
299
        self.assertEqual(child.branch.nick, base.branch.nick)
305
 
        self.assertEqual(child.branch.get_config().has_explicit_nickname(),
306
 
            False)
 
300
        self.assertEqual(False,
 
301
                         child.branch.get_config().has_explicit_nickname())
307
302
 
308
303
    def test_bind_explicit_nick(self):
309
304
        """Bind should update explicit nick."""
310
305
        base = self.make_branch_and_tree('base')
311
306
        child = self.make_branch_and_tree('child')
312
 
        os.chdir('child')
313
307
        child.branch.nick = "explicit_nick"
314
 
        self.assertEqual(child.branch.nick, "explicit_nick")
315
 
        self.assertEqual(child.branch.get_config()._get_explicit_nickname(),
316
 
            "explicit_nick")
317
 
        self.run_bzr('bind ../base')
 
308
        self.assertEqual("explicit_nick", child.branch.nick)
 
309
        self.assertEqual("explicit_nick",
 
310
                         child.branch.get_config()._get_explicit_nickname())
 
311
        self.run_bzr('bind ../base', working_dir='child')
 
312
        # Refresh the child tree/branch objects as 'bind' modified them
 
313
        child = BzrDir.open('child').open_workingtree()
318
314
        self.assertEqual(child.branch.nick, base.branch.nick)
319
315
        self.assertEqual(child.branch.get_config()._get_explicit_nickname(),
320
 
            base.branch.nick)
 
316
                         base.branch.nick)
321
317
 
322
318
    def test_commit_after_merge(self):
323
319
        base_tree, child_tree = self.create_branches()
347
343
 
348
344
        # Commit should succeed, and cause merged revisions to
349
345
        # be pulled into base
350
 
        os.chdir('child')
351
 
        self.run_bzr(['commit', '-m', 'merge other'])
352
 
 
353
 
        self.check_revno(2)
354
 
 
355
 
        self.check_revno(2, '../base')
 
346
        self.run_bzr(['commit', '-m', 'merge other'], working_dir='child')
 
347
 
 
348
        self.check_revno(2, 'child')
 
349
 
 
350
        self.check_revno(2, 'base')
356
351
 
357
352
        self.assertTrue(base_tree.branch.repository.has_revision(new_rev_id))
358
353
 
380
375
        self.check_revno(2, 'child')
381
376
        self.check_revno(2, 'base')
382
377
 
383
 
        os.chdir('child')
384
 
        self.run_bzr('pull --overwrite ../other')
 
378
        self.run_bzr('pull --overwrite ../other', working_dir='child')
385
379
 
386
380
        # both the local and master should have been updated.
387
 
        self.check_revno(4)
388
 
        self.check_revno(4, '../base')
 
381
        self.check_revno(4, 'child')
 
382
        self.check_revno(4, 'base')
389
383
 
390
384
    def test_bind_directory(self):
391
385
        """Test --directory option"""