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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
"""Tests for the BzrDir facility and any format specific tests.
19
For interface contract tests, see tests/bzr_dir_implementations.
19
For interface contract tests, see tests/per_bzr_dir.
24
from StringIO import StringIO
58
55
from bzrlib.transport.memory import MemoryServer
59
56
from bzrlib.transport.nosmart import NoSmartTransportDecorator
60
57
from bzrlib.transport.readonly import ReadonlyTransportDecorator
61
from bzrlib.repofmt import knitrepo, weaverepo
58
from bzrlib.repofmt import knitrepo, weaverepo, pack_repo
64
61
class TestDefaultFormat(TestCase):
84
81
my_format_registry.register('weave', bzrdir.BzrDirFormat6,
85
82
'Pre-0.8 format. Slower and does not support checkouts or shared'
86
83
' repositories', deprecated=True)
87
my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir',
84
my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir',
88
85
'BzrDirFormat6', 'Format registered lazily', deprecated=True)
89
86
my_format_registry.register_metadir('knit',
90
87
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
117
114
my_bzrdir = my_format_registry.make_bzrdir('weave')
118
115
self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
119
116
my_bzrdir = my_format_registry.make_bzrdir('default')
120
self.assertIsInstance(my_bzrdir.repository_format,
117
self.assertIsInstance(my_bzrdir.repository_format,
121
118
knitrepo.RepositoryFormatKnit1)
122
119
my_bzrdir = my_format_registry.make_bzrdir('knit')
123
self.assertIsInstance(my_bzrdir.repository_format,
120
self.assertIsInstance(my_bzrdir.repository_format,
124
121
knitrepo.RepositoryFormatKnit1)
125
122
my_bzrdir = my_format_registry.make_bzrdir('branch6')
126
123
self.assertIsInstance(my_bzrdir.get_branch_format(),
130
127
my_format_registry = self.make_format_registry()
131
128
self.assertEqual('Format registered lazily',
132
129
my_format_registry.get_help('lazy'))
133
self.assertEqual('Format using knits',
130
self.assertEqual('Format using knits',
134
131
my_format_registry.get_help('knit'))
135
self.assertEqual('Format using knits',
132
self.assertEqual('Format using knits',
136
133
my_format_registry.get_help('default'))
137
134
self.assertEqual('Pre-0.8 format. Slower and does not support'
138
' checkouts or shared repositories',
135
' checkouts or shared repositories',
139
136
my_format_registry.get_help('weave'))
141
138
def test_help_topic(self):
142
139
topics = help_topics.HelpTopicRegistry()
143
140
registry = self.make_format_registry()
144
topics.register('current-formats', registry.help_topic,
141
topics.register('current-formats', registry.help_topic,
145
142
'Current formats')
146
topics.register('other-formats', registry.help_topic,
143
topics.register('other-formats', registry.help_topic,
148
145
new = topics.get_detail('current-formats')
149
146
rest = topics.get_detail('other-formats')
150
147
experimental, deprecated = rest.split('Deprecated formats')
151
self.assertContainsRe(new, 'bzr help formats')
152
self.assertContainsRe(new,
148
self.assertContainsRe(new, 'formats-help')
149
self.assertContainsRe(new,
153
150
':knit:\n \(native\) \(default\) Format using knits\n')
154
self.assertContainsRe(experimental,
151
self.assertContainsRe(experimental,
155
152
':branch6:\n \(native\) Experimental successor to knit')
156
self.assertContainsRe(deprecated,
153
self.assertContainsRe(deprecated,
157
154
':lazy:\n \(native\) Format registered lazily\n')
158
155
self.assertNotContainsRe(new, 'hidden')
246
243
def test_find_format(self):
247
244
# is the right format object found for a branch?
248
245
# create a branch with a few known format objects.
249
# this is not quite the same as
246
# this is not quite the same as
250
247
t = get_transport(self.get_url())
251
248
self.build_tree(["foo/", "bar/"], transport=t)
252
249
def check_format(format, url):
256
253
self.failUnless(isinstance(found_format, format.__class__))
257
254
check_format(bzrdir.BzrDirFormat5(), "foo")
258
255
check_format(bzrdir.BzrDirFormat6(), "bar")
260
257
def test_find_format_nothing_there(self):
261
258
self.assertRaises(NotBranchError,
262
259
bzrdir.BzrDirFormat.find_format,
306
303
branch.bzrdir.open_repository)
308
305
def test_create_branch_and_repo_under_shared_force_new(self):
309
# creating a branch and repo in a shared repo can be forced to
306
# creating a branch and repo in a shared repo can be forced to
310
307
# make a new repo
311
308
format = bzrdir.format_registry.make_bzrdir('knit')
312
309
self.make_repository('.', shared=True, format=format)
318
315
def test_create_standalone_working_tree(self):
319
316
format = SampleBzrDirFormat()
320
# note this is deliberately readonly, as this failure should
317
# note this is deliberately readonly, as this failure should
321
318
# occur before any writes.
322
319
self.assertRaises(errors.NotLocalUrl,
323
320
bzrdir.BzrDir.create_standalone_workingtree,
324
321
self.get_readonly_url(), format=format)
325
tree = bzrdir.BzrDir.create_standalone_workingtree('.',
322
tree = bzrdir.BzrDir.create_standalone_workingtree('.',
327
324
self.assertEqual('A tree', tree)
330
327
# create standalone working tree always makes a repo.
331
328
format = bzrdir.format_registry.make_bzrdir('knit')
332
329
self.make_repository('.', shared=True, format=format)
333
# note this is deliberately readonly, as this failure should
330
# note this is deliberately readonly, as this failure should
334
331
# occur before any writes.
335
332
self.assertRaises(errors.NotLocalUrl,
336
333
bzrdir.BzrDir.create_standalone_workingtree,
337
334
self.get_readonly_url('child'), format=format)
338
tree = bzrdir.BzrDir.create_standalone_workingtree('child',
335
tree = bzrdir.BzrDir.create_standalone_workingtree('child',
340
337
tree.bzrdir.open_repository()
360
357
self.vfs_transport_factory = MemoryServer
361
358
# outside a repo the default convenience output is a repo+branch_tree
362
359
format = bzrdir.format_registry.make_bzrdir('knit')
363
branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(),
360
branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(),
365
362
self.assertRaises(errors.NoWorkingTree,
366
363
branch.bzrdir.open_workingtree)
376
373
branch.bzrdir.open_workingtree()
377
374
self.assertRaises(errors.NoRepositoryPresent,
378
375
branch.bzrdir.open_repository)
380
377
def test_create_branch_convenience_under_shared_repo_force_no_tree(self):
381
378
# inside a repo the default convenience output is a branch+ follow the
382
379
# repo tree policy but we can override that
388
385
branch.bzrdir.open_workingtree)
389
386
self.assertRaises(errors.NoRepositoryPresent,
390
387
branch.bzrdir.open_repository)
392
389
def test_create_branch_convenience_under_shared_repo_no_tree_policy(self):
393
390
# inside a repo the default convenience output is a branch+ follow the
394
391
# repo tree policy
395
392
format = bzrdir.format_registry.make_bzrdir('knit')
396
393
repo = self.make_repository('.', shared=True, format=format)
397
394
repo.set_make_working_trees(False)
398
branch = bzrdir.BzrDir.create_branch_convenience('child',
395
branch = bzrdir.BzrDir.create_branch_convenience('child',
400
397
self.assertRaises(errors.NoWorkingTree,
401
398
branch.bzrdir.open_workingtree)
431
428
"""The default acquisition policy should create a standalone branch."""
432
429
my_bzrdir = self.make_bzrdir('.')
433
430
repo_policy = my_bzrdir.determine_repository_policy()
434
repo = repo_policy.acquire_repository()
431
repo, is_new = repo_policy.acquire_repository()
435
432
self.assertEqual(repo.bzrdir.root_transport.base,
436
433
my_bzrdir.root_transport.base)
437
434
self.assertFalse(repo.is_shared())
440
436
def test_determine_stacking_policy(self):
441
437
parent_bzrdir = self.make_bzrdir('.')
442
438
child_bzrdir = self.make_bzrdir('child')
466
462
self.assertEqual(child_branch.base,
467
463
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'))
469
477
def test_sprout_obeys_stacking_policy(self):
470
478
child_branch, new_child_transport = self.prepare_default_stacking()
471
479
new_child = child_branch.bzrdir.sprout(new_child_transport.base)
725
733
opened_bzrdir = bzrdir.BzrDir.open_from_transport(transport)
726
734
self.assertEqual(transport.base, opened_bzrdir.root_transport.base)
727
735
self.assertIsInstance(opened_bzrdir, bzrdir.BzrDir)
729
737
def test_open_from_transport_no_bzrdir(self):
730
738
transport = get_transport(self.get_url())
731
739
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
742
750
def test_sprout_recursive(self):
743
tree = self.make_branch_and_tree('tree1', format='dirstate-with-subtree')
751
tree = self.make_branch_and_tree('tree1',
752
format='dirstate-with-subtree')
744
753
sub_tree = self.make_branch_and_tree('tree1/subtree',
745
754
format='dirstate-with-subtree')
755
sub_tree.set_root_id('subtree-root')
746
756
tree.add_reference(sub_tree)
747
757
self.build_tree(['tree1/subtree/file'])
748
758
sub_tree.add('file')
749
759
tree.commit('Initial commit')
750
tree.bzrdir.sprout('tree2')
760
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
762
self.addCleanup(tree2.unlock)
751
763
self.failUnlessExists('tree2/subtree/file')
764
self.assertEqual('tree-reference', tree2.kind('subtree-root'))
753
766
def test_cloning_metadir(self):
754
767
"""Ensure that cloning metadir is suitable"""
885
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)
889
918
class TestFormat5(TestCaseWithTransport):
890
919
"""Tests specific to the version 5 bzrdir format."""
892
921
def test_same_lockfiles_between_tree_repo_branch(self):
893
# this checks that only a single lockfiles instance is created
922
# this checks that only a single lockfiles instance is created
894
923
# for format 5 objects
895
924
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
896
925
def check_dir_components_use_same_lock(dir):
903
932
# and if we open it normally.
904
933
dir = bzrdir.BzrDir.open(self.get_url())
905
934
check_dir_components_use_same_lock(dir)
907
936
def test_can_convert(self):
908
937
# format 5 dirs are convertable
909
938
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
910
939
self.assertTrue(dir.can_convert_format())
912
941
def test_needs_conversion(self):
913
942
# format 5 dirs need a conversion if they are not the default,
914
943
# and they aren't
924
953
"""Tests specific to the version 6 bzrdir format."""
926
955
def test_same_lockfiles_between_tree_repo_branch(self):
927
# this checks that only a single lockfiles instance is created
956
# this checks that only a single lockfiles instance is created
928
957
# for format 6 objects
929
958
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
930
959
def check_dir_components_use_same_lock(dir):
937
966
# and if we open it normally.
938
967
dir = bzrdir.BzrDir.open(self.get_url())
939
968
check_dir_components_use_same_lock(dir)
941
970
def test_can_convert(self):
942
971
# format 6 dirs are convertable
943
972
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
944
973
self.assertTrue(dir.can_convert_format())
946
975
def test_needs_conversion(self):
947
976
# format 6 dirs need an conversion if they are not the default.
948
977
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
985
1014
class TestNotBzrDir(TestCaseWithTransport):
986
1015
"""Tests for using the bzrdir api with a non .bzr based disk format.
988
1017
If/when one of these is in the core, we can let the implementation tests
989
1018
verify this works.
992
1021
def test_create_and_find_format(self):
993
# create a .notbzr dir
1022
# create a .notbzr dir
994
1023
format = NotBzrDirFormat()
995
1024
dir = format.initialize(self.get_url())
996
1025
self.assertIsInstance(dir, NotBzrDir)
1073
1102
We can't inherit directly from TestCaseWithTwoWebservers or the
1074
1103
test framework will try to create an instance which cannot
1075
run, its implementation being incomplete.
1104
run, its implementation being incomplete.
1078
1107
def create_transport_readonly_server(self):
1133
1164
"""Tests redirections for pycurl implementation"""
1135
1166
def _qualified_url(self, host, port):
1136
return 'http+pycurl://%s:%s' % (host, port)
1167
result = 'http+pycurl://%s:%s' % (host, port)
1168
self.permit_url(result)
1139
1172
class TestHTTPRedirections_nosmart(TestHTTPRedirections,
1143
1176
_transport = NoSmartTransportDecorator
1145
1178
def _qualified_url(self, host, port):
1146
return 'nosmart+http://%s:%s' % (host, port)
1179
result = 'nosmart+http://%s:%s' % (host, port)
1180
self.permit_url(result)
1149
1184
class TestHTTPRedirections_readonly(TestHTTPRedirections,
1153
1188
_transport = ReadonlyTransportDecorator
1155
1190
def _qualified_url(self, host, port):
1156
return 'readonly+http://%s:%s' % (host, port)
1191
result = 'readonly+http://%s:%s' % (host, port)
1192
self.permit_url(result)
1159
1196
class TestDotBzrHidden(TestCaseWithTransport):
1211
1248
return _TestBzrDirFormat()
1251
class _TestBranchFormat(bzrlib.branch.BranchFormat):
1252
"""Test Branch format for TestBzrDirSprout."""
1214
1255
class _TestBranch(bzrlib.branch.Branch):
1215
1256
"""Test Branch implementation for TestBzrDirSprout."""
1217
1258
def __init__(self, *args, **kwargs):
1259
self._format = _TestBranchFormat()
1218
1260
super(_TestBranch, self).__init__(*args, **kwargs)
1219
1261
self.calls = []
1220
1262
self._parent = None
1241
1283
Usually, BzrDir.sprout should delegate to the branch's sprout method
1242
1284
for part of the work. This allows the source branch to control the
1243
1285
choice of format for the new branch.
1245
1287
There are exceptions, but this tests avoids them:
1246
1288
- if there's no branch in the source bzrdir,
1247
1289
- or if the stacking has been requested and the format needs to be
1268
1310
parent = grandparent_tree.bzrdir.sprout('parent').open_branch()
1269
1311
branch_tree = parent.bzrdir.sprout('branch').open_branch()
1270
1312
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)