77    raise  SystemExit 
88
99
10+ def  test_monotonic_advance (func_name , min_advance_s , sleep_ms ):
11+     """Test that a time function advances by at least min_advance_s seconds.""" 
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 
28+         return  t2  !=  t1 
29+     # For numeric return values (time, ticks_*) 
30+     else :
31+         # Should have advanced by at least min_advance_s 
32+         # Use appropriate diff function for ticks 
33+         if  func_name .startswith ("ticks_" ):
34+             diff  =  time .ticks_diff (t2 , t1 )
35+             if  func_name  ==  "ticks_ms" :
36+                 # Expect at least 80% of sleep time (accounting for overhead) 
37+                 return  diff  >=  sleep_ms  *  0.8 
38+             elif  func_name  ==  "ticks_us" :
39+                 # Expect at least 80% of sleep time in microseconds 
40+                 return  diff  >=  sleep_ms  *  1000  *  0.8 
41+             elif  func_name  ==  "ticks_ns" :
42+                 # Expect at least 80% of sleep time in nanoseconds 
43+                 return  diff  >=  sleep_ms  *  1000000  *  0.8 
44+             elif  func_name  ==  "ticks_cpu" :
45+                 # ticks_cpu may return 0 on some ports, just check it advanced 
46+                 return  diff  >  0  or  t2  ==  0 
47+         else :
48+             # For time() and other float/int returns 
49+             return  t2  >=  t1  +  min_advance_s 
50+ 
51+ 
1052def  gmtime_time ():
1153    return  time .gmtime (time .time ())
1254
@@ -16,53 +58,27 @@ def localtime_time():
1658
1759
1860def  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 ),
61+     # Test configuration: (function name, minimum advance in seconds, sleep time in ms) 
62+     TEST_CONFIG  =  (
63+         ("time" , 1 , 1200 ),
64+         ("gmtime" , 0 , 1200 ),  # gmtime returns tuple, just check it changes 
65+         ("localtime" , 0 , 1200 ),
66+         ("gmtime_time" , 0 , 1200 ),
67+         ("localtime_time" , 0 , 1200 ),
68+         ("ticks_ms" , 0 , 150 ),  # Test millisecond resolution 
69+         ("ticks_us" , 0 , 150 ),  # Test microsecond resolution 
70+         ("ticks_ns" , 0 , 150 ),  # Test nanosecond resolution 
71+         ("ticks_cpu" , 0 , 150 ),
3172    )
3273
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 :
74+     for  func_name , min_advance , sleep_ms  in  TEST_CONFIG :
5475        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) 
76+         result  =  test_monotonic_advance (func_name , min_advance , sleep_ms )
77+         if  result  is  None :
78+             # Function not available, skip silently 
6079            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-             )
80+         elif  not  result :
81+             print ("%s() did not advance as expected"  %  func_name )
6682
6783
6884test ()
0 commit comments