summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYongqin Liu <yongqin.liu@linaro.org>2020-01-05 23:40:48 +0800
committerYongqin Liu <yongqin.liu@linaro.org>2020-01-05 23:40:48 +0800
commita47e7f01b6f5be470bbef7a79fdf05aaa27c56eb (patch)
treea7d3ba84e588377d984066ee63955682c0079f0a
parent0aa1e06c97a83d25d689d703fff654e39af0373c (diff)
lkftreport.py: print bugs information for builds
Signed-off-by: Yongqin Liu <yongqin.liu@linaro.org>
-rw-r--r--lkft/management/commands/lkftreport.py110
-rw-r--r--lkft/views.py5
2 files changed, 108 insertions, 7 deletions
diff --git a/lkft/management/commands/lkftreport.py b/lkft/management/commands/lkftreport.py
index 6ca7a6f..71f9ba9 100644
--- a/lkft/management/commands/lkftreport.py
+++ b/lkft/management/commands/lkftreport.py
@@ -7,6 +7,8 @@
import datetime
+import json
+import os
import re
import urllib2
import yaml
@@ -19,6 +21,8 @@ from lcr import qa_report
from lcr.settings import QA_REPORT, QA_REPORT_DEFAULT
from lkft.views import get_test_result_number_for_build, get_lkft_build_status
+from lkft.views import extract
+from lkft.views import get_lkft_bugs, get_hardware_from_pname, get_result_file_path, get_kver_with_pname_env
qa_report_def = QA_REPORT[QA_REPORT_DEFAULT]
qa_report_api = qa_report.QAReportApi(qa_report_def.get('domain'), qa_report_def.get('token'))
@@ -87,6 +91,43 @@ class Command(BaseCommand):
return projects
+
+ def classify_bugs_and_failures(self, bugs=[], failures=[]):
+ bugs_reproduced = []
+ bugs_not_reproduced = []
+ new_failures = []
+
+ for module_name in sorted(failures.keys()):
+ failures_in_module = failures.get(module_name)
+ for test_name in sorted(failures_in_module.keys()):
+ failure = failures_in_module.get(test_name)
+
+ for bug in bugs:
+ if test_name.find(module_name) >=0:
+ # vts test, module name is the same as the test name.
+ search_key = test_name
+ else:
+ search_key = '%s %s' % (module_name, test_name)
+
+ if bug.summary.find(search_key) >= 0:
+ bugs_reproduced.append(bug)
+ if failure.get('bugs'):
+ failure['bugs'].append(bug)
+ else:
+ failure['bugs'] = [bug]
+
+ if failure.get('bugs') is None or len(failure.get('bugs')) == 0:
+ new_failures.append(failure)
+
+ bugs_not_reproduced = [ bug for bug in bugs if not (bug in bugs_reproduced) ]
+
+ return {
+ 'bugs_reproduced': bugs_reproduced,
+ 'bugs_not_reproduced': bugs_not_reproduced,
+ 'new_failures': new_failures,
+ }
+
+
def handle(self, *args, **options):
total_reports = []
@@ -173,7 +214,47 @@ class Command(BaseCommand):
build['resubmitted_or_duplicated_jobs'] = resubmitted_or_duplicated_jobs
qa_report_builds.append(build)
found_build = True
- break
+
+ project_name = lkft_project.get('name')
+ bugs = get_lkft_bugs(summary_keyword=project_name, platform=get_hardware_from_pname(project_name))
+ build['bugs'] = bugs
+
+ failures = {}
+ for job in final_jobs:
+ if job.get('job_status') is None and \
+ job.get('submitted') and \
+ not job.get('fetched'):
+ job['job_status'] = 'Submitted'
+ if job.get('failure'):
+ failure = job.get('failure')
+ new_str = failure.replace('"', '\\"').replace('\'', '"')
+ try:
+ failure_dict = json.loads(new_str)
+ except ValueError:
+ failure_dict = {'error_msg': new_str}
+
+
+ result_file_path = get_result_file_path(job=job)
+ if not result_file_path or not os.path.exists(result_file_path):
+ continue
+
+ kernel_version = get_kver_with_pname_env(prj_name=project_name, env=job.get('environment'))
+
+ platform = job.get('environment').split('_')[0]
+
+ metadata = {
+ 'job_id': job.get('job_id'),
+ 'qa_job_id': qa_report_api.get_qa_job_id_with_url(job_url=job.get('url')),
+ 'result_url': job.get('attachment_url'),
+ 'lava_nick': job.get('lava_config').get('nick'),
+ 'kernel_version': kernel_version,
+ 'platform': platform,
+ }
+ extract(result_file_path, failed_testcases_all=failures, metadata=metadata)
+
+ build['failures'] = failures
+ classification = self.classify_bugs_and_failures(bugs=bugs, failures=failures)
+ build['classification'] = classification
kernel_change_report = {
'kernel_change': kernel_change,
@@ -229,6 +310,27 @@ class Command(BaseCommand):
numbers_of_result.get('number_total'),
numbers_of_result.get('number_failed'))
- print "\t Failures Not Reported:"
- print "\t Failures Reproduced:"
- print "\t Failures Not Reproduced:"
+
+ print "\t Failures and Bugs:"
+ for build in qa_report_builds:
+ qa_report_project = build.get('qa_report_project')
+ print "\t\t %s %s %s" % (qa_report_project.get('full_name'),
+ build.get('build_status'),
+ build.get('created_at'))
+
+ classification = build.get('classification')
+ bugs_reproduced = classification.get('bugs_reproduced')
+ bugs_not_reproduced = classification.get('bugs_not_reproduced')
+ new_failures = classification.get('new_failures')
+
+ print "\t\t\t Bugs Reproduced:"
+ for bug in bugs_reproduced:
+ print "\t\t\t\t %s %s %s" % (bug.id, bug.summary, bug.status)
+
+ print "\t\t\t Bugs Not Reproduced:"
+ for bug in bugs_not_reproduced:
+ print "\t\t\t\t %s %s %s" % (bug.id, bug.summary, bug.status)
+
+ print "\t\t\t Failures Not Reported:"
+ for failure in new_failures:
+ print "\t\t\t\t %s %s" % (failure.get('module_name'), failure.get('test_name'))
diff --git a/lkft/views.py b/lkft/views.py
index 2c1ee70..f371b78 100644
--- a/lkft/views.py
+++ b/lkft/views.py
@@ -277,7 +277,7 @@ def get_testcases_number_for_job(job):
logger.error('xml.etree.ElementTree.ParseError: %s' % e)
logger.info('Please Check %s manually' % result_zip_path)
- job['numbers_of_result'] = {
+ job['numbers'] = {
'number_passed': int(job_number_passed),
'number_failed': int(job_number_failed),
'number_total': int(job_number_passed) + int(job_number_failed),
@@ -285,7 +285,7 @@ def get_testcases_number_for_job(job):
'modules_done': int(modules_done)
}
- return job['numbers_of_result']
+ return job['numbers']
def get_test_result_number_for_build(build, jobs=None):
@@ -323,7 +323,6 @@ def get_test_result_number_for_build(build, jobs=None):
build_number_total = build_number_total + numbers.get('number_total')
build_modules_total = build_modules_total + numbers.get('modules_total')
build_modules_done = build_modules_done + numbers.get('modules_done')
- job['numbers'] = numbers
job_names.append(job.get('name'))
return {