13
13
# You should have received a copy of the GNU General Public License
14
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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
"""Tests for the Branch facility that are not interface tests.
19
For interface tests see `tests/per_branch/*.py`.
19
For interface tests see tests/branch_implementations/*.py.
21
21
For concrete class tests see this file, and for meta-branch tests
22
22
also see this file.
25
from cStringIO import StringIO
28
branch as _mod_branch,
40
class TestDefaultFormat(tests.TestCase):
42
def test_default_format(self):
43
# update this if you change the default branch format
44
self.assertIsInstance(_mod_branch.format_registry.get_default(),
45
_mod_branch.BzrBranchFormat7)
47
def test_default_format_is_same_as_bzrdir_default(self):
48
# XXX: it might be nice if there was only one place the default was
49
# set, but at the moment that's not true -- mbp 20070814 --
50
# https://bugs.launchpad.net/bzr/+bug/132376
52
_mod_branch.format_registry.get_default(),
53
bzrdir.BzrDirFormat.get_default_format().get_branch_format())
25
from StringIO import StringIO
28
from bzrlib.branch import (BzrBranch5,
30
import bzrlib.bzrdir as bzrdir
31
from bzrlib.bzrdir import (BzrDirMetaFormat1, BzrDirMeta1,
33
from bzrlib.errors import (NotBranchError,
35
UnsupportedFormatError,
38
from bzrlib.tests import TestCase, TestCaseWithTransport
39
from bzrlib.transport import get_transport
41
class TestDefaultFormat(TestCase):
55
43
def test_get_set_default_format(self):
56
# set the format and then set it back again
57
old_format = _mod_branch.format_registry.get_default()
58
_mod_branch.format_registry.set_default(SampleBranchFormat())
44
old_format = bzrlib.branch.BranchFormat.get_default_format()
46
self.assertTrue(isinstance(old_format, bzrlib.branch.BzrBranchFormat5))
47
bzrlib.branch.BranchFormat.set_default_format(SampleBranchFormat())
60
49
# the default branch format is used by the meta dir format
61
50
# which is not the default bzrdir format at this point
62
dir = bzrdir.BzrDirMetaFormat1().initialize('memory:///')
51
dir = BzrDirMetaFormat1().initialize('memory:/')
63
52
result = dir.create_branch()
64
53
self.assertEqual(result, 'A branch')
66
_mod_branch.format_registry.set_default(old_format)
67
self.assertEqual(old_format,
68
_mod_branch.format_registry.get_default())
71
class TestBranchFormat5(tests.TestCaseWithTransport):
55
bzrlib.branch.BranchFormat.set_default_format(old_format)
56
self.assertEqual(old_format, bzrlib.branch.BranchFormat.get_default_format())
59
class TestBranchFormat5(TestCaseWithTransport):
72
60
"""Tests specific to branch format 5"""
74
62
def test_branch_format_5_uses_lockdir(self):
75
63
url = self.get_url()
76
bdir = bzrdir.BzrDirMetaFormat1().initialize(url)
77
bdir.create_repository()
78
branch = _mod_branch.BzrBranchFormat5().initialize(bdir)
64
bzrdir = BzrDirMetaFormat1().initialize(url)
65
bzrdir.create_repository()
66
branch = bzrdir.create_branch()
79
67
t = self.get_transport()
80
68
self.log("branch instance is %r" % branch)
81
self.assert_(isinstance(branch, _mod_branch.BzrBranch5))
69
self.assert_(isinstance(branch, BzrBranch5))
82
70
self.assertIsDirectory('.', t)
83
71
self.assertIsDirectory('.bzr/branch', t)
84
72
self.assertIsDirectory('.bzr/branch/lock', t)
85
73
branch.lock_write()
86
self.addCleanup(branch.unlock)
87
74
self.assertIsDirectory('.bzr/branch/lock/held', t)
89
def test_set_push_location(self):
90
conf = config.LocationConfig.from_string('# comment\n', '.', save=True)
92
branch = self.make_branch('.', format='knit')
93
branch.set_push_location('foo')
94
local_path = urlutils.local_path_from_url(branch.base[:-1])
95
self.assertFileEqual("# comment\n"
97
"push_location = foo\n"
98
"push_location:policy = norecurse\n" % local_path,
99
config.locations_config_filename())
101
# TODO RBC 20051029 test getting a push location from a branch in a
102
# recursive section - that is, it appends the branch name.
105
class SampleBranchFormat(_mod_branch.BranchFormatMetadir):
77
class SampleBranchFormat(bzrlib.branch.BranchFormat):
106
78
"""A sample format
108
this format is initializable, unsupported to aid in testing the
80
this format is initializable, unsupported to aid in testing the
109
81
open and open_downlevel routines.
113
def get_format_string(cls):
84
def get_format_string(self):
114
85
"""See BzrBranchFormat.get_format_string()."""
115
86
return "Sample branch format."
117
def initialize(self, a_bzrdir, name=None, repository=None,
118
append_revisions_only=None):
88
def initialize(self, a_bzrdir):
119
89
"""Format 4 branches cannot be created."""
120
t = a_bzrdir.get_branch_transport(self, name=name)
121
t.put_bytes('format', self.get_format_string())
90
t = a_bzrdir.get_branch_transport(self)
91
t.put('format', StringIO(self.get_format_string()))
124
94
def is_supported(self):
127
def open(self, transport, name=None, _found=False, ignore_fallbacks=False,
128
possible_transports=None):
97
def open(self, transport, _found=False):
129
98
return "opened branch."
132
# Demonstrating how lazy loading is often implemented:
133
# A constant string is created.
134
SampleSupportedBranchFormatString = "Sample supported branch format."
136
# And the format class can then reference the constant to avoid skew.
137
class SampleSupportedBranchFormat(_mod_branch.BranchFormatMetadir):
138
"""A sample supported format."""
141
def get_format_string(cls):
142
"""See BzrBranchFormat.get_format_string()."""
143
return SampleSupportedBranchFormatString
145
def initialize(self, a_bzrdir, name=None, append_revisions_only=None):
146
t = a_bzrdir.get_branch_transport(self, name=name)
147
t.put_bytes('format', self.get_format_string())
150
def open(self, transport, name=None, _found=False, ignore_fallbacks=False,
151
possible_transports=None):
152
return "opened supported branch."
155
class SampleExtraBranchFormat(_mod_branch.BranchFormat):
156
"""A sample format that is not usable in a metadir."""
158
def get_format_string(self):
159
# This format is not usable in a metadir.
162
def network_name(self):
163
# Network name always has to be provided.
166
def initialize(self, a_bzrdir, name=None):
167
raise NotImplementedError(self.initialize)
169
def open(self, transport, name=None, _found=False, ignore_fallbacks=False,
170
possible_transports=None):
171
raise NotImplementedError(self.open)
174
class TestBzrBranchFormat(tests.TestCaseWithTransport):
101
class TestBzrBranchFormat(TestCaseWithTransport):
175
102
"""Tests for the BzrBranchFormat facility."""
177
104
def test_find_format(self):
178
105
# is the right format object found for a branch?
179
106
# create a branch with a few known format objects.
180
# this is not quite the same as
107
# this is not quite the same as
181
108
self.build_tree(["foo/", "bar/"])
182
109
def check_format(format, url):
183
110
dir = format._matchingbzrdir.initialize(url)
184
111
dir.create_repository()
185
112
format.initialize(dir)
186
found_format = _mod_branch.BranchFormatMetadir.find_format(dir)
187
self.assertIsInstance(found_format, format.__class__)
188
check_format(_mod_branch.BzrBranchFormat5(), "bar")
190
def test_find_format_factory(self):
191
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
192
SampleSupportedBranchFormat().initialize(dir)
193
factory = _mod_branch.MetaDirBranchFormatFactory(
194
SampleSupportedBranchFormatString,
195
"bzrlib.tests.test_branch", "SampleSupportedBranchFormat")
196
_mod_branch.format_registry.register(factory)
197
self.addCleanup(_mod_branch.format_registry.remove, factory)
198
b = _mod_branch.Branch.open(self.get_url())
199
self.assertEqual(b, "opened supported branch.")
201
def test_from_string(self):
202
self.assertIsInstance(
203
SampleBranchFormat.from_string("Sample branch format."),
205
self.assertRaises(AssertionError,
206
SampleBranchFormat.from_string, "Different branch format.")
113
found_format = bzrlib.branch.BranchFormat.find_format(dir)
114
self.failUnless(isinstance(found_format, format.__class__))
115
check_format(bzrlib.branch.BzrBranchFormat5(), "bar")
208
117
def test_find_format_not_branch(self):
209
118
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
210
self.assertRaises(errors.NotBranchError,
211
_mod_branch.BranchFormatMetadir.find_format,
119
self.assertRaises(NotBranchError,
120
bzrlib.branch.BranchFormat.find_format,
214
123
def test_find_format_unknown_format(self):
215
124
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
216
125
SampleBranchFormat().initialize(dir)
217
self.assertRaises(errors.UnknownFormatError,
218
_mod_branch.BranchFormatMetadir.find_format,
126
self.assertRaises(UnknownFormatError,
127
bzrlib.branch.BranchFormat.find_format,
221
def test_find_format_with_features(self):
222
tree = self.make_branch_and_tree('.', format='2a')
223
tree.branch.update_feature_flags({"name": "optional"})
224
found_format = _mod_branch.BranchFormatMetadir.find_format(tree.bzrdir)
225
self.assertIsInstance(found_format, _mod_branch.BranchFormatMetadir)
226
self.assertEquals(found_format.features.get("name"), "optional")
227
tree.branch.update_feature_flags({"name": None})
228
branch = _mod_branch.Branch.open('.')
229
self.assertEquals(branch._format.features, {})
232
class TestBranchFormatRegistry(tests.TestCase):
235
super(TestBranchFormatRegistry, self).setUp()
236
self.registry = _mod_branch.BranchFormatRegistry()
238
def test_default(self):
239
self.assertIs(None, self.registry.get_default())
240
format = SampleBranchFormat()
241
self.registry.set_default(format)
242
self.assertEquals(format, self.registry.get_default())
244
130
def test_register_unregister_format(self):
245
131
format = SampleBranchFormat()
246
self.registry.register(format)
247
self.assertEquals(format,
248
self.registry.get("Sample branch format."))
249
self.registry.remove(format)
250
self.assertRaises(KeyError, self.registry.get,
251
"Sample branch format.")
253
def test_get_all(self):
254
format = SampleBranchFormat()
255
self.assertEquals([], self.registry._get_all())
256
self.registry.register(format)
257
self.assertEquals([format], self.registry._get_all())
259
def test_register_extra(self):
260
format = SampleExtraBranchFormat()
261
self.assertEquals([], self.registry._get_all())
262
self.registry.register_extra(format)
263
self.assertEquals([format], self.registry._get_all())
265
def test_register_extra_lazy(self):
266
self.assertEquals([], self.registry._get_all())
267
self.registry.register_extra_lazy("bzrlib.tests.test_branch",
268
"SampleExtraBranchFormat")
269
formats = self.registry._get_all()
270
self.assertEquals(1, len(formats))
271
self.assertIsInstance(formats[0], SampleExtraBranchFormat)
274
#Used by TestMetaDirBranchFormatFactory
275
FakeLazyFormat = None
278
class TestMetaDirBranchFormatFactory(tests.TestCase):
280
def test_get_format_string_does_not_load(self):
281
"""Formats have a static format string."""
282
factory = _mod_branch.MetaDirBranchFormatFactory("yo", None, None)
283
self.assertEqual("yo", factory.get_format_string())
285
def test_call_loads(self):
286
# __call__ is used by the network_format_registry interface to get a
288
global FakeLazyFormat
290
factory = _mod_branch.MetaDirBranchFormatFactory(None,
291
"bzrlib.tests.test_branch", "FakeLazyFormat")
292
self.assertRaises(AttributeError, factory)
294
def test_call_returns_call_of_referenced_object(self):
295
global FakeLazyFormat
296
FakeLazyFormat = lambda:'called'
297
factory = _mod_branch.MetaDirBranchFormatFactory(None,
298
"bzrlib.tests.test_branch", "FakeLazyFormat")
299
self.assertEqual('called', factory())
302
class TestBranch67(object):
303
"""Common tests for both branch 6 and 7 which are mostly the same."""
305
def get_format_name(self):
306
raise NotImplementedError(self.get_format_name)
308
def get_format_name_subtree(self):
309
raise NotImplementedError(self.get_format_name)
312
raise NotImplementedError(self.get_class)
314
def test_creation(self):
315
format = bzrdir.BzrDirMetaFormat1()
316
format.set_branch_format(_mod_branch.BzrBranchFormat6())
317
branch = self.make_branch('a', format=format)
318
self.assertIsInstance(branch, self.get_class())
319
branch = self.make_branch('b', format=self.get_format_name())
320
self.assertIsInstance(branch, self.get_class())
321
branch = _mod_branch.Branch.open('a')
322
self.assertIsInstance(branch, self.get_class())
324
def test_layout(self):
325
branch = self.make_branch('a', format=self.get_format_name())
326
self.assertPathExists('a/.bzr/branch/last-revision')
327
self.assertPathDoesNotExist('a/.bzr/branch/revision-history')
328
self.assertPathDoesNotExist('a/.bzr/branch/references')
330
def test_config(self):
331
"""Ensure that all configuration data is stored in the branch"""
332
branch = self.make_branch('a', format=self.get_format_name())
333
branch.set_parent('http://example.com')
334
self.assertPathDoesNotExist('a/.bzr/branch/parent')
335
self.assertEqual('http://example.com', branch.get_parent())
336
branch.set_push_location('sftp://example.com')
337
conf = branch.get_config_stack()
338
self.assertEqual('sftp://example.com', conf.get('push_location'))
339
branch.set_bound_location('ftp://example.com')
340
self.assertPathDoesNotExist('a/.bzr/branch/bound')
341
self.assertEqual('ftp://example.com', branch.get_bound_location())
343
def do_checkout_test(self, lightweight=False):
344
tree = self.make_branch_and_tree('source',
345
format=self.get_format_name_subtree())
346
subtree = self.make_branch_and_tree('source/subtree',
347
format=self.get_format_name_subtree())
348
subsubtree = self.make_branch_and_tree('source/subtree/subsubtree',
349
format=self.get_format_name_subtree())
350
self.build_tree(['source/subtree/file',
351
'source/subtree/subsubtree/file'])
352
subsubtree.add('file')
354
subtree.add_reference(subsubtree)
355
tree.add_reference(subtree)
356
tree.commit('a revision')
357
subtree.commit('a subtree file')
358
subsubtree.commit('a subsubtree file')
359
tree.branch.create_checkout('target', lightweight=lightweight)
360
self.assertPathExists('target')
361
self.assertPathExists('target/subtree')
362
self.assertPathExists('target/subtree/file')
363
self.assertPathExists('target/subtree/subsubtree/file')
364
subbranch = _mod_branch.Branch.open('target/subtree/subsubtree')
366
self.assertEndsWith(subbranch.base, 'source/subtree/subsubtree/')
368
self.assertEndsWith(subbranch.base, 'target/subtree/subsubtree/')
370
def test_checkout_with_references(self):
371
self.do_checkout_test()
373
def test_light_checkout_with_references(self):
374
self.do_checkout_test(lightweight=True)
377
class TestBranch6(TestBranch67, tests.TestCaseWithTransport):
380
return _mod_branch.BzrBranch6
382
def get_format_name(self):
383
return "dirstate-tags"
385
def get_format_name_subtree(self):
386
return "dirstate-with-subtree"
388
def test_set_stacked_on_url_errors(self):
389
branch = self.make_branch('a', format=self.get_format_name())
390
self.assertRaises(errors.UnstackableBranchFormat,
391
branch.set_stacked_on_url, None)
393
def test_default_stacked_location(self):
394
branch = self.make_branch('a', format=self.get_format_name())
395
self.assertRaises(errors.UnstackableBranchFormat, branch.get_stacked_on_url)
398
class TestBranch7(TestBranch67, tests.TestCaseWithTransport):
401
return _mod_branch.BzrBranch7
403
def get_format_name(self):
406
def get_format_name_subtree(self):
407
return "development-subtree"
409
def test_set_stacked_on_url_unstackable_repo(self):
410
repo = self.make_repository('a', format='dirstate-tags')
411
control = repo.bzrdir
412
branch = _mod_branch.BzrBranchFormat7().initialize(control)
413
target = self.make_branch('b')
414
self.assertRaises(errors.UnstackableRepositoryFormat,
415
branch.set_stacked_on_url, target.base)
417
def test_clone_stacked_on_unstackable_repo(self):
418
repo = self.make_repository('a', format='dirstate-tags')
419
control = repo.bzrdir
420
branch = _mod_branch.BzrBranchFormat7().initialize(control)
421
# Calling clone should not raise UnstackableRepositoryFormat.
422
cloned_bzrdir = control.clone('cloned')
424
def _test_default_stacked_location(self):
425
branch = self.make_branch('a', format=self.get_format_name())
426
self.assertRaises(errors.NotStacked, branch.get_stacked_on_url)
428
def test_stack_and_unstack(self):
429
branch = self.make_branch('a', format=self.get_format_name())
430
target = self.make_branch_and_tree('b', format=self.get_format_name())
431
branch.set_stacked_on_url(target.branch.base)
432
self.assertEqual(target.branch.base, branch.get_stacked_on_url())
433
revid = target.commit('foo')
434
self.assertTrue(branch.repository.has_revision(revid))
435
branch.set_stacked_on_url(None)
436
self.assertRaises(errors.NotStacked, branch.get_stacked_on_url)
437
self.assertFalse(branch.repository.has_revision(revid))
439
def test_open_opens_stacked_reference(self):
440
branch = self.make_branch('a', format=self.get_format_name())
441
target = self.make_branch_and_tree('b', format=self.get_format_name())
442
branch.set_stacked_on_url(target.branch.base)
443
branch = branch.bzrdir.open_branch()
444
revid = target.commit('foo')
445
self.assertTrue(branch.repository.has_revision(revid))
448
class BzrBranch8(tests.TestCaseWithTransport):
450
def make_branch(self, location, format=None):
452
format = controldir.format_registry.make_bzrdir('1.9')
453
format.set_branch_format(_mod_branch.BzrBranchFormat8())
454
return tests.TestCaseWithTransport.make_branch(
455
self, location, format=format)
457
def create_branch_with_reference(self):
458
branch = self.make_branch('branch')
459
branch._set_all_reference_info({'file-id': ('path', 'location')})
463
def instrument_branch(branch, gets):
464
old_get = branch._transport.get
465
def get(*args, **kwargs):
466
gets.append((args, kwargs))
467
return old_get(*args, **kwargs)
468
branch._transport.get = get
470
def test_reference_info_caching_read_locked(self):
472
branch = self.create_branch_with_reference()
474
self.addCleanup(branch.unlock)
475
self.instrument_branch(branch, gets)
476
branch.get_reference_info('file-id')
477
branch.get_reference_info('file-id')
478
self.assertEqual(1, len(gets))
480
def test_reference_info_caching_read_unlocked(self):
482
branch = self.create_branch_with_reference()
483
self.instrument_branch(branch, gets)
484
branch.get_reference_info('file-id')
485
branch.get_reference_info('file-id')
486
self.assertEqual(2, len(gets))
488
def test_reference_info_caching_write_locked(self):
490
branch = self.make_branch('branch')
492
self.instrument_branch(branch, gets)
493
self.addCleanup(branch.unlock)
494
branch._set_all_reference_info({'file-id': ('path2', 'location2')})
495
path, location = branch.get_reference_info('file-id')
496
self.assertEqual(0, len(gets))
497
self.assertEqual('path2', path)
498
self.assertEqual('location2', location)
500
def test_reference_info_caches_cleared(self):
501
branch = self.make_branch('branch')
503
branch.set_reference_info('file-id', 'path2', 'location2')
505
doppelganger = _mod_branch.Branch.open('branch')
506
doppelganger.set_reference_info('file-id', 'path3', 'location3')
507
self.assertEqual(('path3', 'location3'),
508
branch.get_reference_info('file-id'))
510
def _recordParentMapCalls(self, repo):
511
self._parent_map_calls = []
512
orig_get_parent_map = repo.revisions.get_parent_map
513
def get_parent_map(q):
515
self._parent_map_calls.extend([e[0] for e in q])
516
return orig_get_parent_map(q)
517
repo.revisions.get_parent_map = get_parent_map
520
class TestBranchReference(tests.TestCaseWithTransport):
133
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
135
format.initialize(dir)
136
# register a format for it.
137
bzrlib.branch.BranchFormat.register_format(format)
138
# which branch.Open will refuse (not supported)
139
self.assertRaises(UnsupportedFormatError, bzrlib.branch.Branch.open, self.get_url())
140
# but open_downlevel will work
141
self.assertEqual(format.open(dir), bzrdir.BzrDir.open(self.get_url()).open_branch(unsupported=True))
142
# unregister the format
143
bzrlib.branch.BranchFormat.unregister_format(format)
146
class TestBranchReference(TestCaseWithTransport):
521
147
"""Tests for the branch reference facility."""
523
149
def test_create_open_reference(self):
524
150
bzrdirformat = bzrdir.BzrDirMetaFormat1()
525
t = self.get_transport()
151
t = get_transport(self.get_url('.'))
527
153
dir = bzrdirformat.initialize(self.get_url('repo'))
528
154
dir.create_repository()
529
155
target_branch = dir.create_branch()
530
156
t.mkdir('branch')
531
157
branch_dir = bzrdirformat.initialize(self.get_url('branch'))
532
made_branch = _mod_branch.BranchReferenceFormat().initialize(
533
branch_dir, target_branch=target_branch)
158
made_branch = bzrlib.branch.BranchReferenceFormat().initialize(branch_dir, target_branch)
534
159
self.assertEqual(made_branch.base, target_branch.base)
535
160
opened_branch = branch_dir.open_branch()
536
161
self.assertEqual(opened_branch.base, target_branch.base)
538
def test_get_reference(self):
539
"""For a BranchReference, get_reference should return the location."""
540
branch = self.make_branch('target')
541
checkout = branch.create_checkout('checkout', lightweight=True)
542
reference_url = branch.bzrdir.root_transport.abspath('') + '/'
543
# if the api for create_checkout changes to return different checkout types
544
# then this file read will fail.
545
self.assertFileEqual(reference_url, 'checkout/.bzr/branch/location')
546
self.assertEqual(reference_url,
547
_mod_branch.BranchReferenceFormat().get_reference(checkout.bzrdir))
550
class TestHooks(tests.TestCaseWithTransport):
552
def test_constructor(self):
553
"""Check that creating a BranchHooks instance has the right defaults."""
554
hooks = _mod_branch.BranchHooks()
555
self.assertTrue("post_push" in hooks, "post_push not in %s" % hooks)
556
self.assertTrue("post_commit" in hooks, "post_commit not in %s" % hooks)
557
self.assertTrue("pre_commit" in hooks, "pre_commit not in %s" % hooks)
558
self.assertTrue("post_pull" in hooks, "post_pull not in %s" % hooks)
559
self.assertTrue("post_uncommit" in hooks,
560
"post_uncommit not in %s" % hooks)
561
self.assertTrue("post_change_branch_tip" in hooks,
562
"post_change_branch_tip not in %s" % hooks)
563
self.assertTrue("post_branch_init" in hooks,
564
"post_branch_init not in %s" % hooks)
565
self.assertTrue("post_switch" in hooks,
566
"post_switch not in %s" % hooks)
568
def test_installed_hooks_are_BranchHooks(self):
569
"""The installed hooks object should be a BranchHooks."""
570
# the installed hooks are saved in self._preserved_hooks.
571
self.assertIsInstance(self._preserved_hooks[_mod_branch.Branch][1],
572
_mod_branch.BranchHooks)
574
def test_post_branch_init_hook(self):
576
_mod_branch.Branch.hooks.install_named_hook('post_branch_init',
578
self.assertLength(0, calls)
579
branch = self.make_branch('a')
580
self.assertLength(1, calls)
582
self.assertIsInstance(params, _mod_branch.BranchInitHookParams)
583
self.assertTrue(hasattr(params, 'bzrdir'))
584
self.assertTrue(hasattr(params, 'branch'))
586
def test_post_branch_init_hook_repr(self):
588
_mod_branch.Branch.hooks.install_named_hook('post_branch_init',
589
lambda params: param_reprs.append(repr(params)), None)
590
branch = self.make_branch('a')
591
self.assertLength(1, param_reprs)
592
param_repr = param_reprs[0]
593
self.assertStartsWith(param_repr, '<BranchInitHookParams of ')
595
def test_post_switch_hook(self):
596
from bzrlib import switch
598
_mod_branch.Branch.hooks.install_named_hook('post_switch',
600
tree = self.make_branch_and_tree('branch-1')
601
self.build_tree(['branch-1/file-1'])
604
to_branch = tree.bzrdir.sprout('branch-2').open_branch()
605
self.build_tree(['branch-1/file-2'])
607
tree.remove('file-1')
609
checkout = tree.branch.create_checkout('checkout')
610
self.assertLength(0, calls)
611
switch.switch(checkout.bzrdir, to_branch)
612
self.assertLength(1, calls)
614
self.assertIsInstance(params, _mod_branch.SwitchHookParams)
615
self.assertTrue(hasattr(params, 'to_branch'))
616
self.assertTrue(hasattr(params, 'revision_id'))
619
class TestBranchOptions(tests.TestCaseWithTransport):
622
super(TestBranchOptions, self).setUp()
623
self.branch = self.make_branch('.')
624
self.config_stack = self.branch.get_config_stack()
626
def check_append_revisions_only(self, expected_value, value=None):
627
"""Set append_revisions_only in config and check its interpretation."""
628
if value is not None:
629
self.config_stack.set('append_revisions_only', value)
630
self.assertEqual(expected_value,
631
self.branch.get_append_revisions_only())
633
def test_valid_append_revisions_only(self):
634
self.assertEquals(None,
635
self.config_stack.get('append_revisions_only'))
636
self.check_append_revisions_only(None)
637
self.check_append_revisions_only(False, 'False')
638
self.check_append_revisions_only(True, 'True')
639
# The following values will cause compatibility problems on projects
640
# using older bzr versions (<2.2) but are accepted
641
self.check_append_revisions_only(False, 'false')
642
self.check_append_revisions_only(True, 'true')
644
def test_invalid_append_revisions_only(self):
645
"""Ensure warning is noted on invalid settings"""
648
self.warnings.append(args[0] % args[1:])
649
self.overrideAttr(trace, 'warning', warning)
650
self.check_append_revisions_only(None, 'not-a-bool')
651
self.assertLength(1, self.warnings)
653
'Value "not-a-bool" is not valid for "append_revisions_only"',
656
def test_use_fresh_values(self):
657
copy = _mod_branch.Branch.open(self.branch.base)
660
copy.get_config_stack().set('foo', 'bar')
663
self.assertFalse(self.branch.is_locked())
664
# Since the branch is locked, the option value won't be saved on disk
665
# so trying to access the config of locked branch via another older
666
# non-locked branch object pointing to the same branch is not supported
667
self.assertEqual(None, self.branch.get_config_stack().get('foo'))
668
# Using a newly created branch object works as expected
669
fresh = _mod_branch.Branch.open(self.branch.base)
670
self.assertEqual('bar', fresh.get_config_stack().get('foo'))
672
def test_set_from_config_get_from_config_stack(self):
673
self.branch.lock_write()
674
self.addCleanup(self.branch.unlock)
675
self.branch.get_config().set_user_option('foo', 'bar')
676
result = self.branch.get_config_stack().get('foo')
677
# https://bugs.launchpad.net/bzr/+bug/948344
678
self.expectFailure('BranchStack uses cache after set_user_option',
679
self.assertEqual, 'bar', result)
681
def test_set_from_config_stack_get_from_config(self):
682
self.branch.lock_write()
683
self.addCleanup(self.branch.unlock)
684
self.branch.get_config_stack().set('foo', 'bar')
685
# Since the branch is locked, the option value won't be saved on disk
686
# so mixing get() and get_user_option() is broken by design.
687
self.assertEqual(None,
688
self.branch.get_config().get_user_option('foo'))
690
def test_set_delays_write_when_branch_is_locked(self):
691
self.branch.lock_write()
692
self.addCleanup(self.branch.unlock)
693
self.branch.get_config_stack().set('foo', 'bar')
694
copy = _mod_branch.Branch.open(self.branch.base)
695
result = copy.get_config_stack().get('foo')
696
# Accessing from a different branch object is like accessing from a
697
# different process: the option has not been saved yet and the new
698
# value cannot be seen.
699
self.assertIs(None, result)
702
class TestPullResult(tests.TestCase):
704
def test_report_changed(self):
705
r = _mod_branch.PullResult()
706
r.old_revid = "old-revid"
708
r.new_revid = "new-revid"
712
self.assertEqual("Now on revision 20.\n", f.getvalue())
713
self.assertEqual("Now on revision 20.\n", f.getvalue())
715
def test_report_unchanged(self):
716
r = _mod_branch.PullResult()
717
r.old_revid = "same-revid"
718
r.new_revid = "same-revid"
721
self.assertEqual("No revisions or tags to pull.\n", f.getvalue())