Validators Reference
Every built-in OpenHTF measurement validator — in_range, within_percent, equals, matches_regex, all_in_range, all_equals, dimension_pivot_validate, consistent_end_dimension_pivot_validate — with marginal limits, custom validators and how they appear in the record.
Last updated · Verified with OpenHTF 1.6.1
A validator is a callable that takes the measured value and returns True (PASS) or False (FAIL). Built-ins live in openhtf.util.validators and are also exposed as chainable methods on htf.Measurement — .in_range(0, 10) is .with_validator(validators.in_range(0, 10)).
import openhtf as htf
from openhtf.util import validators
@htf.measures(
htf.Measurement("vbat").in_range(3.5, 4.2), # method form
htf.Measurement("fw").matches_regex(r"^1\.4\.\d+$"),
htf.Measurement("ok").equals(True),
htf.Measurement("ripple", validators=[validators.in_range(maximum=50)]), # kwargs form
)
def measure(test):
...A measurement may carry several validators; all must pass.
Scalar validators
in_range(minimum=None, maximum=None, marginal_minimum=None, marginal_maximum=None, type=None)Inclusive numeric range. Either bound may be omitted. marginal_* set inner limits that flag a passing value as marginal. type casts templated string arguments ('{minimum}' filled by with_args). Record string: 3.0 <= x <= 5.0; with marginal limits 5 <= Marginal:9 <= x <= Marginal:11 <= 17; x == 5 when both bounds are equal.
within_percent(expected, percent, marginal_percent=None)expected ± percent %. within_percent(5.0, 2) accepts 4.9–5.1. Record string: 'x' is within 2% of 5.0. Marginal: None% of 5.0.
equals(value, type=None)Exact equality for numbers, strings, booleans. Record string: 'x' is equal to '5'.
matches_regex(regex)re.match against a string value. Record string: 'x' matches /^1\.4/.
with_validator(callable)Any callable value -> bool. Define __str__ on a class-based validator so the record shows something readable instead of <function <lambda>>.
Validators for lists and dimensioned measurements
all_in_range(minimum, maximum, marginal_minimum=None, marginal_maximum=None)Every element of a list value is within the range.
all_equals(value, type=None)Every element of a list value equals value.
dimension_pivot_validate(sub_validator)Apply a scalar validator to every stored value of a multi-dimensional measurement. Fails if any sample fails. This is the way to put limits on a monitor's time series. Record string: All values pass: 0.3 <= x <= 0.5.
consistent_end_dimension_pivot_validate(sub_validator)Like dimension_pivot_validate, but once a row passes every following row must pass — models a value that must settle and stay settled (a rail reaching regulation, a temperature reaching set point). Record string: Once pass, rest must also pass: ....
import openhtf as htf
from openhtf.core import monitors
from openhtf.util import units, validators
def read_current(test):
return 0.42
@monitors.monitors("current", read_current, units=units.AMPERE, poll_interval_ms=100)
@htf.measures(
htf.Measurement("current").dimension_pivot_validate(validators.in_range(0.3, 0.5))
)
def load_test(test):
import time; time.sleep(1)Marginal limits
in_range and within_percent accept inner marginal bounds. A value between the marginal and hard limits passes but sets marginal: true on the measurement, phase and test, and the console banner shows PASS (MARGINAL). Use it to catch drift before it becomes yield loss. Marginal →
htf.Measurement("resistance").in_range(minimum=5, maximum=17, marginal_minimum=9, marginal_maximum=11)Conditional validators
.validate_on({DiagResult: validator}) swaps in a different validator when a diagnosis is present — for example a wider current limit in high-power mode.
Custom validators
For anything reusable, subclass ValidatorBase and give it a __str__:
from openhtf.util import validators
class Monotonic(validators.ValidatorBase):
"""Every sample of a dimensioned value is >= the previous one."""
def __call__(self, dim_value):
samples = [row[-1] for row in dim_value.value]
return all(b >= a for a, b in zip(samples, samples[1:]))
def __str__(self):
return "'x' is monotonically increasing"htf.Measurement("ramp").with_dimensions(units.SECOND).with_validator(Monotonic())Validators must be deepcopy()-able (phases are copied when templated with with_args), so avoid holding open file handles or sockets in them. Registering with validators.register(Monotonic, name='monotonic') additionally enables the method form .monotonic().
In the record
Validators are serialized with str():
"supply_voltage": {
"outcome": "PASS",
"validators": ["3.2 <= x <= 3.4"],
"measured_value": 3.31
}Tools that parse limits back out of the record (including TofuPilot) rely on the built-in formats above — one more reason to prefer built-ins and readable __str__ on custom ones.
Related
Units
Searchable table of all 2,134 unit constants in openhtf.util.units — name, UNECE code and suffix — with how to attach units to measurements and dimensions and how to look a unit up by string.
JSON format
Field-by-field reference for the JSON file OpenHTF's OutputToJSON writes — top-level record, metadata, phases, measurements, validators, units, attachments, subtests, branches, checkpoints, diagnoses, log records — with a complete annotated sample.