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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
"""Tests for the Branch facility that are not interface tests.
19
For interface tests see tests/branch_implementations/*.py.
19
For interface tests see `tests/per_branch/*.py`.
21
21
For concrete class tests see this file, and for meta-branch tests
22
22
also see this file.
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):
25
from cStringIO import StringIO
28
branch as _mod_branch,
39
class TestDefaultFormat(tests.TestCase):
41
def test_default_format(self):
42
# update this if you change the default branch format
43
self.assertIsInstance(_mod_branch.format_registry.get_default(),
44
_mod_branch.BzrBranchFormat7)
46
def test_default_format_is_same_as_bzrdir_default(self):
47
# XXX: it might be nice if there was only one place the default was
48
# set, but at the moment that's not true -- mbp 20070814 --
49
# https://bugs.launchpad.net/bzr/+bug/132376
51
_mod_branch.format_registry.get_default(),
52
bzrdir.BzrDirFormat.get_default_format().get_branch_format())
43
54
def test_get_set_default_format(self):
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())
55
# set the format and then set it back again
56
old_format = _mod_branch.format_registry.get_default()
57
_mod_branch.format_registry.set_default(SampleBranchFormat())
49
59
# the default branch format is used by the meta dir format
50
60
# which is not the default bzrdir format at this point
51
dir = BzrDirMetaFormat1().initialize('memory:///')
61
dir = bzrdir.BzrDirMetaFormat1().initialize('memory:///')
52
62
result = dir.create_branch()
53
63
self.assertEqual(result, 'A branch')
55
bzrlib.branch.BranchFormat.set_default_format(old_format)
56
self.assertEqual(old_format, bzrlib.branch.BranchFormat.get_default_format())
59
class TestBranchFormat5(TestCaseWithTransport):
65
_mod_branch.format_registry.set_default(old_format)
66
self.assertEqual(old_format,
67
_mod_branch.format_registry.get_default())
70
class TestBranchFormat5(tests.TestCaseWithTransport):
60
71
"""Tests specific to branch format 5"""
62
73
def test_branch_format_5_uses_lockdir(self):
63
74
url = self.get_url()
64
bzrdir = BzrDirMetaFormat1().initialize(url)
65
bzrdir.create_repository()
66
branch = bzrdir.create_branch()
75
bdir = bzrdir.BzrDirMetaFormat1().initialize(url)
76
bdir.create_repository()
77
branch = _mod_branch.BzrBranchFormat5().initialize(bdir)
67
78
t = self.get_transport()
68
79
self.log("branch instance is %r" % branch)
69
self.assert_(isinstance(branch, BzrBranch5))
80
self.assert_(isinstance(branch, _mod_branch.BzrBranch5))
70
81
self.assertIsDirectory('.', t)
71
82
self.assertIsDirectory('.bzr/branch', t)
72
83
self.assertIsDirectory('.bzr/branch/lock', t)
73
84
branch.lock_write()
75
self.assertIsDirectory('.bzr/branch/lock/held', t)
80
class TestBranchEscaping(TestCaseWithTransport):
81
"""Test a branch can be correctly stored and used on a vfat-like transport
83
Makes sure we have proper escaping of invalid characters, etc.
85
It'd be better to test all operations on the FakeVFATTransportDecorator,
86
but working trees go straight to the os not through the Transport layer.
87
Therefore we build some history first in the regular way and then
88
check it's safe to access for vfat.
95
super(TestBranchEscaping, self).setUp()
96
from bzrlib.repository import RepositoryFormatKnit1
97
bzrdir = BzrDirMetaFormat1().initialize(self.get_url())
98
repo = RepositoryFormatKnit1().initialize(bzrdir)
99
branch = bzrdir.create_branch()
100
wt = bzrdir.create_workingtree()
101
self.build_tree_contents([("foo", "contents of foo")])
102
# add file with id containing wierd characters
103
wt.add(['foo'], [self.FOO_ID])
104
wt.commit('this is my new commit', rev_id=self.REV_ID)
106
def test_branch_on_vfat(self):
107
from bzrlib.transport.fakevfat import FakeVFATTransportDecorator
108
# now access over vfat; should be safe
109
transport = FakeVFATTransportDecorator('vfat+' + self.get_url())
110
bzrdir, junk = BzrDir.open_containing_from_transport(transport)
111
branch = bzrdir.open_branch()
112
revtree = branch.repository.revision_tree(self.REV_ID)
113
contents = revtree.get_file_text(self.FOO_ID)
114
self.assertEqual(contents, 'contents of foo')
117
class SampleBranchFormat(bzrlib.branch.BranchFormat):
85
self.addCleanup(branch.unlock)
86
self.assertIsDirectory('.bzr/branch/lock/held', t)
88
def test_set_push_location(self):
89
conf = config.LocationConfig.from_string('# comment\n', '.', save=True)
91
branch = self.make_branch('.', format='knit')
92
branch.set_push_location('foo')
93
local_path = urlutils.local_path_from_url(branch.base[:-1])
94
self.assertFileEqual("# comment\n"
96
"push_location = foo\n"
97
"push_location:policy = norecurse\n" % local_path,
98
config.locations_config_filename())
100
# TODO RBC 20051029 test getting a push location from a branch in a
101
# recursive section - that is, it appends the branch name.
104
class SampleBranchFormat(_mod_branch.BranchFormat):
118
105
"""A sample format
120
this format is initializable, unsupported to aid in testing the
107
this format is initializable, unsupported to aid in testing the
121
108
open and open_downlevel routines.
125
112
"""See BzrBranchFormat.get_format_string()."""
126
113
return "Sample branch format."
128
def initialize(self, a_bzrdir):
115
def initialize(self, a_bzrdir, name=None, repository=None,
116
append_revisions_only=None):
129
117
"""Format 4 branches cannot be created."""
130
t = a_bzrdir.get_branch_transport(self)
131
t.put('format', StringIO(self.get_format_string()))
118
t = a_bzrdir.get_branch_transport(self, name=name)
119
t.put_bytes('format', self.get_format_string())
132
120
return 'A branch'
134
122
def is_supported(self):
137
def open(self, transport, _found=False):
125
def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
138
126
return "opened branch."
141
class TestBzrBranchFormat(TestCaseWithTransport):
129
# Demonstrating how lazy loading is often implemented:
130
# A constant string is created.
131
SampleSupportedBranchFormatString = "Sample supported branch format."
133
# And the format class can then reference the constant to avoid skew.
134
class SampleSupportedBranchFormat(_mod_branch.BranchFormat):
135
"""A sample supported format."""
137
def get_format_string(self):
138
"""See BzrBranchFormat.get_format_string()."""
139
return SampleSupportedBranchFormatString
141
def initialize(self, a_bzrdir, name=None, append_revisions_only=None):
142
t = a_bzrdir.get_branch_transport(self, name=name)
143
t.put_bytes('format', self.get_format_string())
146
def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
147
return "opened supported branch."
150
class SampleExtraBranchFormat(_mod_branch.BranchFormat):
151
"""A sample format that is not usable in a metadir."""
153
def get_format_string(self):
154
# This format is not usable in a metadir.
157
def network_name(self):
158
# Network name always has to be provided.
161
def initialize(self, a_bzrdir, name=None):
162
raise NotImplementedError(self.initialize)
164
def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
165
raise NotImplementedError(self.open)
168
class TestBzrBranchFormat(tests.TestCaseWithTransport):
142
169
"""Tests for the BzrBranchFormat facility."""
144
171
def test_find_format(self):
145
172
# is the right format object found for a branch?
146
173
# create a branch with a few known format objects.
147
# this is not quite the same as
174
# this is not quite the same as
148
175
self.build_tree(["foo/", "bar/"])
149
176
def check_format(format, url):
150
177
dir = format._matchingbzrdir.initialize(url)
151
178
dir.create_repository()
152
179
format.initialize(dir)
153
found_format = bzrlib.branch.BranchFormat.find_format(dir)
154
self.failUnless(isinstance(found_format, format.__class__))
155
check_format(bzrlib.branch.BzrBranchFormat5(), "bar")
180
found_format = _mod_branch.BranchFormat.find_format(dir)
181
self.assertIsInstance(found_format, format.__class__)
182
check_format(_mod_branch.BzrBranchFormat5(), "bar")
184
def test_find_format_factory(self):
185
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
186
SampleSupportedBranchFormat().initialize(dir)
187
factory = _mod_branch.MetaDirBranchFormatFactory(
188
SampleSupportedBranchFormatString,
189
"bzrlib.tests.test_branch", "SampleSupportedBranchFormat")
190
_mod_branch.format_registry.register(factory)
191
self.addCleanup(_mod_branch.format_registry.remove, factory)
192
b = _mod_branch.Branch.open(self.get_url())
193
self.assertEqual(b, "opened supported branch.")
157
195
def test_find_format_not_branch(self):
158
196
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
159
self.assertRaises(NotBranchError,
160
bzrlib.branch.BranchFormat.find_format,
197
self.assertRaises(errors.NotBranchError,
198
_mod_branch.BranchFormat.find_format,
163
201
def test_find_format_unknown_format(self):
164
202
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
165
203
SampleBranchFormat().initialize(dir)
166
self.assertRaises(UnknownFormatError,
167
bzrlib.branch.BranchFormat.find_format,
204
self.assertRaises(errors.UnknownFormatError,
205
_mod_branch.BranchFormat.find_format,
170
208
def test_register_unregister_format(self):
209
# Test the deprecated format registration functions
171
210
format = SampleBranchFormat()
172
211
# make a control dir
173
212
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
175
214
format.initialize(dir)
176
215
# register a format for it.
177
bzrlib.branch.BranchFormat.register_format(format)
216
self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
217
_mod_branch.BranchFormat.register_format, format)
178
218
# which branch.Open will refuse (not supported)
179
self.assertRaises(UnsupportedFormatError, bzrlib.branch.Branch.open, self.get_url())
219
self.assertRaises(errors.UnsupportedFormatError,
220
_mod_branch.Branch.open, self.get_url())
221
self.make_branch_and_tree('foo')
180
222
# but open_downlevel will work
181
self.assertEqual(format.open(dir), bzrdir.BzrDir.open(self.get_url()).open_branch(unsupported=True))
225
bzrdir.BzrDir.open(self.get_url()).open_branch(unsupported=True))
182
226
# unregister the format
183
bzrlib.branch.BranchFormat.unregister_format(format)
186
class TestBranchReference(TestCaseWithTransport):
227
self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
228
_mod_branch.BranchFormat.unregister_format, format)
229
self.make_branch_and_tree('bar')
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
def test_register_unregister_format(self):
245
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
config = branch.get_config()._get_branch_data_config()
338
self.assertEqual('sftp://example.com',
339
config.get_user_option('push_location'))
340
branch.set_bound_location('ftp://example.com')
341
self.assertPathDoesNotExist('a/.bzr/branch/bound')
342
self.assertEqual('ftp://example.com', branch.get_bound_location())
344
def test_set_revision_history(self):
345
builder = self.make_branch_builder('.', format=self.get_format_name())
346
builder.build_snapshot('foo', None,
347
[('add', ('', None, 'directory', None))],
349
builder.build_snapshot('bar', None, [], message='bar')
350
branch = builder.get_branch()
352
self.addCleanup(branch.unlock)
353
self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
354
branch.set_revision_history, ['foo', 'bar'])
355
self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
356
branch.set_revision_history, ['foo'])
357
self.assertRaises(errors.NotLefthandHistory,
358
self.applyDeprecated, symbol_versioning.deprecated_in((2, 4, 0)),
359
branch.set_revision_history, ['bar'])
361
def do_checkout_test(self, lightweight=False):
362
tree = self.make_branch_and_tree('source',
363
format=self.get_format_name_subtree())
364
subtree = self.make_branch_and_tree('source/subtree',
365
format=self.get_format_name_subtree())
366
subsubtree = self.make_branch_and_tree('source/subtree/subsubtree',
367
format=self.get_format_name_subtree())
368
self.build_tree(['source/subtree/file',
369
'source/subtree/subsubtree/file'])
370
subsubtree.add('file')
372
subtree.add_reference(subsubtree)
373
tree.add_reference(subtree)
374
tree.commit('a revision')
375
subtree.commit('a subtree file')
376
subsubtree.commit('a subsubtree file')
377
tree.branch.create_checkout('target', lightweight=lightweight)
378
self.assertPathExists('target')
379
self.assertPathExists('target/subtree')
380
self.assertPathExists('target/subtree/file')
381
self.assertPathExists('target/subtree/subsubtree/file')
382
subbranch = _mod_branch.Branch.open('target/subtree/subsubtree')
384
self.assertEndsWith(subbranch.base, 'source/subtree/subsubtree/')
386
self.assertEndsWith(subbranch.base, 'target/subtree/subsubtree/')
388
def test_checkout_with_references(self):
389
self.do_checkout_test()
391
def test_light_checkout_with_references(self):
392
self.do_checkout_test(lightweight=True)
394
def test_set_push(self):
395
branch = self.make_branch('source', format=self.get_format_name())
396
branch.get_config().set_user_option('push_location', 'old',
397
store=config.STORE_LOCATION)
400
warnings.append(args[0] % args[1:])
401
_warning = trace.warning
402
trace.warning = warning
404
branch.set_push_location('new')
406
trace.warning = _warning
407
self.assertEqual(warnings[0], 'Value "new" is masked by "old" from '
411
class TestBranch6(TestBranch67, tests.TestCaseWithTransport):
414
return _mod_branch.BzrBranch6
416
def get_format_name(self):
417
return "dirstate-tags"
419
def get_format_name_subtree(self):
420
return "dirstate-with-subtree"
422
def test_set_stacked_on_url_errors(self):
423
branch = self.make_branch('a', format=self.get_format_name())
424
self.assertRaises(errors.UnstackableBranchFormat,
425
branch.set_stacked_on_url, None)
427
def test_default_stacked_location(self):
428
branch = self.make_branch('a', format=self.get_format_name())
429
self.assertRaises(errors.UnstackableBranchFormat, branch.get_stacked_on_url)
432
class TestBranch7(TestBranch67, tests.TestCaseWithTransport):
435
return _mod_branch.BzrBranch7
437
def get_format_name(self):
440
def get_format_name_subtree(self):
441
return "development-subtree"
443
def test_set_stacked_on_url_unstackable_repo(self):
444
repo = self.make_repository('a', format='dirstate-tags')
445
control = repo.bzrdir
446
branch = _mod_branch.BzrBranchFormat7().initialize(control)
447
target = self.make_branch('b')
448
self.assertRaises(errors.UnstackableRepositoryFormat,
449
branch.set_stacked_on_url, target.base)
451
def test_clone_stacked_on_unstackable_repo(self):
452
repo = self.make_repository('a', format='dirstate-tags')
453
control = repo.bzrdir
454
branch = _mod_branch.BzrBranchFormat7().initialize(control)
455
# Calling clone should not raise UnstackableRepositoryFormat.
456
cloned_bzrdir = control.clone('cloned')
458
def _test_default_stacked_location(self):
459
branch = self.make_branch('a', format=self.get_format_name())
460
self.assertRaises(errors.NotStacked, branch.get_stacked_on_url)
462
def test_stack_and_unstack(self):
463
branch = self.make_branch('a', format=self.get_format_name())
464
target = self.make_branch_and_tree('b', format=self.get_format_name())
465
branch.set_stacked_on_url(target.branch.base)
466
self.assertEqual(target.branch.base, branch.get_stacked_on_url())
467
revid = target.commit('foo')
468
self.assertTrue(branch.repository.has_revision(revid))
469
branch.set_stacked_on_url(None)
470
self.assertRaises(errors.NotStacked, branch.get_stacked_on_url)
471
self.assertFalse(branch.repository.has_revision(revid))
473
def test_open_opens_stacked_reference(self):
474
branch = self.make_branch('a', format=self.get_format_name())
475
target = self.make_branch_and_tree('b', format=self.get_format_name())
476
branch.set_stacked_on_url(target.branch.base)
477
branch = branch.bzrdir.open_branch()
478
revid = target.commit('foo')
479
self.assertTrue(branch.repository.has_revision(revid))
482
class BzrBranch8(tests.TestCaseWithTransport):
484
def make_branch(self, location, format=None):
486
format = bzrdir.format_registry.make_bzrdir('1.9')
487
format.set_branch_format(_mod_branch.BzrBranchFormat8())
488
return tests.TestCaseWithTransport.make_branch(
489
self, location, format=format)
491
def create_branch_with_reference(self):
492
branch = self.make_branch('branch')
493
branch._set_all_reference_info({'file-id': ('path', 'location')})
497
def instrument_branch(branch, gets):
498
old_get = branch._transport.get
499
def get(*args, **kwargs):
500
gets.append((args, kwargs))
501
return old_get(*args, **kwargs)
502
branch._transport.get = get
504
def test_reference_info_caching_read_locked(self):
506
branch = self.create_branch_with_reference()
508
self.addCleanup(branch.unlock)
509
self.instrument_branch(branch, gets)
510
branch.get_reference_info('file-id')
511
branch.get_reference_info('file-id')
512
self.assertEqual(1, len(gets))
514
def test_reference_info_caching_read_unlocked(self):
516
branch = self.create_branch_with_reference()
517
self.instrument_branch(branch, gets)
518
branch.get_reference_info('file-id')
519
branch.get_reference_info('file-id')
520
self.assertEqual(2, len(gets))
522
def test_reference_info_caching_write_locked(self):
524
branch = self.make_branch('branch')
526
self.instrument_branch(branch, gets)
527
self.addCleanup(branch.unlock)
528
branch._set_all_reference_info({'file-id': ('path2', 'location2')})
529
path, location = branch.get_reference_info('file-id')
530
self.assertEqual(0, len(gets))
531
self.assertEqual('path2', path)
532
self.assertEqual('location2', location)
534
def test_reference_info_caches_cleared(self):
535
branch = self.make_branch('branch')
537
branch.set_reference_info('file-id', 'path2', 'location2')
539
doppelganger = _mod_branch.Branch.open('branch')
540
doppelganger.set_reference_info('file-id', 'path3', 'location3')
541
self.assertEqual(('path3', 'location3'),
542
branch.get_reference_info('file-id'))
544
class TestBranchReference(tests.TestCaseWithTransport):
187
545
"""Tests for the branch reference facility."""
189
547
def test_create_open_reference(self):
190
548
bzrdirformat = bzrdir.BzrDirMetaFormat1()
191
t = get_transport(self.get_url('.'))
549
t = self.get_transport()
193
551
dir = bzrdirformat.initialize(self.get_url('repo'))
194
552
dir.create_repository()
195
553
target_branch = dir.create_branch()
196
554
t.mkdir('branch')
197
555
branch_dir = bzrdirformat.initialize(self.get_url('branch'))
198
made_branch = bzrlib.branch.BranchReferenceFormat().initialize(branch_dir, target_branch)
556
made_branch = _mod_branch.BranchReferenceFormat().initialize(
557
branch_dir, target_branch=target_branch)
199
558
self.assertEqual(made_branch.base, target_branch.base)
200
559
opened_branch = branch_dir.open_branch()
201
560
self.assertEqual(opened_branch.base, target_branch.base)
562
def test_get_reference(self):
563
"""For a BranchReference, get_reference should reutrn the location."""
564
branch = self.make_branch('target')
565
checkout = branch.create_checkout('checkout', lightweight=True)
566
reference_url = branch.bzrdir.root_transport.abspath('') + '/'
567
# if the api for create_checkout changes to return different checkout types
568
# then this file read will fail.
569
self.assertFileEqual(reference_url, 'checkout/.bzr/branch/location')
570
self.assertEqual(reference_url,
571
_mod_branch.BranchReferenceFormat().get_reference(checkout.bzrdir))
574
class TestHooks(tests.TestCaseWithTransport):
576
def test_constructor(self):
577
"""Check that creating a BranchHooks instance has the right defaults."""
578
hooks = _mod_branch.BranchHooks()
579
self.assertTrue("set_rh" in hooks, "set_rh not in %s" % hooks)
580
self.assertTrue("post_push" in hooks, "post_push not in %s" % hooks)
581
self.assertTrue("post_commit" in hooks, "post_commit not in %s" % hooks)
582
self.assertTrue("pre_commit" in hooks, "pre_commit not in %s" % hooks)
583
self.assertTrue("post_pull" in hooks, "post_pull not in %s" % hooks)
584
self.assertTrue("post_uncommit" in hooks,
585
"post_uncommit not in %s" % hooks)
586
self.assertTrue("post_change_branch_tip" in hooks,
587
"post_change_branch_tip not in %s" % hooks)
588
self.assertTrue("post_branch_init" in hooks,
589
"post_branch_init not in %s" % hooks)
590
self.assertTrue("post_switch" in hooks,
591
"post_switch not in %s" % hooks)
593
def test_installed_hooks_are_BranchHooks(self):
594
"""The installed hooks object should be a BranchHooks."""
595
# the installed hooks are saved in self._preserved_hooks.
596
self.assertIsInstance(self._preserved_hooks[_mod_branch.Branch][1],
597
_mod_branch.BranchHooks)
599
def test_post_branch_init_hook(self):
601
_mod_branch.Branch.hooks.install_named_hook('post_branch_init',
603
self.assertLength(0, calls)
604
branch = self.make_branch('a')
605
self.assertLength(1, calls)
607
self.assertIsInstance(params, _mod_branch.BranchInitHookParams)
608
self.assertTrue(hasattr(params, 'bzrdir'))
609
self.assertTrue(hasattr(params, 'branch'))
611
def test_post_branch_init_hook_repr(self):
613
_mod_branch.Branch.hooks.install_named_hook('post_branch_init',
614
lambda params: param_reprs.append(repr(params)), None)
615
branch = self.make_branch('a')
616
self.assertLength(1, param_reprs)
617
param_repr = param_reprs[0]
618
self.assertStartsWith(param_repr, '<BranchInitHookParams of ')
620
def test_post_switch_hook(self):
621
from bzrlib import switch
623
_mod_branch.Branch.hooks.install_named_hook('post_switch',
625
tree = self.make_branch_and_tree('branch-1')
626
self.build_tree(['branch-1/file-1'])
629
to_branch = tree.bzrdir.sprout('branch-2').open_branch()
630
self.build_tree(['branch-1/file-2'])
632
tree.remove('file-1')
634
checkout = tree.branch.create_checkout('checkout')
635
self.assertLength(0, calls)
636
switch.switch(checkout.bzrdir, to_branch)
637
self.assertLength(1, calls)
639
self.assertIsInstance(params, _mod_branch.SwitchHookParams)
640
self.assertTrue(hasattr(params, 'to_branch'))
641
self.assertTrue(hasattr(params, 'revision_id'))
644
class TestBranchOptions(tests.TestCaseWithTransport):
647
super(TestBranchOptions, self).setUp()
648
self.branch = self.make_branch('.')
649
self.config = self.branch.get_config()
651
def check_append_revisions_only(self, expected_value, value=None):
652
"""Set append_revisions_only in config and check its interpretation."""
653
if value is not None:
654
self.config.set_user_option('append_revisions_only', value)
655
self.assertEqual(expected_value,
656
self.branch.get_append_revisions_only())
658
def test_valid_append_revisions_only(self):
659
self.assertEquals(None,
660
self.config.get_user_option('append_revisions_only'))
661
self.check_append_revisions_only(None)
662
self.check_append_revisions_only(False, 'False')
663
self.check_append_revisions_only(True, 'True')
664
# The following values will cause compatibility problems on projects
665
# using older bzr versions (<2.2) but are accepted
666
self.check_append_revisions_only(False, 'false')
667
self.check_append_revisions_only(True, 'true')
669
def test_invalid_append_revisions_only(self):
670
"""Ensure warning is noted on invalid settings"""
673
self.warnings.append(args[0] % args[1:])
674
self.overrideAttr(trace, 'warning', warning)
675
self.check_append_revisions_only(None, 'not-a-bool')
676
self.assertLength(1, self.warnings)
678
'Value "not-a-bool" is not a boolean for "append_revisions_only"',
682
class TestPullResult(tests.TestCase):
684
def test_pull_result_to_int(self):
685
# to support old code, the pull result can be used as an int
686
r = _mod_branch.PullResult()
689
# this usage of results is not recommended for new code (because it
690
# doesn't describe very well what happened), but for api stability
691
# it's still supported
692
self.assertEqual(self.applyDeprecated(
693
symbol_versioning.deprecated_in((2, 3, 0)),
697
def test_report_changed(self):
698
r = _mod_branch.PullResult()
699
r.old_revid = "old-revid"
701
r.new_revid = "new-revid"
705
self.assertEqual("Now on revision 20.\n", f.getvalue())
707
def test_report_unchanged(self):
708
r = _mod_branch.PullResult()
709
r.old_revid = "same-revid"
710
r.new_revid = "same-revid"
713
self.assertEqual("No revisions or tags to pull.\n", f.getvalue())