blob: 0695928652c193a1a13695011e318c25bcb37dc0 [file] [log] [blame]
# -*- coding: utf-8 -*-
# Copyright 2017 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.
"""Classes to manage HWTest result."""
from __future__ import print_function
import collections
import os
from chromite.lib import constants
from chromite.lib import cros_logging as logging
from chromite.lib import git
from chromite.lib import patch as cros_patch
HWTEST_RESULT_COLUMNS = ['id', 'build_id', 'test_name', 'status']
_hwTestResult = collections.namedtuple('_hwTestResult',
class HWTestResult(_hwTestResult):
"""Class to present HWTest status."""
def FromReport(cls, build_id, test_name, status):
"""Get a HWTestResult instance from a result report."""
return HWTestResult(None, build_id, test_name, status)
def FromEntry(cls, entry):
"""Get a HWTestResult instance from cidb entry."""
return HWTestResult(, entry.build_id, entry.test_name, entry.status)
def NormalizeTestName(cls, test_name):
"""Normalize test name.
Normalization examples:
Suite job -> None -> cheets_CTS
security_NetworkListeners -> security_NetworkListeners
test_name: The test name string to normalize.
Test name after normalization.
if test_name == 'Suite job':
return None
names = test_name.split('.')
return names[0]
class HWTestResultManager(object):
"""Class to manage HWTest results."""
def GetHWTestResultsFromCIDB(cls, db, build_ids, test_statues=None):
"""Get HWTest results for given builds from CIDB.
db: An instance of cidb.CIDBConnection.
build_ids: A list of build_ids (strings) to get HWTest results.
test_statues: A set of HWTest statuses (stirngs) to get. If not None,
only return HWTests in test_statues.
A list of HWTestResult instances.
results = db.GetHWTestResultsForBuilds(build_ids)
if test_statues is None:
return results
return [x for x in results if x.status in test_statues]
def GetFailedHWTestsFromCIDB(cls, db, build_ids):
"""Get test names of failed HWTests from CIDB.
db: An instance of cidb.CIDBConnection
build_ids: A list of build_ids (strings) to get failed HWTests.
A list of normalized HWTest names (strings).
# TODO: probably only count 'fail' and exclude abort' and 'other' results?
hwtest_results = cls.GetHWTestResultsFromCIDB(
db, build_ids, test_statues=constants.HWTEST_STATUES_NOT_PASSED)
failed_tests = set([HWTestResult.NormalizeTestName(result.test_name)
for result in hwtest_results])
failed_tests.discard(None)'Found failed tests: %s ', failed_tests)
return failed_tests
def GetFailedHwtestsAffectedByChange(cls, change, manifest, failed_hwtests):
"""Get failed HWtests which could be affected by the given change.
change: An instance of cros_patch.GerritPatch.
manifest: An instance of ManifestCheckout.
failed_hwtests: A list of normalized name of failed hwtests got from CIDB
(see the return type of HWTestResultManager.GetFailedHWTestsFromCIDB).
A list of failed hwtest names (strings) which are likely to be affected by
the change.
assert failed_hwtests
checkout = change.GetCheckout(manifest)
assigned_failed_hwtests = set()
if checkout:
git_repo = checkout.GetPath(absolute=True)
for path in change.GetDiffStatus(git_repo):
root, _ = os.path.splitext(path)
touched_dirs = root.split(os.sep)
for touched_dir in touched_dirs:
if touched_dir in failed_hwtests:'Change %s changed path %s which may be relevant to '
'the failed HWTest %s', change, path, touched_dir)
return assigned_failed_hwtests
def FindHWTestFailureSuspects(cls, changes, build_root, failed_hwtests):
"""Find suspects for HWTest failures.
changes: A list of cros_patch.GerritPatch instances.
build_root: The path to the build root.
failed_hwtests: A list of names of failed hwtests got from CIDB (see the
return type of HWTestResultManager.GetFailedHWTestsFromCIDB), or None.
A pair of suspects and no_assignee_hwtests. suspects is a set of
cros_patch.GerritPatch instances. no_assignee_hwtests is True when there
are failed hwtests without assigned suspects; else False.
suspects = set()
no_assignee_hwtests = False
if not failed_hwtests:'No failed HWTests, skip finding HWTest failure suspects')
return suspects, no_assignee_hwtests
manifest = git.ManifestCheckout.Cached(build_root)
hwtests_with_assignee = set()
for change in changes:
assigned = cls.GetFailedHwtestsAffectedByChange(
change, manifest, failed_hwtests)
if assigned:
if suspects:'Found suspects for HWTest failures: %s',
hwtests_without_assignee = failed_hwtests - hwtests_with_assignee
if hwtests_without_assignee:'Didn\'t find changes to blame for failed HWtests: %s',
no_assignee_hwtests = True
return suspects, no_assignee_hwtests