~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart_transport.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-05-20 07:16:50 UTC
  • mfrom: (3431.3.11 bug-230550)
  • Revision ID: pqm@pqm.ubuntu.com-20080520071650-9vbizb6v6ji8k1jy
Fix spurious "No repository present" errors when accessing branches
        in shared repos via bzr+http.

Show diffs side-by-side

added added

removed removed

Lines of Context:
115
115
        sock.bind(('127.0.0.1', 0))
116
116
        sock.listen(1)
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
120
120
 
121
121
    def receive_bytes_on_server(self, sock, bytes):
133
133
        t.start()
134
134
        return t
135
135
    
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()
142
 
 
143
 
    def test_construct_smart_client_medium(self):
144
 
        # the base client medium takes no parameters
145
 
        client_medium = medium.SmartClientMedium()
146
 
    
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)
153
142
        
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)
159
148
 
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())
182
173
    
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
189
181
        # close.
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
210
203
        # does nothing.
211
 
        client_medium = medium.SmartSimplePipesClientMedium(None, None)
 
204
        client_medium = medium.SmartSimplePipesClientMedium(None, None, 'base')
212
205
        client_medium.disconnect()
213
206
 
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))
230
223
        flush_calls = []
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')
255
249
        sock.close()
256
250
 
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,
 
258
            'bzr')
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',
313
 
                                                    vendor=vendor,
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()
366
360
 
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,
373
367
                          0)
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',
389
 
                                                    vendor=vendor,
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')
405
399
        sock.close()
406
400
 
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()
440
434
 
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)
447
441
 
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)
473
467
 
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)
514
511
 
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
526
524
        # medium
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(
 
537
            None, None, 'base')
538
538
        request = medium.SmartClientStreamMediumRequest(client_medium)
539
539
        self.assertRaises(errors.WritingNotComplete, request.finished_reading)
540
540
        
547
547
        # smoke tests.
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)
566
567
 
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.
1394
1397
 
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,
1433
1436
        else:
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)
1572
1577
 
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)])
1709
1717
            server_bytes):
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)
1817
1830
 
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(
2585
2608
        """
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.
2770
2794
        """
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.
2804
2828
        """
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.
2829
2853
        """
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'))
 
3185
        self.assertEqual(
 
3186
            'child_dir/',
 
3187
            new_transport._client.remote_path_from_transport(new_transport))
3161
3188
 
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)
 
3201
        self.assertEqual(
 
3202
            'c/',
 
3203
            new_transport._client.remote_path_from_transport(new_transport))
3174
3204
 
3175
3205
        
3176
3206
# TODO: Client feature that does get_bundle and then installs that into a