13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
"""Tests for the BzrDir facility and any format specific tests.
19
For interface contract tests, see tests/per_bzr_dir.
19
For interface contract tests, see tests/bzr_dir_implementations.
24
from StringIO import StringIO
45
46
TestCaseWithMemoryTransport,
46
47
TestCaseWithTransport,
49
51
from bzrlib.tests import(
53
55
from bzrlib.tests.test_http import TestWithTransport_pycurl
54
from bzrlib.transport import (
56
from bzrlib.transport import get_transport
58
57
from bzrlib.transport.http._urllib import HttpTransport_urllib
58
from bzrlib.transport.memory import MemoryServer
59
59
from bzrlib.transport.nosmart import NoSmartTransportDecorator
60
60
from bzrlib.transport.readonly import ReadonlyTransportDecorator
61
from bzrlib.repofmt import knitrepo, weaverepo, pack_repo
61
from bzrlib.repofmt import knitrepo, weaverepo
64
64
class TestDefaultFormat(TestCase):
84
84
my_format_registry.register('weave', bzrdir.BzrDirFormat6,
85
85
'Pre-0.8 format. Slower and does not support checkouts or shared'
86
86
' repositories', deprecated=True)
87
my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir',
87
my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir',
88
88
'BzrDirFormat6', 'Format registered lazily', deprecated=True)
89
89
my_format_registry.register_metadir('knit',
90
90
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
117
117
my_bzrdir = my_format_registry.make_bzrdir('weave')
118
118
self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
119
119
my_bzrdir = my_format_registry.make_bzrdir('default')
120
self.assertIsInstance(my_bzrdir.repository_format,
120
self.assertIsInstance(my_bzrdir.repository_format,
121
121
knitrepo.RepositoryFormatKnit1)
122
122
my_bzrdir = my_format_registry.make_bzrdir('knit')
123
self.assertIsInstance(my_bzrdir.repository_format,
123
self.assertIsInstance(my_bzrdir.repository_format,
124
124
knitrepo.RepositoryFormatKnit1)
125
125
my_bzrdir = my_format_registry.make_bzrdir('branch6')
126
126
self.assertIsInstance(my_bzrdir.get_branch_format(),
130
130
my_format_registry = self.make_format_registry()
131
131
self.assertEqual('Format registered lazily',
132
132
my_format_registry.get_help('lazy'))
133
self.assertEqual('Format using knits',
133
self.assertEqual('Format using knits',
134
134
my_format_registry.get_help('knit'))
135
self.assertEqual('Format using knits',
135
self.assertEqual('Format using knits',
136
136
my_format_registry.get_help('default'))
137
137
self.assertEqual('Pre-0.8 format. Slower and does not support'
138
' checkouts or shared repositories',
138
' checkouts or shared repositories',
139
139
my_format_registry.get_help('weave'))
141
141
def test_help_topic(self):
142
142
topics = help_topics.HelpTopicRegistry()
143
143
registry = self.make_format_registry()
144
topics.register('current-formats', registry.help_topic,
144
topics.register('current-formats', registry.help_topic,
145
145
'Current formats')
146
topics.register('other-formats', registry.help_topic,
146
topics.register('other-formats', registry.help_topic,
148
148
new = topics.get_detail('current-formats')
149
149
rest = topics.get_detail('other-formats')
150
150
experimental, deprecated = rest.split('Deprecated formats')
151
self.assertContainsRe(new, 'formats-help')
152
self.assertContainsRe(new,
151
self.assertContainsRe(new, 'bzr help formats')
152
self.assertContainsRe(new,
153
153
':knit:\n \(native\) \(default\) Format using knits\n')
154
self.assertContainsRe(experimental,
154
self.assertContainsRe(experimental,
155
155
':branch6:\n \(native\) Experimental successor to knit')
156
self.assertContainsRe(deprecated,
156
self.assertContainsRe(deprecated,
157
157
':lazy:\n \(native\) Format registered lazily\n')
158
158
self.assertNotContainsRe(new, 'hidden')
207
207
"""See BzrDir.open_repository."""
208
208
return SampleRepository(self)
210
def create_branch(self, name=None):
210
def create_branch(self):
211
211
"""See BzrDir.create_branch."""
213
raise NoColocatedBranchSupport(self)
214
212
return SampleBranch(self)
216
214
def create_workingtree(self):
248
246
def test_find_format(self):
249
247
# is the right format object found for a branch?
250
248
# create a branch with a few known format objects.
251
# this is not quite the same as
249
# this is not quite the same as
252
250
t = get_transport(self.get_url())
253
251
self.build_tree(["foo/", "bar/"], transport=t)
254
252
def check_format(format, url):
258
256
self.failUnless(isinstance(found_format, format.__class__))
259
257
check_format(bzrdir.BzrDirFormat5(), "foo")
260
258
check_format(bzrdir.BzrDirFormat6(), "bar")
262
260
def test_find_format_nothing_there(self):
263
261
self.assertRaises(NotBranchError,
264
262
bzrdir.BzrDirFormat.find_format,
308
306
branch.bzrdir.open_repository)
310
308
def test_create_branch_and_repo_under_shared_force_new(self):
311
# creating a branch and repo in a shared repo can be forced to
309
# creating a branch and repo in a shared repo can be forced to
312
310
# make a new repo
313
311
format = bzrdir.format_registry.make_bzrdir('knit')
314
312
self.make_repository('.', shared=True, format=format)
320
318
def test_create_standalone_working_tree(self):
321
319
format = SampleBzrDirFormat()
322
# note this is deliberately readonly, as this failure should
320
# note this is deliberately readonly, as this failure should
323
321
# occur before any writes.
324
322
self.assertRaises(errors.NotLocalUrl,
325
323
bzrdir.BzrDir.create_standalone_workingtree,
326
324
self.get_readonly_url(), format=format)
327
tree = bzrdir.BzrDir.create_standalone_workingtree('.',
325
tree = bzrdir.BzrDir.create_standalone_workingtree('.',
329
327
self.assertEqual('A tree', tree)
332
330
# create standalone working tree always makes a repo.
333
331
format = bzrdir.format_registry.make_bzrdir('knit')
334
332
self.make_repository('.', shared=True, format=format)
335
# note this is deliberately readonly, as this failure should
333
# note this is deliberately readonly, as this failure should
336
334
# occur before any writes.
337
335
self.assertRaises(errors.NotLocalUrl,
338
336
bzrdir.BzrDir.create_standalone_workingtree,
339
337
self.get_readonly_url('child'), format=format)
340
tree = bzrdir.BzrDir.create_standalone_workingtree('child',
338
tree = bzrdir.BzrDir.create_standalone_workingtree('child',
342
340
tree.bzrdir.open_repository()
360
358
def test_create_branch_convenience_root(self):
361
359
"""Creating a branch at the root of a fs should work."""
362
self.vfs_transport_factory = memory.MemoryServer
360
self.vfs_transport_factory = MemoryServer
363
361
# outside a repo the default convenience output is a repo+branch_tree
364
362
format = bzrdir.format_registry.make_bzrdir('knit')
365
branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(),
363
branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(),
367
365
self.assertRaises(errors.NoWorkingTree,
368
366
branch.bzrdir.open_workingtree)
378
376
branch.bzrdir.open_workingtree()
379
377
self.assertRaises(errors.NoRepositoryPresent,
380
378
branch.bzrdir.open_repository)
382
380
def test_create_branch_convenience_under_shared_repo_force_no_tree(self):
383
381
# inside a repo the default convenience output is a branch+ follow the
384
382
# repo tree policy but we can override that
390
388
branch.bzrdir.open_workingtree)
391
389
self.assertRaises(errors.NoRepositoryPresent,
392
390
branch.bzrdir.open_repository)
394
392
def test_create_branch_convenience_under_shared_repo_no_tree_policy(self):
395
393
# inside a repo the default convenience output is a branch+ follow the
396
394
# repo tree policy
397
395
format = bzrdir.format_registry.make_bzrdir('knit')
398
396
repo = self.make_repository('.', shared=True, format=format)
399
397
repo.set_make_working_trees(False)
400
branch = bzrdir.BzrDir.create_branch_convenience('child',
398
branch = bzrdir.BzrDir.create_branch_convenience('child',
402
400
self.assertRaises(errors.NoWorkingTree,
403
401
branch.bzrdir.open_workingtree)
433
431
"""The default acquisition policy should create a standalone branch."""
434
432
my_bzrdir = self.make_bzrdir('.')
435
433
repo_policy = my_bzrdir.determine_repository_policy()
436
repo, is_new = repo_policy.acquire_repository()
434
repo = repo_policy.acquire_repository()
437
435
self.assertEqual(repo.bzrdir.root_transport.base,
438
436
my_bzrdir.root_transport.base)
439
437
self.assertFalse(repo.is_shared())
441
440
def test_determine_stacking_policy(self):
442
441
parent_bzrdir = self.make_bzrdir('.')
443
442
child_bzrdir = self.make_bzrdir('child')
467
466
self.assertEqual(child_branch.base,
468
467
new_child.open_branch().get_stacked_on_url())
470
def test_default_stacking_with_stackable_branch_unstackable_repo(self):
471
# Make stackable source branch with an unstackable repo format.
472
source_bzrdir = self.make_bzrdir('source')
473
pack_repo.RepositoryFormatKnitPack1().initialize(source_bzrdir)
474
source_branch = bzrlib.branch.BzrBranchFormat7().initialize(
476
# Make a directory with a default stacking policy
477
parent_bzrdir = self.make_bzrdir('parent')
478
stacked_on = self.make_branch('parent/stacked-on', format='pack-0.92')
479
parent_bzrdir.get_config().set_default_stack_on(stacked_on.base)
480
# Clone source into directory
481
target = source_bzrdir.clone(self.get_url('parent/target'))
483
469
def test_sprout_obeys_stacking_policy(self):
484
470
child_branch, new_child_transport = self.prepare_default_stacking()
485
471
new_child = child_branch.bzrdir.sprout(new_child_transport.base)
573
559
super(ChrootedTests, self).setUp()
574
if not self.vfs_transport_factory == memory.MemoryServer:
560
if not self.vfs_transport_factory == MemoryServer:
575
561
self.transport_readonly_server = http_server.HttpServer
577
563
def local_branch_path(self, branch):
739
725
opened_bzrdir = bzrdir.BzrDir.open_from_transport(transport)
740
726
self.assertEqual(transport.base, opened_bzrdir.root_transport.base)
741
727
self.assertIsInstance(opened_bzrdir, bzrdir.BzrDir)
743
729
def test_open_from_transport_no_bzrdir(self):
744
730
transport = get_transport(self.get_url())
745
731
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
756
742
def test_sprout_recursive(self):
757
tree = self.make_branch_and_tree('tree1',
758
format='dirstate-with-subtree')
743
tree = self.make_branch_and_tree('tree1', format='dirstate-with-subtree')
759
744
sub_tree = self.make_branch_and_tree('tree1/subtree',
760
745
format='dirstate-with-subtree')
761
sub_tree.set_root_id('subtree-root')
762
746
tree.add_reference(sub_tree)
763
747
self.build_tree(['tree1/subtree/file'])
764
748
sub_tree.add('file')
765
749
tree.commit('Initial commit')
766
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
768
self.addCleanup(tree2.unlock)
750
tree.bzrdir.sprout('tree2')
769
751
self.failUnlessExists('tree2/subtree/file')
770
self.assertEqual('tree-reference', tree2.kind('subtree-root'))
772
753
def test_cloning_metadir(self):
773
754
"""Ensure that cloning metadir is suitable"""
900
881
def test_needs_conversion_different_working_tree(self):
901
882
# meta1dirs need an conversion if any element is not the default.
902
new_format = bzrdir.format_registry.make_bzrdir('dirstate')
903
tree = self.make_branch_and_tree('tree', format='knit')
904
self.assertTrue(tree.bzrdir.needs_format_conversion(
907
def test_initialize_on_format_uses_smart_transport(self):
908
self.setup_smart_server_with_call_log()
909
new_format = bzrdir.format_registry.make_bzrdir('dirstate')
910
transport = self.get_transport('target')
911
transport.ensure_base()
912
self.reset_smart_call_log()
913
instance = new_format.initialize_on_transport(transport)
914
self.assertIsInstance(instance, remote.RemoteBzrDir)
915
rpc_count = len(self.hpss_calls)
916
# This figure represent the amount of work to perform this use case. It
917
# is entirely ok to reduce this number if a test fails due to rpc_count
918
# being too low. If rpc_count increases, more network roundtrips have
919
# become necessary for this use case. Please do not adjust this number
920
# upwards without agreement from bzr's network support maintainers.
921
self.assertEqual(2, rpc_count)
883
old_format = bzrdir.BzrDirFormat.get_default_format()
885
new_default = bzrdir.format_registry.make_bzrdir('dirstate')
886
bzrdir.BzrDirFormat._set_default_format(new_default)
888
tree = self.make_branch_and_tree('tree', format='knit')
889
self.assertTrue(tree.bzrdir.needs_format_conversion())
891
bzrdir.BzrDirFormat._set_default_format(old_format)
924
894
class TestFormat5(TestCaseWithTransport):
925
895
"""Tests specific to the version 5 bzrdir format."""
927
897
def test_same_lockfiles_between_tree_repo_branch(self):
928
# this checks that only a single lockfiles instance is created
898
# this checks that only a single lockfiles instance is created
929
899
# for format 5 objects
930
900
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
931
901
def check_dir_components_use_same_lock(dir):
938
908
# and if we open it normally.
939
909
dir = bzrdir.BzrDir.open(self.get_url())
940
910
check_dir_components_use_same_lock(dir)
942
912
def test_can_convert(self):
943
913
# format 5 dirs are convertable
944
914
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
945
915
self.assertTrue(dir.can_convert_format())
947
917
def test_needs_conversion(self):
948
# format 5 dirs need a conversion if they are not the default,
950
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
951
# don't need to convert it to itself
952
self.assertFalse(dir.needs_format_conversion(bzrdir.BzrDirFormat5()))
953
# do need to convert it to the current default
954
self.assertTrue(dir.needs_format_conversion(
955
bzrdir.BzrDirFormat.get_default_format()))
918
# format 5 dirs need a conversion if they are not the default.
919
# and they start of not the default.
920
old_format = bzrdir.BzrDirFormat.get_default_format()
921
bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirFormat5())
923
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
924
self.assertFalse(dir.needs_format_conversion())
926
bzrdir.BzrDirFormat._set_default_format(old_format)
927
self.assertTrue(dir.needs_format_conversion())
958
930
class TestFormat6(TestCaseWithTransport):
959
931
"""Tests specific to the version 6 bzrdir format."""
961
933
def test_same_lockfiles_between_tree_repo_branch(self):
962
# this checks that only a single lockfiles instance is created
934
# this checks that only a single lockfiles instance is created
963
935
# for format 6 objects
964
936
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
965
937
def check_dir_components_use_same_lock(dir):
972
944
# and if we open it normally.
973
945
dir = bzrdir.BzrDir.open(self.get_url())
974
946
check_dir_components_use_same_lock(dir)
976
948
def test_can_convert(self):
977
949
# format 6 dirs are convertable
978
950
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
979
951
self.assertTrue(dir.can_convert_format())
981
953
def test_needs_conversion(self):
982
954
# format 6 dirs need an conversion if they are not the default.
983
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
984
self.assertTrue(dir.needs_format_conversion(
985
bzrdir.BzrDirFormat.get_default_format()))
955
old_format = bzrdir.BzrDirFormat.get_default_format()
956
bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirMetaFormat1())
958
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
959
self.assertTrue(dir.needs_format_conversion())
961
bzrdir.BzrDirFormat._set_default_format(old_format)
988
964
class NotBzrDir(bzrlib.bzrdir.BzrDir):
1020
996
class TestNotBzrDir(TestCaseWithTransport):
1021
997
"""Tests for using the bzrdir api with a non .bzr based disk format.
1023
999
If/when one of these is in the core, we can let the implementation tests
1024
1000
verify this works.
1027
1003
def test_create_and_find_format(self):
1028
# create a .notbzr dir
1004
# create a .notbzr dir
1029
1005
format = NotBzrDirFormat()
1030
1006
dir = format.initialize(self.get_url())
1031
1007
self.assertIsInstance(dir, NotBzrDir)
1056
1032
def setUp(self):
1057
1033
super(NonLocalTests, self).setUp()
1058
self.vfs_transport_factory = memory.MemoryServer
1034
self.vfs_transport_factory = MemoryServer
1060
1036
def test_create_branch_convenience(self):
1061
1037
# outside a repo the default convenience output is a repo+branch_tree
1062
1038
format = bzrdir.format_registry.make_bzrdir('knit')
1108
1084
We can't inherit directly from TestCaseWithTwoWebservers or the
1109
1085
test framework will try to create an instance which cannot
1110
run, its implementation being incomplete.
1086
run, its implementation being incomplete.
1113
1089
def create_transport_readonly_server(self):
1170
1144
"""Tests redirections for pycurl implementation"""
1172
1146
def _qualified_url(self, host, port):
1173
result = 'http+pycurl://%s:%s' % (host, port)
1174
self.permit_url(result)
1147
return 'http+pycurl://%s:%s' % (host, port)
1178
1150
class TestHTTPRedirections_nosmart(TestHTTPRedirections,
1182
1154
_transport = NoSmartTransportDecorator
1184
1156
def _qualified_url(self, host, port):
1185
result = 'nosmart+http://%s:%s' % (host, port)
1186
self.permit_url(result)
1157
return 'nosmart+http://%s:%s' % (host, port)
1190
1160
class TestHTTPRedirections_readonly(TestHTTPRedirections,
1194
1164
_transport = ReadonlyTransportDecorator
1196
1166
def _qualified_url(self, host, port):
1197
result = 'readonly+http://%s:%s' % (host, port)
1198
self.permit_url(result)
1167
return 'readonly+http://%s:%s' % (host, port)
1202
1170
class TestDotBzrHidden(TestCaseWithTransport):
1254
1222
return _TestBzrDirFormat()
1257
class _TestBranchFormat(bzrlib.branch.BranchFormat):
1258
"""Test Branch format for TestBzrDirSprout."""
1261
1225
class _TestBranch(bzrlib.branch.Branch):
1262
1226
"""Test Branch implementation for TestBzrDirSprout."""
1264
1228
def __init__(self, *args, **kwargs):
1265
self._format = _TestBranchFormat()
1266
1229
super(_TestBranch, self).__init__(*args, **kwargs)
1267
1230
self.calls = []
1268
1231
self._parent = None
1289
1252
Usually, BzrDir.sprout should delegate to the branch's sprout method
1290
1253
for part of the work. This allows the source branch to control the
1291
1254
choice of format for the new branch.
1293
1256
There are exceptions, but this tests avoids them:
1294
1257
- if there's no branch in the source bzrdir,
1295
1258
- or if the stacking has been requested and the format needs to be
1316
1279
parent = grandparent_tree.bzrdir.sprout('parent').open_branch()
1317
1280
branch_tree = parent.bzrdir.sprout('branch').open_branch()
1318
1281
self.assertContainsRe(branch_tree.get_parent(), '/parent/$')
1321
class TestBzrDirHooks(TestCaseWithMemoryTransport):
1323
def test_pre_open_called(self):
1325
bzrdir.BzrDir.hooks.install_named_hook('pre_open', calls.append, None)
1326
transport = self.get_transport('foo')
1327
url = transport.base
1328
self.assertRaises(errors.NotBranchError, bzrdir.BzrDir.open, url)
1329
self.assertEqual([transport.base], [t.base for t in calls])
1331
def test_pre_open_actual_exceptions_raised(self):
1333
def fail_once(transport):
1336
raise errors.BzrError("fail")
1337
bzrdir.BzrDir.hooks.install_named_hook('pre_open', fail_once, None)
1338
transport = self.get_transport('foo')
1339
url = transport.base
1340
err = self.assertRaises(errors.BzrError, bzrdir.BzrDir.open, url)
1341
self.assertEqual('fail', err._preformatted_string)
1343
def test_post_repo_init(self):
1344
from bzrlib.bzrdir import RepoInitHookParams
1346
bzrdir.BzrDir.hooks.install_named_hook('post_repo_init',
1348
self.make_repository('foo')
1349
self.assertLength(1, calls)
1351
self.assertIsInstance(params, RepoInitHookParams)
1352
self.assertTrue(hasattr(params, 'bzrdir'))
1353
self.assertTrue(hasattr(params, 'repository'))