/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/test_smart_transport.py

  • Committer: Jelmer Vernooij
  • Date: 2018-02-18 19:18:40 UTC
  • mto: This revision was merged to the branch mainline in revision 6928.
  • Revision ID: jelmer@jelmer.uk-20180218191840-2wezg20u9ffbfmed
Fix more bees, use with rather than try/finally for some files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
255
255
        output = BytesIO()
256
256
        client_medium = medium.SmartSimplePipesClientMedium(
257
257
            None, output, 'base')
258
 
        client_medium._accept_bytes('abc')
259
 
        self.assertEqual('abc', output.getvalue())
 
258
        client_medium._accept_bytes(b'abc')
 
259
        self.assertEqual(b'abc', output.getvalue())
260
260
 
261
261
    def test_simple_pipes__accept_bytes_subprocess_closed(self):
262
262
        # It is unfortunate that we have to use Popen for this. However,
270
270
            stdout=subprocess.PIPE, stdin=subprocess.PIPE)
271
271
        client_medium = medium.SmartSimplePipesClientMedium(
272
272
            p.stdout, p.stdin, 'base')
273
 
        client_medium._accept_bytes('abc\n')
274
 
        self.assertEqual('abc', client_medium._read_bytes(3))
 
273
        client_medium._accept_bytes(b'abc\n')
 
274
        self.assertEqual(b'abc', client_medium._read_bytes(3))
275
275
        p.wait()
276
276
        # While writing to the underlying pipe,
277
277
        #   Windows py2.6.6 we get IOError(EINVAL)
284
284
        child_read, client_write = create_file_pipes()
285
285
        client_medium = medium.SmartSimplePipesClientMedium(
286
286
            None, client_write, 'base')
287
 
        client_medium._accept_bytes('abc\n')
288
 
        self.assertEqual('abc\n', child_read.read(4))
 
287
        client_medium._accept_bytes(b'abc\n')
 
288
        self.assertEqual(b'abc\n', child_read.read(4))
289
289
        # While writing to the underlying pipe,
290
290
        #   Windows py2.6.6 we get IOError(EINVAL)
291
291
        #   Lucid py2.6.5, we get IOError(EPIPE)
298
298
        child_read, client_write = create_file_pipes()
299
299
        client_medium = medium.SmartSimplePipesClientMedium(
300
300
            None, client_write, 'base')
301
 
        client_medium._accept_bytes('abc\n')
 
301
        client_medium._accept_bytes(b'abc\n')
302
302
        child_read.close()
303
303
        # Even though the pipe is closed, flush on the write side seems to be a
304
304
        # no-op, rather than a failure.
312
312
            stdout=subprocess.PIPE, stdin=subprocess.PIPE)
313
313
        client_medium = medium.SmartSimplePipesClientMedium(
314
314
            p.stdout, p.stdin, 'base')
315
 
        client_medium._accept_bytes('abc\n')
 
315
        client_medium._accept_bytes(b'abc\n')
316
316
        p.wait()
317
317
        # Even though the child process is dead, flush seems to be a no-op.
318
318
        client_medium._flush()
321
321
        child_read, client_write = create_file_pipes()
322
322
        client_medium = medium.SmartSimplePipesClientMedium(
323
323
            child_read, client_write, 'base')
324
 
        client_medium._accept_bytes('abc\n')
 
324
        client_medium._accept_bytes(b'abc\n')
325
325
        client_write.close()
326
 
        self.assertEqual('abc\n', client_medium._read_bytes(4))
327
 
        self.assertEqual('', client_medium._read_bytes(4))
 
326
        self.assertEqual(b'abc\n', client_medium._read_bytes(4))
 
327
        self.assertEqual(b'', client_medium._read_bytes(4))
328
328
 
329
329
    def test_simple_pipes__read_bytes_subprocess_closed(self):
330
330
        p = subprocess.Popen([sys.executable, '-c',
338
338
            stdout=subprocess.PIPE, stdin=subprocess.PIPE)
339
339
        client_medium = medium.SmartSimplePipesClientMedium(
340
340
            p.stdout, p.stdin, 'base')
341
 
        client_medium._accept_bytes('abc\n')
 
341
        client_medium._accept_bytes(b'abc\n')
342
342
        p.wait()
343
 
        self.assertEqual('abc\n', client_medium._read_bytes(4))
344
 
        self.assertEqual('', client_medium._read_bytes(4))
 
343
        self.assertEqual(b'abc\n', client_medium._read_bytes(4))
 
344
        self.assertEqual(b'', client_medium._read_bytes(4))
345
345
 
346
346
    def test_simple_pipes_client_disconnect_does_nothing(self):
347
347
        # calling disconnect does nothing.
351
351
            input, output, 'base')
