diff -r 85b87789f048 Lib/test/regrtest.py --- a/Lib/test/regrtest.py Mon Mar 17 23:16:02 2014 +0100 +++ b/Lib/test/regrtest.py Tue Mar 18 00:14:42 2014 +0100 @@ -322,6 +322,9 @@ def _create_parser(): group.add_argument('-F', '--forever', action='store_true', help='run the specified tests in a loop, until an ' 'error happens') + group.add_argument('--check-time-delta', type=float, + help='delay in seconds tolerated to check max_dt in ' + 'check_time_delta() (default: 500 ms)') parser.add_argument('args', nargs=argparse.REMAINDER, help=argparse.SUPPRESS) @@ -420,6 +423,10 @@ def _parse_args(args, **kwargs): ns.use_resources.append(r) if ns.random_seed is not None: ns.randomize = True + if ns.check_time_delta is not None: + if ns.check_time_delta < 1e-9: + parser.error("--check-time-delta must be >= 1e-9") + support.check_time_delta.max_dt_delta = ns.check_time_delta * 2 return ns diff -r 85b87789f048 Lib/test/support/__init__.py --- a/Lib/test/support/__init__.py Mon Mar 17 23:16:02 2014 +0100 +++ b/Lib/test/support/__init__.py Tue Mar 18 00:14:42 2014 +0100 @@ -2174,3 +2174,60 @@ def run_in_subinterp(code): "memory allocations") import _testcapi return _testcapi.run_in_subinterp(code) + +def _format_time_delta(dt): + abs_dt = abs(dt) + if abs_dt < 1e-9: + # abs(dt) < 1e-9 + return '%.1f ns' % (dt * 1e9) + if abs_dt < 1e-6: + # 1e-9 < abs(dt) < 1e-6 + return '%.1f ns' % (dt * 1e9) + if abs_dt < 1e-3: + # 1e-6 < abs(dt) < 1e-3 + return '%.1f us' % (dt * 1e6) + if abs_dt < 1.0: + # 1e-3 < abs(dt) < 1.0 + return '%.1f ms' % (dt * 1e3) + # 1.0 < abs(dt) + return '%.0f sec' % dt + +def check_time_delta(min_dt, dt, max_dt, *, clock='time', resolution=None): + if max_dt < min_dt: + raise ValueError("check_time_delta requires max_dt >= min_dt") + + if min_dt <= dt <= max_dt: + return + + if resolution is not None: + message = ("use a resolution of %s" + % (clock, _format_time_delta(resolution))) + else: + clock_info = time.get_clock_info(clock) + resolution = clock_info.resolution + message = ("the clock %r has a resolution of %s" + % (clock, _format_time_delta(resolution))) + + message = ("%s; tolerate a delta of %s seconds" + % (message, + _format_time_delta(check_time_delta.max_dt_delta))) + + min_dt2 = min_dt - resolution + max_dt2 = max_dt + resolution + check_time_delta.max_dt_delta + if min_dt2 <= dt <= max_dt2: + return + + if dt <= max_dt2: + # dt < min_dt <= max_dt + raise AssertionError("timing %s seconds < min timing %s seconds; %s" + % (_format_time_delta(dt), + _format_time_delta(min_dt), + message)) + else: + # min_dt <= max_dt < dt + raise AssertionError("timing %s seconds > max timing %s seconds; %s" + % (_format_time_delta(dt), + _format_time_delta(max_dt), + message)) + +check_time_delta.max_dt_delta = 0.500 # seconds diff -r 85b87789f048 Lib/test/test_asyncio/test_base_events.py --- a/Lib/test/test_asyncio/test_base_events.py Mon Mar 17 23:16:02 2014 +0100 +++ b/Lib/test/test_asyncio/test_base_events.py Tue Mar 18 00:14:42 2014 +0100 @@ -7,7 +7,7 @@ import sys import time import unittest from unittest import mock -from test.support import IPV6_ENABLED +from test.support import IPV6_ENABLED, check_time_delta import asyncio from asyncio import base_events @@ -130,11 +130,7 @@ class BaseEventLoopTests(unittest.TestCa self.loop.run_forever() dt = self.loop.time() - t0 - # 50 ms: maximum granularity of the event loop - self.assertGreaterEqual(dt, delay - 0.050, dt) - # tolerate a difference of +800 ms because some Python buildbots - # are really slow - self.assertLessEqual(dt, 0.9, dt) + check_time_delta(delay, dt, delay + 0.1, clock='monotonic') def test_run_once_in_executor_handle(self): def cb(): diff -r 85b87789f048 Lib/test/test_time.py --- a/Lib/test/test_time.py Mon Mar 17 23:16:02 2014 +0100 +++ b/Lib/test/test_time.py Tue Mar 18 00:14:42 2014 +0100 @@ -394,7 +394,7 @@ class TimeTestCase(unittest.TestCase): dt = t2 - t1 self.assertGreater(t2, t1) # Issue #20101: On some Windows machines, dt may be slightly low - self.assertTrue(0.45 <= dt <= 1.0, dt) + support.check_time_delta(0.5, dt, 0.501, clock='monotonic') # monotonic() is a monotonic but non adjustable clock info = time.get_clock_info('monotonic') @@ -406,12 +406,10 @@ class TimeTestCase(unittest.TestCase): def test_process_time(self): # process_time() should not include time spend during a sleep - start = time.process_time() + t0 = time.process_time() time.sleep(0.100) - stop = time.process_time() - # use 20 ms because process_time() has usually a resolution of 15 ms - # on Windows - self.assertLess(stop - start, 0.020) + dt = time.process_time() - t0 + support.check_time_delta(0.0, dt, 0.010, clock='process_time') info = time.get_clock_info('process_time') self.assertTrue(info.monotonic)