151
151
self.expecting_body = True
152
152
return result[0], FakeProtocol(result[1], self)
154
def call_with_body_bytes_expecting_body(self, method, args, body):
155
self._calls.append(('call_with_body_bytes_expecting_body', method,
157
result = self.responses.pop(0)
158
self.expecting_body = True
159
return result[0], FakeProtocol(result[1], self)
155
162
class FakeMedium(object):
157
def __init__(self, base):
164
def __init__(self, base, client_calls):
166
self.connection = FakeConnection(client_calls)
167
self._client_calls = client_calls
170
class FakeConnection(object):
172
def __init__(self, client_calls):
173
self._remote_is_at_least_1_2 = True
174
self._client_calls = client_calls
176
def disconnect(self):
177
self._client_calls.append(('disconnect medium',))
180
class TestVfsHas(tests.TestCase):
182
def test_unicode_path(self):
183
client = FakeClient([(('yes',), )], '/')
184
transport = RemoteTransport('bzr://localhost/', _client=client)
185
filename = u'/hell\u00d8'.encode('utf8')
186
result = transport.has(filename)
188
[('call', 'has', (filename,))],
190
self.assertTrue(result)
161
193
class TestBzrDirOpenBranch(tests.TestCase):
164
196
transport = MemoryTransport()
165
197
transport.mkdir('quack')
166
198
transport = transport.clone('quack')
167
client = FakeClient([(('ok', ''), ), (('ok', '', 'no', 'no'), )],
199
client = FakeClient([(('ok', ''), ), (('ok', '', 'no', 'no', 'no'), )],
169
201
bzrdir = RemoteBzrDir(transport, _client=client)
170
202
result = bzrdir.open_branch()
171
203
self.assertEqual(
172
204
[('call', 'BzrDir.open_branch', ('quack/',)),
173
('call', 'BzrDir.find_repository', ('quack/',))],
205
('call', 'BzrDir.find_repositoryV2', ('quack/',))],
175
207
self.assertIsInstance(result, RemoteBranch)
176
208
self.assertEqual(bzrdir, result.bzrdir)
186
218
[('call', 'BzrDir.open_branch', ('quack/',))],
189
def check_open_repository(self, rich_root, subtrees):
221
def test__get_tree_branch(self):
222
# _get_tree_branch is a form of open_branch, but it should only ask for
223
# branch opening, not any other network requests.
226
calls.append("Called")
228
transport = MemoryTransport()
229
# no requests on the network - catches other api calls being made.
230
client = FakeClient([], transport.base)
231
bzrdir = RemoteBzrDir(transport, _client=client)
232
# patch the open_branch call to record that it was called.
233
bzrdir.open_branch = open_branch
234
self.assertEqual((None, "a-branch"), bzrdir._get_tree_branch())
235
self.assertEqual(["Called"], calls)
236
self.assertEqual([], client._calls)
238
def test_url_quoting_of_path(self):
239
# Relpaths on the wire should not be URL-escaped. So "~" should be
240
# transmitted as "~", not "%7E".
241
transport = RemoteTransport('bzr://localhost/~hello/')
242
client = FakeClient([(('ok', ''), ), (('ok', '', 'no', 'no', 'no'), )],
244
bzrdir = RemoteBzrDir(transport, _client=client)
245
result = bzrdir.open_branch()
247
[('call', 'BzrDir.open_branch', ('~hello/',)),
248
('call', 'BzrDir.find_repositoryV2', ('~hello/',))],
251
def check_open_repository(self, rich_root, subtrees, external_lookup='no'):
190
252
transport = MemoryTransport()
191
253
transport.mkdir('quack')
192
254
transport = transport.clone('quack')
198
260
subtree_response = 'yes'
200
262
subtree_response = 'no'
201
client = FakeClient([(('ok', '', rich_response, subtree_response), ),],
264
[(('ok', '', rich_response, subtree_response, external_lookup), ),],
203
266
bzrdir = RemoteBzrDir(transport, _client=client)
204
267
result = bzrdir.open_repository()
205
268
self.assertEqual(
206
[('call', 'BzrDir.find_repository', ('quack/',))],
269
[('call', 'BzrDir.find_repositoryV2', ('quack/',))],
208
271
self.assertIsInstance(result, RemoteRepository)
209
272
self.assertEqual(bzrdir, result.bzrdir)
624
class TestRepositoryGetGraph(TestRemoteRepository):
626
def test_get_graph(self):
627
# get_graph returns a graph with the repository as the
630
transport_path = 'quack'
631
repo, client = self.setup_fake_client_and_repository(
632
responses, transport_path)
633
graph = repo.get_graph()
634
self.assertEqual(graph._parents_provider, repo)
637
class TestRepositoryGetParentMap(TestRemoteRepository):
639
def test_get_parent_map_caching(self):
640
# get_parent_map returns from cache until unlock()
641
# setup a reponse with two revisions
642
r1 = u'\u0e33'.encode('utf8')
643
r2 = u'\u0dab'.encode('utf8')
644
lines = [' '.join([r2, r1]), r1]
645
encoded_body = bz2.compress('\n'.join(lines))
646
responses = [(('ok', ), encoded_body), (('ok', ), encoded_body)]
648
transport_path = 'quack'
649
repo, client = self.setup_fake_client_and_repository(
650
responses, transport_path)
652
graph = repo.get_graph()
653
parents = graph.get_parent_map([r2])
654
self.assertEqual({r2: (r1,)}, parents)
655
# locking and unlocking deeper should not reset
658
parents = graph.get_parent_map([r1])
659
self.assertEqual({r1: (NULL_REVISION,)}, parents)
661
[('call_with_body_bytes_expecting_body',
662
'Repository.get_parent_map', ('quack/', r2), '\n\n0')],
665
# now we call again, and it should use the second response.
667
graph = repo.get_graph()
668
parents = graph.get_parent_map([r1])
669
self.assertEqual({r1: (NULL_REVISION,)}, parents)
671
[('call_with_body_bytes_expecting_body',
672
'Repository.get_parent_map', ('quack/', r2), '\n\n0'),
673
('call_with_body_bytes_expecting_body',
674
'Repository.get_parent_map', ('quack/', r1), '\n\n0'),
679
def test_get_parent_map_reconnects_if_unknown_method(self):
681
"Generic bzr smart protocol error: "
682
"bad request 'Repository.get_parent_map'")
684
(('error', error_msg), ''),
686
transport_path = 'quack'
687
repo, client = self.setup_fake_client_and_repository(
688
responses, transport_path)
689
rev_id = 'revision-id'
690
parents = repo.get_parent_map([rev_id])
692
[('call_with_body_bytes_expecting_body',
693
'Repository.get_parent_map', ('quack/', rev_id), '\n\n0'),
694
('disconnect medium',),
695
('call_expecting_body', 'Repository.get_revision_graph',
557
701
class TestRepositoryGetRevisionGraph(TestRemoteRepository):
559
703
def test_null_revision(self):
811
955
transport_path = 'quack'
812
956
repo, client = self.setup_fake_client_and_repository(
813
957
responses, transport_path)
814
stream = repo.get_data_stream(['revid'])
958
search = graph.SearchResult(set(['revid']), set(), 1, set(['revid']))
959
stream = repo.get_data_stream_for_search(search)
815
960
self.assertRaises(errors.SmartProtocolError, list, stream)
817
962
def test_backwards_compatibility(self):