@@ -422,10 +422,15 @@ def _select_affordable_tests(
422422 This ensures we don't select tests that would exceed our time constraints
423423 even with the minimum number of retries.
424424 """
425+ if len (test_durations ) == 0 :
426+ return {}
427+
428+ budget_per_test = budget_duration / len (test_durations )
425429
426430 result = {}
427431 for test , duration in test_durations .items ():
428- if duration * _MIN_TEST_RETRY_COUNT <= budget_duration / len (test_durations ):
432+ expected_retries_duration = duration * _MIN_TEST_RETRY_COUNT
433+ if expected_retries_duration <= budget_per_test :
429434 result [test ] = duration
430435
431436 return result
@@ -436,7 +441,20 @@ def _allocate_test_retries(
436441 test_durations : typing .Dict [str , datetime .timedelta ],
437442) -> typing .Dict [str , int ]:
438443 """
439- Distributes test retries based on their duration and a time budget.
444+ Distribute retries within a fixed time budget.
445+
446+ Why this shape:
447+
448+ 1. First, drop tests that aren't affordable (cannot reach
449+ `_MIN_TEST_RETRY_COUNT` within the budget). This avoids wasting time on
450+ tests that would starve the rest.
451+
452+ 2. Then allocate from fastest to slowest to free budget early: fast tests
453+ often hit `_MAX_TEST_RETRY_COUNT`; when capped, leftover time rolls over to
454+ slower tests.
455+
456+ 3. At each step we recompute a fair per-test slice from the remaining budget
457+ and remaining tests, so the distribution adapts as we go.
440458 """
441459
442460 allocation : typing .Dict [str , int ] = {}
0 commit comments