~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart_transport.py

Start splitting bzrlib/transport/smart.py into a package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
        SmartClientHTTPMediumRequest,
42
42
        SmartRequestHandler,
43
43
        )
 
44
from bzrlib.transport.smart import medium
44
45
 
45
46
 
46
47
class StringIOSSHVendor(object):
85
86
        sock.bind(('127.0.0.1', 0))
86
87
        sock.listen(1)
87
88
        port = sock.getsockname()[1]
88
 
        medium = smart.SmartTCPClientMedium('127.0.0.1', port)
89
 
        return sock, medium
 
89
        client_medium = medium.SmartTCPClientMedium('127.0.0.1', port)
 
90
        return sock, client_medium
90
91
 
91
92
    def receive_bytes_on_server(self, sock, bytes):
92
93
        """Accept a connection on sock and read 3 bytes.
108
109
        # this just ensures that the constructor stays parameter-free which
109
110
        # is important for reuse : some subclasses will dynamically connect,
110
111
        # others are always on, etc.
111
 
        medium = smart.SmartClientStreamMedium()
 
112
        client_medium = medium.SmartClientStreamMedium()
112
113
 
113
114
    def test_construct_smart_client_medium(self):
114
115
        # the base client medium takes no parameters
115
 
        medium = smart.SmartClientMedium()
 
116
        client_medium = medium.SmartClientMedium()
116
117
    
117
118
    def test_construct_smart_simple_pipes_client_medium(self):
118
119
        # the SimplePipes client medium takes two pipes:
119
120
        # readable pipe, writeable pipe.
120
121
        # Constructing one should just save these and do nothing.
121
122
        # We test this by passing in None.
122
 
        medium = smart.SmartSimplePipesClientMedium(None, None)
 
123
        client_medium = medium.SmartSimplePipesClientMedium(None, None)
123
124
        
124
125
    def test_simple_pipes_client_request_type(self):
125
126
        # SimplePipesClient should use SmartClientStreamMediumRequest's.
126
 
        medium = smart.SmartSimplePipesClientMedium(None, None)
127
 
        request = medium.get_request()
128
 
        self.assertIsInstance(request, smart.SmartClientStreamMediumRequest)
 
127
        client_medium = medium.SmartSimplePipesClientMedium(None, None)
 
128
        request = client_medium.get_request()
 
129
        self.assertIsInstance(request, medium.SmartClientStreamMediumRequest)
129
130
 
130
131
    def test_simple_pipes_client_get_concurrent_requests(self):
131
132
        # the simple_pipes client does not support pipelined requests:
135
136
        # classes - as the sibling classes share this logic, they do not have
136
137
        # explicit tests for this.
137
138
        output = StringIO()
138
 
        medium = smart.SmartSimplePipesClientMedium(None, output)
139
 
        request = medium.get_request()
 
139
        client_medium = medium.SmartSimplePipesClientMedium(None, output)
 
140
        request = client_medium.get_request()
140
141
        request.finished_writing()
141
142
        request.finished_reading()
142
 
        request2 = medium.get_request()
 
143
        request2 = client_medium.get_request()
143
144
        request2.finished_writing()
144
145
        request2.finished_reading()
145
146
 
146
147
    def test_simple_pipes_client__accept_bytes_writes_to_writable(self):
147
148
        # accept_bytes writes to the writeable pipe.
148
149
        output = StringIO()
149
 
        medium = smart.SmartSimplePipesClientMedium(None, output)
150
 
        medium._accept_bytes('abc')
 
150
        client_medium = medium.SmartSimplePipesClientMedium(None, output)
 
151
        client_medium._accept_bytes('abc')
151
152
        self.assertEqual('abc', output.getvalue())
152
153
    
153
154
    def test_simple_pipes_client_disconnect_does_nothing(self):
154
155
        # calling disconnect does nothing.
155
156
        input = StringIO()
156
157
        output = StringIO()
157
 
        medium = smart.SmartSimplePipesClientMedium(input, output)
 
158
        client_medium = medium.SmartSimplePipesClientMedium(input, output)
158
159
        # send some bytes to ensure disconnecting after activity still does not
159
160
        # close.
160
 
        medium._accept_bytes('abc')
161
 
        medium.disconnect()
 
161
        client_medium._accept_bytes('abc')
 
162
        client_medium.disconnect()
162
163
        self.assertFalse(input.closed)
163
164
        self.assertFalse(output.closed)
164
165
 
167
168
        # accept_bytes writes to.
168
169
        input = StringIO()
169
170
        output = StringIO()
170
 
        medium = smart.SmartSimplePipesClientMedium(input, output)
171
 
        medium._accept_bytes('abc')
172
 
        medium.disconnect()
173
 
        medium._accept_bytes('abc')
 
171
        client_medium = medium.SmartSimplePipesClientMedium(input, output)
 
172
        client_medium._accept_bytes('abc')
 
173
        client_medium.disconnect()
 
174
        client_medium._accept_bytes('abc')
174
175
        self.assertFalse(input.closed)
175
176
        self.assertFalse(output.closed)
176
177
        self.assertEqual('abcabc', output.getvalue())
178
179
    def test_simple_pipes_client_ignores_disconnect_when_not_connected(self):
179
180
        # Doing a disconnect on a new (and thus unconnected) SimplePipes medium
180
181
        # does nothing.
181
 
        medium = smart.SmartSimplePipesClientMedium(None, None)
182
 
        medium.disconnect()
 
182
        client_medium = medium.SmartSimplePipesClientMedium(None, None)
 
183
        client_medium.disconnect()
183
184
 
184
185
    def test_simple_pipes_client_can_always_read(self):
185
186
        # SmartSimplePipesClientMedium is never disconnected, so read_bytes
186
187
        # always tries to read from the underlying pipe.
187
188
        input = StringIO('abcdef')
188
 
        medium = smart.SmartSimplePipesClientMedium(input, None)
189
 
        self.assertEqual('abc', medium.read_bytes(3))
190
 
        medium.disconnect()
191
 
        self.assertEqual('def', medium.read_bytes(3))
 
189
        client_medium = medium.SmartSimplePipesClientMedium(input, None)
 
190
        self.assertEqual('abc', client_medium.read_bytes(3))
 
191
        client_medium.disconnect()
 
192
        self.assertEqual('def', client_medium.read_bytes(3))
192
193
        
193
194
    def test_simple_pipes_client_supports__flush(self):
194
195
        # invoking _flush on a SimplePipesClient should flush the output 
200
201
        flush_calls = []
201
202
        def logging_flush(): flush_calls.append('flush')
202
203
        output.flush = logging_flush
203
 
        medium = smart.SmartSimplePipesClientMedium(input, output)
 
204
        client_medium = medium.SmartSimplePipesClientMedium(input, output)
204
205
        # this call is here to ensure we only flush once, not on every
205
206
        # _accept_bytes call.
206
 
        medium._accept_bytes('abc')
207
 
        medium._flush()
208
 
        medium.disconnect()
 
207
        client_medium._accept_bytes('abc')
 
208
        client_medium._flush()
 
209
        client_medium.disconnect()
209
210
        self.assertEqual(['flush'], flush_calls)
210
211
 
211
212
    def test_construct_smart_ssh_client_medium(self):
219
220
        unopened_port = sock.getsockname()[1]
220
221
        # having vendor be invalid means that if it tries to connect via the
221
222
        # vendor it will blow up.
222
 
        medium = smart.SmartSSHClientMedium('127.0.0.1', unopened_port,
 
223
        client_medium = medium.SmartSSHClientMedium('127.0.0.1', unopened_port,
223
224
            username=None, password=None, vendor="not a vendor")
224
225
        sock.close()
225
226
 
228
229
        # it bytes.
229
230
        output = StringIO()
230
231
        vendor = StringIOSSHVendor(StringIO(), output)
231
 
        medium = smart.SmartSSHClientMedium('a hostname', 'a port', 'a username',
232
 
            'a password', vendor)
233
 
        medium._accept_bytes('abc')
 
232
        client_medium = medium.SmartSSHClientMedium(
 
233
            'a hostname', 'a port', 'a username', 'a password', vendor)
 
234
        client_medium._accept_bytes('abc')
234
235
        self.assertEqual('abc', output.getvalue())
235
236
        self.assertEqual([('connect_ssh', 'a username', 'a password',
236
237
            'a hostname', 'a port',
247
248
            osutils.set_or_unset_env('BZR_REMOTE_PATH', orig_bzr_remote_path)
248
249
        self.addCleanup(cleanup_environ)
249
250
        os.environ['BZR_REMOTE_PATH'] = 'fugly'
250
 
        medium = smart.SmartSSHClientMedium('a hostname', 'a port', 'a username',
 
251
        client_medium = medium.SmartSSHClientMedium('a hostname', 'a port', 'a username',
251
252
            'a password', vendor)
252
 
        medium._accept_bytes('abc')
 
253
        client_medium._accept_bytes('abc')
253
254
        self.assertEqual('abc', output.getvalue())
254
255
        self.assertEqual([('connect_ssh', 'a username', 'a password',
255
256
            'a hostname', 'a port',
262
263
        input = StringIO()
263
264
        output = StringIO()
264
265
        vendor = StringIOSSHVendor(input, output)
265
 
        medium = smart.SmartSSHClientMedium('a hostname', vendor=vendor)
266
 
        medium._accept_bytes('abc')
267
 
        medium.disconnect()
 
266
        client_medium = medium.SmartSSHClientMedium('a hostname', vendor=vendor)
 
267
        client_medium._accept_bytes('abc')
 
268
        client_medium.disconnect()
268
269
        self.assertTrue(input.closed)
269
270
        self.assertTrue(output.closed)
270
271
        self.assertEqual([
282
283
        input = StringIO()
283
284
        output = StringIO()
284
285
        vendor = StringIOSSHVendor(input, output)
285
 
        medium = smart.SmartSSHClientMedium('a hostname', vendor=vendor)
286
 
        medium._accept_bytes('abc')
287
 
        medium.disconnect()
 
286
        client_medium = medium.SmartSSHClientMedium('a hostname', vendor=vendor)
 
287
        client_medium._accept_bytes('abc')
 
288
        client_medium.disconnect()
288
289
        # the disconnect has closed output, so we need a new output for the
289
290
        # new connection to write to.
290
291
        input2 = StringIO()
291
292
        output2 = StringIO()
292
293
        vendor.read_from = input2
293
294
        vendor.write_to = output2
294
 
        medium._accept_bytes('abc')
295
 
        medium.disconnect()
 
295
        client_medium._accept_bytes('abc')
 
296
        client_medium.disconnect()
296
297
        self.assertTrue(input.closed)
297
298
        self.assertTrue(output.closed)
298
299
        self.assertTrue(input2.closed)
310
311
    def test_ssh_client_ignores_disconnect_when_not_connected(self):
311
312
        # Doing a disconnect on a new (and thus unconnected) SSH medium
312
313
        # does not fail.  It's ok to disconnect an unconnected medium.
313
 
        medium = smart.SmartSSHClientMedium(None)
314
 
        medium.disconnect()
 
314
        client_medium = medium.SmartSSHClientMedium(None)
 
315
        client_medium.disconnect()
315
316
 
316
317
    def test_ssh_client_raises_on_read_when_not_connected(self):
317
318
        # Doing a read on a new (and thus unconnected) SSH medium raises
318
319
        # MediumNotConnected.
319
 
        medium = smart.SmartSSHClientMedium(None)
320
 
        self.assertRaises(errors.MediumNotConnected, medium.read_bytes, 0)
321
 
        self.assertRaises(errors.MediumNotConnected, medium.read_bytes, 1)
 
320
        client_medium = medium.SmartSSHClientMedium(None)
 
321
        self.assertRaises(errors.MediumNotConnected, client_medium.read_bytes, 0)
 
322
        self.assertRaises(errors.MediumNotConnected, client_medium.read_bytes, 1)
322
323
 
323
324
    def test_ssh_client_supports__flush(self):
324
325
        # invoking _flush on a SSHClientMedium should flush the output 
331
332
        def logging_flush(): flush_calls.append('flush')
332
333
        output.flush = logging_flush
333
334
        vendor = StringIOSSHVendor(input, output)
334
 
        medium = smart.SmartSSHClientMedium('a hostname', vendor=vendor)
 
335
        client_medium = medium.SmartSSHClientMedium('a hostname', vendor=vendor)
335
336
        # this call is here to ensure we only flush once, not on every
336
337
        # _accept_bytes call.
337
 
        medium._accept_bytes('abc')
338
 
        medium._flush()
339
 
        medium.disconnect()
 
338
        client_medium._accept_bytes('abc')
 
339
        client_medium._flush()
 
340
        client_medium.disconnect()
340
341
        self.assertEqual(['flush'], flush_calls)
341
342
        
342
343
    def test_construct_smart_tcp_client_medium(self):
345
346
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
346
347
        sock.bind(('127.0.0.1', 0))
347
348
        unopened_port = sock.getsockname()[1]
348
 
        medium = smart.SmartTCPClientMedium('127.0.0.1', unopened_port)
 
349
        client_medium = medium.SmartTCPClientMedium('127.0.0.1', unopened_port)
349
350
        sock.close()
350
351
 
351
352
    def test_tcp_client_connects_on_first_use(self):
378
379
    def test_tcp_client_ignores_disconnect_when_not_connected(self):
379
380
        # Doing a disconnect on a new (and thus unconnected) TCP medium
380
381
        # does not fail.  It's ok to disconnect an unconnected medium.
381
 
        medium = smart.SmartTCPClientMedium(None, None)
382
 
        medium.disconnect()
 
382
        client_medium = medium.SmartTCPClientMedium(None, None)
 
383
        client_medium.disconnect()
383
384
 
384
385
    def test_tcp_client_raises_on_read_when_not_connected(self):
385
386
        # Doing a read on a new (and thus unconnected) TCP medium raises
386
387
        # MediumNotConnected.
387
 
        medium = smart.SmartTCPClientMedium(None, None)
388
 
        self.assertRaises(errors.MediumNotConnected, medium.read_bytes, 0)
389
 
        self.assertRaises(errors.MediumNotConnected, medium.read_bytes, 1)
 
388
        client_medium = medium.SmartTCPClientMedium(None, None)
 
389
        self.assertRaises(errors.MediumNotConnected, client_medium.read_bytes, 0)
 
390
        self.assertRaises(errors.MediumNotConnected, client_medium.read_bytes, 1)
390
391
 
391
392
    def test_tcp_client_supports__flush(self):
392
393
        # invoking _flush on a TCPClientMedium should do something useful.
421
422
        # WritingCompleted to prevent bad assumptions on stream environments
422
423
        # breaking the needs of message-based environments.
423
424
        output = StringIO()
424
 
        medium = smart.SmartSimplePipesClientMedium(None, output)
425
 
        request = smart.SmartClientStreamMediumRequest(medium)
 
425
        client_medium = medium.SmartSimplePipesClientMedium(None, output)
 
426
        request = medium.SmartClientStreamMediumRequest(client_medium)
426
427
        request.finished_writing()
427
428
        self.assertRaises(errors.WritingCompleted, request.accept_bytes, None)
428
429
 
432
433
        # and checking that the pipes get the data.
433
434
        input = StringIO()
434
435
        output = StringIO()
435
 
        medium = smart.SmartSimplePipesClientMedium(input, output)
436
 
        request = smart.SmartClientStreamMediumRequest(medium)
 
436
        client_medium = medium.SmartSimplePipesClientMedium(input, output)
 
437
        request = medium.SmartClientStreamMediumRequest(client_medium)
437
438
        request.accept_bytes('123')
438
439
        request.finished_writing()
439
440
        request.finished_reading()
444
445
        # constructing a SmartClientStreamMediumRequest on a StreamMedium sets
445
446
        # the current request to the new SmartClientStreamMediumRequest
446
447
        output = StringIO()
447
 
        medium = smart.SmartSimplePipesClientMedium(None, output)
448
 
        request = smart.SmartClientStreamMediumRequest(medium)
449
 
        self.assertIs(medium._current_request, request)
 
448
        client_medium = medium.SmartSimplePipesClientMedium(None, output)
 
449
        request = medium.SmartClientStreamMediumRequest(client_medium)
 
450
        self.assertIs(client_medium._current_request, request)
450
451
 
451
452
    def test_construct_while_another_request_active_throws(self):
452
453
        # constructing a SmartClientStreamMediumRequest on a StreamMedium with
453
454
        # a non-None _current_request raises TooManyConcurrentRequests.
454
455
        output = StringIO()
455
 
        medium = smart.SmartSimplePipesClientMedium(None, output)
456
 
        medium._current_request = "a"
 
456
        client_medium = medium.SmartSimplePipesClientMedium(None, output)
 
457
        client_medium._current_request = "a"
457
458
        self.assertRaises(errors.TooManyConcurrentRequests,
458
 
            smart.SmartClientStreamMediumRequest, medium)
 
459
            medium.SmartClientStreamMediumRequest, client_medium)
459
460
 
460
461
    def test_finished_read_clears_current_request(self):
461
462
        # calling finished_reading clears the current request from the requests
462
463
        # medium
463
464
        output = StringIO()
464
 
        medium = smart.SmartSimplePipesClientMedium(None, output)
465
 
        request = smart.SmartClientStreamMediumRequest(medium)
 
465
        client_medium = medium.SmartSimplePipesClientMedium(None, output)
 
466
        request = medium.SmartClientStreamMediumRequest(client_medium)
466
467
        request.finished_writing()
467
468
        request.finished_reading()
468
 
        self.assertEqual(None, medium._current_request)
 
469
        self.assertEqual(None, client_medium._current_request)
469
470
 
470
471
    def test_finished_read_before_finished_write_errors(self):
471
472
        # calling finished_reading before calling finished_writing triggers a
472
473
        # WritingNotComplete error.
473
 
        medium = smart.SmartSimplePipesClientMedium(None, None)
474
 
        request = smart.SmartClientStreamMediumRequest(medium)
 
474
        client_medium = medium.SmartSimplePipesClientMedium(None, None)
 
475
        request = medium.SmartClientStreamMediumRequest(client_medium)
475
476
        self.assertRaises(errors.WritingNotComplete, request.finished_reading)
476
477
        
477
478
    def test_read_bytes(self):
483
484
        # smoke tests.
484
485
        input = StringIO('321')
485
486
        output = StringIO()
486
 
        medium = smart.SmartSimplePipesClientMedium(input, output)
487
 
        request = smart.SmartClientStreamMediumRequest(medium)
 
487
        client_medium = medium.SmartSimplePipesClientMedium(input, output)
 
488
        request = medium.SmartClientStreamMediumRequest(client_medium)
488
489
        request.finished_writing()
489
490
        self.assertEqual('321', request.read_bytes(3))
490
491
        request.finished_reading()
496
497
        # WritingNotComplete error because the Smart protocol is designed to be
497
498
        # compatible with strict message based protocols like HTTP where the
498
499
        # request cannot be submitted until the writing has completed.
499
 
        medium = smart.SmartSimplePipesClientMedium(None, None)
500
 
        request = smart.SmartClientStreamMediumRequest(medium)
 
500
        client_medium = medium.SmartSimplePipesClientMedium(None, None)
 
501
        request = medium.SmartClientStreamMediumRequest(client_medium)
501
502
        self.assertRaises(errors.WritingNotComplete, request.read_bytes, None)
502
503
 
503
504
    def test_read_bytes_after_finished_reading_errors(self):
505
506
        # ReadingCompleted to prevent bad assumptions on stream environments
506
507
        # breaking the needs of message-based environments.
507
508
        output = StringIO()
508
 
        medium = smart.SmartSimplePipesClientMedium(None, output)
509
 
        request = smart.SmartClientStreamMediumRequest(medium)
 
509
        client_medium = medium.SmartSimplePipesClientMedium(None, output)
 
510
        request = medium.SmartClientStreamMediumRequest(client_medium)
510
511
        request.finished_writing()
511
512
        request.finished_reading()
512
513
        self.assertRaises(errors.ReadingCompleted, request.read_bytes, None)
532
533
    def test_get_medium_from_transport(self):
533
534
        """Remote transport has a medium always, which it can return."""
534
535
        t = self.get_transport()
535
 
        medium = t.get_smart_medium()
536
 
        self.assertIsInstance(medium, smart.SmartClientMedium)
 
536
        client_medium = t.get_smart_medium()
 
537
        self.assertIsInstance(client_medium, medium.SmartClientMedium)
537
538
 
538
539
 
539
540
class ErrorRaisingProtocol(object):
588
589
        to_server = StringIO('hello\n')
589
590
        from_server = StringIO()
590
591
        transport = local.LocalTransport(urlutils.local_path_to_url('/'))
591
 
        server = smart.SmartServerPipeStreamMedium(
 
592
        server = medium.SmartServerPipeStreamMedium(
592
593
            to_server, from_server, transport)
593
594
        protocol = smart.SmartServerRequestProtocolOne(transport,
594
595
                from_server.write)
601
602
        transport.put_bytes('testfile', 'contents\nof\nfile\n')
602
603
        to_server = StringIO('get\001./testfile\n')
603
604
        from_server = StringIO()
604
 
        server = smart.SmartServerPipeStreamMedium(
 
605
        server = medium.SmartServerPipeStreamMedium(
605
606
            to_server, from_server, transport)
606
607
        protocol = smart.SmartServerRequestProtocolOne(transport,
607
608
                from_server.write)
619
620
        transport.put_bytes(utf8_filename, 'contents\nof\nfile\n')
620
621
        to_server = StringIO('get\001' + utf8_filename + '\n')
621
622
        from_server = StringIO()
622
 
        server = smart.SmartServerPipeStreamMedium(
 
623
        server = medium.SmartServerPipeStreamMedium(
623
624
            to_server, from_server, transport)
624
625
        protocol = smart.SmartServerRequestProtocolOne(transport,
625
626
                from_server.write)
634
635
        sample_request_bytes = 'command\n9\nbulk datadone\n'
635
636
        to_server = StringIO(sample_request_bytes)
636
637
        from_server = StringIO()
637
 
        server = smart.SmartServerPipeStreamMedium(to_server, from_server, None)
 
638
        server = medium.SmartServerPipeStreamMedium(
 
639
            to_server, from_server, None)
638
640
        sample_protocol = SampleRequest(expected_bytes=sample_request_bytes)
639
641
        server._serve_one_request(sample_protocol)
640
642
        self.assertEqual('', from_server.getvalue())
644
646
    def test_socket_stream_with_bulk_data(self):
645
647
        sample_request_bytes = 'command\n9\nbulk datadone\n'
646
648
        server_sock, client_sock = self.portable_socket_pair()
647
 
        server = smart.SmartServerSocketStreamMedium(
 
649
        server = medium.SmartServerSocketStreamMedium(
648
650
            server_sock, None)
649
651
        sample_protocol = SampleRequest(expected_bytes=sample_request_bytes)
650
652
        client_sock.sendall(sample_request_bytes)
657
659
    def test_pipe_like_stream_shutdown_detection(self):
658
660
        to_server = StringIO('')
659
661
        from_server = StringIO()
660
 
        server = smart.SmartServerPipeStreamMedium(to_server, from_server, None)
 
662
        server = medium.SmartServerPipeStreamMedium(to_server, from_server, None)
661
663
        server._serve_one_request(SampleRequest('x'))
662
664
        self.assertTrue(server.finished)
663
665
        
664
666
    def test_socket_stream_shutdown_detection(self):
665
667
        server_sock, client_sock = self.portable_socket_pair()
666
668
        client_sock.close()
667
 
        server = smart.SmartServerSocketStreamMedium(
 
669
        server = medium.SmartServerSocketStreamMedium(
668
670
            server_sock, None)
669
671
        server._serve_one_request(SampleRequest('x'))
670
672
        self.assertTrue(server.finished)
676
678
        sample_request_bytes = 'command\n'
677
679
        to_server = StringIO(sample_request_bytes * 2)
678
680
        from_server = StringIO()
679
 
        server = smart.SmartServerPipeStreamMedium(to_server, from_server, None)
 
681
        server = medium.SmartServerPipeStreamMedium(
 
682
            to_server, from_server, None)
680
683
        first_protocol = SampleRequest(expected_bytes=sample_request_bytes)
681
684
        server._serve_one_request(first_protocol)
682
685
        self.assertEqual(0, first_protocol.next_read_size())
696
699
        # been received seperately.
697
700
        sample_request_bytes = 'command\n'
698
701
        server_sock, client_sock = self.portable_socket_pair()
699
 
        server = smart.SmartServerSocketStreamMedium(
 
702
        server = medium.SmartServerSocketStreamMedium(
700
703
            server_sock, None)
701
704
        first_protocol = SampleRequest(expected_bytes=sample_request_bytes)
702
705
        # Put two whole requests on the wire.
723
726
        def close():
724
727
            self.closed = True
725
728
        from_server.close = close
726
 
        server = smart.SmartServerPipeStreamMedium(to_server, from_server, None)
 
729
        server = medium.SmartServerPipeStreamMedium(
 
730
            to_server, from_server, None)
727
731
        fake_protocol = ErrorRaisingProtocol(Exception('boom'))
728
732
        server._serve_one_request(fake_protocol)
729
733
        self.assertEqual('', from_server.getvalue())
735
739
        # not discard the contents.
736
740
        from StringIO import StringIO
737
741
        server_sock, client_sock = self.portable_socket_pair()
738
 
        server = smart.SmartServerSocketStreamMedium(
 
742
        server = medium.SmartServerSocketStreamMedium(
739
743
            server_sock, None)
740
744
        fake_protocol = ErrorRaisingProtocol(Exception('boom'))
741
745
        server._serve_one_request(fake_protocol)
749
753
        # not discard the contents.
750
754
        to_server = StringIO('')
751
755
        from_server = StringIO()
752
 
        server = smart.SmartServerPipeStreamMedium(to_server, from_server, None)
 
756
        server = medium.SmartServerPipeStreamMedium(
 
757
            to_server, from_server, None)
753
758
        fake_protocol = ErrorRaisingProtocol(KeyboardInterrupt('boom'))
754
759
        self.assertRaises(
755
760
            KeyboardInterrupt, server._serve_one_request, fake_protocol)
757
762
 
758
763
    def test_socket_stream_keyboard_interrupt_handling(self):
759
764
        server_sock, client_sock = self.portable_socket_pair()
760
 
        server = smart.SmartServerSocketStreamMedium(
 
765
        server = medium.SmartServerSocketStreamMedium(
761
766
            server_sock, None)
762
767
        fake_protocol = ErrorRaisingProtocol(KeyboardInterrupt('boom'))
763
768
        self.assertRaises(
1004
1009
        # We want to be able to pass a client as a parameter to SmartTransport.
1005
1010
        input = StringIO("ok\n3\nbardone\n")
1006
1011
        output = StringIO()
1007
 
        medium = smart.SmartSimplePipesClientMedium(input, output)
1008
 
        transport = smart.SmartTransport('bzr://localhost/', medium=medium)
 
1012
        client_medium = medium.SmartSimplePipesClientMedium(input, output)
 
1013
        transport = smart.SmartTransport(
 
1014
            'bzr://localhost/', medium=client_medium)
1009
1015
 
1010
1016
        # We want to make sure the client is used when the first remote
1011
1017
        # method is called.  No data should have been sent, or read.
1023
1029
 
1024
1030
    def test__translate_error_readonly(self):
1025
1031
        """Sending a ReadOnlyError to _translate_error raises TransportNotPossible."""
1026
 
        medium = smart.SmartClientMedium()
1027
 
        transport = smart.SmartTransport('bzr://localhost/', medium=medium)
 
1032
        client_medium = medium.SmartClientMedium()
 
1033
        transport = smart.SmartTransport(
 
1034
            'bzr://localhost/', medium=client_medium)
1028
1035
        self.assertRaises(errors.TransportNotPossible,
1029
1036
            transport._translate_error, ("ReadOnlyError", ))
1030
1037
 
1031
1038
 
1032
 
class InstrumentedServerProtocol(smart.SmartServerStreamMedium):
 
1039
class InstrumentedServerProtocol(medium.SmartServerStreamMedium):
1033
1040
    """A smart server which is backed by memory and saves its write requests."""
1034
1041
 
1035
1042
    def __init__(self, write_output_list):
1036
 
        smart.SmartServerStreamMedium.__init__(self, memory.MemoryTransport())
 
1043
        medium.SmartServerStreamMedium.__init__(self, memory.MemoryTransport())
1037
1044
        self._write_output_list = write_output_list
1038
1045
 
1039
1046
 
1055
1062
        self.server_to_client = []
1056
1063
        self.to_server = StringIO()
1057
1064
        self.to_client = StringIO()
1058
 
        self.client_medium = smart.SmartSimplePipesClientMedium(self.to_client,
 
1065
        self.client_medium = medium.SmartSimplePipesClientMedium(self.to_client,
1059
1066
            self.to_server)
1060
1067
        self.client_protocol = smart.SmartClientRequestProtocolOne(
1061
1068
            self.client_medium)
1108
1115
    def test_construct_version_one_client_protocol(self):
1109
1116
        # we can construct a client protocol from a client medium request
1110
1117
        output = StringIO()
1111
 
        medium = smart.SmartSimplePipesClientMedium(None, output)
1112
 
        request = medium.get_request()
 
1118
        client_medium = medium.SmartSimplePipesClientMedium(None, output)
 
1119
        request = client_medium.get_request()
1113
1120
        client_protocol = smart.SmartClientRequestProtocolOne(request)
1114
1121
 
1115
1122
    def test_server_offset_serialisation(self):
1208
1215
        # the error if the response is a non-understood version.
1209
1216
        input = StringIO('ok\x011\n')
1210
1217
        output = StringIO()
1211
 
        medium = smart.SmartSimplePipesClientMedium(input, output)
1212
 
        protocol = smart.SmartClientRequestProtocolOne(medium.get_request())
 
1218
        client_medium = medium.SmartSimplePipesClientMedium(input, output)
 
1219
        request = client_medium.get_request()
 
1220
        protocol = smart.SmartClientRequestProtocolOne(request)
1213
1221
        self.assertEqual(1, protocol.query_version())
1214
1222
 
1215
1223
    def assertServerToClientEncoding(self, expected_bytes, expected_tuple,
1228
1236
        # check the decoding of the client protocol from expected_bytes:
1229
1237
        input = StringIO(expected_bytes)
1230
1238
        output = StringIO()
1231
 
        medium = smart.SmartSimplePipesClientMedium(input, output)
1232
 
        protocol = smart.SmartClientRequestProtocolOne(medium.get_request())
 
1239
        client_medium = medium.SmartSimplePipesClientMedium(input, output)
 
1240
        request = client_medium.get_request()
 
1241
        protocol = smart.SmartClientRequestProtocolOne(request)
1233
1242
        protocol.call('foo')
1234
1243
        self.assertEqual(expected_tuple, protocol.read_response_tuple())
1235
1244
 
1251
1260
        expected_bytes = "foo\n7\nabcdefgdone\n"
1252
1261
        input = StringIO("\n")
1253
1262
        output = StringIO()
1254
 
        medium = smart.SmartSimplePipesClientMedium(input, output)
1255
 
        protocol = smart.SmartClientRequestProtocolOne(medium.get_request())
 
1263
        client_medium = medium.SmartSimplePipesClientMedium(input, output)
 
1264
        request = client_medium.get_request()
 
1265
        protocol = smart.SmartClientRequestProtocolOne(request)
1256
1266
        protocol.call_with_body_bytes(('foo', ), "abcdefg")
1257
1267
        self.assertEqual(expected_bytes, output.getvalue())
1258
1268
 
1262
1272
        expected_bytes = "foo\n7\n1,2\n5,6done\n"
1263
1273
        input = StringIO("\n")
1264
1274
        output = StringIO()
1265
 
        medium = smart.SmartSimplePipesClientMedium(input, output)
1266
 
        protocol = smart.SmartClientRequestProtocolOne(medium.get_request())
 
1275
        client_medium = medium.SmartSimplePipesClientMedium(input, output)
 
1276
        request = client_medium.get_request()
 
1277
        protocol = smart.SmartClientRequestProtocolOne(request)
1267
1278
        protocol.call_with_body_readv_array(('foo', ), [(1,2),(5,6)])
1268
1279
        self.assertEqual(expected_bytes, output.getvalue())
1269
1280
 
1274
1285
        server_bytes = "ok\n7\n1234567done\n"
1275
1286
        input = StringIO(server_bytes)
1276
1287
        output = StringIO()
1277
 
        medium = smart.SmartSimplePipesClientMedium(input, output)
1278
 
        protocol = smart.SmartClientRequestProtocolOne(medium.get_request())
 
1288
        client_medium = medium.SmartSimplePipesClientMedium(input, output)
 
1289
        request = client_medium.get_request()
 
1290
        protocol = smart.SmartClientRequestProtocolOne(request)
1279
1291
        protocol.call('foo')
1280
1292
        protocol.read_response_tuple(True)
1281
1293
        self.assertEqual(expected_bytes, protocol.read_body_bytes())
1290
1302
        server_bytes = "ok\n7\n1234567done\n"
1291
1303
        input = StringIO(server_bytes)
1292
1304
        output = StringIO()
1293
 
        medium = smart.SmartSimplePipesClientMedium(input, output)
1294
 
        protocol = smart.SmartClientRequestProtocolOne(medium.get_request())
 
1305
        client_medium = medium.SmartSimplePipesClientMedium(input, output)
 
1306
        request = client_medium.get_request()
 
1307
        protocol = smart.SmartClientRequestProtocolOne(request)
1295
1308
        protocol.call('foo')
1296
1309
        protocol.read_response_tuple(True)
1297
1310
        self.assertEqual(expected_bytes[0:2], protocol.read_body_bytes(2))
1306
1319
        server_bytes = "ok\n7\n1234567done\n"
1307
1320
        input = StringIO(server_bytes)
1308
1321
        output = StringIO()
1309
 
        medium = smart.SmartSimplePipesClientMedium(input, output)
1310
 
        protocol = smart.SmartClientRequestProtocolOne(medium.get_request())
 
1322
        client_medium = medium.SmartSimplePipesClientMedium(input, output)
 
1323
        request = client_medium.get_request()
 
1324
        protocol = smart.SmartClientRequestProtocolOne(request)
1311
1325
        protocol.call('foo')
1312
1326
        protocol.read_response_tuple(True)
1313
1327
        protocol.cancel_read_body()