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.symbol_versioning import (
42
from bzrlib.tests import (
44
TestCaseWithTransport,
47
from bzrlib.tests.HttpServer import HttpServer
48
from bzrlib.tests.HTTPTestUtil import (
49
TestCaseWithTwoWebservers,
50
HTTPServerRedirecting,
52
from bzrlib.tests.test_http import TestWithTransport_pycurl
53
from bzrlib.transport import get_transport
54
from bzrlib.transport.http._urllib import HttpTransport_urllib
55
from bzrlib.transport.memory import MemoryServer
56
from bzrlib.repofmt import knitrepo, weaverepo
59
class TestDefaultFormat(TestCase):
61
def test_get_set_default_format(self):
62
old_format = bzrdir.BzrDirFormat.get_default_format()
63
# default is BzrDirFormat6
64
self.failUnless(isinstance(old_format, bzrdir.BzrDirMetaFormat1))
65
self.applyDeprecated(symbol_versioning.zero_fourteen,
66
bzrdir.BzrDirFormat.set_default_format,
68
# creating a bzr dir should now create an instrumented dir.
70
result = bzrdir.BzrDir.create('memory:///')
71
self.failUnless(isinstance(result, SampleBzrDir))
73
self.applyDeprecated(symbol_versioning.zero_fourteen,
74
bzrdir.BzrDirFormat.set_default_format, old_format)
75
self.assertEqual(old_format, bzrdir.BzrDirFormat.get_default_format())
78
class TestFormatRegistry(TestCase):
80
def make_format_registry(self):
81
my_format_registry = bzrdir.BzrDirFormatRegistry()
82
my_format_registry.register('weave', bzrdir.BzrDirFormat6,
83
'Pre-0.8 format. Slower and does not support checkouts or shared'
84
' repositories', deprecated=True)
85
my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir',
86
'BzrDirFormat6', 'Format registered lazily', deprecated=True)
87
my_format_registry.register_metadir('knit',
88
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
91
my_format_registry.set_default('knit')
92
my_format_registry.register_metadir(
94
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
95
'Experimental successor to knit. Use at your own risk.',
96
branch_format='bzrlib.branch.BzrBranchFormat6')
97
my_format_registry.register_metadir(
99
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
100
'Experimental successor to knit. Use at your own risk.',
101
branch_format='bzrlib.branch.BzrBranchFormat6', hidden=True)
102
my_format_registry.register('hiddenweave', bzrdir.BzrDirFormat6,
103
'Pre-0.8 format. Slower and does not support checkouts or shared'
104
' repositories', hidden=True)
105
my_format_registry.register_lazy('hiddenlazy', 'bzrlib.bzrdir',
106
'BzrDirFormat6', 'Format registered lazily', deprecated=True,
108
return my_format_registry
110
def test_format_registry(self):
111
my_format_registry = self.make_format_registry()
112
my_bzrdir = my_format_registry.make_bzrdir('lazy')
113
self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
114
my_bzrdir = my_format_registry.make_bzrdir('weave')
115
self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
116
my_bzrdir = my_format_registry.make_bzrdir('default')
117
self.assertIsInstance(my_bzrdir.repository_format,
118
knitrepo.RepositoryFormatKnit1)
119
my_bzrdir = my_format_registry.make_bzrdir('knit')
120
self.assertIsInstance(my_bzrdir.repository_format,
121
knitrepo.RepositoryFormatKnit1)
122
my_bzrdir = my_format_registry.make_bzrdir('branch6')
123
self.assertIsInstance(my_bzrdir.get_branch_format(),
124
bzrlib.branch.BzrBranchFormat6)
126
def test_get_help(self):
127
my_format_registry = self.make_format_registry()
128
self.assertEqual('Format registered lazily',
129
my_format_registry.get_help('lazy'))
130
self.assertEqual('Format using knits',
131
my_format_registry.get_help('knit'))
132
self.assertEqual('Format using knits',
133
my_format_registry.get_help('default'))
134
self.assertEqual('Pre-0.8 format. Slower and does not support'
135
' checkouts or shared repositories',
136
my_format_registry.get_help('weave'))
138
def test_help_topic(self):
139
topics = help_topics.HelpTopicRegistry()
140
topics.register('formats', self.make_format_registry().help_topic,
142
topic = topics.get_detail('formats')
143
new, deprecated = topic.split('Deprecated formats')
144
self.assertContainsRe(new, 'These formats can be used')
145
self.assertContainsRe(new,
146
':knit:\n \(native\) \(default\) Format using knits\n')
147
self.assertContainsRe(deprecated,
148
':lazy:\n \(native\) Format registered lazily\n')
149
self.assertNotContainsRe(new, 'hidden')
151
def test_set_default_repository(self):
152
default_factory = bzrdir.format_registry.get('default')
153
old_default = [k for k, v in bzrdir.format_registry.iteritems()
154
if v == default_factory and k != 'default'][0]
155
bzrdir.format_registry.set_default_repository('dirstate-with-subtree')
157
self.assertIs(bzrdir.format_registry.get('dirstate-with-subtree'),
158
bzrdir.format_registry.get('default'))
160
repository.RepositoryFormat.get_default_format().__class__,
161
knitrepo.RepositoryFormatKnit3)
163
bzrdir.format_registry.set_default_repository(old_default)
166
class SampleBranch(bzrlib.branch.Branch):
167
"""A dummy branch for guess what, dummy use."""
169
def __init__(self, dir):
173
class SampleBzrDir(bzrdir.BzrDir):
174
"""A sample BzrDir implementation to allow testing static methods."""
176
def create_repository(self, shared=False):
177
"""See BzrDir.create_repository."""
178
return "A repository"
180
def open_repository(self):
181
"""See BzrDir.open_repository."""
182
return "A repository"
184
def create_branch(self):
185
"""See BzrDir.create_branch."""
186
return SampleBranch(self)
188
def create_workingtree(self):
189
"""See BzrDir.create_workingtree."""
193
class SampleBzrDirFormat(bzrdir.BzrDirFormat):
196
this format is initializable, unsupported to aid in testing the
197
open and open_downlevel routines.
200
def get_format_string(self):
201
"""See BzrDirFormat.get_format_string()."""
202
return "Sample .bzr dir format."
204
def initialize_on_transport(self, t):
205
"""Create a bzr dir."""
207
t.put_bytes('.bzr/branch-format', self.get_format_string())
208
return SampleBzrDir(t, self)
210
def is_supported(self):
213
def open(self, transport, _found=None):
214
return "opened branch."
217
class TestBzrDirFormat(TestCaseWithTransport):
218
"""Tests for the BzrDirFormat facility."""
220
def test_find_format(self):
221
# is the right format object found for a branch?
222
# create a branch with a few known format objects.
223
# this is not quite the same as
224
t = get_transport(self.get_url())
225
self.build_tree(["foo/", "bar/"], transport=t)
226
def check_format(format, url):
227
format.initialize(url)
228
t = get_transport(url)
229
found_format = bzrdir.BzrDirFormat.find_format(t)
230
self.failUnless(isinstance(found_format, format.__class__))
231
check_format(bzrdir.BzrDirFormat5(), "foo")
232
check_format(bzrdir.BzrDirFormat6(), "bar")
234
def test_find_format_nothing_there(self):
235
self.assertRaises(NotBranchError,
236
bzrdir.BzrDirFormat.find_format,
239
def test_find_format_unknown_format(self):
240
t = get_transport(self.get_url())
242
t.put_bytes('.bzr/branch-format', '')
243
self.assertRaises(UnknownFormatError,
244
bzrdir.BzrDirFormat.find_format,
247
def test_register_unregister_format(self):
248
format = SampleBzrDirFormat()
251
format.initialize(url)
252
# register a format for it.
253
bzrdir.BzrDirFormat.register_format(format)
254
# which bzrdir.Open will refuse (not supported)
255
self.assertRaises(UnsupportedFormatError, bzrdir.BzrDir.open, url)
256
# which bzrdir.open_containing will refuse (not supported)
257
self.assertRaises(UnsupportedFormatError, bzrdir.BzrDir.open_containing, url)
258
# but open_downlevel will work
259
t = get_transport(url)
260
self.assertEqual(format.open(t), bzrdir.BzrDir.open_unsupported(url))
261
# unregister the format
262
bzrdir.BzrDirFormat.unregister_format(format)
263
# now open_downlevel should fail too.
264
self.assertRaises(UnknownFormatError, bzrdir.BzrDir.open_unsupported, url)
266
def test_create_repository_deprecated(self):
267
# new interface is to make the bzrdir, then a repository within that.
268
format = SampleBzrDirFormat()
269
repo = self.applyDeprecated(zero_ninetyone,
270
bzrdir.BzrDir.create_repository,
271
self.get_url(), format=format)
272
self.assertEqual('A repository', repo)
274
def test_create_repository_shared(self):
275
# new interface is to make the bzrdir, then a repository within that.
276
old_format = bzrdir.BzrDirFormat.get_default_format()
277
repo = self.applyDeprecated(zero_ninetyone,
278
bzrdir.BzrDir.create_repository,
280
self.assertTrue(repo.is_shared())
282
def test_create_repository_nonshared(self):
283
# new interface is to make the bzrdir, then a repository within that.
284
old_format = bzrdir.BzrDirFormat.get_default_format()
285
repo = self.applyDeprecated(zero_ninetyone,
286
bzrdir.BzrDir.create_repository,
288
self.assertFalse(repo.is_shared())
290
def test_create_repository_under_shared(self):
291
# an explicit create_repository always does so.
292
# we trust the format is right from the 'create_repository test'
293
# new interface is to make the bzrdir, then a repository within that.
294
format = bzrdir.format_registry.make_bzrdir('knit')
295
self.make_repository('.', shared=True, format=format)
296
repo = self.applyDeprecated(zero_ninetyone,
297
bzrdir.BzrDir.create_repository,
298
self.get_url('child'),
300
self.assertTrue(isinstance(repo, repository.Repository))
301
self.assertTrue(repo.bzrdir.root_transport.base.endswith('child/'))
303
def test_create_branch_and_repo_uses_default(self):
304
format = SampleBzrDirFormat()
305
branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url(),
307
self.assertTrue(isinstance(branch, SampleBranch))
309
def test_create_branch_and_repo_under_shared(self):
310
# creating a branch and repo in a shared repo uses the
312
format = bzrdir.format_registry.make_bzrdir('knit')
313
self.make_repository('.', shared=True, format=format)
314
branch = bzrdir.BzrDir.create_branch_and_repo(
315
self.get_url('child'), format=format)
316
self.assertRaises(errors.NoRepositoryPresent,
317
branch.bzrdir.open_repository)
319
def test_create_branch_and_repo_under_shared_force_new(self):
320
# creating a branch and repo in a shared repo can be forced to
322
format = bzrdir.format_registry.make_bzrdir('knit')
323
self.make_repository('.', shared=True, format=format)
324
branch = bzrdir.BzrDir.create_branch_and_repo(self.get_url('child'),
327
branch.bzrdir.open_repository()
329
def test_create_standalone_working_tree(self):
330
format = SampleBzrDirFormat()
331
# note this is deliberately readonly, as this failure should
332
# occur before any writes.
333
self.assertRaises(errors.NotLocalUrl,
334
bzrdir.BzrDir.create_standalone_workingtree,
335
self.get_readonly_url(), format=format)
336
tree = bzrdir.BzrDir.create_standalone_workingtree('.',
338
self.assertEqual('A tree', tree)
340
def test_create_standalone_working_tree_under_shared_repo(self):
341
# create standalone working tree always makes a repo.
342
format = bzrdir.format_registry.make_bzrdir('knit')
343
self.make_repository('.', shared=True, format=format)
344
# note this is deliberately readonly, as this failure should
345
# occur before any writes.
346
self.assertRaises(errors.NotLocalUrl,
347
bzrdir.BzrDir.create_standalone_workingtree,
348
self.get_readonly_url('child'), format=format)
349
tree = bzrdir.BzrDir.create_standalone_workingtree('child',
351
tree.bzrdir.open_repository()
353
def test_create_branch_convenience(self):
354
# outside a repo the default convenience output is a repo+branch_tree
355
format = bzrdir.format_registry.make_bzrdir('knit')
356
branch = bzrdir.BzrDir.create_branch_convenience('.', format=format)
357
branch.bzrdir.open_workingtree()
358
branch.bzrdir.open_repository()
360
def test_create_branch_convenience_possible_transports(self):
361
"""Check that the optional 'possible_transports' is recognized"""
362
format = bzrdir.format_registry.make_bzrdir('knit')
363
t = self.get_transport()
364
branch = bzrdir.BzrDir.create_branch_convenience(
365
'.', format=format, possible_transports=[t])
366
branch.bzrdir.open_workingtree()
367
branch.bzrdir.open_repository()
369
def test_create_branch_convenience_root(self):
370
"""Creating a branch at the root of a fs should work."""
371
self.vfs_transport_factory = MemoryServer
372
# outside a repo the default convenience output is a repo+branch_tree
373
format = bzrdir.format_registry.make_bzrdir('knit')
374
branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(),
376
self.assertRaises(errors.NoWorkingTree,
377
branch.bzrdir.open_workingtree)
378
branch.bzrdir.open_repository()
380
def test_create_branch_convenience_under_shared_repo(self):
381
# inside a repo the default convenience output is a branch+ follow the
383
format = bzrdir.format_registry.make_bzrdir('knit')
384
self.make_repository('.', shared=True, format=format)
385
branch = bzrdir.BzrDir.create_branch_convenience('child',
387
branch.bzrdir.open_workingtree()
388
self.assertRaises(errors.NoRepositoryPresent,
389
branch.bzrdir.open_repository)
391
def test_create_branch_convenience_under_shared_repo_force_no_tree(self):
392
# inside a repo the default convenience output is a branch+ follow the
393
# repo tree policy but we can override that
394
format = bzrdir.format_registry.make_bzrdir('knit')
395
self.make_repository('.', shared=True, format=format)
396
branch = bzrdir.BzrDir.create_branch_convenience('child',
397
force_new_tree=False, format=format)
398
self.assertRaises(errors.NoWorkingTree,
399
branch.bzrdir.open_workingtree)
400
self.assertRaises(errors.NoRepositoryPresent,
401
branch.bzrdir.open_repository)
403
def test_create_branch_convenience_under_shared_repo_no_tree_policy(self):
404
# inside a repo the default convenience output is a branch+ follow the
406
format = bzrdir.format_registry.make_bzrdir('knit')
407
repo = self.make_repository('.', shared=True, format=format)
408
repo.set_make_working_trees(False)
409
branch = bzrdir.BzrDir.create_branch_convenience('child',
411
self.assertRaises(errors.NoWorkingTree,
412
branch.bzrdir.open_workingtree)
413
self.assertRaises(errors.NoRepositoryPresent,
414
branch.bzrdir.open_repository)
416
def test_create_branch_convenience_under_shared_repo_no_tree_policy_force_tree(self):
417
# inside a repo the default convenience output is a branch+ follow the
418
# repo tree policy but we can override that
419
format = bzrdir.format_registry.make_bzrdir('knit')
420
repo = self.make_repository('.', shared=True, format=format)
421
repo.set_make_working_trees(False)
422
branch = bzrdir.BzrDir.create_branch_convenience('child',
423
force_new_tree=True, format=format)
424
branch.bzrdir.open_workingtree()
425
self.assertRaises(errors.NoRepositoryPresent,
426
branch.bzrdir.open_repository)
428
def test_create_branch_convenience_under_shared_repo_force_new_repo(self):
429
# inside a repo the default convenience output is overridable to give
431
format = bzrdir.format_registry.make_bzrdir('knit')
432
self.make_repository('.', shared=True, format=format)
433
branch = bzrdir.BzrDir.create_branch_convenience('child',
434
force_new_repo=True, format=format)
435
branch.bzrdir.open_repository()
436
branch.bzrdir.open_workingtree()
439
class ChrootedTests(TestCaseWithTransport):
440
"""A support class that provides readonly urls outside the local namespace.
442
This is done by checking if self.transport_server is a MemoryServer. if it
443
is then we are chrooted already, if it is not then an HttpServer is used
448
super(ChrootedTests, self).setUp()
449
if not self.vfs_transport_factory == MemoryServer:
450
self.transport_readonly_server = HttpServer
452
def test_open_containing(self):
453
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing,
454
self.get_readonly_url(''))
455
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing,
456
self.get_readonly_url('g/p/q'))
457
control = bzrdir.BzrDir.create(self.get_url())
458
branch, relpath = bzrdir.BzrDir.open_containing(self.get_readonly_url(''))
459
self.assertEqual('', relpath)
460
branch, relpath = bzrdir.BzrDir.open_containing(self.get_readonly_url('g/p/q'))
461
self.assertEqual('g/p/q', relpath)
463
def test_open_containing_from_transport(self):
464
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
465
get_transport(self.get_readonly_url('')))
466
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_containing_from_transport,
467
get_transport(self.get_readonly_url('g/p/q')))
468
control = bzrdir.BzrDir.create(self.get_url())
469
branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
470
get_transport(self.get_readonly_url('')))
471
self.assertEqual('', relpath)
472
branch, relpath = bzrdir.BzrDir.open_containing_from_transport(
473
get_transport(self.get_readonly_url('g/p/q')))
474
self.assertEqual('g/p/q', relpath)
476
def test_open_containing_tree_or_branch(self):
477
def local_branch_path(branch):
478
return os.path.realpath(
479
urlutils.local_path_from_url(branch.base))
481
self.make_branch_and_tree('topdir')
482
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
484
self.assertEqual(os.path.realpath('topdir'),
485
os.path.realpath(tree.basedir))
486
self.assertEqual(os.path.realpath('topdir'),
487
local_branch_path(branch))
488
self.assertIs(tree.bzrdir, branch.bzrdir)
489
self.assertEqual('foo', relpath)
490
# opening from non-local should not return the tree
491
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
492
self.get_readonly_url('topdir/foo'))
493
self.assertEqual(None, tree)
494
self.assertEqual('foo', relpath)
496
self.make_branch('topdir/foo')
497
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
499
self.assertIs(tree, None)
500
self.assertEqual(os.path.realpath('topdir/foo'),
501
local_branch_path(branch))
502
self.assertEqual('', relpath)
504
def test_open_from_transport(self):
505
# transport pointing at bzrdir should give a bzrdir with root transport
506
# set to the given transport
507
control = bzrdir.BzrDir.create(self.get_url())
508
transport = get_transport(self.get_url())
509
opened_bzrdir = bzrdir.BzrDir.open_from_transport(transport)
510
self.assertEqual(transport.base, opened_bzrdir.root_transport.base)
511
self.assertIsInstance(opened_bzrdir, bzrdir.BzrDir)
513
def test_open_from_transport_no_bzrdir(self):
514
transport = get_transport(self.get_url())
515
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
518
def test_open_from_transport_bzrdir_in_parent(self):
519
control = bzrdir.BzrDir.create(self.get_url())
520
transport = get_transport(self.get_url())
521
transport.mkdir('subdir')
522
transport = transport.clone('subdir')
523
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
526
def test_sprout_recursive(self):
527
tree = self.make_branch_and_tree('tree1', format='dirstate-with-subtree')
528
sub_tree = self.make_branch_and_tree('tree1/subtree',
529
format='dirstate-with-subtree')
530
tree.add_reference(sub_tree)
531
self.build_tree(['tree1/subtree/file'])
533
tree.commit('Initial commit')
534
tree.bzrdir.sprout('tree2')
535
self.failUnlessExists('tree2/subtree/file')
537
def test_cloning_metadir(self):
538
"""Ensure that cloning metadir is suitable"""
539
bzrdir = self.make_bzrdir('bzrdir')
540
bzrdir.cloning_metadir()
541
branch = self.make_branch('branch', format='knit')
542
format = branch.bzrdir.cloning_metadir()
543
self.assertIsInstance(format.workingtree_format,
544
workingtree.WorkingTreeFormat3)
546
def test_sprout_recursive_treeless(self):
547
tree = self.make_branch_and_tree('tree1',
548
format='dirstate-with-subtree')
549
sub_tree = self.make_branch_and_tree('tree1/subtree',
550
format='dirstate-with-subtree')
551
tree.add_reference(sub_tree)
552
self.build_tree(['tree1/subtree/file'])
554
tree.commit('Initial commit')
555
tree.bzrdir.destroy_workingtree()
556
repo = self.make_repository('repo', shared=True,
557
format='dirstate-with-subtree')
558
repo.set_make_working_trees(False)
559
tree.bzrdir.sprout('repo/tree2')
560
self.failUnlessExists('repo/tree2/subtree')
561
self.failIfExists('repo/tree2/subtree/file')
564
class TestMeta1DirFormat(TestCaseWithTransport):
565
"""Tests specific to the meta1 dir format."""
567
def test_right_base_dirs(self):
568
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
570
branch_base = t.clone('branch').base
571
self.assertEqual(branch_base, dir.get_branch_transport(None).base)
572
self.assertEqual(branch_base,
573
dir.get_branch_transport(bzrlib.branch.BzrBranchFormat5()).base)
574
repository_base = t.clone('repository').base
575
self.assertEqual(repository_base, dir.get_repository_transport(None).base)
576
self.assertEqual(repository_base,
577
dir.get_repository_transport(weaverepo.RepositoryFormat7()).base)
578
checkout_base = t.clone('checkout').base
579
self.assertEqual(checkout_base, dir.get_workingtree_transport(None).base)
580
self.assertEqual(checkout_base,
581
dir.get_workingtree_transport(workingtree.WorkingTreeFormat3()).base)
583
def test_meta1dir_uses_lockdir(self):
584
"""Meta1 format uses a LockDir to guard the whole directory, not a file."""
585
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
587
self.assertIsDirectory('branch-lock', t)
589
def test_comparison(self):
590
"""Equality and inequality behave properly.
592
Metadirs should compare equal iff they have the same repo, branch and
595
mydir = bzrdir.format_registry.make_bzrdir('knit')
596
self.assertEqual(mydir, mydir)
597
self.assertFalse(mydir != mydir)
598
otherdir = bzrdir.format_registry.make_bzrdir('knit')
599
self.assertEqual(otherdir, mydir)
600
self.assertFalse(otherdir != mydir)
601
otherdir2 = bzrdir.format_registry.make_bzrdir('dirstate-with-subtree')
602
self.assertNotEqual(otherdir2, mydir)
603
self.assertFalse(otherdir2 == mydir)
605
def test_needs_conversion_different_working_tree(self):
606
# meta1dirs need an conversion if any element is not the default.
607
old_format = bzrdir.BzrDirFormat.get_default_format()
609
new_default = bzrdir.format_registry.make_bzrdir('dirstate')
610
bzrdir.BzrDirFormat._set_default_format(new_default)
612
tree = self.make_branch_and_tree('tree', format='knit')
613
self.assertTrue(tree.bzrdir.needs_format_conversion())
615
bzrdir.BzrDirFormat._set_default_format(old_format)
618
class TestFormat5(TestCaseWithTransport):
619
"""Tests specific to the version 5 bzrdir format."""
621
def test_same_lockfiles_between_tree_repo_branch(self):
622
# this checks that only a single lockfiles instance is created
623
# for format 5 objects
624
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
625
def check_dir_components_use_same_lock(dir):
626
ctrl_1 = dir.open_repository().control_files
627
ctrl_2 = dir.open_branch().control_files
628
ctrl_3 = dir.open_workingtree()._control_files
629
self.assertTrue(ctrl_1 is ctrl_2)
630
self.assertTrue(ctrl_2 is ctrl_3)
631
check_dir_components_use_same_lock(dir)
632
# and if we open it normally.
633
dir = bzrdir.BzrDir.open(self.get_url())
634
check_dir_components_use_same_lock(dir)
636
def test_can_convert(self):
637
# format 5 dirs are convertable
638
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
639
self.assertTrue(dir.can_convert_format())
641
def test_needs_conversion(self):
642
# format 5 dirs need a conversion if they are not the default.
643
# and they start of not the default.
644
old_format = bzrdir.BzrDirFormat.get_default_format()
645
bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirFormat5())
647
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
648
self.assertFalse(dir.needs_format_conversion())
650
bzrdir.BzrDirFormat._set_default_format(old_format)
651
self.assertTrue(dir.needs_format_conversion())
654
class TestFormat6(TestCaseWithTransport):
655
"""Tests specific to the version 6 bzrdir format."""
657
def test_same_lockfiles_between_tree_repo_branch(self):
658
# this checks that only a single lockfiles instance is created
659
# for format 6 objects
660
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
661
def check_dir_components_use_same_lock(dir):
662
ctrl_1 = dir.open_repository().control_files
663
ctrl_2 = dir.open_branch().control_files
664
ctrl_3 = dir.open_workingtree()._control_files
665
self.assertTrue(ctrl_1 is ctrl_2)
666
self.assertTrue(ctrl_2 is ctrl_3)
667
check_dir_components_use_same_lock(dir)
668
# and if we open it normally.
669
dir = bzrdir.BzrDir.open(self.get_url())
670
check_dir_components_use_same_lock(dir)
672
def test_can_convert(self):
673
# format 6 dirs are convertable
674
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
675
self.assertTrue(dir.can_convert_format())
677
def test_needs_conversion(self):
678
# format 6 dirs need an conversion if they are not the default.
679
old_format = bzrdir.BzrDirFormat.get_default_format()
680
bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirMetaFormat1())
682
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
683
self.assertTrue(dir.needs_format_conversion())
685
bzrdir.BzrDirFormat._set_default_format(old_format)
688
class NotBzrDir(bzrlib.bzrdir.BzrDir):
689
"""A non .bzr based control directory."""
691
def __init__(self, transport, format):
692
self._format = format
693
self.root_transport = transport
694
self.transport = transport.clone('.not')
697
class NotBzrDirFormat(bzrlib.bzrdir.BzrDirFormat):
698
"""A test class representing any non-.bzr based disk format."""
700
def initialize_on_transport(self, transport):
701
"""Initialize a new .not dir in the base directory of a Transport."""
702
transport.mkdir('.not')
703
return self.open(transport)
705
def open(self, transport):
706
"""Open this directory."""
707
return NotBzrDir(transport, self)
710
def _known_formats(self):
711
return set([NotBzrDirFormat()])
714
def probe_transport(self, transport):
715
"""Our format is present if the transport ends in '.not/'."""
716
if transport.has('.not'):
717
return NotBzrDirFormat()
720
class TestNotBzrDir(TestCaseWithTransport):
721
"""Tests for using the bzrdir api with a non .bzr based disk format.
723
If/when one of these is in the core, we can let the implementation tests
727
def test_create_and_find_format(self):
728
# create a .notbzr dir
729
format = NotBzrDirFormat()
730
dir = format.initialize(self.get_url())
731
self.assertIsInstance(dir, NotBzrDir)
733
bzrlib.bzrdir.BzrDirFormat.register_control_format(format)
735
found = bzrlib.bzrdir.BzrDirFormat.find_format(
736
get_transport(self.get_url()))
737
self.assertIsInstance(found, NotBzrDirFormat)
739
bzrlib.bzrdir.BzrDirFormat.unregister_control_format(format)
741
def test_included_in_known_formats(self):
742
bzrlib.bzrdir.BzrDirFormat.register_control_format(NotBzrDirFormat)
744
formats = bzrlib.bzrdir.BzrDirFormat.known_formats()
745
for format in formats:
746
if isinstance(format, NotBzrDirFormat):
748
self.fail("No NotBzrDirFormat in %s" % formats)
750
bzrlib.bzrdir.BzrDirFormat.unregister_control_format(NotBzrDirFormat)
753
class NonLocalTests(TestCaseWithTransport):
754
"""Tests for bzrdir static behaviour on non local paths."""
757
super(NonLocalTests, self).setUp()
758
self.vfs_transport_factory = MemoryServer
760
def test_create_branch_convenience(self):
761
# outside a repo the default convenience output is a repo+branch_tree
762
format = bzrdir.format_registry.make_bzrdir('knit')
763
branch = bzrdir.BzrDir.create_branch_convenience(
764
self.get_url('foo'), format=format)
765
self.assertRaises(errors.NoWorkingTree,
766
branch.bzrdir.open_workingtree)
767
branch.bzrdir.open_repository()
769
def test_create_branch_convenience_force_tree_not_local_fails(self):
770
# outside a repo the default convenience output is a repo+branch_tree
771
format = bzrdir.format_registry.make_bzrdir('knit')
772
self.assertRaises(errors.NotLocalUrl,
773
bzrdir.BzrDir.create_branch_convenience,
777
t = get_transport(self.get_url('.'))
778
self.assertFalse(t.has('foo'))
780
def test_clone(self):
781
# clone into a nonlocal path works
782
format = bzrdir.format_registry.make_bzrdir('knit')
783
branch = bzrdir.BzrDir.create_branch_convenience('local',
785
branch.bzrdir.open_workingtree()
786
result = branch.bzrdir.clone(self.get_url('remote'))
787
self.assertRaises(errors.NoWorkingTree,
788
result.open_workingtree)
790
result.open_repository()
792
def test_checkout_metadir(self):
793
# checkout_metadir has reasonable working tree format even when no
794
# working tree is present
795
self.make_branch('branch-knit2', format='dirstate-with-subtree')
796
my_bzrdir = bzrdir.BzrDir.open(self.get_url('branch-knit2'))
797
checkout_format = my_bzrdir.checkout_metadir()
798
self.assertIsInstance(checkout_format.workingtree_format,
799
workingtree.WorkingTreeFormat3)
802
class TestHTTPRedirectionLoop(object):
803
"""Test redirection loop between two http servers.
805
This MUST be used by daughter classes that also inherit from
806
TestCaseWithTwoWebservers.
808
We can't inherit directly from TestCaseWithTwoWebservers or the
809
test framework will try to create an instance which cannot
810
run, its implementation being incomplete.
813
# Should be defined by daughter classes to ensure redirection
814
# still use the same transport implementation (not currently
815
# enforced as it's a bit tricky to get right (see the FIXME
816
# in BzrDir.open_from_transport for the unique use case so
820
def create_transport_readonly_server(self):
821
return HTTPServerRedirecting()
823
def create_transport_secondary_server(self):
824
return HTTPServerRedirecting()
827
# Both servers redirect to each server creating a loop
828
super(TestHTTPRedirectionLoop, self).setUp()
829
# The redirections will point to the new server
830
self.new_server = self.get_readonly_server()
831
# The requests to the old server will be redirected
832
self.old_server = self.get_secondary_server()
833
# Configure the redirections
834
self.old_server.redirect_to(self.new_server.host, self.new_server.port)
835
self.new_server.redirect_to(self.old_server.host, self.old_server.port)
837
def _qualified_url(self, host, port):
838
return 'http+%s://%s:%s' % (self._qualifier, host, port)
841
# Starting from either server should loop
842
old_url = self._qualified_url(self.old_server.host,
843
self.old_server.port)
844
oldt = self._transport(old_url)
845
self.assertRaises(errors.NotBranchError,
846
bzrdir.BzrDir.open_from_transport, oldt)
847
new_url = self._qualified_url(self.new_server.host,
848
self.new_server.port)
849
newt = self._transport(new_url)
850
self.assertRaises(errors.NotBranchError,
851
bzrdir.BzrDir.open_from_transport, newt)
854
class TestHTTPRedirections_urllib(TestHTTPRedirectionLoop,
855
TestCaseWithTwoWebservers):
856
"""Tests redirections for urllib implementation"""
858
_qualifier = 'urllib'
859
_transport = HttpTransport_urllib
863
class TestHTTPRedirections_pycurl(TestWithTransport_pycurl,
864
TestHTTPRedirectionLoop,
865
TestCaseWithTwoWebservers):
866
"""Tests redirections for pycurl implementation"""
868
_qualifier = 'pycurl'