Skip to content

Commit

Permalink
Revise package structure as discussed in issue #314. (#411)
Browse files Browse the repository at this point in the history
  • Loading branch information
jettisonjoe authored Aug 23, 2016
1 parent 6760825 commit c9845da
Show file tree
Hide file tree
Showing 133 changed files with 295 additions and 469 deletions.
90 changes: 55 additions & 35 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,41 +128,61 @@ If you're adding a new module or feature, put some thought into where it best
fits in based on what it does.

```
.-----------------.
| openhtf |
|-----------------|
| Python package. |
'-----------------'
|
| .---------------------------------.
| | conf |
|--->|---------------------------------|
| | Reads and stores configuration. |
| '---------------------------------'
|
| .-------------------------.
| | exe |
|--->|-------------------------|
| | Manages test execution. |
| '-------------------------'
|
| .----------------------------------------.
| | io |
|--->|----------------------------------------|
| | Manages UI, logging, and test records. |
| '----------------------------------------'
|
| .---------------------------------------------------.
| | plugs |
|--->|---------------------------------------------------|
| | Extensions for interfacing with various hardware. |
| '---------------------------------------------------'
|
| .-----------------------------------.
| | util |
'--->|-----------------------------------|
| Utility functions and misc tools. |
'-----------------------------------'
openhtf
|
| Repository root directory.
|
|
|-> bin
|
| Standalone tools and scripts to help manage the codebase.
|
|
|-> contrib
|
| Standalone scripts that use the OpenHTF package. Nothing in the
| OpenHTF package should depend on these.
|
|
|-> examples
|
| Example OpenHTF tests and plugs.
|
|
|-> openhtf
| |
| | The OpenHTF Python package.
| |
| |-> core
| |
| | Framework internals that manage test state and execution.
| | The contents of this submodule shouldn't normally need to be
| | accessed from outside the package.
| |
| |
| |-> output
| |
| | Manages the framework's output, including UI, logging, and test
| | records.
| |
| |
| |-> plugs
| |
| | Extensions for interfacing with various hardware, such as test
| | equipment and DUT's.
| |
| |
| '-> util
|
| Generic utility functions and miscellaneous tools.
| The contents of this submodule should be general enough to be
| useable outside of OpenHTF, meaning it should not be dependent
| on other code in the OpenHTF package.
|
|
'-> test
Unittest code.
```


Expand Down
4 changes: 2 additions & 2 deletions openhtf/bin/units_from_xls.py → bin/units_from_xls.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,8 @@ def main():
parser.add_argument(
'--outfile',
type=str,
default=os.path.join(os.path.dirname(__file__), os.path.pardir, 'util',
'units.py'),
default=os.path.join(os.path.dirname(__file__), os.path.pardir,
'openhtf','util', 'units.py'),
help='where to put the generated .py file.')
args = parser.parse_args()

Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion contrib/poll_stations.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
import time


from openhtf.io import station_api
from openhtf.core import station_api
from openhtf.util import threads


Expand Down
60 changes: 29 additions & 31 deletions examples/all_the_things.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,36 +22,30 @@
import os
import time

import example_plug
import openhtf

from openhtf.io import output
from openhtf.io.output import json_factory
from openhtf.io.output import mfg_inspector
from openhtf.names import *
# Uncomment for mfg-inspector output, requires setup.py build_proto.
#from openhtf.io.output import mfg_inspector
from openhtf.plugs import user_input
import openhtf as htf
from openhtf.util import units
from openhtf.util import user_input

import example_plug


@plug(example=example_plug.ExamplePlug)
@htf.plug(example=example_plug.ExamplePlug)
def example_monitor(example):
time.sleep(.2)
return example.increment()


