pytest: Add approx match to verify component test
- Show the closest hardwares when the number of components from probed
results and from device data are mismatched.
BUG=chromium:875167
Test=manually run on device
Change-Id: I8239e0f37be2695ee5bb440a635d58c1ac66b9ed
Reviewed-on: https://chromium-review.googlesource.com/1183054
Commit-Ready: Yuan-Yao Sung <yysung@google.com>
Tested-by: Yuan-Yao Sung <yysung@google.com>
Reviewed-by: Cheng-Han Yang <chenghan@chromium.org>
diff --git a/py/test/pytests/verify_component.py b/py/test/pytests/verify_component.py
index 8489c11..a05e00a 100644
--- a/py/test/pytests/verify_component.py
+++ b/py/test/pytests/verify_component.py
@@ -31,9 +31,15 @@
class VerifyComponentTest(test_case.TestCase):
ARGS = [
+ Arg('approx_match', bool,
+ 'Enable apporximate matching results.',
+ default=True),
Arg('enable_factory_server', bool,
'Update hwid data from factory server.',
default=True),
+ Arg('max_mismatch', int,
+ 'The number of mismatched rules at most.',
+ default=1),
Arg('verify_checksum', bool,
'Enable converted statements checksum verification.',
default=True)
@@ -47,6 +53,7 @@
self.num_mismatch = []
self.not_supported = []
self.probed_results = {}
+ self.perfect_match_results = {}
self.component_data = {}
self.converted_statement_file = self.dut.path.join(
self.tmpdir, 'converted_statement_file.json')
@@ -64,7 +71,10 @@
session.console.info('Checksum passed.')
self.probed_results = json_utils.LoadStr(self.factory_tools.CheckOutput(
- ['probe', 'probe', '--config-file', self.converted_statement_file]))
+ ['probe', 'probe', '--config-file', self.converted_statement_file,
+ '--approx-match', '--mismatch-num',
+ '{}'.format(self.args.max_mismatch)]))
+ self.perfect_match_results = self._GetPerfectMatchProbeResult()
self.component_data = {k[4:]: int(v) for k, v in
device_data.GetDeviceData('component').iteritems()
if k.startswith('has_')}
@@ -76,7 +86,8 @@
self.ui.CallJSFunction('setFailedMessage')
if self.num_mismatch:
self.ui.CallJSFunction(
- 'createNumMismatchResult', self.num_mismatch)
+ 'createNumMismatchResult', self.num_mismatch,
+ self.args.approx_match, self.probed_results)
if self.not_supported:
self.ui.CallJSFunction(
@@ -93,7 +104,7 @@
return [comp['name'] for comp in comp_info]
for comp_cls, correct_num in self.component_data.iteritems():
- comp_info = self.probed_results.get(comp_cls, [])
+ comp_info = self.perfect_match_results.get(comp_cls, [])
actual_num = len(comp_info)
if correct_num != actual_num:
self.num_mismatch.append((comp_cls, correct_num,
@@ -101,7 +112,7 @@
# The number of component should be _NUMBER_NOT_IN_DEVICE_DATA
# when the component is not in device data.
- for comp_cls, comp_info in self.probed_results.iteritems():
+ for comp_cls, comp_info in self.perfect_match_results.iteritems():
if comp_cls not in self.component_data:
actual_num = len(comp_info)
if actual_num != _NUMBER_NOT_IN_DEVICE_DATA:
@@ -111,7 +122,7 @@
def _VerifyNotSupported(self):
if self._CheckPhase():
- for comp_cls, comp_info in self.probed_results.iteritems():
+ for comp_cls, comp_info in self.perfect_match_results.iteritems():
for comp_item in comp_info:
status = comp_item['information']['status']
if status != common.COMPONENT_STATUS.supported:
@@ -129,3 +140,10 @@
converted_statement = self.dut.ReadFile(self.converted_statement_file)
converted_checksum = self.dut.ReadFile(converted_checksum_file)
return converted_statement, converted_checksum
+
+ def _GetPerfectMatchProbeResult(self):
+ res = {}
+ for comp_cls, comp_info in self.probed_results.iteritems():
+ res[comp_cls] = [item for item in comp_info if item['perfect_match']]
+
+ return res
diff --git a/py/test/pytests/verify_component_static/verify_component.js b/py/test/pytests/verify_component_static/verify_component.js
index 08535e3..c86fc4b 100644
--- a/py/test/pytests/verify_component_static/verify_component.js
+++ b/py/test/pytests/verify_component_static/verify_component.js
@@ -2,36 +2,66 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-const createNumMismatchResult = (data) => {
+const createNumMismatchResult = (data, approxMatch, probedResults) => {
const title = document.getElementById('verify-component-mismatch-label');
title.classList.remove('hidden');
const numMismatch = document.getElementById('verify-component-mismatch');
- data.forEach(([comp_cls, expected_num, comp_names]) => {
+ data.forEach(([compCls, expectedNum, compNames]) => {
const content = document.createElement('div');
const contentTitle = document.createElement('h2');
- contentTitle.appendChild(document.createTextNode(comp_cls));
+ contentTitle.appendChild(document.createTextNode(compCls));
content.appendChild(contentTitle);
const contentResult = document.createElement('div');
contentResult.classList.add('verify-component-mismatch-result');
const contentText = document.createElement('p');
contentText.appendChild(document.createTextNode(
- `Expected ${expected_num} component(s)`));
+ `Expected ${expectedNum} component(s)`));
contentText.appendChild(document.createElement('br'));
contentText.appendChild(document.createTextNode(
- `Found ${comp_names.length} component(s):`));
+ `Found ${compNames.length} component(s):`));
contentResult.appendChild(contentText);
const contentListBody = document.createElement('ul');
- comp_names.forEach((comp_name) => {
+ compNames.forEach((compName) => {
const contentList = document.createElement('li');
- contentList.appendChild(document.createTextNode(comp_name));
+ contentList.appendChild(document.createTextNode(compName));
contentListBody.appendChild(contentList);
});
contentResult.appendChild(contentListBody);
+ if (approxMatch) {
+ createApproxMatchResult(contentResult, probedResults[compCls]);
+ }
content.appendChild(contentResult);
numMismatch.appendChild(content);
});
};
+const createApproxMatchResult = (contentResult, compInfo) => {
+ const approxText = document.createElement('p');
+ approxText.appendChild(document.createTextNode(
+ 'Found almost matched components(s):'));
+ contentResult.appendChild(approxText);
+ compInfo.forEach((comp) => {
+ if (!comp.perfect_match) {
+ const approxResult = document.createElement('div');
+ const approxCompName = document.createElement('h2');
+ approxCompName.appendChild(document.createTextNode(comp['name']));
+ approxResult.appendChild(approxCompName);
+ const approxListBody = document.createElement('ul');
+ const rules = comp.approx_match.rule;
+ for (const rule in rules) {
+ if (!rules[rule].result) {
+ const approxList = document.createElement('li');
+ approxList.appendChild(document.createTextNode(
+ `${rule}: ${rules[rule].info}, found: ${comp.values[rule]}`));
+ approxListBody.append(approxList);
+ }
+ }
+ approxResult.appendChild(approxListBody);
+ contentResult.appendChild(approxResult)
+ }
+ });
+}
+
const createNotSupportedResult = (data) => {
const title = document.getElementById('verify-component-not-supported-label');
title.classList.remove('hidden');