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
55
58
from bzrlib.transport.memory import MemoryServer
56
59
from bzrlib.transport.nosmart import NoSmartTransportDecorator
57
60
from bzrlib.transport.readonly import ReadonlyTransportDecorator
58
from bzrlib.repofmt import knitrepo, weaverepo, pack_repo
61
from bzrlib.repofmt import knitrepo, weaverepo
61
64
class TestDefaultFormat(TestCase):
81
84
my_format_registry.register('weave', bzrdir.BzrDirFormat6,
82
85
'Pre-0.8 format. Slower and does not support checkouts or shared'
83
86
' repositories', deprecated=True)
84
my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir',
87
my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir',
85
88
'BzrDirFormat6', 'Format registered lazily', deprecated=True)
86
89
my_format_registry.register_metadir('knit',
87
90
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
114
117
my_bzrdir = my_format_registry.make_bzrdir('weave')
115
118
self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
116
119
my_bzrdir = my_format_registry.make_bzrdir('default')
117
self.assertIsInstance(my_bzrdir.repository_format,
120
self.assertIsInstance(my_bzrdir.repository_format,
118
121
knitrepo.RepositoryFormatKnit1)
119
122
my_bzrdir = my_format_registry.make_bzrdir('knit')
120
self.assertIsInstance(my_bzrdir.repository_format,
123
self.assertIsInstance(my_bzrdir.repository_format,
121
124
knitrepo.RepositoryFormatKnit1)
122
125
my_bzrdir = my_format_registry.make_bzrdir('branch6')
123
126
self.assertIsInstance(my_bzrdir.get_branch_format(),
127
130
my_format_registry = self.make_format_registry()
128
131
self.assertEqual('Format registered lazily',
129
132
my_format_registry.get_help('lazy'))
130
self.assertEqual('Format using knits',
133
self.assertEqual('Format using knits',
131
134
my_format_registry.get_help('knit'))
132
self.assertEqual('Format using knits',
135
self.assertEqual('Format using knits',
133
136
my_format_registry.get_help('default'))
134
137
self.assertEqual('Pre-0.8 format. Slower and does not support'
135
' checkouts or shared repositories',
138
' checkouts or shared repositories',
136
139
my_format_registry.get_help('weave'))
138
141
def test_help_topic(self):
139
142
topics = help_topics.HelpTopicRegistry()
140
143
registry = self.make_format_registry()
141
topics.register('current-formats', registry.help_topic,
144
topics.register('current-formats', registry.help_topic,
142
145
'Current formats')
143
topics.register('other-formats', registry.help_topic,
146
topics.register('other-formats', registry.help_topic,
145
148
new = topics.get_detail('current-formats')
146
149
rest = topics.get_detail('other-formats')
147
150
experimental, deprecated = rest.split('Deprecated formats')
148
self.assertContainsRe(new, 'formats-help')
149
self.assertContainsRe(new,
151
self.assertContainsRe(new, 'bzr help formats')
152
self.assertContainsRe(new,
150
153
':knit:\n \(native\) \(default\) Format using knits\n')
151
self.assertContainsRe(experimental,
154
self.assertContainsRe(experimental,
152
155
':branch6:\n \(native\) Experimental successor to knit')
153
self.assertContainsRe(deprecated,
156
self.assertContainsRe(deprecated,
154
157
':lazy:\n \(native\) Format registered lazily\n')
155
158
self.assertNotContainsRe(new, 'hidden')
177
180
'Pre-0.8 format. Slower and does not support checkouts or shared'
178
181
' repositories', deprecated=True, alias=True)
179
182
self.assertEqual(frozenset(['weavealias']), a_registry.aliases())
182
185
class SampleBranch(bzrlib.branch.Branch):
183
186
"""A dummy branch for guess what, dummy use."""
243
239
def test_find_format(self):
244
240
# is the right format object found for a branch?
245
241
# create a branch with a few known format objects.
246
# this is not quite the same as
242
# this is not quite the same as
247
243
t = get_transport(self.get_url())
248
244
self.build_tree(["foo/", "bar/"], transport=t)
249
245
def check_format(format, url):
253
249
self.failUnless(isinstance(found_format, format.__class__))
254
250
check_format(bzrdir.BzrDirFormat5(), "foo")
255
251
check_format(bzrdir.BzrDirFormat6(), "bar")
257
253
def test_find_format_nothing_there(self):
258
254
self.assertRaises(NotBranchError,
259
255
bzrdir.BzrDirFormat.find_format,
303
299
branch.bzrdir.open_repository)
305
301
def test_create_branch_and_repo_under_shared_force_new(self):
306
# creating a branch and repo in a shared repo can be forced to
302
# creating a branch and repo in a shared repo can be forced to
307
303
# make a new repo
308
304
format = bzrdir.format_registry.make_bzrdir('knit')
309
305
self.make_repository('.', shared=True, format=format)
315
311
def test_create_standalone_working_tree(self):
316
312
format = SampleBzrDirFormat()
317
# note this is deliberately readonly, as this failure should
313
# note this is deliberately readonly, as this failure should
318
314
# occur before any writes.
319
315
self.assertRaises(errors.NotLocalUrl,
320
316
bzrdir.BzrDir.create_standalone_workingtree,
321
317
self.get_readonly_url(), format=format)
322
tree = bzrdir.BzrDir.create_standalone_workingtree('.',
318
tree = bzrdir.BzrDir.create_standalone_workingtree('.',
324
320
self.assertEqual('A tree', tree)
327
323
# create standalone working tree always makes a repo.
328
324
format = bzrdir.format_registry.make_bzrdir('knit')
329
325
self.make_repository('.', shared=True, format=format)
330
# note this is deliberately readonly, as this failure should
326
# note this is deliberately readonly, as this failure should
331
327
# occur before any writes.
332
328
self.assertRaises(errors.NotLocalUrl,
333
329
bzrdir.BzrDir.create_standalone_workingtree,
334
330
self.get_readonly_url('child'), format=format)
335
tree = bzrdir.BzrDir.create_standalone_workingtree('child',
331
tree = bzrdir.BzrDir.create_standalone_workingtree('child',
337
333
tree.bzrdir.open_repository()
357
353
self.vfs_transport_factory = MemoryServer
358
354
# outside a repo the default convenience output is a repo+branch_tree
359
355
format = bzrdir.format_registry.make_bzrdir('knit')
360
branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(),
356
branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(),
362
358
self.assertRaises(errors.NoWorkingTree,
363
359
branch.bzrdir.open_workingtree)
373
369
branch.bzrdir.open_workingtree()
374
370
self.assertRaises(errors.NoRepositoryPresent,
375
371
branch.bzrdir.open_repository)
377
373
def test_create_branch_convenience_under_shared_repo_force_no_tree(self):
378
374
# inside a repo the default convenience output is a branch+ follow the
379
375
# repo tree policy but we can override that
385
381
branch.bzrdir.open_workingtree)
386
382
self.assertRaises(errors.NoRepositoryPresent,
387
383
branch.bzrdir.open_repository)
389
385
def test_create_branch_convenience_under_shared_repo_no_tree_policy(self):
390
386
# inside a repo the default convenience output is a branch+ follow the
391
387
# repo tree policy
392
388
format = bzrdir.format_registry.make_bzrdir('knit')
393
389
repo = self.make_repository('.', shared=True, format=format)
394
390
repo.set_make_working_trees(False)
395
branch = bzrdir.BzrDir.create_branch_convenience('child',
391
branch = bzrdir.BzrDir.create_branch_convenience('child',
397
393
self.assertRaises(errors.NoWorkingTree,
398
394
branch.bzrdir.open_workingtree)
428
424
"""The default acquisition policy should create a standalone branch."""
429
425
my_bzrdir = self.make_bzrdir('.')
430
426
repo_policy = my_bzrdir.determine_repository_policy()
431
repo, is_new = repo_policy.acquire_repository()
427
repo = repo_policy.acquire_repository()
432
428
self.assertEqual(repo.bzrdir.root_transport.base,
433
429
my_bzrdir.root_transport.base)
434
430
self.assertFalse(repo.is_shared())
436
433
def test_determine_stacking_policy(self):
437
434
parent_bzrdir = self.make_bzrdir('.')
438
435
child_bzrdir = self.make_bzrdir('child')
462
459
self.assertEqual(child_branch.base,
463
460
new_child.open_branch().get_stacked_on_url())
465
def test_default_stacking_with_stackable_branch_unstackable_repo(self):
466
# Make stackable source branch with an unstackable repo format.
467
source_bzrdir = self.make_bzrdir('source')
468
pack_repo.RepositoryFormatKnitPack1().initialize(source_bzrdir)
469
source_branch = bzrlib.branch.BzrBranchFormat7().initialize(source_bzrdir)
470
# Make a directory with a default stacking policy
471
parent_bzrdir = self.make_bzrdir('parent')
472
stacked_on = self.make_branch('parent/stacked-on', format='pack-0.92')
473
parent_bzrdir.get_config().set_default_stack_on(stacked_on.base)
474
# Clone source into directory
475
target = source_bzrdir.clone(self.get_url('parent/target'))
477
462
def test_sprout_obeys_stacking_policy(self):
478
463
child_branch, new_child_transport = self.prepare_default_stacking()
479
464
new_child = child_branch.bzrdir.sprout(new_child_transport.base)
733
718
opened_bzrdir = bzrdir.BzrDir.open_from_transport(transport)
734
719
self.assertEqual(transport.base, opened_bzrdir.root_transport.base)
735
720
self.assertIsInstance(opened_bzrdir, bzrdir.BzrDir)
737
722
def test_open_from_transport_no_bzrdir(self):
738
723
transport = get_transport(self.get_url())
739
724
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
750
735
def test_sprout_recursive(self):
751
tree = self.make_branch_and_tree('tree1',
752
format='dirstate-with-subtree')
736
tree = self.make_branch_and_tree('tree1', format='dirstate-with-subtree')
753
737
sub_tree = self.make_branch_and_tree('tree1/subtree',
754
738
format='dirstate-with-subtree')
755
sub_tree.set_root_id('subtree-root')
756
739
tree.add_reference(sub_tree)
757
740
self.build_tree(['tree1/subtree/file'])
758
741
sub_tree.add('file')
759
742
tree.commit('Initial commit')
760
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
762
self.addCleanup(tree2.unlock)
743
tree.bzrdir.sprout('tree2')
763
744
self.failUnlessExists('tree2/subtree/file')
764
self.assertEqual('tree-reference', tree2.kind('subtree-root'))
766
746
def test_cloning_metadir(self):
767
747
"""Ensure that cloning metadir is suitable"""
894
874
def test_needs_conversion_different_working_tree(self):
895
875
# meta1dirs need an conversion if any element is not the default.
896
new_format = bzrdir.format_registry.make_bzrdir('dirstate')
897
tree = self.make_branch_and_tree('tree', format='knit')
898
self.assertTrue(tree.bzrdir.needs_format_conversion(
901
def test_initialize_on_format_uses_smart_transport(self):
902
self.setup_smart_server_with_call_log()
903
new_format = bzrdir.format_registry.make_bzrdir('dirstate')
904
transport = self.get_transport('target')
905
transport.ensure_base()
906
self.reset_smart_call_log()
907
instance = new_format.initialize_on_transport(transport)
908
self.assertIsInstance(instance, remote.RemoteBzrDir)
909
rpc_count = len(self.hpss_calls)
910
# This figure represent the amount of work to perform this use case. It
911
# is entirely ok to reduce this number if a test fails due to rpc_count
912
# being too low. If rpc_count increases, more network roundtrips have
913
# become necessary for this use case. Please do not adjust this number
914
# upwards without agreement from bzr's network support maintainers.
915
self.assertEqual(2, rpc_count)
876
old_format = bzrdir.BzrDirFormat.get_default_format()
878
new_default = bzrdir.format_registry.make_bzrdir('dirstate')
879
bzrdir.BzrDirFormat._set_default_format(new_default)
881
tree = self.make_branch_and_tree('tree', format='knit')
882
self.assertTrue(tree.bzrdir.needs_format_conversion())
884
bzrdir.BzrDirFormat._set_default_format(old_format)
918
887
class TestFormat5(TestCaseWithTransport):
919
888
"""Tests specific to the version 5 bzrdir format."""
921
890
def test_same_lockfiles_between_tree_repo_branch(self):
922
# this checks that only a single lockfiles instance is created
891
# this checks that only a single lockfiles instance is created
923
892
# for format 5 objects
924
893
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
925
894
def check_dir_components_use_same_lock(dir):
932
901
# and if we open it normally.
933
902
dir = bzrdir.BzrDir.open(self.get_url())
934
903
check_dir_components_use_same_lock(dir)
936
905
def test_can_convert(self):
937
906
# format 5 dirs are convertable
938
907
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
939
908
self.assertTrue(dir.can_convert_format())
941
910
def test_needs_conversion(self):
942
# format 5 dirs need a conversion if they are not the default,
944
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
945
# don't need to convert it to itself
946
self.assertFalse(dir.needs_format_conversion(bzrdir.BzrDirFormat5()))
947
# do need to convert it to the current default
948
self.assertTrue(dir.needs_format_conversion(
949
bzrdir.BzrDirFormat.get_default_format()))
911
# format 5 dirs need a conversion if they are not the default.
912
# and they start of not the default.
913
old_format = bzrdir.BzrDirFormat.get_default_format()
914
bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirFormat5())
916
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
917
self.assertFalse(dir.needs_format_conversion())
919
bzrdir.BzrDirFormat._set_default_format(old_format)
920
self.assertTrue(dir.needs_format_conversion())
952
923
class TestFormat6(TestCaseWithTransport):
953
924
"""Tests specific to the version 6 bzrdir format."""
955
926
def test_same_lockfiles_between_tree_repo_branch(self):
956
# this checks that only a single lockfiles instance is created
927
# this checks that only a single lockfiles instance is created
957
928
# for format 6 objects
958
929
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
959
930
def check_dir_components_use_same_lock(dir):
966
937
# and if we open it normally.
967
938
dir = bzrdir.BzrDir.open(self.get_url())
968
939
check_dir_components_use_same_lock(dir)
970
941
def test_can_convert(self):
971
942
# format 6 dirs are convertable
972
943
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
973
944
self.assertTrue(dir.can_convert_format())
975
946
def test_needs_conversion(self):
976
947
# format 6 dirs need an conversion if they are not the default.
977
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
978
self.assertTrue(dir.needs_format_conversion(
979
bzrdir.BzrDirFormat.get_default_format()))
948
old_format = bzrdir.BzrDirFormat.get_default_format()
949
bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirMetaFormat1())
951
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
952
self.assertTrue(dir.needs_format_conversion())
954
bzrdir.BzrDirFormat._set_default_format(old_format)
982
957
class NotBzrDir(bzrlib.bzrdir.BzrDir):
1014
989
class TestNotBzrDir(TestCaseWithTransport):
1015
990
"""Tests for using the bzrdir api with a non .bzr based disk format.
1017
992
If/when one of these is in the core, we can let the implementation tests
1018
993
verify this works.
1021
996
def test_create_and_find_format(self):
1022
# create a .notbzr dir
997
# create a .notbzr dir
1023
998
format = NotBzrDirFormat()
1024
999
dir = format.initialize(self.get_url())
1025
1000
self.assertIsInstance(dir, NotBzrDir)
1102
1077
We can't inherit directly from TestCaseWithTwoWebservers or the
1103
1078
test framework will try to create an instance which cannot
1104
run, its implementation being incomplete.
1079
run, its implementation being incomplete.
1107
1082
def create_transport_readonly_server(self):
1164
1137
"""Tests redirections for pycurl implementation"""
1166
1139
def _qualified_url(self, host, port):
1167
result = 'http+pycurl://%s:%s' % (host, port)
1168
self.permit_url(result)
1140
return 'http+pycurl://%s:%s' % (host, port)
1172
1143
class TestHTTPRedirections_nosmart(TestHTTPRedirections,
1176
1147
_transport = NoSmartTransportDecorator
1178
1149
def _qualified_url(self, host, port):
1179
result = 'nosmart+http://%s:%s' % (host, port)
1180
self.permit_url(result)
1150
return 'nosmart+http://%s:%s' % (host, port)
1184
1153
class TestHTTPRedirections_readonly(TestHTTPRedirections,
1188
1157
_transport = ReadonlyTransportDecorator
1190
1159
def _qualified_url(self, host, port):
1191
result = 'readonly+http://%s:%s' % (host, port)
1192
self.permit_url(result)
1160
return 'readonly+http://%s:%s' % (host, port)
1196
1163
class TestDotBzrHidden(TestCaseWithTransport):
1248
1215
return _TestBzrDirFormat()
1251
class _TestBranchFormat(bzrlib.branch.BranchFormat):
1252
"""Test Branch format for TestBzrDirSprout."""
1255
1218
class _TestBranch(bzrlib.branch.Branch):
1256
1219
"""Test Branch implementation for TestBzrDirSprout."""
1258
1221
def __init__(self, *args, **kwargs):
1259
self._format = _TestBranchFormat()
1260
1222
super(_TestBranch, self).__init__(*args, **kwargs)
1261
1223
self.calls = []
1262
1224
self._parent = None
1283
1245
Usually, BzrDir.sprout should delegate to the branch's sprout method
1284
1246
for part of the work. This allows the source branch to control the
1285
1247
choice of format for the new branch.
1287
1249
There are exceptions, but this tests avoids them:
1288
1250
- if there's no branch in the source bzrdir,
1289
1251
- or if the stacking has been requested and the format needs to be
1310
1272
parent = grandparent_tree.bzrdir.sprout('parent').open_branch()
1311
1273
branch_tree = parent.bzrdir.sprout('branch').open_branch()
1312
1274
self.assertContainsRe(branch_tree.get_parent(), '/parent/$')
1315
class TestBzrDirHooks(TestCaseWithMemoryTransport):
1317
def test_pre_open_called(self):
1319
bzrdir.BzrDir.hooks.install_named_hook('pre_open', calls.append, None)
1320
transport = self.get_transport('foo')
1321
url = transport.base
1322
self.assertRaises(errors.NotBranchError, bzrdir.BzrDir.open, url)
1323
self.assertEqual([transport.base], [t.base for t in calls])
1325
def test_pre_open_actual_exceptions_raised(self):
1327
def fail_once(transport):
1330
raise errors.BzrError("fail")
1331
bzrdir.BzrDir.hooks.install_named_hook('pre_open', fail_once, None)
1332
transport = self.get_transport('foo')
1333
url = transport.base
1334
err = self.assertRaises(errors.BzrError, bzrdir.BzrDir.open, url)
1335
self.assertEqual('fail', err._preformatted_string)