@measures(
Measurement('unset_meas'),
Measurement(
@htf.measures(
htf.Measurement('unset_meas'),
htf.Measurement(
'widget_type').matches_regex(r'.*Widget$').doc(
'''This measurement tracks the type of widgets.'''),
Measurement(
htf.Measurement(
'widget_color').doc('Color of the widget'),
Measurement('widget_size').in_range(1, 4))
@plug(example=example_plug.ExamplePlug)
@plug(prompts=user_input.UserInput)
def hello_world(test, example, prompts):
htf.Measurement('widget_size').in_range(1, 4))
@htf.plug(example=example_plug.ExamplePlug)
@htf.plug(prompts=user_input.UserInput)
def hello_world(test, example):
"""A hello world test phase."""
test.logger.info('Hello World!')
test.measurements.widget_type = prompts.prompt(
Expand All @@ -64,11 +58,11 @@ def hello_world(test, example, prompts):


# Timeout if this phase takes longer than 10 seconds.
@TestPhase(timeout_s=10)
@measures(
*(Measurement(
@htf.TestPhase(timeout_s=10)
@htf.measures(
*(htf.Measurement(
'level_%s' % i) for i in ['none', 'some', 'all']))
@monitors('monitor_measurement', example_monitor)
@htf.monitors('monitor_measurement', example_monitor)
def set_measurements(test):
"""Test phase that sets a measurement."""
test.measurements.level_none = 0
Expand All @@ -79,10 +73,10 @@ def set_measurements(test):
time.sleep(1)


@measures(
Measurement('unset_dims').with_dimensions(units.HERTZ),
Measurement('dimensions').with_dimensions(units.HERTZ),
Measurement('lots_of_dims').with_dimensions(
@htf.measures(
htf.Measurement('unset_dims').with_dimensions(units.HERTZ),
htf.Measurement('dimensions').with_dimensions(units.HERTZ),
htf.Measurement('lots_of_dims').with_dimensions(
units.HERTZ, units.SECOND, units.RADIAN))
def dimensions(test):
for dim in range(5):
Expand All @@ -100,19 +94,23 @@ def teardown(test):


if __name__ == '__main__':
test = openhtf.Test(hello_world, set_measurements, dimensions, attachments,
test = htf.Test(hello_world, set_measurements, dimensions, attachments,
# Some metadata fields, these in particular are used by mfg-inspector,
# but you can include any metadata fields.
test_name='MyTest', test_description='OpenHTF Example Test',
test_version='1.0.0')
test.add_output_callbacks(output.OutputToFile(
test.add_output_callbacks(htf.output.callbacks.OutputToFile(
'./{dut_id}.{metadata[test_name]}.{start_time_millis}.pickle'))
test.add_output_callbacks(
json_factory.OutputToJSON(
htf.output.callbacks.json_factory.OutputToJSON(
'./{dut_id}.{metadata[test_name]}.{start_time_millis}.json',
indent=4))
#test.add_output_callbacks(mfg_inspector.OutputToTestRunProto(

# Example of how to output to testrun protobuf format.
#test.add_output_callbacks(
# htf.output.callbacks.mfg_inspector.OutputToTestRunProto(
# './{dut_id}.{start_time_millis}.pb'))

# Example of how to upload to mfg-inspector. Replace filename with your
# JSON-formatted private key downloaded from Google Developers Console
# when you created the Service Account you intend to use, or name it
Expand Down
2 changes: 1 addition & 1 deletion examples/example_plug.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@

import time

import openhtf.conf as conf
import openhtf.plugs as plugs
from openhtf.util import conf


conf.declare('example_plug_increment_size', default_value=1,
Expand Down
18 changes: 9 additions & 9 deletions examples/hello_world.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,21 @@
For more information on output, see the output.py example.
"""

# Import openhtf with an abbreviated name, as we'll be using a bunch of stuff
# from it throughout our test scripts. See __all__ at the top of
# openhtf/__init__.py for details on what's in top-of-module namespace.
import openhtf as htf

# Import this output mechanism as it's the specific one we want to use.
from openhtf.io.output import json_factory
from openhtf.output.callbacks import json_factory

# Import a handful of useful names. If you're worried about polluting
# your namespace, you can manually import just the things you want, this
# is just a convenience. See names.py for an exhaustive list.
from openhtf.names import *
from openhtf.plugs import user_input


# The @measures annotation notifies the OpenHTF framework that this test
# The @htf.measures annotation notifies the OpenHTF framework that this test
# phase will be taking a measurement that we'd like to call
# 'hello_world_measurement'. Measurements can be accessed and set via
# the 'test' object, always passed as the first argument to test phases.
@measures(Measurement('hello_world_measurement'))
@htf.measures(htf.Measurement('hello_world_measurement'))
def hello_world(test):
"""A hello world test phase."""
# At the heart of an OpenHTF test script are the test phases, such as
Expand All @@ -68,7 +68,7 @@ def hello_world(test):
# Multiple phases would be passed as additional args, and additional
# keyword arguments may be passed as well. See other examples for more
# complex uses.
test = Test(hello_world)
test = htf.Test(hello_world)

# In order to view the result of the test, we have to output it somewhere,
# and a local JSON file is a convenient way to do this. Custom output
Expand Down
32 changes: 16 additions & 16 deletions examples/measurements.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,29 +44,29 @@
measurements, which some output formats require.
"""

# Import openhtf with an abbreviated name, as we'll be using a bunch of stuff
# from it throughout our test scripts. See __all__ at the top of
# openhtf/__init__.py for details on what's in top-of-module namespace.
import openhtf as htf

# Import this output mechanism as it's the specific one we want to use.
from openhtf.io.output import json_factory
from openhtf.output.callbacks import json_factory

# You won't normally need to import this, see validators.py example for
# more details. It's used for the inline measurement declaration example
# below, but normally you'll only import it when you want to define custom
# measurement validators.
from openhtf.util import validators

# Import a handful of useful names. If you're worried about polluting
# your namespace, you can manually import just the things you want, this
# is just a convenience. See names.py for an exhaustive list.
from openhtf.names import *


# Simple example of measurement use, similar to hello_world.py usage.
@measures(Measurement('hello_world_measurement'))
@htf.measures(htf.Measurement('hello_world_measurement'))
def hello_phase(test):
test.measurements.hello_world_measurement = 'Hello!'


# An alternative simpler syntax that creates the Measurement for you.
@measures('hello_again_measurement')
@htf.measures('hello_again_measurement')
def again_phase(test):
test.measurements.hello_again_measurement = 'Again!'

Expand All @@ -77,8 +77,8 @@ def again_phase(test):
# single decorator call. You'll also note that you can stack multiple
# decorations on a single phase. This is useful if you have a handful of simple
# measurements, and then one or two with more complex declarations (see below).
@measures('first_measurement', 'second_measurement')
@measures(Measurement('third'), Measurement('fourth'))
@htf.measures('first_measurement', 'second_measurement')
@htf.measures(htf.Measurement('third'), htf.Measurement('fourth'))
def lots_of_measurements(test):
test.measurements.first_measurement = 'First!'
# Measurements can also be access via indexing rather than attributes.
Expand All @@ -92,7 +92,7 @@ def lots_of_measurements(test):
# measurement against some criteria, or specify additional information
# describing the measurement. Validators can get quite complex, for more
# details, see the validators.py example.
@measures(Measurement('validated_measurement').InRange(0, 10).Doc(
@htf.measures(htf.Measurement('validated_measurement').in_range(0, 10).doc(
'This measurement is validated.').with_units(units.SECOND))
def measure_seconds(test):
# The 'outcome' of this measurement in the test_record result will be a PASS
Expand All @@ -105,9 +105,9 @@ def measure_seconds(test):
# specify exactly one measurement with that decorator (ie. the first argument
# must be a string containing the measurement name). If you want to specify
# multiple measurements this way, you can stack multiple decorators.
@measures('inline_kwargs', docstring='This measurement is declared inline!',
units=units.HERTZ, validators=[validators.InRange(0, 10)])
@measures('another_inline', docstring='Because why not?')
@htf.measures('inline_kwargs', docstring='This measurement is declared inline!',
units=units.HERTZ, validators=[validators.in_range(0, 10)])
@htf.measures('another_inline', docstring='Because why not?')
def inline_phase(test):
# This measurement will have an outcome of FAIL, because the set value of 15
# will not pass the 0 <= x <= 10 validator.
Expand All @@ -120,8 +120,8 @@ def inline_phase(test):

if __name__ == '__main__':
# We instantiate our OpenHTF test with the phases we want to run as args.
test = Test(hello_phase, again_phase, lots_of_measurements, measure_seconds,
inline_phase)
test = htf.Test(hello_phase, again_phase, lots_of_measurements,
measure_seconds, inline_phase)

# In order to view the result of the test, we have to output it somewhere,
# and a local JSON file is a convenient way to do this. Custom output
Expand Down
Loading

0 comments on commit c9845da

Please sign in to comment.