2054
2054
one that should coalesce.
2056
2056
requester, response_handler = self.make_client_protocol()
2057
self.assertOffsetSerialisation([], '', requester)
2058
self.assertOffsetSerialisation([(1, 2)], '1,2', requester)
2059
self.assertOffsetSerialisation([(10, 40), (0, 5)], '10,40\n0,5',
2057
self.assertOffsetSerialisation([], b'', requester)
2058
self.assertOffsetSerialisation([(1, 2)], b'1,2', requester)
2059
self.assertOffsetSerialisation([(10, 40), (0, 5)], b'10,40\n0,5',
2061
2061
self.assertOffsetSerialisation([(1, 2), (3, 4), (100, 200)],
2062
'1,2\n3,4\n100,200', requester)
2062
b'1,2\n3,4\n100,200', requester)
2065
2065
class TestVersionOneFeaturesInProtocolOne(
2101
2101
def test_accept_body_bytes_to_protocol(self):
2102
2102
protocol = self.build_protocol_waiting_for_body()
2103
2103
self.assertEqual(6, protocol.next_read_size())
2104
protocol.accept_bytes('7\nabc')
2104
protocol.accept_bytes(b'7\nabc')
2105
2105
self.assertEqual(9, protocol.next_read_size())
2106
protocol.accept_bytes('defgd')
2107
protocol.accept_bytes('one\n')
2106
protocol.accept_bytes(b'defgd')
2107
protocol.accept_bytes(b'one\n')
2108
2108
self.assertEqual(0, protocol.next_read_size())
2109
2109
self.assertTrue(self.end_received)
2111
2111
def test_accept_request_and_body_all_at_once(self):
2112
2112
self.overrideEnv('BRZ_NO_SMART_VFS', None)
2113
2113
mem_transport = memory.MemoryTransport()
2114
mem_transport.put_bytes('foo', 'abcdefghij')
2114
mem_transport.put_bytes('foo', b'abcdefghij')
2115
2115
out_stream = BytesIO()
2116
2116
smart_protocol = protocol.SmartServerRequestProtocolOne(mem_transport,
2117
2117
out_stream.write)
2118
smart_protocol.accept_bytes('readv\x01foo\n3\n3,3done\n')
2118
smart_protocol.accept_bytes(b'readv\x01foo\n3\n3,3done\n')
2119
2119
self.assertEqual(0, smart_protocol.next_read_size())
2120
self.assertEqual('readv\n3\ndefdone\n', out_stream.getvalue())
2121
self.assertEqual('', smart_protocol.unused_data)
2122
self.assertEqual('', smart_protocol.in_buffer)
2120
self.assertEqual(b'readv\n3\ndefdone\n', out_stream.getvalue())
2121
self.assertEqual(b'', smart_protocol.unused_data)
2122
self.assertEqual(b'', smart_protocol.in_buffer)
2124
2124
def test_accept_excess_bytes_are_preserved(self):
2125
2125
out_stream = BytesIO()
2126
2126
smart_protocol = protocol.SmartServerRequestProtocolOne(
2127
2127
None, out_stream.write)
2128
smart_protocol.accept_bytes('hello\nhello\n')
2129
self.assertEqual("ok\x012\n", out_stream.getvalue())
2130
self.assertEqual("hello\n", smart_protocol.unused_data)
2131
self.assertEqual("", smart_protocol.in_buffer)
2128
smart_protocol.accept_bytes(b'hello\nhello\n')
2129
self.assertEqual(b"ok\x012\n", out_stream.getvalue())
2130
self.assertEqual(b"hello\n", smart_protocol.unused_data)
2131
self.assertEqual(b"", smart_protocol.in_buffer)
2133
2133
def test_accept_excess_bytes_after_body(self):
2134
2134
protocol = self.build_protocol_waiting_for_body()
2135
protocol.accept_bytes('7\nabcdefgdone\nX')
2135
protocol.accept_bytes(b'7\nabcdefgdone\nX')
2136
2136
self.assertTrue(self.end_received)
2137
self.assertEqual("X", protocol.unused_data)
2138
self.assertEqual("", protocol.in_buffer)
2139
protocol.accept_bytes('Y')
2140
self.assertEqual("XY", protocol.unused_data)
2141
self.assertEqual("", protocol.in_buffer)
2137
self.assertEqual(b"X", protocol.unused_data)
2138
self.assertEqual(b"", protocol.in_buffer)
2139
protocol.accept_bytes(b'Y')
2140
self.assertEqual(b"XY", protocol.unused_data)
2141
self.assertEqual(b"", protocol.in_buffer)
2143
2143
def test_accept_excess_bytes_after_dispatch(self):
2144
2144
out_stream = BytesIO()
2145
2145
smart_protocol = protocol.SmartServerRequestProtocolOne(
2146
2146
None, out_stream.write)
2147
smart_protocol.accept_bytes('hello\n')
2148
self.assertEqual("ok\x012\n", out_stream.getvalue())
2149
smart_protocol.accept_bytes('hel')
2150
self.assertEqual("hel", smart_protocol.unused_data)
2151
smart_protocol.accept_bytes('lo\n')
2152
self.assertEqual("hello\n", smart_protocol.unused_data)
2153
self.assertEqual("", smart_protocol.in_buffer)
2147
smart_protocol.accept_bytes(b'hello\n')
2148
self.assertEqual(b"ok\x012\n", out_stream.getvalue())
2149
smart_protocol.accept_bytes(b'hel')
2150
self.assertEqual(b"hel", smart_protocol.unused_data)
2151
smart_protocol.accept_bytes(b'lo\n')
2152
self.assertEqual(b"hello\n", smart_protocol.unused_data)
2153
self.assertEqual(b"", smart_protocol.in_buffer)
2155
2155
def test__send_response_sets_finished_reading(self):
2156
2156
smart_protocol = protocol.SmartServerRequestProtocolOne(
2157
2157
None, lambda x: None)
2158
2158
self.assertEqual(1, smart_protocol.next_read_size())
2159
2159
smart_protocol._send_response(
2160
_mod_request.SuccessfulSmartServerResponse(('x',)))
2160
_mod_request.SuccessfulSmartServerResponse((b'x',)))
2161
2161
self.assertEqual(0, smart_protocol.next_read_size())
2163
2163
def test__send_response_errors_with_base_response(self):
2189
2189
# protocol.call() can get back an empty tuple as a response. This occurs
2190
2190
# when the parsed line is an empty line, and results in a tuple with
2191
2191
# one element - an empty string.
2192
self.assertServerToClientEncoding('\n', ('', ), [(), ('', )])
2192
self.assertServerToClientEncoding(b'\n', (b'', ), [(), (b'', )])
2194
2194
def test_client_call_three_element_response(self):
2195
2195
# protocol.call() can get back tuples of other lengths. A three element
2196
2196
# tuple should be unpacked as three strings.
2197
self.assertServerToClientEncoding('a\x01b\x0134\n', ('a', 'b', '34'),
2197
self.assertServerToClientEncoding(b'a\x01b\x0134\n', (b'a', b'b', b'34'),
2198
[(b'a', b'b', b'34')])
2200
2200
def test_client_call_with_body_bytes_uploads(self):
2201
2201
# protocol.call_with_body_bytes should length-prefix the bytes onto the
3950
3950
decoder = protocol.LengthPrefixedBodyDecoder()
3951
3951
self.assertFalse(decoder.finished_reading)
3952
3952
self.assertEqual(6, decoder.next_read_size())
3953
self.assertEqual('', decoder.read_pending_data())
3954
self.assertEqual('', decoder.unused_data)
3953
self.assertEqual(b'', decoder.read_pending_data())
3954
self.assertEqual(b'', decoder.unused_data)
3956
3956
def test_accept_bytes(self):
3957
3957
decoder = protocol.LengthPrefixedBodyDecoder()
3958
decoder.accept_bytes('')
3959
self.assertFalse(decoder.finished_reading)
3960
self.assertEqual(6, decoder.next_read_size())
3961
self.assertEqual('', decoder.read_pending_data())
3962
self.assertEqual('', decoder.unused_data)
3963
decoder.accept_bytes('7')
3964
self.assertFalse(decoder.finished_reading)
3965
self.assertEqual(6, decoder.next_read_size())
3966
self.assertEqual('', decoder.read_pending_data())
3967
self.assertEqual('', decoder.unused_data)
3968
decoder.accept_bytes('\na')
3958
decoder.accept_bytes(b'')
3959
self.assertFalse(decoder.finished_reading)
3960
self.assertEqual(6, decoder.next_read_size())
3961
self.assertEqual(b'', decoder.read_pending_data())
3962
self.assertEqual(b'', decoder.unused_data)
3963
decoder.accept_bytes(b'7')
3964
self.assertFalse(decoder.finished_reading)
3965
self.assertEqual(6, decoder.next_read_size())
3966
self.assertEqual(b'', decoder.read_pending_data())
3967
self.assertEqual(b'', decoder.unused_data)
3968
decoder.accept_bytes(b'\na')
3969
3969
self.assertFalse(decoder.finished_reading)
3970
3970
self.assertEqual(11, decoder.next_read_size())
3971
self.assertEqual('a', decoder.read_pending_data())
3972
self.assertEqual('', decoder.unused_data)
3973
decoder.accept_bytes('bcdefgd')
3971
self.assertEqual(b'a', decoder.read_pending_data())
3972
self.assertEqual(b'', decoder.unused_data)
3973
decoder.accept_bytes(b'bcdefgd')
3974
3974
self.assertFalse(decoder.finished_reading)
3975
3975
self.assertEqual(4, decoder.next_read_size())
3976
self.assertEqual('bcdefg', decoder.read_pending_data())
3977
self.assertEqual('', decoder.unused_data)
3978
decoder.accept_bytes('one')
3976
self.assertEqual(b'bcdefg', decoder.read_pending_data())
3977
self.assertEqual(b'', decoder.unused_data)
3978
decoder.accept_bytes(b'one')
3979
3979
self.assertFalse(decoder.finished_reading)
3980
3980
self.assertEqual(1, decoder.next_read_size())
3981
self.assertEqual('', decoder.read_pending_data())
3982
self.assertEqual('', decoder.unused_data)
3983
decoder.accept_bytes('\nblarg')
3981
self.assertEqual(b'', decoder.read_pending_data())
3982
self.assertEqual(b'', decoder.unused_data)
3983
decoder.accept_bytes(b'\nblarg')
3984
3984
self.assertTrue(decoder.finished_reading)
3985
3985
self.assertEqual(1, decoder.next_read_size())
3986
self.assertEqual('', decoder.read_pending_data())
3987
self.assertEqual('blarg', decoder.unused_data)
3986
self.assertEqual(b'', decoder.read_pending_data())
3987
self.assertEqual(b'blarg', decoder.unused_data)
3989
3989
def test_accept_bytes_all_at_once_with_excess(self):
3990
3990
decoder = protocol.LengthPrefixedBodyDecoder()
3991
decoder.accept_bytes('1\nadone\nunused')
3991
decoder.accept_bytes(b'1\nadone\nunused')
3992
3992
self.assertTrue(decoder.finished_reading)
3993
3993
self.assertEqual(1, decoder.next_read_size())
3994
self.assertEqual('a', decoder.read_pending_data())
3995
self.assertEqual('unused', decoder.unused_data)
3994
self.assertEqual(b'a', decoder.read_pending_data())
3995
self.assertEqual(b'unused', decoder.unused_data)
3997
3997
def test_accept_bytes_exact_end_of_body(self):
3998
3998
decoder = protocol.LengthPrefixedBodyDecoder()
3999
decoder.accept_bytes('1\na')
3999
decoder.accept_bytes(b'1\na')
4000
4000
self.assertFalse(decoder.finished_reading)
4001
4001
self.assertEqual(5, decoder.next_read_size())
4002
self.assertEqual('a', decoder.read_pending_data())
4003
self.assertEqual('', decoder.unused_data)
4004
decoder.accept_bytes('done\n')
4002
self.assertEqual(b'a', decoder.read_pending_data())
4003
self.assertEqual(b'', decoder.unused_data)
4004
decoder.accept_bytes(b'done\n')
4005
4005
self.assertTrue(decoder.finished_reading)
4006
4006
self.assertEqual(1, decoder.next_read_size())
4007
self.assertEqual('', decoder.read_pending_data())
4008
self.assertEqual('', decoder.unused_data)
4007
self.assertEqual(b'', decoder.read_pending_data())
4008
self.assertEqual(b'', decoder.unused_data)
4011
4011
class TestChunkedBodyDecoder(tests.TestCase):
4019
4019
self.assertFalse(decoder.finished_reading)
4020
4020
self.assertEqual(8, decoder.next_read_size())
4021
4021
self.assertEqual(None, decoder.read_next_chunk())
4022
self.assertEqual('', decoder.unused_data)
4022
self.assertEqual(b'', decoder.unused_data)
4024
4024
def test_empty_content(self):
4025
4025
"""'chunked\nEND\n' is the complete encoding of a zero-length body.
4027
4027
decoder = protocol.ChunkedBodyDecoder()
4028
decoder.accept_bytes('chunked\n')
4029
decoder.accept_bytes('END\n')
4028
decoder.accept_bytes(b'chunked\n')
4029
decoder.accept_bytes(b'END\n')
4030
4030
self.assertTrue(decoder.finished_reading)
4031
4031
self.assertEqual(None, decoder.read_next_chunk())
4032
self.assertEqual('', decoder.unused_data)
4032
self.assertEqual(b'', decoder.unused_data)
4034
4034
def test_one_chunk(self):
4035
4035
"""A body in a single chunk is decoded correctly."""
4036
4036
decoder = protocol.ChunkedBodyDecoder()
4037
decoder.accept_bytes('chunked\n')
4038
chunk_length = 'f\n'
4039
chunk_content = '123456789abcdef'
4037
decoder.accept_bytes(b'chunked\n')
4038
chunk_length = b'f\n'
4039
chunk_content = b'123456789abcdef'
4041
4041
decoder.accept_bytes(chunk_length + chunk_content + finish)
4042
4042
self.assertTrue(decoder.finished_reading)
4043
4043
self.assertEqual(chunk_content, decoder.read_next_chunk())
4044
self.assertEqual('', decoder.unused_data)
4044
self.assertEqual(b'', decoder.unused_data)
4046
4046
def test_incomplete_chunk(self):
4047
4047
"""When there are less bytes in the chunk than declared by the length,
4048
4048
then we haven't finished reading yet.
4050
4050
decoder = protocol.ChunkedBodyDecoder()
4051
decoder.accept_bytes('chunked\n')
4052
chunk_length = '8\n'
4051
decoder.accept_bytes(b'chunked\n')
4052
chunk_length = b'8\n'
4053
three_bytes = b'123'
4054
4054
decoder.accept_bytes(chunk_length + three_bytes)
4055
4055
self.assertFalse(decoder.finished_reading)
4056
4056
self.assertEqual(
4081
4081
def test_two_chunks(self):
4082
4082
"""Content from multiple chunks is concatenated."""
4083
4083
decoder = protocol.ChunkedBodyDecoder()
4084
decoder.accept_bytes('chunked\n')
4085
chunk_one = '3\naaa'
4086
chunk_two = '5\nbbbbb'
4084
decoder.accept_bytes(b'chunked\n')
4085
chunk_one = b'3\naaa'
4086
chunk_two = b'5\nbbbbb'
4088
4088
decoder.accept_bytes(chunk_one + chunk_two + finish)
4089
4089
self.assertTrue(decoder.finished_reading)
4090
self.assertEqual('aaa', decoder.read_next_chunk())
4091
self.assertEqual('bbbbb', decoder.read_next_chunk())
4090
self.assertEqual(b'aaa', decoder.read_next_chunk())
4091
self.assertEqual(b'bbbbb', decoder.read_next_chunk())
4092
4092
self.assertEqual(None, decoder.read_next_chunk())
4093
self.assertEqual('', decoder.unused_data)
4093
self.assertEqual(b'', decoder.unused_data)
4095
4095
def test_excess_bytes(self):
4096
4096
"""Bytes after the chunked body are reported as unused bytes."""
4097
4097
decoder = protocol.ChunkedBodyDecoder()
4098
decoder.accept_bytes('chunked\n')
4099
chunked_body = "5\naaaaaEND\n"
4100
excess_bytes = "excess bytes"
4098
decoder.accept_bytes(b'chunked\n')
4099
chunked_body = b"5\naaaaaEND\n"
4100
excess_bytes = b"excess bytes"
4101
4101
decoder.accept_bytes(chunked_body + excess_bytes)
4102
4102
self.assertTrue(decoder.finished_reading)
4103
self.assertEqual('aaaaa', decoder.read_next_chunk())
4103
self.assertEqual(b'aaaaa', decoder.read_next_chunk())
4104
4104
self.assertEqual(excess_bytes, decoder.unused_data)
4105
4105
self.assertEqual(
4106
4106
1, decoder.next_read_size(),
4129
4129
decoder = protocol.ChunkedBodyDecoder()
4130
decoder.accept_bytes('chunked\n')
4131
chunk_length = 'f\n'
4132
chunk_content = '123456789abcdef'
4134
for byte in (chunk_length + chunk_content + finish):
4135
decoder.accept_bytes(byte)
4130
decoder.accept_bytes(b'chunked\n')
4131
chunk_length = b'f\n'
4132
chunk_content = b'123456789abcdef'
4134
combined = chunk_length + chunk_content + finish
4135
for i in range(len(combined)):
4136
decoder.accept_bytes(combined[i:i+1])
4136
4137
self.assertTrue(decoder.finished_reading)
4137
4138
self.assertEqual(chunk_content, decoder.read_next_chunk())
4138
self.assertEqual('', decoder.unused_data)
4139
self.assertEqual(b'', decoder.unused_data)
4140
4141
def test_read_pending_data_resets(self):
4141
4142
"""read_pending_data does not return the same bytes twice."""
4142
4143
decoder = protocol.ChunkedBodyDecoder()
4143
decoder.accept_bytes('chunked\n')
4144
chunk_one = '3\naaa'
4145
chunk_two = '3\nbbb'
4144
decoder.accept_bytes(b'chunked\n')
4145
chunk_one = b'3\naaa'
4146
chunk_two = b'3\nbbb'
4147
4148
decoder.accept_bytes(chunk_one)
4148
self.assertEqual('aaa', decoder.read_next_chunk())
4149
self.assertEqual(b'aaa', decoder.read_next_chunk())
4149
4150
decoder.accept_bytes(chunk_two)
4150
self.assertEqual('bbb', decoder.read_next_chunk())
4151
self.assertEqual(b'bbb', decoder.read_next_chunk())
4151
4152
self.assertEqual(None, decoder.read_next_chunk())
4153
4154
def test_decode_error(self):
4154
4155
decoder = protocol.ChunkedBodyDecoder()
4155
decoder.accept_bytes('chunked\n')
4156
chunk_one = 'b\nfirst chunk'
4157
error_signal = 'ERR\n'
4158
error_chunks = '5\npart1' + '5\npart2'
4156
decoder.accept_bytes(b'chunked\n')
4157
chunk_one = b'b\nfirst chunk'
4158
error_signal = b'ERR\n'
4159
error_chunks = b'5\npart1' + b'5\npart2'
4160
4161
decoder.accept_bytes(chunk_one + error_signal + error_chunks + finish)
4161
4162
self.assertTrue(decoder.finished_reading)
4162
self.assertEqual('first chunk', decoder.read_next_chunk())
4163
self.assertEqual(b'first chunk', decoder.read_next_chunk())
4163
4164
expected_failure = _mod_request.FailedSmartServerResponse(
4165
(b'part1', b'part2'))
4165
4166
self.assertEqual(expected_failure, decoder.read_next_chunk())
4167
4168
def test_bad_header(self):