352
352
        # send some bytes to ensure disconnecting after activity still does not
353
353
        # close.
354
 
        client_medium._accept_bytes('abc')
 
354
        client_medium._accept_bytes(b'abc')
355
355
        client_medium.disconnect()
356
356
        self.assertFalse(input.closed)
357
357
        self.assertFalse(output.closed)
363
363
        output = BytesIO()
364
364
        client_medium = medium.SmartSimplePipesClientMedium(
365
365
            input, output, 'base')
366
 
        client_medium._accept_bytes('abc')
 
366
        client_medium._accept_bytes(b'abc')
367
367
        client_medium.disconnect()
368
 
        client_medium._accept_bytes('abc')
 
368
        client_medium._accept_bytes(b'abc')
369
369
        self.assertFalse(input.closed)
370
370
        self.assertFalse(output.closed)
371
 
        self.assertEqual('abcabc', output.getvalue())
 
371
        self.assertEqual(b'abcabc', output.getvalue())
372
372
 
373
373
    def test_simple_pipes_client_ignores_disconnect_when_not_connected(self):
374
374
        # Doing a disconnect on a new (and thus unconnected) SimplePipes medium
399
399
            input, output, 'base')
400
400
        # this call is here to ensure we only flush once, not on every
401
401
        # _accept_bytes call.
402
 
        client_medium._accept_bytes('abc')
 
402
        client_medium._accept_bytes(b'abc')
403
403
        client_medium._flush()
404
404
        client_medium.disconnect()
405
405
        self.assertEqual(['flush'], flush_calls)
428
428
        ssh_params = medium.SSHParams(
429
429
            'a hostname', 'a port', 'a username', 'a password', 'bzr')
430
430
        client_medium = medium.SmartSSHClientMedium('base', ssh_params, vendor)
431
 
        client_medium._accept_bytes('abc')
432
 
        self.assertEqual('abc', output.getvalue())
 
431
        client_medium._accept_bytes(b'abc')
 
432
        self.assertEqual(b'abc', output.getvalue())
433
433
        self.assertEqual([('connect_ssh', 'a username', 'a password',
434
434
            'a hostname', 'a port',
435
435
            ['bzr', 'serve', '--inet', '--directory=/', '--allow-writes'])],
444
444
            'a hostname', 'a port', 'a username', 'a password',
445
445
            bzr_remote_path='fugly')
446
446
        client_medium = medium.SmartSSHClientMedium('base', ssh_params, vendor)
447
 
        client_medium._accept_bytes('abc')
448
 
        self.assertEqual('abc', output.getvalue())
 
447
        client_medium._accept_bytes(b'abc')
 
448
        self.assertEqual(b'abc', output.getvalue())
449
449
        self.assertEqual([('connect_ssh', 'a username', 'a password',
450
450
            'a hostname', 'a port',
451
451
            ['fugly', 'serve', '--inet', '--directory=/', '--allow-writes'])],
459
459
        vendor = BytesIOSSHVendor(input, output)
460
460
        client_medium = medium.SmartSSHClientMedium(
461
461
            'base', medium.SSHParams('a hostname'), vendor)
462
 
        client_medium._accept_bytes('abc')
 
462
        client_medium._accept_bytes(b'abc')
463
463
        client_medium.disconnect()
464
464
        self.assertTrue(input.closed)
465
465
        self.assertTrue(output.closed)
480
480
        vendor = BytesIOSSHVendor(input, output)
481
481
        client_medium = medium.SmartSSHClientMedium(
482
482
            'base', medium.SSHParams('a hostname'), vendor)
483
 
        client_medium._accept_bytes('abc')
 
483
        client_medium._accept_bytes(b'abc')
484
484
        client_medium.disconnect()
485
485
        # the disconnect has closed output, so we need a new output for the
486
486
        # new connection to write to.
488
488
        output2 = BytesIO()
489
489
        vendor.read_from = input2
490
490
        vendor.write_to = output2
491
 
        client_medium._accept_bytes('abc')
 
491
        client_medium._accept_bytes(b'abc')
492
492
        client_medium.disconnect()
493
493
        self.assertTrue(input.closed)
494
494
        self.assertTrue(output.closed)
557
557
            'base', medium.SSHParams('a hostname'), vendor=vendor)
