blob: 5a0f0881e4c65c2f6c0545982bb49c85aee812f2 [file] [log] [blame]
Guido van Rossum27b7c7e2013-10-17 13:40:50 -07001"""Tests for proactor_events.py"""
2
3import socket
4import unittest
Victor Stinner24ba2032014-02-26 10:25:02 +01005from unittest import mock
Guido van Rossum27b7c7e2013-10-17 13:40:50 -07006
7import asyncio
Victor Stinner128ee222014-01-25 22:22:18 +01008from asyncio.proactor_events import BaseProactorEventLoop
Guido van Rossum27b7c7e2013-10-17 13:40:50 -07009from asyncio.proactor_events import _ProactorSocketTransport
10from asyncio.proactor_events import _ProactorWritePipeTransport
11from asyncio.proactor_events import _ProactorDuplexPipeTransport
12from asyncio import test_utils
13
14
Victor Stinner02392c92015-01-15 13:18:32 +010015def close_transport(transport):
16 # Don't call transport.close() because the event loop and the IOCP proactor
17 # are mocked
18 if transport._sock is None:
19 return
20 transport._sock.close()
21 transport._sock = None
22
23
Victor Stinnerc73701d2014-06-18 01:36:32 +020024class ProactorSocketTransportTests(test_utils.TestCase):
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070025
26 def setUp(self):
Victor Stinnerc73701d2014-06-18 01:36:32 +020027 self.loop = self.new_test_loop()
Victor Stinner33cb0392015-01-15 13:17:34 +010028 self.addCleanup(self.loop.close)
Victor Stinner24ba2032014-02-26 10:25:02 +010029 self.proactor = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070030 self.loop._proactor = self.proactor
31 self.protocol = test_utils.make_test_protocol(asyncio.Protocol)
Victor Stinner24ba2032014-02-26 10:25:02 +010032 self.sock = mock.Mock(socket.socket)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070033
Victor Stinner02392c92015-01-15 13:18:32 +010034 def socket_transport(self, waiter=None):
35 transport = _ProactorSocketTransport(self.loop, self.sock,
36 self.protocol, waiter=waiter)
37 self.addCleanup(close_transport, transport)
38 return transport
39
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070040 def test_ctor(self):
41 fut = asyncio.Future(loop=self.loop)
Victor Stinner02392c92015-01-15 13:18:32 +010042 tr = self.socket_transport(waiter=fut)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070043 test_utils.run_briefly(self.loop)
44 self.assertIsNone(fut.result())
45 self.protocol.connection_made(tr)
46 self.proactor.recv.assert_called_with(self.sock, 4096)
47
48 def test_loop_reading(self):
Victor Stinner02392c92015-01-15 13:18:32 +010049 tr = self.socket_transport()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070050 tr._loop_reading()
51 self.loop._proactor.recv.assert_called_with(self.sock, 4096)
52 self.assertFalse(self.protocol.data_received.called)
53 self.assertFalse(self.protocol.eof_received.called)
54
55 def test_loop_reading_data(self):
56 res = asyncio.Future(loop=self.loop)
57 res.set_result(b'data')
58
Victor Stinner02392c92015-01-15 13:18:32 +010059 tr = self.socket_transport()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070060 tr._read_fut = res
61 tr._loop_reading(res)
62 self.loop._proactor.recv.assert_called_with(self.sock, 4096)
63 self.protocol.data_received.assert_called_with(b'data')
64
65 def test_loop_reading_no_data(self):
66 res = asyncio.Future(loop=self.loop)
67 res.set_result(b'')
68
Victor Stinner02392c92015-01-15 13:18:32 +010069 tr = self.socket_transport()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070070 self.assertRaises(AssertionError, tr._loop_reading, res)
71
Victor Stinner24ba2032014-02-26 10:25:02 +010072 tr.close = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070073 tr._read_fut = res
74 tr._loop_reading(res)
75 self.assertFalse(self.loop._proactor.recv.called)
76 self.assertTrue(self.protocol.eof_received.called)
77 self.assertTrue(tr.close.called)
78
79 def test_loop_reading_aborted(self):
80 err = self.loop._proactor.recv.side_effect = ConnectionAbortedError()
81
Victor Stinner02392c92015-01-15 13:18:32 +010082 tr = self.socket_transport()
Victor Stinner24ba2032014-02-26 10:25:02 +010083 tr._fatal_error = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070084 tr._loop_reading()
Victor Stinner065ca252014-02-19 01:40:41 +010085 tr._fatal_error.assert_called_with(
86 err,
87 'Fatal read error on pipe transport')
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070088
89 def test_loop_reading_aborted_closing(self):
90 self.loop._proactor.recv.side_effect = ConnectionAbortedError()
91
Victor Stinner02392c92015-01-15 13:18:32 +010092 tr = self.socket_transport()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070093 tr._closing = True
Victor Stinner24ba2032014-02-26 10:25:02 +010094 tr._fatal_error = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070095 tr._loop_reading()
96 self.assertFalse(tr._fatal_error.called)
97
98 def test_loop_reading_aborted_is_fatal(self):
99 self.loop._proactor.recv.side_effect = ConnectionAbortedError()
Victor Stinner02392c92015-01-15 13:18:32 +0100100 tr = self.socket_transport()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700101 tr._closing = False
Victor Stinner24ba2032014-02-26 10:25:02 +0100102 tr._fatal_error = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700103 tr._loop_reading()
104 self.assertTrue(tr._fatal_error.called)
105
106 def test_loop_reading_conn_reset_lost(self):
107 err = self.loop._proactor.recv.side_effect = ConnectionResetError()
108
Victor Stinner02392c92015-01-15 13:18:32 +0100109 tr = self.socket_transport()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700110 tr._closing = False
Victor Stinner24ba2032014-02-26 10:25:02 +0100111 tr._fatal_error = mock.Mock()
112 tr._force_close = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700113 tr._loop_reading()
114 self.assertFalse(tr._fatal_error.called)
115 tr._force_close.assert_called_with(err)
116
117 def test_loop_reading_exception(self):
118 err = self.loop._proactor.recv.side_effect = (OSError())
119
Victor Stinner02392c92015-01-15 13:18:32 +0100120 tr = self.socket_transport()
Victor Stinner24ba2032014-02-26 10:25:02 +0100121 tr._fatal_error = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700122 tr._loop_reading()
Victor Stinner065ca252014-02-19 01:40:41 +0100123 tr._fatal_error.assert_called_with(
124 err,
125 'Fatal read error on pipe transport')
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700126
127 def test_write(self):
Victor Stinner02392c92015-01-15 13:18:32 +0100128 tr = self.socket_transport()
Victor Stinner24ba2032014-02-26 10:25:02 +0100129 tr._loop_writing = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700130 tr.write(b'data')
Guido van Rossumebb8e582013-12-04 12:12:07 -0800131 self.assertEqual(tr._buffer, None)
132 tr._loop_writing.assert_called_with(data=b'data')
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700133
134 def test_write_no_data(self):
Victor Stinner02392c92015-01-15 13:18:32 +0100135 tr = self.socket_transport()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700136 tr.write(b'')
137 self.assertFalse(tr._buffer)
138
139 def test_write_more(self):
Victor Stinner02392c92015-01-15 13:18:32 +0100140 tr = self.socket_transport()
Victor Stinner24ba2032014-02-26 10:25:02 +0100141 tr._write_fut = mock.Mock()
142 tr._loop_writing = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700143 tr.write(b'data')
Guido van Rossumebb8e582013-12-04 12:12:07 -0800144 self.assertEqual(tr._buffer, b'data')
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700145 self.assertFalse(tr._loop_writing.called)
146
147 def test_loop_writing(self):
Victor Stinner02392c92015-01-15 13:18:32 +0100148 tr = self.socket_transport()
Guido van Rossumebb8e582013-12-04 12:12:07 -0800149 tr._buffer = bytearray(b'data')
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700150 tr._loop_writing()
151 self.loop._proactor.send.assert_called_with(self.sock, b'data')
152 self.loop._proactor.send.return_value.add_done_callback.\
153 assert_called_with(tr._loop_writing)
154
Victor Stinner24ba2032014-02-26 10:25:02 +0100155 @mock.patch('asyncio.proactor_events.logger')
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700156 def test_loop_writing_err(self, m_log):
157 err = self.loop._proactor.send.side_effect = OSError()
Victor Stinner02392c92015-01-15 13:18:32 +0100158 tr = self.socket_transport()
Victor Stinner24ba2032014-02-26 10:25:02 +0100159 tr._fatal_error = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700160 tr._buffer = [b'da', b'ta']
161 tr._loop_writing()
Victor Stinner065ca252014-02-19 01:40:41 +0100162 tr._fatal_error.assert_called_with(
163 err,
164 'Fatal write error on pipe transport')
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700165 tr._conn_lost = 1
166
167 tr.write(b'data')
168 tr.write(b'data')
169 tr.write(b'data')
170 tr.write(b'data')
171 tr.write(b'data')
Guido van Rossumebb8e582013-12-04 12:12:07 -0800172 self.assertEqual(tr._buffer, None)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700173 m_log.warning.assert_called_with('socket.send() raised exception.')
174
175 def test_loop_writing_stop(self):
176 fut = asyncio.Future(loop=self.loop)
177 fut.set_result(b'data')
178
Victor Stinner02392c92015-01-15 13:18:32 +0100179 tr = self.socket_transport()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700180 tr._write_fut = fut
181 tr._loop_writing(fut)
182 self.assertIsNone(tr._write_fut)
183
184 def test_loop_writing_closing(self):
185 fut = asyncio.Future(loop=self.loop)
186 fut.set_result(1)
187
Victor Stinner02392c92015-01-15 13:18:32 +0100188 tr = self.socket_transport()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700189 tr._write_fut = fut
190 tr.close()
191 tr._loop_writing(fut)
192 self.assertIsNone(tr._write_fut)
193 test_utils.run_briefly(self.loop)
194 self.protocol.connection_lost.assert_called_with(None)
195
196 def test_abort(self):
Victor Stinner02392c92015-01-15 13:18:32 +0100197 tr = self.socket_transport()
Victor Stinner24ba2032014-02-26 10:25:02 +0100198 tr._force_close = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700199 tr.abort()
200 tr._force_close.assert_called_with(None)
201
202 def test_close(self):
Victor Stinner02392c92015-01-15 13:18:32 +0100203 tr = self.socket_transport()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700204 tr.close()
205 test_utils.run_briefly(self.loop)
206 self.protocol.connection_lost.assert_called_with(None)
Yury Selivanov5bb1afb2015-11-16 12:43:21 -0500207 self.assertTrue(tr.is_closing())
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700208 self.assertEqual(tr._conn_lost, 1)
209
210 self.protocol.connection_lost.reset_mock()
211 tr.close()
212 test_utils.run_briefly(self.loop)
213 self.assertFalse(self.protocol.connection_lost.called)
214
215 def test_close_write_fut(self):
Victor Stinner02392c92015-01-15 13:18:32 +0100216 tr = self.socket_transport()
Victor Stinner24ba2032014-02-26 10:25:02 +0100217 tr._write_fut = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700218 tr.close()
219 test_utils.run_briefly(self.loop)
220 self.assertFalse(self.protocol.connection_lost.called)
221
222 def test_close_buffer(self):
Victor Stinner02392c92015-01-15 13:18:32 +0100223 tr = self.socket_transport()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700224 tr._buffer = [b'data']
225 tr.close()
226 test_utils.run_briefly(self.loop)
227 self.assertFalse(self.protocol.connection_lost.called)
228
Victor Stinner24ba2032014-02-26 10:25:02 +0100229 @mock.patch('asyncio.base_events.logger')
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700230 def test_fatal_error(self, m_logging):
Victor Stinner02392c92015-01-15 13:18:32 +0100231 tr = self.socket_transport()
Victor Stinner24ba2032014-02-26 10:25:02 +0100232 tr._force_close = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700233 tr._fatal_error(None)
234 self.assertTrue(tr._force_close.called)
Yury Selivanovff827f02014-02-18 18:02:19 -0500235 self.assertTrue(m_logging.error.called)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700236
237 def test_force_close(self):
Victor Stinner02392c92015-01-15 13:18:32 +0100238 tr = self.socket_transport()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700239 tr._buffer = [b'data']
Victor Stinner24ba2032014-02-26 10:25:02 +0100240 read_fut = tr._read_fut = mock.Mock()
241 write_fut = tr._write_fut = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700242 tr._force_close(None)
243
244 read_fut.cancel.assert_called_with()
245 write_fut.cancel.assert_called_with()
246 test_utils.run_briefly(self.loop)
247 self.protocol.connection_lost.assert_called_with(None)
Guido van Rossumebb8e582013-12-04 12:12:07 -0800248 self.assertEqual(None, tr._buffer)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700249 self.assertEqual(tr._conn_lost, 1)
250
251 def test_force_close_idempotent(self):
Victor Stinner02392c92015-01-15 13:18:32 +0100252 tr = self.socket_transport()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700253 tr._closing = True
254 tr._force_close(None)
255 test_utils.run_briefly(self.loop)
256 self.assertFalse(self.protocol.connection_lost.called)
257
258 def test_fatal_error_2(self):
Victor Stinner02392c92015-01-15 13:18:32 +0100259 tr = self.socket_transport()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700260 tr._buffer = [b'data']
261 tr._force_close(None)
262
263 test_utils.run_briefly(self.loop)
264 self.protocol.connection_lost.assert_called_with(None)
Guido van Rossumebb8e582013-12-04 12:12:07 -0800265 self.assertEqual(None, tr._buffer)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700266
267 def test_call_connection_lost(self):
Victor Stinner02392c92015-01-15 13:18:32 +0100268 tr = self.socket_transport()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700269 tr._call_connection_lost(None)
270 self.assertTrue(self.protocol.connection_lost.called)
271 self.assertTrue(self.sock.close.called)
272
273 def test_write_eof(self):
Victor Stinner02392c92015-01-15 13:18:32 +0100274 tr = self.socket_transport()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700275 self.assertTrue(tr.can_write_eof())
276 tr.write_eof()
277 self.sock.shutdown.assert_called_with(socket.SHUT_WR)
278 tr.write_eof()
279 self.assertEqual(self.sock.shutdown.call_count, 1)
280 tr.close()
281
282 def test_write_eof_buffer(self):
Victor Stinner02392c92015-01-15 13:18:32 +0100283 tr = self.socket_transport()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700284 f = asyncio.Future(loop=self.loop)
285 tr._loop._proactor.send.return_value = f
286 tr.write(b'data')
287 tr.write_eof()
288 self.assertTrue(tr._eof_written)
289 self.assertFalse(self.sock.shutdown.called)
290 tr._loop._proactor.send.assert_called_with(self.sock, b'data')
291 f.set_result(4)
292 self.loop._run_once()
293 self.sock.shutdown.assert_called_with(socket.SHUT_WR)
294 tr.close()
295
296 def test_write_eof_write_pipe(self):
297 tr = _ProactorWritePipeTransport(
298 self.loop, self.sock, self.protocol)
299 self.assertTrue(tr.can_write_eof())
300 tr.write_eof()
Yury Selivanov5bb1afb2015-11-16 12:43:21 -0500301 self.assertTrue(tr.is_closing())
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700302 self.loop._run_once()
303 self.assertTrue(self.sock.close.called)
304 tr.close()
305
306 def test_write_eof_buffer_write_pipe(self):
307 tr = _ProactorWritePipeTransport(self.loop, self.sock, self.protocol)
308 f = asyncio.Future(loop=self.loop)
309 tr._loop._proactor.send.return_value = f
310 tr.write(b'data')
311 tr.write_eof()
Yury Selivanov5bb1afb2015-11-16 12:43:21 -0500312 self.assertTrue(tr.is_closing())
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700313 self.assertFalse(self.sock.shutdown.called)
314 tr._loop._proactor.send.assert_called_with(self.sock, b'data')
315 f.set_result(4)
316 self.loop._run_once()
317 self.loop._run_once()
318 self.assertTrue(self.sock.close.called)
319 tr.close()
320
321 def test_write_eof_duplex_pipe(self):
322 tr = _ProactorDuplexPipeTransport(
323 self.loop, self.sock, self.protocol)
324 self.assertFalse(tr.can_write_eof())
325 with self.assertRaises(NotImplementedError):
326 tr.write_eof()
Victor Stinner02392c92015-01-15 13:18:32 +0100327 close_transport(tr)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700328
Guido van Rossum57497ad2013-10-18 07:58:20 -0700329 def test_pause_resume_reading(self):
Victor Stinner02392c92015-01-15 13:18:32 +0100330 tr = self.socket_transport()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700331 futures = []
332 for msg in [b'data1', b'data2', b'data3', b'data4', b'']:
333 f = asyncio.Future(loop=self.loop)
334 f.set_result(msg)
335 futures.append(f)
336 self.loop._proactor.recv.side_effect = futures
337 self.loop._run_once()
338 self.assertFalse(tr._paused)
339 self.loop._run_once()
340 self.protocol.data_received.assert_called_with(b'data1')
341 self.loop._run_once()
342 self.protocol.data_received.assert_called_with(b'data2')
Guido van Rossum57497ad2013-10-18 07:58:20 -0700343 tr.pause_reading()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700344 self.assertTrue(tr._paused)
345 for i in range(10):
346 self.loop._run_once()
347 self.protocol.data_received.assert_called_with(b'data2')
Guido van Rossum57497ad2013-10-18 07:58:20 -0700348 tr.resume_reading()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700349 self.assertFalse(tr._paused)
350 self.loop._run_once()
351 self.protocol.data_received.assert_called_with(b'data3')
352 self.loop._run_once()
353 self.protocol.data_received.assert_called_with(b'data4')
354 tr.close()
355
356
Victor Stinnerdf75d5b2014-12-11 22:23:19 +0100357 def pause_writing_transport(self, high):
Victor Stinner02392c92015-01-15 13:18:32 +0100358 tr = self.socket_transport()
Victor Stinnerdf75d5b2014-12-11 22:23:19 +0100359 tr.set_write_buffer_limits(high=high)
360
361 self.assertEqual(tr.get_write_buffer_size(), 0)
362 self.assertFalse(self.protocol.pause_writing.called)
363 self.assertFalse(self.protocol.resume_writing.called)
364 return tr
365
366 def test_pause_resume_writing(self):
367 tr = self.pause_writing_transport(high=4)
368
369 # write a large chunk, must pause writing
370 fut = asyncio.Future(loop=self.loop)
371 self.loop._proactor.send.return_value = fut
372 tr.write(b'large data')
373 self.loop._run_once()
374 self.assertTrue(self.protocol.pause_writing.called)
375
376 # flush the buffer
377 fut.set_result(None)
378 self.loop._run_once()
379 self.assertEqual(tr.get_write_buffer_size(), 0)
380 self.assertTrue(self.protocol.resume_writing.called)
381
382 def test_pause_writing_2write(self):
383 tr = self.pause_writing_transport(high=4)
384
385 # first short write, the buffer is not full (3 <= 4)
386 fut1 = asyncio.Future(loop=self.loop)
387 self.loop._proactor.send.return_value = fut1
388 tr.write(b'123')
389 self.loop._run_once()
390 self.assertEqual(tr.get_write_buffer_size(), 3)
391 self.assertFalse(self.protocol.pause_writing.called)
392
393 # fill the buffer, must pause writing (6 > 4)
394 tr.write(b'abc')
395 self.loop._run_once()
396 self.assertEqual(tr.get_write_buffer_size(), 6)
397 self.assertTrue(self.protocol.pause_writing.called)
398
399 def test_pause_writing_3write(self):
400 tr = self.pause_writing_transport(high=4)
401
402 # first short write, the buffer is not full (1 <= 4)
403 fut = asyncio.Future(loop=self.loop)
404 self.loop._proactor.send.return_value = fut
405 tr.write(b'1')
406 self.loop._run_once()
407 self.assertEqual(tr.get_write_buffer_size(), 1)
408 self.assertFalse(self.protocol.pause_writing.called)
409
410 # second short write, the buffer is not full (3 <= 4)
411 tr.write(b'23')
412 self.loop._run_once()
413 self.assertEqual(tr.get_write_buffer_size(), 3)
414 self.assertFalse(self.protocol.pause_writing.called)
415
416 # fill the buffer, must pause writing (6 > 4)
417 tr.write(b'abc')
418 self.loop._run_once()
419 self.assertEqual(tr.get_write_buffer_size(), 6)
420 self.assertTrue(self.protocol.pause_writing.called)
421
422 def test_dont_pause_writing(self):
423 tr = self.pause_writing_transport(high=4)
424
425 # write a large chunk which completes immedialty,
426 # it should not pause writing
427 fut = asyncio.Future(loop=self.loop)
428 fut.set_result(None)
429 self.loop._proactor.send.return_value = fut
430 tr.write(b'very large data')
431 self.loop._run_once()
432 self.assertEqual(tr.get_write_buffer_size(), 0)
433 self.assertFalse(self.protocol.pause_writing.called)
434
435
Victor Stinnerc73701d2014-06-18 01:36:32 +0200436class BaseProactorEventLoopTests(test_utils.TestCase):
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700437
438 def setUp(self):
Victor Stinner24ba2032014-02-26 10:25:02 +0100439 self.sock = mock.Mock(socket.socket)
440 self.proactor = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700441
Victor Stinner24ba2032014-02-26 10:25:02 +0100442 self.ssock, self.csock = mock.Mock(), mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700443
Victor Stinner128ee222014-01-25 22:22:18 +0100444 class EventLoop(BaseProactorEventLoop):
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700445 def _socketpair(s):
446 return (self.ssock, self.csock)
447
448 self.loop = EventLoop(self.proactor)
Victor Stinner02392c92015-01-15 13:18:32 +0100449 self.set_event_loop(self.loop)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700450
Victor Stinner956de692014-12-26 21:07:52 +0100451 @mock.patch.object(BaseProactorEventLoop, 'call_soon')
Victor Stinner24ba2032014-02-26 10:25:02 +0100452 @mock.patch.object(BaseProactorEventLoop, '_socketpair')
Victor Stinner956de692014-12-26 21:07:52 +0100453 def test_ctor(self, socketpair, call_soon):
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700454 ssock, csock = socketpair.return_value = (
Victor Stinner24ba2032014-02-26 10:25:02 +0100455 mock.Mock(), mock.Mock())
Victor Stinner128ee222014-01-25 22:22:18 +0100456 loop = BaseProactorEventLoop(self.proactor)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700457 self.assertIs(loop._ssock, ssock)
458 self.assertIs(loop._csock, csock)
459 self.assertEqual(loop._internal_fds, 1)
Victor Stinner956de692014-12-26 21:07:52 +0100460 call_soon.assert_called_with(loop._loop_self_reading)
Victor Stinner02392c92015-01-15 13:18:32 +0100461 loop.close()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700462
463 def test_close_self_pipe(self):
464 self.loop._close_self_pipe()
465 self.assertEqual(self.loop._internal_fds, 0)
466 self.assertTrue(self.ssock.close.called)
467 self.assertTrue(self.csock.close.called)
468 self.assertIsNone(self.loop._ssock)
469 self.assertIsNone(self.loop._csock)
470
Victor Stinner33cb0392015-01-15 13:17:34 +0100471 # Don't call close(): _close_self_pipe() cannot be called twice
472 self.loop._closed = True
473
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700474 def test_close(self):
Victor Stinner24ba2032014-02-26 10:25:02 +0100475 self.loop._close_self_pipe = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700476 self.loop.close()
477 self.assertTrue(self.loop._close_self_pipe.called)
478 self.assertTrue(self.proactor.close.called)
479 self.assertIsNone(self.loop._proactor)
480
481 self.loop._close_self_pipe.reset_mock()
482 self.loop.close()
483 self.assertFalse(self.loop._close_self_pipe.called)
484
485 def test_sock_recv(self):
486 self.loop.sock_recv(self.sock, 1024)
487 self.proactor.recv.assert_called_with(self.sock, 1024)
488
489 def test_sock_sendall(self):
490 self.loop.sock_sendall(self.sock, b'data')
491 self.proactor.send.assert_called_with(self.sock, b'data')
492
493 def test_sock_connect(self):
494 self.loop.sock_connect(self.sock, 123)
495 self.proactor.connect.assert_called_with(self.sock, 123)
496
497 def test_sock_accept(self):
498 self.loop.sock_accept(self.sock)
499 self.proactor.accept.assert_called_with(self.sock)
500
501 def test_socketpair(self):
Victor Stinner978a9af2015-01-29 17:50:58 +0100502 class EventLoop(BaseProactorEventLoop):
503 # override the destructor to not log a ResourceWarning
504 def __del__(self):
505 pass
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700506 self.assertRaises(
Victor Stinner978a9af2015-01-29 17:50:58 +0100507 NotImplementedError, EventLoop, self.proactor)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700508
509 def test_make_socket_transport(self):
Victor Stinnera1254972014-02-11 11:34:30 +0100510 tr = self.loop._make_socket_transport(self.sock, asyncio.Protocol())
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700511 self.assertIsInstance(tr, _ProactorSocketTransport)
Victor Stinner02392c92015-01-15 13:18:32 +0100512 close_transport(tr)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700513
514 def test_loop_self_reading(self):
515 self.loop._loop_self_reading()
516 self.proactor.recv.assert_called_with(self.ssock, 4096)
517 self.proactor.recv.return_value.add_done_callback.assert_called_with(
518 self.loop._loop_self_reading)
519
520 def test_loop_self_reading_fut(self):
Victor Stinner24ba2032014-02-26 10:25:02 +0100521 fut = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700522 self.loop._loop_self_reading(fut)
523 self.assertTrue(fut.result.called)
524 self.proactor.recv.assert_called_with(self.ssock, 4096)
525 self.proactor.recv.return_value.add_done_callback.assert_called_with(
526 self.loop._loop_self_reading)
527
528 def test_loop_self_reading_exception(self):
Victor Stinner24ba2032014-02-26 10:25:02 +0100529 self.loop.close = mock.Mock()
Victor Stinnercd0f7f92015-01-21 23:38:37 +0100530 self.loop.call_exception_handler = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700531 self.proactor.recv.side_effect = OSError()
Victor Stinnercd0f7f92015-01-21 23:38:37 +0100532 self.loop._loop_self_reading()
533 self.assertTrue(self.loop.call_exception_handler.called)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700534
535 def test_write_to_self(self):
536 self.loop._write_to_self()
Victor Stinnerfe5649c2014-07-17 22:43:40 +0200537 self.csock.send.assert_called_with(b'\0')
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700538
539 def test_process_events(self):
540 self.loop._process_events([])
541
Victor Stinner24ba2032014-02-26 10:25:02 +0100542 @mock.patch('asyncio.base_events.logger')
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700543 def test_create_server(self, m_log):
Victor Stinner24ba2032014-02-26 10:25:02 +0100544 pf = mock.Mock()
545 call_soon = self.loop.call_soon = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700546
547 self.loop._start_serving(pf, self.sock)
548 self.assertTrue(call_soon.called)
549
550 # callback
551 loop = call_soon.call_args[0][0]
552 loop()
553 self.proactor.accept.assert_called_with(self.sock)
554
555 # conn
Victor Stinner24ba2032014-02-26 10:25:02 +0100556 fut = mock.Mock()
557 fut.result.return_value = (mock.Mock(), mock.Mock())
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700558
Victor Stinner24ba2032014-02-26 10:25:02 +0100559 make_tr = self.loop._make_socket_transport = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700560 loop(fut)
561 self.assertTrue(fut.result.called)
562 self.assertTrue(make_tr.called)
563
564 # exception
565 fut.result.side_effect = OSError()
566 loop(fut)
567 self.assertTrue(self.sock.close.called)
Yury Selivanovff827f02014-02-18 18:02:19 -0500568 self.assertTrue(m_log.error.called)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700569
570 def test_create_server_cancel(self):
Victor Stinner24ba2032014-02-26 10:25:02 +0100571 pf = mock.Mock()
572 call_soon = self.loop.call_soon = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700573
574 self.loop._start_serving(pf, self.sock)
575 loop = call_soon.call_args[0][0]
576
577 # cancelled
578 fut = asyncio.Future(loop=self.loop)
579 fut.cancel()
580 loop(fut)
581 self.assertTrue(self.sock.close.called)
582
583 def test_stop_serving(self):
Victor Stinner24ba2032014-02-26 10:25:02 +0100584 sock = mock.Mock()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700585 self.loop._stop_serving(sock)
586 self.assertTrue(sock.close.called)
587 self.proactor._stop_serving.assert_called_with(sock)
Antoine Pitroucb1fe982013-10-20 21:02:53 +0200588
589
590if __name__ == '__main__':
591 unittest.main()