blob: 5d2e0861997da0c13989c3c167fa94698751174d [file] [log] [blame]
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
import factory_common # pylint: disable=unused-import
from cros.factory.hwid.v3.bom import BOM
from cros.factory.hwid.v3 import common
from cros.factory.hwid.v3.rule import Context
from cros.factory.hwid.v3.rule import Value
from cros.factory.probe import probe_utils
DEFAULT_PROBE_STATEMENT_PATH = os.path.join(
os.path.dirname(__file__), 'default_probe_statement.json')
def ProbeDUT():
"""Probe the device to obtain the probed results.
Returns:
A dict of probed results.
"""
try:
probe_statement = probe_utils.GenerateProbeStatement(
config_file=DEFAULT_PROBE_STATEMENT_PATH)
return probe_utils.Probe(probe_statement)
except Exception as e:
raise common.HWIDException('Failed to execute the probe tool: %r.' % e)
def GenerateBOMFromProbedResults(database, probed_results, device_info, vpd,
mode, allow_mismatched_components):
"""Generates a BOM object according to the given probed results.
Args:
database: An instance of a HWID database.
probed_results: A JSON-serializable dict of the probe result, which is
usually the output of the probe command.
device_info: None or a dict of device info.
vpd: None or a dict of vpd data.
mode: None or "rma" or "normal".
allow_mismatched_components: Whether to Allows some probed components to be
ignored if no any component in the database matches with them.
Returns:
A instance of BOM class and a sub-dictionary of the probed results contains
the mismatched components.
"""
def _IsValuesMatch(probed_values, comp_values):
for key, value in comp_values.iteritems():
if not isinstance(value, Value):
value = Value(value)
if key not in probed_values or not value.Matches(probed_values[key]):
return False
return True
# Construct a dict of component classes to list of component names.
matched_components = {comp_cls: []
for comp_cls in database.GetComponentClasses()}
mismatched_components = {comp_cls: comps
for comp_cls, comps in probed_results.iteritems()
if comp_cls not in matched_components}
for comp_cls in database.GetComponentClasses():
default_comp = database.GetDefaultComponent(comp_cls)
for probed_comp in probed_results.get(comp_cls, []):
for comp_name, comp_info in database.GetComponents(comp_cls).iteritems():
if comp_info.values is None:
continue
if _IsValuesMatch(probed_comp['values'], comp_info.values):
matched_components[comp_cls].append(comp_name)
break
else:
if default_comp is not None:
matched_components[comp_cls].append(default_comp)
else:
mismatched_components.setdefault(comp_cls, [])
mismatched_components[comp_cls].append(probed_comp)
# If no any probed result of this component class, try add the default one.
if not matched_components[comp_cls] and default_comp is not None:
matched_components[comp_cls].append(default_comp)
if (not allow_mismatched_components and
any(mismatched_components.itervalues())):
raise common.HWIDException(
'Probed components %r are not matched with any component records in '
'the database.' % mismatched_components)
bom = BOM(encoding_pattern_index=0,
image_id=database.max_image_id,
components=matched_components)
# Evaluate device_info rules to fill unprobeable data in the BOM object.
context = Context(database=database, bom=bom,
device_info=device_info, vpd=vpd, mode=mode)
for rule in database.device_info_rules:
rule.Evaluate(context)
return bom, mismatched_components