Skip to content

Commit 8f04a84

Browse files
authored
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
1 parent 5aad027 commit 8f04a84

File tree

1 file changed

+20
-14
lines changed

1 file changed

+20
-14
lines changed

Lib/test/test_asyncio/test_sock_lowlevel.py

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ async def _basetest_sock_send_racing(self, listener, sock):
166166
listener.listen(1)
167167

168168
# make connection
169+
sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 1024)
169170
sock.setblocking(False)
170171
task = asyncio.create_task(
171172
self.loop.sock_connect(sock, listener.getsockname()))
@@ -176,30 +177,35 @@ async def _basetest_sock_send_racing(self, listener, sock):
176177
with server:
177178
await task
178179

179-
# fill the buffer
180-
with self.assertRaises(BlockingIOError):
181-
while True:
182-
sock.send(b' ' * 5)
180+
# fill the buffer until sending 5 chars would block
181+
size = 8192
182+
while size >= 4:
183+
with self.assertRaises(BlockingIOError):
184+
while True:
185+
sock.send(b' ' * size)
186+
size = int(size / 2)
183187

184188
# cancel a blocked sock_sendall
185189
task = asyncio.create_task(
186190
self.loop.sock_sendall(sock, b'hello'))
187191
await asyncio.sleep(0)
188192
task.cancel()
189193

190-
# clear the buffer
191-
async def recv_until():
192-
data = b''
193-
while not data:
194-
data = await self.loop.sock_recv(server, 1024)
195-
data = data.strip()
196-
return data
197-
task = asyncio.create_task(recv_until())
194+
# receive everything that is not a space
195+
async def recv_all():
196+
rv = b''
197+
while True:
198+
buf = await self.loop.sock_recv(server, 8192)
199+
if not buf:
200+
return rv
201+
rv += buf.strip()
202+
task = asyncio.create_task(recv_all())
198203

199-
# immediately register another sock_sendall
204+
# immediately make another sock_sendall call
200205
await self.loop.sock_sendall(sock, b'world')
206+
sock.shutdown(socket.SHUT_WR)
201207
data = await task
202-
# ProactorEventLoop could deliver hello
208+
# ProactorEventLoop could deliver hello, so endswith is necessary
203209
self.assertTrue(data.endswith(b'world'))
204210

205211
# After the first connect attempt before the listener is ready,

0 commit comments

Comments
 (0)