558
558
        # this call is here to ensure we only flush once, not on every
559
559
        # _accept_bytes call.
560
 
        client_medium._accept_bytes('abc')
 
560
        client_medium._accept_bytes(b'abc')
561
561
        client_medium._flush()
562
562
        client_medium.disconnect()
563
563
        self.assertEqual(['flush'], flush_calls)
578
578
        sock, medium = self.make_loopsocket_and_medium()
579
579
        bytes = []
580
580
        t = self.receive_bytes_on_server(sock, bytes)
581
 
        medium.accept_bytes('abc')
 
581
        medium.accept_bytes(b'abc')
582
582
        t.join()
583
583
        sock.close()
584
584
        self.assertEqual(['abc'], bytes)
590
590
        sock, medium = self.make_loopsocket_and_medium()
591
591
        bytes = []
592
592
        t = self.receive_bytes_on_server(sock, bytes)
593
 
        medium.accept_bytes('ab')
 
593
        medium.accept_bytes(b'ab')
594
594
        medium.disconnect()
595
595
        t.join()
596
596
        sock.close()
621
621
        t = self.receive_bytes_on_server(sock, bytes)
622
622
        # try with nothing buffered
623
623
        medium._flush()
624
 
        medium._accept_bytes('ab')
 
624
        medium._accept_bytes(b'ab')
625
625
        # and with something sent.
626
626
        medium._flush()
627
627
        medium.disconnect()
628
628
        t.join()
629
629
        sock.close()
630
 
        self.assertEqual(['ab'], bytes)
 
630
        self.assertEqual([b'ab'], bytes)
631
631
        # now disconnect again : this should not do anything, if disconnection
632
632
        # really did disconnect.
633
633
        medium.disconnect()
668
668
        client_medium = medium.SmartSimplePipesClientMedium(
669
669
            input, output, 'base')
670
670
        request = medium.SmartClientStreamMediumRequest(client_medium)
671
 
        request.accept_bytes('123')
 
671
        request.accept_bytes(b'123')
672
672
        request.finished_writing()
673
673
        request.finished_reading()
674
674
        self.assertEqual('', input.getvalue())
2013
2013
        # is initialised.  This test should probably be given a clearer
2014
2014
        # interface to work with that will not cause this inconsistency.
2015
2015
        #   -- Andrew Bennetts, 2006-09-28
2016
 
        smart_protocol.accept_bytes('')
 
2016
        smart_protocol.accept_bytes(b'')
2017
2017
        return smart_protocol
2018
2018
 
