115
115
sock.bind(('127.0.0.1', 0))
117
117
port = sock.getsockname()[1]
118
client_medium = medium.SmartTCPClientMedium('127.0.0.1', port)
118
client_medium = medium.SmartTCPClientMedium('127.0.0.1', port, 'base')
119
119
return sock, client_medium
121
121
def receive_bytes_on_server(self, sock, bytes):
136
def test_construct_smart_stream_medium_client(self):
137
# make a new instance of the common base for Stream-like Mediums.
138
# this just ensures that the constructor stays parameter-free which
139
# is important for reuse : some subclasses will dynamically connect,
140
# others are always on, etc.
141
client_medium = medium.SmartClientStreamMedium()
143
def test_construct_smart_client_medium(self):
144
# the base client medium takes no parameters
145
client_medium = medium.SmartClientMedium()
147
136
def test_construct_smart_simple_pipes_client_medium(self):
148
137
# the SimplePipes client medium takes two pipes:
149
138
# readable pipe, writeable pipe.
150
139
# Constructing one should just save these and do nothing.
151
140
# We test this by passing in None.
152
client_medium = medium.SmartSimplePipesClientMedium(None, None)
141
client_medium = medium.SmartSimplePipesClientMedium(None, None, None)
154
143
def test_simple_pipes_client_request_type(self):
155
144
# SimplePipesClient should use SmartClientStreamMediumRequest's.
156
client_medium = medium.SmartSimplePipesClientMedium(None, None)
145
client_medium = medium.SmartSimplePipesClientMedium(None, None, None)
157
146
request = client_medium.get_request()
158
147
self.assertIsInstance(request, medium.SmartClientStreamMediumRequest)
165
154
# classes - as the sibling classes share this logic, they do not have
166
155
# explicit tests for this.
167
156
output = StringIO()
168
client_medium = medium.SmartSimplePipesClientMedium(None, output)
157
client_medium = medium.SmartSimplePipesClientMedium(
158
None, output, 'base')
169
159
request = client_medium.get_request()
170
160
request.finished_writing()
171
161
request.finished_reading()
176
166
def test_simple_pipes_client__accept_bytes_writes_to_writable(self):
177
167
# accept_bytes writes to the writeable pipe.
178
168
output = StringIO()
179
client_medium = medium.SmartSimplePipesClientMedium(None, output)
169
client_medium = medium.SmartSimplePipesClientMedium(
170
None, output, 'base')
180
171
client_medium._accept_bytes('abc')
181
172
self.assertEqual('abc', output.getvalue())
184
175
# calling disconnect does nothing.
185
176
input = StringIO()
186
177
output = StringIO()
187
client_medium = medium.SmartSimplePipesClientMedium(input, output)
178
client_medium = medium.SmartSimplePipesClientMedium(
179
input, output, 'base')
188
180
# send some bytes to ensure disconnecting after activity still does not
190
182
client_medium._accept_bytes('abc')
197
189
# accept_bytes writes to.
198
190
input = StringIO()
199
191
output = StringIO()
200
client_medium = medium.SmartSimplePipesClientMedium(input, output)
192
client_medium = medium.SmartSimplePipesClientMedium(
193
input, output, 'base')
201
194
client_medium._accept_bytes('abc')
202
195
client_medium.disconnect()
203
196
client_medium._accept_bytes('abc')
208
201
def test_simple_pipes_client_ignores_disconnect_when_not_connected(self):
209
202
# Doing a disconnect on a new (and thus unconnected) SimplePipes medium
211
client_medium = medium.SmartSimplePipesClientMedium(None, None)
204
client_medium = medium.SmartSimplePipesClientMedium(None, None, 'base')
212
205
client_medium.disconnect()
214
207
def test_simple_pipes_client_can_always_read(self):
215
208
# SmartSimplePipesClientMedium is never disconnected, so read_bytes
216
209
# always tries to read from the underlying pipe.
217
210
input = StringIO('abcdef')
218
client_medium = medium.SmartSimplePipesClientMedium(input, None)
211
client_medium = medium.SmartSimplePipesClientMedium(input, None, 'base')
219
212
self.assertEqual('abc', client_medium.read_bytes(3))
220
213
client_medium.disconnect()
221
214
self.assertEqual('def', client_medium.read_bytes(3))
231
224
def logging_flush(): flush_calls.append('flush')
232
225
output.flush = logging_flush
233
client_medium = medium.SmartSimplePipesClientMedium(input, output)
226
client_medium = medium.SmartSimplePipesClientMedium(
227
input, output, 'base')
234
228
# this call is here to ensure we only flush once, not on every
235
229
# _accept_bytes call.
236
230
client_medium._accept_bytes('abc')
250
244
# having vendor be invalid means that if it tries to connect via the
251
245
# vendor it will blow up.
252
246
client_medium = medium.SmartSSHClientMedium('127.0.0.1', unopened_port,
253
username=None, password=None, vendor="not a vendor",
247
username=None, password=None, base='base', vendor="not a vendor",
254
248
bzr_remote_path='bzr')
260
254
output = StringIO()
261
255
vendor = StringIOSSHVendor(StringIO(), output)
262
256
client_medium = medium.SmartSSHClientMedium(
263
'a hostname', 'a port', 'a username', 'a password', vendor, 'bzr')
257
'a hostname', 'a port', 'a username', 'a password', 'base', vendor,
264
259
client_medium._accept_bytes('abc')
265
260
self.assertEqual('abc', output.getvalue())
266
261
self.assertEqual([('connect_ssh', 'a username', 'a password',
281
276
client_medium = self.callDeprecated(
282
277
['bzr_remote_path is required as of bzr 0.92'],
283
278
medium.SmartSSHClientMedium, 'a hostname', 'a port', 'a username',
284
'a password', vendor)
279
'a password', 'base', vendor)
285
280
client_medium._accept_bytes('abc')
286
281
self.assertEqual('abc', output.getvalue())
287
282
self.assertEqual([('connect_ssh', 'a username', 'a password',
295
290
output = StringIO()
296
291
vendor = StringIOSSHVendor(StringIO(), output)
297
292
client_medium = medium.SmartSSHClientMedium('a hostname', 'a port',
298
'a username', 'a password', vendor, bzr_remote_path='fugly')
293
'a username', 'a password', 'base', vendor, bzr_remote_path='fugly')
299
294
client_medium._accept_bytes('abc')
300
295
self.assertEqual('abc', output.getvalue())
301
296
self.assertEqual([('connect_ssh', 'a username', 'a password',
309
304
input = StringIO()
310
305
output = StringIO()
311
306
vendor = StringIOSSHVendor(input, output)
312
client_medium = medium.SmartSSHClientMedium('a hostname',
314
bzr_remote_path='bzr')
307
client_medium = medium.SmartSSHClientMedium(
308
'a hostname', base='base', vendor=vendor, bzr_remote_path='bzr')
315
309
client_medium._accept_bytes('abc')
316
310
client_medium.disconnect()
317
311
self.assertTrue(input.closed)
331
325
input = StringIO()
332
326
output = StringIO()
333
327
vendor = StringIOSSHVendor(input, output)
334
client_medium = medium.SmartSSHClientMedium('a hostname',
335
vendor=vendor, bzr_remote_path='bzr')
328
client_medium = medium.SmartSSHClientMedium(
329
'a hostname', base='base', vendor=vendor, bzr_remote_path='bzr')
336
330
client_medium._accept_bytes('abc')
337
331
client_medium.disconnect()
338
332
# the disconnect has closed output, so we need a new output for the
360
354
def test_ssh_client_ignores_disconnect_when_not_connected(self):
361
355
# Doing a disconnect on a new (and thus unconnected) SSH medium
362
356
# does not fail. It's ok to disconnect an unconnected medium.
363
client_medium = medium.SmartSSHClientMedium(None,
364
bzr_remote_path='bzr')
357
client_medium = medium.SmartSSHClientMedium(
358
None, base='base', bzr_remote_path='bzr')
365
359
client_medium.disconnect()
367
361
def test_ssh_client_raises_on_read_when_not_connected(self):
368
362
# Doing a read on a new (and thus unconnected) SSH medium raises
369
363
# MediumNotConnected.
370
client_medium = medium.SmartSSHClientMedium(None,
371
bzr_remote_path='bzr')
364
client_medium = medium.SmartSSHClientMedium(
365
None, base='base', bzr_remote_path='bzr')
372
366
self.assertRaises(errors.MediumNotConnected, client_medium.read_bytes,
374
368
self.assertRaises(errors.MediumNotConnected, client_medium.read_bytes,
385
379
def logging_flush(): flush_calls.append('flush')
386
380
output.flush = logging_flush
387
381
vendor = StringIOSSHVendor(input, output)
388
client_medium = medium.SmartSSHClientMedium('a hostname',
390
bzr_remote_path='bzr')
382
client_medium = medium.SmartSSHClientMedium(
383
'a hostname', base='base', vendor=vendor, bzr_remote_path='bzr')
391
384
# this call is here to ensure we only flush once, not on every
392
385
# _accept_bytes call.
393
386
client_medium._accept_bytes('abc')
401
394
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
402
395
sock.bind(('127.0.0.1', 0))
403
396
unopened_port = sock.getsockname()[1]
404
client_medium = medium.SmartTCPClientMedium('127.0.0.1', unopened_port)
397
client_medium = medium.SmartTCPClientMedium(
398
'127.0.0.1', unopened_port, 'base')
407
401
def test_tcp_client_connects_on_first_use(self):
435
429
def test_tcp_client_ignores_disconnect_when_not_connected(self):
436
430
# Doing a disconnect on a new (and thus unconnected) TCP medium
437
431
# does not fail. It's ok to disconnect an unconnected medium.
438
client_medium = medium.SmartTCPClientMedium(None, None)
432
client_medium = medium.SmartTCPClientMedium(None, None, None)
439
433
client_medium.disconnect()
441
435
def test_tcp_client_raises_on_read_when_not_connected(self):
442
436
# Doing a read on a new (and thus unconnected) TCP medium raises
443
437
# MediumNotConnected.
444
client_medium = medium.SmartTCPClientMedium(None, None)
438
client_medium = medium.SmartTCPClientMedium(None, None, None)
445
439
self.assertRaises(errors.MediumNotConnected, client_medium.read_bytes, 0)
446
440
self.assertRaises(errors.MediumNotConnected, client_medium.read_bytes, 1)
467
461
def test_tcp_client_host_unknown_connection_error(self):
468
462
self.requireFeature(InvalidHostnameFeature)
469
463
client_medium = medium.SmartTCPClientMedium(
470
'non_existent.invalid', 4155)
464
'non_existent.invalid', 4155, 'base')
471
465
self.assertRaises(
472
466
errors.ConnectionError, client_medium._ensure_connection)
485
479
# WritingCompleted to prevent bad assumptions on stream environments
486
480
# breaking the needs of message-based environments.
487
481
output = StringIO()
488
client_medium = medium.SmartSimplePipesClientMedium(None, output)
482
client_medium = medium.SmartSimplePipesClientMedium(
483
None, output, 'base')
489
484
request = medium.SmartClientStreamMediumRequest(client_medium)
490
485
request.finished_writing()
491
486
self.assertRaises(errors.WritingCompleted, request.accept_bytes, None)
496
491
# and checking that the pipes get the data.
497
492
input = StringIO()
498
493
output = StringIO()
499
client_medium = medium.SmartSimplePipesClientMedium(input, output)
494
client_medium = medium.SmartSimplePipesClientMedium(
495
input, output, 'base')
500
496
request = medium.SmartClientStreamMediumRequest(client_medium)
501
497
request.accept_bytes('123')
502
498
request.finished_writing()
508
504
# constructing a SmartClientStreamMediumRequest on a StreamMedium sets
509
505
# the current request to the new SmartClientStreamMediumRequest
510
506
output = StringIO()
511
client_medium = medium.SmartSimplePipesClientMedium(None, output)
507
client_medium = medium.SmartSimplePipesClientMedium(
508
None, output, 'base')
512
509
request = medium.SmartClientStreamMediumRequest(client_medium)
513
510
self.assertIs(client_medium._current_request, request)
516
513
# constructing a SmartClientStreamMediumRequest on a StreamMedium with
517
514
# a non-None _current_request raises TooManyConcurrentRequests.
518
515
output = StringIO()
519
client_medium = medium.SmartSimplePipesClientMedium(None, output)
516
client_medium = medium.SmartSimplePipesClientMedium(
517
None, output, 'base')
520
518
client_medium._current_request = "a"
521
519
self.assertRaises(errors.TooManyConcurrentRequests,
522
520
medium.SmartClientStreamMediumRequest, client_medium)
525
523
# calling finished_reading clears the current request from the requests
527
525
output = StringIO()
528
client_medium = medium.SmartSimplePipesClientMedium(None, output)
526
client_medium = medium.SmartSimplePipesClientMedium(
527
None, output, 'base')
529
528
request = medium.SmartClientStreamMediumRequest(client_medium)
530
529
request.finished_writing()
531
530
request.finished_reading()
534
533
def test_finished_read_before_finished_write_errors(self):
535
534
# calling finished_reading before calling finished_writing triggers a
536
535
# WritingNotComplete error.
537
client_medium = medium.SmartSimplePipesClientMedium(None, None)
536
client_medium = medium.SmartSimplePipesClientMedium(
538
538
request = medium.SmartClientStreamMediumRequest(client_medium)
539
539
self.assertRaises(errors.WritingNotComplete, request.finished_reading)
548
548
input = StringIO('321')
549
549
output = StringIO()
550
client_medium = medium.SmartSimplePipesClientMedium(input, output)
550
client_medium = medium.SmartSimplePipesClientMedium(
551
input, output, 'base')
551
552
request = medium.SmartClientStreamMediumRequest(client_medium)
552
553
request.finished_writing()
553
554
self.assertEqual('321', request.read_bytes(3))
560
561
# WritingNotComplete error because the Smart protocol is designed to be
561
562
# compatible with strict message based protocols like HTTP where the
562
563
# request cannot be submitted until the writing has completed.
563
client_medium = medium.SmartSimplePipesClientMedium(None, None)
564
client_medium = medium.SmartSimplePipesClientMedium(None, None, 'base')
564
565
request = medium.SmartClientStreamMediumRequest(client_medium)
565
566
self.assertRaises(errors.WritingNotComplete, request.read_bytes, None)
569
570
# ReadingCompleted to prevent bad assumptions on stream environments
570
571
# breaking the needs of message-based environments.
571
572
output = StringIO()
572
client_medium = medium.SmartSimplePipesClientMedium(None, output)
573
client_medium = medium.SmartSimplePipesClientMedium(
574
None, output, 'base')
573
575
request = medium.SmartClientStreamMediumRequest(client_medium)
574
576
request.finished_writing()
575
577
request.finished_reading()
1372
1374
# We want to be able to pass a client as a parameter to RemoteTransport.
1373
1375
input = StringIO('ok\n3\nbardone\n')
1374
1376
output = StringIO()
1375
client_medium = medium.SmartSimplePipesClientMedium(input, output)
1377
client_medium = medium.SmartSimplePipesClientMedium(
1378
input, output, 'base')
1376
1379
transport = remote.RemoteTransport(
1377
1380
'bzr://localhost/', medium=client_medium)
1378
1381
# Disable version detection.
1395
1398
def test__translate_error_readonly(self):
1396
1399
"""Sending a ReadOnlyError to _translate_error raises TransportNotPossible."""
1397
client_medium = medium.SmartClientMedium()
1400
client_medium = medium.SmartSimplePipesClientMedium(None, None, 'base')
1398
1401
transport = remote.RemoteTransport(
1399
1402
'bzr://localhost/', medium=client_medium)
1400
1403
self.assertRaises(errors.TransportNotPossible,
1434
1437
input = StringIO(input_bytes)
1435
1438
output = StringIO()
1436
client_medium = medium.SmartSimplePipesClientMedium(input, output)
1439
client_medium = medium.SmartSimplePipesClientMedium(
1440
input, output, 'base')
1437
1441
request = client_medium.get_request()
1438
1442
if self.client_protocol_class is not None:
1439
1443
client_protocol = self.client_protocol_class(request)
1566
1570
def test_construct_version_one_client_protocol(self):
1567
1571
# we can construct a client protocol from a client medium request
1568
1572
output = StringIO()
1569
client_medium = medium.SmartSimplePipesClientMedium(None, output)
1573
client_medium = medium.SmartSimplePipesClientMedium(
1574
None, output, 'base')
1570
1575
request = client_medium.get_request()
1571
1576
client_protocol = protocol.SmartClientRequestProtocolOne(request)
1664
1669
# the error if the response is a non-understood version.
1665
1670
input = StringIO('ok\x012\n')
1666
1671
output = StringIO()
1667
client_medium = medium.SmartSimplePipesClientMedium(input, output)
1672
client_medium = medium.SmartSimplePipesClientMedium(
1673
input, output, 'base')
1668
1674
request = client_medium.get_request()
1669
1675
smart_protocol = protocol.SmartClientRequestProtocolOne(request)
1670
1676
self.assertEqual(2, smart_protocol.query_version())
1687
1693
expected_bytes = "foo\n7\nabcdefgdone\n"
1688
1694
input = StringIO("\n")
1689
1695
output = StringIO()
1690
client_medium = medium.SmartSimplePipesClientMedium(input, output)
1696
client_medium = medium.SmartSimplePipesClientMedium(
1697
input, output, 'base')
1691
1698
request = client_medium.get_request()
1692
1699
smart_protocol = protocol.SmartClientRequestProtocolOne(request)
1693
1700
smart_protocol.call_with_body_bytes(('foo', ), "abcdefg")
1699
1706
expected_bytes = "foo\n7\n1,2\n5,6done\n"
1700
1707
input = StringIO("\n")
1701
1708
output = StringIO()
1702
client_medium = medium.SmartSimplePipesClientMedium(input, output)
1709
client_medium = medium.SmartSimplePipesClientMedium(
1710
input, output, 'base')
1703
1711
request = client_medium.get_request()
1704
1712
smart_protocol = protocol.SmartClientRequestProtocolOne(request)
1705
1713
smart_protocol.call_with_body_readv_array(('foo', ), [(1,2),(5,6)])
1710
1718
input = StringIO(server_bytes)
1711
1719
output = StringIO()
1712
client_medium = medium.SmartSimplePipesClientMedium(input, output)
1720
client_medium = medium.SmartSimplePipesClientMedium(
1721
input, output, 'base')
1713
1722
request = client_medium.get_request()
1714
1723
smart_protocol = protocol.SmartClientRequestProtocolOne(request)
1715
1724
smart_protocol.call('foo')
1747
1756
server_bytes = "ok\n7\n1234567done\n"
1748
1757
input = StringIO(server_bytes)
1749
1758
output = StringIO()
1750
client_medium = medium.SmartSimplePipesClientMedium(input, output)
1759
client_medium = medium.SmartSimplePipesClientMedium(
1760
input, output, 'base')
1751
1761
request = client_medium.get_request()
1752
1762
smart_protocol = protocol.SmartClientRequestProtocolOne(request)
1753
1763
smart_protocol.call('foo')
1764
1774
server_bytes = "ok\n7\n1234567done\n"
1765
1775
input = StringIO(server_bytes)
1766
1776
output = StringIO()
1767
client_medium = medium.SmartSimplePipesClientMedium(input, output)
1777
client_medium = medium.SmartSimplePipesClientMedium(
1778
input, output, 'base')
1768
1779
request = client_medium.get_request()
1769
1780
smart_protocol = protocol.SmartClientRequestProtocolOne(request)
1770
1781
smart_protocol.call('foo')
1781
1792
server_bytes = "ok\n7\n1234567done\n"
1782
1793
input = StringIO(server_bytes)
1783
1794
output = StringIO()
1784
client_medium = medium.SmartSimplePipesClientMedium(input, output)
1795
client_medium = medium.SmartSimplePipesClientMedium(
1796
input, output, 'base')
1785
1797
request = client_medium.get_request()
1786
1798
smart_protocol = protocol.SmartClientRequestProtocolOne(request)
1787
1799
smart_protocol.call('foo')
1811
1823
def test_construct_version_two_client_protocol(self):
1812
1824
# we can construct a client protocol from a client medium request
1813
1825
output = StringIO()
1814
client_medium = medium.SmartSimplePipesClientMedium(None, output)
1826
client_medium = medium.SmartSimplePipesClientMedium(
1827
None, output, 'base')
1815
1828
request = client_medium.get_request()
1816
1829
client_protocol = protocol.SmartClientRequestProtocolTwo(request)
1914
1927
# the error if the response is a non-understood version.
1915
1928
input = StringIO(self.response_marker + 'success\nok\x012\n')
1916
1929
output = StringIO()
1917
client_medium = medium.SmartSimplePipesClientMedium(input, output)
1930
client_medium = medium.SmartSimplePipesClientMedium(
1931
input, output, 'base')
1918
1932
request = client_medium.get_request()
1919
1933
smart_protocol = self.client_protocol_class(request)
1920
1934
self.assertEqual(2, smart_protocol.query_version())
1940
1954
expected_bytes = self.request_marker + "foo\n7\nabcdefgdone\n"
1941
1955
input = StringIO("\n")
1942
1956
output = StringIO()
1943
client_medium = medium.SmartSimplePipesClientMedium(input, output)
1957
client_medium = medium.SmartSimplePipesClientMedium(
1958
input, output, 'base')
1944
1959
request = client_medium.get_request()
1945
1960
smart_protocol = self.client_protocol_class(request)
1946
1961
smart_protocol.call_with_body_bytes(('foo', ), "abcdefg")
1952
1967
expected_bytes = self.request_marker + "foo\n7\n1,2\n5,6done\n"
1953
1968
input = StringIO("\n")
1954
1969
output = StringIO()
1955
client_medium = medium.SmartSimplePipesClientMedium(input, output)
1970
client_medium = medium.SmartSimplePipesClientMedium(
1971
input, output, 'base')
1956
1972
request = client_medium.get_request()
1957
1973
smart_protocol = self.client_protocol_class(request)
1958
1974
smart_protocol.call_with_body_readv_array(('foo', ), [(1,2),(5,6)])
1966
1982
"success\nok\n7\n1234567done\n")
1967
1983
input = StringIO(server_bytes)
1968
1984
output = StringIO()
1969
client_medium = medium.SmartSimplePipesClientMedium(input, output)
1985
client_medium = medium.SmartSimplePipesClientMedium(
1986
input, output, 'base')
1970
1987
request = client_medium.get_request()
1971
1988
smart_protocol = self.client_protocol_class(request)
1972
1989
smart_protocol.call('foo')
1983
2000
server_bytes = self.response_marker + "success\nok\n7\n1234567done\n"
1984
2001
input = StringIO(server_bytes)
1985
2002
output = StringIO()
1986
client_medium = medium.SmartSimplePipesClientMedium(input, output)
2003
client_medium = medium.SmartSimplePipesClientMedium(
2004
input, output, 'base')
1987
2005
request = client_medium.get_request()
1988
2006
smart_protocol = self.client_protocol_class(request)
1989
2007
smart_protocol.call('foo')
1999
2017
server_bytes = self.response_marker + "success\nok\n7\n1234567done\n"
2000
2018
input = StringIO(server_bytes)
2001
2019
output = StringIO()
2002
client_medium = medium.SmartSimplePipesClientMedium(input, output)
2020
client_medium = medium.SmartSimplePipesClientMedium(
2021
input, output, 'base')
2003
2022
request = client_medium.get_request()
2004
2023
smart_protocol = self.client_protocol_class(request)
2005
2024
smart_protocol.call('foo')
2102
2121
body_terminator)
2103
2122
input = StringIO(server_bytes)
2104
2123
output = StringIO()
2105
client_medium = medium.SmartSimplePipesClientMedium(input, output)
2124
client_medium = medium.SmartSimplePipesClientMedium(
2125
input, output, 'base')
2106
2126
request = client_medium.get_request()
2107
2127
smart_protocol = protocol.SmartClientRequestProtocolTwo(request)
2108
2128
smart_protocol.call('foo')
2122
2142
"success\nok\n" + body)
2123
2143
input = StringIO(server_bytes)
2124
2144
output = StringIO()
2125
client_medium = medium.SmartSimplePipesClientMedium(input, output)
2145
client_medium = medium.SmartSimplePipesClientMedium(
2146
input, output, 'base')
2126
2147
smart_request = client_medium.get_request()
2127
2148
smart_protocol = protocol.SmartClientRequestProtocolTwo(smart_request)
2128
2149
smart_protocol.call('foo')
2137
2158
server_bytes = protocol.RESPONSE_VERSION_TWO + "success\nok\n"
2138
2159
input = StringIO(server_bytes)
2139
2160
output = StringIO()
2140
client_medium = medium.SmartSimplePipesClientMedium(input, output)
2161
client_medium = medium.SmartSimplePipesClientMedium(
2162
input, output, 'base')
2141
2163
request = client_medium.get_request()
2142
2164
smart_protocol = protocol.SmartClientRequestProtocolTwo(request)
2143
2165
smart_protocol.call('foo')
2154
2176
"error\x01Generic bzr smart protocol error: bad request 'foo'\n")
2155
2177
input = StringIO(server_bytes)
2156
2178
output = StringIO()
2157
client_medium = medium.SmartSimplePipesClientMedium(input, output)
2179
client_medium = medium.SmartSimplePipesClientMedium(
2180
input, output, 'base')
2158
2181
request = client_medium.get_request()
2159
2182
smart_protocol = protocol.SmartClientRequestProtocolTwo(request)
2160
2183
smart_protocol.call('foo')
2332
2355
protocol_decoder.state_accept = protocol_decoder._state_accept_expecting_message_part
2333
2356
output = StringIO()
2334
2357
client_medium = medium.SmartSimplePipesClientMedium(
2335
StringIO(interrupted_body_stream), output)
2358
StringIO(interrupted_body_stream), output, 'base')
2336
2359
medium_request = client_medium.get_request()
2337
2360
medium_request.finished_writing()
2338
2361
response_handler.setProtoAndMediumRequest(
2586
2609
input = StringIO("\n")
2587
2610
output = StringIO()
2588
client_medium = medium.SmartSimplePipesClientMedium(input, output)
2589
smart_client = client._SmartClient(client_medium, 'ignored base')
2611
client_medium = medium.SmartSimplePipesClientMedium(
2612
input, output, 'ignored base')
2613
smart_client = client._SmartClient(client_medium)
2590
2614
self.assertRaises(TypeError,
2591
2615
smart_client.call_with_body_bytes, method, args, body)
2592
2616
self.assertEqual("", output.getvalue())
2749
2773
def test_version_three_server(self):
2750
2774
"""With a protocol 3 server, only one request is needed."""
2751
2775
medium = MockMedium()
2752
smart_client = client._SmartClient(medium, 'base', headers={})
2776
smart_client = client._SmartClient(medium, headers={})
2753
2777
message_start = protocol.MESSAGE_VERSION_THREE + '\x00\x00\x00\x02de'
2754
2778
medium.expect_request(
2755
2779
message_start +
2769
2793
use protocol 2 immediately.
2771
2795
medium = MockMedium()
2772
smart_client = client._SmartClient(medium, 'base', headers={})
2796
smart_client = client._SmartClient(medium, headers={})
2773
2797
# First the client should send a v3 request, but the server will reply
2774
2798
# with a v2 error.
2775
2799
medium.expect_request(
2803
2827
protocol version, a SmartProtocolError is raised.
2805
2829
medium = MockMedium()
2806
smart_client = client._SmartClient(medium, 'base', headers={})
2830
smart_client = client._SmartClient(medium, headers={})
2807
2831
unknown_protocol_bytes = 'Unknown protocol!'
2808
2832
# The client will try v3 and v2 before eventually giving up.
2809
2833
medium.expect_request(
2827
2851
"""ProtocolThreeRequester.call by default sends a 'Software
2828
2852
version' header.
2830
smart_client = client._SmartClient(medium, 'base')
2854
smart_client = client._SmartClient('dummy medium')
2831
2855
self.assertEqual(
2832
2856
bzrlib.__version__, smart_client._headers['Software version'])
2833
2857
# XXX: need a test that smart_client._headers is passed to the request
3158
3182
self.assertEqual(base_transport._http_transport,
3159
3183
new_transport._http_transport)
3160
3184
self.assertEqual('child_dir/foo', new_transport._remote_path('foo'))
3187
new_transport._client.remote_path_from_transport(new_transport))
3162
3189
def test_remote_path_unnormal_base(self):
3163
3190
# If the transport's base isn't normalised, the _remote_path should
3171
3198
base_transport = remote.RemoteHTTPTransport('bzr+http://host/%7Ea/b')
3172
3199
new_transport = base_transport.clone('c')
3173
3200
self.assertEqual('bzr+http://host/%7Ea/b/c/', new_transport.base)
3203
new_transport._client.remote_path_from_transport(new_transport))
3176
3206
# TODO: Client feature that does get_bundle and then installs that into a