77 raise SystemExit
88
99
10+ def test_monotonic_advance (func_name , min_advance_s , sleep_ms ):
11+ """Test that a time function advances within expected bounds."""
12+ try :
13+ if func_name .endswith ("_time" ):
14+ # Helper functions defined below
15+ time_func = globals ()[func_name ]
16+ else :
17+ time_func = getattr (time , func_name )
18+ except AttributeError :
19+ return None # Function not available
20+
21+ t1 = time_func ()
22+ time .sleep_ms (sleep_ms )
23+ t2 = time_func ()
24+
25+ # For tuple return values (gmtime, localtime), compare as tuples
26+ if isinstance (t1 , tuple ) and isinstance (t2 , tuple ):
27+ # Should have changed (checking resolution)
28+ return t2 != t1
29+ # For numeric return values (time, ticks_*)
30+ else :
31+ # Use appropriate diff function for ticks
32+ if func_name .startswith ("ticks_" ):
33+ diff = time .ticks_diff (t2 , t1 )
34+ if func_name == "ticks_ms" :
35+ # Expect 80%-200% of sleep time (tolerance for overhead and loaded CI)
36+ expected = sleep_ms
37+ return (expected * 0.8 ) <= diff <= (expected * 2.0 )
38+ elif func_name == "ticks_us" :
39+ # Expect 80%-200% of sleep time in microseconds
40+ expected = sleep_ms * 1000
41+ return (expected * 0.8 ) <= diff <= (expected * 2.0 )
42+ elif func_name == "ticks_ns" :
43+ # Expect 80%-200% of sleep time in nanoseconds
44+ expected = sleep_ms * 1000000
45+ return (expected * 0.8 ) <= diff <= (expected * 2.0 )
46+ elif func_name == "ticks_cpu" :
47+ # ticks_cpu may return 0 on some ports, just check it advanced
48+ return diff > 0 or t2 == 0
49+ else :
50+ # For time() and other float/int returns, check both bounds
51+ # 2x tolerance for overhead and loaded CI systems
52+ min_expected = min_advance_s
53+ max_expected = (sleep_ms / 1000.0 ) * 2.0
54+ actual_diff = t2 - t1
55+ return min_expected <= actual_diff <= max_expected
56+
57+
1058def gmtime_time ():
1159 return time .gmtime (time .time ())
1260
@@ -16,53 +64,27 @@ def localtime_time():
1664
1765
1866def test ():
19- TEST_TIME = 2500
20- EXPECTED_MAP = (
21- # (function name, min. number of results in 2.5 sec)
22- ("time" , 3 ),
23- ("gmtime" , 3 ),
24- ("localtime" , 3 ),
25- ("gmtime_time" , 3 ),
26- ("localtime_time" , 3 ),
27- ("ticks_ms" , 15 ),
28- ("ticks_us" , 15 ),
29- ("ticks_ns" , 15 ),
30- ("ticks_cpu" , 15 ),
67+ # Test configuration: (function name, minimum advance in seconds, sleep time in ms)
68+ TEST_CONFIG = (
69+ ("time" , 1 , 1200 ),
70+ ("gmtime" , 0 , 1200 ), # gmtime returns tuple, just check it changes
71+ ("localtime" , 0 , 1200 ),
72+ ("gmtime_time" , 0 , 1200 ),
73+ ("localtime_time" , 0 , 1200 ),
74+ ("ticks_ms" , 0 , 150 ), # Test millisecond resolution
75+ ("ticks_us" , 0 , 150 ), # Test microsecond resolution
76+ ("ticks_ns" , 0 , 150 ), # Test nanosecond resolution
77+ ("ticks_cpu" , 0 , 150 ),
3178 )
3279
33- # call time functions
34- results_map = {}
35- end_time = time .ticks_ms () + TEST_TIME
36- while time .ticks_diff (end_time , time .ticks_ms ()) > 0 :
37- time .sleep_ms (100 )
38- for func_name , _ in EXPECTED_MAP :
39- try :
40- if func_name .endswith ("_time" ):
41- time_func = globals ()[func_name ]
42- else :
43- time_func = getattr (time , func_name )
44- now = time_func () # may raise AttributeError
45- except AttributeError :
46- continue
47- try :
48- results_map [func_name ].add (now )
49- except KeyError :
50- results_map [func_name ] = {now }
51-
52- # check results
53- for func_name , min_len in EXPECTED_MAP :
80+ for func_name , min_advance , sleep_ms in TEST_CONFIG :
5481 print ("Testing %s" % func_name )
55- results = results_map .get (func_name )
56- if results is None :
57- pass
58- elif func_name == "ticks_cpu" and results == {0 }:
59- # ticks_cpu() returns 0 on some ports (e.g. unix)
82+ result = test_monotonic_advance (func_name , min_advance , sleep_ms )
83+ if result is None :
84+ # Function not available, skip silently
6085 pass
61- elif len (results ) < min_len :
62- print (
63- "%s() returns %s result%s in %s ms, expecting >= %s"
64- % (func_name , len (results ), "s" [: len (results ) != 1 ], TEST_TIME , min_len )
65- )
86+ elif not result :
87+ print ("%s() did not advance as expected" % func_name )
6688
6789
6890test ()
0 commit comments