@@ -532,6 +532,10 @@ def start():
532532 # Track collected test results across multiple runs (only used when run_sets_cnt > 1)
533533 collected_test_results = []
534534 seen_test_names = set ()
535+ # Track accumulated run time per test for the targeted check per-test time cap
536+ test_time_accumulated : dict [str , float ] = {}
537+ TIME_CAP_PER_TEST_SEC = 10 * 60
538+ tests_to_run = list (tests ) if tests else tests
535539
536540 for cnt in range (run_sets_cnt ):
537541 # For targeted checks with multiple iterations, recalculate
@@ -542,9 +546,9 @@ def start():
542546 )
543547
544548 run_tests (
545- batch_num = batch_num if not tests else 0 ,
546- batch_total = total_batches if not tests else 0 ,
547- tests = tests ,
549+ batch_num = batch_num if not tests_to_run else 0 ,
550+ batch_total = total_batches if not tests_to_run else 0 ,
551+ tests = tests_to_run ,
548552 extra_args = runner_options ,
549553 random_order = is_flaky_check
550554 or is_targeted_check
@@ -559,6 +563,27 @@ def start():
559563 if run_sets_cnt > 1 :
560564 is_final_run = cnt == run_sets_cnt - 1
561565
566+ # Accumulate per-test run time and filter tests that exceeded the time cap
567+ if is_targeted_check :
568+ for test_case_result in test_result .results :
569+ if test_case_result .duration is not None :
570+ test_time_accumulated [test_case_result .name ] = (
571+ test_time_accumulated .get (test_case_result .name , 0.0 )
572+ + test_case_result .duration
573+ )
574+ if not is_final_run :
575+ tests_to_run = [
576+ t
577+ for t in tests_to_run
578+ if test_time_accumulated .get (t , 0.0 )
579+ < TIME_CAP_PER_TEST_SEC
580+ ]
581+ if not tests_to_run :
582+ print (
583+ "NOTE: All tests exceeded the time cap; stopping early"
584+ )
585+ is_final_run = True
586+
562587 for test_case_result in test_result .results :
563588 # Only collect each test once (first failure or final result)
564589 if test_case_result .name not in seen_test_names :
0 commit comments