mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
bpo-32015: Asyncio looping during simultaneously socket read/write an… (#4386)
* bpo-32015: Asyncio cycling during simultaneously socket read/write and reconnection * Tests fix * Tests fix * News add * Add new unit tests
This commit is contained in:
parent
56935a53b1
commit
e1d62e0b7c
3 changed files with 79 additions and 38 deletions
|
@ -182,7 +182,27 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
|
|||
|
||||
f = self.loop.sock_recv(sock, 1024)
|
||||
self.assertIsInstance(f, asyncio.Future)
|
||||
self.loop._sock_recv.assert_called_with(f, False, sock, 1024)
|
||||
self.loop._sock_recv.assert_called_with(f, None, sock, 1024)
|
||||
|
||||
def test_sock_recv_reconnection(self):
|
||||
sock = mock.Mock()
|
||||
sock.fileno.return_value = 10
|
||||
sock.recv.side_effect = BlockingIOError
|
||||
|
||||
self.loop.add_reader = mock.Mock()
|
||||
self.loop.remove_reader = mock.Mock()
|
||||
fut = self.loop.sock_recv(sock, 1024)
|
||||
callback = self.loop.add_reader.call_args[0][1]
|
||||
params = self.loop.add_reader.call_args[0][2:]
|
||||
|
||||
# emulate the old socket has closed, but the new one has
|
||||
# the same fileno, so callback is called with old (closed) socket
|
||||
sock.fileno.return_value = -1
|
||||
sock.recv.side_effect = OSError(9)
|
||||
callback(*params)
|
||||
|
||||
self.assertIsInstance(fut.exception(), OSError)
|
||||
self.assertEqual((10,), self.loop.remove_reader.call_args[0])
|
||||
|
||||
def test__sock_recv_canceled_fut(self):
|
||||
sock = mock.Mock()
|
||||
|
@ -190,7 +210,7 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
|
|||
f = asyncio.Future(loop=self.loop)
|
||||
f.cancel()
|
||||
|
||||
self.loop._sock_recv(f, False, sock, 1024)
|
||||
self.loop._sock_recv(f, None, sock, 1024)
|
||||
self.assertFalse(sock.recv.called)
|
||||
|
||||
def test__sock_recv_unregister(self):
|
||||
|
@ -201,7 +221,7 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
|
|||
f.cancel()
|
||||
|
||||
self.loop.remove_reader = mock.Mock()
|
||||
self.loop._sock_recv(f, True, sock, 1024)
|
||||
self.loop._sock_recv(f, 10, sock, 1024)
|
||||
self.assertEqual((10,), self.loop.remove_reader.call_args[0])
|
||||
|
||||
def test__sock_recv_tryagain(self):
|
||||
|
@ -211,8 +231,8 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
|
|||
sock.recv.side_effect = BlockingIOError
|
||||
|
||||
self.loop.add_reader = mock.Mock()
|
||||
self.loop._sock_recv(f, False, sock, 1024)
|
||||
self.assertEqual((10, self.loop._sock_recv, f, True, sock, 1024),
|
||||
self.loop._sock_recv(f, None, sock, 1024)
|
||||
self.assertEqual((10, self.loop._sock_recv, f, 10, sock, 1024),
|
||||
self.loop.add_reader.call_args[0])
|
||||
|
||||
def test__sock_recv_exception(self):
|
||||
|
@ -221,7 +241,7 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
|
|||
sock.fileno.return_value = 10
|
||||
err = sock.recv.side_effect = OSError()
|
||||
|
||||
self.loop._sock_recv(f, False, sock, 1024)
|
||||
self.loop._sock_recv(f, None, sock, 1024)
|
||||
self.assertIs(err, f.exception())
|
||||
|
||||
def test_sock_sendall(self):
|
||||
|
@ -231,7 +251,7 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
|
|||
f = self.loop.sock_sendall(sock, b'data')
|
||||
self.assertIsInstance(f, asyncio.Future)
|
||||
self.assertEqual(
|
||||
(f, False, sock, b'data'),
|
||||
(f, None, sock, b'data'),
|
||||
self.loop._sock_sendall.call_args[0])
|
||||
|
||||
def test_sock_sendall_nodata(self):
|
||||
|
@ -244,13 +264,33 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
|
|||
self.assertIsNone(f.result())
|
||||
self.assertFalse(self.loop._sock_sendall.called)
|
||||
|
||||
def test_sock_sendall_reconnection(self):
|
||||
sock = mock.Mock()
|
||||
sock.fileno.return_value = 10
|
||||
sock.send.side_effect = BlockingIOError
|
||||
|
||||
self.loop.add_writer = mock.Mock()
|
||||
self.loop.remove_writer = mock.Mock()
|
||||
fut = self.loop.sock_sendall(sock, b'data')
|
||||
callback = self.loop.add_writer.call_args[0][1]
|
||||
params = self.loop.add_writer.call_args[0][2:]
|
||||
|
||||
# emulate the old socket has closed, but the new one has
|
||||
# the same fileno, so callback is called with old (closed) socket
|
||||
sock.fileno.return_value = -1
|
||||
sock.send.side_effect = OSError(9)
|
||||
callback(*params)
|
||||
|
||||
self.assertIsInstance(fut.exception(), OSError)
|
||||
self.assertEqual((10,), self.loop.remove_writer.call_args[0])
|
||||
|
||||
def test__sock_sendall_canceled_fut(self):
|
||||
sock = mock.Mock()
|
||||
|
||||
f = asyncio.Future(loop=self.loop)
|
||||
f.cancel()
|
||||
|
||||
self.loop._sock_sendall(f, False, sock, b'data')
|
||||
self.loop._sock_sendall(f, None, sock, b'data')
|
||||
self.assertFalse(sock.send.called)
|
||||
|
||||
def test__sock_sendall_unregister(self):
|
||||
|
@ -261,7 +301,7 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
|
|||
f.cancel()
|
||||
|
||||
self.loop.remove_writer = mock.Mock()
|
||||
self.loop._sock_sendall(f, True, sock, b'data')
|
||||
self.loop._sock_sendall(f, 10, sock, b'data')
|
||||
self.assertEqual((10,), self.loop.remove_writer.call_args[0])
|
||||
|
||||
def test__sock_sendall_tryagain(self):
|
||||
|
@ -271,9 +311,9 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
|
|||
sock.send.side_effect = BlockingIOError
|
||||
|
||||
self.loop.add_writer = mock.Mock()
|
||||
self.loop._sock_sendall(f, False, sock, b'data')
|
||||
self.loop._sock_sendall(f, None, sock, b'data')
|
||||
self.assertEqual(
|
||||
(10, self.loop._sock_sendall, f, True, sock, b'data'),
|
||||
(10, self.loop._sock_sendall, f, 10, sock, b'data'),
|
||||
self.loop.add_writer.call_args[0])
|
||||
|
||||
def test__sock_sendall_interrupted(self):
|
||||
|
@ -283,9 +323,9 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
|
|||
sock.send.side_effect = InterruptedError
|
||||
|
||||
self.loop.add_writer = mock.Mock()
|
||||
self.loop._sock_sendall(f, False, sock, b'data')
|
||||
self.loop._sock_sendall(f, None, sock, b'data')
|
||||
self.assertEqual(
|
||||
(10, self.loop._sock_sendall, f, True, sock, b'data'),
|
||||
(10, self.loop._sock_sendall, f, 10, sock, b'data'),
|
||||
self.loop.add_writer.call_args[0])
|
||||
|
||||
def test__sock_sendall_exception(self):
|
||||
|
@ -294,7 +334,7 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
|
|||
sock.fileno.return_value = 10
|
||||
err = sock.send.side_effect = OSError()
|
||||
|
||||
self.loop._sock_sendall(f, False, sock, b'data')
|
||||
self.loop._sock_sendall(f, None, sock, b'data')
|
||||
self.assertIs(f.exception(), err)
|
||||
|
||||
def test__sock_sendall(self):
|
||||
|
@ -304,7 +344,7 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
|
|||
sock.fileno.return_value = 10
|
||||
sock.send.return_value = 4
|
||||
|
||||
self.loop._sock_sendall(f, False, sock, b'data')
|
||||
self.loop._sock_sendall(f, None, sock, b'data')
|
||||
self.assertTrue(f.done())
|
||||
self.assertIsNone(f.result())
|
||||
|
||||
|
@ -316,10 +356,10 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
|
|||
sock.send.return_value = 2
|
||||
|
||||
self.loop.add_writer = mock.Mock()
|
||||
self.loop._sock_sendall(f, False, sock, b'data')
|
||||
self.loop._sock_sendall(f, None, sock, b'data')
|
||||
self.assertFalse(f.done())
|
||||
self.assertEqual(
|
||||
(10, self.loop._sock_sendall, f, True, sock, b'ta'),
|
||||
(10, self.loop._sock_sendall, f, 10, sock, b'ta'),
|
||||
self.loop.add_writer.call_args[0])
|
||||
|
||||
def test__sock_sendall_none(self):
|
||||
|
@ -330,10 +370,10 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
|
|||
sock.send.return_value = 0
|
||||
|
||||
self.loop.add_writer = mock.Mock()
|
||||
self.loop._sock_sendall(f, False, sock, b'data')
|
||||
self.loop._sock_sendall(f, None, sock, b'data')
|
||||
self.assertFalse(f.done())
|
||||
self.assertEqual(
|
||||
(10, self.loop._sock_sendall, f, True, sock, b'data'),
|
||||
(10, self.loop._sock_sendall, f, 10, sock, b'data'),
|
||||
self.loop.add_writer.call_args[0])
|
||||
|
||||
def test_sock_connect_timeout(self):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue