mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
Issue #23243: Close explicitly transports in asyncio tests
This commit is contained in:
parent
33cb0396e8
commit
02392c9282
3 changed files with 226 additions and 277 deletions
|
@ -12,6 +12,15 @@ from asyncio.proactor_events import _ProactorDuplexPipeTransport
|
|||
from asyncio import test_utils
|
||||
|
||||
|
||||
def close_transport(transport):
|
||||
# Don't call transport.close() because the event loop and the IOCP proactor
|
||||
# are mocked
|
||||
if transport._sock is None:
|
||||
return
|
||||
transport._sock.close()
|
||||
transport._sock = None
|
||||
|
||||
|
||||
class ProactorSocketTransportTests(test_utils.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
@ -22,17 +31,22 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
self.protocol = test_utils.make_test_protocol(asyncio.Protocol)
|
||||
self.sock = mock.Mock(socket.socket)
|
||||
|
||||
def socket_transport(self, waiter=None):
|
||||
transport = _ProactorSocketTransport(self.loop, self.sock,
|
||||
self.protocol, waiter=waiter)
|
||||
self.addCleanup(close_transport, transport)
|
||||
return transport
|
||||
|
||||
def test_ctor(self):
|
||||
fut = asyncio.Future(loop=self.loop)
|
||||
tr = _ProactorSocketTransport(
|
||||
self.loop, self.sock, self.protocol, fut)
|
||||
tr = self.socket_transport(waiter=fut)
|
||||
test_utils.run_briefly(self.loop)
|
||||
self.assertIsNone(fut.result())
|
||||
self.protocol.connection_made(tr)
|
||||
self.proactor.recv.assert_called_with(self.sock, 4096)
|
||||
|
||||
def test_loop_reading(self):
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr._loop_reading()
|
||||
self.loop._proactor.recv.assert_called_with(self.sock, 4096)
|
||||
self.assertFalse(self.protocol.data_received.called)
|
||||
|
@ -42,8 +56,7 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
res = asyncio.Future(loop=self.loop)
|
||||
res.set_result(b'data')
|
||||
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
|
||||
tr = self.socket_transport()
|
||||
tr._read_fut = res
|
||||
tr._loop_reading(res)
|
||||
self.loop._proactor.recv.assert_called_with(self.sock, 4096)
|
||||
|
@ -53,8 +66,7 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
res = asyncio.Future(loop=self.loop)
|
||||
res.set_result(b'')
|
||||
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
|
||||
tr = self.socket_transport()
|
||||
self.assertRaises(AssertionError, tr._loop_reading, res)
|
||||
|
||||
tr.close = mock.Mock()
|
||||
|
@ -67,7 +79,7 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
def test_loop_reading_aborted(self):
|
||||
err = self.loop._proactor.recv.side_effect = ConnectionAbortedError()
|
||||
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr._fatal_error = mock.Mock()
|
||||
tr._loop_reading()
|
||||
tr._fatal_error.assert_called_with(
|
||||
|
@ -77,7 +89,7 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
def test_loop_reading_aborted_closing(self):
|
||||
self.loop._proactor.recv.side_effect = ConnectionAbortedError()
|
||||
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr._closing = True
|
||||
tr._fatal_error = mock.Mock()
|
||||
tr._loop_reading()
|
||||
|
@ -85,7 +97,7 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
|
||||
def test_loop_reading_aborted_is_fatal(self):
|
||||
self.loop._proactor.recv.side_effect = ConnectionAbortedError()
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr._closing = False
|
||||
tr._fatal_error = mock.Mock()
|
||||
tr._loop_reading()
|
||||
|
@ -94,7 +106,7 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
def test_loop_reading_conn_reset_lost(self):
|
||||
err = self.loop._proactor.recv.side_effect = ConnectionResetError()
|
||||
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr._closing = False
|
||||
tr._fatal_error = mock.Mock()
|
||||
tr._force_close = mock.Mock()
|
||||
|
@ -105,7 +117,7 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
def test_loop_reading_exception(self):
|
||||
err = self.loop._proactor.recv.side_effect = (OSError())
|
||||
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr._fatal_error = mock.Mock()
|
||||
tr._loop_reading()
|
||||
tr._fatal_error.assert_called_with(
|
||||
|
@ -113,19 +125,19 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
'Fatal read error on pipe transport')
|
||||
|
||||
def test_write(self):
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr._loop_writing = mock.Mock()
|
||||
tr.write(b'data')
|
||||
self.assertEqual(tr._buffer, None)
|
||||
tr._loop_writing.assert_called_with(data=b'data')
|
||||
|
||||
def test_write_no_data(self):
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr.write(b'')
|
||||
self.assertFalse(tr._buffer)
|
||||
|
||||
def test_write_more(self):
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr._write_fut = mock.Mock()
|
||||
tr._loop_writing = mock.Mock()
|
||||
tr.write(b'data')
|
||||
|
@ -133,7 +145,7 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
self.assertFalse(tr._loop_writing.called)
|
||||
|
||||
def test_loop_writing(self):
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr._buffer = bytearray(b'data')
|
||||
tr._loop_writing()
|
||||
self.loop._proactor.send.assert_called_with(self.sock, b'data')
|
||||
|
@ -143,7 +155,7 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
@mock.patch('asyncio.proactor_events.logger')
|
||||
def test_loop_writing_err(self, m_log):
|
||||
err = self.loop._proactor.send.side_effect = OSError()
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr._fatal_error = mock.Mock()
|
||||
tr._buffer = [b'da', b'ta']
|
||||
tr._loop_writing()
|
||||
|
@ -164,7 +176,7 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
fut = asyncio.Future(loop=self.loop)
|
||||
fut.set_result(b'data')
|
||||
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr._write_fut = fut
|
||||
tr._loop_writing(fut)
|
||||
self.assertIsNone(tr._write_fut)
|
||||
|
@ -173,7 +185,7 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
fut = asyncio.Future(loop=self.loop)
|
||||
fut.set_result(1)
|
||||
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr._write_fut = fut
|
||||
tr.close()
|
||||
tr._loop_writing(fut)
|
||||
|
@ -182,13 +194,13 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
self.protocol.connection_lost.assert_called_with(None)
|
||||
|
||||
def test_abort(self):
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr._force_close = mock.Mock()
|
||||
tr.abort()
|
||||
tr._force_close.assert_called_with(None)
|
||||
|
||||
def test_close(self):
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr.close()
|
||||
test_utils.run_briefly(self.loop)
|
||||
self.protocol.connection_lost.assert_called_with(None)
|
||||
|
@ -201,14 +213,14 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
self.assertFalse(self.protocol.connection_lost.called)
|
||||
|
||||
def test_close_write_fut(self):
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr._write_fut = mock.Mock()
|
||||
tr.close()
|
||||
test_utils.run_briefly(self.loop)
|
||||
self.assertFalse(self.protocol.connection_lost.called)
|
||||
|
||||
def test_close_buffer(self):
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr._buffer = [b'data']
|
||||
tr.close()
|
||||
test_utils.run_briefly(self.loop)
|
||||
|
@ -216,14 +228,14 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
|
||||
@mock.patch('asyncio.base_events.logger')
|
||||
def test_fatal_error(self, m_logging):
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr._force_close = mock.Mock()
|
||||
tr._fatal_error(None)
|
||||
self.assertTrue(tr._force_close.called)
|
||||
self.assertTrue(m_logging.error.called)
|
||||
|
||||
def test_force_close(self):
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr._buffer = [b'data']
|
||||
read_fut = tr._read_fut = mock.Mock()
|
||||
write_fut = tr._write_fut = mock.Mock()
|
||||
|
@ -237,14 +249,14 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
self.assertEqual(tr._conn_lost, 1)
|
||||
|
||||
def test_force_close_idempotent(self):
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr._closing = True
|
||||
tr._force_close(None)
|
||||
test_utils.run_briefly(self.loop)
|
||||
self.assertFalse(self.protocol.connection_lost.called)
|
||||
|
||||
def test_fatal_error_2(self):
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr._buffer = [b'data']
|
||||
tr._force_close(None)
|
||||
|
||||
|
@ -253,14 +265,13 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
self.assertEqual(None, tr._buffer)
|
||||
|
||||
def test_call_connection_lost(self):
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
tr._call_connection_lost(None)
|
||||
self.assertTrue(self.protocol.connection_lost.called)
|
||||
self.assertTrue(self.sock.close.called)
|
||||
|
||||
def test_write_eof(self):
|
||||
tr = _ProactorSocketTransport(
|
||||
self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
self.assertTrue(tr.can_write_eof())
|
||||
tr.write_eof()
|
||||
self.sock.shutdown.assert_called_with(socket.SHUT_WR)
|
||||
|
@ -269,7 +280,7 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
tr.close()
|
||||
|
||||
def test_write_eof_buffer(self):
|
||||
tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
f = asyncio.Future(loop=self.loop)
|
||||
tr._loop._proactor.send.return_value = f
|
||||
tr.write(b'data')
|
||||
|
@ -313,11 +324,10 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
self.assertFalse(tr.can_write_eof())
|
||||
with self.assertRaises(NotImplementedError):
|
||||
tr.write_eof()
|
||||
tr.close()
|
||||
close_transport(tr)
|
||||
|
||||
def test_pause_resume_reading(self):
|
||||
tr = _ProactorSocketTransport(
|
||||
self.loop, self.sock, self.protocol)
|
||||
tr = self.socket_transport()
|
||||
futures = []
|
||||
for msg in [b'data1', b'data2', b'data3', b'data4', b'']:
|
||||
f = asyncio.Future(loop=self.loop)
|
||||
|
@ -345,10 +355,7 @@ class ProactorSocketTransportTests(test_utils.TestCase):
|
|||
|
||||
|
||||
def pause_writing_transport(self, high):
|
||||
tr = _ProactorSocketTransport(
|
||||
self.loop, self.sock, self.protocol)
|
||||
self.addCleanup(tr.close)
|
||||
|
||||
tr = self.socket_transport()
|
||||
tr.set_write_buffer_limits(high=high)
|
||||
|
||||
self.assertEqual(tr.get_write_buffer_size(), 0)
|
||||
|
@ -439,7 +446,7 @@ class BaseProactorEventLoopTests(test_utils.TestCase):
|
|||
return (self.ssock, self.csock)
|
||||
|
||||
self.loop = EventLoop(self.proactor)
|
||||
self.set_event_loop(self.loop, cleanup=False)
|
||||
self.set_event_loop(self.loop)
|
||||
|
||||
@mock.patch.object(BaseProactorEventLoop, 'call_soon')
|
||||
@mock.patch.object(BaseProactorEventLoop, '_socketpair')
|
||||
|
@ -451,6 +458,7 @@ class BaseProactorEventLoopTests(test_utils.TestCase):
|
|||
self.assertIs(loop._csock, csock)
|
||||
self.assertEqual(loop._internal_fds, 1)
|
||||
call_soon.assert_called_with(loop._loop_self_reading)
|
||||
loop.close()
|
||||
|
||||
def test_close_self_pipe(self):
|
||||
self.loop._close_self_pipe()
|
||||
|
@ -497,6 +505,7 @@ class BaseProactorEventLoopTests(test_utils.TestCase):
|
|||
def test_make_socket_transport(self):
|
||||
tr = self.loop._make_socket_transport(self.sock, asyncio.Protocol())
|
||||
self.assertIsInstance(tr, _ProactorSocketTransport)
|
||||
close_transport(tr)
|
||||
|
||||
def test_loop_self_reading(self):
|
||||
self.loop._loop_self_reading()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue