Пример #1
0
  def test_mfg_event_from_test_record(self):
    """Test for the full conversion flow."""
    record = test_record.TestRecord(
        dut_id='dut_serial',
        start_time_millis=1,
        end_time_millis=1,
        station_id='localhost',
        outcome=test_record.Outcome.PASS,
    )
    record.outcome = test_record.Outcome.PASS
    record.metadata = {
        'assembly_events': [assembly_event_pb2.AssemblyEvent()] * 2,
        'config': {'mock-config-key': 'mock-config-value'},
        'operator_name': 'mock-operator-name',
    }
    record.phases = [
        test_record.PhaseRecord(
            name='phase-%d' % idx,
            descriptor_id=idx,
            codeinfo=test_record.CodeInfo.uncaptured(),
            result=None,
            attachments={},
            start_time_millis=1,
            end_time_millis=1
        )
        for idx in range(1, 5)
    ]
    for phase in record.phases:
      phase.measurements = {
          'meas-1': measurements.Measurement('meas-1'),
          'meas-2': measurements.Measurement('meas-2'),
          'meas-3': measurements.Measurement('meas-3').with_dimensions('V'),
      }
      phase.attachments = {
          'attach-1': test_record.Attachment(data='data-1', mimetype=''),
          'attach-2': test_record.Attachment(data='data-2', mimetype=''),
      }

    mfg_event = mfg_event_converter.mfg_event_from_test_record(record)

    self.assertEqual(mfg_event.dut_serial, record.dut_id)
    self.assertEqual(len(mfg_event.assembly_events), 2)
    self.assertEqual(len(mfg_event.measurement), 8)
    self.assertEqual(sorted(m.name for m in mfg_event.measurement),
                     ['meas-1_0', 'meas-1_1', 'meas-1_2', 'meas-1_3',
                      'meas-2_0', 'meas-2_1', 'meas-2_2', 'meas-2_3'])
    self.assertEqual(len(mfg_event.attachment), 15)
    self.assertEqual(sorted(str(m.name) for m in mfg_event.attachment),
                     ['OpenHTF_record.json', 'argv',
                      'attach-1_0', 'attach-1_1', 'attach-1_2', 'attach-1_3',
                      'attach-2_0', 'attach-2_1', 'attach-2_2', 'attach-2_3',
                      'config',
                      'multidim_meas-3_0', 'multidim_meas-3_1',
                      'multidim_meas-3_2', 'multidim_meas-3_3'])
Пример #2
0
    def wrapper(phase_func):
        phase_desc = openhtf.PhaseDescriptor.wrap_or_copy(phase_func)

        # Re-key this dict so we don't have to worry about collisions with
        # plug.plug() decorators on the phase function.  Since we aren't
        # updating kwargs here, we don't have to worry about collisions with
        # kwarg names.
        monitor_plugs = {
            ('_' * idx) + measurement_name + '_monitor': plug.cls
            for idx, plug in enumerate(monitor_desc.plugs, start=1)
        }

        @openhtf.PhaseOptions(requires_state=True)
        @plugs.plug(update_kwargs=False, **monitor_plugs)
        @measurements.measures(
            measurements.Measurement(measurement_name).with_units(
                units).with_dimensions(uom.MILLISECOND))
        @functools.wraps(phase_desc.func)
        def monitored_phase_func(test_state, *args, **kwargs):
            # Start monitor thread, it will run monitor_desc periodically.
            monitor_thread = _MonitorThread(measurement_name, monitor_desc,
                                            phase_desc.extra_kwargs,
                                            test_state, poll_interval_ms)
            monitor_thread.start()
            try:
                return phase_desc(test_state, *args, **kwargs)
            finally:
                monitor_thread.kill()
                monitor_thread.join()

        return monitored_phase_func
Пример #3
0
  def _create_and_set_measurement(self, name, value):
    measured_value = measurements.MeasuredValue(name, is_value_set=False)
    measured_value.set(value)

    measurement = measurements.Measurement(
        name=name, outcome=measurements.Outcome.PASS)
    # Cannot be set in initialization.
    measurement.measured_value = measured_value
    return measurement
