45
45
from bzrlib.branch import Branch
46
from bzrlib.bzrdir import BzrDir, BzrDirFormat
46
from bzrlib.bzrdir import (
47
51
from bzrlib.remote import (
49
53
RemoteBranchFormat,
53
56
RemoteRepositoryFormat,
55
58
from bzrlib.repofmt import groupcompress_repo, pack_repo
56
59
from bzrlib.revision import NULL_REVISION
57
from bzrlib.smart import medium
60
from bzrlib.smart import medium, request
58
61
from bzrlib.smart.client import _SmartClient
59
from bzrlib.smart.repository import SmartServerRepositoryGetParentMap
62
from bzrlib.smart.repository import (
63
SmartServerRepositoryGetParentMap,
64
SmartServerRepositoryGetStream_1_19,
60
66
from bzrlib.tests import (
62
split_suite_by_condition,
66
from bzrlib.transport import get_transport
69
from bzrlib.tests.scenarios import load_tests_apply_scenarios
67
70
from bzrlib.transport.memory import MemoryTransport
68
71
from bzrlib.transport.remote import (
70
73
RemoteSSHTransport,
71
74
RemoteTCPTransport,
74
def load_tests(standard_tests, module, loader):
75
to_adapt, result = split_suite_by_condition(
76
standard_tests, condition_isinstance(BasicRemoteObjectTests))
77
smart_server_version_scenarios = [
78
load_tests = load_tests_apply_scenarios
81
class BasicRemoteObjectTests(tests.TestCaseWithTransport):
79
{'transport_server': test_server.SmartTCPServer_for_testing_v2_only}),
85
{'transport_server': test_server.SmartTCPServer_for_testing_v2_only}),
81
{'transport_server': test_server.SmartTCPServer_for_testing})]
82
return multiply_tests(to_adapt, smart_server_version_scenarios, result)
85
class BasicRemoteObjectTests(tests.TestCaseWithTransport):
87
{'transport_server': test_server.SmartTCPServer_for_testing})]
88
91
super(BasicRemoteObjectTests, self).setUp()
89
92
self.transport = self.get_transport()
90
93
# make a branch that can be opened over the smart transport
91
94
self.local_wt = BzrDir.create_standalone_workingtree('.')
94
self.transport.disconnect()
95
tests.TestCaseWithTransport.tearDown(self)
95
self.addCleanup(self.transport.disconnect)
97
97
def test_create_remote_bzrdir(self):
98
98
b = remote.RemoteBzrDir(self.transport, remote.RemoteBzrDirFormat())
122
122
def test_find_correct_format(self):
123
123
"""Should open a RemoteBzrDir over a RemoteTransport"""
124
124
fmt = BzrDirFormat.find_format(self.transport)
125
self.assertTrue(RemoteBzrDirFormat
126
in BzrDirFormat._control_server_formats)
125
self.assertTrue(bzrdir.RemoteBzrProber
126
in controldir.ControlDirFormat._server_probers)
127
127
self.assertIsInstance(fmt, remote.RemoteBzrDirFormat)
129
129
def test_open_detected_smart_format(self):
1652
1652
branch.unlock()
1653
1653
self.assertFinished(client)
1655
def test_set_option_with_dict(self):
1656
client = FakeClient()
1657
client.add_expected_call(
1658
'Branch.get_stacked_on_url', ('memory:///',),
1659
'error', ('NotStacked',),)
1660
client.add_expected_call(
1661
'Branch.lock_write', ('memory:///', '', ''),
1662
'success', ('ok', 'branch token', 'repo token'))
1663
encoded_dict_value = 'd5:ascii1:a11:unicode \xe2\x8c\x9a3:\xe2\x80\xbde'
1664
client.add_expected_call(
1665
'Branch.set_config_option_dict', ('memory:///', 'branch token',
1666
'repo token', encoded_dict_value, 'foo', ''),
1668
client.add_expected_call(
1669
'Branch.unlock', ('memory:///', 'branch token', 'repo token'),
1671
transport = MemoryTransport()
1672
branch = self.make_remote_branch(transport, client)
1674
config = branch._get_config()
1676
{'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'},
1679
self.assertFinished(client)
1655
1681
def test_backwards_compat_set_option(self):
1656
1682
self.setup_smart_server_with_call_log()
1657
1683
branch = self.make_branch('.')
1664
1690
self.assertLength(10, self.hpss_calls)
1665
1691
self.assertEqual('value', branch._get_config().get_option('name'))
1693
def test_backwards_compat_set_option_with_dict(self):
1694
self.setup_smart_server_with_call_log()
1695
branch = self.make_branch('.')
1696
verb = 'Branch.set_config_option_dict'
1697
self.disable_verb(verb)
1699
self.addCleanup(branch.unlock)
1700
self.reset_smart_call_log()
1701
config = branch._get_config()
1702
value_dict = {'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'}
1703
config.set_option(value_dict, 'name')
1704
self.assertLength(10, self.hpss_calls)
1705
self.assertEqual(value_dict, branch._get_config().get_option('name'))
1668
1708
class TestBranchLockWrite(RemoteBranchTestCase):
2301
2342
transport_path = 'quack'
2302
2343
repo, client = self.setup_fake_client_and_repository(transport_path)
2303
2344
client.add_success_response('ok', 'a token')
2304
result = repo.lock_write()
2345
token = repo.lock_write().repository_token
2305
2346
self.assertEqual(
2306
2347
[('call', 'Repository.lock_write', ('quack/', ''))],
2308
self.assertEqual('a token', result)
2349
self.assertEqual('a token', token)
2310
2351
def test_lock_write_already_locked(self):
2311
2352
transport_path = 'quack'
3143
3184
def test_copy_content_into_avoids_revision_history(self):
3144
3185
local = self.make_branch('local')
3145
remote_backing_tree = self.make_branch_and_tree('remote')
3146
remote_backing_tree.commit("Commit.")
3186
builder = self.make_branch_builder('remote')
3187
builder.build_commit(message="Commit.")
3147
3188
remote_branch_url = self.smart_server.get_url() + 'remote'
3148
3189
remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
3149
3190
local.repository.fetch(remote_branch.repository)
3150
3191
self.hpss_calls = []
3151
3192
remote_branch.copy_content_into(local)
3152
3193
self.assertFalse('Branch.revision_history' in self.hpss_calls)
3195
def test_fetch_everything_needs_just_one_call(self):
3196
local = self.make_branch('local')
3197
builder = self.make_branch_builder('remote')
3198
builder.build_commit(message="Commit.")
3199
remote_branch_url = self.smart_server.get_url() + 'remote'
3200
remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
3201
self.hpss_calls = []
3202
local.repository.fetch(remote_branch.repository,
3203
fetch_spec=graph.EverythingResult(remote_branch.repository))
3204
self.assertEqual(['Repository.get_stream_1.19'], self.hpss_calls)
3206
def override_verb(self, verb_name, verb):
3207
request_handlers = request.request_handlers
3208
orig_verb = request_handlers.get(verb_name)
3209
request_handlers.register(verb_name, verb, override_existing=True)
3210
self.addCleanup(request_handlers.register, verb_name, orig_verb,
3211
override_existing=True)
3213
def test_fetch_everything_backwards_compat(self):
3214
"""Can fetch with EverythingResult even with pre 2.4 servers.
3216
Pre-2.4 do not support 'everything' searches with the
3217
Repository.get_stream_1.19 verb.
3220
class OldGetStreamVerb(SmartServerRepositoryGetStream_1_19):
3221
"""A version of the Repository.get_stream_1.19 verb patched to
3222
reject 'everything' searches the way 2.3 and earlier do.
3224
def recreate_search(self, repository, search_bytes, discard_excess=False):
3225
verb_log.append(search_bytes.split('\n', 1)[0])
3226
if search_bytes == 'everything':
3227
return (None, request.FailedSmartServerResponse(('BadSearch',)))
3228
return super(OldGetStreamVerb,
3229
self).recreate_search(repository, search_bytes,
3230
discard_excess=discard_excess)
3231
self.override_verb('Repository.get_stream_1.19', OldGetStreamVerb)
3232
local = self.make_branch('local')
3233
builder = self.make_branch_builder('remote')
3234
builder.build_commit(message="Commit.")
3235
remote_branch_url = self.smart_server.get_url() + 'remote'
3236
remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
3237
self.hpss_calls = []
3238
local.repository.fetch(remote_branch.repository,
3239
fetch_spec=graph.EverythingResult(remote_branch.repository))
3240
# make sure the overridden verb was used
3241
self.assertLength(1, verb_log)
3242
# more than one HPSS call is needed, but because it's a VFS callback
3243
# its hard to predict exactly how many.
3244
self.assertTrue(len(self.hpss_calls) > 1)