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.transport_server = 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.transport_server == 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
self.make_branch('topdir/foo')
458
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
460
self.assertIs(tree, None)
461
self.assertEqual(os.path.realpath('topdir/foo'),
462
local_branch_path(branch))
463
self.assertEqual('', relpath)
465
def test_open_from_transport(self):
466
# transport pointing at bzrdir should give a bzrdir with root transport
467
# set to the given transport
468
control = bzrdir.BzrDir.create(self.get_url())
469
transport = get_transport(self.get_url())
470
opened_bzrdir = bzrdir.BzrDir.open_from_transport(transport)
471
self.assertEqual(transport.base, opened_bzrdir.root_transport.base)
472
self.assertIsInstance(opened_bzrdir, bzrdir.BzrDir)
474
def test_open_from_transport_no_bzrdir(self):
475
transport = get_transport(self.get_url())
476
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
479
def test_open_from_transport_bzrdir_in_parent(self):
480
control = bzrdir.BzrDir.create(self.get_url())
481
transport = get_transport(self.get_url())
482
transport.mkdir('subdir')
483
transport = transport.clone('subdir')
484
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
487
def test_sprout_recursive(self):
488
tree = self.make_branch_and_tree('tree1', format='dirstate-with-subtree')
489
sub_tree = self.make_branch_and_tree('tree1/subtree',
490
format='dirstate-with-subtree')
491
tree.add_reference(sub_tree)
492
self.build_tree(['tree1/subtree/file'])
494
tree.commit('Initial commit')
495
tree.bzrdir.sprout('tree2')
496
self.failUnlessExists('tree2/subtree/file')
498
def test_cloning_metadir(self):
499
"""Ensure that cloning metadir is suitable"""
500
bzrdir = self.make_bzrdir('bzrdir')
501
bzrdir.cloning_metadir()
502
branch = self.make_branch('branch', format='knit')
503
format = branch.bzrdir.cloning_metadir()
504
self.assertIsInstance(format.workingtree_format,
505
workingtree.WorkingTreeFormat3)
507
def test_sprout_recursive_treeless(self):
508
tree = self.make_branch_and_tree('tree1',
509
format='dirstate-with-subtree')
510
sub_tree = self.make_branch_and_tree('tree1/subtree',
511
format='dirstate-with-subtree')
512
tree.add_reference(sub_tree)
513
self.build_tree(['tree1/subtree/file'])
515
tree.commit('Initial commit')
516
tree.bzrdir.destroy_workingtree()
517
repo = self.make_repository('repo', shared=True,
518
format='dirstate-with-subtree')
519
repo.set_make_working_trees(False)
520
tree.bzrdir.sprout('repo/tree2')
521
self.failUnlessExists('repo/tree2/subtree')
522
self.failIfExists('repo/tree2/subtree/file')
525
class TestMeta1DirFormat(TestCaseWithTransport):
526
"""Tests specific to the meta1 dir format."""
528
def test_right_base_dirs(self):
529
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
531
branch_base = t.clone('branch').base
532
self.assertEqual(branch_base, dir.get_branch_transport(None).base)
533
self.assertEqual(branch_base,
534
dir.get_branch_transport(bzrlib.branch.BzrBranchFormat5()).base)
535
repository_base = t.clone('repository').base
536
self.assertEqual(repository_base, dir.get_repository_transport(None).base)
537
self.assertEqual(repository_base,
538
dir.get_repository_transport(weaverepo.RepositoryFormat7()).base)
539
checkout_base = t.clone('checkout').base
540
self.assertEqual(checkout_base, dir.get_workingtree_transport(None).base)
541
self.assertEqual(checkout_base,
542
dir.get_workingtree_transport(workingtree.WorkingTreeFormat3()).base)
544
def test_meta1dir_uses_lockdir(self):
545
"""Meta1 format uses a LockDir to guard the whole directory, not a file."""
546
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
548
self.assertIsDirectory('branch-lock', t)
550
def test_comparison(self):
551
"""Equality and inequality behave properly.
553
Metadirs should compare equal iff they have the same repo, branch and
556
mydir = bzrdir.format_registry.make_bzrdir('knit')
557
self.assertEqual(mydir, mydir)
558
self.assertFalse(mydir != mydir)
559
otherdir = bzrdir.format_registry.make_bzrdir('knit')
560
self.assertEqual(otherdir, mydir)
561
self.assertFalse(otherdir != mydir)
562
otherdir2 = bzrdir.format_registry.make_bzrdir('dirstate-with-subtree')
563
self.assertNotEqual(otherdir2, mydir)
564
self.assertFalse(otherdir2 == mydir)
566
def test_needs_conversion_different_working_tree(self):
567
# meta1dirs need an conversion if any element is not the default.
568
old_format = bzrdir.BzrDirFormat.get_default_format()
570
new_default = bzrdir.format_registry.make_bzrdir('dirstate')
571
bzrdir.BzrDirFormat._set_default_format(new_default)
573
tree = self.make_branch_and_tree('tree', format='knit')
574
self.assertTrue(tree.bzrdir.needs_format_conversion())
576
bzrdir.BzrDirFormat._set_default_format(old_format)
579
class TestFormat5(TestCaseWithTransport):
580
"""Tests specific to the version 5 bzrdir format."""
582
def test_same_lockfiles_between_tree_repo_branch(self):
583
# this checks that only a single lockfiles instance is created
584
# for format 5 objects
585
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
586
def check_dir_components_use_same_lock(dir):
587
ctrl_1 = dir.open_repository().control_files
588
ctrl_2 = dir.open_branch().control_files
589
ctrl_3 = dir.open_workingtree()._control_files
590
self.assertTrue(ctrl_1 is ctrl_2)
591
self.assertTrue(ctrl_2 is ctrl_3)
592
check_dir_components_use_same_lock(dir)
593
# and if we open it normally.
594
dir = bzrdir.BzrDir.open(self.get_url())
595
check_dir_components_use_same_lock(dir)
597
def test_can_convert(self):
598
# format 5 dirs are convertable
599
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
600
self.assertTrue(dir.can_convert_format())
602
def test_needs_conversion(self):
603
# format 5 dirs need a conversion if they are not the default.
604
# and they start of not the default.
605
old_format = bzrdir.BzrDirFormat.get_default_format()
606
bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirFormat5())
608
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
609
self.assertFalse(dir.needs_format_conversion())
611
bzrdir.BzrDirFormat._set_default_format(old_format)
612
self.assertTrue(dir.needs_format_conversion())
615
class TestFormat6(TestCaseWithTransport):
616
"""Tests specific to the version 6 bzrdir format."""
618
def test_same_lockfiles_between_tree_repo_branch(self):
619
# this checks that only a single lockfiles instance is created
620
# for format 6 objects
621
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
622
def check_dir_components_use_same_lock(dir):
623
ctrl_1 = dir.open_repository().control_files
624
ctrl_2 = dir.open_branch().control_files
625
ctrl_3 = dir.open_workingtree()._control_files
626
self.assertTrue(ctrl_1 is ctrl_2)
627
self.assertTrue(ctrl_2 is ctrl_3)
628
check_dir_components_use_same_lock(dir)
629
# and if we open it normally.
630
dir = bzrdir.BzrDir.open(self.get_url())
631
check_dir_components_use_same_lock(dir)
633
def test_can_convert(self):
634
# format 6 dirs are convertable
635
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
636
self.assertTrue(dir.can_convert_format())
638
def test_needs_conversion(self):
639
# format 6 dirs need an conversion if they are not the default.
640
old_format = bzrdir.BzrDirFormat.get_default_format()
641
bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirMetaFormat1())
643
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
644
self.assertTrue(dir.needs_format_conversion())
646
bzrdir.BzrDirFormat._set_default_format(old_format)
649
class NotBzrDir(bzrlib.bzrdir.BzrDir):
650
"""A non .bzr based control directory."""
652
def __init__(self, transport, format):
653
self._format = format
654
self.root_transport = transport
655
self.transport = transport.clone('.not')
658
class NotBzrDirFormat(bzrlib.bzrdir.BzrDirFormat):
659
"""A test class representing any non-.bzr based disk format."""
661
def initialize_on_transport(self, transport):
662
"""Initialize a new .not dir in the base directory of a Transport."""
663
transport.mkdir('.not')
664
return self.open(transport)
666
def open(self, transport):
667
"""Open this directory."""
668
return NotBzrDir(transport, self)
671
def _known_formats(self):
672
return set([NotBzrDirFormat()])
675
def probe_transport(self, transport):
676
"""Our format is present if the transport ends in '.not/'."""
677
if transport.has('.not'):
678
return NotBzrDirFormat()
681
class TestNotBzrDir(TestCaseWithTransport):
682
"""Tests for using the bzrdir api with a non .bzr based disk format.
684
If/when one of these is in the core, we can let the implementation tests
688
def test_create_and_find_format(self):
689
# create a .notbzr dir
690
format = NotBzrDirFormat()
691
dir = format.initialize(self.get_url())
692
self.assertIsInstance(dir, NotBzrDir)
694
bzrlib.bzrdir.BzrDirFormat.register_control_format(format)
696
found = bzrlib.bzrdir.BzrDirFormat.find_format(
697
get_transport(self.get_url()))
698
self.assertIsInstance(found, NotBzrDirFormat)
700
bzrlib.bzrdir.BzrDirFormat.unregister_control_format(format)
702
def test_included_in_known_formats(self):
703
bzrlib.bzrdir.BzrDirFormat.register_control_format(NotBzrDirFormat)
705
formats = bzrlib.bzrdir.BzrDirFormat.known_formats()
706
for format in formats:
707
if isinstance(format, NotBzrDirFormat):
709
self.fail("No NotBzrDirFormat in %s" % formats)
711
bzrlib.bzrdir.BzrDirFormat.unregister_control_format(NotBzrDirFormat)
714
class NonLocalTests(TestCaseWithTransport):
715
"""Tests for bzrdir static behaviour on non local paths."""
718
super(NonLocalTests, self).setUp()
719
self.transport_server = MemoryServer
721
def test_create_branch_convenience(self):
722
# outside a repo the default convenience output is a repo+branch_tree
723
format = bzrdir.format_registry.make_bzrdir('knit')
724
branch = bzrdir.BzrDir.create_branch_convenience(
725
self.get_url('foo'), format=format)
726
self.assertRaises(errors.NoWorkingTree,
727
branch.bzrdir.open_workingtree)
728
branch.bzrdir.open_repository()
730
def test_create_branch_convenience_force_tree_not_local_fails(self):
731
# outside a repo the default convenience output is a repo+branch_tree
732
format = bzrdir.format_registry.make_bzrdir('knit')
733
self.assertRaises(errors.NotLocalUrl,
734
bzrdir.BzrDir.create_branch_convenience,
738
t = get_transport(self.get_url('.'))
739
self.assertFalse(t.has('foo'))
741
def test_clone(self):
742
# clone into a nonlocal path works
743
format = bzrdir.format_registry.make_bzrdir('knit')
744
branch = bzrdir.BzrDir.create_branch_convenience('local',
746
branch.bzrdir.open_workingtree()
747
result = branch.bzrdir.clone(self.get_url('remote'))
748
self.assertRaises(errors.NoWorkingTree,
749
result.open_workingtree)
751
result.open_repository()
753
def test_checkout_metadir(self):
754
# checkout_metadir has reasonable working tree format even when no
755
# working tree is present
756
self.make_branch('branch-knit2', format='dirstate-with-subtree')
757
my_bzrdir = bzrdir.BzrDir.open(self.get_url('branch-knit2'))
758
checkout_format = my_bzrdir.checkout_metadir()
759
self.assertIsInstance(checkout_format.workingtree_format,
760
workingtree.WorkingTreeFormat3)
763
class TestRemoteSFTP(test_sftp_transport.TestCaseWithSFTPServer):
765
def test_open_containing_tree_or_branch(self):
766
tree = self.make_branch_and_tree('tree')
767
bzrdir.BzrDir.open_containing_tree_or_branch(self.get_url('tree'))