Пример #4
0
    def _create_and_set_measurement(self, name, value):
        measured_value = measurements.MeasuredValue(name, is_value_set=False)
        measured_value.set(value)

        measurement = measurements.Measurement(
            name=name,
            outcome=measurements.Outcome.PASS,
            measured_value=measured_value)
        return measurement
Пример #5
0
 def _maybe_make(
     meas: Union[Text, core_measurements.Measurement]
 ) -> core_measurements.Measurement:
   """Turn strings into Measurement objects if necessary."""
   if isinstance(meas, core_measurements.Measurement):
     return meas
   elif isinstance(meas, six.string_types):
     return core_measurements.Measurement(meas, **kwargs)
   raise core_measurements.InvalidMeasurementTypeError(
       'Expected Measurement or string', meas)
Пример #6
0
  def create_multi_dim_measurement(cls):
    """Util function to create a test multi-dim measurement."""
    measurement = measurements.Measurement('test_measurement')
    measurement.with_units('°C').with_dimensions('ms', 'assembly', 'zone')
    for t in range(10):
      for assembly in ['A', 'B', 'C']:
        for zone in range(3):
          temp = zone + t
          dims = (t, assembly, zone)
          measurement.measured_value[dims] = temp

    measurement.outcome = measurements.Outcome.PASS

    return measurement
Пример #7
0
def attachment_to_multidim_measurement(attachment, name=None):
    """Convert an OpenHTF test record attachment to a multi-dim measurement.

  This is a best effort attempt to reverse, as some data is lost in converting
  from a multidim to an attachment.

  Args:
    attachment: an `openhtf.test_record.Attachment` from a multi-dim.
    name: an optional name for the measurement.  If not provided will use the
     name included in the attachment.

  Returns:
    An multi-dim `openhtf.Measurement`.
  """
    data = json.loads(attachment.data)

    name = name or data.get('name')
    # attachment_dimn are a list of dicts with keys 'uom_suffix' and 'uom_code'
    attachment_dims = data.get('dimensions', [])
    # attachment_value is a list of lists [[t1, x1, y1, f1], [t2, x2, y2, f2]]
    attachment_values = data.get('value')

    attachment_outcome_str = data.get('outcome')
    if attachment_outcome_str not in TEST_RUN_STATUS_NAME_TO_MEASUREMENT_OUTCOME:
        # Fpr backward compatibility with saved data we'll convert integers to str
        try:
            attachment_outcome_str = test_runs_pb2.Status.Name(
                int(attachment_outcome_str))
        except ValueError:
            attachment_outcome_str = None

    # Convert test status outcome str to measurement outcome
    outcome = TEST_RUN_STATUS_NAME_TO_MEASUREMENT_OUTCOME.get(
        attachment_outcome_str)

    # convert dimensions into htf.Dimensions
    _lazy_load_units_by_code()
    dims = []
    for d in attachment_dims:
        # Try to convert into htf.Dimension including backwards compatibility.
        unit = UNITS_BY_CODE.get(d.get('uom_code'), units.NONE)
        description = d.get('name', '')
        dims.append(measurements.Dimension(description=description, unit=unit))

    # Attempt to determine if units are included.
    if attachment_values and len(dims) == len(attachment_values[0]):
        # units provided
        units_ = dims[-1].unit
        dimensions = dims[:-1]
    else:
        units_ = None
        dimensions = dims

    # created dimensioned_measured_value and populate with values.
    measured_value = measurements.DimensionedMeasuredValue(
        name=name, num_dimensions=len(dimensions))
    for row in attachment_values:
        coordinates = tuple(row[:-1])
        val = row[-1]
        measured_value[coordinates] = val

    measurement = measurements.Measurement(name=name,
                                           units=units_,
                                           dimensions=tuple(dimensions),
                                           measured_value=measured_value,
                                           outcome=outcome)
    return measurement