google / openhtf

The open-source hardware testing framework.
Apache License 2.0
535 stars 215 forks source link

Provide a method to add dynamic measurements to Phases #821

Open kunaljdoshi opened 6 years ago

kunaljdoshi commented 6 years ago

Currently we can declare measurements mostly using @openhtf.measures decorator. However, there are cases where we need to add measurements on the fly based on some other measurements in the phase. For example, based on the version of FW read back there might be some extra measurements that can be recorded in that phase.

I was toying with that idea and here's an example that I came up with:

"""Example on adding Dynamic Measurement in Phase."""

import openhtf from openhtf.util import validators from openhtf.util import units from openhtf.plugs import user_input

TEST_NAME = 'DYNAMIC_MEASUREMENT_TESTER'

@openhtf.measures('hello_world_measurement') @openhtf.PhaseOptions(requires_state=True) def dynamic_measurement(test): """Dynamic measurement phase.""" test.logger.info('Experimenting with dynamic measurements!')

test.running_phase_state.measurements.update({'abc': openhtf.Measurement('abc')}) test.test_api.measurements.abc = '34' test.test_api.measurements.hello_world_measurement = '12'

@openhtf.PhaseOptions(requires_state=True) def dynamic_meas_with_limits(test): """Dynamic measurement phase.""" test.running_phase_state.measurements.update({'vbat': openhtf.Measurement('vbat').in_range( 1, 10).with_units(units.VOLT)}) test.test_api.measurements.vbat = 5

v_sleep = openhtf.Measurement('v_sleep', validators=[validators.in_range(0, 2)], units=units.VOLT) test.running_phase_state.measurements.update({'v_sleep': v_sleep}) test.test_api.measurements.v_sleep = 0.5

test_phases = ( dynamic_measurement, dynamic_meas_with_limits )

if name == 'main': test = openhtf.Test(*test_phases, test_name=TEST_NAME) test.execute(test_start=user_input.prompt_for_test_start('Enter Serial: '))

If we can add a method to expose the _measurement dictionary one can do this more directly.

kdsudac commented 6 years ago

Yeah, this is a somewhat common request.

I believe that philosophy of original OpenHTF authors is that the "right" way to think about measurements is as specifications. i.e. in a manufacturing test environment, you don't really want dynamically defined specifications.

Can you share more information about your use-case?

kunaljdoshi commented 6 years ago

In my particular case; new version of the chip has very different measurements than the older version of the chip. Now, I want my test software to be backward compatible; Hence, it would be nice to read the version of the chip and initialize measurements based on the version of the chip.

Sure, I could initialize all possible measurements and then set the unused ones to None but doesn't sound like the right approach.

cricdecyan commented 6 years ago

Usually, this case is handled by user APIs, you may want to explore a mechanism for creating product variants. We have something like this, but it is not upstreamed.

On Mon, Oct 1, 2018 at 11:49 AM, kunaljdoshi notifications@github.com wrote:

In my particular case; new version of the chip has very different measurements than the older version of the chip. Now, I want my test software to be backward compatible; Hence, it would be nice to read the version of the chip and initialize measurements based on the version of the chip.

Sure, I could initialize all possible measurements and then set the unused ones to None but doesn't sound like the right approach.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/google/openhtf/issues/821#issuecomment-426020109, or mute the thread https://github.com/notifications/unsubscribe-auth/AP89lJL9dukNtOtbHCDwLMVYS6RDqIasks5ugmOvgaJpZM4XCYKy .

wallacbe commented 6 years ago

If this request is common and to implement with current API would require boilerplate can we consider this? Dynamic limits based on a configuration is common in manufacturing. If there's a better place or do this or examples we're open to suggestions. Thanks!

jettisonjoe commented 6 years ago

What I would suggest for a case like this is to code up different versions of the phase for the different chip models (there should only be a small number of these, right?), and conditionally select which phase to include in the test at runtime, while building the Test instance but before executing it.

If you're in a situation where you're forced to choose the branch during test execution instead of before it, you can add all the models' phases to the test, and set a flag in test.state that is checked at the beginning of each model's respective phase. For all the phases that don't match the actual model, return from the phase early.

As for dynamic limits, they're pretty easy to create using conf:

import frobber_module
import openhtf as htf
from openhtf import conf

conf.declare(frobber_time_limit_s',
             description='Upper bound on how long it should take frob the bits.',
             default_value=10)

@htf.plug(frobber=frobber_module.Frobber)
@htf.measures(
    frobber_time_s',
    docstring='Time taken to frob the bits.',
    validators=(validators.in_range(maximum=conf.frobber_time_limit_s),))
def frobber_phase(test, frobber):
  frobber_time_s = frobber.timed_bit_frobbing()