1803
1803
self.assertRaises(
1804
1804
errors.ReadingCompleted, smart_protocol.read_body_bytes)
1806
def test_client_read_body_bytes_interrupted_connection(self):
1807
server_bytes = "ok\n999\nincomplete body"
1808
input = StringIO(server_bytes)
1810
client_medium = medium.SmartSimplePipesClientMedium(
1811
input, output, 'base')
1812
request = client_medium.get_request()
1813
smart_protocol = self.client_protocol_class(request)
1814
smart_protocol.call('foo')
1815
smart_protocol.read_response_tuple(True)
1817
errors.ConnectionReset, smart_protocol.read_body_bytes)
1807
1820
class TestVersionOneFeaturesInProtocolTwo(
1808
1821
TestSmartProtocol, CommonSmartProtocolTestMixin):
2029
2042
self.assertRaises(
2030
2043
errors.ReadingCompleted, smart_protocol.read_body_bytes)
2045
def test_client_read_body_bytes_interrupted_connection(self):
2046
server_bytes = (self.response_marker +
2047
"success\nok\n999\nincomplete body")
2048
input = StringIO(server_bytes)
2050
client_medium = medium.SmartSimplePipesClientMedium(
2051
input, output, 'base')
2052
request = client_medium.get_request()
2053
smart_protocol = self.client_protocol_class(request)
2054
smart_protocol.call('foo')
2055
smart_protocol.read_response_tuple(True)
2057
errors.ConnectionReset, smart_protocol.read_body_bytes)
2033
2060
class TestSmartProtocolTwoSpecificsMixin(object):
2154
2181
stream = smart_protocol.read_streamed_body()
2155
2182
self.assertEqual(expected_chunks, list(stream))
2184
def test_streamed_body_bytes_interrupted_connection(self):
2185
body_header = 'chunked\n'
2186
incomplete_body_chunk = "9999\nincomplete chunk"
2187
server_bytes = (protocol.RESPONSE_VERSION_TWO +
2188
"success\nok\n" + body_header + incomplete_body_chunk)
2189
input = StringIO(server_bytes)
2191
client_medium = medium.SmartSimplePipesClientMedium(
2192
input, output, 'base')
2193
request = client_medium.get_request()
2194
smart_protocol = protocol.SmartClientRequestProtocolTwo(request)
2195
smart_protocol.call('foo')
2196
smart_protocol.read_response_tuple(True)
2197
stream = smart_protocol.read_streamed_body()
2198
self.assertRaises(errors.ConnectionReset, stream.next)
2157
2200
def test_client_read_response_tuple_sets_response_status(self):
2158
2201
server_bytes = protocol.RESPONSE_VERSION_TWO + "success\nok\n"
2159
2202
input = StringIO(server_bytes)
2339
2382
class TestConventionalResponseHandler(tests.TestCase):
2341
def test_interrupted_body_stream(self):
2342
interrupted_body_stream = (
2343
'oS' # successful response
2344
's\0\0\0\x02le' # empty args
2345
'b\0\0\0\x09chunk one' # first chunk
2346
'b\0\0\0\x09chunk two' # second chunk
2348
's\0\0\0\x0el5:error3:abce' # bencoded error
2384
def make_response_handler(self, response_bytes):
2351
2385
from bzrlib.smart.message import ConventionalResponseHandler
2352
2386
response_handler = ConventionalResponseHandler()
2353
2387
protocol_decoder = protocol.ProtocolThreeDecoder(response_handler)
2355
2389
protocol_decoder.state_accept = protocol_decoder._state_accept_expecting_message_part
2356
2390
output = StringIO()
2357
2391
client_medium = medium.SmartSimplePipesClientMedium(
2358
StringIO(interrupted_body_stream), output, 'base')
2392
StringIO(response_bytes), output, 'base')
2359
2393
medium_request = client_medium.get_request()
2360
2394
medium_request.finished_writing()
2361
2395
response_handler.setProtoAndMediumRequest(
2362
2396
protocol_decoder, medium_request)
2397
return response_handler
2399
def test_body_stream_interrupted_by_error(self):
2400
interrupted_body_stream = (
2401
'oS' # successful response
2402
's\0\0\0\x02le' # empty args
2403
'b\0\0\0\x09chunk one' # first chunk
2404
'b\0\0\0\x09chunk two' # second chunk
2406
's\0\0\0\x0el5:error3:abce' # bencoded error
2409
response_handler = self.make_response_handler(interrupted_body_stream)
2363
2410
stream = response_handler.read_streamed_body()
2364
2411
self.assertEqual('chunk one', stream.next())
2365
2412
self.assertEqual('chunk two', stream.next())
2366
2413
exc = self.assertRaises(errors.ErrorFromSmartServer, stream.next)
2367
2414
self.assertEqual(('error', 'abc'), exc.error_tuple)
2416
def test_body_stream_interrupted_by_connection_lost(self):
2417
interrupted_body_stream = (
2418
'oS' # successful response
2419
's\0\0\0\x02le' # empty args
2420
'b\0\0\xff\xffincomplete chunk')
2421
response_handler = self.make_response_handler(interrupted_body_stream)
2422
stream = response_handler.read_streamed_body()
2423
self.assertRaises(errors.ConnectionReset, stream.next)
2425
def test_read_body_bytes_interrupted_by_connection_lost(self):
2426
interrupted_body_stream = (
2427
'oS' # successful response
2428
's\0\0\0\x02le' # empty args
2429
'b\0\0\xff\xffincomplete chunk')
2430
response_handler = self.make_response_handler(interrupted_body_stream)
2432
errors.ConnectionReset, response_handler.read_body_bytes)
2370
2435
class TestMessageHandlerErrors(tests.TestCase):
2371
2436
"""Tests for v3 that unrecognised (but well-formed) requests/responses are
2709
2774
self.assertCallDoesNotBreakMedium('method', ('args',), u'body')
2712
class MockMedium(object):
2777
class MockMedium(medium.SmartClientMedium):
2713
2778
"""A mock medium that can be used to test _SmartClient.
2715
2780
It can be given a series of requests to expect (and responses it should
2728
2793
def __init__(self):
2729
self.base = 'dummy base'
2794
super(MockMedium, self).__init__('dummy base')
2730
2795
self._mock_request = _MockMediumRequest(self)
2731
2796
self._expected_events = []
2732
self._protocol_version = None
2734
2798
def expect_request(self, request_bytes, response_bytes,
2735
2799
allow_partial_read=False):
2866
2930
# medium, and the smart_client returns the response from the server.
2867
2931
self.assertEqual(('response value',), result)
2868
2932
self.assertEqual([], medium._expected_events)
2933
# Also, the v3 works then the server should be assumed to support RPCs
2934
# introduced in 1.6.
2935
self.assertFalse(medium._is_remote_before((1, 6)))
2870
2937
def test_version_two_server(self):
2871
2938
"""If the server only speaks protocol 2, the client will first try
2904
2971
self.assertEqual(('another response',), result)
2905
2972
self.assertEqual([], medium._expected_events)
2974
# Also, because v3 is not supported, the client medium should assume
2975
# that RPCs introduced in 1.6 aren't supported either.
2976
self.assertTrue(medium._is_remote_before((1, 6)))
2907
2978
def test_unknown_version(self):
2908
2979
"""If the server does not use any known (or at least supported)
2909
2980
protocol version, a SmartProtocolError is raised.