1010import time
1111import unittest
1212from test .libregrtest .cmdline import _parse_args , Namespace
13+ from test .libregrtest .logger import Logger
1314from test .libregrtest .runtest import (
1415 findtests , split_test_packages , run_single_test , abs_module_name ,
1516 PROGRESS_MIN_TIME , State , RunTests , HuntRefleak ,
@@ -54,6 +55,8 @@ class Regrtest:
5455 on the command line.
5556 """
5657 def __init__ (self , ns : Namespace ):
58+ self .logger = Logger ()
59+
5760 # Actions
5861 self .want_header : bool = ns .header
5962 self .want_list_tests : bool = ns .list_tests
@@ -137,29 +140,8 @@ def __init__(self, ns: Namespace):
137140 self .next_single_test : TestName | None = None
138141 self .next_single_filename : StrPath | None = None
139142
140- # misc
141- self .win_load_tracker = None
142-
143143 def log (self , line = '' ):
144- empty = not line
145-
146- # add the system load prefix: "load avg: 1.80 "
147- load_avg = self .getloadavg ()
148- if load_avg is not None :
149- line = f"load avg: { load_avg :.2f} { line } "
150-
151- # add the timestamp prefix: "0:01:05 "
152- test_time = time .perf_counter () - self .start_time
153-
154- mins , secs = divmod (int (test_time ), 60 )
155- hours , mins = divmod (mins , 60 )
156- test_time = "%d:%02d:%02d" % (hours , mins , secs )
157-
158- line = f"{ test_time } { line } "
159- if empty :
160- line = line [:- 1 ]
161-
162- print (line , flush = True )
144+ self .logger .log (line )
163145
164146 def display_progress (self , test_index , text ):
165147 if self .quiet :
@@ -293,7 +275,7 @@ def _rerun_failed_tests(self, runtests: RunTests):
293275 fail_fast = False ,
294276 match_tests_dict = match_tests_dict ,
295277 output_on_failure = False )
296- self .set_tests (runtests )
278+ self .logger . set_tests (runtests )
297279 self ._run_tests_mp (runtests , self .num_workers )
298280 return runtests
299281
@@ -437,44 +419,7 @@ def get_state(self):
437419
438420 def _run_tests_mp (self , runtests : RunTests , num_workers : int ) -> None :
439421 from test .libregrtest .runtest_mp import RunWorkers
440-
441- # If we're on windows and this is the parent runner (not a worker),
442- # track the load average.
443- if sys .platform == 'win32' :
444- from test .libregrtest .win_utils import WindowsLoadTracker
445-
446- try :
447- self .win_load_tracker = WindowsLoadTracker ()
448- except PermissionError as error :
449- # Standard accounts may not have access to the performance
450- # counters.
451- print (f'Failed to create WindowsLoadTracker: { error } ' )
452-
453- try :
454- RunWorkers (self , runtests , num_workers ).run ()
455- finally :
456- if self .win_load_tracker is not None :
457- self .win_load_tracker .close ()
458- self .win_load_tracker = None
459-
460- def set_tests (self , runtests : RunTests ):
461- self .tests = runtests .tests
462- if runtests .forever :
463- self .test_count_text = ''
464- self .test_count_width = 3
465- else :
466- self .test_count_text = '/{}' .format (len (self .tests ))
467- self .test_count_width = len (self .test_count_text ) - 1
468-
469- def run_tests (self , runtests : RunTests ):
470- self .first_runtests = runtests
471- self .set_tests (runtests )
472- if self .num_workers :
473- self ._run_tests_mp (runtests , self .num_workers )
474- tracer = None
475- else :
476- tracer = self .run_tests_sequentially (runtests )
477- return tracer
422+ RunWorkers (self , runtests , num_workers ).run ()
478423
479424 def finalize_tests (self , tracer ):
480425 if self .next_single_filename :
@@ -496,7 +441,7 @@ def finalize_tests(self, tracer):
496441 self .results .write_junit (self .junit_filename )
497442
498443 def display_summary (self ):
499- duration = time .perf_counter () - self .start_time
444+ duration = time .perf_counter () - self .logger . start_time
500445 filtered = bool (self .match_tests ) or bool (self .ignore_tests )
501446
502447 # Total duration
@@ -619,35 +564,8 @@ def main(self, tests: TestList | None = None):
619564
620565 sys .exit (exc .code )
621566
622- def getloadavg (self ):
623- if self .win_load_tracker is not None :
624- return self .win_load_tracker .getloadavg ()
625-
626- if hasattr (os , 'getloadavg' ):
627- return os .getloadavg ()[0 ]
628-
629- return None
630-
631- def action_run_tests (self ):
632- if self .hunt_refleak and self .hunt_refleak .warmups < 3 :
633- msg = ("WARNING: Running tests with --huntrleaks/-R and "
634- "less than 3 warmup repetitions can give false positives!" )
635- print (msg , file = sys .stdout , flush = True )
636-
637- # For a partial run, we do not need to clutter the output.
638- if (self .want_header
639- or not (self .pgo or self .quiet or self .single_test_run
640- or self .tests or self .cmdline_args )):
641- self .display_header ()
642-
643- if self .randomize :
644- print ("Using random seed" , self .random_seed )
645-
646- if self .num_workers < 0 :
647- # Use all cores + extras for tests that like to sleep
648- self .num_workers = 2 + (os .cpu_count () or 1 )
649-
650- runtests = RunTests (
567+ def create_run_tests (self ):
568+ return RunTests (
651569 tuple (self .selected ),
652570 fail_fast = self .fail_fast ,
653571 match_tests = self .match_tests ,
@@ -668,17 +586,53 @@ def action_run_tests(self):
668586 python_cmd = self .python_cmd ,
669587 )
670588
589+ def run_tests (self ) -> int :
590+ if self .hunt_refleak and self .hunt_refleak .warmups < 3 :
591+ msg = ("WARNING: Running tests with --huntrleaks/-R and "
592+ "less than 3 warmup repetitions can give false positives!" )
593+ print (msg , file = sys .stdout , flush = True )
594+
595+ if self .num_workers < 0 :
596+ # Use all CPUs + 2 extra worker processes for tests
597+ # that like to sleep
598+ self .num_workers = (os .cpu_count () or 1 ) + 2
599+
600+ # For a partial run, we do not need to clutter the output.
601+ if (self .want_header
602+ or not (self .pgo or self .quiet or self .single_test_run
603+ or self .tests or self .cmdline_args )):
604+ self .display_header ()
605+
606+ if self .randomize :
607+ print ("Using random seed" , self .random_seed )
608+
609+ runtests = self .create_run_tests ()
610+ self .first_runtests = runtests
611+ self .logger .set_tests (runtests )
612+
671613 setup_tests (runtests )
672614
673- tracer = self .run_tests (runtests )
674- self .display_result (runtests )
615+ self .logger .start_load_tracker ()
616+ try :
617+ if self .num_workers :
618+ self ._run_tests_mp (runtests , self .num_workers )
619+ tracer = None
620+ else :
621+ tracer = self .run_tests_sequentially (runtests )
675622
676- if self .want_rerun and self .results .need_rerun ():
677- self .rerun_failed_tests (runtests )
623+ self .display_result (runtests )
624+
625+ if self .want_rerun and self .results .need_rerun ():
626+ self .rerun_failed_tests (runtests )
627+ finally :
628+ self .logger .stop_load_tracker ()
678629
679630 self .display_summary ()
680631 self .finalize_tests (tracer )
681632
633+ return self .results .get_exitcode (self .fail_env_changed ,
634+ self .fail_rerun )
635+
682636 def _main (self ):
683637 if self .is_worker ():
684638 from test .libregrtest .runtest_mp import worker_process
@@ -697,9 +651,7 @@ def _main(self):
697651 elif self .want_list_cases :
698652 self .list_cases ()
699653 else :
700- self .action_run_tests ()
701- exitcode = self .results .get_exitcode (self .fail_env_changed ,
702- self .fail_rerun )
654+ exitcode = self .run_tests ()
703655
704656 sys .exit (exitcode )
705657
0 commit comments