Esempio n. 1
0
 def test_attachment_memory_safety(self):
     empty_attachment = test_record.Attachment('', 'text')
     expected_obj_size = _get_obj_size(empty_attachment)
     large_data = b'test attachment data' * 1000
     attachment = test_record.Attachment(large_data, 'text')
     obj_size = _get_obj_size(attachment)
     self.assertEqual(obj_size, expected_obj_size)
Esempio n. 2
0
 def test_attachment_memory_safety(self):
     small_data = b' '  # Use non-empty so Attachment.size (ints) are equal size.
     empty_attachment = test_record.Attachment(small_data, 'text')
     expected_obj_size = _get_obj_size(empty_attachment)
     large_data = b'test attachment data' * 1000
     attachment = test_record.Attachment(large_data, 'text')
     obj_size = _get_obj_size(attachment)
     self.assertEqual(obj_size, expected_obj_size)
Esempio n. 3
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'])
Esempio n. 4
0
    def attach(self, name, data, mimetype=INFER_MIMETYPE):
        """Store the given data as an attachment with the given name.

    Args:
      name: Attachment name under which to store this data.
      data: Data to attach.
      mimetype: One of the following:
          INFER_MIMETYPE: The type will be guessed from the attachment name.
          None: The type will be left unspecified.
          A string: The type will be set to the specified value.

    Raises:
      DuplicateAttachmentError: Raised if there is already an attachment with
        the given name.
      ValueError: Raised if the name contains a period
    """
        if '.' in name:
            raise ValueError('Attachment names cannot contain periods.')
        if name in self.phase_record.attachments:
            raise DuplicateAttachmentError('Duplicate attachment for %s' %
                                           name)

        if mimetype is INFER_MIMETYPE:
            mimetype = mimetypes.guess_type(name)[0]
        elif mimetype is not None and not mimetypes.guess_extension(mimetype):
            _LOG.debug('Unrecognized MIME type: "%s" for attachment "%s"',
                       mimetype, name)

        self.phase_record.attachments[name] = test_record.Attachment(
            data, mimetype)
Esempio n. 5
0
    def attach(self,
               name: Text,
               binary_data: Union[Text, bytes],
               mimetype: MimetypeT = INFER_MIMETYPE) -> None:
        """Store the given binary_data as an attachment with the given name.

    Args:
      name: Attachment name under which to store this binary_data.
      binary_data: Data to attach.
      mimetype: One of the following: INFER_MIMETYPE - The type will be guessed
        from the attachment name. None - The type will be left unspecified. A
        string - The type will be set to the specified value.

    Raises:
      DuplicateAttachmentError: Raised if there is already an attachment with
        the given name.
    """
        if name in self.phase_record.attachments:
            raise DuplicateAttachmentError('Duplicate attachment for %s' %
                                           name)

        if mimetype is INFER_MIMETYPE:
            mimetype = mimetypes.guess_type(name)[0]
        elif mimetype is not None and not mimetypes.guess_extension(mimetype):
            self.logger.warning(
                'Unrecognized MIME type: "%s" for attachment "%s"', mimetype,
                name)

        attach_record = test_record.Attachment(binary_data, mimetype)
        self.phase_record.attachments[name] = attach_record
        self._cached['attachments'][name] = attach_record._asdict()
Esempio n. 6
0
def multidim_measurement_to_attachment(name, measurement):
    """Convert a multi-dim measurement to an `openhtf.test_record.Attachment`."""

    dimensions = list(measurement.dimensions)
    if measurement.units:
        dimensions.append(
            measurements.Dimension.from_unit_descriptor(measurement.units))

    dims = []
    for d in dimensions:
        if d.suffix is None:
            suffix = u''
        else:
            suffix = six.ensure_text(d.suffix)
        dims.append({
            'uom_suffix': suffix,
            'uom_code': d.code,
            'name': d.name,
        })
    # Refer to the module docstring for the expected schema.
    dimensioned_measured_value = measurement.measured_value
    value = (sorted(dimensioned_measured_value.value, key=lambda x: x[0])
             if dimensioned_measured_value.is_value_set else None)
    outcome_str = _measurement_outcome_to_test_run_status_name(
        measurement.outcome, measurement.marginal)
    data = _convert_object_to_json({
        'outcome': outcome_str,
        'name': name,
        'dimensions': dims,
        'value': value,
    })
    attachment = htf_test_record.Attachment(data, test_runs_pb2.MULTIDIM_JSON)

    return attachment
Esempio n. 7
0
  def test_attachment_to_multidim_measurement(self):
    expected = self.create_multi_dim_measurement()

    attachment = test_record.Attachment(TEST_MULTIDIM_JSON,
                                        test_runs_pb2.MULTIDIM_JSON)
    measurement = mfg_event_converter.attachment_to_multidim_measurement(
        attachment)

    self.assertEqual(expected.measured_value.value,
                     measurement.measured_value.value)
    for exp, act in zip(expected.dimensions, measurement.dimensions):
      self.assertEqual(exp, act)
