1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
"""Tests for the BzrDir facility and any format specific tests.
19
For interface contract tests, see tests/bzr_dir_implementations.
23
from StringIO import StringIO
35
from bzrlib.errors import (NotBranchError,
37
UnsupportedFormatError,
39
from bzrlib.tests import TestCase, TestCaseWithTransport, test_sftp_transport
40
from bzrlib.tests.HttpServer import HttpServer
41
from bzrlib.transport import get_transport
42
from bzrlib.transport.memory import MemoryServer
43
from bzrlib.repofmt import knitrepo, weaverepo
46
class TestDefaultFormat(TestCase):
48
def test_get_set_default_format(self):
49
old_format = bzrdir.BzrDirFormat.get_default_format()
50
# default is BzrDirFormat6
51
self.failUnless(isinstance(old_format, bzrdir.BzrDirMetaFormat1))
52
self.applyDeprecated(symbol_versioning.zero_fourteen,
53
bzrdir.BzrDirFormat.set_default_format,
55
# creating a bzr dir should now create an instrumented dir.
57
result = bzrdir.BzrDir.create('memory:///')
58
self.failUnless(isinstance(result, SampleBzrDir))
60
self.applyDeprecated(symbol_versioning.zero_fourteen,
61
bzrdir.BzrDirFormat.set_default_format, old_format)
62
self.assertEqual(old_format, bzrdir.BzrDirFormat.get_default_format())
65
class TestFormatRegistry(TestCase):
67
def make_format_registry(self):
68
my_format_registry = bzrdir.BzrDirFormatRegistry()
69
my_format_registry.register('weave', bzrdir.BzrDirFormat6,
70
'Pre-0.8 format. Slower and does not support checkouts or shared'
71
' repositories', deprecated=True)
72
my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir',
73
'BzrDirFormat6', 'Format registered lazily', deprecated=True)
74
my_format_registry.register_metadir('knit',
75
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
78
my_format_registry.set_default('knit')
79
my_format_registry.register_metadir(
81
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
82
'Experimental successor to knit. Use at your own risk.',
83
branch_format='bzrlib.branch.BzrBranchFormat6')
84
my_format_registry.register_metadir(
86
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
87
'Experimental successor to knit. Use at your own risk.',
88
branch_format='bzrlib.branch.BzrBranchFormat6', hidden=True)
89
my_format_registry.register('hiddenweave', bzrdir.BzrDirFormat6,
90
'Pre-0.8 format. Slower and does not support checkouts or shared'
91
' repositories', hidden=True)
92
my_format_registry.register_lazy('hiddenlazy', 'bzrlib.bzrdir',
93
'BzrDirFormat6', 'Format registered lazily', deprecated=True,
95
return my_format_registry
97
def test_format_registry(self):
98
my_format_registry = self.make_format_registry()
99
my_bzrdir = my_format_registry.make_bzrdir('lazy')
100
self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
101
my_bzrdir = my_format_registry.make_bzrdir('weave')
102
self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
103
my_bzrdir = my_format_registry.make_bzrdir('default')
104
self.assertIsInstance(my_bzrdir.repository_format,
105
knitrepo.RepositoryFormatKnit1)
106
my_bzrdir = my_format_registry.make_bzrdir('knit')
107
self.assertIsInstance(my_bzrdir.repository_format,
108
knitrepo.RepositoryFormatKnit1)
109
my_bzrdir = my_format_registry.make_bzrdir('branch6')
110
self.assertIsInstance(my_bzrdir.get_branch_format(),
111
bzrlib.branch.BzrBranchFormat6)
113
def test_get_help(self):
114
my_format_registry = self.make_format_registry()
115
self.assertEqual('Format registered lazily',
116
my_format_registry.get_help('lazy'))
117
self.assertEqual('Format using knits',
118
my_format_registry.get_help('knit'))
119
self.assertEqual('Format using knits',
120
my_format_registry.get_help('default'))
121
self.assertEqual('Pre-0.8 format. Slower and does not support'
122
' checkouts or shared repositories',
123
my_format_registry.get_help('weave'))
125
def test_help_topic(self):
126
topics = help_topics.HelpTopicRegistry()
127
topics.register('formats', self.make_format_registry().help_topic,
129
topic = topics.get_detail('formats')
130
new, deprecated = topic.split('Deprecated formats')
131
self.assertContainsRe(new, 'Bazaar directory formats')
132
self.assertContainsRe(new,
133
' knit/default:\n \(native\) Format using knits\n')
134
self.assertContainsRe(deprecated,
135
' lazy:\n \(native\) Format registered lazily\n')
136
self.assertNotContainsRe(new, 'hidden')
138
def test_set_default_repository(self):
139
default_factory = bzrdir.format_registry.get('default')
140
old_default = [k for k, v in bzrdir.format_registry.iteritems()
141
if v == default_factory and k != 'default'][0]
142
bzrdir.format_registry.set_default_repository('dirstate-with-subtree')
144
self.assertIs(bzrdir.format_registry.get('dirstate-with-subtree'),
145
bzrdir.format_registry.get('default'))
147
repository.RepositoryFormat.get_default_format().__class__,
148
knitrepo.RepositoryFormatKnit3)
150
bzrdir.format_registry.set_default_repository(old_default)
153
class SampleBranch(bzrlib.branch.Branch):
154
"""A dummy branch for guess what, dummy use."""
156
def __init__(self, dir):
160
class SampleBzrDir(bzrdir.BzrDir):
161
"""A sample BzrDir implementation to allow testing static methods."""
163
def create_repository(self, shared=False):
164
"""See BzrDir.create_repository."""
165
return "A repository"
167
def open_repository(self):
168
"""See BzrDir.open_repository."""
169
return "A repository"
171
def create_branch(self):
172
"""See BzrDir.create_branch."""
173
return SampleBranch(self)
175
def create_workingtree(self):
176
"""See BzrDir.create_workingtree."""
180
class SampleBzrDirFormat(bzrdir.BzrDirFormat):
183
this format is initializable, unsupported to aid in testing the
184
open and open_downlevel routines.
187
def get_format_string(self):
188
"""See BzrDirFormat.get_format_string()."""
189
return "Sample .bzr dir format."
191
def initialize(self, url):
192
"""Create a bzr dir."""
193
t = get_transport(url)
195
t.put_bytes('.bzr/branch-format', self.get_format_string())
196
return SampleBzrDir(t, self)
198
def is_supported(self):
201
def open(self, transport, _found=None):
202
return "opened branch."
205
class TestBzrDirFormat(TestCaseWithTransport):
206
"""Tests for the BzrDirFormat facility."""
208
def test_find_format(self):
209
# is the right format object found for a branch?
210
# create a branch with a few known format objects.
211
# this is not quite the same as
212
t = get_transport(self.get_url())
213
self.build_tree(["foo/", "bar/"], transport=t)
214
def check_format(format, url):
215
format.initialize(url)
216
t = get_transport(url)
217
found_format = bzrdir.BzrDirFormat.find_format(t)
218
self.failUnless(isinstance(found_format, format.__class__))
219
check_format(bzrdir.BzrDirFormat5(), "foo")
220
check_format(bzrdir.BzrDirFormat6(), "bar")
222
def test_find_format_nothing_there(self):
223
self.assertRaises(NotBranchError,
224
bzrdir.BzrDirFormat.find_format,
227
def test_find_format_unknown_format(self):
228
t = get_transport(self.get_url())
230
t.put_bytes('.bzr/branch-format', '')
231
self.assertRaises(UnknownFormatError,
232
bzrdir.BzrDirFormat.find_format,
235
def test_register_unregister_format(self):
236
format = SampleBzrDirFormat()
239
format.initialize(url)
240
# register a format for it.
241
bzrdir.BzrDirFormat.register_format(format)
242
# which bzrdir.Open will refuse (not supported)
243
self.assertRaises(UnsupportedFormatError, bzrdir.BzrDir.open, url)
244
# which bzrdir.open_containing will refuse (not supported)
245
self.assertRaises(UnsupportedFormatError, bzrdir.BzrDir.open_containing, url)
246
# but open_downlevel will work
247
t = get_transport(url)
248
self.assertEqual(format.open(t), bzrdir.BzrDir.open_unsupported(url))
249
# unregister the format
250
bzrdir.BzrDirFormat.unregister_format(format)
251
# now open_downlevel should fail too.
252
self.assertRaises(UnknownFormatError, bzrdir.BzrDir.open_unsupported, url)
254
def test_create_repository(self):
255
format = SampleBzrDirFormat()
256
repo = bzrdir.BzrDir.create_repository(self.get_url(), format=format)
257
self.assertEqual('A repository', repo)
259
def test_create_repository_shared(self):
260
old_format = bzrdir.BzrDirFormat.get_default_format()
261
repo = bzrdir.BzrDir.create_repository('.', shared=True)
262
self.assertTrue(repo.is_shared())
264
def test_create_repository_nonshared(self):
265
old_format = bzrdir.BzrDirFormat.get_default_format()
266
repo = bzrdir.BzrDir.create_repository('.')
267
self.assertFalse(repo.is_shared())
269
def test_create_repository_under_shared(self):
270
# an explicit create_repository always does so.
271
# we trust the format is right from the 'create_repository test'
272
format = bzrdir.format_registry.make_bzrdir('knit')
273
self.make_repository('.', shared=True, format=format)
274
repo = bzrdir.BzrDir.create_repository(self.get_url('child'),
276
self.assertTrue(isinstance(repo, repository.Repository))
277
self.assertTrue(repo.bzrdir.root_transport.base.endswith('child/'))
279
def test_create_branch_and_repo_uses_default(self):
280
format = SampleBzrDirFormat()
281
branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url(),
283
self.assertTrue(isinstance(branch, SampleBranch))
285
def test_create_branch_and_repo_under_shared(self):
286
# creating a branch and repo in a shared repo uses the
288
format = bzrdir.format_registry.make_bzrdir('knit')
289
self.make_repository('.', shared=True, format=format)
290
branch = bzrdir.BzrDir.create_branch_and_repo(
291
self.get_url('child'), format=format)
292
self.assertRaises(errors.NoRepositoryPresent,
293
branch.bzrdir.open_repository)
295
def test_create_branch_and_repo_under_shared_force_new(self):
296
# creating a branch and repo in a shared repo can be forced to
298
format = bzrdir.format_registry.make_bzrdir('knit')
299
self.make_repository('.', shared=True, format=format)
300
branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url('child'),
303
branch.bzrdir.open_repository()
305
def test_create_standalone_working_tree(self):
306
format = SampleBzrDirFormat()
307
# note this is deliberately readonly, as this failure should
308
# occur before any writes.
309
self.assertRaises(errors.NotLocalUrl,
310
bzrdir.BzrDir.create_standalone_workingtree,
311
self.get_readonly_url(), format=format)
312
tree = bzrdir.BzrDir.create_standalone_workingtree('.',
314
self.assertEqual('A tree', tree)
316
def test_create_standalone_working_tree_under_shared_repo(self):
317
# create standalone working tree always makes a repo.
318
format = bzrdir.format_registry.make_bzrdir('knit')
319
self.make_repository('.', shared=True, format=format)
320
# note this is deliberately readonly, as this failure should
321
# occur before any writes.
322
self.assertRaises(errors.NotLocalUrl,
323
bzrdir.BzrDir.create_standalone_workingtree,
324
self.get_readonly_url('child'), format=format)
325
tree = bzrdir.BzrDir.create_standalone_workingtree('child',
327
tree.bzrdir.open_repository()
329
def test_create_branch_convenience(self):
330
# outside a repo the default convenience output is a repo+branch_tree
331
format = bzrdir.format_registry.make_bzrdir('knit')
332
branch = bzrdir.BzrDir.create_branch_convenience('.', format=format)
333
branch.bzrdir.open_workingtree()
334
branch.bzrdir.open_repository()
336
def test_create_branch_convenience_root(self):
337
"""Creating a branch at the root of a fs should work."""
338
self.vfs_transport_factory = MemoryServer
339
# outside a repo the default convenience output is a repo+branch_tree
340
format = bzrdir.format_registry.make_bzrdir('knit')
341
branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(),
343
self.assertRaises(errors.NoWorkingTree,
344
branch.bzrdir.open_workingtree)
345
branch.bzrdir.open_repository()
347
def test_create_branch_convenience_under_shared_repo(self):
348
# inside a repo the default convenience output is a branch+ follow the
350
format = bzrdir.format_registry.make_bzrdir('knit')
351
self.make_repository('.', shared=True, format=format)
352
branch = bzrdir.BzrDir.create_branch_convenience('child',
354
branch.bzrdir.open_workingtree()
355
self.assertRaises(errors.NoRepositoryPresent,
356
branch.bzrdir.open_repository)
358
def test_create_branch_convenience_under_shared_repo_force_no_tree(self):
359
# inside a repo the default convenience output is a branch+ follow the
360
# repo tree policy but we can override that
361
format = bzrdir.format_registry.make_bzrdir('knit')
362
self.make_repository('.', shared=True, format=format)
363
branch = bzrdir.BzrDir.create_branch_convenience('child',
364
force_new_tree=False, format=format)
365
self.assertRaises(errors.NoWorkingTree,
366
branch.bzrdir.open_workingtree)
367
self.assertRaises(errors.NoRepositoryPresent,
368
branch.bzrdir.open_repository)
370
def test_create_branch_convenience_under_shared_repo_no_tree_policy(self):
371
# inside a repo the default convenience output is a branch+ follow the
373
format = bzrdir.format_registry.make_bzrdir('knit')
374
repo = self.make_repository('.', shared=True, format=format)
375
repo.set_make_working_trees(False)
376
branch = bzrdir.BzrDir.create_branch_convenience('child',
378
self.assertRaises(errors.NoWorkingTree,
379
branch.bzrdir.open_workingtree)
380
self.assertRaises(errors.NoRepositoryPresent,
381
branch.bzrdir.open_repository)
383
def test_create_branch_convenience_under_shared_repo_no_tree_policy_force_tree(self):
384
# inside a repo the default convenience output is a branch+ follow the
385
# repo tree policy but we can override that
386
format = bzrdir.format_registry.make_bzrdir('knit')
387
repo = self.make_repository('.', shared=True, format=format)
388
repo.set_make_working_trees(False)
389
branch = bzrdir.BzrDir.create_branch_convenience('child',
390
force_new_tree=True, format=format)
391
branch.bzrdir.open_workingtree()
392
self.assertRaises(errors.NoRepositoryPresent,
393
branch.bzrdir.open_repository)
395
def test_create_branch_convenience_under_shared_repo_force_new_repo(self):
396
# inside a repo the default convenience output is overridable to give
398
format = bzrdir.format_registry.make_bzrdir('knit')
399
self.make_repository('.', shared=True, format=format)
400
branch = bzrdir.BzrDir.create_branch_convenience('child',
401
force_new_repo=True, format=format)
402
branch.bzrdir.open_repository()
403
branch.bzrdir.open_workingtree()
406
class ChrootedTests(TestCaseWithTransport):
407
"""A support class that provides readonly urls outside the local namespace.
409
This is done by checking if self.transport_server is a MemoryServer. if it
410
is then we are chrooted already, if it is not then an HttpServer is used
415
super(ChrootedTests, self).setUp()
416
if not self.vfs_transport_factory == MemoryServer:
417
self.transport_readonly_server = HttpServer
419
def test_open_containing(self):
420
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing,
421
self.get_readonly_url(''))
422
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing,
423
self.get_readonly_url('g/p/q'))
424
control = bzrdir.BzrDir.create(self.get_url())
425
branch, relpath = bzrdir.BzrDir.open_containing(self.get_readonly_url(''))
426
self.assertEqual('', relpath)
427
branch, relpath = bzrdir.BzrDir.open_containing(self.get_readonly_url('g/p/q'))
428
self.assertEqual('g/p/q', relpath)
430
def test_open_containing_from_transport(self):
431
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
432
get_transport(self.get_readonly_url('')))
433
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
434
get_transport(self.get_readonly_url('g/p/q')))
435
control = bzrdir.BzrDir.create(self.get_url())
436
branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
437
get_transport(self.get_readonly_url('')))
438
self.assertEqual('', relpath)
439
branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
440
get_transport(self.get_readonly_url('g/p/q')))
441
self.assertEqual('g/p/q', relpath)
443
def test_open_containing_tree_or_branch(self):
444
def local_branch_path(branch):
445
return os.path.realpath(
446
urlutils.local_path_from_url(branch.base))
448
self.make_branch_and_tree('topdir')
449
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
451
self.assertEqual(os.path.realpath('topdir'),
452
os.path.realpath(tree.basedir))
453
self.assertEqual(os.path.realpath('topdir'),
454
local_branch_path(branch))
455
self.assertIs(tree.bzrdir, branch.bzrdir)
456
self.assertEqual('foo', relpath)
457
# opening from non-local should not return the tree
458
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
459
self.get_readonly_url('topdir/foo'))
460
self.assertEqual(None, tree)
461
self.assertEqual('foo', relpath)
463
self.make_branch('topdir/foo')
464
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
466
self.assertIs(tree, None)
467
self.assertEqual(os.path.realpath('topdir/foo'),
468
local_branch_path(branch))
469
self.assertEqual('', relpath)
471
def test_open_from_transport(self):
472
# transport pointing at bzrdir should give a bzrdir with root transport
473
# set to the given transport
474
control = bzrdir.BzrDir.create(self.get_url())
475
transport = get_transport(self.get_url())
476
opened_bzrdir = bzrdir.BzrDir.open_from_transport(transport)
477
self.assertEqual(transport.base, opened_bzrdir.root_transport.base)
478
self.assertIsInstance(opened_bzrdir, bzrdir.BzrDir)
480
def test_open_from_transport_no_bzrdir(self):
481
transport = get_transport(self.get_url())
482
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
485
def test_open_from_transport_bzrdir_in_parent(self):
486
control = bzrdir.BzrDir.create(self.get_url())
487
transport = get_transport(self.get_url())
488
transport.mkdir('subdir')
489
transport = transport.clone('subdir')
490
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
493
def test_sprout_recursive(self):
494
tree = self.make_branch_and_tree('tree1', format='dirstate-with-subtree')
495
sub_tree = self.make_branch_and_tree('tree1/subtree',
496
format='dirstate-with-subtree')
497
tree.add_reference(sub_tree)
498
self.build_tree(['tree1/subtree/file'])
500
tree.commit('Initial commit')
501
tree.bzrdir.sprout('tree2')
502
self.failUnlessExists('tree2/subtree/file')
504
def test_cloning_metadir(self):
505
"""Ensure that cloning metadir is suitable"""
506
bzrdir = self.make_bzrdir('bzrdir')
507
bzrdir.cloning_metadir()
508
branch = self.make_branch('branch', format='knit')
509
format = branch.bzrdir.cloning_metadir()
510
self.assertIsInstance(format.workingtree_format,
511
workingtree.WorkingTreeFormat3)
513
def test_sprout_recursive_treeless(self):
514
tree = self.make_branch_and_tree('tree1',
515
format='dirstate-with-subtree')
516
sub_tree = self.make_branch_and_tree('tree1/subtree',
517
format='dirstate-with-subtree')
518
tree.add_reference(sub_tree)
519
self.build_tree(['tree1/subtree/file'])
521
tree.commit('Initial commit')
522
tree.bzrdir.destroy_workingtree()
523
repo = self.make_repository('repo', shared=True,
524
format='dirstate-with-subtree')
525
repo.set_make_working_trees(False)
526
tree.bzrdir.sprout('repo/tree2')
527
self.failUnlessExists('repo/tree2/subtree')
528
self.failIfExists('repo/tree2/subtree/file')
531
class TestMeta1DirFormat(TestCaseWithTransport):
532
"""Tests specific to the meta1 dir format."""
534
def test_right_base_dirs(self):
535
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
537
branch_base = t.clone('branch').base
538
self.assertEqual(branch_base, dir.get_branch_transport(None).base)
539
self.assertEqual(branch_base,
540
dir.get_branch_transport(bzrlib.branch.BzrBranchFormat5()).base)
541
repository_base = t.clone('repository').base
542
self.assertEqual(repository_base, dir.get_repository_transport(None).base)
543
self.assertEqual(repository_base,
544
dir.get_repository_transport(weaverepo.RepositoryFormat7()).base)
545
checkout_base = t.clone('checkout').base
546
self.assertEqual(checkout_base, dir.get_workingtree_transport(None).base)
547
self.assertEqual(checkout_base,
548
dir.get_workingtree_transport(workingtree.WorkingTreeFormat3()).base)
550
def test_meta1dir_uses_lockdir(self):
551
"""Meta1 format uses a LockDir to guard the whole directory, not a file."""
552
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
554
self.assertIsDirectory('branch-lock', t)
556
def test_comparison(self):
557
"""Equality and inequality behave properly.
559
Metadirs should compare equal iff they have the same repo, branch and
562
mydir = bzrdir.format_registry.make_bzrdir('knit')
563
self.assertEqual(mydir, mydir)
564
self.assertFalse(mydir != mydir)
565
otherdir = bzrdir.format_registry.make_bzrdir('knit')
566
self.assertEqual(otherdir, mydir)
567
self.assertFalse(otherdir != mydir)
568
otherdir2 = bzrdir.format_registry.make_bzrdir('dirstate-with-subtree')
569
self.assertNotEqual(otherdir2, mydir)
570
self.assertFalse(otherdir2 == mydir)
572
def test_needs_conversion_different_working_tree(self):
573
# meta1dirs need an conversion if any element is not the default.
574
old_format = bzrdir.BzrDirFormat.get_default_format()
576
new_default = bzrdir.format_registry.make_bzrdir('dirstate')
577
bzrdir.BzrDirFormat._set_default_format(new_default)
579
tree = self.make_branch_and_tree('tree', format='knit')
580
self.assertTrue(tree.bzrdir.needs_format_conversion())
582
bzrdir.BzrDirFormat._set_default_format(old_format)
585
class TestFormat5(TestCaseWithTransport):
586
"""Tests specific to the version 5 bzrdir format."""
588
def test_same_lockfiles_between_tree_repo_branch(self):
589
# this checks that only a single lockfiles instance is created
590
# for format 5 objects
591
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
592
def check_dir_components_use_same_lock(dir):
593
ctrl_1 = dir.open_repository().control_files
594
ctrl_2 = dir.open_branch().control_files
595
ctrl_3 = dir.open_workingtree()._control_files
596
self.assertTrue(ctrl_1 is ctrl_2)
597
self.assertTrue(ctrl_2 is ctrl_3)
598
check_dir_components_use_same_lock(dir)
599
# and if we open it normally.
600
dir = bzrdir.BzrDir.open(self.get_url())
601
check_dir_components_use_same_lock(dir)
603
def test_can_convert(self):
604
# format 5 dirs are convertable
605
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
606
self.assertTrue(dir.can_convert_format())
608
def test_needs_conversion(self):
609
# format 5 dirs need a conversion if they are not the default.
610
# and they start of not the default.
611
old_format = bzrdir.BzrDirFormat.get_default_format()
612
bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirFormat5())
614
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
615
self.assertFalse(dir.needs_format_conversion())
617
bzrdir.BzrDirFormat._set_default_format(old_format)
618
self.assertTrue(dir.needs_format_conversion())
621
class TestFormat6(TestCaseWithTransport):
622
"""Tests specific to the version 6 bzrdir format."""
624
def test_same_lockfiles_between_tree_repo_branch(self):
625
# this checks that only a single lockfiles instance is created
626
# for format 6 objects
627
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
628
def check_dir_components_use_same_lock(dir):
629
ctrl_1 = dir.open_repository().control_files
630
ctrl_2 = dir.open_branch().control_files
631
ctrl_3 = dir.open_workingtree()._control_files
632
self.assertTrue(ctrl_1 is ctrl_2)
633
self.assertTrue(ctrl_2 is ctrl_3)
634
check_dir_components_use_same_lock(dir)
635
# and if we open it normally.
636
dir = bzrdir.BzrDir.open(self.get_url())
637
check_dir_components_use_same_lock(dir)
639
def test_can_convert(self):
640
# format 6 dirs are convertable
641
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
642
self.assertTrue(dir.can_convert_format())
644
def test_needs_conversion(self):
645
# format 6 dirs need an conversion if they are not the default.
646
old_format = bzrdir.BzrDirFormat.get_default_format()
647
bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirMetaFormat1())
649
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
650
self.assertTrue(dir.needs_format_conversion())
652
bzrdir.BzrDirFormat._set_default_format(old_format)
655
class NotBzrDir(bzrlib.bzrdir.BzrDir):
656
"""A non .bzr based control directory."""
658
def __init__(self, transport, format):
659
self._format = format
660
self.root_transport = transport
661
self.transport = transport.clone('.not')
664
class NotBzrDirFormat(bzrlib.bzrdir.BzrDirFormat):
665
"""A test class representing any non-.bzr based disk format."""
667
def initialize_on_transport(self, transport):
668
"""Initialize a new .not dir in the base directory of a Transport."""
669
transport.mkdir('.not')
670
return self.open(transport)
672
def open(self, transport):
673
"""Open this directory."""
674
return NotBzrDir(transport, self)
677
def _known_formats(self):
678
return set([NotBzrDirFormat()])
681
def probe_transport(self, transport):
682
"""Our format is present if the transport ends in '.not/'."""
683
if transport.has('.not'):
684
return NotBzrDirFormat()
687
class TestNotBzrDir(TestCaseWithTransport):
688
"""Tests for using the bzrdir api with a non .bzr based disk format.
690
If/when one of these is in the core, we can let the implementation tests
694
def test_create_and_find_format(self):
695
# create a .notbzr dir
696
format = NotBzrDirFormat()
697
dir = format.initialize(self.get_url())
698
self.assertIsInstance(dir, NotBzrDir)
700
bzrlib.bzrdir.BzrDirFormat.register_control_format(format)
702
found = bzrlib.bzrdir.BzrDirFormat.find_format(
703
get_transport(self.get_url()))
704
self.assertIsInstance(found, NotBzrDirFormat)
706
bzrlib.bzrdir.BzrDirFormat.unregister_control_format(format)
708
def test_included_in_known_formats(self):
709
bzrlib.bzrdir.BzrDirFormat.register_control_format(NotBzrDirFormat)
711
formats = bzrlib.bzrdir.BzrDirFormat.known_formats()
712
for format in formats:
713
if isinstance(format, NotBzrDirFormat):
715
self.fail("No NotBzrDirFormat in %s" % formats)
717
bzrlib.bzrdir.BzrDirFormat.unregister_control_format(NotBzrDirFormat)
720
class NonLocalTests(TestCaseWithTransport):
721
"""Tests for bzrdir static behaviour on non local paths."""
724
super(NonLocalTests, self).setUp()
725
self.vfs_transport_factory = MemoryServer
727
def test_create_branch_convenience(self):
728
# outside a repo the default convenience output is a repo+branch_tree
729
format = bzrdir.format_registry.make_bzrdir('knit')
730
branch = bzrdir.BzrDir.create_branch_convenience(
731
self.get_url('foo'), format=format)
732
self.assertRaises(errors.NoWorkingTree,
733
branch.bzrdir.open_workingtree)
734
branch.bzrdir.open_repository()
736
def test_create_branch_convenience_force_tree_not_local_fails(self):
737
# outside a repo the default convenience output is a repo+branch_tree
738
format = bzrdir.format_registry.make_bzrdir('knit')
739
self.assertRaises(errors.NotLocalUrl,
740
bzrdir.BzrDir.create_branch_convenience,
744
t = get_transport(self.get_url('.'))
745
self.assertFalse(t.has('foo'))
747
def test_clone(self):
748
# clone into a nonlocal path works
749
format = bzrdir.format_registry.make_bzrdir('knit')
750
branch = bzrdir.BzrDir.create_branch_convenience('local',
752
branch.bzrdir.open_workingtree()
753
result = branch.bzrdir.clone(self.get_url('remote'))
754
self.assertRaises(errors.NoWorkingTree,
755
result.open_workingtree)
757
result.open_repository()
759
def test_checkout_metadir(self):
760
# checkout_metadir has reasonable working tree format even when no
761
# working tree is present
762
self.make_branch('branch-knit2', format='dirstate-with-subtree')
763
my_bzrdir = bzrdir.BzrDir.open(self.get_url('branch-knit2'))
764
checkout_format = my_bzrdir.checkout_metadir()
765
self.assertIsInstance(checkout_format.workingtree_format,
766
workingtree.WorkingTreeFormat3)