Skip to content

Commit cadbd83

Browse files
authored
Merge pull request #3262 from vkarak/feat/retries-threshold
[feat] Add new `--retries-threshold` option
2 parents f63e040 + a819a31 commit cadbd83

File tree

4 files changed

+37
-3
lines changed

4 files changed

+37
-3
lines changed

docs/manpage.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,17 @@ Options controlling ReFrame execution
694694
.. versionchanged:: 3.6.1
695695
Multiple report files are now accepted.
696696

697+
698+
.. option:: --retries-threshold=VALUE[%]
699+
700+
Skip retries (see :option:`--max-retries`) if failures exceed the given threshold.
701+
702+
Threshold can be specified either as an absolute value or as a percentage using the ``%`` character, e.g., ``--retries-threshold=30%``.
703+
Note that in certain shells the ``%`` character may need to be escaped.
704+
705+
.. versionadded:: 4.7
706+
707+
697708
.. option:: -S, --setvar=[TEST.]VAR=VAL
698709

699710
Set variable ``VAR`` in all tests or optionally only in test ``TEST`` to ``VAL``.

reframe/frontend/cli.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,11 @@ def main():
522522
metavar='REPORT',
523523
help='Restore a testing session from REPORT file'
524524
)
525+
run_options.add_argument(
526+
'--retries-threshold', action='store', default='1000%',
527+
metavar='VALUE[%]',
528+
help='Retry tests only if failures do not exceed threshold'
529+
)
525530
run_options.add_argument(
526531
'-S', '--setvar', action='append', metavar='[TEST.]VAR=VAL',
527532
dest='vars', default=[],
@@ -1564,8 +1569,16 @@ def module_unuse(*paths):
15641569
f"{options.reruns}"
15651570
)
15661571

1572+
# Parse retries threshold
1573+
if options.retries_threshold[-1] == '%':
1574+
ratio = int(options.retries_threshold[:-1]) / 100.
1575+
retries_threshold = int(len(testcases)*ratio)
1576+
else:
1577+
retries_threshold = int(options.retries_threshold)
1578+
15671579
runner = Runner(exec_policy, printer, options.max_retries,
1568-
options.maxfail, options.reruns, options.duration)
1580+
options.maxfail, options.reruns, options.duration,
1581+
retries_threshold)
15691582
try:
15701583
time_start = time.time()
15711584
runner.runall(testcases, restored_cases)

reframe/frontend/executors/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -573,10 +573,12 @@ class Runner:
573573
_timeout = fields.TypedField(typ.Duration, type(None), allow_implicit=True)
574574

575575
def __init__(self, policy, printer=None, max_retries=0,
576-
max_failures=sys.maxsize, reruns=0, timeout=None):
576+
max_failures=sys.maxsize, reruns=0, timeout=None,
577+
retries_threshold=sys.maxsize):
577578
self._policy = policy
578579
self._printer = printer or PrettyPrinter()
579580
self._max_retries = max_retries
581+
self._retries_threshold = retries_threshold
580582
self._num_reruns = reruns
581583
self._timeout = timeout
582584
self._t_init = timeout
@@ -620,7 +622,8 @@ def runall(self, testcases, restored_cases=None):
620622
self._policy.set_expiry(self._t_init + self._timeout)
621623

622624
self._runall(testcases)
623-
if self._max_retries:
625+
if (self._max_retries and
626+
len(self._stats.failed()) <= self._retries_threshold):
624627
restored_cases = restored_cases or []
625628
self._retry_failed(testcases + restored_cases)
626629

unittests/test_policies.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,13 @@ def test_retries_bad_check(make_runner, make_cases, common_exec_ctx):
274274
assert_runall(runner)
275275
assert runner.max_retries == rt.runtime().current_run
276276
assert 2 == len(runner.stats.failed())
277+
assert 3 == runner.stats.num_runs
278+
279+
280+
def test_retries_threshold(make_runner, make_cases, common_exec_ctx):
281+
runner = make_runner(max_retries=2, retries_threshold=1)
282+
runner.runall(make_cases([BadSetupCheck(), BadSetupCheckEarly()]))
283+
assert 1 == runner.stats.num_runs
277284

278285

279286
def test_retries_good_check(make_runner, make_cases, common_exec_ctx):

0 commit comments

Comments
 (0)