35
revision as _mod_revision,
37
transport as _mod_transport,
38
from bzrlib.errors import (NotBranchError,
39
NoColocatedBranchSupport,
41
UnsupportedFormatError,
43
from bzrlib.tests import (
49
import breezy.bzr.branch
50
from ..bzr.fullhistory import BzrBranchFormat5
51
from ..errors import (
53
NoColocatedBranchSupport,
55
UnsupportedFormatError,
45
59
TestCaseWithMemoryTransport,
46
60
TestCaseWithTransport,
49
from bzrlib.tests import(
53
from bzrlib.tests.test_http import TestWithTransport_pycurl
54
from bzrlib.transport import (
67
from ..transport import (
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
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
64
77
class TestDefaultFormat(TestCase):
66
79
def test_get_set_default_format(self):
67
80
old_format = bzrdir.BzrDirFormat.get_default_format()
68
# default is BzrDirFormat6
69
self.failUnless(isinstance(old_format, bzrdir.BzrDirMetaFormat1))
70
bzrdir.BzrDirFormat._set_default_format(SampleBzrDirFormat())
81
# default is BzrDirMetaFormat1
82
self.assertIsInstance(old_format, bzrdir.BzrDirMetaFormat1)
83
controldir.ControlDirFormat._set_default_format(SampleBzrDirFormat())
71
84
# creating a bzr dir should now create an instrumented dir.
73
86
result = bzrdir.BzrDir.create('memory:///')
74
self.failUnless(isinstance(result, SampleBzrDir))
87
self.assertIsInstance(result, SampleBzrDir)
76
bzrdir.BzrDirFormat._set_default_format(old_format)
89
controldir.ControlDirFormat._set_default_format(old_format)
77
90
self.assertEqual(old_format, bzrdir.BzrDirFormat.get_default_format())
93
class DeprecatedBzrDirFormat(bzrdir.BzrDirFormat):
94
"""A deprecated bzr dir format."""
80
97
class TestFormatRegistry(TestCase):
82
99
def make_format_registry(self):
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',
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',
93
111
my_format_registry.set_default('knit')
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,
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)
111
128
return my_format_registry
113
130
def test_format_registry(self):
114
131
my_format_registry = self.make_format_registry()
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')
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')
126
143
self.assertIsInstance(my_bzrdir.get_branch_format(),
127
bzrlib.branch.BzrBranchFormat6)
144
breezy.bzr.branch.BzrBranchFormat6)
129
146
def test_get_help(self):
130
147
my_format_registry = self.make_format_registry()
150
166
experimental, deprecated = rest.split('Deprecated formats')
151
167
self.assertContainsRe(new, 'formats-help')
152
168
self.assertContainsRe(new,
153
':knit:\n \(native\) \(default\) Format using knits\n')
169
':knit:\n \\(native\\) \\(default\\) Format using knits\n')
154
170
self.assertContainsRe(experimental,
155
':branch6:\n \(native\) Experimental successor to knit')
171
':branch6:\n \\(native\\) Experimental successor to knit')
156
172
self.assertContainsRe(deprecated,
157
':lazy:\n \(native\) Format registered lazily\n')
173
':lazy:\n \\(native\\) Format registered lazily\n')
158
174
self.assertNotContainsRe(new, 'hidden')
160
176
def test_set_default_repository(self):
161
default_factory = bzrdir.format_registry.get('default')
162
old_default = [k for k, v in bzrdir.format_registry.iteritems()
177
default_factory = controldir.format_registry.get('default')
178
old_default = [k for k, v in controldir.format_registry.iteritems()
163
179
if v == default_factory and k != 'default'][0]
164
bzrdir.format_registry.set_default_repository('dirstate-with-subtree')
180
controldir.format_registry.set_default_repository(
181
'dirstate-with-subtree')
166
self.assertIs(bzrdir.format_registry.get('dirstate-with-subtree'),
167
bzrdir.format_registry.get('default'))
183
self.assertIs(controldir.format_registry.get('dirstate-with-subtree'),
184
controldir.format_registry.get('default'))
169
repository.RepositoryFormat.get_default_format().__class__,
186
repository.format_registry.get_default().__class__,
170
187
knitrepo.RepositoryFormatKnit3)
172
bzrdir.format_registry.set_default_repository(old_default)
189
controldir.format_registry.set_default_repository(old_default)
174
191
def test_aliases(self):
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):
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):
186
202
"""A dummy branch for guess what, dummy use."""
188
204
def __init__(self, dir):
192
class SampleRepository(bzrlib.repository.Repository):
205
self.controldir = dir
208
class SampleRepository(breezy.repository.Repository):
193
209
"""A dummy repo."""
195
211
def __init__(self, dir):
212
self.controldir = dir
199
215
class SampleBzrDir(bzrdir.BzrDir):
200
216
"""A sample BzrDir implementation to allow testing static methods."""
202
218
def create_repository(self, shared=False):
203
"""See BzrDir.create_repository."""
219
"""See ControlDir.create_repository."""
204
220
return "A repository"
206
222
def open_repository(self):
207
"""See BzrDir.open_repository."""
223
"""See ControlDir.open_repository."""
208
224
return SampleRepository(self)
210
226
def create_branch(self, name=None):
211
"""See BzrDir.create_branch."""
227
"""See ControlDir.create_branch."""
212
228
if name is not None:
213
229
raise NoColocatedBranchSupport(self)
214
230
return SampleBranch(self)
216
232
def create_workingtree(self):
217
"""See BzrDir.create_workingtree."""
233
"""See ControlDir.create_workingtree."""
248
282
def test_find_format(self):
249
283
# is the right format object found for a branch?
250
284
# create a branch with a few known format objects.
251
# this is not quite the same as
252
t = get_transport(self.get_url())
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()
253
294
self.build_tree(["foo/", "bar/"], transport=t)
254
296
def check_format(format, url):
255
297
format.initialize(url)
256
t = get_transport(url)
298
t = _mod_transport.get_transport_from_path(url)
257
299
found_format = bzrdir.BzrDirFormat.find_format(t)
258
self.failUnless(isinstance(found_format, format.__class__))
259
check_format(bzrdir.BzrDirFormat5(), "foo")
260
check_format(bzrdir.BzrDirFormat6(), "bar")
300
self.assertIsInstance(found_format, format.__class__)
301
check_format(BzrDirFormatTest1(), "foo")
302
check_format(BzrDirFormatTest2(), "bar")
262
304
def test_find_format_nothing_there(self):
263
305
self.assertRaises(NotBranchError,
264
306
bzrdir.BzrDirFormat.find_format,
307
_mod_transport.get_transport_from_path('.'))
267
309
def test_find_format_unknown_format(self):
268
t = get_transport(self.get_url())
310
t = self.get_transport()
270
t.put_bytes('.bzr/branch-format', '')
312
t.put_bytes('.bzr/branch-format', b'')
271
313
self.assertRaises(UnknownFormatError,
272
314
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('.'))
275
325
def test_register_unregister_format(self):
276
326
format = SampleBzrDirFormat()
338
390
bzrdir.BzrDir.create_standalone_workingtree,
339
391
self.get_readonly_url('child'), format=format)
340
392
tree = bzrdir.BzrDir.create_standalone_workingtree('child',
342
tree.bzrdir.open_repository()
394
tree.controldir.open_repository()
344
396
def test_create_branch_convenience(self):
345
397
# outside a repo the default convenience output is a repo+branch_tree
346
format = bzrdir.format_registry.make_bzrdir('knit')
398
format = controldir.format_registry.make_controldir('knit')
347
399
branch = bzrdir.BzrDir.create_branch_convenience('.', format=format)
348
branch.bzrdir.open_workingtree()
349
branch.bzrdir.open_repository()
400
branch.controldir.open_workingtree()
401
branch.controldir.open_repository()
351
403
def test_create_branch_convenience_possible_transports(self):
352
404
"""Check that the optional 'possible_transports' is recognized"""
353
format = bzrdir.format_registry.make_bzrdir('knit')
405
format = controldir.format_registry.make_controldir('knit')
354
406
t = self.get_transport()
355
407
branch = bzrdir.BzrDir.create_branch_convenience(
356
408
'.', format=format, possible_transports=[t])
357
branch.bzrdir.open_workingtree()
358
branch.bzrdir.open_repository()
409
branch.controldir.open_workingtree()
410
branch.controldir.open_repository()
360
412
def test_create_branch_convenience_root(self):
361
413
"""Creating a branch at the root of a fs should work."""
362
414
self.vfs_transport_factory = memory.MemoryServer
363
415
# outside a repo the default convenience output is a repo+branch_tree
364
format = bzrdir.format_registry.make_bzrdir('knit')
416
format = controldir.format_registry.make_controldir('knit')
365
417
branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(),
367
419
self.assertRaises(errors.NoWorkingTree,
368
branch.bzrdir.open_workingtree)
369
branch.bzrdir.open_repository()
420
branch.controldir.open_workingtree)
421
branch.controldir.open_repository()
371
423
def test_create_branch_convenience_under_shared_repo(self):
372
424
# inside a repo the default convenience output is a branch+ follow the
373
425
# repo tree policy
374
format = bzrdir.format_registry.make_bzrdir('knit')
426
format = controldir.format_registry.make_controldir('knit')
375
427
self.make_repository('.', shared=True, format=format)
376
428
branch = bzrdir.BzrDir.create_branch_convenience('child',
378
branch.bzrdir.open_workingtree()
430
branch.controldir.open_workingtree()
379
431
self.assertRaises(errors.NoRepositoryPresent,
380
branch.bzrdir.open_repository)
432
branch.controldir.open_repository)
382
434
def test_create_branch_convenience_under_shared_repo_force_no_tree(self):
383
435
# inside a repo the default convenience output is a branch+ follow the
384
436
# repo tree policy but we can override that
385
format = bzrdir.format_registry.make_bzrdir('knit')
437
format = controldir.format_registry.make_controldir('knit')
386
438
self.make_repository('.', shared=True, format=format)
387
439
branch = bzrdir.BzrDir.create_branch_convenience('child',
388
force_new_tree=False, format=format)
440
force_new_tree=False, format=format)
389
441
self.assertRaises(errors.NoWorkingTree,
390
branch.bzrdir.open_workingtree)
442
branch.controldir.open_workingtree)
391
443
self.assertRaises(errors.NoRepositoryPresent,
392
branch.bzrdir.open_repository)
444
branch.controldir.open_repository)
394
446
def test_create_branch_convenience_under_shared_repo_no_tree_policy(self):
395
447
# inside a repo the default convenience output is a branch+ follow the
396
448
# repo tree policy
397
format = bzrdir.format_registry.make_bzrdir('knit')
449
format = controldir.format_registry.make_controldir('knit')
398
450
repo = self.make_repository('.', shared=True, format=format)
399
451
repo.set_make_working_trees(False)
400
452
branch = bzrdir.BzrDir.create_branch_convenience('child',
402
454
self.assertRaises(errors.NoWorkingTree,
403
branch.bzrdir.open_workingtree)
455
branch.controldir.open_workingtree)
404
456
self.assertRaises(errors.NoRepositoryPresent,
405
branch.bzrdir.open_repository)
457
branch.controldir.open_repository)
407
459
def test_create_branch_convenience_under_shared_repo_no_tree_policy_force_tree(self):
408
460
# inside a repo the default convenience output is a branch+ follow the
409
461
# repo tree policy but we can override that
410
format = bzrdir.format_registry.make_bzrdir('knit')
462
format = controldir.format_registry.make_controldir('knit')
411
463
repo = self.make_repository('.', shared=True, format=format)
412
464
repo.set_make_working_trees(False)
413
465
branch = bzrdir.BzrDir.create_branch_convenience('child',
414
force_new_tree=True, format=format)
415
branch.bzrdir.open_workingtree()
466
force_new_tree=True, format=format)
467
branch.controldir.open_workingtree()
416
468
self.assertRaises(errors.NoRepositoryPresent,
417
branch.bzrdir.open_repository)
469
branch.controldir.open_repository)
419
471
def test_create_branch_convenience_under_shared_repo_force_new_repo(self):
420
472
# inside a repo the default convenience output is overridable to give
421
473
# repo+branch+tree
422
format = bzrdir.format_registry.make_bzrdir('knit')
474
format = controldir.format_registry.make_controldir('knit')
423
475
self.make_repository('.', shared=True, format=format)
424
476
branch = bzrdir.BzrDir.create_branch_convenience('child',
425
force_new_repo=True, format=format)
426
branch.bzrdir.open_repository()
427
branch.bzrdir.open_workingtree()
477
force_new_repo=True, format=format)
478
branch.controldir.open_repository()
479
branch.controldir.open_workingtree()
430
482
class TestRepositoryAcquisitionPolicy(TestCaseWithTransport):
432
484
def test_acquire_repository_standalone(self):
433
485
"""The default acquisition policy should create a standalone branch."""
434
my_bzrdir = self.make_bzrdir('.')
486
my_bzrdir = self.make_controldir('.')
435
487
repo_policy = my_bzrdir.determine_repository_policy()
436
488
repo, is_new = repo_policy.acquire_repository()
437
self.assertEqual(repo.bzrdir.root_transport.base,
489
self.assertEqual(repo.controldir.root_transport.base,
438
490
my_bzrdir.root_transport.base)
439
491
self.assertFalse(repo.is_shared())
441
493
def test_determine_stacking_policy(self):
442
parent_bzrdir = self.make_bzrdir('.')
443
child_bzrdir = self.make_bzrdir('child')
494
parent_bzrdir = self.make_controldir('.')
495
child_bzrdir = self.make_controldir('child')
444
496
parent_bzrdir.get_config().set_default_stack_on('http://example.org')
445
497
repo_policy = child_bzrdir.determine_repository_policy()
446
498
self.assertEqual('http://example.org', repo_policy._stack_on)
448
500
def test_determine_stacking_policy_relative(self):
449
parent_bzrdir = self.make_bzrdir('.')
450
child_bzrdir = self.make_bzrdir('child')
501
parent_bzrdir = self.make_controldir('.')
502
child_bzrdir = self.make_controldir('child')
451
503
parent_bzrdir.get_config().set_default_stack_on('child2')
452
504
repo_policy = child_bzrdir.determine_repository_policy()
453
505
self.assertEqual('child2', repo_policy._stack_on)
464
516
def test_clone_on_transport_obeys_stacking_policy(self):
465
517
child_branch, new_child_transport = self.prepare_default_stacking()
466
new_child = child_branch.bzrdir.clone_on_transport(new_child_transport)
518
new_child = child_branch.controldir.clone_on_transport(
467
520
self.assertEqual(child_branch.base,
468
521
new_child.open_branch().get_stacked_on_url())
470
523
def test_default_stacking_with_stackable_branch_unstackable_repo(self):
471
524
# Make stackable source branch with an unstackable repo format.
472
source_bzrdir = self.make_bzrdir('source')
473
pack_repo.RepositoryFormatKnitPack1().initialize(source_bzrdir)
474
source_branch = bzrlib.branch.BzrBranchFormat7().initialize(
525
source_bzrdir = self.make_controldir('source')
526
knitpack_repo.RepositoryFormatKnitPack1().initialize(source_bzrdir)
527
source_branch = breezy.bzr.branch.BzrBranchFormat7().initialize(
476
529
# Make a directory with a default stacking policy
477
parent_bzrdir = self.make_bzrdir('parent')
530
parent_bzrdir = self.make_controldir('parent')
478
531
stacked_on = self.make_branch('parent/stacked-on', format='pack-0.92')
479
532
parent_bzrdir.get_config().set_default_stack_on(stacked_on.base)
480
533
# Clone source into directory
481
534
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)
483
565
def test_sprout_obeys_stacking_policy(self):
484
566
child_branch, new_child_transport = self.prepare_default_stacking()
485
new_child = child_branch.bzrdir.sprout(new_child_transport.base)
567
new_child = child_branch.controldir.sprout(new_child_transport.base)
486
568
self.assertEqual(child_branch.base,
487
569
new_child.open_branch().get_stacked_on_url())
489
571
def test_clone_ignores_policy_for_unsupported_formats(self):
490
572
child_branch, new_child_transport = self.prepare_default_stacking(
491
573
child_format='pack-0.92')
492
new_child = child_branch.bzrdir.clone_on_transport(new_child_transport)
493
self.assertRaises(errors.UnstackableBranchFormat,
574
new_child = child_branch.controldir.clone_on_transport(
576
self.assertRaises(branch.UnstackableBranchFormat,
494
577
new_child.open_branch().get_stacked_on_url)
496
579
def test_sprout_ignores_policy_for_unsupported_formats(self):
497
580
child_branch, new_child_transport = self.prepare_default_stacking(
498
581
child_format='pack-0.92')
499
new_child = child_branch.bzrdir.sprout(new_child_transport.base)
500
self.assertRaises(errors.UnstackableBranchFormat,
582
new_child = child_branch.controldir.sprout(new_child_transport.base)
583
self.assertRaises(branch.UnstackableBranchFormat,
501
584
new_child.open_branch().get_stacked_on_url)
503
586
def test_sprout_upgrades_format_if_stacked_specified(self):
504
587
child_branch, new_child_transport = self.prepare_default_stacking(
505
588
child_format='pack-0.92')
506
new_child = child_branch.bzrdir.sprout(new_child_transport.base,
508
self.assertEqual(child_branch.bzrdir.root_transport.base,
589
new_child = child_branch.controldir.sprout(new_child_transport.base,
591
self.assertEqual(child_branch.controldir.root_transport.base,
509
592
new_child.open_branch().get_stacked_on_url())
510
593
repo = new_child.open_repository()
511
594
self.assertTrue(repo._format.supports_external_lookups)
672
757
self.assertEqual(branch, None)
673
758
self.assertEqual(
674
759
osutils.realpath(os.path.join('bar', '.bzr', 'repository')),
675
repo.bzrdir.transport.local_abspath('repository'))
760
repo.controldir.transport.local_abspath('repository'))
676
761
self.assertEqual(relpath, 'baz')
678
763
def test_open_containing_from_transport(self):
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')))
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')))
683
771
control = bzrdir.BzrDir.create(self.get_url())
684
772
branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
685
get_transport(self.get_readonly_url('')))
773
_mod_transport.get_transport_from_url(
774
self.get_readonly_url('')))
686
775
self.assertEqual('', relpath)
687
776
branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
688
get_transport(self.get_readonly_url('g/p/q')))
777
_mod_transport.get_transport_from_url(
778
self.get_readonly_url('g/p/q')))
689
779
self.assertEqual('g/p/q', relpath)
691
781
def test_open_containing_tree_or_branch(self):
735
825
# transport pointing at bzrdir should give a bzrdir with root transport
736
826
# set to the given transport
737
827
control = bzrdir.BzrDir.create(self.get_url())
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)
828
t = self.get_transport()
829
opened_bzrdir = bzrdir.BzrDir.open_from_transport(t)
830
self.assertEqual(t.base, opened_bzrdir.root_transport.base)
741
831
self.assertIsInstance(opened_bzrdir, bzrdir.BzrDir)
743
833
def test_open_from_transport_no_bzrdir(self):
744
transport = get_transport(self.get_url())
745
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
834
t = self.get_transport()
835
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport, t)
748
837
def test_open_from_transport_bzrdir_in_parent(self):
749
838
control = bzrdir.BzrDir.create(self.get_url())
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,
839
t = self.get_transport()
841
t = t.clone('subdir')
842
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport, t)
756
844
def test_sprout_recursive(self):
757
845
tree = self.make_branch_and_tree('tree1',
758
format='dirstate-with-subtree')
846
format='development-subtree')
759
847
sub_tree = self.make_branch_and_tree('tree1/subtree',
760
format='dirstate-with-subtree')
761
sub_tree.set_root_id('subtree-root')
848
format='development-subtree')
849
sub_tree.set_root_id(b'subtree-root')
762
850
tree.add_reference(sub_tree)
763
851
self.build_tree(['tree1/subtree/file'])
764
852
sub_tree.add('file')
765
853
tree.commit('Initial commit')
766
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
854
tree2 = tree.controldir.sprout('tree2').open_workingtree()
767
855
tree2.lock_read()
768
856
self.addCleanup(tree2.unlock)
769
self.failUnlessExists('tree2/subtree/file')
770
self.assertEqual('tree-reference', tree2.kind('subtree-root'))
857
self.assertPathExists('tree2/subtree/file')
858
self.assertEqual('tree-reference', tree2.kind('subtree'))
772
860
def test_cloning_metadir(self):
773
861
"""Ensure that cloning metadir is suitable"""
774
bzrdir = self.make_bzrdir('bzrdir')
862
bzrdir = self.make_controldir('bzrdir')
775
863
bzrdir.cloning_metadir()
776
864
branch = self.make_branch('branch', format='knit')
777
format = branch.bzrdir.cloning_metadir()
865
format = branch.controldir.cloning_metadir()
778
866
self.assertIsInstance(format.workingtree_format,
779
workingtree.WorkingTreeFormat3)
867
workingtree_4.WorkingTreeFormat6)
781
869
def test_sprout_recursive_treeless(self):
782
870
tree = self.make_branch_and_tree('tree1',
783
format='dirstate-with-subtree')
871
format='development-subtree')
784
872
sub_tree = self.make_branch_and_tree('tree1/subtree',
785
format='dirstate-with-subtree')
873
format='development-subtree')
786
874
tree.add_reference(sub_tree)
787
875
self.build_tree(['tree1/subtree/file'])
788
876
sub_tree.add('file')
789
877
tree.commit('Initial commit')
790
tree.bzrdir.destroy_workingtree()
878
# The following line force the orhaning to reveal bug #634470
879
tree.branch.get_config_stack().set(
880
'transform.orphan_policy', 'move')
881
tree.controldir.destroy_workingtree()
882
# FIXME: subtree/.bzr is left here which allows the test to pass (or
883
# fail :-( ) -- vila 20100909
791
884
repo = self.make_repository('repo', shared=True,
792
format='dirstate-with-subtree')
885
format='development-subtree')
793
886
repo.set_make_working_trees(False)
794
tree.bzrdir.sprout('repo/tree2')
795
self.failUnlessExists('repo/tree2/subtree')
796
self.failIfExists('repo/tree2/subtree/file')
887
# FIXME: we just deleted the workingtree and now we want to use it ????
888
# At a minimum, we should use tree.branch below (but this fails too
889
# currently) or stop calling this test 'treeless'. Specifically, I've
890
# turn the line below into an assertRaises when 'subtree/.bzr' is
891
# orphaned and sprout tries to access the branch there (which is left
892
# by bzrdir.BzrDirMeta1.destroy_workingtree when it ignores the
893
# [DeletingParent('Not deleting', u'subtree', None)] conflict). See bug
894
# #634470. -- vila 20100909
895
self.assertRaises(errors.NotBranchError,
896
tree.controldir.sprout, 'repo/tree2')
897
# self.assertPathExists('repo/tree2/subtree')
898
# self.assertPathDoesNotExist('repo/tree2/subtree/file')
798
900
def make_foo_bar_baz(self):
799
foo = bzrdir.BzrDir.create_branch_convenience('foo').bzrdir
800
bar = self.make_branch('foo/bar').bzrdir
801
baz = self.make_branch('baz').bzrdir
901
foo = bzrdir.BzrDir.create_branch_convenience('foo').controldir
902
bar = self.make_branch('foo/bar').controldir
903
baz = self.make_branch('baz').controldir
802
904
return foo, bar, baz
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):
906
def test_find_controldirs(self):
907
foo, bar, baz = self.make_foo_bar_baz()
908
t = self.get_transport()
909
self.assertEqualBzrdirs(
910
[baz, foo, bar], bzrdir.BzrDir.find_controldirs(t))
912
def make_fake_permission_denied_transport(self, transport, paths):
913
"""Create a transport that raises PermissionDenied for some paths."""
916
raise errors.PermissionDenied(path)
918
path_filter_server = pathfilter.PathFilteringServer(transport, filter)
919
path_filter_server.start_server()
920
self.addCleanup(path_filter_server.stop_server)
921
path_filter_transport = pathfilter.PathFilteringTransport(
922
path_filter_server, '.')
923
return (path_filter_server, path_filter_transport)
925
def assertBranchUrlsEndWith(self, expect_url_suffix, actual_bzrdirs):
926
"""Check that each branch url ends with the given suffix."""
927
for actual_bzrdir in actual_bzrdirs:
928
self.assertEndsWith(actual_bzrdir.user_url, expect_url_suffix)
930
def test_find_controldirs_permission_denied(self):
931
foo, bar, baz = self.make_foo_bar_baz()
932
t = self.get_transport()
933
path_filter_server, path_filter_transport = \
934
self.make_fake_permission_denied_transport(t, ['foo'])
936
self.assertBranchUrlsEndWith('/baz/',
937
bzrdir.BzrDir.find_controldirs(path_filter_transport))
939
smart_transport = self.make_smart_server('.',
940
backing_server=path_filter_server)
941
self.assertBranchUrlsEndWith('/baz/',
942
bzrdir.BzrDir.find_controldirs(smart_transport))
944
def test_find_controldirs_list_current(self):
811
945
def list_current(transport):
812
946
return [s for s in transport.list_dir('') if s != 'baz']
814
948
foo, bar, baz = self.make_foo_bar_baz()
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):
949
t = self.get_transport()
950
self.assertEqualBzrdirs(
952
bzrdir.BzrDir.find_controldirs(t, list_current=list_current))
954
def test_find_controldirs_evaluate(self):
822
955
def evaluate(bzrdir):
824
957
repo = bzrdir.open_repository()
825
except NoRepositoryPresent:
958
except errors.NoRepositoryPresent:
826
959
return True, bzrdir.root_transport.base
828
961
return False, bzrdir.root_transport.base
830
963
foo, bar, baz = self.make_foo_bar_baz()
831
transport = get_transport(self.get_url())
964
t = self.get_transport()
832
965
self.assertEqual([baz.root_transport.base, foo.root_transport.base],
833
list(bzrdir.BzrDir.find_bzrdirs(transport,
966
list(bzrdir.BzrDir.find_controldirs(t, evaluate=evaluate)))
836
968
def assertEqualBzrdirs(self, first, second):
837
969
first = list(first)
843
975
def test_find_branches(self):
844
976
root = self.make_repository('', shared=True)
845
977
foo, bar, baz = self.make_foo_bar_baz()
846
qux = self.make_bzrdir('foo/qux')
847
transport = get_transport(self.get_url())
848
branches = bzrdir.BzrDir.find_branches(transport)
978
qux = self.make_controldir('foo/qux')
979
t = self.get_transport()
980
branches = bzrdir.BzrDir.find_branches(t)
849
981
self.assertEqual(baz.root_transport.base, branches[0].base)
850
982
self.assertEqual(foo.root_transport.base, branches[1].base)
851
983
self.assertEqual(bar.root_transport.base, branches[2].base)
853
985
# ensure this works without a top-level repo
854
branches = bzrdir.BzrDir.find_branches(transport.clone('foo'))
986
branches = bzrdir.BzrDir.find_branches(t.clone('foo'))
855
987
self.assertEqual(foo.root_transport.base, branches[0].base)
856
988
self.assertEqual(bar.root_transport.base, branches[1].base)
991
class TestMissingRepoBranchesSkipped(TestCaseWithMemoryTransport):
993
def test_find_controldirs_missing_repo(self):
994
t = self.get_transport()
995
arepo = self.make_repository('arepo', shared=True)
996
abranch_url = arepo.user_url + '/abranch'
997
abranch = bzrdir.BzrDir.create(abranch_url).create_branch()
998
t.delete_tree('arepo/.bzr')
999
self.assertRaises(errors.NoRepositoryPresent,
1000
branch.Branch.open, abranch_url)
1001
self.make_branch('baz')
1002
for actual_bzrdir in bzrdir.BzrDir.find_branches(t):
1003
self.assertEndsWith(actual_bzrdir.user_url, '/baz/')
859
1006
class TestMeta1DirFormat(TestCaseWithTransport):
860
1007
"""Tests specific to the meta1 dir format."""
887
1037
Metadirs should compare equal iff they have the same repo, branch and
890
mydir = bzrdir.format_registry.make_bzrdir('knit')
1040
mydir = controldir.format_registry.make_controldir('knit')
891
1041
self.assertEqual(mydir, mydir)
892
1042
self.assertFalse(mydir != mydir)
893
otherdir = bzrdir.format_registry.make_bzrdir('knit')
1043
otherdir = controldir.format_registry.make_controldir('knit')
894
1044
self.assertEqual(otherdir, mydir)
895
1045
self.assertFalse(otherdir != mydir)
896
otherdir2 = bzrdir.format_registry.make_bzrdir('dirstate-with-subtree')
1046
otherdir2 = controldir.format_registry.make_controldir(
1047
'development-subtree')
897
1048
self.assertNotEqual(otherdir2, mydir)
898
1049
self.assertFalse(otherdir2 == mydir)
1051
def test_with_features(self):
1052
tree = self.make_branch_and_tree('tree', format='2a')
1053
tree.controldir.update_feature_flags({b"bar": b"required"})
1054
self.assertRaises(bzrdir.MissingFeature, bzrdir.BzrDir.open, 'tree')
1055
bzrdir.BzrDirMetaFormat1.register_feature(b'bar')
1056
self.addCleanup(bzrdir.BzrDirMetaFormat1.unregister_feature, b'bar')
1057
dir = bzrdir.BzrDir.open('tree')
1058
self.assertEqual(b"required", dir._format.features.get(b"bar"))
1059
tree.controldir.update_feature_flags({
1061
b"nonexistant": None})
1062
dir = bzrdir.BzrDir.open('tree')
1063
self.assertEqual({}, dir._format.features)
900
1065
def test_needs_conversion_different_working_tree(self):
901
1066
# meta1dirs need an conversion if any element is not the default.
902
new_format = bzrdir.format_registry.make_bzrdir('dirstate')
1067
new_format = controldir.format_registry.make_controldir('dirstate')
903
1068
tree = self.make_branch_and_tree('tree', format='knit')
904
self.assertTrue(tree.bzrdir.needs_format_conversion(
1069
self.assertTrue(tree.controldir.needs_format_conversion(
907
1072
def test_initialize_on_format_uses_smart_transport(self):
908
1073
self.setup_smart_server_with_call_log()
909
new_format = bzrdir.format_registry.make_bzrdir('dirstate')
1074
new_format = controldir.format_registry.make_controldir('dirstate')
910
1075
transport = self.get_transport('target')
911
1076
transport.ensure_base()
912
1077
self.reset_smart_call_log()
921
1086
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)
1053
1089
class NonLocalTests(TestCaseWithTransport):
1054
1090
"""Tests for bzrdir static behaviour on non local paths."""
1245
1273
def __init__(self, *args, **kwargs):
1246
1274
super(_TestBzrDir, self).__init__(*args, **kwargs)
1247
self.test_branch = _TestBranch()
1275
self.test_branch = _TestBranch(self.transport)
1248
1276
self.test_branch.repository = self.create_repository()
1250
def open_branch(self, unsupported=False):
1278
def open_branch(self, unsupported=False, possible_transports=None):
1251
1279
return self.test_branch
1253
1281
def cloning_metadir(self, require_stacking=False):
1254
1282
return _TestBzrDirFormat()
1257
class _TestBranchFormat(bzrlib.branch.BranchFormat):
1285
class _TestBranchFormat(breezy.branch.BranchFormat):
1258
1286
"""Test Branch format for TestBzrDirSprout."""
1261
class _TestBranch(bzrlib.branch.Branch):
1289
class _TestBranch(breezy.branch.Branch):
1262
1290
"""Test Branch implementation for TestBzrDirSprout."""
1264
def __init__(self, *args, **kwargs):
1292
def __init__(self, transport, *args, **kwargs):
1265
1293
self._format = _TestBranchFormat()
1294
self._transport = transport
1295
self.base = transport.base
1266
1296
super(_TestBranch, self).__init__(*args, **kwargs)
1267
1297
self.calls = []
1268
1298
self._parent = None
1270
1300
def sprout(self, *args, **kwargs):
1271
1301
self.calls.append('sprout')
1272
return _TestBranch()
1302
return _TestBranch(self._transport)
1274
1304
def copy_content_into(self, destination, revision_id=None):
1275
1305
self.calls.append('copy_content_into')
1307
def last_revision(self):
1308
return _mod_revision.NULL_REVISION
1277
1310
def get_parent(self):
1278
1311
return self._parent
1313
def _get_config(self):
1314
return config.TransportConfig(self._transport, 'branch.conf')
1316
def _get_config_store(self):
1317
return config.BranchStore(self)
1280
1319
def set_parent(self, parent):
1281
1320
self._parent = parent
1322
def lock_read(self):
1323
return lock.LogicalLockResult(self.unlock)
1284
1329
class TestBzrDirSprout(TestCaseWithMemoryTransport):
1341
1387
self.assertEqual('fail', err._preformatted_string)
1343
1389
def test_post_repo_init(self):
1344
from bzrlib.bzrdir import RepoInitHookParams
1390
from ..controldir import RepoInitHookParams
1346
1392
bzrdir.BzrDir.hooks.install_named_hook('post_repo_init',
1348
1394
self.make_repository('foo')
1349
1395
self.assertLength(1, calls)
1350
1396
params = calls[0]
1351
1397
self.assertIsInstance(params, RepoInitHookParams)
1352
self.assertTrue(hasattr(params, 'bzrdir'))
1398
self.assertTrue(hasattr(params, 'controldir'))
1353
1399
self.assertTrue(hasattr(params, 'repository'))
1401
def test_post_repo_init_hook_repr(self):
1403
bzrdir.BzrDir.hooks.install_named_hook('post_repo_init',
1404
lambda params: param_reprs.append(repr(params)), None)
1405
self.make_repository('foo')
1406
self.assertLength(1, param_reprs)
1407
param_repr = param_reprs[0]
1408
self.assertStartsWith(param_repr, '<RepoInitHookParams for ')
1411
class TestGenerateBackupName(TestCaseWithMemoryTransport):
1412
# FIXME: This may need to be unified with test_osutils.TestBackupNames or
1413
# moved to per_bzrdir or per_transport for better coverage ?
1417
super(TestGenerateBackupName, self).setUp()
1418
self._transport = self.get_transport()
1419
bzrdir.BzrDir.create(self.get_url(),
1420
possible_transports=[self._transport])
1421
self._bzrdir = bzrdir.BzrDir.open_from_transport(self._transport)
1424
self.assertEqual("a.~1~", self._bzrdir._available_backup_name("a"))
1426
def test_exiting(self):
1427
self._transport.put_bytes("a.~1~", b"some content")
1428
self.assertEqual("a.~2~", self._bzrdir._available_backup_name("a"))
1431
class TestMeta1DirColoFormat(TestCaseWithTransport):
1432
"""Tests specific to the meta1 dir with colocated branches format."""
1434
def test_supports_colo(self):
1435
format = bzrdir.BzrDirMetaFormat1Colo()
1436
self.assertTrue(format.colocated_branches)
1438
def test_upgrade_from_2a(self):
1439
tree = self.make_branch_and_tree('.', format='2a')
1440
format = bzrdir.BzrDirMetaFormat1Colo()
1441
self.assertTrue(tree.controldir.needs_format_conversion(format))
1442
converter = tree.controldir._format.get_converter(format)
1443
result = converter.convert(tree.controldir, None)
1444
self.assertIsInstance(result._format, bzrdir.BzrDirMetaFormat1Colo)
1445
self.assertFalse(result.needs_format_conversion(format))
1447
def test_downgrade_to_2a(self):
1448
tree = self.make_branch_and_tree('.', format='development-colo')
1449
format = bzrdir.BzrDirMetaFormat1()
1450
self.assertTrue(tree.controldir.needs_format_conversion(format))
1451
converter = tree.controldir._format.get_converter(format)
1452
result = converter.convert(tree.controldir, None)
1453
self.assertIsInstance(result._format, bzrdir.BzrDirMetaFormat1)
1454
self.assertFalse(result.needs_format_conversion(format))
1456
def test_downgrade_to_2a_too_many_branches(self):
1457
tree = self.make_branch_and_tree('.', format='development-colo')
1458
tree.controldir.create_branch(name="another-colocated-branch")
1459
converter = tree.controldir._format.get_converter(
1460
bzrdir.BzrDirMetaFormat1())
1461
result = converter.convert(tree.controldir, bzrdir.BzrDirMetaFormat1())
1462
self.assertIsInstance(result._format, bzrdir.BzrDirMetaFormat1)
1464
def test_nested(self):
1465
tree = self.make_branch_and_tree('.', format='development-colo')
1466
tree.controldir.create_branch(name='foo')
1467
tree.controldir.create_branch(name='fool/bla')
1469
errors.ParentBranchExists, tree.controldir.create_branch,
1472
def test_parent(self):
1473
tree = self.make_branch_and_tree('.', format='development-colo')
1474
tree.controldir.create_branch(name='fool/bla')
1475
tree.controldir.create_branch(name='foo/bar')
1477
errors.AlreadyBranchError, tree.controldir.create_branch,
1480
def test_supports_relative_reference(self):
1481
tree = self.make_branch_and_tree('.', format='development-colo')
1482
target1 = tree.controldir.create_branch(name='target1')
1483
target2 = tree.controldir.create_branch(name='target2')
1484
source = tree.controldir.set_branch_reference(target1, name='source')
1486
target1.user_url, tree.controldir.open_branch('source').user_url)
1487
source.controldir.get_branch_transport(None, 'source').put_bytes(
1488
'location', b'file:,branch=target2')
1490
target2.user_url, tree.controldir.open_branch('source').user_url)
1493
class SampleBzrFormat(bzrdir.BzrFormat):
1496
def get_format_string(cls):
1497
return b"First line\n"
1500
class TestBzrFormat(TestCase):
1501
"""Tests for BzrFormat."""
1503
def test_as_string(self):
1504
format = SampleBzrFormat()
1505
format.features = {b"foo": b"required"}
1506
self.assertEqual(format.as_string(),
1509
format.features[b"another"] = b"optional"
1510
self.assertEqual(format.as_string(),
1512
b"optional another\n"
1515
def test_network_name(self):
1516
# The network string should include the feature info
1517
format = SampleBzrFormat()
1518
format.features = {b"foo": b"required"}
1520
b"First line\nrequired foo\n",
1521
format.network_name())
1523
def test_from_string_no_features(self):
1525
format = SampleBzrFormat.from_string(
1527
self.assertEqual({}, format.features)
1529
def test_from_string_with_feature(self):
1531
format = SampleBzrFormat.from_string(
1532
b"First line\nrequired foo\n")
1533
self.assertEqual(b"required", format.features.get(b"foo"))
1535
def test_from_string_format_string_mismatch(self):
1536
# The first line has to match the format string
1537
self.assertRaises(AssertionError, SampleBzrFormat.from_string,
1538
b"Second line\nrequired foo\n")
1540
def test_from_string_missing_space(self):
1541
# At least one space is required in the feature lines
1542
self.assertRaises(errors.ParseFormatError, SampleBzrFormat.from_string,
1543
b"First line\nfoo\n")
1545
def test_from_string_with_spaces(self):
1546
# Feature with spaces (in case we add stuff like this in the future)
1547
format = SampleBzrFormat.from_string(
1548
b"First line\nrequired foo with spaces\n")
1549
self.assertEqual(b"required", format.features.get(b"foo with spaces"))
1552
format1 = SampleBzrFormat()
1553
format1.features = {b"nested-trees": b"optional"}
1554
format2 = SampleBzrFormat()
1555
format2.features = {b"nested-trees": b"optional"}
1556
self.assertEqual(format1, format1)
1557
self.assertEqual(format1, format2)
1558
format3 = SampleBzrFormat()
1559
self.assertNotEqual(format1, format3)
1561
def test_check_support_status_optional(self):
1562
# Optional, so silently ignore
1563
format = SampleBzrFormat()
1564
format.features = {b"nested-trees": b"optional"}
1565
format.check_support_status(True)
1566
self.addCleanup(SampleBzrFormat.unregister_feature, b"nested-trees")
1567
SampleBzrFormat.register_feature(b"nested-trees")
1568
format.check_support_status(True)
1570
def test_check_support_status_required(self):
1571
# Optional, so trigger an exception
1572
format = SampleBzrFormat()
1573
format.features = {b"nested-trees": b"required"}
1574
self.assertRaises(bzrdir.MissingFeature, format.check_support_status,
1576
self.addCleanup(SampleBzrFormat.unregister_feature, b"nested-trees")
1577
SampleBzrFormat.register_feature(b"nested-trees")
1578
format.check_support_status(True)
1580
def test_check_support_status_unknown(self):
1581
# treat unknown necessity as required
1582
format = SampleBzrFormat()
1583
format.features = {b"nested-trees": b"unknown"}
1584
self.assertRaises(bzrdir.MissingFeature, format.check_support_status,
1586
self.addCleanup(SampleBzrFormat.unregister_feature, b"nested-trees")
1587
SampleBzrFormat.register_feature(b"nested-trees")
1588
format.check_support_status(True)
1590
def test_feature_already_registered(self):
1591
# a feature can only be registered once
1592
self.addCleanup(SampleBzrFormat.unregister_feature, b"nested-trees")
1593
SampleBzrFormat.register_feature(b"nested-trees")
1594
self.assertRaises(bzrdir.FeatureAlreadyRegistered,
1595
SampleBzrFormat.register_feature, b"nested-trees")
1597
def test_feature_with_space(self):
1598
# spaces are not allowed in feature names
1599
self.assertRaises(ValueError, SampleBzrFormat.register_feature,