Skip to content

Commit eb8739e

Browse files
committed
more robust selector thread test
for thread asynciness
1 parent 502bfaf commit eb8739e

File tree

2 files changed

+23
-6
lines changed

2 files changed

+23
-6
lines changed

Lib/test/test_asyncio/test_selector_thread.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,30 @@ async def asyncTearDown(self):
2424

2525
async def test_slow_reader(self):
2626
a, b = self.socketpair()
27+
first_recv = asyncio.Future()
28+
2729
def recv():
28-
b.recv(100)
30+
msg = b.recv(100)
31+
if not first_recv.done():
32+
first_recv.set_result(msg)
33+
2934
mock_recv = mock.MagicMock(wraps=recv)
3035
# make sure select is only called once when
3136
# event loop thread is slow to consume events
3237
a.sendall(b"msg")
3338
with mock.patch("select.select", wraps=select.select) as mock_select:
3439
self.selector_thread.add_reader(b, mock_recv)
40+
# ready event, but main event loop is blocked for some time
3541
time.sleep(0.1)
36-
self.assertEqual(mock_select.call_count, 1)
37-
await asyncio.sleep(0.1)
42+
recvd = await asyncio.wait_for(first_recv, timeout=10)
43+
self.assertEqual(recvd, b"msg")
44+
# make sure recv wasn't scheduled more than once
3845
self.assertEqual(mock_recv.call_count, 1)
46+
# 1 for add_reader
47+
# 1 for finishing reader callback
48+
# up to 2 more for wake FD calls if CI is slow
49+
# this would be thousands if select is busy-looping while the main thread blocks
50+
self.assertLessEqual(mock_select.call_count, 5)
3951

4052
async def test_reader_error(self):
4153
# test error handling in callbacks doesn't break handling
@@ -44,10 +56,12 @@ async def test_reader_error(self):
4456

4557
selector_thread = self.selector_thread
4658

47-
# make sure it's called a few
59+
# make sure it's called a few times,
60+
# and errors don't prevent rescheduling
4861
n_failures = 5
4962
counter = 0
5063
bad_recv_done = asyncio.Future()
64+
5165
def bad_recv(sock):
5266
# fail the first n_failures calls, then succeed
5367
nonlocal counter
@@ -67,7 +81,9 @@ def bad_recv(sock):
6781

6882
# make sure start_select is called
6983
# even when recv callback errors,
70-
with mock.patch.object(selector_thread, "_start_select", wraps=selector_thread._start_select) as start_select:
84+
with mock.patch.object(
85+
selector_thread, "_start_select", wraps=selector_thread._start_select
86+
) as start_select:
7187
await asyncio.wait_for(bad_recv_done, timeout=10)
7288

7389
# make sure recv is called N + 1 times,

Lib/test/test_asyncio/test_windows_events.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ def threadMain():
325325

326326
def test_add_reader_invalid_argument(self):
327327
def assert_raises():
328-
return self.assertRaisesRegex(ValueError, r'Invalid file object')
328+
return self.assertRaisesRegex(ValueError, r"Invalid file object")
329329

330330
def cb(sock):
331331
return None
@@ -343,6 +343,7 @@ def cb(sock):
343343
def test_selector_thread(self):
344344
assert self.loop._selector_thread is None
345345
a, b = socket.socketpair()
346+
346347
async def _test():
347348
read_future = asyncio.Future()
348349
sent = b"asdf"

0 commit comments

Comments
 (0)