2019
2019
    def assertServerToClientEncoding(self, expected_bytes, expected_tuple,
2030
2030
            self.assertEqual(expected_bytes, server_output.getvalue())
2031
2031
        # check the decoding of the client smart_protocol from expected_bytes:
2032
2032
        requester, response_handler = self.make_client_protocol(expected_bytes)
2033
 
        requester.call('foo')
 
2033
        requester.call(b'foo')
2034
2034
        self.assertEqual(expected_tuple, response_handler.read_response_tuple())
2035
2035
 
2036
2036
 
2038
2038
 
2039
2039
    def test_connection_closed_reporting(self):
2040
2040
        requester, response_handler = self.make_client_protocol()
2041
 
        requester.call('hello')
 
2041
        requester.call(b'hello')
2042
2042
        ex = self.assertRaises(errors.ConnectionReset,
2043
2043
            response_handler.read_response_tuple)
2044
2044
        self.assertEqual("Connection closed: "
2054
2054
        one that should coalesce.
2055
2055
        """
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',
2060
2060
            requester)
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)
2063
2063
 
2064
2064
 
2065
2065
class TestVersionOneFeaturesInProtocolOne(
2072
2072
 
2073
2073
    def test_construct_version_one_server_protocol(self):
2074
2074
        smart_protocol = protocol.SmartServerRequestProtocolOne(None, None)
2075
 
        self.assertEqual('', smart_protocol.unused_data)
2076
 
        self.assertEqual('', smart_protocol.in_buffer)
 
2075
        self.assertEqual(b'', smart_protocol.unused_data)
 
2076
        self.assertEqual(b'', smart_protocol.in_buffer)
2077
2077
        self.assertFalse(smart_protocol._has_dispatched)
2078
2078
        self.assertEqual(1, smart_protocol.next_read_size())
2079
2079
 
2089
2089
        out_stream = BytesIO()
2090
2090
        smart_protocol = protocol.SmartServerRequestProtocolOne(
2091
2091
            None, out_stream.write)
2092
 
        smart_protocol.accept_bytes('abc')
2093
 
        self.assertEqual('abc', smart_protocol.in_buffer)
2094
 
        smart_protocol.accept_bytes('\n')
 
2092
        smart_protocol.accept_bytes(b'abc')
 
2093
        self.assertEqual(b'abc', smart_protocol.in_buffer)
 
2094
        smart_protocol.accept_bytes(b'\n')
2095
2095
        self.assertEqual(
2096
 
            "error\x01Generic bzr smart protocol error: bad request 'abc'\n",
 
2096
            b"error\x01Generic bzr smart protocol error: bad request 'abc'\n",
2097
2097
            out_stream.getvalue())
2098
2098
        self.assertTrue(smart_protocol._has_dispatched)
2099
2099
        self.assertEqual(0, smart_protocol.next_read_size())
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)
2110
2110
 
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)
2123
2123
 
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)
2132
2132
 
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)
2142
2142
 
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)
2154
2154
 
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())
2162
2162
 
2163
2163
    def test__send_response_errors_with_base_response(self):
2165
2165
        smart_protocol = protocol.SmartServerRequestProtocolOne(
2166
2166
            None, lambda x: None)
2167
2167
        self.assertRaises(AttributeError, smart_protocol._send_response,
2168
 
            _mod_request.SmartServerResponse(('x',)))
 
2168
            _mod_request.SmartServerResponse((b'x',)))
2169
2169
 
2170
2170
    def test_query_version(self):
2171
2171
        """query_version on a SmartClientProtocolOne should return a number.
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'', )])
2193
2193
 
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'),
2198
 
            [('a', 'b', '34')])
 
2197
        self.assertServerToClientEncoding(b'a\x01b\x0134\n', (b'a', b'b', b'34'),
 
2198
            [(b'a', b'b', b'34')])
2199
2199
 
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
2231
2231
            input, output, 'base')
2232
2232
        request = client_medium.get_request()
2233
2233
        smart_protocol = protocol.SmartClientRequestProtocolOne(request)
2234
 
        smart_protocol.call('foo')
 
2234
        smart_protocol.call(b'foo')
2235
2235
        self.assertRaises(
2236
2236
            errors.UnknownSmartMethod, smart_protocol.read_response_tuple)
2237
2237
        # The request has been finished.  There is no body to read, and
2270
2270
            input, output, 'base')
2271
2271
        request = client_medium.get_request()
2272
2272
        smart_protocol = protocol.SmartClientRequestProtocolOne(request)
2273
 
        smart_protocol.call('foo')
 
2273
        smart_protocol.call(b'foo')
2274
2274
        smart_protocol.read_response_tuple(True)
2275
2275
        self.assertEqual(expected_bytes, smart_protocol.read_body_bytes())
2276
2276
 
2288
2288
            input, output, 'base')
2289
2289
        request = client_medium.get_request()
2290
2290
        smart_protocol = protocol.SmartClientRequestProtocolOne(request)
2291
 
        smart_protocol.call('foo')
 
2291
        smart_protocol.call(b'foo')
2292
2292
        smart_protocol.read_response_tuple(True)
2293
2293
        self.assertEqual(expected_bytes[0:2], smart_protocol.read_body_bytes(2))
2294
2294
        self.assertEqual(expected_bytes[2:4], smart_protocol.read_body_bytes(2))
2306
2306
            input, output, 'base')
2307
2307
        request = client_medium.get_request()
2308
2308
        smart_protocol = protocol.SmartClientRequestProtocolOne(request)
2309
 
        smart_protocol.call('foo')
 
2309
        smart_protocol.call(b'foo')
2310
2310
        smart_protocol.read_response_tuple(True)
2311
2311
        smart_protocol.cancel_read_body()
2312
2312
        self.assertEqual(3, input.tell())
2321
2321
            input, output, 'base')
2322
2322
        request = client_medium.get_request()
2323
2323
        smart_protocol = self.client_protocol_class(request)
2324
 
        smart_protocol.call('foo')
 