Esempio n. 8
0
  def testCopyAttachmentsFromPhase(self):
    attachment = test_record.Attachment('mock-data', 'text/plain')
    phase = test_record.PhaseRecord(
        name='mock-phase-name',
        descriptor_id=1,
        codeinfo=self.create_codeinfo(),
        attachments={'mock-attachment-name': attachment},
    )

    mfg_event = mfg_event_pb2.MfgEvent()
    copier = mfg_event_converter.PhaseCopier([phase])
    copier.copy_attachments(mfg_event)

    self.assertEqual(mfg_event.attachment[0].name, 'mock-attachment-name')
    self.assertEqual(mfg_event.attachment[0].value_binary, b'mock-data')
    self.assertEqual(mfg_event.attachment[0].type, test_runs_pb2.TEXT_UTF8)
Esempio n. 9
0
  def attach(self, name, data, mimetype=None):
    """Store the given data as an attachment with the given name.

    Args:
      name: Attachment name under which to store this data.
      data: Data to attach.
      mimetype: If provided, will be saved in the attachment.

    Raises:
      DuplicateAttachmentError: Raised if there is already an attachment with
        the given name.
    """
    if name in self.phase_record.attachments:
      raise DuplicateAttachmentError('Duplicate attachment for %s' % name)
    if mimetype and not mimetypes.guess_extension(mimetype):
      _LOG.warning('Unrecognized MIME type: "%s" for attachment "%s"',
                   mimetype, name)
    self.phase_record.attachments[name] = test_record.Attachment(data, mimetype)
Esempio n. 10
0
  def test_reversibleish_leagcy_status_int(self):
    """Verfiy multidim -> attachment is reversible even on leagacy data.

    Older implementations would cast the outcome to an int instead of a string.
    We verify we can cast the saved int into correct outcome.
    """
    mdim = self.create_multi_dim_measurement()

    attachment = mfg_event_converter.multidim_measurement_to_attachment(
        name='test_measurement_multidim', measurement=mdim)

    # Re-parse the data, edit the outcome field to a int, then reserialize.
    data_dict = json.loads(attachment.data)
    data_dict['outcome'] = test_runs_pb2.Status.Value(data_dict['outcome'])
    attachment = test_record.Attachment(json.dumps(data_dict),
                                        test_runs_pb2.MULTIDIM_JSON)

    reversed_mdim = mfg_event_converter.attachment_to_multidim_measurement(
        attachment)

    self.assert_same_mdim(mdim, reversed_mdim)
Esempio n. 11
0
def multidim_measurement_to_attachment(name, measurement):
    """Convert a multi-dim measurement to an `openhtf.test_record.Attachment`."""

    dimensions = list(measurement.dimensions)
    if measurement.units:
        dimensions.append(
            measurements.Dimension.from_unit_descriptor(measurement.units))

    dims = []
    for d in dimensions:
        if d.suffix is None:
            suffix = u''
        # Ensure that the suffix is unicode. It's typically str/bytes because
        # units.py looks them up against str/bytes.
        elif isinstance(d.suffix, unicode):
            suffix = d.suffix
        else:
            suffix = d.suffix.decode('utf8')
        dims.append({
            'uom_suffix': suffix,
            'uom_code': d.code,
            'name': d.name,
        })
    # Refer to the module docstring for the expected schema.
    dimensioned_measured_value = measurement.measured_value
    value = (sorted(dimensioned_measured_value.value, key=lambda x: x[0])
             if dimensioned_measured_value.is_value_set else None)
    outcome_str = MEASUREMENT_OUTCOME_TO_TEST_RUN_STATUS_NAME[
        measurement.outcome]
    data = _convert_object_to_json({
        'outcome': outcome_str,
        'name': name,
        'dimensions': dims,
        'value': value,
    })
    attachment = htf_test_record.Attachment(data, test_runs_pb2.MULTIDIM_JSON)

    return attachment
Esempio n. 12
0
 def test_attachment_size(self):
     expected_size = 10
     data = b't' * expected_size
     attachment = test_record.Attachment(data, 'text')
     self.assertEqual(attachment.size, expected_size)
Esempio n. 13
0
 def test_attachment_data(self):
     expected_data = b'test attachment data'
     attachment = test_record.Attachment(expected_data, 'text')
     data = attachment.data
     self.assertEqual(data, expected_data)
Esempio n. 14
0
 def testStringFromAttachment_SuccessfullyConvertsPassMeasurement(self):
     attachment = test_record.Attachment('content', 'text/plain')
     self.assertEqual(
         text.StringFromAttachment(attachment, 'attachment_a.txt'),
         '| attachment: attachment_a.txt (mimetype=text/plain)')
def _create_hacked_massive_attachment() -> test_record.Attachment:
    """Returns an attachment that seems massive by size."""
    attachment = test_record.Attachment(b'dummy', 'text/plain')
    attachment.size = mfg_event_converter.MAX_TOTAL_ATTACHMENT_BYTES
    return attachment