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
47
TestCaseWithMemoryTransport,
46
48
TestCaseWithTransport,
49
52
from bzrlib.tests import(
53
56
from bzrlib.tests.test_http import TestWithTransport_pycurl
54
from bzrlib.transport import (
57
from bzrlib.transport import get_transport
58
58
from bzrlib.transport.http._urllib import HttpTransport_urllib
59
from bzrlib.transport.memory import MemoryServer
59
60
from bzrlib.transport.nosmart import NoSmartTransportDecorator
60
61
from bzrlib.transport.readonly import ReadonlyTransportDecorator
61
from bzrlib.repofmt import knitrepo, weaverepo, pack_repo
62
from bzrlib.repofmt import knitrepo, weaverepo
64
65
class TestDefaultFormat(TestCase):
84
85
my_format_registry.register('weave', bzrdir.BzrDirFormat6,
85
86
'Pre-0.8 format. Slower and does not support checkouts or shared'
86
87
' repositories', deprecated=True)
87
my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir',
88
my_format_registry.register_lazy('lazy', 'bzrlib.bzrdir',
88
89
'BzrDirFormat6', 'Format registered lazily', deprecated=True)
89
90
my_format_registry.register_metadir('knit',
90
91
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
117
118
my_bzrdir = my_format_registry.make_bzrdir('weave')
118
119
self.assertIsInstance(my_bzrdir, bzrdir.BzrDirFormat6)
119
120
my_bzrdir = my_format_registry.make_bzrdir('default')
120
self.assertIsInstance(my_bzrdir.repository_format,
121
self.assertIsInstance(my_bzrdir.repository_format,
121
122
knitrepo.RepositoryFormatKnit1)
122
123
my_bzrdir = my_format_registry.make_bzrdir('knit')
123
self.assertIsInstance(my_bzrdir.repository_format,
124
self.assertIsInstance(my_bzrdir.repository_format,
124
125
knitrepo.RepositoryFormatKnit1)
125
126
my_bzrdir = my_format_registry.make_bzrdir('branch6')
126
127
self.assertIsInstance(my_bzrdir.get_branch_format(),
130
131
my_format_registry = self.make_format_registry()
131
132
self.assertEqual('Format registered lazily',
132
133
my_format_registry.get_help('lazy'))
133
self.assertEqual('Format using knits',
134
self.assertEqual('Format using knits',
134
135
my_format_registry.get_help('knit'))
135
self.assertEqual('Format using knits',
136
self.assertEqual('Format using knits',
136
137
my_format_registry.get_help('default'))
137
138
self.assertEqual('Pre-0.8 format. Slower and does not support'
138
' checkouts or shared repositories',
139
' checkouts or shared repositories',
139
140
my_format_registry.get_help('weave'))
141
142
def test_help_topic(self):
142
143
topics = help_topics.HelpTopicRegistry()
143
144
registry = self.make_format_registry()
144
topics.register('current-formats', registry.help_topic,
145
topics.register('current-formats', registry.help_topic,
145
146
'Current formats')
146
topics.register('other-formats', registry.help_topic,
147
topics.register('other-formats', registry.help_topic,
148
149
new = topics.get_detail('current-formats')
149
150
rest = topics.get_detail('other-formats')
150
151
experimental, deprecated = rest.split('Deprecated formats')
151
self.assertContainsRe(new, 'formats-help')
152
self.assertContainsRe(new,
152
self.assertContainsRe(new, 'bzr help formats')
153
self.assertContainsRe(new,
153
154
':knit:\n \(native\) \(default\) Format using knits\n')
154
self.assertContainsRe(experimental,
155
self.assertContainsRe(experimental,
155
156
':branch6:\n \(native\) Experimental successor to knit')
156
self.assertContainsRe(deprecated,
157
self.assertContainsRe(deprecated,
157
158
':lazy:\n \(native\) Format registered lazily\n')
158
159
self.assertNotContainsRe(new, 'hidden')
207
208
"""See BzrDir.open_repository."""
208
209
return SampleRepository(self)
210
def create_branch(self, name=None):
211
def create_branch(self):
211
212
"""See BzrDir.create_branch."""
213
raise NoColocatedBranchSupport(self)
214
213
return SampleBranch(self)
216
215
def create_workingtree(self):
248
247
def test_find_format(self):
249
248
# is the right format object found for a branch?
250
249
# create a branch with a few known format objects.
251
# this is not quite the same as
250
# this is not quite the same as
252
251
t = get_transport(self.get_url())
253
252
self.build_tree(["foo/", "bar/"], transport=t)
254
253
def check_format(format, url):
258
257
self.failUnless(isinstance(found_format, format.__class__))
259
258
check_format(bzrdir.BzrDirFormat5(), "foo")
260
259
check_format(bzrdir.BzrDirFormat6(), "bar")
262
261
def test_find_format_nothing_there(self):
263
262
self.assertRaises(NotBranchError,
264
263
bzrdir.BzrDirFormat.find_format,
308
307
branch.bzrdir.open_repository)
310
309
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
310
# creating a branch and repo in a shared repo can be forced to
312
311
# make a new repo
313
312
format = bzrdir.format_registry.make_bzrdir('knit')
314
313
self.make_repository('.', shared=True, format=format)
320
319
def test_create_standalone_working_tree(self):
321
320
format = SampleBzrDirFormat()
322
# note this is deliberately readonly, as this failure should
321
# note this is deliberately readonly, as this failure should
323
322
# occur before any writes.
324
323
self.assertRaises(errors.NotLocalUrl,
325
324
bzrdir.BzrDir.create_standalone_workingtree,
326
325
self.get_readonly_url(), format=format)
327
tree = bzrdir.BzrDir.create_standalone_workingtree('.',
326
tree = bzrdir.BzrDir.create_standalone_workingtree('.',
329
328
self.assertEqual('A tree', tree)
332
331
# create standalone working tree always makes a repo.
333
332
format = bzrdir.format_registry.make_bzrdir('knit')
334
333
self.make_repository('.', shared=True, format=format)
335
# note this is deliberately readonly, as this failure should
334
# note this is deliberately readonly, as this failure should
336
335
# occur before any writes.
337
336
self.assertRaises(errors.NotLocalUrl,
338
337
bzrdir.BzrDir.create_standalone_workingtree,
339
338
self.get_readonly_url('child'), format=format)
340
tree = bzrdir.BzrDir.create_standalone_workingtree('child',
339
tree = bzrdir.BzrDir.create_standalone_workingtree('child',
342
341
tree.bzrdir.open_repository()
360
359
def test_create_branch_convenience_root(self):
361
360
"""Creating a branch at the root of a fs should work."""
362
self.vfs_transport_factory = memory.MemoryServer
361
self.vfs_transport_factory = MemoryServer
363
362
# outside a repo the default convenience output is a repo+branch_tree
364
363
format = bzrdir.format_registry.make_bzrdir('knit')
365
branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(),
364
branch = bzrdir.BzrDir.create_branch_convenience(self.get_url(),
367
366
self.assertRaises(errors.NoWorkingTree,
368
367
branch.bzrdir.open_workingtree)
378
377
branch.bzrdir.open_workingtree()
379
378
self.assertRaises(errors.NoRepositoryPresent,
380
379
branch.bzrdir.open_repository)
382
381
def test_create_branch_convenience_under_shared_repo_force_no_tree(self):
383
382
# inside a repo the default convenience output is a branch+ follow the
384
383
# repo tree policy but we can override that
390
389
branch.bzrdir.open_workingtree)
391
390
self.assertRaises(errors.NoRepositoryPresent,
392
391
branch.bzrdir.open_repository)
394
393
def test_create_branch_convenience_under_shared_repo_no_tree_policy(self):
395
394
# inside a repo the default convenience output is a branch+ follow the
396
395
# repo tree policy
397
396
format = bzrdir.format_registry.make_bzrdir('knit')
398
397
repo = self.make_repository('.', shared=True, format=format)
399
398
repo.set_make_working_trees(False)
400
branch = bzrdir.BzrDir.create_branch_convenience('child',
399
branch = bzrdir.BzrDir.create_branch_convenience('child',
402
401
self.assertRaises(errors.NoWorkingTree,
403
402
branch.bzrdir.open_workingtree)
433
432
"""The default acquisition policy should create a standalone branch."""
434
433
my_bzrdir = self.make_bzrdir('.')
435
434
repo_policy = my_bzrdir.determine_repository_policy()
436
repo, is_new = repo_policy.acquire_repository()
435
repo = repo_policy.acquire_repository()
437
436
self.assertEqual(repo.bzrdir.root_transport.base,
438
437
my_bzrdir.root_transport.base)
439
438
self.assertFalse(repo.is_shared())
441
441
def test_determine_stacking_policy(self):
442
442
parent_bzrdir = self.make_bzrdir('.')
443
443
child_bzrdir = self.make_bzrdir('child')
467
467
self.assertEqual(child_branch.base,
468
468
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
470
def test_sprout_obeys_stacking_policy(self):
484
471
child_branch, new_child_transport = self.prepare_default_stacking()
485
472
new_child = child_branch.bzrdir.sprout(new_child_transport.base)
573
560
super(ChrootedTests, self).setUp()
574
if not self.vfs_transport_factory == memory.MemoryServer:
561
if not self.vfs_transport_factory == MemoryServer:
575
562
self.transport_readonly_server = http_server.HttpServer
577
564
def local_branch_path(self, branch):
739
726
opened_bzrdir = bzrdir.BzrDir.open_from_transport(transport)
740
727
self.assertEqual(transport.base, opened_bzrdir.root_transport.base)
741
728
self.assertIsInstance(opened_bzrdir, bzrdir.BzrDir)
743
730
def test_open_from_transport_no_bzrdir(self):
744
731
transport = get_transport(self.get_url())
745
732
self.assertRaises(NotBranchError, bzrdir.BzrDir.open_from_transport,
756
743
def test_sprout_recursive(self):
757
tree = self.make_branch_and_tree('tree1',
758
format='dirstate-with-subtree')
744
tree = self.make_branch_and_tree('tree1', format='dirstate-with-subtree')
759
745
sub_tree = self.make_branch_and_tree('tree1/subtree',
760
746
format='dirstate-with-subtree')
761
sub_tree.set_root_id('subtree-root')
762
747
tree.add_reference(sub_tree)
763
748
self.build_tree(['tree1/subtree/file'])
764
749
sub_tree.add('file')
765
750
tree.commit('Initial commit')
766
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
768
self.addCleanup(tree2.unlock)
751
tree.bzrdir.sprout('tree2')
769
752
self.failUnlessExists('tree2/subtree/file')
770
self.assertEqual('tree-reference', tree2.kind('subtree-root'))
772
754
def test_cloning_metadir(self):
773
755
"""Ensure that cloning metadir is suitable"""
925
907
"""Tests specific to the version 5 bzrdir format."""
927
909
def test_same_lockfiles_between_tree_repo_branch(self):
928
# this checks that only a single lockfiles instance is created
910
# this checks that only a single lockfiles instance is created
929
911
# for format 5 objects
930
912
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
931
913
def check_dir_components_use_same_lock(dir):
938
920
# and if we open it normally.
939
921
dir = bzrdir.BzrDir.open(self.get_url())
940
922
check_dir_components_use_same_lock(dir)
942
924
def test_can_convert(self):
943
925
# format 5 dirs are convertable
944
926
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
945
927
self.assertTrue(dir.can_convert_format())
947
929
def test_needs_conversion(self):
948
930
# format 5 dirs need a conversion if they are not the default,
949
931
# and they aren't
959
941
"""Tests specific to the version 6 bzrdir format."""
961
943
def test_same_lockfiles_between_tree_repo_branch(self):
962
# this checks that only a single lockfiles instance is created
944
# this checks that only a single lockfiles instance is created
963
945
# for format 6 objects
964
946
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
965
947
def check_dir_components_use_same_lock(dir):
972
954
# and if we open it normally.
973
955
dir = bzrdir.BzrDir.open(self.get_url())
974
956
check_dir_components_use_same_lock(dir)
976
958
def test_can_convert(self):
977
959
# format 6 dirs are convertable
978
960
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
979
961
self.assertTrue(dir.can_convert_format())
981
963
def test_needs_conversion(self):
982
964
# format 6 dirs need an conversion if they are not the default.
983
965
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
1020
1002
class TestNotBzrDir(TestCaseWithTransport):
1021
1003
"""Tests for using the bzrdir api with a non .bzr based disk format.
1023
1005
If/when one of these is in the core, we can let the implementation tests
1024
1006
verify this works.
1027
1009
def test_create_and_find_format(self):
1028
# create a .notbzr dir
1010
# create a .notbzr dir
1029
1011
format = NotBzrDirFormat()
1030
1012
dir = format.initialize(self.get_url())
1031
1013
self.assertIsInstance(dir, NotBzrDir)
1056
1038
def setUp(self):
1057
1039
super(NonLocalTests, self).setUp()
1058
self.vfs_transport_factory = memory.MemoryServer
1040
self.vfs_transport_factory = MemoryServer
1060
1042
def test_create_branch_convenience(self):
1061
1043
# outside a repo the default convenience output is a repo+branch_tree
1062
1044
format = bzrdir.format_registry.make_bzrdir('knit')
1108
1090
We can't inherit directly from TestCaseWithTwoWebservers or the
1109
1091
test framework will try to create an instance which cannot
1110
run, its implementation being incomplete.
1092
run, its implementation being incomplete.
1113
1095
def create_transport_readonly_server(self):
1170
1150
"""Tests redirections for pycurl implementation"""
1172
1152
def _qualified_url(self, host, port):
1173
result = 'http+pycurl://%s:%s' % (host, port)
1174
self.permit_url(result)
1153
return 'http+pycurl://%s:%s' % (host, port)
1178
1156
class TestHTTPRedirections_nosmart(TestHTTPRedirections,
1182
1160
_transport = NoSmartTransportDecorator
1184
1162
def _qualified_url(self, host, port):
1185
result = 'nosmart+http://%s:%s' % (host, port)
1186
self.permit_url(result)
1163
return 'nosmart+http://%s:%s' % (host, port)
1190
1166
class TestHTTPRedirections_readonly(TestHTTPRedirections,
1194
1170
_transport = ReadonlyTransportDecorator
1196
1172
def _qualified_url(self, host, port):
1197
result = 'readonly+http://%s:%s' % (host, port)
1198
self.permit_url(result)
1173
return 'readonly+http://%s:%s' % (host, port)
1202
1176
class TestDotBzrHidden(TestCaseWithTransport):
1254
1228
return _TestBzrDirFormat()
1257
class _TestBranchFormat(bzrlib.branch.BranchFormat):
1258
"""Test Branch format for TestBzrDirSprout."""
1261
1231
class _TestBranch(bzrlib.branch.Branch):
1262
1232
"""Test Branch implementation for TestBzrDirSprout."""
1264
1234
def __init__(self, *args, **kwargs):
1265
self._format = _TestBranchFormat()
1266
1235
super(_TestBranch, self).__init__(*args, **kwargs)
1267
1236
self.calls = []
1268
1237
self._parent = None
1289
1258
Usually, BzrDir.sprout should delegate to the branch's sprout method
1290
1259
for part of the work. This allows the source branch to control the
1291
1260
choice of format for the new branch.
1293
1262
There are exceptions, but this tests avoids them:
1294
1263
- if there's no branch in the source bzrdir,
1295
1264
- or if the stacking has been requested and the format needs to be
1316
1285
parent = grandparent_tree.bzrdir.sprout('parent').open_branch()
1317
1286
branch_tree = parent.bzrdir.sprout('branch').open_branch()
1318
1287
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'))