2324
        smart_protocol.call(b'foo')
2325
2325
        smart_protocol.read_response_tuple(True)
2326
2326
        self.assertRaises(
2327
2327
            errors.ConnectionReset, smart_protocol.read_body_bytes)
2338
2338
 
2339
2339
    def test_construct_version_two_server_protocol(self):
2340
2340
        smart_protocol = protocol.SmartServerRequestProtocolTwo(None, None)
2341
 
        self.assertEqual('', smart_protocol.unused_data)
2342
 
        self.assertEqual('', smart_protocol.in_buffer)
 
2341
        self.assertEqual(b'', smart_protocol.unused_data)
 
2342
        self.assertEqual(b'', smart_protocol.in_buffer)
2343
2343
        self.assertFalse(smart_protocol._has_dispatched)
2344
2344
        self.assertEqual(1, smart_protocol.next_read_size())
2345
2345
 
2354
2354
    def test_accept_bytes_of_bad_request_to_protocol(self):
2355
2355
        out_stream = BytesIO()
2356
2356
        smart_protocol = self.server_protocol_class(None, out_stream.write)
2357
 
        smart_protocol.accept_bytes('abc')
2358
 
        self.assertEqual('abc', smart_protocol.in_buffer)
2359
 
        smart_protocol.accept_bytes('\n')
 
2357
        smart_protocol.accept_bytes(b'abc')
 
2358
        self.assertEqual(b'abc', smart_protocol.in_buffer)
 
2359
        smart_protocol.accept_bytes(b'\n')
2360
2360
        self.assertEqual(
2361
2361
            self.response_marker +
2362
 
            "failed\nerror\x01Generic bzr smart protocol error: bad request 'abc'\n",
 
2362
            b"failed\nerror\x01Generic bzr smart protocol error: bad request 'abc'\n",
2363
2363
            out_stream.getvalue())
2364
2364
        self.assertTrue(smart_protocol._has_dispatched)
2365
2365
        self.assertEqual(0, smart_protocol.next_read_size())
2367
2367
    def test_accept_body_bytes_to_protocol(self):
2368
2368
        protocol = self.build_protocol_waiting_for_body()
2369
2369
        self.assertEqual(6, protocol.next_read_size())
2370
 
        protocol.accept_bytes('7\nabc')
 
2370
        protocol.accept_bytes(b'7\nabc')
2371
2371
        self.assertEqual(9, protocol.next_read_size())
2372
 
        protocol.accept_bytes('defgd')
2373
 
        protocol.accept_bytes('one\n')
 
2372
        protocol.accept_bytes(b'defgd')
 
2373
        protocol.accept_bytes(b'one\n')
2374
2374
        self.assertEqual(0, protocol.next_read_size())
2375
2375
        self.assertTrue(self.end_received)
2376
2376
 
2509
2509
            input, output, 'base')
2510
2510
        request = client_medium.get_request()
2511
2511
        smart_protocol = self.client_protocol_class(request)
2512
 
        smart_protocol.call('foo')
 
2512
        smart_protocol.call(b'foo')
2513
2513
        smart_protocol.read_response_tuple(True)
2514
2514
        self.assertEqual(expected_bytes, smart_protocol.read_body_bytes())
2515
2515
 
2527
2527
            input, output, 'base')
2528
2528
        request = client_medium.get_request()
2529
2529
        smart_protocol = self.client_protocol_class(request)
2530
 
        smart_protocol.call('foo')
 
2530
        smart_protocol.call(b'foo')
2531
2531
        smart_protocol.read_response_tuple(True)
2532
2532
        self.assertEqual(expected_bytes[0:2], smart_protocol.read_body_bytes(2))
2533
2533
        self.assertEqual(expected_bytes[2:4], smart_protocol.read_body_bytes(2))
2544
2544
            input, output, 'base')
2545
2545
        request = client_medium.get_request()
2546
2546
        smart_protocol = self.client_protocol_class(request)
2547
 
        smart_protocol.call('foo')
 
2547
        smart_protocol.call(b'foo')
2548
2548
        smart_protocol.read_response_tuple(True)
2549
2549
        smart_protocol.cancel_read_body()
2550
2550
        self.assertEqual(len(self.response_marker + 'success\nok\n'),
2561
2561
            input, output, 'base')
2562
2562
        request = client_medium.get_request()
2563
2563
        smart_protocol = self.client_protocol_class(request)
