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,
39
from bzrlib.errors import (NotBranchError,
40
NoColocatedBranchSupport,
42
UnsupportedFormatError,
44
from bzrlib.tests import (
59
46
TestCaseWithMemoryTransport,
60
47
TestCaseWithTransport,
50
from bzrlib.tests import(
67
from ..transport import (
54
from bzrlib.tests.test_http import TestWithTransport_pycurl
55
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
60
from bzrlib.transport.http._urllib import HttpTransport_urllib
61
from bzrlib.transport.nosmart import NoSmartTransportDecorator
62
from bzrlib.transport.readonly import ReadonlyTransportDecorator
63
from bzrlib.repofmt import knitrepo, weaverepo, pack_repo
77
66
class TestDefaultFormat(TestCase):
79
68
def test_get_set_default_format(self):
80
69
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())
70
# default is BzrDirFormat6
71
self.failUnless(isinstance(old_format, bzrdir.BzrDirMetaFormat1))
72
bzrdir.BzrDirFormat._set_default_format(SampleBzrDirFormat())
84
73
# creating a bzr dir should now create an instrumented dir.
86
75
result = bzrdir.BzrDir.create('memory:///')
87
self.assertIsInstance(result, SampleBzrDir)
76
self.failUnless(isinstance(result, SampleBzrDir))
89
controldir.ControlDirFormat._set_default_format(old_format)
78
bzrdir.BzrDirFormat._set_default_format(old_format)
90
79
self.assertEqual(old_format, bzrdir.BzrDirFormat.get_default_format())
93
class DeprecatedBzrDirFormat(bzrdir.BzrDirFormat):
94
"""A deprecated bzr dir format."""
97
82
class TestFormatRegistry(TestCase):
99
84
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',
85
my_format_registry = bzrdir.BzrDirFormatRegistry()
86
my_format_registry.register('weave', bzrdir.BzrDirFormat6,
87
'Pre-0.8 format. Slower and does not support checkouts or shared'
88
' repositories', deprecated=True)
89
my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir',
90
'BzrDirFormat6', 'Format registered lazily', deprecated=True)
91
my_format_registry.register_metadir('knit',
92
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
111
95
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)
96
my_format_registry.register_metadir(
98
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
99
'Experimental successor to knit. Use at your own risk.',
100
branch_format='bzrlib.branch.BzrBranchFormat6',
102
my_format_registry.register_metadir(
104
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
105
'Experimental successor to knit. Use at your own risk.',
106
branch_format='bzrlib.branch.BzrBranchFormat6', hidden=True)
107
my_format_registry.register('hiddenweave', bzrdir.BzrDirFormat6,
108
'Pre-0.8 format. Slower and does not support checkouts or shared'
109
' repositories', hidden=True)
110
my_format_registry.register_lazy('hiddenlazy', 'bzrlib.bzrdir',
111
'BzrDirFormat6', 'Format registered lazily', deprecated=True,
128
113
return my_format_registry
130
115
def test_format_registry(self):
131
116
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')
117
my_bzrdir = my_format_registry.make_bzrdir('lazy')
118
self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
119
my_bzrdir = my_format_registry.make_bzrdir('weave')
120
self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
121
my_bzrdir = my_format_registry.make_bzrdir('default')
122
self.assertIsInstance(my_bzrdir.repository_format,
123
knitrepo.RepositoryFormatKnit1)
124
my_bzrdir = my_format_registry.make_bzrdir('knit')
125
self.assertIsInstance(my_bzrdir.repository_format,
126
knitrepo.RepositoryFormatKnit1)
127
my_bzrdir = my_format_registry.make_bzrdir('branch6')
143
128
self.assertIsInstance(my_bzrdir.get_branch_format(),
144
breezy.bzr.branch.BzrBranchFormat6)
129
bzrlib.branch.BzrBranchFormat6)
146
131
def test_get_help(self):
147
132
my_format_registry = self.make_format_registry()
166
152
experimental, deprecated = rest.split('Deprecated formats')
167
153
self.assertContainsRe(new, 'formats-help')
168
154
self.assertContainsRe(new,
169
':knit:\n \\(native\\) \\(default\\) Format using knits\n')
155
':knit:\n \(native\) \(default\) Format using knits\n')
170
156
self.assertContainsRe(experimental,
171
':branch6:\n \\(native\\) Experimental successor to knit')
157
':branch6:\n \(native\) Experimental successor to knit')
172
158
self.assertContainsRe(deprecated,
173
':lazy:\n \\(native\\) Format registered lazily\n')
159
':lazy:\n \(native\) Format registered lazily\n')
174
160
self.assertNotContainsRe(new, 'hidden')
176
162
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()
163
default_factory = bzrdir.format_registry.get('default')
164
old_default = [k for k, v in bzrdir.format_registry.iteritems()
179
165
if v == default_factory and k != 'default'][0]
180
controldir.format_registry.set_default_repository(
181
'dirstate-with-subtree')
166
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'))
168
self.assertIs(bzrdir.format_registry.get('dirstate-with-subtree'),
169
bzrdir.format_registry.get('default'))
186
repository.format_registry.get_default().__class__,
171
repository.RepositoryFormat.get_default_format().__class__,
187
172
knitrepo.RepositoryFormatKnit3)
189
controldir.format_registry.set_default_repository(old_default)
174
bzrdir.format_registry.set_default_repository(old_default)
191
176
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):
177
a_registry = bzrdir.BzrDirFormatRegistry()
178
a_registry.register('weave', bzrdir.BzrDirFormat6,
179
'Pre-0.8 format. Slower and does not support checkouts or shared'
180
' repositories', deprecated=True)
181
a_registry.register('weavealias', bzrdir.BzrDirFormat6,
182
'Pre-0.8 format. Slower and does not support checkouts or shared'
183
' repositories', deprecated=True, alias=True)
184
self.assertEqual(frozenset(['weavealias']), a_registry.aliases())
187
class SampleBranch(bzrlib.branch.Branch):
202
188
"""A dummy branch for guess what, dummy use."""
204
190
def __init__(self, dir):
205
self.controldir = dir
208
class SampleRepository(breezy.repository.Repository):
194
class SampleRepository(bzrlib.repository.Repository):
209
195
"""A dummy repo."""
211
197
def __init__(self, dir):
212
self.controldir = dir
215
201
class SampleBzrDir(bzrdir.BzrDir):
216
202
"""A sample BzrDir implementation to allow testing static methods."""
218
204
def create_repository(self, shared=False):
219
"""See ControlDir.create_repository."""
205
"""See BzrDir.create_repository."""
220
206
return "A repository"
222
208
def open_repository(self):
223
"""See ControlDir.open_repository."""
209
"""See BzrDir.open_repository."""
224
210
return SampleRepository(self)
226
212
def create_branch(self, name=None):
227
"""See ControlDir.create_branch."""
213
"""See BzrDir.create_branch."""
228
214
if name is not None:
229
215
raise NoColocatedBranchSupport(self)
230
216
return SampleBranch(self)
232
218
def create_workingtree(self):
233
"""See ControlDir.create_workingtree."""
219
"""See BzrDir.create_workingtree."""
282
250
def test_find_format(self):
283
251
# is the right format object found for a branch?
284
252
# 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()
253
# this is not quite the same as
254
t = get_transport(self.get_url())
294
255
self.build_tree(["foo/", "bar/"], transport=t)
296
256
def check_format(format, url):
297
257
format.initialize(url)
298
t = _mod_transport.get_transport_from_path(url)
258
t = get_transport(url)
299
259
found_format = bzrdir.BzrDirFormat.find_format(t)
300
self.assertIsInstance(found_format, format.__class__)
301
check_format(BzrDirFormatTest1(), "foo")
302
check_format(BzrDirFormatTest2(), "bar")
260
self.failUnless(isinstance(found_format, format.__class__))
261
check_format(bzrdir.BzrDirFormat5(), "foo")
262
check_format(bzrdir.BzrDirFormat6(), "bar")
304
264
def test_find_format_nothing_there(self):
305
265
self.assertRaises(NotBranchError,
306
266
bzrdir.BzrDirFormat.find_format,
307
_mod_transport.get_transport_from_path('.'))
309
269
def test_find_format_unknown_format(self):
310
t = self.get_transport()
270
t = get_transport(self.get_url())
312
t.put_bytes('.bzr/branch-format', b'')
272
t.put_bytes('.bzr/branch-format', '')
313
273
self.assertRaises(UnknownFormatError,
314
274
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
277
def test_register_unregister_format(self):
326
278
format = SampleBzrDirFormat()
390
340
bzrdir.BzrDir.create_standalone_workingtree,
391
341
self.get_readonly_url('child'), format=format)
392
342
tree = bzrdir.BzrDir.create_standalone_workingtree('child',
394
tree.controldir.open_repository()
344
tree.bzrdir.open_repository()
396
346
def test_create_branch_convenience(self):
397
347
# outside a repo the default convenience output is a repo+branch_tree
398
format = controldir.format_registry.make_controldir('knit')
348
format = bzrdir.format_registry.make_bzrdir('knit')
399
349
branch = bzrdir.BzrDir.create_branch_convenience('.', format=format)
400
branch.controldir.open_workingtree()
401
branch.controldir.open_repository()
350
branch.bzrdir.open_workingtree()
351
branch.bzrdir.open_repository()
403
353
def test_create_branch_convenience_possible_transports(self):
404
354
"""Check that the optional 'possible_transports' is recognized"""
405
format = controldir.format_registry.make_controldir('knit')
355
format = bzrdir.format_registry.make_bzrdir('knit')
406
356
t = self.get_transport()
407
357
branch = bzrdir.BzrDir.create_branch_convenience(
408
358
'.', format=format, possible_transports=[t])
409
branch.controldir.open_workingtree()
410
branch.controldir.open_repository()
359
branch.bzrdir.open_workingtree()
360
branch.bzrdir.open_repository()
412
362
def test_create_branch_convenience_root(self):
413
363
"""Creating a branch at the root of a fs should work."""
414
364
self.vfs_transport_factory = memory.MemoryServer
415
365
# outside a repo the default convenience output is a repo+branch_tree
416
format = controldir.format_registry.make_controldir('knit')
366
format = bzrdir.format_registry.make_bzrdir('knit')
417
367
branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(),
419
369
self.assertRaises(errors.NoWorkingTree,
420
branch.controldir.open_workingtree)
421
branch.controldir.open_repository()
370
branch.bzrdir.open_workingtree)
371
branch.bzrdir.open_repository()
423
373
def test_create_branch_convenience_under_shared_repo(self):
424
374
# inside a repo the default convenience output is a branch+ follow the
425
375
# repo tree policy
426
format = controldir.format_registry.make_controldir('knit')
376
format = bzrdir.format_registry.make_bzrdir('knit')
427
377
self.make_repository('.', shared=True, format=format)
428
378
branch = bzrdir.BzrDir.create_branch_convenience('child',
430
branch.controldir.open_workingtree()
380
branch.bzrdir.open_workingtree()
431
381
self.assertRaises(errors.NoRepositoryPresent,
432
branch.controldir.open_repository)
382
branch.bzrdir.open_repository)
434
384
def test_create_branch_convenience_under_shared_repo_force_no_tree(self):
435
385
# inside a repo the default convenience output is a branch+ follow the
436
386
# repo tree policy but we can override that
437
format = controldir.format_registry.make_controldir('knit')
387
format = bzrdir.format_registry.make_bzrdir('knit')
438
388
self.make_repository('.', shared=True, format=format)
439
389
branch = bzrdir.BzrDir.create_branch_convenience('child',
440
force_new_tree=False, format=format)
390
force_new_tree=False, format=format)
441
391
self.assertRaises(errors.NoWorkingTree,
442
branch.controldir.open_workingtree)
392
branch.bzrdir.open_workingtree)
443
393
self.assertRaises(errors.NoRepositoryPresent,
444
branch.controldir.open_repository)
394
branch.bzrdir.open_repository)
446
396
def test_create_branch_convenience_under_shared_repo_no_tree_policy(self):
447
397
# inside a repo the default convenience output is a branch+ follow the
448
398
# repo tree policy
449
format = controldir.format_registry.make_controldir('knit')
399
format = bzrdir.format_registry.make_bzrdir('knit')
450
400
repo = self.make_repository('.', shared=True, format=format)
451
401
repo.set_make_working_trees(False)
452
402
branch = bzrdir.BzrDir.create_branch_convenience('child',
454
404
self.assertRaises(errors.NoWorkingTree,
455
branch.controldir.open_workingtree)
405
branch.bzrdir.open_workingtree)
456
406
self.assertRaises(errors.NoRepositoryPresent,
457
branch.controldir.open_repository)
407
branch.bzrdir.open_repository)
459
409
def test_create_branch_convenience_under_shared_repo_no_tree_policy_force_tree(self):
460
410
# inside a repo the default convenience output is a branch+ follow the
461
411
# repo tree policy but we can override that
462
format = controldir.format_registry.make_controldir('knit')
412
format = bzrdir.format_registry.make_bzrdir('knit')
463
413
repo = self.make_repository('.', shared=True, format=format)
464
414
repo.set_make_working_trees(False)
465
415
branch = bzrdir.BzrDir.create_branch_convenience('child',
466
force_new_tree=True, format=format)
467
branch.controldir.open_workingtree()
416
force_new_tree=True, format=format)
417
branch.bzrdir.open_workingtree()
468
418
self.assertRaises(errors.NoRepositoryPresent,
469
branch.controldir.open_repository)
419
branch.bzrdir.open_repository)
471
421
def test_create_branch_convenience_under_shared_repo_force_new_repo(self):
472
422
# inside a repo the default convenience output is overridable to give
473
423
# repo+branch+tree
474
format = controldir.format_registry.make_controldir('knit')
424
format = bzrdir.format_registry.make_bzrdir('knit')
475
425
self.make_repository('.', shared=True, format=format)
476
426
branch = bzrdir.BzrDir.create_branch_convenience('child',
477
force_new_repo=True, format=format)
478
branch.controldir.open_repository()
479
branch.controldir.open_workingtree()
427
force_new_repo=True, format=format)
428
branch.bzrdir.open_repository()
429
branch.bzrdir.open_workingtree()
482
432
class TestRepositoryAcquisitionPolicy(TestCaseWithTransport):
484
434
def test_acquire_repository_standalone(self):
485
435
"""The default acquisition policy should create a standalone branch."""
486
my_bzrdir = self.make_controldir('.')
436
my_bzrdir = self.make_bzrdir('.')
487
437
repo_policy = my_bzrdir.determine_repository_policy()
488
438
repo, is_new = repo_policy.acquire_repository()
489
self.assertEqual(repo.controldir.root_transport.base,
439
self.assertEqual(repo.bzrdir.root_transport.base,
490
440
my_bzrdir.root_transport.base)
491
441
self.assertFalse(repo.is_shared())
493
443
def test_determine_stacking_policy(self):
494
parent_bzrdir = self.make_controldir('.')
495
child_bzrdir = self.make_controldir('child')
444
parent_bzrdir = self.make_bzrdir('.')
445
child_bzrdir = self.make_bzrdir('child')
496
446
parent_bzrdir.get_config().set_default_stack_on('http://example.org')
497
447
repo_policy = child_bzrdir.determine_repository_policy()
498
448
self.assertEqual('http://example.org', repo_policy._stack_on)
500
450
def test_determine_stacking_policy_relative(self):
501
parent_bzrdir = self.make_controldir('.')
502
child_bzrdir = self.make_controldir('child')
451
parent_bzrdir = self.make_bzrdir('.')
452
child_bzrdir = self.make_bzrdir('child')
503
453
parent_bzrdir.get_config().set_default_stack_on('child2')
504
454
repo_policy = child_bzrdir.determine_repository_policy()
505
455
self.assertEqual('child2', repo_policy._stack_on)
516
466
def test_clone_on_transport_obeys_stacking_policy(self):
517
467
child_branch, new_child_transport = self.prepare_default_stacking()
518
new_child = child_branch.controldir.clone_on_transport(
468
new_child = child_branch.bzrdir.clone_on_transport(new_child_transport)
520
469
self.assertEqual(child_branch.base,
521
470
new_child.open_branch().get_stacked_on_url())
523
472
def test_default_stacking_with_stackable_branch_unstackable_repo(self):
524
473
# 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(
474
source_bzrdir = self.make_bzrdir('source')
475
pack_repo.RepositoryFormatKnitPack1().initialize(source_bzrdir)
476
source_branch = bzrlib.branch.BzrBranchFormat7().initialize(
529
478
# Make a directory with a default stacking policy
530
parent_bzrdir = self.make_controldir('parent')
479
parent_bzrdir = self.make_bzrdir('parent')
531
480
stacked_on = self.make_branch('parent/stacked-on', format='pack-0.92')
532
481
parent_bzrdir.get_config().set_default_stack_on(stacked_on.base)
533
482
# Clone source into directory
534
483
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
485
def test_sprout_obeys_stacking_policy(self):
566
486
child_branch, new_child_transport = self.prepare_default_stacking()
567
new_child = child_branch.controldir.sprout(new_child_transport.base)
487
new_child = child_branch.bzrdir.sprout(new_child_transport.base)
568
488
self.assertEqual(child_branch.base,
569
489
new_child.open_branch().get_stacked_on_url())
571
491
def test_clone_ignores_policy_for_unsupported_formats(self):
572
492
child_branch, new_child_transport = self.prepare_default_stacking(
573
493
child_format='pack-0.92')
574
new_child = child_branch.controldir.clone_on_transport(
576
self.assertRaises(branch.UnstackableBranchFormat,
494
new_child = child_branch.bzrdir.clone_on_transport(new_child_transport)
495
self.assertRaises(errors.UnstackableBranchFormat,
577
496
new_child.open_branch().get_stacked_on_url)
579
498
def test_sprout_ignores_policy_for_unsupported_formats(self):
580
499
child_branch, new_child_transport = self.prepare_default_stacking(
581
500
child_format='pack-0.92')
582
new_child = child_branch.controldir.sprout(new_child_transport.base)
583
self.assertRaises(branch.UnstackableBranchFormat,
501
new_child = child_branch.bzrdir.sprout(new_child_transport.base)
502
self.assertRaises(errors.UnstackableBranchFormat,
584
503
new_child.open_branch().get_stacked_on_url)
586
505
def test_sprout_upgrades_format_if_stacked_specified(self):
587
506
child_branch, new_child_transport = self.prepare_default_stacking(
588
507
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,
508
new_child = child_branch.bzrdir.sprout(new_child_transport.base,
510
self.assertEqual(child_branch.bzrdir.root_transport.base,
592
511
new_child.open_branch().get_stacked_on_url())
593
512
repo = new_child.open_repository()
594
513
self.assertTrue(repo._format.supports_external_lookups)
757
674
self.assertEqual(branch, None)
758
675
self.assertEqual(
759
676
osutils.realpath(os.path.join('bar', '.bzr', 'repository')),
760
repo.controldir.transport.local_abspath('repository'))
677
repo.bzrdir.transport.local_abspath('repository'))
761
678
self.assertEqual(relpath, 'baz')
763
680
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')))
681
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
682
get_transport(self.get_readonly_url('')))
683
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
684
get_transport(self.get_readonly_url('g/p/q')))
771
685
control = bzrdir.BzrDir.create(self.get_url())
772
686
branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
773
_mod_transport.get_transport_from_url(
774
self.get_readonly_url('')))
687
get_transport(self.get_readonly_url('')))
775
688
self.assertEqual('', relpath)
776
689
branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
777
_mod_transport.get_transport_from_url(
778
self.get_readonly_url('g/p/q')))
690
get_transport(self.get_readonly_url('g/p/q')))
779
691
self.assertEqual('g/p/q', relpath)
781
693
def test_open_containing_tree_or_branch(self):
821
733
self.assertEqual(os.path.realpath('topdir/foo'),
822
734
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
736
def test_open_from_transport(self):
839
737
# transport pointing at bzrdir should give a bzrdir with root transport
840
738
# set to the given transport
841
739
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)
740
transport = get_transport(self.get_url())
741
opened_bzrdir = bzrdir.BzrDir.open_from_transport(transport)
742
self.assertEqual(transport.base, opened_bzrdir.root_transport.base)
845
743
self.assertIsInstance(opened_bzrdir, bzrdir.BzrDir)
847
745
def test_open_from_transport_no_bzrdir(self):
848
t = self.get_transport()
849
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport, t)
746
transport = get_transport(self.get_url())
747
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
851
750
def test_open_from_transport_bzrdir_in_parent(self):
852
751
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)
752
transport = get_transport(self.get_url())
753
transport.mkdir('subdir')
754
transport = transport.clone('subdir')
755
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
858
758
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')
759
tree = self.make_branch_and_tree('tree1',
760
format='dirstate-with-subtree')
761
sub_tree = self.make_branch_and_tree('tree1/subtree',
762
format='dirstate-with-subtree')
763
sub_tree.set_root_id('subtree-root')
862
764
tree.add_reference(sub_tree)
863
tree.set_reference_info('subtree', sub_tree.branch.user_url)
864
765
self.build_tree(['tree1/subtree/file'])
865
766
sub_tree.add('file')
866
767
tree.commit('Initial commit')
867
tree2 = tree.controldir.sprout('tree2').open_workingtree()
768
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
868
769
tree2.lock_read()
869
770
self.addCleanup(tree2.unlock)
870
self.assertPathExists('tree2/subtree/file')
871
self.assertEqual('tree-reference', tree2.kind('subtree'))
771
self.failUnlessExists('tree2/subtree/file')
772
self.assertEqual('tree-reference', tree2.kind('subtree-root'))
873
774
def test_cloning_metadir(self):
874
775
"""Ensure that cloning metadir is suitable"""
875
bzrdir = self.make_controldir('bzrdir')
776
bzrdir = self.make_bzrdir('bzrdir')
876
777
bzrdir.cloning_metadir()
877
778
branch = self.make_branch('branch', format='knit')
878
format = branch.controldir.cloning_metadir()
779
format = branch.bzrdir.cloning_metadir()
879
780
self.assertIsInstance(format.workingtree_format,
880
workingtree_4.WorkingTreeFormat6)
781
workingtree.WorkingTreeFormat3)
882
783
def test_sprout_recursive_treeless(self):
883
784
tree = self.make_branch_and_tree('tree1',
884
format='development-subtree')
785
format='dirstate-with-subtree')
885
786
sub_tree = self.make_branch_and_tree('tree1/subtree',
886
format='development-subtree')
787
format='dirstate-with-subtree')
887
788
tree.add_reference(sub_tree)
888
tree.set_reference_info('subtree', sub_tree.branch.user_url)
889
789
self.build_tree(['tree1/subtree/file'])
890
790
sub_tree.add('file')
891
791
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
792
tree.bzrdir.destroy_workingtree()
897
793
repo = self.make_repository('repo', shared=True,
898
format='development-subtree')
794
format='dirstate-with-subtree')
899
795
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')
796
tree.bzrdir.sprout('repo/tree2')
797
self.failUnlessExists('repo/tree2/subtree')
798
self.failIfExists('repo/tree2/subtree/file')
912
800
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
801
foo = bzrdir.BzrDir.create_branch_convenience('foo').bzrdir
802
bar = self.make_branch('foo/bar').bzrdir
803
baz = self.make_branch('baz').bzrdir
916
804
return foo, bar, baz
918
def test_find_controldirs(self):
806
def test_find_bzrdirs(self):
919
807
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))
808
transport = get_transport(self.get_url())
809
self.assertEqualBzrdirs([baz, foo, bar],
810
bzrdir.BzrDir.find_bzrdirs(transport))
924
812
def make_fake_permission_denied_transport(self, transport, paths):
925
813
"""Create a transport that raises PermissionDenied for some paths."""
939
827
for actual_bzrdir in actual_bzrdirs:
940
828
self.assertEndsWith(actual_bzrdir.user_url, expect_url_suffix)
942
def test_find_controldirs_permission_denied(self):
830
def test_find_bzrdirs_permission_denied(self):
943
831
foo, bar, baz = self.make_foo_bar_baz()
944
t = self.get_transport()
832
transport = get_transport(self.get_url())
945
833
path_filter_server, path_filter_transport = \
946
self.make_fake_permission_denied_transport(t, ['foo'])
834
self.make_fake_permission_denied_transport(transport, ['foo'])
947
835
# local transport
948
836
self.assertBranchUrlsEndWith('/baz/',
949
bzrdir.BzrDir.find_controldirs(path_filter_transport))
837
bzrdir.BzrDir.find_bzrdirs(path_filter_transport))
951
839
smart_transport = self.make_smart_server('.',
952
backing_server=path_filter_server)
840
backing_server=path_filter_server)
953
841
self.assertBranchUrlsEndWith('/baz/',
954
bzrdir.BzrDir.find_controldirs(smart_transport))
842
bzrdir.BzrDir.find_bzrdirs(smart_transport))
956
def test_find_controldirs_list_current(self):
844
def test_find_bzrdirs_list_current(self):
957
845
def list_current(transport):
958
846
return [s for s in transport.list_dir('') if s != 'baz']
960
848
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))
849
transport = get_transport(self.get_url())
850
self.assertEqualBzrdirs([foo, bar],
851
bzrdir.BzrDir.find_bzrdirs(transport,
852
list_current=list_current))
966
def test_find_controldirs_evaluate(self):
854
def test_find_bzrdirs_evaluate(self):
967
855
def evaluate(bzrdir):
969
857
repo = bzrdir.open_repository()
970
except errors.NoRepositoryPresent:
858
except NoRepositoryPresent:
971
859
return True, bzrdir.root_transport.base
973
861
return False, bzrdir.root_transport.base
975
863
foo, bar, baz = self.make_foo_bar_baz()
976
t = self.get_transport()
864
transport = get_transport(self.get_url())
977
865
self.assertEqual([baz.root_transport.base, foo.root_transport.base],
978
list(bzrdir.BzrDir.find_controldirs(t, evaluate=evaluate)))
866
list(bzrdir.BzrDir.find_bzrdirs(transport,
980
869
def assertEqualBzrdirs(self, first, second):
981
870
first = list(first)
987
876
def test_find_branches(self):
988
877
root = self.make_repository('', shared=True)
989
878
foo, bar, baz = self.make_foo_bar_baz()
990
qux = self.make_controldir('foo/qux')
991
t = self.get_transport()
992
branches = bzrdir.BzrDir.find_branches(t)
879
qux = self.make_bzrdir('foo/qux')
880
transport = get_transport(self.get_url())
881
branches = bzrdir.BzrDir.find_branches(transport)
993
882
self.assertEqual(baz.root_transport.base, branches[0].base)
994
883
self.assertEqual(foo.root_transport.base, branches[1].base)
995
884
self.assertEqual(bar.root_transport.base, branches[2].base)
997
886
# ensure this works without a top-level repo
998
branches = bzrdir.BzrDir.find_branches(t.clone('foo'))
887
branches = bzrdir.BzrDir.find_branches(transport.clone('foo'))
999
888
self.assertEqual(foo.root_transport.base, branches[0].base)
1000
889
self.assertEqual(bar.root_transport.base, branches[1].base)
1003
892
class TestMissingRepoBranchesSkipped(TestCaseWithMemoryTransport):
1005
def test_find_controldirs_missing_repo(self):
1006
t = self.get_transport()
894
def test_find_bzrdirs_missing_repo(self):
895
transport = get_transport(self.get_url())
1007
896
arepo = self.make_repository('arepo', shared=True)
1008
897
abranch_url = arepo.user_url + '/abranch'
1009
898
abranch = bzrdir.BzrDir.create(abranch_url).create_branch()
1010
t.delete_tree('arepo/.bzr')
899
transport.delete_tree('arepo/.bzr')
1011
900
self.assertRaises(errors.NoRepositoryPresent,
1012
branch.Branch.open, abranch_url)
901
branch.Branch.open, abranch_url)
1013
902
self.make_branch('baz')
1014
for actual_bzrdir in bzrdir.BzrDir.find_branches(t):
903
for actual_bzrdir in bzrdir.BzrDir.find_branches(transport):
1015
904
self.assertEndsWith(actual_bzrdir.user_url, '/baz/')
1049
935
Metadirs should compare equal iff they have the same repo, branch and
1052
mydir = controldir.format_registry.make_controldir('knit')
938
mydir = bzrdir.format_registry.make_bzrdir('knit')
1053
939
self.assertEqual(mydir, mydir)
1054
940
self.assertFalse(mydir != mydir)
1055
otherdir = controldir.format_registry.make_controldir('knit')
941
otherdir = bzrdir.format_registry.make_bzrdir('knit')
1056
942
self.assertEqual(otherdir, mydir)
1057
943
self.assertFalse(otherdir != mydir)
1058
otherdir2 = controldir.format_registry.make_controldir(
1059
'development-subtree')
944
otherdir2 = bzrdir.format_registry.make_bzrdir('dirstate-with-subtree')
1060
945
self.assertNotEqual(otherdir2, mydir)
1061
946
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
948
def test_needs_conversion_different_working_tree(self):
1078
949
# meta1dirs need an conversion if any element is not the default.
1079
new_format = controldir.format_registry.make_controldir('dirstate')
950
new_format = bzrdir.format_registry.make_bzrdir('dirstate')
1080
951
tree = self.make_branch_and_tree('tree', format='knit')
1081
self.assertTrue(tree.controldir.needs_format_conversion(
952
self.assertTrue(tree.bzrdir.needs_format_conversion(
1084
955
def test_initialize_on_format_uses_smart_transport(self):
1085
956
self.setup_smart_server_with_call_log()
1086
new_format = controldir.format_registry.make_controldir('dirstate')
957
new_format = bzrdir.format_registry.make_bzrdir('dirstate')
1087
958
transport = self.get_transport('target')
1088
959
transport.ensure_base()
1089
960
self.reset_smart_call_log()
1098
969
self.assertEqual(2, rpc_count)
972
class TestFormat5(TestCaseWithTransport):
973
"""Tests specific to the version 5 bzrdir format."""
975
def test_same_lockfiles_between_tree_repo_branch(self):
976
# this checks that only a single lockfiles instance is created
977
# for format 5 objects
978
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
979
def check_dir_components_use_same_lock(dir):
980
ctrl_1 = dir.open_repository().control_files
981
ctrl_2 = dir.open_branch().control_files
982
ctrl_3 = dir.open_workingtree()._control_files
983
self.assertTrue(ctrl_1 is ctrl_2)
984
self.assertTrue(ctrl_2 is ctrl_3)
985
check_dir_components_use_same_lock(dir)
986
# and if we open it normally.
987
dir = bzrdir.BzrDir.open(self.get_url())
988
check_dir_components_use_same_lock(dir)
990
def test_can_convert(self):
991
# format 5 dirs are convertable
992
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
993
self.assertTrue(dir.can_convert_format())
995
def test_needs_conversion(self):
996
# format 5 dirs need a conversion if they are not the default,
998
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
999
# don't need to convert it to itself
1000
self.assertFalse(dir.needs_format_conversion(bzrdir.BzrDirFormat5()))
1001
# do need to convert it to the current default
1002
self.assertTrue(dir.needs_format_conversion(
1003
bzrdir.BzrDirFormat.get_default_format()))
1006
class TestFormat6(TestCaseWithTransport):
1007
"""Tests specific to the version 6 bzrdir format."""
1009
def test_same_lockfiles_between_tree_repo_branch(self):
1010
# this checks that only a single lockfiles instance is created
1011
# for format 6 objects
1012
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
1013
def check_dir_components_use_same_lock(dir):
1014
ctrl_1 = dir.open_repository().control_files
1015
ctrl_2 = dir.open_branch().control_files
1016
ctrl_3 = dir.open_workingtree()._control_files
1017
self.assertTrue(ctrl_1 is ctrl_2)
1018
self.assertTrue(ctrl_2 is ctrl_3)
1019
check_dir_components_use_same_lock(dir)
1020
# and if we open it normally.
1021
dir = bzrdir.BzrDir.open(self.get_url())
1022
check_dir_components_use_same_lock(dir)
1024
def test_can_convert(self):
1025
# format 6 dirs are convertable
1026
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
1027
self.assertTrue(dir.can_convert_format())
1029
def test_needs_conversion(self):
1030
# format 6 dirs need an conversion if they are not the default.
1031
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
1032
self.assertTrue(dir.needs_format_conversion(
1033
bzrdir.BzrDirFormat.get_default_format()))
1036
class NotBzrDir(bzrlib.bzrdir.BzrDir):
1037
"""A non .bzr based control directory."""
1039
def __init__(self, transport, format):
1040
self._format = format
1041
self.root_transport = transport
1042
self.transport = transport.clone('.not')
1045
class NotBzrDirFormat(bzrlib.bzrdir.BzrDirFormat):
1046
"""A test class representing any non-.bzr based disk format."""
1048
def initialize_on_transport(self, transport):
1049
"""Initialize a new .not dir in the base directory of a Transport."""
1050
transport.mkdir('.not')
1051
return self.open(transport)
1053
def open(self, transport):
1054
"""Open this directory."""
1055
return NotBzrDir(transport, self)
1058
def _known_formats(self):
1059
return set([NotBzrDirFormat()])
1062
def probe_transport(self, transport):
1063
"""Our format is present if the transport ends in '.not/'."""
1064
if transport.has('.not'):
1065
return NotBzrDirFormat()
1068
class TestNotBzrDir(TestCaseWithTransport):
1069
"""Tests for using the bzrdir api with a non .bzr based disk format.
1071
If/when one of these is in the core, we can let the implementation tests
1075
def test_create_and_find_format(self):
1076
# create a .notbzr dir
1077
format = NotBzrDirFormat()
1078
dir = format.initialize(self.get_url())
1079
self.assertIsInstance(dir, NotBzrDir)
1081
bzrlib.bzrdir.BzrDirFormat.register_control_format(format)
1083
found = bzrlib.bzrdir.BzrDirFormat.find_format(
1084
get_transport(self.get_url()))
1085
self.assertIsInstance(found, NotBzrDirFormat)
1087
bzrlib.bzrdir.BzrDirFormat.unregister_control_format(format)
1089
def test_included_in_known_formats(self):
1090
bzrlib.bzrdir.BzrDirFormat.register_control_format(NotBzrDirFormat)
1092
formats = bzrlib.bzrdir.BzrDirFormat.known_formats()
1093
for format in formats:
1094
if isinstance(format, NotBzrDirFormat):
1096
self.fail("No NotBzrDirFormat in %s" % formats)
1098
bzrlib.bzrdir.BzrDirFormat.unregister_control_format(NotBzrDirFormat)
1101
1101
class NonLocalTests(TestCaseWithTransport):
1102
1102
"""Tests for bzrdir static behaviour on non local paths."""
1279
1295
def __init__(self, *args, **kwargs):
1280
1296
super(_TestBzrDir, self).__init__(*args, **kwargs)
1281
self.test_branch = _TestBranch(self.transport)
1297
self.test_branch = _TestBranch()
1282
1298
self.test_branch.repository = self.create_repository()
1284
def open_branch(self, unsupported=False, possible_transports=None):
1300
def open_branch(self, unsupported=False):
1285
1301
return self.test_branch
1287
1303
def cloning_metadir(self, require_stacking=False):
1288
1304
return _TestBzrDirFormat()
1291
class _TestBranchFormat(breezy.branch.BranchFormat):
1307
class _TestBranchFormat(bzrlib.branch.BranchFormat):
1292
1308
"""Test Branch format for TestBzrDirSprout."""
1295
class _TestBranch(breezy.branch.Branch):
1311
class _TestBranch(bzrlib.branch.Branch):
1296
1312
"""Test Branch implementation for TestBzrDirSprout."""
1298
def __init__(self, transport, *args, **kwargs):
1314
def __init__(self, *args, **kwargs):
1299
1315
self._format = _TestBranchFormat()
1300
self._transport = transport
1301
self.base = transport.base
1302
1316
super(_TestBranch, self).__init__(*args, **kwargs)
1303
1317
self.calls = []
1304
1318
self._parent = None
1306
1320
def sprout(self, *args, **kwargs):
1307
1321
self.calls.append('sprout')
1308
return _TestBranch(self._transport)
1322
return _TestBranch()
1310
1324
def copy_content_into(self, destination, revision_id=None):
1311
1325
self.calls.append('copy_content_into')
1313
def last_revision(self):
1314
return _mod_revision.NULL_REVISION
1316
1327
def get_parent(self):
1317
1328
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
1330
def set_parent(self, parent):
1326
1331
self._parent = parent
1328
def lock_read(self):
1329
return lock.LogicalLockResult(self.unlock)
1335
1334
class TestBzrDirSprout(TestCaseWithMemoryTransport):
1393
1391
self.assertEqual('fail', err._preformatted_string)
1395
1393
def test_post_repo_init(self):
1396
from ..controldir import RepoInitHookParams
1394
from bzrlib.bzrdir import RepoInitHookParams
1398
1396
bzrdir.BzrDir.hooks.install_named_hook('post_repo_init',
1400
1398
self.make_repository('foo')
1401
1399
self.assertLength(1, calls)
1402
1400
params = calls[0]
1403
1401
self.assertIsInstance(params, RepoInitHookParams)
1404
self.assertTrue(hasattr(params, 'controldir'))
1402
self.assertTrue(hasattr(params, 'bzrdir'))
1405
1403
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
1406
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 ?
1422
1408
def setUp(self):
1423
1409
super(TestGenerateBackupName, self).setUp()
1424
self._transport = self.get_transport()
1410
self._transport = get_transport(self.get_url())
1425
1411
bzrdir.BzrDir.create(self.get_url(),
1426
possible_transports=[self._transport])
1412
possible_transports=[self._transport])
1427
1413
self._bzrdir = bzrdir.BzrDir.open_from_transport(self._transport)
1429
1415
def test_new(self):
1430
self.assertEqual("a.~1~", self._bzrdir._available_backup_name("a"))
1416
self.assertEqual("a.~1~", self._bzrdir.generate_backup_name("a"))
1432
1418
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,
1419
self._transport.put_bytes("a.~1~", "some content")
1420
self.assertEqual("a.~2~", self._bzrdir.generate_backup_name("a"))