Examples

Repeat Example

The upstream repeat.py example — retry a phase on a plug exception with PhaseResult.REPEAT, and cap retries on a bad result with PhaseOptions(repeat_limit=5).

Last updated · Verified with OpenHTF 1.6.1

Two phases that retry themselves: one after an exception, one after an unwanted result, with a cap. Based on examples/repeat.py.

repeat.py
import openhtf
from openhtf import plugs
from openhtf.core import base_plugs


class FailTwicePlug(base_plugs.BasePlug):
    """Raises on the first two calls, succeeds on the third."""

    def __init__(self):
        self.count = 0

    def run(self):
        self.count += 1
        print('FailTwicePlug: Run number %s' % self.count)
        if self.count < 3:
            raise RuntimeError('Fails a couple times')
        return True


class FailAlwaysPlug(base_plugs.BasePlug):
    """Always returns False."""

    def __init__(self):
        self.count = 0

    def run(self):
        self.count += 1
        print('FailAlwaysPlug: Run number %s' % self.count)
        return False


# Catch the plug's exception and ask for a repeat. Runs three times in total.
@plugs.plug(test_plug=FailTwicePlug)
def phase_repeat(test_plug):
    try:
        test_plug.run()
    except Exception:
        print('Error in phase_repeat, will retry')
        return openhtf.PhaseResult.REPEAT
    print('Completed phase_repeat')


# Repeat on a bad result, but never more than 5 times.
@openhtf.PhaseOptions(repeat_limit=5)
@plugs.plug(test_plug=FailAlwaysPlug)
def phase_repeat_with_limit(test_plug):
    if not test_plug.run():
        print('Invalid result in phase_repeat_with_limit, will retry')
        return openhtf.PhaseResult.REPEAT


def main():
    test = openhtf.Test(phase_repeat, phase_repeat_with_limit)
    test.execute(test_start=lambda: 'RepeatDutID')


if __name__ == '__main__':
    main()
Terminal
$ python repeat.py
FailTwicePlug: Run number 1
Error in phase_repeat, will retry
FailTwicePlug: Run number 2
Error in phase_repeat, will retry
FailTwicePlug: Run number 3
Completed phase_repeat
FailAlwaysPlug: Run number 1
Invalid result in phase_repeat_with_limit, will retry
FailAlwaysPlug: Run number 2
Invalid result in phase_repeat_with_limit, will retry
FailAlwaysPlug: Run number 3
Invalid result in phase_repeat_with_limit, will retry
FailAlwaysPlug: Run number 4
Invalid result in phase_repeat_with_limit, will retry
FailAlwaysPlug: Run number 5
Invalid result in phase_repeat_with_limit, will retry

======================= test: openhtf_test  outcome: FAIL ======================

What it shows

PhaseResult.REPEAT

Run the phase again, ignoring this attempt's measurements. Each attempt is recorded as its own PhaseRecord with outcome SKIP, and the final one carries the result. Results →

repeat_limit

When REPEAT is returned more than repeat_limit times the framework treats it as STOP, hence the FAIL above. Without the option the default limit applies (DEFAULT_REPEAT_LIMIT, 3 in 1.6.1); set repeat_limit=None for unlimited. Options →

Phase without the test argument

phase_repeat(test_plug) takes only the plug. The test parameter is optional; OpenHTF inspects the signature.

Plug state across repeats

The plug is instantiated once per test, so self.count survives repeats — which is what lets FailTwicePlug succeed on the third try. Plugs →

  • repeat_on_measurement_fail=True repeats automatically when a measurement fails validation — no REPEAT needed in the phase body.
  • repeat_on_timeout=True repeats after timeout_s expires.
  • force_repeat=True repeats repeat_limit times regardless of result (soak-style loops).

Next

On this page

First-pass yield
0%4.1
Track with TofuPilot