2564
 
        smart_protocol.call('foo')
 
2564
        smart_protocol.call(b'foo')
2565
2565
        smart_protocol.read_response_tuple(True)
2566
2566
        self.assertRaises(
2567
2567
            errors.ConnectionReset, smart_protocol.read_body_bytes)
2776
2776
 
2777
2777
    def test_construct_version_three_server_protocol(self):
2778
2778
        smart_protocol = protocol.ProtocolThreeDecoder(None)
2779
 
        self.assertEqual('', smart_protocol.unused_data)
 
2779
        self.assertEqual(b'', smart_protocol.unused_data)
2780
2780
        self.assertEqual([], smart_protocol._in_buffer_list)
2781
2781
        self.assertEqual(0, smart_protocol._in_buffer_len)
2782
2782
        self.assertFalse(smart_protocol._has_dispatched)
2830
2830
        smart_protocol = self.server_protocol_class(LoggingMessageHandler())
2831
2831
        smart_protocol.accept_bytes(request_bytes)
2832
2832
        self.assertEqual(0, smart_protocol.next_read_size())
2833
 
        self.assertEqual('', smart_protocol.unused_data)
 
2833
        self.assertEqual(b'', smart_protocol.unused_data)
2834
2834
 
2835
2835
    def test_repeated_excess(self):
2836
2836
        """Repeated calls to accept_bytes after the message end has been parsed
3716
3716
        """
3717
3717
        medium = MockMedium()
3718
3718
        smart_client = client._SmartClient(medium, headers={})
3719
 
        message_start = protocol.MESSAGE_VERSION_THREE + '\x00\x00\x00\x02de'
 
3719
        message_start = protocol.MESSAGE_VERSION_THREE + b'\x00\x00\x00\x02de'
3720
3720
        # Issue a request that gets an error reply in a non-default protocol
3721
3721
        # version.
3722
3722
        medium.expect_request(
3723
3723
            message_start +
3724
 
            's\x00\x00\x00\x10l11:method-nameee',
3725
 
            'bzr response 2\nfailed\n\n')
 
3724
            b's\x00\x00\x00\x10l11:method-nameee',
 
3725
            b'bzr response 2\nfailed\n\n')
3726
3726
        medium.expect_disconnect()
3727
3727
        medium.expect_request(
3728
 
            'bzr request 2\nmethod-name\n',
3729
 
            'bzr response 2\nfailed\nFooBarError\n')
 
3728
            b'bzr request 2\nmethod-name\n',
 
3729
            b'bzr response 2\nfailed\nFooBarError\n')
3730
3730
        err = self.assertRaises(
3731
3731
            errors.ErrorFromSmartServer,
3732
3732
            smart_client.call, 'method-name')
3734
3734
        # Now the medium should have remembered the protocol version, so
3735
3735
        # subsequent requests will use the remembered version immediately.
3736
3736
        medium.expect_request(
3737
 
            'bzr request 2\nmethod-name\n',
3738
 
            'bzr response 2\nsuccess\nresponse value\n')
3739
 
        result = smart_client.call('method-name')
3740
 
        self.assertEqual(('response value',), result)
 
3737
            b'bzr request 2\nmethod-name\n',
 
3738
            b'bzr response 2\nsuccess\nresponse value\n')
 
3739
        result = smart_client.call(b'method-name')
 
3740
        self.assertEqual((b'response value',), result)
3741
3741
        self.assertEqual([], medium._expected_events)
3742
3742
 
3743
3743
 
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)
3955
3955
 
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)
3988
3988
 
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)
3996
3996
 
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)
4009
4009
 
4010
4010
 
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)
4023
4023
 
4024
4024
    def test_empty_content(self):
4025
4025
        """'chunked\nEND\n' is the complete encoding of a zero-length body.
4026
4026
        """
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)
4033
4033
 
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'
4040
 
        finish = 'END\n'
 
4037
        decoder.accept_bytes(b'chunked\n')
 
4038
        chunk_length = b'f\n'
 
4039
        chunk_content = b'123456789abcdef'
 
4040
        finish = b'END\n'
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)
4045
4045
 
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.
4049
4049
        """
4050
4050
        decoder = protocol.ChunkedBodyDecoder()
4051
 
        decoder.accept_bytes('chunked\n')
4052
 
        chunk_length = '8\n'
4053
 
        three_bytes = '123'
 
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(
4064
4064
        """A chunk length hasn't been read until a newline byte has been read.
