35
revision as _mod_revision,
37
transport as _mod_transport,
49
import breezy.bzr.branch
50
from ..bzr.fullhistory import BzrBranchFormat5
51
from ..errors import (
53
NoColocatedBranchSupport,
55
UnsupportedFormatError,
38
from bzrlib.errors import (NotBranchError,
39
NoColocatedBranchSupport,
41
UnsupportedFormatError,
43
from bzrlib.tests import (
59
45
TestCaseWithMemoryTransport,
60
46
TestCaseWithTransport,
49
from bzrlib.tests import(
67
from ..transport import (
53
from bzrlib.tests.test_http import TestWithTransport_pycurl
54
from bzrlib.transport import (
71
from ..transport.http import HttpTransport
72
from ..transport.nosmart import NoSmartTransportDecorator
73
from ..transport.readonly import ReadonlyTransportDecorator
74
from ..bzr import knitrepo, knitpack_repo
58
from bzrlib.transport.http._urllib import HttpTransport_urllib
59
from bzrlib.transport.nosmart import NoSmartTransportDecorator
60
from bzrlib.transport.readonly import ReadonlyTransportDecorator
61
from bzrlib.repofmt import knitrepo, weaverepo, pack_repo
77
64
class TestDefaultFormat(TestCase):
79
66
def test_get_set_default_format(self):
80
67
old_format = bzrdir.BzrDirFormat.get_default_format()
81
# default is BzrDirMetaFormat1
82
self.assertIsInstance(old_format, bzrdir.BzrDirMetaFormat1)
83
controldir.ControlDirFormat._set_default_format(SampleBzrDirFormat())
68
# default is BzrDirFormat6
69
self.failUnless(isinstance(old_format, bzrdir.BzrDirMetaFormat1))
70
bzrdir.BzrDirFormat._set_default_format(SampleBzrDirFormat())
84
71
# creating a bzr dir should now create an instrumented dir.
86
73
result = bzrdir.BzrDir.create('memory:///')
87
self.assertIsInstance(result, SampleBzrDir)
74
self.failUnless(isinstance(result, SampleBzrDir))
89
controldir.ControlDirFormat._set_default_format(old_format)
76
bzrdir.BzrDirFormat._set_default_format(old_format)
90
77
self.assertEqual(old_format, bzrdir.BzrDirFormat.get_default_format())
93
class DeprecatedBzrDirFormat(bzrdir.BzrDirFormat):
94
"""A deprecated bzr dir format."""
97
80
class TestFormatRegistry(TestCase):
99
82
def make_format_registry(self):
100
my_format_registry = controldir.ControlDirFormatRegistry()
101
my_format_registry.register('deprecated', DeprecatedBzrDirFormat,
102
'Some format. Slower and unawesome and deprecated.',
104
my_format_registry.register_lazy('lazy', 'breezy.tests.test_bzrdir',
105
'DeprecatedBzrDirFormat', 'Format registered lazily',
107
bzr.register_metadir(my_format_registry, 'knit',
108
'breezy.bzr.knitrepo.RepositoryFormatKnit1',
109
'Format using knits',
83
my_format_registry = bzrdir.BzrDirFormatRegistry()
84
my_format_registry.register('weave', bzrdir.BzrDirFormat6,
85
'Pre-0.8 format. Slower and does not support checkouts or shared'
86
' repositories', deprecated=True)
87
my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir',
88
'BzrDirFormat6', 'Format registered lazily', deprecated=True)
89
my_format_registry.register_metadir('knit',
90
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
111
93
my_format_registry.set_default('knit')
112
bzr.register_metadir(my_format_registry,
114
'breezy.bzr.knitrepo.RepositoryFormatKnit3',
115
'Experimental successor to knit. Use at your own risk.',
116
branch_format='breezy.bzr.branch.BzrBranchFormat6',
118
bzr.register_metadir(my_format_registry,
120
'breezy.bzr.knitrepo.RepositoryFormatKnit3',
121
'Experimental successor to knit. Use at your own risk.',
122
branch_format='breezy.bzr.branch.BzrBranchFormat6', hidden=True)
123
my_format_registry.register('hiddendeprecated', DeprecatedBzrDirFormat,
124
'Old format. Slower and does not support things. ', hidden=True)
125
my_format_registry.register_lazy('hiddenlazy', 'breezy.tests.test_bzrdir',
126
'DeprecatedBzrDirFormat', 'Format registered lazily',
127
deprecated=True, hidden=True)
94
my_format_registry.register_metadir(
96
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
97
'Experimental successor to knit. Use at your own risk.',
98
branch_format='bzrlib.branch.BzrBranchFormat6',
100
my_format_registry.register_metadir(
102
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
103
'Experimental successor to knit. Use at your own risk.',
104
branch_format='bzrlib.branch.BzrBranchFormat6', hidden=True)
105
my_format_registry.register('hiddenweave', bzrdir.BzrDirFormat6,
106
'Pre-0.8 format. Slower and does not support checkouts or shared'
107
' repositories', hidden=True)
108
my_format_registry.register_lazy('hiddenlazy', 'bzrlib.bzrdir',
109
'BzrDirFormat6', 'Format registered lazily', deprecated=True,
128
111
return my_format_registry
130
113
def test_format_registry(self):
131
114
my_format_registry = self.make_format_registry()
132
my_bzrdir = my_format_registry.make_controldir('lazy')
133
self.assertIsInstance(my_bzrdir, DeprecatedBzrDirFormat)
134
my_bzrdir = my_format_registry.make_controldir('deprecated')
135
self.assertIsInstance(my_bzrdir, DeprecatedBzrDirFormat)
136
my_bzrdir = my_format_registry.make_controldir('default')
137
self.assertIsInstance(my_bzrdir.repository_format,
138
knitrepo.RepositoryFormatKnit1)
139
my_bzrdir = my_format_registry.make_controldir('knit')
140
self.assertIsInstance(my_bzrdir.repository_format,
141
knitrepo.RepositoryFormatKnit1)
142
my_bzrdir = my_format_registry.make_controldir('branch6')
115
my_bzrdir = my_format_registry.make_bzrdir('lazy')
116
self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
117
my_bzrdir = my_format_registry.make_bzrdir('weave')
118
self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
119
my_bzrdir = my_format_registry.make_bzrdir('default')
120
self.assertIsInstance(my_bzrdir.repository_format,
121
knitrepo.RepositoryFormatKnit1)
122
my_bzrdir = my_format_registry.make_bzrdir('knit')
123
self.assertIsInstance(my_bzrdir.repository_format,
124
knitrepo.RepositoryFormatKnit1)
125
my_bzrdir = my_format_registry.make_bzrdir('branch6')
143
126
self.assertIsInstance(my_bzrdir.get_branch_format(),
144
breezy.bzr.branch.BzrBranchFormat6)
127
bzrlib.branch.BzrBranchFormat6)
146
129
def test_get_help(self):
147
130
my_format_registry = self.make_format_registry()
166
150
experimental, deprecated = rest.split('Deprecated formats')
167
151
self.assertContainsRe(new, 'formats-help')
168
152
self.assertContainsRe(new,
169
':knit:\n \\(native\\) \\(default\\) Format using knits\n')
153
':knit:\n \(native\) \(default\) Format using knits\n')
170
154
self.assertContainsRe(experimental,
171
':branch6:\n \\(native\\) Experimental successor to knit')
155
':branch6:\n \(native\) Experimental successor to knit')
172
156
self.assertContainsRe(deprecated,
173
':lazy:\n \\(native\\) Format registered lazily\n')
157
':lazy:\n \(native\) Format registered lazily\n')
174
158
self.assertNotContainsRe(new, 'hidden')
176
160
def test_set_default_repository(self):
177
default_factory = controldir.format_registry.get('default')
178
old_default = [k for k, v in controldir.format_registry.iteritems()
161
default_factory = bzrdir.format_registry.get('default')
162
old_default = [k for k, v in bzrdir.format_registry.iteritems()
179
163
if v == default_factory and k != 'default'][0]
180
controldir.format_registry.set_default_repository(
181
'dirstate-with-subtree')
164
bzrdir.format_registry.set_default_repository('dirstate-with-subtree')
183
self.assertIs(controldir.format_registry.get('dirstate-with-subtree'),
184
controldir.format_registry.get('default'))
166
self.assertIs(bzrdir.format_registry.get('dirstate-with-subtree'),
167
bzrdir.format_registry.get('default'))
186
repository.format_registry.get_default().__class__,
169
repository.RepositoryFormat.get_default_format().__class__,
187
170
knitrepo.RepositoryFormatKnit3)
189
controldir.format_registry.set_default_repository(old_default)
172
bzrdir.format_registry.set_default_repository(old_default)
191
174
def test_aliases(self):
192
a_registry = controldir.ControlDirFormatRegistry()
193
a_registry.register('deprecated', DeprecatedBzrDirFormat,
194
'Old format. Slower and does not support stuff',
196
a_registry.register_alias('deprecatedalias', 'deprecated')
197
self.assertEqual({'deprecatedalias': 'deprecated'},
198
a_registry.aliases())
201
class SampleBranch(breezy.branch.Branch):
175
a_registry = bzrdir.BzrDirFormatRegistry()
176
a_registry.register('weave', bzrdir.BzrDirFormat6,
177
'Pre-0.8 format. Slower and does not support checkouts or shared'
178
' repositories', deprecated=True)
179
a_registry.register('weavealias', bzrdir.BzrDirFormat6,
180
'Pre-0.8 format. Slower and does not support checkouts or shared'
181
' repositories', deprecated=True, alias=True)
182
self.assertEqual(frozenset(['weavealias']), a_registry.aliases())
185
class SampleBranch(bzrlib.branch.Branch):
202
186
"""A dummy branch for guess what, dummy use."""
204
188
def __init__(self, dir):
205
self.controldir = dir
208
class SampleRepository(breezy.repository.Repository):
192
class SampleRepository(bzrlib.repository.Repository):
209
193
"""A dummy repo."""
211
195
def __init__(self, dir):
212
self.controldir = dir
215
199
class SampleBzrDir(bzrdir.BzrDir):
216
200
"""A sample BzrDir implementation to allow testing static methods."""
218
202
def create_repository(self, shared=False):
219
"""See ControlDir.create_repository."""
203
"""See BzrDir.create_repository."""
220
204
return "A repository"
222
206
def open_repository(self):
223
"""See ControlDir.open_repository."""
207
"""See BzrDir.open_repository."""
224
208
return SampleRepository(self)
226
210
def create_branch(self, name=None):
227
"""See ControlDir.create_branch."""
211
"""See BzrDir.create_branch."""
228
212
if name is not None:
229
213
raise NoColocatedBranchSupport(self)
230
214
return SampleBranch(self)
232
216
def create_workingtree(self):
233
"""See ControlDir.create_workingtree."""
217
"""See BzrDir.create_workingtree."""
282
248
def test_find_format(self):
283
249
# is the right format object found for a branch?
284
250
# create a branch with a few known format objects.
285
bzr.BzrProber.formats.register(BzrDirFormatTest1.get_format_string(),
287
self.addCleanup(bzr.BzrProber.formats.remove,
288
BzrDirFormatTest1.get_format_string())
289
bzr.BzrProber.formats.register(BzrDirFormatTest2.get_format_string(),
291
self.addCleanup(bzr.BzrProber.formats.remove,
292
BzrDirFormatTest2.get_format_string())
293
t = self.get_transport()
251
# this is not quite the same as
252
t = get_transport(self.get_url())
294
253
self.build_tree(["foo/", "bar/"], transport=t)
296
254
def check_format(format, url):
297
255
format.initialize(url)
298
t = _mod_transport.get_transport_from_path(url)
256
t = get_transport(url)
299
257
found_format = bzrdir.BzrDirFormat.find_format(t)
300
self.assertIsInstance(found_format, format.__class__)
301
check_format(BzrDirFormatTest1(), "foo")
302
check_format(BzrDirFormatTest2(), "bar")
258
self.failUnless(isinstance(found_format, format.__class__))
259
check_format(bzrdir.BzrDirFormat5(), "foo")
260
check_format(bzrdir.BzrDirFormat6(), "bar")
304
262
def test_find_format_nothing_there(self):
305
263
self.assertRaises(NotBranchError,
306
264
bzrdir.BzrDirFormat.find_format,
307
_mod_transport.get_transport_from_path('.'))
309
267
def test_find_format_unknown_format(self):
310
t = self.get_transport()
268
t = get_transport(self.get_url())
312
t.put_bytes('.bzr/branch-format', b'')
270
t.put_bytes('.bzr/branch-format', '')
313
271
self.assertRaises(UnknownFormatError,
314
272
bzrdir.BzrDirFormat.find_format,
315
_mod_transport.get_transport_from_path('.'))
317
def test_find_format_line_endings(self):
318
t = self.get_transport()
320
t.put_bytes('.bzr/branch-format', b'Corrupt line endings\r\n')
321
self.assertRaises(errors.LineEndingError,
322
bzrdir.BzrDirFormat.find_format,
323
_mod_transport.get_transport_from_path('.'))
325
275
def test_register_unregister_format(self):
326
276
format = SampleBzrDirFormat()
390
338
bzrdir.BzrDir.create_standalone_workingtree,
391
339
self.get_readonly_url('child'), format=format)
392
340
tree = bzrdir.BzrDir.create_standalone_workingtree('child',
394
tree.controldir.open_repository()
342
tree.bzrdir.open_repository()
396
344
def test_create_branch_convenience(self):
397
345
# outside a repo the default convenience output is a repo+branch_tree
398
format = controldir.format_registry.make_controldir('knit')
346
format = bzrdir.format_registry.make_bzrdir('knit')
399
347
branch = bzrdir.BzrDir.create_branch_convenience('.', format=format)
400
branch.controldir.open_workingtree()
401
branch.controldir.open_repository()
348
branch.bzrdir.open_workingtree()
349
branch.bzrdir.open_repository()
403
351
def test_create_branch_convenience_possible_transports(self):
404
352
"""Check that the optional 'possible_transports' is recognized"""
405
format = controldir.format_registry.make_controldir('knit')
353
format = bzrdir.format_registry.make_bzrdir('knit')
406
354
t = self.get_transport()
407
355
branch = bzrdir.BzrDir.create_branch_convenience(
408
356
'.', format=format, possible_transports=[t])
409
branch.controldir.open_workingtree()
410
branch.controldir.open_repository()
357
branch.bzrdir.open_workingtree()
358
branch.bzrdir.open_repository()
412
360
def test_create_branch_convenience_root(self):
413
361
"""Creating a branch at the root of a fs should work."""
414
362
self.vfs_transport_factory = memory.MemoryServer
415
363
# outside a repo the default convenience output is a repo+branch_tree
416
format = controldir.format_registry.make_controldir('knit')
364
format = bzrdir.format_registry.make_bzrdir('knit')
417
365
branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(),
419
367
self.assertRaises(errors.NoWorkingTree,
420
branch.controldir.open_workingtree)
421
branch.controldir.open_repository()
368
branch.bzrdir.open_workingtree)
369
branch.bzrdir.open_repository()
423
371
def test_create_branch_convenience_under_shared_repo(self):
424
372
# inside a repo the default convenience output is a branch+ follow the
425
373
# repo tree policy
426
format = controldir.format_registry.make_controldir('knit')
374
format = bzrdir.format_registry.make_bzrdir('knit')
427
375
self.make_repository('.', shared=True, format=format)
428
376
branch = bzrdir.BzrDir.create_branch_convenience('child',
430
branch.controldir.open_workingtree()
378
branch.bzrdir.open_workingtree()
431
379
self.assertRaises(errors.NoRepositoryPresent,
432
branch.controldir.open_repository)
380
branch.bzrdir.open_repository)
434
382
def test_create_branch_convenience_under_shared_repo_force_no_tree(self):
435
383
# inside a repo the default convenience output is a branch+ follow the
436
384
# repo tree policy but we can override that
437
format = controldir.format_registry.make_controldir('knit')
385
format = bzrdir.format_registry.make_bzrdir('knit')
438
386
self.make_repository('.', shared=True, format=format)
439
387
branch = bzrdir.BzrDir.create_branch_convenience('child',
440
force_new_tree=False, format=format)
388
force_new_tree=False, format=format)
441
389
self.assertRaises(errors.NoWorkingTree,
442
branch.controldir.open_workingtree)
390
branch.bzrdir.open_workingtree)
443
391
self.assertRaises(errors.NoRepositoryPresent,
444
branch.controldir.open_repository)
392
branch.bzrdir.open_repository)
446
394
def test_create_branch_convenience_under_shared_repo_no_tree_policy(self):
447
395
# inside a repo the default convenience output is a branch+ follow the
448
396
# repo tree policy
449
format = controldir.format_registry.make_controldir('knit')
397
format = bzrdir.format_registry.make_bzrdir('knit')
450
398
repo = self.make_repository('.', shared=True, format=format)
451
399
repo.set_make_working_trees(False)
452
400
branch = bzrdir.BzrDir.create_branch_convenience('child',
454
402
self.assertRaises(errors.NoWorkingTree,
455
branch.controldir.open_workingtree)
403
branch.bzrdir.open_workingtree)
456
404
self.assertRaises(errors.NoRepositoryPresent,
457
branch.controldir.open_repository)
405
branch.bzrdir.open_repository)
459
407
def test_create_branch_convenience_under_shared_repo_no_tree_policy_force_tree(self):
460
408
# inside a repo the default convenience output is a branch+ follow the
461
409
# repo tree policy but we can override that
462
format = controldir.format_registry.make_controldir('knit')
410
format = bzrdir.format_registry.make_bzrdir('knit')
463
411
repo = self.make_repository('.', shared=True, format=format)
464
412
repo.set_make_working_trees(False)
465
413
branch = bzrdir.BzrDir.create_branch_convenience('child',
466
force_new_tree=True, format=format)
467
branch.controldir.open_workingtree()
414
force_new_tree=True, format=format)
415
branch.bzrdir.open_workingtree()
468
416
self.assertRaises(errors.NoRepositoryPresent,
469
branch.controldir.open_repository)
417
branch.bzrdir.open_repository)
471
419
def test_create_branch_convenience_under_shared_repo_force_new_repo(self):
472
420
# inside a repo the default convenience output is overridable to give
473
421
# repo+branch+tree
474
format = controldir.format_registry.make_controldir('knit')
422
format = bzrdir.format_registry.make_bzrdir('knit')
475
423
self.make_repository('.', shared=True, format=format)
476
424
branch = bzrdir.BzrDir.create_branch_convenience('child',
477
force_new_repo=True, format=format)
478
branch.controldir.open_repository()
479
branch.controldir.open_workingtree()
425
force_new_repo=True, format=format)
426
branch.bzrdir.open_repository()
427
branch.bzrdir.open_workingtree()
482
430
class TestRepositoryAcquisitionPolicy(TestCaseWithTransport):
484
432
def test_acquire_repository_standalone(self):
485
433
"""The default acquisition policy should create a standalone branch."""
486
my_bzrdir = self.make_controldir('.')
434
my_bzrdir = self.make_bzrdir('.')
487
435
repo_policy = my_bzrdir.determine_repository_policy()
488
436
repo, is_new = repo_policy.acquire_repository()
489
self.assertEqual(repo.controldir.root_transport.base,
437
self.assertEqual(repo.bzrdir.root_transport.base,
490
438
my_bzrdir.root_transport.base)
491
439
self.assertFalse(repo.is_shared())
493
441
def test_determine_stacking_policy(self):
494
parent_bzrdir = self.make_controldir('.')
495
child_bzrdir = self.make_controldir('child')
442
parent_bzrdir = self.make_bzrdir('.')
443
child_bzrdir = self.make_bzrdir('child')
496
444
parent_bzrdir.get_config().set_default_stack_on('http://example.org')
497
445
repo_policy = child_bzrdir.determine_repository_policy()
498
446
self.assertEqual('http://example.org', repo_policy._stack_on)
500
448
def test_determine_stacking_policy_relative(self):
501
parent_bzrdir = self.make_controldir('.')
502
child_bzrdir = self.make_controldir('child')
449
parent_bzrdir = self.make_bzrdir('.')
450
child_bzrdir = self.make_bzrdir('child')
503
451
parent_bzrdir.get_config().set_default_stack_on('child2')
504
452
repo_policy = child_bzrdir.determine_repository_policy()
505
453
self.assertEqual('child2', repo_policy._stack_on)
516
464
def test_clone_on_transport_obeys_stacking_policy(self):
517
465
child_branch, new_child_transport = self.prepare_default_stacking()
518
new_child = child_branch.controldir.clone_on_transport(
466
new_child = child_branch.bzrdir.clone_on_transport(new_child_transport)
520
467
self.assertEqual(child_branch.base,
521
468
new_child.open_branch().get_stacked_on_url())
523
470
def test_default_stacking_with_stackable_branch_unstackable_repo(self):
524
471
# Make stackable source branch with an unstackable repo format.
525
source_bzrdir = self.make_controldir('source')
526
knitpack_repo.RepositoryFormatKnitPack1().initialize(source_bzrdir)
527
source_branch = breezy.bzr.branch.BzrBranchFormat7().initialize(
472
source_bzrdir = self.make_bzrdir('source')
473
pack_repo.RepositoryFormatKnitPack1().initialize(source_bzrdir)
474
source_branch = bzrlib.branch.BzrBranchFormat7().initialize(
529
476
# Make a directory with a default stacking policy
530
parent_bzrdir = self.make_controldir('parent')
477
parent_bzrdir = self.make_bzrdir('parent')
531
478
stacked_on = self.make_branch('parent/stacked-on', format='pack-0.92')
532
479
parent_bzrdir.get_config().set_default_stack_on(stacked_on.base)
533
480
# Clone source into directory
534
481
target = source_bzrdir.clone(self.get_url('parent/target'))
536
def test_format_initialize_on_transport_ex_stacked_on(self):
537
# trunk is a stackable format. Note that its in the same server area
538
# which is what launchpad does, but not sufficient to exercise the
540
trunk = self.make_branch('trunk', format='1.9')
541
t = self.get_transport('stacked')
542
old_fmt = controldir.format_registry.make_controldir('pack-0.92')
543
repo_name = old_fmt.repository_format.network_name()
544
# Should end up with a 1.9 format (stackable)
545
repo, control, require_stacking, repo_policy = \
546
old_fmt.initialize_on_transport_ex(t,
547
repo_format_name=repo_name, stacked_on='../trunk',
550
# Repositories are open write-locked
551
self.assertTrue(repo.is_write_locked())
552
self.addCleanup(repo.unlock)
554
repo = control.open_repository()
555
self.assertIsInstance(control, bzrdir.BzrDir)
556
opened = bzrdir.BzrDir.open(t.base)
557
if not isinstance(old_fmt, remote.RemoteBzrDirFormat):
558
self.assertEqual(control._format.network_name(),
559
old_fmt.network_name())
560
self.assertEqual(control._format.network_name(),
561
opened._format.network_name())
562
self.assertEqual(control.__class__, opened.__class__)
563
self.assertLength(1, repo._fallback_repositories)
565
483
def test_sprout_obeys_stacking_policy(self):
566
484
child_branch, new_child_transport = self.prepare_default_stacking()
567
new_child = child_branch.controldir.sprout(new_child_transport.base)
485
new_child = child_branch.bzrdir.sprout(new_child_transport.base)
568
486
self.assertEqual(child_branch.base,
569
487
new_child.open_branch().get_stacked_on_url())
571
489
def test_clone_ignores_policy_for_unsupported_formats(self):
572
490
child_branch, new_child_transport = self.prepare_default_stacking(
573
491
child_format='pack-0.92')
574
new_child = child_branch.controldir.clone_on_transport(
576
self.assertRaises(branch.UnstackableBranchFormat,
492
new_child = child_branch.bzrdir.clone_on_transport(new_child_transport)
493
self.assertRaises(errors.UnstackableBranchFormat,
577
494
new_child.open_branch().get_stacked_on_url)
579
496
def test_sprout_ignores_policy_for_unsupported_formats(self):
580
497
child_branch, new_child_transport = self.prepare_default_stacking(
581
498
child_format='pack-0.92')
582
new_child = child_branch.controldir.sprout(new_child_transport.base)
583
self.assertRaises(branch.UnstackableBranchFormat,
499
new_child = child_branch.bzrdir.sprout(new_child_transport.base)
500
self.assertRaises(errors.UnstackableBranchFormat,
584
501
new_child.open_branch().get_stacked_on_url)
586
503
def test_sprout_upgrades_format_if_stacked_specified(self):
587
504
child_branch, new_child_transport = self.prepare_default_stacking(
588
505
child_format='pack-0.92')
589
new_child = child_branch.controldir.sprout(new_child_transport.base,
591
self.assertEqual(child_branch.controldir.root_transport.base,
506
new_child = child_branch.bzrdir.sprout(new_child_transport.base,
508
self.assertEqual(child_branch.bzrdir.root_transport.base,
592
509
new_child.open_branch().get_stacked_on_url())
593
510
repo = new_child.open_repository()
594
511
self.assertTrue(repo._format.supports_external_lookups)
757
672
self.assertEqual(branch, None)
758
673
self.assertEqual(
759
674
osutils.realpath(os.path.join('bar', '.bzr', 'repository')),
760
repo.controldir.transport.local_abspath('repository'))
675
repo.bzrdir.transport.local_abspath('repository'))
761
676
self.assertEqual(relpath, 'baz')
763
678
def test_open_containing_from_transport(self):
764
self.assertRaises(NotBranchError,
765
bzrdir.BzrDir.open_containing_from_transport,
766
_mod_transport.get_transport_from_url(self.get_readonly_url('')))
767
self.assertRaises(NotBranchError,
768
bzrdir.BzrDir.open_containing_from_transport,
769
_mod_transport.get_transport_from_url(
770
self.get_readonly_url('g/p/q')))
679
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
680
get_transport(self.get_readonly_url('')))
681
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
682
get_transport(self.get_readonly_url('g/p/q')))
771
683
control = bzrdir.BzrDir.create(self.get_url())
772
684
branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
773
_mod_transport.get_transport_from_url(
774
self.get_readonly_url('')))
685
get_transport(self.get_readonly_url('')))
775
686
self.assertEqual('', relpath)
776
687
branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
777
_mod_transport.get_transport_from_url(
778
self.get_readonly_url('g/p/q')))
688
get_transport(self.get_readonly_url('g/p/q')))
779
689
self.assertEqual('g/p/q', relpath)
781
691
def test_open_containing_tree_or_branch(self):
821
731
self.assertEqual(os.path.realpath('topdir/foo'),
822
732
self.local_branch_path(branch))
824
def test_open_tree_or_branch_named(self):
825
tree = self.make_branch_and_tree('topdir')
828
bzrdir.BzrDir.open_tree_or_branch, 'topdir', name='missing')
829
tree.branch.controldir.create_branch('named')
830
tree, branch = bzrdir.BzrDir.open_tree_or_branch('topdir', name='named')
831
self.assertEqual(os.path.realpath('topdir'),
832
os.path.realpath(tree.basedir))
833
self.assertEqual(os.path.realpath('topdir'),
834
self.local_branch_path(branch))
835
self.assertEqual(branch.name, 'named')
836
self.assertIs(tree.controldir, branch.controldir)
838
734
def test_open_from_transport(self):
839
735
# transport pointing at bzrdir should give a bzrdir with root transport
840
736
# set to the given transport
841
737
control = bzrdir.BzrDir.create(self.get_url())
842
t = self.get_transport()
843
opened_bzrdir = bzrdir.BzrDir.open_from_transport(t)
844
self.assertEqual(t.base, opened_bzrdir.root_transport.base)
738
transport = get_transport(self.get_url())
739
opened_bzrdir = bzrdir.BzrDir.open_from_transport(transport)
740
self.assertEqual(transport.base, opened_bzrdir.root_transport.base)
845
741
self.assertIsInstance(opened_bzrdir, bzrdir.BzrDir)
847
743
def test_open_from_transport_no_bzrdir(self):
848
t = self.get_transport()
849
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport, t)
744
transport = get_transport(self.get_url())
745
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
851
748
def test_open_from_transport_bzrdir_in_parent(self):
852
749
control = bzrdir.BzrDir.create(self.get_url())
853
t = self.get_transport()
855
t = t.clone('subdir')
856
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport, t)
750
transport = get_transport(self.get_url())
751
transport.mkdir('subdir')
752
transport = transport.clone('subdir')
753
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
858
756
def test_sprout_recursive(self):
859
tree = self.make_branch_and_tree('tree1')
860
sub_tree = self.make_branch_and_tree('tree1/subtree')
861
sub_tree.set_root_id(b'subtree-root')
757
tree = self.make_branch_and_tree('tree1',
758
format='dirstate-with-subtree')
759
sub_tree = self.make_branch_and_tree('tree1/subtree',
760
format='dirstate-with-subtree')
761
sub_tree.set_root_id('subtree-root')
862
762
tree.add_reference(sub_tree)
863
tree.set_reference_info('subtree', sub_tree.branch.user_url)
864
763
self.build_tree(['tree1/subtree/file'])
865
764
sub_tree.add('file')
866
765
tree.commit('Initial commit')
867
tree2 = tree.controldir.sprout('tree2').open_workingtree()
766
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
868
767
tree2.lock_read()
869
768
self.addCleanup(tree2.unlock)
870
self.assertPathExists('tree2/subtree/file')
871
self.assertEqual('tree-reference', tree2.kind('subtree'))
769
self.failUnlessExists('tree2/subtree/file')
770
self.assertEqual('tree-reference', tree2.kind('subtree-root'))
873
772
def test_cloning_metadir(self):
874
773
"""Ensure that cloning metadir is suitable"""
875
bzrdir = self.make_controldir('bzrdir')
774
bzrdir = self.make_bzrdir('bzrdir')
876
775
bzrdir.cloning_metadir()
877
776
branch = self.make_branch('branch', format='knit')
878
format = branch.controldir.cloning_metadir()
777
format = branch.bzrdir.cloning_metadir()
879
778
self.assertIsInstance(format.workingtree_format,
880
workingtree_4.WorkingTreeFormat6)
779
workingtree.WorkingTreeFormat3)
882
781
def test_sprout_recursive_treeless(self):
883
782
tree = self.make_branch_and_tree('tree1',
884
format='development-subtree')
783
format='dirstate-with-subtree')
885
784
sub_tree = self.make_branch_and_tree('tree1/subtree',
886
format='development-subtree')
785
format='dirstate-with-subtree')
887
786
tree.add_reference(sub_tree)
888
tree.set_reference_info('subtree', sub_tree.branch.user_url)
889
787
self.build_tree(['tree1/subtree/file'])
890
788
sub_tree.add('file')
891
789
tree.commit('Initial commit')
892
# The following line force the orhaning to reveal bug #634470
893
tree.branch.get_config_stack().set('transform.orphan_policy', 'move')
894
tree.controldir.destroy_workingtree()
895
# FIXME: subtree/.bzr is left here which allows the test to pass (or
896
# fail :-( ) -- vila 20100909
790
tree.bzrdir.destroy_workingtree()
897
791
repo = self.make_repository('repo', shared=True,
898
format='development-subtree')
792
format='dirstate-with-subtree')
899
793
repo.set_make_working_trees(False)
900
# FIXME: we just deleted the workingtree and now we want to use it ????
901
# At a minimum, we should use tree.branch below (but this fails too
902
# currently) or stop calling this test 'treeless'. Specifically, I've
903
# turn the line below into an assertRaises when 'subtree/.bzr' is
904
# orphaned and sprout tries to access the branch there (which is left
905
# by bzrdir.BzrDirMeta1.destroy_workingtree when it ignores the
906
# [DeletingParent('Not deleting', u'subtree', None)] conflict). See bug
907
# #634470. -- vila 20100909
908
tree.controldir.sprout('repo/tree2')
909
self.assertPathExists('repo/tree2/subtree')
910
self.assertPathDoesNotExist('repo/tree2/subtree/file')
794
tree.bzrdir.sprout('repo/tree2')
795
self.failUnlessExists('repo/tree2/subtree')
796
self.failIfExists('repo/tree2/subtree/file')
912
798
def make_foo_bar_baz(self):
913
foo = bzrdir.BzrDir.create_branch_convenience('foo').controldir
914
bar = self.make_branch('foo/bar').controldir
915
baz = self.make_branch('baz').controldir
799
foo = bzrdir.BzrDir.create_branch_convenience('foo').bzrdir
800
bar = self.make_branch('foo/bar').bzrdir
801
baz = self.make_branch('baz').bzrdir
916
802
return foo, bar, baz
918
def test_find_controldirs(self):
919
foo, bar, baz = self.make_foo_bar_baz()
920
t = self.get_transport()
921
self.assertEqualBzrdirs(
922
[baz, foo, bar], bzrdir.BzrDir.find_controldirs(t))
924
def make_fake_permission_denied_transport(self, transport, paths):
925
"""Create a transport that raises PermissionDenied for some paths."""
928
raise errors.PermissionDenied(path)
930
path_filter_server = pathfilter.PathFilteringServer(transport, filter)
931
path_filter_server.start_server()
932
self.addCleanup(path_filter_server.stop_server)
933
path_filter_transport = pathfilter.PathFilteringTransport(
934
path_filter_server, '.')
935
return (path_filter_server, path_filter_transport)
937
def assertBranchUrlsEndWith(self, expect_url_suffix, actual_bzrdirs):
938
"""Check that each branch url ends with the given suffix."""
939
for actual_bzrdir in actual_bzrdirs:
940
self.assertEndsWith(actual_bzrdir.user_url, expect_url_suffix)
942
def test_find_controldirs_permission_denied(self):
943
foo, bar, baz = self.make_foo_bar_baz()
944
t = self.get_transport()
945
path_filter_server, path_filter_transport = \
946
self.make_fake_permission_denied_transport(t, ['foo'])
948
self.assertBranchUrlsEndWith('/baz/',
949
bzrdir.BzrDir.find_controldirs(path_filter_transport))
951
smart_transport = self.make_smart_server('.',
952
backing_server=path_filter_server)
953
self.assertBranchUrlsEndWith('/baz/',
954
bzrdir.BzrDir.find_controldirs(smart_transport))
956
def test_find_controldirs_list_current(self):
804
def test_find_bzrdirs(self):
805
foo, bar, baz = self.make_foo_bar_baz()
806
transport = get_transport(self.get_url())
807
self.assertEqualBzrdirs([baz, foo, bar],
808
bzrdir.BzrDir.find_bzrdirs(transport))
810
def test_find_bzrdirs_list_current(self):
957
811
def list_current(transport):
958
812
return [s for s in transport.list_dir('') if s != 'baz']
960
814
foo, bar, baz = self.make_foo_bar_baz()
961
t = self.get_transport()
962
self.assertEqualBzrdirs(
964
bzrdir.BzrDir.find_controldirs(t, list_current=list_current))
966
def test_find_controldirs_evaluate(self):
815
transport = get_transport(self.get_url())
816
self.assertEqualBzrdirs([foo, bar],
817
bzrdir.BzrDir.find_bzrdirs(transport,
818
list_current=list_current))
821
def test_find_bzrdirs_evaluate(self):
967
822
def evaluate(bzrdir):
969
824
repo = bzrdir.open_repository()
970
except errors.NoRepositoryPresent:
825
except NoRepositoryPresent:
971
826
return True, bzrdir.root_transport.base
973
828
return False, bzrdir.root_transport.base
975
830
foo, bar, baz = self.make_foo_bar_baz()
976
t = self.get_transport()
831
transport = get_transport(self.get_url())
977
832
self.assertEqual([baz.root_transport.base, foo.root_transport.base],
978
list(bzrdir.BzrDir.find_controldirs(t, evaluate=evaluate)))
833
list(bzrdir.BzrDir.find_bzrdirs(transport,
980
836
def assertEqualBzrdirs(self, first, second):
981
837
first = list(first)
1049
887
Metadirs should compare equal iff they have the same repo, branch and
1052
mydir = controldir.format_registry.make_controldir('knit')
890
mydir = bzrdir.format_registry.make_bzrdir('knit')
1053
891
self.assertEqual(mydir, mydir)
1054
892
self.assertFalse(mydir != mydir)
1055
otherdir = controldir.format_registry.make_controldir('knit')
893
otherdir = bzrdir.format_registry.make_bzrdir('knit')
1056
894
self.assertEqual(otherdir, mydir)
1057
895
self.assertFalse(otherdir != mydir)
1058
otherdir2 = controldir.format_registry.make_controldir(
1059
'development-subtree')
896
otherdir2 = bzrdir.format_registry.make_bzrdir('dirstate-with-subtree')
1060
897
self.assertNotEqual(otherdir2, mydir)
1061
898
self.assertFalse(otherdir2 == mydir)
1063
def test_with_features(self):
1064
tree = self.make_branch_and_tree('tree', format='2a')
1065
tree.controldir.update_feature_flags({b"bar": b"required"})
1066
self.assertRaises(bzrdir.MissingFeature, bzrdir.BzrDir.open, 'tree')
1067
bzrdir.BzrDirMetaFormat1.register_feature(b'bar')
1068
self.addCleanup(bzrdir.BzrDirMetaFormat1.unregister_feature, b'bar')
1069
dir = bzrdir.BzrDir.open('tree')
1070
self.assertEqual(b"required", dir._format.features.get(b"bar"))
1071
tree.controldir.update_feature_flags({
1073
b"nonexistant": None})
1074
dir = bzrdir.BzrDir.open('tree')
1075
self.assertEqual({}, dir._format.features)
1077
900
def test_needs_conversion_different_working_tree(self):
1078
901
# meta1dirs need an conversion if any element is not the default.
1079
new_format = controldir.format_registry.make_controldir('dirstate')
902
new_format = bzrdir.format_registry.make_bzrdir('dirstate')
1080
903
tree = self.make_branch_and_tree('tree', format='knit')
1081
self.assertTrue(tree.controldir.needs_format_conversion(
904
self.assertTrue(tree.bzrdir.needs_format_conversion(
1084
907
def test_initialize_on_format_uses_smart_transport(self):
1085
908
self.setup_smart_server_with_call_log()
1086
new_format = controldir.format_registry.make_controldir('dirstate')
909
new_format = bzrdir.format_registry.make_bzrdir('dirstate')
1087
910
transport = self.get_transport('target')
1088
911
transport.ensure_base()
1089
912
self.reset_smart_call_log()
1098
921
self.assertEqual(2, rpc_count)
924
class TestFormat5(TestCaseWithTransport):
925
"""Tests specific to the version 5 bzrdir format."""
927
def test_same_lockfiles_between_tree_repo_branch(self):
928
# this checks that only a single lockfiles instance is created
929
# for format 5 objects
930
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
931
def check_dir_components_use_same_lock(dir):
932
ctrl_1 = dir.open_repository().control_files
933
ctrl_2 = dir.open_branch().control_files
934
ctrl_3 = dir.open_workingtree()._control_files
935
self.assertTrue(ctrl_1 is ctrl_2)
936
self.assertTrue(ctrl_2 is ctrl_3)
937
check_dir_components_use_same_lock(dir)
938
# and if we open it normally.
939
dir = bzrdir.BzrDir.open(self.get_url())
940
check_dir_components_use_same_lock(dir)
942
def test_can_convert(self):
943
# format 5 dirs are convertable
944
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
945
self.assertTrue(dir.can_convert_format())
947
def test_needs_conversion(self):
948
# format 5 dirs need a conversion if they are not the default,
950
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
951
# don't need to convert it to itself
952
self.assertFalse(dir.needs_format_conversion(bzrdir.BzrDirFormat5()))
953
# do need to convert it to the current default
954
self.assertTrue(dir.needs_format_conversion(
955
bzrdir.BzrDirFormat.get_default_format()))
958
class TestFormat6(TestCaseWithTransport):
959
"""Tests specific to the version 6 bzrdir format."""
961
def test_same_lockfiles_between_tree_repo_branch(self):
962
# this checks that only a single lockfiles instance is created
963
# for format 6 objects
964
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
965
def check_dir_components_use_same_lock(dir):
966
ctrl_1 = dir.open_repository().control_files
967
ctrl_2 = dir.open_branch().control_files
968
ctrl_3 = dir.open_workingtree()._control_files
969
self.assertTrue(ctrl_1 is ctrl_2)
970
self.assertTrue(ctrl_2 is ctrl_3)
971
check_dir_components_use_same_lock(dir)
972
# and if we open it normally.
973
dir = bzrdir.BzrDir.open(self.get_url())
974
check_dir_components_use_same_lock(dir)
976
def test_can_convert(self):
977
# format 6 dirs are convertable
978
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
979
self.assertTrue(dir.can_convert_format())
981
def test_needs_conversion(self):
982
# format 6 dirs need an conversion if they are not the default.
983
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
984
self.assertTrue(dir.needs_format_conversion(
985
bzrdir.BzrDirFormat.get_default_format()))
988
class NotBzrDir(bzrlib.bzrdir.BzrDir):
989
"""A non .bzr based control directory."""
991
def __init__(self, transport, format):
992
self._format = format
993
self.root_transport = transport
994
self.transport = transport.clone('.not')
997
class NotBzrDirFormat(bzrlib.bzrdir.BzrDirFormat):
998
"""A test class representing any non-.bzr based disk format."""
1000
def initialize_on_transport(self, transport):
1001
"""Initialize a new .not dir in the base directory of a Transport."""
1002
transport.mkdir('.not')
1003
return self.open(transport)
1005
def open(self, transport):
1006
"""Open this directory."""
1007
return NotBzrDir(transport, self)
1010
def _known_formats(self):
1011
return set([NotBzrDirFormat()])
1014
def probe_transport(self, transport):
1015
"""Our format is present if the transport ends in '.not/'."""
1016
if transport.has('.not'):
1017
return NotBzrDirFormat()
1020
class TestNotBzrDir(TestCaseWithTransport):
1021
"""Tests for using the bzrdir api with a non .bzr based disk format.
1023
If/when one of these is in the core, we can let the implementation tests
1027
def test_create_and_find_format(self):
1028
# create a .notbzr dir
1029
format = NotBzrDirFormat()
1030
dir = format.initialize(self.get_url())
1031
self.assertIsInstance(dir, NotBzrDir)
1033
bzrlib.bzrdir.BzrDirFormat.register_control_format(format)
1035
found = bzrlib.bzrdir.BzrDirFormat.find_format(
1036
get_transport(self.get_url()))
1037
self.assertIsInstance(found, NotBzrDirFormat)
1039
bzrlib.bzrdir.BzrDirFormat.unregister_control_format(format)
1041
def test_included_in_known_formats(self):
1042
bzrlib.bzrdir.BzrDirFormat.register_control_format(NotBzrDirFormat)
1044
formats = bzrlib.bzrdir.BzrDirFormat.known_formats()
1045
for format in formats:
1046
if isinstance(format, NotBzrDirFormat):
1048
self.fail("No NotBzrDirFormat in %s" % formats)
1050
bzrlib.bzrdir.BzrDirFormat.unregister_control_format(NotBzrDirFormat)
1101
1053
class NonLocalTests(TestCaseWithTransport):
1102
1054
"""Tests for bzrdir static behaviour on non local paths."""
1279
1245
def __init__(self, *args, **kwargs):
1280
1246
super(_TestBzrDir, self).__init__(*args, **kwargs)
1281
self.test_branch = _TestBranch(self.transport)
1247
self.test_branch = _TestBranch()
1282
1248
self.test_branch.repository = self.create_repository()
1284
def open_branch(self, unsupported=False, possible_transports=None):
1250
def open_branch(self, unsupported=False):
1285
1251
return self.test_branch
1287
1253
def cloning_metadir(self, require_stacking=False):
1288
1254
return _TestBzrDirFormat()
1291
class _TestBranchFormat(breezy.branch.BranchFormat):
1257
class _TestBranchFormat(bzrlib.branch.BranchFormat):
1292
1258
"""Test Branch format for TestBzrDirSprout."""
1295
class _TestBranch(breezy.branch.Branch):
1261
class _TestBranch(bzrlib.branch.Branch):
1296
1262
"""Test Branch implementation for TestBzrDirSprout."""
1298
def __init__(self, transport, *args, **kwargs):
1264
def __init__(self, *args, **kwargs):
1299
1265
self._format = _TestBranchFormat()
1300
self._transport = transport
1301
self.base = transport.base
1302
1266
super(_TestBranch, self).__init__(*args, **kwargs)
1303
1267
self.calls = []
1304
1268
self._parent = None
1306
1270
def sprout(self, *args, **kwargs):
1307
1271
self.calls.append('sprout')
1308
return _TestBranch(self._transport)
1272
return _TestBranch()
1310
1274
def copy_content_into(self, destination, revision_id=None):
1311
1275
self.calls.append('copy_content_into')
1313
def last_revision(self):
1314
return _mod_revision.NULL_REVISION
1316
1277
def get_parent(self):
1317
1278
return self._parent
1319
def _get_config(self):
1320
return config.TransportConfig(self._transport, 'branch.conf')
1322
def _get_config_store(self):
1323
return config.BranchStore(self)
1325
1280
def set_parent(self, parent):
1326
1281
self._parent = parent
1328
def lock_read(self):
1329
return lock.LogicalLockResult(self.unlock)
1335
1284
class TestBzrDirSprout(TestCaseWithMemoryTransport):
1393
1341
self.assertEqual('fail', err._preformatted_string)
1395
1343
def test_post_repo_init(self):
1396
from ..controldir import RepoInitHookParams
1344
from bzrlib.bzrdir import RepoInitHookParams
1398
1346
bzrdir.BzrDir.hooks.install_named_hook('post_repo_init',
1400
1348
self.make_repository('foo')
1401
1349
self.assertLength(1, calls)
1402
1350
params = calls[0]
1403
1351
self.assertIsInstance(params, RepoInitHookParams)
1404
self.assertTrue(hasattr(params, 'controldir'))
1352
self.assertTrue(hasattr(params, 'bzrdir'))
1405
1353
self.assertTrue(hasattr(params, 'repository'))
1407
def test_post_repo_init_hook_repr(self):
1409
bzrdir.BzrDir.hooks.install_named_hook('post_repo_init',
1410
lambda params: param_reprs.append(repr(params)), None)
1411
self.make_repository('foo')
1412
self.assertLength(1, param_reprs)
1413
param_repr = param_reprs[0]
1414
self.assertStartsWith(param_repr, '<RepoInitHookParams for ')
1417
class TestGenerateBackupName(TestCaseWithMemoryTransport):
1418
# FIXME: This may need to be unified with test_osutils.TestBackupNames or
1419
# moved to per_bzrdir or per_transport for better coverage ?
1423
super(TestGenerateBackupName, self).setUp()
1424
self._transport = self.get_transport()
1425
bzrdir.BzrDir.create(self.get_url(),
1426
possible_transports=[self._transport])
1427
self._bzrdir = bzrdir.BzrDir.open_from_transport(self._transport)
1430
self.assertEqual("a.~1~", self._bzrdir._available_backup_name("a"))
1432
def test_exiting(self):
1433
self._transport.put_bytes("a.~1~", b"some content")
1434
self.assertEqual("a.~2~", self._bzrdir._available_backup_name("a"))
1437
class TestMeta1DirColoFormat(TestCaseWithTransport):
1438
"""Tests specific to the meta1 dir with colocated branches format."""
1440
def test_supports_colo(self):
1441
format = bzrdir.BzrDirMetaFormat1Colo()
1442
self.assertTrue(format.colocated_branches)
1444
def test_upgrade_from_2a(self):
1445
tree = self.make_branch_and_tree('.', format='2a')
1446
format = bzrdir.BzrDirMetaFormat1Colo()
1447
self.assertTrue(tree.controldir.needs_format_conversion(format))
1448
converter = tree.controldir._format.get_converter(format)
1449
result = converter.convert(tree.controldir, None)
1450
self.assertIsInstance(result._format, bzrdir.BzrDirMetaFormat1Colo)
1451
self.assertFalse(result.needs_format_conversion(format))
1453
def test_downgrade_to_2a(self):
1454
tree = self.make_branch_and_tree('.', format='development-colo')
1455
format = bzrdir.BzrDirMetaFormat1()
1456
self.assertTrue(tree.controldir.needs_format_conversion(format))
1457
converter = tree.controldir._format.get_converter(format)
1458
result = converter.convert(tree.controldir, None)
1459
self.assertIsInstance(result._format, bzrdir.BzrDirMetaFormat1)
1460
self.assertFalse(result.needs_format_conversion(format))
1462
def test_downgrade_to_2a_too_many_branches(self):
1463
tree = self.make_branch_and_tree('.', format='development-colo')
1464
tree.controldir.create_branch(name="another-colocated-branch")
1465
converter = tree.controldir._format.get_converter(
1466
bzrdir.BzrDirMetaFormat1())
1467
result = converter.convert(tree.controldir, bzrdir.BzrDirMetaFormat1())
1468
self.assertIsInstance(result._format, bzrdir.BzrDirMetaFormat1)
1470
def test_nested(self):
1471
tree = self.make_branch_and_tree('.', format='development-colo')
1472
tree.controldir.create_branch(name='foo')
1473
tree.controldir.create_branch(name='fool/bla')
1475
errors.ParentBranchExists, tree.controldir.create_branch,
1478
def test_parent(self):
1479
tree = self.make_branch_and_tree('.', format='development-colo')
1480
tree.controldir.create_branch(name='fool/bla')
1481
tree.controldir.create_branch(name='foo/bar')
1483
errors.AlreadyBranchError, tree.controldir.create_branch,
1486
def test_supports_relative_reference(self):
1487
tree = self.make_branch_and_tree('.', format='development-colo')
1488
target1 = tree.controldir.create_branch(name='target1')
1489
target2 = tree.controldir.create_branch(name='target2')
1490
source = tree.controldir.set_branch_reference(target1, name='source')
1492
target1.user_url, tree.controldir.open_branch('source').user_url)
1493
source.controldir.get_branch_transport(None, 'source').put_bytes(
1494
'location', b'file:,branch=target2')
1496
target2.user_url, tree.controldir.open_branch('source').user_url)
1499
class SampleBzrFormat(bzrdir.BzrFormat):
1502
def get_format_string(cls):
1503
return b"First line\n"
1506
class TestBzrFormat(TestCase):
1507
"""Tests for BzrFormat."""
1509
def test_as_string(self):
1510
format = SampleBzrFormat()
1511
format.features = {b"foo": b"required"}
1512
self.assertEqual(format.as_string(),
1515
format.features[b"another"] = b"optional"
1516
self.assertEqual(format.as_string(),
1518
b"optional another\n"
1521
def test_network_name(self):
1522
# The network string should include the feature info
1523
format = SampleBzrFormat()
1524
format.features = {b"foo": b"required"}
1526
b"First line\nrequired foo\n",
1527
format.network_name())
1529
def test_from_string_no_features(self):
1531
format = SampleBzrFormat.from_string(
1533
self.assertEqual({}, format.features)
1535
def test_from_string_with_feature(self):
1537
format = SampleBzrFormat.from_string(
1538
b"First line\nrequired foo\n")
1539
self.assertEqual(b"required", format.features.get(b"foo"))
1541
def test_from_string_format_string_mismatch(self):
1542
# The first line has to match the format string
1543
self.assertRaises(AssertionError, SampleBzrFormat.from_string,
1544
b"Second line\nrequired foo\n")
1546
def test_from_string_missing_space(self):
1547
# At least one space is required in the feature lines
1548
self.assertRaises(errors.ParseFormatError, SampleBzrFormat.from_string,
1549
b"First line\nfoo\n")
1551
def test_from_string_with_spaces(self):
1552
# Feature with spaces (in case we add stuff like this in the future)
1553
format = SampleBzrFormat.from_string(
1554
b"First line\nrequired foo with spaces\n")
1555
self.assertEqual(b"required", format.features.get(b"foo with spaces"))
1558
format1 = SampleBzrFormat()
1559
format1.features = {b"nested-trees": b"optional"}
1560
format2 = SampleBzrFormat()
1561
format2.features = {b"nested-trees": b"optional"}
1562
self.assertEqual(format1, format1)
1563
self.assertEqual(format1, format2)
1564
format3 = SampleBzrFormat()
1565
self.assertNotEqual(format1, format3)
1567
def test_check_support_status_optional(self):
1568
# Optional, so silently ignore
1569
format = SampleBzrFormat()
1570
format.features = {b"nested-trees": b"optional"}
1571
format.check_support_status(True)
1572
self.addCleanup(SampleBzrFormat.unregister_feature, b"nested-trees")
1573
SampleBzrFormat.register_feature(b"nested-trees")
1574
format.check_support_status(True)
1576
def test_check_support_status_required(self):
1577
# Optional, so trigger an exception
1578
format = SampleBzrFormat()
1579
format.features = {b"nested-trees": b"required"}
1580
self.assertRaises(bzrdir.MissingFeature, format.check_support_status,
1582
self.addCleanup(SampleBzrFormat.unregister_feature, b"nested-trees")
1583
SampleBzrFormat.register_feature(b"nested-trees")
1584
format.check_support_status(True)
1586
def test_check_support_status_unknown(self):
1587
# treat unknown necessity as required
1588
format = SampleBzrFormat()
1589
format.features = {b"nested-trees": b"unknown"}
1590
self.assertRaises(bzrdir.MissingFeature, format.check_support_status,
1592
self.addCleanup(SampleBzrFormat.unregister_feature, b"nested-trees")
1593
SampleBzrFormat.register_feature(b"nested-trees")
1594
format.check_support_status(True)
1596
def test_feature_already_registered(self):
1597
# a feature can only be registered once
1598
self.addCleanup(SampleBzrFormat.unregister_feature, b"nested-trees")
1599
SampleBzrFormat.register_feature(b"nested-trees")
1600
self.assertRaises(bzrdir.FeatureAlreadyRegistered,
1601
SampleBzrFormat.register_feature, b"nested-trees")
1603
def test_feature_with_space(self):
1604
# spaces are not allowed in feature names
1605
self.assertRaises(ValueError, SampleBzrFormat.register_feature,