Skip to content

Commit 184ce14

Browse files
authored
[3.11] gh-110088, gh-109878: Fix test_asyncio timeouts (#110092) (#110099)
gh-110088, gh-109878: Fix test_asyncio timeouts (#110092) Fix test_asyncio timeouts: don't measure the maximum duration, a test should not measure a CI performance. Only measure the minimum duration when a task has a timeout or delay. Add CLOCK_RES to test_asyncio.utils. (cherry picked from commit db0a258)
1 parent d81bcc2 commit 184ce14

File tree

7 files changed

+19
-54
lines changed

7 files changed

+19
-54
lines changed

Lib/test/test_asyncio/test_base_events.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ def cb():
273273
self.loop.stop()
274274

275275
self.loop._process_events = mock.Mock()
276-
delay = 0.1
276+
delay = 0.100
277277

278278
when = self.loop.time() + delay
279279
self.loop.call_at(when, cb)
@@ -282,10 +282,7 @@ def cb():
282282
dt = self.loop.time() - t0
283283

284284
# 50 ms: maximum granularity of the event loop
285-
self.assertGreaterEqual(dt, delay - 0.050, dt)
286-
# tolerate a difference of +800 ms because some Python buildbots
287-
# are really slow
288-
self.assertLessEqual(dt, 0.9, dt)
285+
self.assertGreaterEqual(dt, delay - test_utils.CLOCK_RES)
289286
with self.assertRaises(TypeError, msg="when cannot be None"):
290287
self.loop.call_at(None, cb)
291288

Lib/test/test_asyncio/test_events.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -294,10 +294,11 @@ async def coro2():
294294
# 15.6 msec, we use fairly long sleep times here (~100 msec).
295295

296296
def test_run_until_complete(self):
297+
delay = 0.100
297298
t0 = self.loop.time()
298-
self.loop.run_until_complete(asyncio.sleep(0.1))
299-
t1 = self.loop.time()
300-
self.assertTrue(0.08 <= t1-t0 <= 0.8, t1-t0)
299+
self.loop.run_until_complete(asyncio.sleep(delay))
300+
dt = self.loop.time() - t0
301+
self.assertGreaterEqual(dt, delay - test_utils.CLOCK_RES)
301302

302303
def test_run_until_complete_stopped(self):
303304

@@ -1695,7 +1696,6 @@ def _run_once():
16951696
self.loop._run_once = _run_once
16961697

16971698
async def wait():
1698-
loop = self.loop
16991699
await asyncio.sleep(1e-2)
17001700
await asyncio.sleep(1e-4)
17011701
await asyncio.sleep(1e-6)

Lib/test/test_asyncio/test_timeouts.py

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ async def test_nested_timeouts(self):
4747
self.assertTrue(cm2.expired())
4848

4949
async def test_waiter_cancelled(self):
50-
loop = asyncio.get_running_loop()
5150
cancelled = False
5251
with self.assertRaises(TimeoutError):
5352
async with asyncio.timeout(0.01):
@@ -60,39 +59,26 @@ async def test_waiter_cancelled(self):
6059

6160
async def test_timeout_not_called(self):
6261
loop = asyncio.get_running_loop()
63-
t0 = loop.time()
6462
async with asyncio.timeout(10) as cm:
6563
await asyncio.sleep(0.01)
6664
t1 = loop.time()
6765

6866
self.assertFalse(cm.expired())
69-
# 2 sec for slow CI boxes
70-
self.assertLess(t1-t0, 2)
7167
self.assertGreater(cm.when(), t1)
7268

7369
async def test_timeout_disabled(self):
74-
loop = asyncio.get_running_loop()
75-
t0 = loop.time()
7670
async with asyncio.timeout(None) as cm:
7771
await asyncio.sleep(0.01)
78-
t1 = loop.time()
7972

8073
self.assertFalse(cm.expired())
8174
self.assertIsNone(cm.when())
82-
# 2 sec for slow CI boxes
83-
self.assertLess(t1-t0, 2)
8475

8576
async def test_timeout_at_disabled(self):
86-
loop = asyncio.get_running_loop()
87-
t0 = loop.time()
8877
async with asyncio.timeout_at(None) as cm:
8978
await asyncio.sleep(0.01)
90-
t1 = loop.time()
9179

9280
self.assertFalse(cm.expired())
9381
self.assertIsNone(cm.when())
94-
# 2 sec for slow CI boxes
95-
self.assertLess(t1-t0, 2)
9682

9783
async def test_timeout_zero(self):
9884
loop = asyncio.get_running_loop()
@@ -102,8 +88,6 @@ async def test_timeout_zero(self):
10288
await asyncio.sleep(10)
10389
t1 = loop.time()
10490
self.assertTrue(cm.expired())
105-
# 2 sec for slow CI boxes
106-
self.assertLess(t1-t0, 2)
10791
self.assertTrue(t0 <= cm.when() <= t1)
10892

10993
async def test_timeout_zero_sleep_zero(self):
@@ -114,8 +98,6 @@ async def test_timeout_zero_sleep_zero(self):
11498
await asyncio.sleep(0)
11599
t1 = loop.time()
116100
self.assertTrue(cm.expired())
117-
# 2 sec for slow CI boxes
118-
self.assertLess(t1-t0, 2)
119101
self.assertTrue(t0 <= cm.when() <= t1)
120102

121103
async def test_timeout_in_the_past_sleep_zero(self):
@@ -126,8 +108,6 @@ async def test_timeout_in_the_past_sleep_zero(self):
126108
await asyncio.sleep(0)
127109
t1 = loop.time()
128110
self.assertTrue(cm.expired())
129-
# 2 sec for slow CI boxes
130-
self.assertLess(t1-t0, 2)
131111
self.assertTrue(t0 >= cm.when() <= t1)
132112

133113
async def test_foreign_exception_passed(self):

Lib/test/test_asyncio/test_waitfor.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,30 +66,22 @@ async def test_wait_for_timeout_less_then_0_or_0_future_done(self):
6666
fut = loop.create_future()
6767
fut.set_result('done')
6868

69-
t0 = loop.time()
7069
ret = await asyncio.wait_for(fut, 0)
71-
t1 = loop.time()
7270

7371
self.assertEqual(ret, 'done')
7472
self.assertTrue(fut.done())
75-
self.assertLess(t1 - t0, 0.1)
7673

7774
async def test_wait_for_timeout_less_then_0_or_0_coroutine_do_not_started(self):
78-
loop = asyncio.get_running_loop()
79-
8075
foo_started = False
8176

8277
async def foo():
8378
nonlocal foo_started
8479
foo_started = True
8580

8681
with self.assertRaises(asyncio.TimeoutError):
87-
t0 = loop.time()
8882
await asyncio.wait_for(foo(), 0)
89-
t1 = loop.time()
9083

9184
self.assertEqual(foo_started, False)
92-
self.assertLess(t1 - t0, 0.1)
9385

9486
async def test_wait_for_timeout_less_then_0_or_0(self):
9587
loop = asyncio.get_running_loop()
@@ -113,18 +105,14 @@ async def foo():
113105
await started
114106

115107
with self.assertRaises(asyncio.TimeoutError):
116-
t0 = loop.time()
117108
await asyncio.wait_for(fut, timeout)
118-
t1 = loop.time()
119109

120110
self.assertTrue(fut.done())
121111
# it should have been cancelled due to the timeout
122112
self.assertTrue(fut.cancelled())
123113
self.assertEqual(foo_running, False)
124-
self.assertLess(t1 - t0, 0.1)
125114

126115
async def test_wait_for(self):
127-
loop = asyncio.get_running_loop()
128116
foo_running = None
129117

130118
async def foo():
@@ -139,13 +127,10 @@ async def foo():
139127
fut = asyncio.create_task(foo())
140128

141129
with self.assertRaises(asyncio.TimeoutError):
142-
t0 = loop.time()
143130
await asyncio.wait_for(fut, 0.1)
144-
t1 = loop.time()
145131
self.assertTrue(fut.done())
146132
# it should have been cancelled due to the timeout
147133
self.assertTrue(fut.cancelled())
148-
self.assertLess(t1 - t0, support.SHORT_TIMEOUT)
149134
self.assertEqual(foo_running, False)
150135

151136
async def test_wait_for_blocking(self):

Lib/test/test_asyncio/test_windows_events.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,29 +163,25 @@ def test_wait_for_handle(self):
163163

164164
# Wait for unset event with 0.5s timeout;
165165
# result should be False at timeout
166-
fut = self.loop._proactor.wait_for_handle(event, 0.5)
166+
timeout = 0.5
167+
fut = self.loop._proactor.wait_for_handle(event, timeout)
167168
start = self.loop.time()
168169
done = self.loop.run_until_complete(fut)
169170
elapsed = self.loop.time() - start
170171

171172
self.assertEqual(done, False)
172173
self.assertFalse(fut.result())
173-
# bpo-31008: Tolerate only 450 ms (at least 500 ms expected),
174-
# because of bad clock resolution on Windows
175-
self.assertTrue(0.45 <= elapsed <= 0.9, elapsed)
174+
self.assertGreaterEqual(elapsed, timeout - test_utils.CLOCK_RES)
176175

177176
_overlapped.SetEvent(event)
178177

179178
# Wait for set event;
180179
# result should be True immediately
181180
fut = self.loop._proactor.wait_for_handle(event, 10)
182-
start = self.loop.time()
183181
done = self.loop.run_until_complete(fut)
184-
elapsed = self.loop.time() - start
185182

186183
self.assertEqual(done, True)
187184
self.assertTrue(fut.result())
188-
self.assertTrue(0 <= elapsed < 0.3, elapsed)
189185

190186
# asyncio issue #195: cancelling a done _WaitHandleFuture
191187
# must not crash
@@ -199,11 +195,8 @@ def test_wait_for_handle_cancel(self):
199195
# CancelledError should be raised immediately
200196
fut = self.loop._proactor.wait_for_handle(event, 10)
201197
fut.cancel()
202-
start = self.loop.time()
203198
with self.assertRaises(asyncio.CancelledError):
204199
self.loop.run_until_complete(fut)
205-
elapsed = self.loop.time() - start
206-
self.assertTrue(0 <= elapsed < 0.1, elapsed)
207200

208201
# asyncio issue #195: cancelling a _WaitHandleFuture twice
209202
# must not crash

Lib/test/test_asyncio/utils.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@
3737
from test.support import threading_helper
3838

3939

40+
# Use the maximum known clock resolution (gh-75191, gh-110088): Windows
41+
# GetTickCount64() has a resolution of 15.6 ms. Use 20 ms to tolerate rounding
42+
# issues.
43+
CLOCK_RES = 0.020
44+
45+
4046
def data_file(filename):
4147
if hasattr(support, 'TEST_HOME_DIR'):
4248
fullname = os.path.join(support.TEST_HOME_DIR, filename)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fix test_asyncio timeouts: don't measure the maximum duration, a test should
2+
not measure a CI performance. Only measure the minimum duration when a task has
3+
a timeout or delay. Add ``CLOCK_RES`` to ``test_asyncio.utils``. Patch by
4+
Victor Stinner.

0 commit comments

Comments
 (0)