4065
4065
        """
4066
4066
        decoder = protocol.ChunkedBodyDecoder()
4067
 
        decoder.accept_bytes('chunked\n')
4068
 
        decoder.accept_bytes('9')
 
4067
        decoder.accept_bytes(b'chunked\n')
 
4068
        decoder.accept_bytes(b'9')
4069
4069
        self.assertEqual(
4070
4070
            1, decoder.next_read_size(),
4071
4071
            "The next_read_size hint should be 1, because we don't know the "
4072
4072
            "length yet.")
4073
 
        decoder.accept_bytes('\n')
 
4073
        decoder.accept_bytes(b'\n')
4074
4074
        self.assertEqual(
4075
4075
            9 + 4, decoder.next_read_size(),
4076
4076
            "The next_read_size hint should be the length of the chunk plus 4 "
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'
4087
 
        finish = 'END\n'
 
4084
        decoder.accept_bytes(b'chunked\n')
 
4085
        chunk_one = b'3\naaa'
 
4086
        chunk_two = b'5\nbbbbb'
 
4087
        finish = b'END\n'
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)
4094
4094
 
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(),
4109
4109
    def test_multidigit_length(self):
4110
4110
        """Lengths in the chunk prefixes can have multiple digits."""
4111
4111
        decoder = protocol.ChunkedBodyDecoder()
4112
 
        decoder.accept_bytes('chunked\n')
 
4112
        decoder.accept_bytes(b'chunked\n')
4113
4113
        length = 0x123
4114
 
        chunk_prefix = hex(length) + '\n'
4115
 
        chunk_bytes = 'z' * length
4116
 
        finish = 'END\n'
 
4114
        chunk_prefix = hex(length).encode('ascii') + b'\n'
 
4115
        chunk_bytes = b'z' * length
 
4116
        finish = b'END\n'
4117
4117
        decoder.accept_bytes(chunk_prefix + chunk_bytes + finish)
4118
4118
        self.assertTrue(decoder.finished_reading)
4119
4119
        self.assertEqual(chunk_bytes, decoder.read_next_chunk())
4127
4127
        is called.
4128
4128
        """
4129
4129
        decoder = protocol.ChunkedBodyDecoder()
4130
 
        decoder.accept_bytes('chunked\n')
4131
 
        chunk_length = 'f\n'
4132
 
        chunk_content = '123456789abcdef'
4133
 
        finish = 'END\n'
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'
 
4133
        finish = b'END\n'
 
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)
4139
4140
 
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'
4146
 
        finish = 'END\n'
 
4144
        decoder.accept_bytes(b'chunked\n')
 
4145
        chunk_one = b'3\naaa'
 
4146
        chunk_two = b'3\nbbb'
 
4147
        finish = b'END\n'
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())
4152
4153
 
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'
4159
 
        finish = 'END\n'
 
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
        finish = b'END\n'
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(
4164
 
            ('part1', 'part2'))
 
4165
            (b'part1', b'part2'))
4165
4166
        self.assertEqual(expected_failure, decoder.read_next_chunk())
4166
4167
 
4167
4168
    def test_bad_header(self):
4170
4171
        """
4171
4172
        decoder = protocol.ChunkedBodyDecoder()
4172
4173
        self.assertRaises(
4173
 
            errors.SmartProtocolError, decoder.accept_bytes, 'bad header\n')
 
4174
            errors.SmartProtocolError, decoder.accept_bytes, b'bad header\n')
4174
4175
 
4175
4176
 
4176
4177
class TestSuccessfulSmartServerResponse(tests.TestCase):
4244
4245
    def test_smart_http_medium_request_accept_bytes(self):
4245
4246
        medium = FakeHTTPMedium()
4246
4247
        request = http.SmartClientHTTPMediumRequest(medium)
4247
 
        request.accept_bytes('abc')
4248
 
        request.accept_bytes('def')
 
4248
        request.accept_bytes(b'abc')
 
4249
        request.accept_bytes(b'def')
4249
4250
        self.assertEqual(None, medium.written_request)
4250
4251
        request.finished_writing()
4251
 
        self.assertEqual('abcdef', medium.written_request)
 
4252
        self.assertEqual(b'abcdef', medium.written_request)
4252
4253
 
4253
4254
 
4254
4255
class RemoteHTTPTransportTestCase(tests.TestCase):