263
263
['bzr', 'serve', '--inet', '--directory=/', '--allow-writes'])],
266
def test_ssh_client_changes_command_when_BZR_REMOTE_PATH_is_set(self):
267
# The only thing that initiates a connection from the medium is giving
270
vendor = StringIOSSHVendor(StringIO(), output)
271
orig_bzr_remote_path = os.environ.get('BZR_REMOTE_PATH')
272
def cleanup_environ():
273
osutils.set_or_unset_env('BZR_REMOTE_PATH', orig_bzr_remote_path)
274
self.addCleanup(cleanup_environ)
275
os.environ['BZR_REMOTE_PATH'] = 'fugly'
276
client_medium = self.callDeprecated(
277
['bzr_remote_path is required as of bzr 0.92'],
278
medium.SmartSSHClientMedium, 'a hostname', 'a port', 'a username',
279
'a password', 'base', vendor)
280
client_medium._accept_bytes('abc')
281
self.assertEqual('abc', output.getvalue())
282
self.assertEqual([('connect_ssh', 'a username', 'a password',
283
'a hostname', 'a port',
284
['fugly', 'serve', '--inet', '--directory=/', '--allow-writes'])],
287
266
def test_ssh_client_changes_command_when_bzr_remote_path_passed(self):
288
267
# The only thing that initiates a connection from the medium is giving
1528
1507
ex = self.assertRaises(errors.ConnectionReset,
1529
1508
response_handler.read_response_tuple)
1530
1509
self.assertEqual("Connection closed: "
1531
"please check connectivity and permissions "
1532
"(and try -Dhpss if further diagnosis is required)", str(ex))
1510
"please check connectivity and permissions ",
1534
1513
def test_server_offset_serialisation(self):
1535
1514
"""The Smart protocol serialises offsets as a comma and \n string.
2385
2364
return response_handler
2387
2366
def test_interrupted_by_error(self):
2388
interrupted_body_stream = (
2389
'oS' # successful response
2390
's\0\0\0\x02le' # empty args
2391
'b\0\0\0\x09chunk one' # first chunk
2392
'b\0\0\0\x09chunk two' # second chunk
2394
's\0\0\0\x0el5:error3:abce' # bencoded error
2397
2367
response_handler = self.make_response_handler(interrupted_body_stream)
2398
2368
stream = response_handler.read_streamed_body()
2399
self.assertEqual('chunk one', stream.next())
2400
self.assertEqual('chunk two', stream.next())
2369
self.assertEqual('aaa', stream.next())
2370
self.assertEqual('bbb', stream.next())
2401
2371
exc = self.assertRaises(errors.ErrorFromSmartServer, stream.next)
2402
self.assertEqual(('error', 'abc'), exc.error_tuple)
2372
self.assertEqual(('error', 'Boom!'), exc.error_tuple)
2404
2374
def test_interrupted_by_connection_lost(self):
2405
2375
interrupted_body_stream = (
2796
2766
self.calls.append('finished_writing')
2769
interrupted_body_stream = (
2770
'oS' # status flag (success)
2771
's\x00\x00\x00\x08l4:argse' # args struct ('args,')
2772
'b\x00\x00\x00\x03aaa' # body part ('aaa')
2773
'b\x00\x00\x00\x03bbb' # body part ('bbb')
2774
'oE' # status flag (error)
2775
's\x00\x00\x00\x10l5:error5:Boom!e' # err struct ('error', 'Boom!')
2799
2780
class TestResponseEncodingProtocolThree(tests.TestCase):
2801
2782
def make_response_encoder(self):
2817
2798
# end of message
2801
def test_send_broken_body_stream(self):
2802
encoder, out_stream = self.make_response_encoder()
2803
encoder._headers = {}
2804
def stream_that_fails():
2807
raise Exception('Boom!')
2808
response = _mod_request.SuccessfulSmartServerResponse(
2809
('args',), body_stream=stream_that_fails())
2810
encoder.send_response(response)
2811
expected_response = (
2812
'bzr message 3 (bzr 1.6)\n' # protocol marker
2813
'\x00\x00\x00\x02de' # headers dict (empty)
2814
+ interrupted_body_stream)
2815
self.assertEqual(expected_response, out_stream.getvalue())
2821
2818
class TestResponseEncoderBufferingProtocolThree(tests.TestCase):
2822
2819
"""Tests for buffering of responses.
2855
2852
self.responder.send_response(response)
2856
2853
self.assertWriteCount(1)
2858
def test_send_response_with_body_stream_writes_once_per_chunk(self):
2859
"""A normal response with a stream body is written to the medium
2860
writes to the medium once per chunk.
2855
def test_send_response_with_body_stream_buffers_writes(self):
2856
"""A normal response with a stream body writes to the medium once."""
2862
2857
# Construct a response with stream with 2 chunks in it.
2863
2858
response = _mod_request.SuccessfulSmartServerResponse(
2864
2859
('arg', 'arg'), body_stream=['chunk1', 'chunk2'])
2865
2860
self.responder.send_response(response)
2866
# We will write 3 times: exactly once for each chunk, plus a final
2867
# write to end the response.
2868
self.assertWriteCount(3)
2861
# We will write just once, despite the multiple chunks, due to
2863
self.assertWriteCount(1)
2865
def test_send_response_with_body_stream_flushes_buffers_sometimes(self):
2866
"""When there are many chunks (>100), multiple writes will occur rather
2867
than buffering indefinitely.
2869
# Construct a response with stream with 40 chunks in it. Every chunk
2870
# triggers 3 buffered writes, so we expect > 100 buffered writes, but <
2872
body_stream = ['chunk %d' % count for count in range(40)]
2873
response = _mod_request.SuccessfulSmartServerResponse(
2874
('arg', 'arg'), body_stream=body_stream)
2875
self.responder.send_response(response)
2876
# The write buffer is flushed every 100 buffered writes, so we expect 2
2878
self.assertWriteCount(2)
2871
2881
class TestSmartClientUnicode(tests.TestCase):