1614
1614
self.assertOffsetSerialisation([(1,2), (3,4), (100, 200)],
1615
1615
'1,2\n3,4\n100,200', self.client_protocol)
1617
def assertBodyStreamSerialisation(self, expected_serialisation,
1619
"""Assert that body_stream is serialised as expected_serialisation."""
1620
out_stream = StringIO()
1621
smart_protocol = self.server_protocol_class(None, out_stream.write)
1622
response = request.SuccessfulSmartServerResponse(
1623
('args',), body_stream=body_stream)
1624
smart_protocol._send_response(response)
1625
expected_prefix = protocol.RESPONSE_VERSION_TWO + 'success\n'
1626
expected_args = 'args\n'
1627
self.assertStartsWith(
1628
out_stream.getvalue(), expected_prefix + expected_args)
1629
body = out_stream.getvalue()[len(expected_prefix + expected_args):]
1630
self.assertEqual(expected_serialisation, body)
1632
def test_body_stream_serialisation_empty(self):
1633
"""A body_stream with no bytes can be serialised."""
1634
self.assertBodyStreamSerialisation('0\n', [])
1636
def test_body_stream_serialisation(self):
1637
self.assertBodyStreamSerialisation(
1638
'9\nchunk one' + '9\nchunk two' + 'b\nchunk three' + '0\n',
1639
['chunk one', 'chunk two', 'chunk three'])
1641
def test_body_stream_with_empty_element_serialisation(self):
1642
"""A body stream that includes '' does not prematurely end the stream.
1644
If the body stream yields an empty string, the protocol should not send
1645
an empty chunk, because that is the signal for end-of-stream.
1647
self.assertBodyStreamSerialisation('5\nchunk' + '0\n', ['', 'chunk'])
1617
1649
def test_accept_bytes_of_bad_request_to_protocol(self):
1618
1650
out_stream = StringIO()
1619
1651
smart_protocol = protocol.SmartServerRequestProtocolTwo(
1700
1732
request.SuccessfulSmartServerResponse(('x',)))
1701
1733
self.assertEqual(0, smart_protocol.next_read_size())
1735
def test__send_response_with_body_stream_sets_finished_reading(self):
1736
smart_protocol = protocol.SmartServerRequestProtocolTwo(
1737
None, lambda x: None)
1738
self.assertEqual(1, smart_protocol.next_read_size())
1739
smart_protocol._send_response(
1740
request.SuccessfulSmartServerResponse(('x',), body_stream=[]))
1741
self.assertEqual(0, smart_protocol.next_read_size())
1703
1743
def test__send_response_errors_with_base_response(self):
1704
1744
"""Ensure that only the Successful/Failed subclasses are used."""
1705
1745
smart_protocol = protocol.SmartServerRequestProtocolTwo(
1833
1873
def test_client_cancel_read_body_does_not_eat_body_bytes(self):
1834
1874
# cancelling the expected body needs to finish the request, but not
1835
1875
# read any more bytes.
1836
expected_bytes = "1234567"
1837
1876
server_bytes = (protocol.RESPONSE_VERSION_TWO +
1838
1877
"success\nok\n7\n1234567done\n")
1839
1878
input = StringIO(server_bytes)
1849
1888
self.assertRaises(
1850
1889
errors.ReadingCompleted, smart_protocol.read_body_bytes)
1891
def test_streamed_body_bytes(self):
1892
two_body_chunks = "4\n1234" + "3\n567"
1893
body_terminator = "0\n"
1894
server_bytes = (protocol.RESPONSE_VERSION_TWO +
1895
"success\nok\n" + two_body_chunks + body_terminator)
1896
input = StringIO(server_bytes)
1898
client_medium = medium.SmartSimplePipesClientMedium(input, output)
1899
request = client_medium.get_request()
1900
smart_protocol = protocol.SmartClientRequestProtocolTwo(request)
1901
smart_protocol.call('foo')
1902
smart_protocol.read_response_tuple(True)
1903
stream = smart_protocol.read_streamed_body()
1904
self.assertEqual(['1234', '567'], list(stream))
1853
1907
class TestSmartClientUnicode(tests.TestCase):
1854
1908
"""_SmartClient tests for unicode arguments.
2015
2069
self.assertFalse(decoder.finished_reading)
2016
2070
self.assertEqual('', decoder.read_pending_data())
2018
def test_accept_two_chunks(self):
2072
def test_two_chunks(self):
2019
2073
"""Content from multiple chunks is concatenated."""
2020
2074
decoder = protocol.ChunkedBodyDecoder()
2021
2075
chunk_one = '3\naaa'
2068
2122
self.assertEqual(chunk_content, decoder.read_pending_data())
2069
2123
self.assertEqual('', decoder.unused_data)
2125
def test_read_pending_data_resets(self):
2126
"""read_pending_data does not return the same bytes twice."""
2127
decoder = protocol.ChunkedBodyDecoder()
2128
chunk_one = '3\naaa'
2129
chunk_two = '3\nbbb'
2131
decoder.accept_bytes(chunk_one)
2132
self.assertEqual('aaa', decoder.read_pending_data())
2133
decoder.accept_bytes(chunk_two)
2134
self.assertEqual('bbb', decoder.read_pending_data())
2135
self.assertEqual('', decoder.read_pending_data())
2072
2138
class TestSuccessfulSmartServerResponse(tests.TestCase):
2074
def test_construct(self):
2140
def test_construct_no_body(self):
2075
2141
response = request.SuccessfulSmartServerResponse(('foo', 'bar'))
2076
2142
self.assertEqual(('foo', 'bar'), response.args)
2077
2143
self.assertEqual(None, response.body)
2078
response = request.SuccessfulSmartServerResponse(('foo', 'bar'), 'bytes')
2145
def test_construct_with_body(self):
2146
response = request.SuccessfulSmartServerResponse(
2147
('foo', 'bar'), 'bytes')
2079
2148
self.assertEqual(('foo', 'bar'), response.args)
2080
2149
self.assertEqual('bytes', response.body)
2151
def test_construct_with_body_stream(self):
2152
bytes_iterable = ['abc']
2153
response = request.SuccessfulSmartServerResponse(
2154
('foo', 'bar'), body_stream=bytes_iterable)
2155
self.assertEqual(('foo', 'bar'), response.args)
2156
self.assertEqual(bytes_iterable, response.body_stream)
2158
def test_construct_rejects_body_and_body_stream(self):
2159
"""'body' and 'body_stream' are mutually exclusive."""
2162
request.SuccessfulSmartServerResponse, (), 'body', ['stream'])
2082
2164
def test_is_successful(self):
2083
2165
"""is_successful should return True for SuccessfulSmartServerResponse."""
2084
2166
response = request.SuccessfulSmartServerResponse(('error',))