[autotest] File bugs on test failure.
When a test fails as part of a suite, if |file_bugs| is true, then
file a bug on the specified bug tracker reporting the failure.
Relanding Ie7664368583f645110fc562010897fbda999b815.
TEST=./run_suite.py with version N against a dummy project and check
for bugs that are filed
TEST=./run_suite.py with version N+1 and check that comments are filed
BUG=chromium-os:29513
Change-Id: I55c72155afba5ee87bedd137d560bde2d03d2cb2
Reviewed-on: https://gerrit.chromium.org/gerrit/41763
Commit-Queue: Alex Miller <milleral@chromium.org>
Reviewed-by: Alex Miller <milleral@chromium.org>
Tested-by: Alex Miller <milleral@chromium.org>
diff --git a/server/cros/dynamic_suite/suite.py b/server/cros/dynamic_suite/suite.py
index fc14312..cedc3de 100644
--- a/server/cros/dynamic_suite/suite.py
+++ b/server/cros/dynamic_suite/suite.py
@@ -13,6 +13,8 @@
from autotest_lib.server.cros.dynamic_suite import frontend_wrappers
from autotest_lib.server.cros.dynamic_suite import job_status
from autotest_lib.server.cros.dynamic_suite.job_status import Status
+from autotest_lib.server.cros.dynamic_suite import reporting
+from autotest_lib.server import frontend
class Suite(object):
@@ -107,7 +109,8 @@
def create_from_name(name, build, devserver, cf_getter=None, afe=None,
tko=None, pool=None, results_dir=None,
max_runtime_mins=24*60,
- version_prefix=constants.VERSION_PREFIX):
+ version_prefix=constants.VERSION_PREFIX,
+ file_bugs=False):
"""
Create a Suite using a predicate based on the SUITE control file var.
@@ -132,6 +135,8 @@
build name to form a label which the DUT needs
to be labeled with to be eligible to run this
test.
+ @param file_bugs: True if we should file bugs on test failures for
+ this suite run.
@return a Suite instance.
"""
if cf_getter is None:
@@ -139,7 +144,7 @@
return Suite(Suite.name_in_tag_predicate(name),
name, build, cf_getter, afe, tko, pool, results_dir,
- max_runtime_mins, version_prefix)
+ max_runtime_mins, version_prefix, file_bugs)
@staticmethod
@@ -147,7 +152,8 @@
cf_getter=None, afe=None, tko=None,
pool=None, results_dir=None,
max_runtime_mins=24*60,
- version_prefix=constants.VERSION_PREFIX):
+ version_prefix=constants.VERSION_PREFIX,
+ file_bugs=False):
"""
Create a Suite using a predicate based on the SUITE control file var.
@@ -173,6 +179,8 @@
build name to form a label which the DUT needs
to be labeled with to be eligible to run this
test.
+ @param file_bugs: True if we should file bugs on test failures for
+ this suite run.
@return a Suite instance.
"""
if cf_getter is None:
@@ -185,12 +193,13 @@
return Suite(in_tag_not_in_blacklist_predicate,
name, build, cf_getter, afe, tko, pool, results_dir,
- max_runtime_mins, version_prefix)
+ max_runtime_mins, version_prefix, file_bugs)
def __init__(self, predicate, tag, build, cf_getter, afe=None, tko=None,
pool=None, results_dir=None, max_runtime_mins=24*60,
- version_prefix=constants.VERSION_PREFIX):
+ version_prefix=constants.VERSION_PREFIX,
+ file_bugs=False):
"""
Constructor
@@ -228,6 +237,8 @@
add_experimental=True)
self._max_runtime_mins = max_runtime_mins
self._version_prefix = version_prefix
+ self._file_bugs = file_bugs
+
@property
def tests(self):
@@ -350,6 +361,8 @@
prototype:
record(base_job.status_log_entry)
"""
+ if self._file_bugs:
+ bug_reporter = reporting.Reporter()
try:
for result in job_status.wait_for_results(self._afe,
self._tko,
@@ -358,6 +371,19 @@
if (self._results_dir and
job_status.is_for_infrastructure_fail(result)):
self._remember_provided_job_id(result)
+
+ # I'd love to grab the actual tko test object here, as that
+ # includes almost all of the needed information: test name,
+ # status, reason, etc. However, doing so would cause a
+ # bunch of database traffic to grab data that we already
+ # have laying around in memory across several objects here.
+ worse = result.is_worse_than(job_status.Status("WARN", ""))
+ if self._file_bugs and worse:
+ failure = reporting.TestFailure(build=self._build,
+ suite=self._tag,
+ test=result.test_name,
+ reason=result.reason)
+ bug_reporter.report(failure)
except Exception: # pylint: disable=W0703
logging.error(traceback.format_exc())
Status('FAIL', self._tag,