@@ -664,84 +664,78 @@ def test_denial_of_service_prevented_int_to_str(self):
664
664
"""Regression test: ensure we fail before performing O(N**2) work."""
665
665
maxdigits = sys .get_int_max_str_digits ()
666
666
assert maxdigits < 50_000 , maxdigits # A test prerequisite.
667
- get_time = time .process_time
668
- if get_time () <= 0 : # some platforms like WASM lack process_time()
669
- get_time = time .monotonic
670
667
671
668
huge_int = int (f'0x{ "c" * 65_000 } ' , base = 16 ) # 78268 decimal digits.
672
669
digits = 78_268
673
- with support .adjust_int_max_str_digits (digits ):
674
- start = get_time ()
670
+ with (
671
+ support .adjust_int_max_str_digits (digits ),
672
+ support .CPUStopwatch () as sw_convert ):
675
673
huge_decimal = str (huge_int )
676
- seconds_to_convert = get_time () - start
677
674
self .assertEqual (len (huge_decimal ), digits )
678
675
# Ensuring that we chose a slow enough conversion to measure.
679
676
# It takes 0.1 seconds on a Zen based cloud VM in an opt build.
680
677
# Some OSes have a low res 1/64s timer, skip if hard to measure.
681
- if seconds_to_convert < 1 / 64 :
678
+ if sw_convert . seconds < sw_convert . clock_info . resolution * 2 :
682
679
raise unittest .SkipTest ('"slow" conversion took only '
683
- f'{ seconds_to_convert } seconds.' )
680
+ f'{ sw_convert . seconds } seconds.' )
684
681
685
682
# We test with the limit almost at the size needed to check performance.
686
683
# The performant limit check is slightly fuzzy, give it a some room.
687
684
with support .adjust_int_max_str_digits (int (.995 * digits )):
688
- with self .assertRaises (ValueError ) as err :
689
- start = get_time ()
685
+ with (
686
+ self .assertRaises (ValueError ) as err ,
687
+ support .CPUStopwatch () as sw_fail_huge ):
690
688
str (huge_int )
691
- seconds_to_fail_huge = get_time () - start
692
689
self .assertIn ('conversion' , str (err .exception ))
693
- self .assertLessEqual (seconds_to_fail_huge , seconds_to_convert / 2 )
690
+ self .assertLessEqual (sw_fail_huge . seconds , sw_convert . seconds / 2 )
694
691
695
692
# Now we test that a conversion that would take 30x as long also fails
696
693
# in a similarly fast fashion.
697
694
extra_huge_int = int (f'0x{ "c" * 500_000 } ' , base = 16 ) # 602060 digits.
698
- with self .assertRaises (ValueError ) as err :
699
- start = get_time ()
695
+ with (
696
+ self .assertRaises (ValueError ) as err ,
697
+ support .CPUStopwatch () as sw_fail_extra_huge ):
700
698
# If not limited, 8 seconds said Zen based cloud VM.
701
699
str (extra_huge_int )
702
- seconds_to_fail_extra_huge = get_time () - start
703
700
self .assertIn ('conversion' , str (err .exception ))
704
- self .assertLess (seconds_to_fail_extra_huge , seconds_to_convert / 2 )
701
+ self .assertLess (sw_fail_extra_huge . seconds , sw_convert . seconds / 2 )
705
702
706
703
def test_denial_of_service_prevented_str_to_int (self ):
707
704
"""Regression test: ensure we fail before performing O(N**2) work."""
708
705
maxdigits = sys .get_int_max_str_digits ()
709
706
assert maxdigits < 100_000 , maxdigits # A test prerequisite.
710
- get_time = time .process_time
711
- if get_time () <= 0 : # some platforms like WASM lack process_time()
712
- get_time = time .monotonic
713
707
714
708
digits = 133700
715
709
huge = '8' * digits
716
- with support .adjust_int_max_str_digits (digits ):
717
- start = get_time ()
710
+ with (
711
+ support .adjust_int_max_str_digits (digits ),
712
+ support .CPUStopwatch () as sw_convert ):
718
713
int (huge )
719
- seconds_to_convert = get_time () - start
720
714
# Ensuring that we chose a slow enough conversion to measure.
721
715
# It takes 0.1 seconds on a Zen based cloud VM in an opt build.
722
716
# Some OSes have a low res 1/64s timer, skip if hard to measure.
723
- if seconds_to_convert < 1 / 64 :
717
+ if sw_convert . seconds < sw_convert . clock_info . resolution * 2 :
724
718
raise unittest .SkipTest ('"slow" conversion took only '
725
- f'{ seconds_to_convert } seconds.' )
719
+ f'{ sw_convert . seconds } seconds.' )
726
720
727
721
with support .adjust_int_max_str_digits (digits - 1 ):
728
- with self .assertRaises (ValueError ) as err :
729
- start = get_time ()
722
+ with (
723
+ self .assertRaises (ValueError ) as err ,
724
+ support .CPUStopwatch () as sw_fail_huge ):
730
725
int (huge )
731
- seconds_to_fail_huge = get_time () - start
732
726
self .assertIn ('conversion' , str (err .exception ))
733
- self .assertLessEqual (seconds_to_fail_huge , seconds_to_convert / 2 )
727
+ self .assertLessEqual (sw_fail_huge . seconds , sw_convert . seconds / 2 )
734
728
735
729
# Now we test that a conversion that would take 30x as long also fails
736
730
# in a similarly fast fashion.
737
731
extra_huge = '7' * 1_200_000
738
- with self .assertRaises (ValueError ) as err :
739
- start = get_time ()
732
+ with (
733
+ self .assertRaises (ValueError ) as err ,
734
+ support .CPUStopwatch () as sw_fail_extra_huge ):
740
735
# If not limited, 8 seconds in the Zen based cloud VM.
741
736
int (extra_huge )
742
- seconds_to_fail_extra_huge = get_time () - start
743
737
self .assertIn ('conversion' , str (err .exception ))
744
- self .assertLessEqual (seconds_to_fail_extra_huge , seconds_to_convert / 2 )
738
+ self .assertLessEqual (sw_fail_extra_huge . seconds , sw_convert . seconds / 2 )
745
739
746
740
def test_power_of_two_bases_unlimited (self ):
747
741
"""The limit does not apply to power of 2 bases."""
0 commit comments