1370
1370
def test_use_connection_factory(self):
1371
1371
# We want to be able to pass a client as a parameter to RemoteTransport.
1372
input = StringIO('ok\x011\n' + 'ok\n3\nbardone\n')
1372
input = StringIO('ok\n3\nbardone\n')
1373
1373
output = StringIO()
1374
1374
client_medium = medium.SmartSimplePipesClientMedium(input, output)
1375
1375
transport = remote.RemoteTransport(
1376
1376
'bzr://localhost/', medium=client_medium)
1377
# Disable version detection.
1378
transport._client._protocol_version = 1
1378
1380
# We want to make sure the client is used when the first remote
1379
1381
# method is called. No data should have been sent, or read.
1380
1382
self.assertEqual(0, input.tell())
1381
1383
self.assertEqual('', output.getvalue())
1383
# Explicitly probe for the server version now, so that it doesn't
1384
# happen implicitly when we call our first remote method.
1385
client_medium.protocol_version()
1389
1385
# Now call a method that should result in one request: as the
1390
1386
# transport makes its own protocol instances, we check on the wire.
1391
1387
# XXX: TODO: give the transport a protocol factory, which can make
1392
1388
# an instrumented protocol for us.
1393
1389
self.assertEqual('bar', transport.get_bytes('foo'))
1394
1390
# only the needed data should have been sent/received.
1395
self.assertEqual(5 + 13, input.tell())
1391
self.assertEqual(13, input.tell())
1396
1392
self.assertEqual('get\x01/foo\n', output.getvalue())
1398
1394
def test__translate_error_readonly(self):
2527
2516
self.assertCallDoesNotBreakMedium('method', ('args',), u'body')
2519
class MockMediumProtocolThree(object):
2523
self.base = 'dummy base'
2525
def get_request(self):
2526
return MockMediumRequestThree(self)
2529
class MockMediumRequestThree(object):
2531
def __init__(self, mock_medium):
2532
self._medium = mock_medium
2533
self._history = mock_medium._history
2536
def accept_bytes(self, bytes):
2537
self._bytes += bytes
2539
def finished_writing(self):
2540
self._history.append(('request', 'finished_writing', self._bytes))
2542
def finished_reading(self):
2543
self._history.append(('request', 'finished_reading'))
2545
def read_bytes(self, size):
2546
self._history.append(('request', 'read_bytes'))
2547
return (protocol.MESSAGE_VERSION_THREE +
2548
'\0\0\0\x02des\0\0\0\x13l14:response valueee')
2551
class MockMediumProtocolTwo(object):
2555
self.base = 'dummy base'
2556
self._request = MockMediumRequestTwo(self)
2558
def get_request(self):
2559
return self._request
2561
def disconnect(self):
2562
self._history.append(('medium', 'disconnect'))
2563
self._request._read_bytes = ''
2564
self._request._response = 'bzr response 2\nsuccess\nresponse value\n'
2567
class MockMediumRequestTwo(object):
2569
def __init__(self, mock_medium):
2570
self._medium = mock_medium
2571
self._history = mock_medium._history
2572
self._written_bytes = ''
2573
self._read_bytes = ''
2574
self._response = 'bzr response 2\nfailed\n\n'
2576
def accept_bytes(self, bytes):
2577
self._written_bytes += bytes
2579
def finished_writing(self):
2580
self._history.append(
2581
('request', 'finished_writing', self._written_bytes))
2582
self._written_bytes = ''
2584
def finished_reading(self):
2585
self._history.append(('request', 'finished_reading', self._read_bytes))
2586
self._read_bytes = ''
2588
def read_bytes(self, size):
2589
resp = self._response
2590
bytes, resp = resp[:size], resp[size:]
2591
self._response = resp
2592
self._read_bytes += bytes
2595
def read_line(self):
2596
resp = self._response
2598
line, resp = resp.split('\n', 1)
2601
line, resp = resp, ''
2602
self._response = resp
2603
self._read_bytes += line
2607
class Test_SmartClientVersionDetection(tests.TestCase):
2609
def test_version_three_server(self):
2610
medium = MockMediumProtocolThree()
2611
smart_client = client._SmartClient(medium, 'base', headers={})
2612
result = smart_client.call('method-name', 'arg 1', 'arg 2')
2613
self.assertEqual(('response value',), result)
2615
[('request', 'finished_writing', 'bzr message 3 (bzr 1.3)\n\x00\x00\x00\x02des\x00\x00\x00\x1el11:method-name5:arg 15:arg 2ee'),
2616
('request', 'read_bytes'),
2617
('request', 'finished_reading'),],
2619
# After the first successful call, we know the version
2620
self.assertEqual(3, smart_client._protocol_version)
2622
def test_version_two_server(self):
2623
medium = MockMediumProtocolTwo()
2624
smart_client = client._SmartClient(medium, 'base', headers={})
2625
result = smart_client.call('method-name', 'arg 1', 'arg 2')
2626
self.assertEqual(('response value',), result)
2628
[('request', 'finished_writing',
2629
'bzr message 3 (bzr 1.3)\n\x00\x00\x00\x02de' +
2630
's\x00\x00\x00\x1el11:method-name5:arg 15:arg 2ee'),
2631
('medium', 'disconnect'),
2632
('request', 'finished_writing',
2633
'bzr request 2\nmethod-name\x01arg 1\x01arg 2\n'),
2634
('request', 'finished_reading',
2635
'bzr response 2\nsuccess\nresponse value\n'),
2638
# After the first successful call, we know the version
2639
self.assertEqual(2, smart_client._protocol_version)
2642
class Test_SmartClient(tests.TestCase):
2644
def test_call_default_headers(self):
2645
"""ProtocolThreeRequester.call by default sends a 'Software
2648
smart_client = client._SmartClient(medium, 'base')
2649
self.assertTrue('Software version' in smart_client._headers)
2650
# XXX: need a test that smart_client._headers is passed to the request
2530
2654
class LengthPrefixedBodyDecoder(tests.TestCase):
2532
2656
# XXX: TODO: make accept_reading_trailer invoke translate_response or