[Python-checkins] bpo-30064: Fix slow asyncio sock test (GH-20868)

Fantix King webhook-mailer at python.org
Sun Jun 14 03:44:11 EDT 2020


https://github.com/python/cpython/commit/8f04a84755babe516ebb5304904ea7c15b865c80
commit: 8f04a84755babe516ebb5304904ea7c15b865c80
branch: master
author: Fantix King <fantix.king at gmail.com>
committer: GitHub <noreply at github.com>
date: 2020-06-14T00:43:57-07:00
summary:

bpo-30064: Fix slow asyncio sock test (GH-20868)



Using a log2n way to fill a much smaller buffer, and receiving in a cleaner way with EOF.

The failing test was reproducible using the following command thanks to @aeros :

```bash
./python -m test test_asyncio.test_sock_lowlevel --match test_sock_client_racing -j100 -F -v
```

According to test results, we may still need to bump the timeout:

https://github.com/python/cpython/blob/5aad027db9618f22f6fa2274e05dd50f928d2ed7/Lib/test/test_asyncio/test_sock_lowlevel.py#L256-L257

files:
M Lib/test/test_asyncio/test_sock_lowlevel.py

diff --git a/Lib/test/test_asyncio/test_sock_lowlevel.py b/Lib/test/test_asyncio/test_sock_lowlevel.py
index 2c8ce6b657c14..e339ee9a4fc49 100644
--- a/Lib/test/test_asyncio/test_sock_lowlevel.py
+++ b/Lib/test/test_asyncio/test_sock_lowlevel.py
@@ -166,6 +166,7 @@ async def _basetest_sock_send_racing(self, listener, sock):
         listener.listen(1)
 
         # make connection
+        sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 1024)
         sock.setblocking(False)
         task = asyncio.create_task(
             self.loop.sock_connect(sock, listener.getsockname()))
@@ -176,10 +177,13 @@ async def _basetest_sock_send_racing(self, listener, sock):
         with server:
             await task
 
-            # fill the buffer
-            with self.assertRaises(BlockingIOError):
-                while True:
-                    sock.send(b' ' * 5)
+            # fill the buffer until sending 5 chars would block
+            size = 8192
+            while size >= 4:
+                with self.assertRaises(BlockingIOError):
+                    while True:
+                        sock.send(b' ' * size)
+                size = int(size / 2)
 
             # cancel a blocked sock_sendall
             task = asyncio.create_task(
@@ -187,19 +191,21 @@ async def _basetest_sock_send_racing(self, listener, sock):
             await asyncio.sleep(0)
             task.cancel()
 
-            # clear the buffer
-            async def recv_until():
-                data = b''
-                while not data:
-                    data = await self.loop.sock_recv(server, 1024)
-                    data = data.strip()
-                return data
-            task = asyncio.create_task(recv_until())
+            # receive everything that is not a space
+            async def recv_all():
+                rv = b''
+                while True:
+                    buf = await self.loop.sock_recv(server, 8192)
+                    if not buf:
+                        return rv
+                    rv += buf.strip()
+            task = asyncio.create_task(recv_all())
 
-            # immediately register another sock_sendall
+            # immediately make another sock_sendall call
             await self.loop.sock_sendall(sock, b'world')
+            sock.shutdown(socket.SHUT_WR)
             data = await task
-            # ProactorEventLoop could deliver hello
+            # ProactorEventLoop could deliver hello, so endswith is necessary
             self.assertTrue(data.endswith(b'world'))
 
     # After the first connect attempt before the listener is ready,



More information about the Python-checkins mailing list