google / google/openhtf

Setting validator targets during test execution

Open
#904 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
722
Forks
237
Avg merge
11h 31m
Merged PRs (30d)
4

Description

My use-case is setting a power supply voltage to a target value, and then checking that the voltage has been successfully achieved within a given tolerance. The target value is only known at runtime and is not hardcoded in the hardware tests (it could be but I want to explore this option). I have come up with a couple of ways of implementing this and wanted to ask for some thoughts here.

An example use-case:
```python
# at this point the limits are unknown
@measures(Measurement('powersupply_a_min', validators=[InRange(???)]))
def test_powersupply_a_minimum(test):
# at this point the limits are available but there is no easy
# mechanism to specify them as a validator
target_voltage = get_target_voltage()
set_supply_a(target_voltage)
test.measurements.powersupply_a_min = measure_supply_a()
```

The following are methods of implementing this:

1. Accessing the internal `_measurements` dictionary of `Collection` and adding a new validator at during the test: `test.measurements._measurements['voltage'].with_validator(InRange(minimum=4.485, maximum=4.515))`

2. Adding a method to `Collection` that can add validators during the test.

3. Using a validator class with a hacked `__deepcopy__()` method and setting it as normal using the decorator and manipulating it as a module-scope variable.

Method 1 is obviously using the internals of `Collection` and so is not desirable but it demonstrates possible access. This gives rise to the idea of having measurements returning their value via `test.measurements.measurement_name` when the value has been set, and prior to that returning the `Measurement` object so that it can be manipulated (in this case its `with_validator()` method would be called.

Method 2 is simple and works (as here https://github.com/JamesMTSloan/openhtf/commit/b59a5fe33bcd5324cf4df0afaf92a2de9b79fb19) but I suppose it rather violates what you want `Collection` to do by introducing public methods to it.

Method 3 is a nasty hack demonstrated as follows to around the deep copying that OpenHTF does when setting up the execution threads:
```python
class RunTimeTarget(ValidatorBase):
def __init__(self):
self.target = None

def __call__(self, value):
if self.target is None:
raise Exception("Target has not yet been set for this validator.")
return self.target == value

def __deepcopy__(self, memodict={}):
return self

my_validator = RunTimeTarget()

@measures(Measurement('something', validators=[my_validator]))
def measure_something(test):
my_validator.target = 5
test.measurements.something = 5
```

I do like the syntax though of using the walrus operator to make your validator accessible within the test.
```python
@measures(Measurement('something', validators=[my_validator := RunTimeTarget()]))
```

For my own use-case I will probably make sure the targets are available when defining the tests but perhaps there are cases where this is not possible. Is this just a use-case that should always be discouraged as it is too dynamic for hardware testing?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.