44
46
TestCaseWithMemoryTransport,
45
47
TestCaseWithTransport,
48
from bzrlib.tests import(
51
from bzrlib.tests.http_server import HttpServer
52
from bzrlib.tests.http_utils import (
53
TestCaseWithTwoWebservers,
54
HTTPServerRedirecting,
52
56
from bzrlib.tests.test_http import TestWithTransport_pycurl
53
57
from bzrlib.transport import get_transport
54
58
from bzrlib.transport.http._urllib import HttpTransport_urllib
55
59
from bzrlib.transport.memory import MemoryServer
56
from bzrlib.transport.nosmart import NoSmartTransportDecorator
57
from bzrlib.transport.readonly import ReadonlyTransportDecorator
58
from bzrlib.repofmt import knitrepo, weaverepo, pack_repo
60
from bzrlib.repofmt import knitrepo, weaverepo
61
63
class TestDefaultFormat(TestCase):
127
129
my_format_registry = self.make_format_registry()
128
130
self.assertEqual('Format registered lazily',
129
131
my_format_registry.get_help('lazy'))
130
self.assertEqual('Format using knits',
132
self.assertEqual('Format using knits',
131
133
my_format_registry.get_help('knit'))
132
self.assertEqual('Format using knits',
134
self.assertEqual('Format using knits',
133
135
my_format_registry.get_help('default'))
134
136
self.assertEqual('Pre-0.8 format. Slower and does not support'
135
' checkouts or shared repositories',
137
' checkouts or shared repositories',
136
138
my_format_registry.get_help('weave'))
138
140
def test_help_topic(self):
139
141
topics = help_topics.HelpTopicRegistry()
140
registry = self.make_format_registry()
141
topics.register('current-formats', registry.help_topic,
143
topics.register('other-formats', registry.help_topic,
145
new = topics.get_detail('current-formats')
146
rest = topics.get_detail('other-formats')
142
topics.register('formats', self.make_format_registry().help_topic,
144
topic = topics.get_detail('formats')
145
new, rest = topic.split('Experimental formats')
147
146
experimental, deprecated = rest.split('Deprecated formats')
148
self.assertContainsRe(new, 'formats-help')
149
self.assertContainsRe(new,
147
self.assertContainsRe(new, 'These formats can be used')
148
self.assertContainsRe(new,
150
149
':knit:\n \(native\) \(default\) Format using knits\n')
151
self.assertContainsRe(experimental,
150
self.assertContainsRe(experimental,
152
151
':branch6:\n \(native\) Experimental successor to knit')
153
self.assertContainsRe(deprecated,
152
self.assertContainsRe(deprecated,
154
153
':lazy:\n \(native\) Format registered lazily\n')
155
154
self.assertNotContainsRe(new, 'hidden')
462
455
self.assertEqual(child_branch.base,
463
456
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
458
def test_sprout_obeys_stacking_policy(self):
478
459
child_branch, new_child_transport = self.prepare_default_stacking()
479
460
new_child = child_branch.bzrdir.sprout(new_child_transport.base)
526
507
self.assertTrue(repo.supports_rich_root())
528
509
def test_add_fallback_repo_handles_absolute_urls(self):
529
stack_on = self.make_branch('stack_on', format='1.6')
530
repo = self.make_repository('repo', format='1.6')
510
stack_on = self.make_branch('stack_on', format='development1')
511
repo = self.make_repository('repo', format='development1')
531
512
policy = bzrdir.UseExistingRepository(repo, stack_on.base)
532
513
policy._add_fallback(repo)
534
515
def test_add_fallback_repo_handles_relative_urls(self):
535
stack_on = self.make_branch('stack_on', format='1.6')
536
repo = self.make_repository('repo', format='1.6')
516
stack_on = self.make_branch('stack_on', format='development1')
517
repo = self.make_repository('repo', format='development1')
537
518
policy = bzrdir.UseExistingRepository(repo, '.', stack_on.base)
538
519
policy._add_fallback(repo)
540
521
def test_configure_relative_branch_stacking_url(self):
541
stack_on = self.make_branch('stack_on', format='1.6')
542
stacked = self.make_branch('stack_on/stacked', format='1.6')
522
stack_on = self.make_branch('stack_on', format='development1')
523
stacked = self.make_branch('stack_on/stacked', format='development1')
543
524
policy = bzrdir.UseExistingRepository(stacked.repository,
544
525
'.', stack_on.base)
545
526
policy.configure_branch(stacked)
546
527
self.assertEqual('..', stacked.get_stacked_on_url())
548
529
def test_relative_branch_stacking_to_absolute(self):
549
stack_on = self.make_branch('stack_on', format='1.6')
550
stacked = self.make_branch('stack_on/stacked', format='1.6')
530
stack_on = self.make_branch('stack_on', format='development1')
531
stacked = self.make_branch('stack_on/stacked', format='development1')
551
532
policy = bzrdir.UseExistingRepository(stacked.repository,
552
533
'.', self.get_readonly_url('stack_on'))
553
534
policy.configure_branch(stacked)
750
731
def test_sprout_recursive(self):
751
tree = self.make_branch_and_tree('tree1',
752
format='dirstate-with-subtree')
732
tree = self.make_branch_and_tree('tree1', format='dirstate-with-subtree')
753
733
sub_tree = self.make_branch_and_tree('tree1/subtree',
754
734
format='dirstate-with-subtree')
755
sub_tree.set_root_id('subtree-root')
756
735
tree.add_reference(sub_tree)
757
736
self.build_tree(['tree1/subtree/file'])
758
737
sub_tree.add('file')
759
738
tree.commit('Initial commit')
760
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
762
self.addCleanup(tree2.unlock)
739
tree.bzrdir.sprout('tree2')
763
740
self.failUnlessExists('tree2/subtree/file')
764
self.assertEqual('tree-reference', tree2.kind('subtree-root'))
766
742
def test_cloning_metadir(self):
767
743
"""Ensure that cloning metadir is suitable"""
894
870
def test_needs_conversion_different_working_tree(self):
895
871
# 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)
872
old_format = bzrdir.BzrDirFormat.get_default_format()
874
new_default = bzrdir.format_registry.make_bzrdir('dirstate')
875
bzrdir.BzrDirFormat._set_default_format(new_default)
877
tree = self.make_branch_and_tree('tree', format='knit')
878
self.assertTrue(tree.bzrdir.needs_format_conversion())
880
bzrdir.BzrDirFormat._set_default_format(old_format)
918
883
class TestFormat5(TestCaseWithTransport):
919
884
"""Tests specific to the version 5 bzrdir format."""
921
886
def test_same_lockfiles_between_tree_repo_branch(self):
922
# this checks that only a single lockfiles instance is created
887
# this checks that only a single lockfiles instance is created
923
888
# for format 5 objects
924
889
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
925
890
def check_dir_components_use_same_lock(dir):
932
897
# and if we open it normally.
933
898
dir = bzrdir.BzrDir.open(self.get_url())
934
899
check_dir_components_use_same_lock(dir)
936
901
def test_can_convert(self):
937
902
# format 5 dirs are convertable
938
903
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
939
904
self.assertTrue(dir.can_convert_format())
941
906
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()))
907
# format 5 dirs need a conversion if they are not the default.
908
# and they start of not the default.
909
old_format = bzrdir.BzrDirFormat.get_default_format()
910
bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirFormat5())
912
dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
913
self.assertFalse(dir.needs_format_conversion())
915
bzrdir.BzrDirFormat._set_default_format(old_format)
916
self.assertTrue(dir.needs_format_conversion())
952
919
class TestFormat6(TestCaseWithTransport):
953
920
"""Tests specific to the version 6 bzrdir format."""
955
922
def test_same_lockfiles_between_tree_repo_branch(self):
956
# this checks that only a single lockfiles instance is created
923
# this checks that only a single lockfiles instance is created
957
924
# for format 6 objects
958
925
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
959
926
def check_dir_components_use_same_lock(dir):
966
933
# and if we open it normally.
967
934
dir = bzrdir.BzrDir.open(self.get_url())
968
935
check_dir_components_use_same_lock(dir)
970
937
def test_can_convert(self):
971
938
# format 6 dirs are convertable
972
939
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
973
940
self.assertTrue(dir.can_convert_format())
975
942
def test_needs_conversion(self):
976
943
# 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()))
944
old_format = bzrdir.BzrDirFormat.get_default_format()
945
bzrdir.BzrDirFormat._set_default_format(bzrdir.BzrDirMetaFormat1())
947
dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
948
self.assertTrue(dir.needs_format_conversion())
950
bzrdir.BzrDirFormat._set_default_format(old_format)
982
953
class NotBzrDir(bzrlib.bzrdir.BzrDir):
1093
1064
workingtree.WorkingTreeFormat3)
1096
class TestHTTPRedirections(object):
1097
"""Test redirection between two http servers.
1067
class TestHTTPRedirectionLoop(object):
1068
"""Test redirection loop between two http servers.
1099
1070
This MUST be used by daughter classes that also inherit from
1100
1071
TestCaseWithTwoWebservers.
1102
1073
We can't inherit directly from TestCaseWithTwoWebservers or the
1103
1074
test framework will try to create an instance which cannot
1104
run, its implementation being incomplete.
1075
run, its implementation being incomplete.
1078
# Should be defined by daughter classes to ensure redirection
1079
# still use the same transport implementation (not currently
1080
# enforced as it's a bit tricky to get right (see the FIXME
1081
# in BzrDir.open_from_transport for the unique use case so
1107
1085
def create_transport_readonly_server(self):
1108
return http_utils.HTTPServerRedirecting()
1086
return HTTPServerRedirecting()
1110
1088
def create_transport_secondary_server(self):
1111
return http_utils.HTTPServerRedirecting()
1089
return HTTPServerRedirecting()
1113
1091
def setUp(self):
1114
super(TestHTTPRedirections, self).setUp()
1092
# Both servers redirect to each server creating a loop
1093
super(TestHTTPRedirectionLoop, self).setUp()
1115
1094
# The redirections will point to the new server
1116
1095
self.new_server = self.get_readonly_server()
1117
1096
# The requests to the old server will be redirected
1118
1097
self.old_server = self.get_secondary_server()
1119
1098
# Configure the redirections
1120
1099
self.old_server.redirect_to(self.new_server.host, self.new_server.port)
1100
self.new_server.redirect_to(self.old_server.host, self.old_server.port)
1102
def _qualified_url(self, host, port):
1103
return 'http+%s://%s:%s' % (self._qualifier, host, port)
1122
1105
def test_loop(self):
1123
# Both servers redirect to each other creating a loop
1124
self.new_server.redirect_to(self.old_server.host, self.old_server.port)
1125
1106
# Starting from either server should loop
1126
old_url = self._qualified_url(self.old_server.host,
1107
old_url = self._qualified_url(self.old_server.host,
1127
1108
self.old_server.port)
1128
1109
oldt = self._transport(old_url)
1129
1110
self.assertRaises(errors.NotBranchError,
1130
1111
bzrdir.BzrDir.open_from_transport, oldt)
1131
new_url = self._qualified_url(self.new_server.host,
1112
new_url = self._qualified_url(self.new_server.host,
1132
1113
self.new_server.port)
1133
1114
newt = self._transport(new_url)
1134
1115
self.assertRaises(errors.NotBranchError,
1135
1116
bzrdir.BzrDir.open_from_transport, newt)
1137
def test_qualifier_preserved(self):
1138
wt = self.make_branch_and_tree('branch')
1139
old_url = self._qualified_url(self.old_server.host,
1140
self.old_server.port)
1141
start = self._transport(old_url).clone('branch')
1142
bdir = bzrdir.BzrDir.open_from_transport(start)
1143
# Redirection should preserve the qualifier, hence the transport class
1145
self.assertIsInstance(bdir.root_transport, type(start))
1148
class TestHTTPRedirections_urllib(TestHTTPRedirections,
1149
http_utils.TestCaseWithTwoWebservers):
1119
class TestHTTPRedirections_urllib(TestHTTPRedirectionLoop,
1120
TestCaseWithTwoWebservers):
1150
1121
"""Tests redirections for urllib implementation"""
1123
_qualifier = 'urllib'
1152
1124
_transport = HttpTransport_urllib
1154
def _qualified_url(self, host, port):
1155
result = 'http+urllib://%s:%s' % (host, port)
1156
self.permit_url(result)
1161
1128
class TestHTTPRedirections_pycurl(TestWithTransport_pycurl,
1162
TestHTTPRedirections,
1163
http_utils.TestCaseWithTwoWebservers):
1129
TestHTTPRedirectionLoop,
1130
TestCaseWithTwoWebservers):
1164
1131
"""Tests redirections for pycurl implementation"""
1166
def _qualified_url(self, host, port):
1167
result = 'http+pycurl://%s:%s' % (host, port)
1168
self.permit_url(result)
1172
class TestHTTPRedirections_nosmart(TestHTTPRedirections,
1173
http_utils.TestCaseWithTwoWebservers):
1174
"""Tests redirections for the nosmart decorator"""
1176
_transport = NoSmartTransportDecorator
1178
def _qualified_url(self, host, port):
1179
result = 'nosmart+http://%s:%s' % (host, port)
1180
self.permit_url(result)
1184
class TestHTTPRedirections_readonly(TestHTTPRedirections,
1185
http_utils.TestCaseWithTwoWebservers):
1186
"""Tests redirections for readonly decoratror"""
1188
_transport = ReadonlyTransportDecorator
1190
def _qualified_url(self, host, port):
1191
result = 'readonly+http://%s:%s' % (host, port)
1192
self.permit_url(result)
1133
_qualifier = 'pycurl'
1196
1136
class TestDotBzrHidden(TestCaseWithTransport):
1310
1245
parent = grandparent_tree.bzrdir.sprout('parent').open_branch()
1311
1246
branch_tree = parent.bzrdir.sprout('branch').open_branch()
1312
1247
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)