1212from test .libregrtest .cmdline import _parse_args , Namespace
1313from test .libregrtest .runtest import (
1414 findtests , split_test_packages , runtest , abs_module_name ,
15- PROGRESS_MIN_TIME , State , FilterDict , RunTests , TestResult , TestList )
15+ PROGRESS_MIN_TIME , State , RunTests , TestResult ,
16+ FilterTuple , FilterDict , TestList )
1617from test .libregrtest .setup import setup_tests
1718from test .libregrtest .pgo import setup_pgo_tests
1819from test .libregrtest .utils import (strip_py_suffix , count , format_duration ,
@@ -62,10 +63,35 @@ def __init__(self, ns: Namespace):
6263 # Namespace of command line options
6364 self .ns : Namespace = ns
6465
66+ # Actions
67+ self .want_header = ns .header
68+ self .want_list_tests = ns .list_tests
69+ self .want_list_cases = ns .list_cases
70+ self .want_wait = ns .wait
71+ self .want_cleanup = ns .cleanup
72+
73+ # Select tests
74+ if ns .match_tests :
75+ self .match_tests : FilterTuple = tuple (ns .match_tests )
76+ else :
77+ self .match_tests = None
78+ if ns .ignore_tests :
79+ self .ignore_tests : FilterTuple = tuple (ns .ignore_tests )
80+ else :
81+ self .ignore_tests = None
82+ self .exclude = ns .exclude
83+ self .fromfile = ns .fromfile
84+ self .starting_test = ns .start
85+
86+ # Options to run tests
87+ self .forever = ns .forever
88+ self .randomize = ns .randomize
89+ self .random_seed = ns .random_seed
90+
6591 # tests
6692 self .tests = []
6793 self .selected = []
68- self .all_runtests : list [ RunTests ] = []
94+ self .first_runtests : RunTests | None = None
6995
7096 # test results
7197 self .good : TestList = []
@@ -187,12 +213,8 @@ def display_progress(self, test_index, text):
187213 def find_tests (self ):
188214 ns = self .ns
189215 single = ns .single
190- fromfile = ns .fromfile
191216 pgo = ns .pgo
192- exclude = ns .exclude
193217 test_dir = ns .testdir
194- starting_test = ns .start
195- randomize = ns .randomize
196218
197219 if single :
198220 self .next_single_filename = os .path .join (self .tmp_dir , 'pynexttest' )
@@ -203,12 +225,12 @@ def find_tests(self):
203225 except OSError :
204226 pass
205227
206- if fromfile :
228+ if self . fromfile :
207229 self .tests = []
208230 # regex to match 'test_builtin' in line:
209231 # '0:00:00 [ 4/400] test_builtin -- test_dict took 1 sec'
210232 regex = re .compile (r'\btest_[a-zA-Z0-9_]+\b' )
211- with open (os .path .join (os_helper .SAVEDCWD , fromfile )) as fp :
233+ with open (os .path .join (os_helper .SAVEDCWD , self . fromfile )) as fp :
212234 for line in fp :
213235 line = line .split ('#' , 1 )[0 ]
214236 line = line .strip ()
@@ -223,14 +245,14 @@ def find_tests(self):
223245 setup_pgo_tests (ns )
224246
225247 exclude_tests = set ()
226- if exclude :
248+ if self . exclude :
227249 for arg in ns .args :
228250 exclude_tests .add (arg )
229251 ns .args = []
230252
231253 alltests = findtests (testdir = test_dir , exclude = exclude_tests )
232254
233- if not fromfile :
255+ if not self . fromfile :
234256 self .selected = self .tests or ns .args
235257 if self .selected :
236258 self .selected = split_test_packages (self .selected )
@@ -248,17 +270,17 @@ def find_tests(self):
248270 pass
249271
250272 # Remove all the selected tests that precede start if it's set.
251- if starting_test :
273+ if self . starting_test :
252274 try :
253- del self .selected [:self .selected .index (starting_test )]
275+ del self .selected [:self .selected .index (self . starting_test )]
254276 except ValueError :
255- print (f"Cannot find starting test: { starting_test } " )
277+ print (f"Cannot find starting test: { self . starting_test } " )
256278 sys .exit (1 )
257279
258- if randomize :
259- if ns .random_seed is None :
260- ns .random_seed = random .randrange (10000000 )
261- random .seed (ns .random_seed )
280+ if self . randomize :
281+ if self .random_seed is None :
282+ self .random_seed = random .randrange (100_000_000 )
283+ random .seed (self .random_seed )
262284 random .shuffle (self .selected )
263285
264286 def list_tests (self ):
@@ -279,7 +301,7 @@ def list_cases(self):
279301 ns = self .ns
280302 test_dir = ns .testdir
281303 support .verbose = False
282- support .set_match_tests (ns .match_tests , ns .ignore_tests )
304+ support .set_match_tests (self .match_tests , self .ignore_tests )
283305
284306 skipped = []
285307 for test_name in self .selected :
@@ -306,20 +328,18 @@ def get_rerun_match(self, rerun_list) -> FilterDict:
306328 rerun_match_tests [result .test_name ] = match_tests
307329 return rerun_match_tests
308330
309- def _rerun_failed_tests (self , need_rerun ):
331+ def _rerun_failed_tests (self , need_rerun , runtests : RunTests ):
310332 # Configure the runner to re-run tests
311333 ns = self .ns
312334 ns .verbose = True
313335 ns .failfast = False
314336 ns .verbose3 = False
315- ns .forever = False
316337 if ns .use_mp is None :
317338 ns .use_mp = 1
318339
319340 # Get tests to re-run
320341 tests = [result .test_name for result in need_rerun ]
321342 match_tests = self .get_rerun_match (need_rerun )
322- self .set_tests (tests )
323343
324344 # Clear previously failed tests
325345 self .rerun_bad .extend (self .bad )
@@ -328,11 +348,14 @@ def _rerun_failed_tests(self, need_rerun):
328348
329349 # Re-run failed tests
330350 self .log (f"Re-running { len (tests )} failed tests in verbose mode in subprocesses" )
331- runtests = RunTests (tuple (tests ), match_tests = match_tests , rerun = True )
332- self .all_runtests .append (runtests )
351+ runtests = runtests .copy (tests = tuple (tests ),
352+ match_tests = match_tests ,
353+ rerun = True ,
354+ forever = False )
355+ self .set_tests (runtests )
333356 self ._run_tests_mp (runtests )
334357
335- def rerun_failed_tests (self , need_rerun ):
358+ def rerun_failed_tests (self , need_rerun , runtests : RunTests ):
336359 if self .ns .python :
337360 # Temp patch for https://github.com/python/cpython/issues/94052
338361 self .log (
@@ -344,7 +367,7 @@ def rerun_failed_tests(self, need_rerun):
344367 self .first_state = self .get_tests_state ()
345368
346369 print ()
347- self ._rerun_failed_tests (need_rerun )
370+ self ._rerun_failed_tests (need_rerun , runtests )
348371
349372 if self .bad :
350373 print (count (len (self .bad ), 'test' ), "failed again:" )
@@ -572,9 +595,9 @@ def _run_tests_mp(self, runtests: RunTests) -> None:
572595 self .win_load_tracker .close ()
573596 self .win_load_tracker = None
574597
575- def set_tests (self , tests ):
576- self .tests = tests
577- if self . ns .forever :
598+ def set_tests (self , runtests : RunTests ):
599+ self .tests = runtests . tests
600+ if runtests .forever :
578601 self .test_count_text = ''
579602 self .test_count_width = 3
580603 else :
@@ -583,7 +606,7 @@ def set_tests(self, tests):
583606
584607 def run_tests (self ):
585608 # For a partial run, we do not need to clutter the output.
586- if (self .ns . header
609+ if (self .want_header
587610 or not (self .ns .pgo or self .ns .quiet or self .ns .single
588611 or self .tests or self .ns .args )):
589612 self .display_header ()
@@ -595,17 +618,18 @@ def run_tests(self):
595618 "3 warmup repetitions can give false positives!" )
596619 print (msg , file = sys .stdout , flush = True )
597620
598- if self .ns . randomize :
599- print ("Using random seed" , self .ns . random_seed )
621+ if self .randomize :
622+ print ("Using random seed" , self .random_seed )
600623
601624 tests = self .selected
602- self . set_tests ( tests )
603- runtests = RunTests ( tuple ( tests ), forever = self . ns . forever )
604- self .all_runtests . append (runtests )
625+ runtests = RunTests ( tuple ( tests ), forever = self . forever )
626+ self . first_runtests = runtests
627+ self .set_tests (runtests )
605628 if self .ns .use_mp :
606629 self ._run_tests_mp (runtests )
607630 else :
608631 self .run_tests_sequentially (runtests )
632+ return runtests
609633
610634 def finalize (self ):
611635 if self .next_single_filename :
@@ -627,11 +651,7 @@ def finalize(self):
627651
628652 def display_summary (self ):
629653 duration = time .perf_counter () - self .start_time
630- first_runtests = self .all_runtests [0 ]
631- # the second runtests (re-run failed tests) disables forever,
632- # use the first runtests
633- forever = first_runtests .forever
634- filtered = bool (self .ns .match_tests ) or bool (self .ns .ignore_tests )
654+ filtered = bool (self .match_tests ) or bool (self .ignore_tests )
635655
636656 # Total duration
637657 print ()
@@ -655,8 +675,8 @@ def display_summary(self):
655675 self .environment_changed , self .run_no_tests ]
656676 run = sum (map (len , all_tests ))
657677 text = f'run={ run } '
658- if not forever :
659- ntest = len (first_runtests .tests )
678+ if not self . first_runtests . forever :
679+ ntest = len (self . first_runtests .tests )
660680 text = f"{ text } /{ ntest } "
661681 if filtered :
662682 text = f"{ text } (filtered)"
@@ -788,7 +808,7 @@ def main(self, tests: TestList | None = None):
788808
789809 self .fix_umask ()
790810
791- if ns . cleanup :
811+ if self . want_cleanup :
792812 self .cleanup ()
793813 sys .exit (0 )
794814
@@ -838,12 +858,12 @@ def get_exitcode(self):
838858 return exitcode
839859
840860 def action_run_tests (self ):
841- self .run_tests ()
861+ runtests = self .run_tests ()
842862 self .display_result ()
843863
844864 need_rerun = self .need_rerun
845865 if self .ns .rerun and need_rerun :
846- self .rerun_failed_tests (need_rerun )
866+ self .rerun_failed_tests (need_rerun , runtests )
847867
848868 self .display_summary ()
849869 self .finalize ()
@@ -854,16 +874,16 @@ def _main(self):
854874 run_tests_worker (self .ns .worker_args )
855875 return
856876
857- if self .ns . wait :
877+ if self .want_wait :
858878 input ("Press any key to continue..." )
859879
860880 setup_tests (self .ns )
861881 self .find_tests ()
862882
863883 exitcode = 0
864- if self .ns . list_tests :
884+ if self .want_list_tests :
865885 self .list_tests ()
866- elif self .ns . list_cases :
886+ elif self .want_list_cases :
867887 self .list_cases ()
868888 else :
869889 self .action_run_tests ()
0 commit comments