summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYongqin Liu <yongqin.liu@linaro.org>2020-02-25 11:28:32 +0800
committerYongqin Liu <yongqin.liu@linaro.org>2020-02-25 11:28:32 +0800
commit1d11212e48f9be189df2cc48a53becd7941d30a2 (patch)
tree1626cb0f5e2c8e9e190b5791f686eb8639d22959
parent08965011c15e3679ec802dc7e6c21ea0b7ffd3d8 (diff)
lkft: add kernel change list page
and fixed the database "received a naive datetime" warning problem Signed-off-by: Yongqin Liu <yongqin.liu@linaro.org>
-rw-r--r--lcr/qa_report.py29
-rw-r--r--lkft/lkft_config.py48
-rw-r--r--lkft/management/commands/lkftreport.py86
-rw-r--r--lkft/templates/lkft-kernelchanges.html46
-rw-r--r--lkft/urls.py1
-rw-r--r--lkft/views.py199
6 files changed, 329 insertions, 80 deletions
diff --git a/lcr/qa_report.py b/lcr/qa_report.py
index ebe3a41..cb9ff53 100644
--- a/lcr/qa_report.py
+++ b/lcr/qa_report.py
@@ -232,3 +232,32 @@ class QAReportApi(RESTFullApi):
def get_qa_job_id_with_url(self, job_url):
return job_url.strip('/').split('/')[-1]
+
+ def get_lkft_qa_report_projects(self):
+ projects = []
+ for project in self.get_projects():
+ if project.get('is_archived'):
+ continue
+
+ project_full_name = project.get('full_name')
+ if not project_full_name.startswith('android-lkft/') \
+ and not project_full_name.startswith('android-lkft-rc/'):
+ continue
+
+ projects.append(project)
+
+ return projects
+
+ def get_aware_datetime_from_str(self, datetime_str):
+ import datetime
+ import pytz
+ # from python3.7, pytz is not necessary, we could use %z to get the timezone info
+ #https://stackoverflow.com/questions/53291250/python-3-6-datetime-strptime-returns-error-while-python-3-7-works-well
+ navie_datetime = datetime.datetime.strptime(datetime_str, '%Y-%m-%dT%H:%M:%S.%fZ')
+ return pytz.utc.localize(navie_datetime)
+
+ def get_aware_datetime_from_timestamp(self, timestamp_in_secs):
+ import datetime
+ from django.utils import timezone
+
+ return datetime.datetime.fromtimestamp(timestamp_in_secs, tz=timezone.utc) \ No newline at end of file
diff --git a/lkft/lkft_config.py b/lkft/lkft_config.py
index 5ac3eb9..359913f 100644
--- a/lkft/lkft_config.py
+++ b/lkft/lkft_config.py
@@ -186,3 +186,51 @@ def get_kver_with_pname_env(prj_name='', env=''):
kernel_version = prj_name.split('-')[0]
return kernel_version
+
+
+def get_url_content(url=None):
+ import urllib2
+ try:
+ response = urllib2.urlopen(url)
+ return response.read()
+ except urllib2.HTTPError:
+ pass
+
+ return None
+
+
+def get_configs(ci_build=None):
+ build_name = ci_build.get('name')
+ configs = []
+ ci_config_file_url = "https://git.linaro.org/ci/job/configs.git/plain/%s.yaml" % build_name
+ content = get_url_content(url=ci_config_file_url)
+ if content is not None:
+ pat_configs = re.compile("\n\s+name:\s*ANDROID_BUILD_CONFIG\n\s+default:\s*'(?P<value>[a-zA-Z0-9\ -_.]+)'\s*\n")
+ configs_str = pat_configs.findall(content)
+ if len(configs_str) > 0:
+ for config in ' '.join(configs_str[0].split()).split():
+ configs.append((config, ci_build))
+
+ return configs
+
+def get_qa_server_project(lkft_build_config_name=None):
+ #TEST_QA_SERVER=https://qa-reports.linaro.org
+ #TEST_QA_SERVER_PROJECT=mainline-gki-aosp-master-hikey960
+ #TEST_QA_SERVER_TEAM=android-lkft-rc
+ url_build_config = "https://android-git.linaro.org/android-build-configs.git/plain/lkft/%s?h=lkft" % lkft_build_config_name
+ content = get_url_content(url_build_config)
+ pat_project = re.compile("\nTEST_QA_SERVER_PROJECT=(?P<value>[a-zA-Z0-9\ -_.]+)\n")
+ project_str = pat_project.findall(content)
+ if len(project_str) > 0:
+ project = project_str[0]
+ else:
+ project = None
+
+ pat_team=re.compile("\nTEST_QA_SERVER_TEAM=(?P<value>[a-zA-Z0-9\ -_.]+)\n")
+ team_str = pat_team.findall(content)
+ if len(team_str) > 0:
+ team = team_str[0]
+ else:
+ team = "android-lkft"
+
+ return (team, project) \ No newline at end of file
diff --git a/lkft/management/commands/lkftreport.py b/lkft/management/commands/lkftreport.py
index c013cdf..6ebeb9e 100644
--- a/lkft/management/commands/lkftreport.py
+++ b/lkft/management/commands/lkftreport.py
@@ -28,6 +28,8 @@ 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
from lkft.lkft_config import find_expect_cibuilds
+from lkft.lkft_config import get_configs, get_qa_server_project
+
qa_report_def = QA_REPORT[QA_REPORT_DEFAULT]
qa_report_api = qa_report.QAReportApi(qa_report_def.get('domain'), qa_report_def.get('token'))
jenkins_api = qa_report.JenkinsApi('ci.linaro.org', None)
@@ -38,66 +40,6 @@ class Command(BaseCommand):
# def add_arguments(self, parser):
# parser.add_argument('git_describes', nargs='+', type=str)
- def get_url_content(self, url=None):
- try:
- response = urllib2.urlopen(url)
- return response.read()
- except urllib2.HTTPError:
- pass
-
- return None
-
-
- def get_configs(self, ci_build=None):
- build_name = ci_build.get('name')
- configs = []
- ci_config_file_url = "https://git.linaro.org/ci/job/configs.git/plain/%s.yaml" % build_name
- content = self.get_url_content(url=ci_config_file_url)
- if content is not None:
- pat_configs = re.compile("\n\s+name:\s*ANDROID_BUILD_CONFIG\n\s+default:\s*'(?P<value>[a-zA-Z0-9\ -_.]+)'\s*\n")
- configs_str = pat_configs.findall(content)
- if len(configs_str) > 0:
- for config in ' '.join(configs_str[0].split()).split():
- configs.append((config, ci_build))
-
- return configs
-
- def get_qa_server_project(self, lkft_build_config_name=None):
- #TEST_QA_SERVER=https://qa-reports.linaro.org
- #TEST_QA_SERVER_PROJECT=mainline-gki-aosp-master-hikey960
- #TEST_QA_SERVER_TEAM=android-lkft-rc
- url_build_config = "https://android-git.linaro.org/android-build-configs.git/plain/lkft/%s?h=lkft" % lkft_build_config_name
- content = self.get_url_content(url_build_config)
- pat_project = re.compile("\nTEST_QA_SERVER_PROJECT=(?P<value>[a-zA-Z0-9\ -_.]+)\n")
- project_str = pat_project.findall(content)
- if len(project_str) > 0:
- project = project_str[0]
- else:
- project = None
-
- pat_team=re.compile("\nTEST_QA_SERVER_TEAM=(?P<value>[a-zA-Z0-9\ -_.]+)\n")
- team_str = pat_team.findall(content)
- if len(team_str) > 0:
- team = team_str[0]
- else:
- team = "android-lkft"
-
- return (team, project)
-
-
- def get_lkft_qa_report_projects(self):
- projects = []
- for project in qa_report_api.get_projects():
- project_full_name = project.get('full_name')
- if not project_full_name.startswith('android-lkft/') \
- or project.get('is_archived'):
- continue
-
- projects.append(project)
-
- return projects
-
-
def classify_bugs_and_failures(self, bugs=[], failures=[]):
bugs_reproduced = []
bugs_not_reproduced = []
@@ -138,14 +80,14 @@ class Command(BaseCommand):
total_reports = []
- lkft_projects = self.get_lkft_qa_report_projects()
+ lkft_projects = qa_report_api.get_lkft_qa_report_projects()
queued_ci_items = jenkins_api.get_queued_items()
kernel_changes = KernelChange.objects_needs_report.all()
for kernel_change in kernel_changes:
lkft_build_configs = []
trigger_url = jenkins_api.get_job_url(name=kernel_change.trigger_name, number=kernel_change.trigger_number)
trigger_build = jenkins_api.get_build_details_with_full_url(build_url=trigger_url)
- trigger_build['start_timestamp'] = datetime.datetime.fromtimestamp(int(trigger_build['timestamp'])/1000)
+ trigger_build['start_timestamp'] = qa_report_api.get_aware_datetime_from_timestamp(int(trigger_build['timestamp'])/1000)
trigger_build['duration'] = datetime.timedelta(milliseconds=trigger_build['duration'])
trigger_build['name'] = kernel_change.trigger_name
trigger_build['kernel_change'] = kernel_change
@@ -154,9 +96,6 @@ class Command(BaseCommand):
kernel_change_status = "TRIGGER_BUILD_COMPLETED"
dbci_builds = CiBuild.objects_kernel_change.get_builds_per_kernel_change(kernel_change=kernel_change).order_by('name', '-number')
-
- ## TODO: how to check if a ci build is still in queue?
- ## check which ci build should be started from the information of the trigger build?
expect_build_names = find_expect_cibuilds(trigger_name=kernel_change.trigger_name)
jenkins_ci_builds = []
@@ -170,7 +109,7 @@ class Command(BaseCommand):
build_url = jenkins_api.get_job_url(name=dbci_build.name, number=dbci_build.number)
build = jenkins_api.get_build_details_with_full_url(build_url=build_url)
- build['start_timestamp'] = datetime.datetime.fromtimestamp(int(build['timestamp'])/1000)
+ build['start_timestamp'] = qa_report_api.get_aware_datetime_from_timestamp(int(build['timestamp'])/1000)
build['dbci_build'] = dbci_build
if build.get('building'):
@@ -183,7 +122,7 @@ class Command(BaseCommand):
build['status'] = build_status
build['name'] = dbci_build.name
jenkins_ci_builds.append(build)
- configs = self.get_configs(ci_build=build)
+ configs = get_configs(ci_build=build)
lkft_build_configs.extend(configs)
not_started_ci_builds = expect_build_names - set(ci_build_names)
@@ -228,7 +167,7 @@ class Command(BaseCommand):
# no need to check the build/job results as the ci build not finished successfully yet
continue
- (project_group, project_name) = self.get_qa_server_project(lkft_build_config_name=lkft_build_config)
+ (project_group, project_name) = get_qa_server_project(lkft_build_config_name=lkft_build_config)
target_lkft_project_full_name = "%s/%s" % (project_group, project_name)
target_qareport_project = None
@@ -253,7 +192,7 @@ class Command(BaseCommand):
continue
created_str = target_qareport_build.get('created_at')
- target_qareport_build['created_at'] = datetime.datetime.strptime(str(created_str), '%Y-%m-%dT%H:%M:%S.%fZ')
+ target_qareport_build['created_at'] = qa_report_api.get_aware_datetime_from_str(created_str)
target_qareport_build['project_name'] = project_name
target_qareport_build['project_group'] = project_group
@@ -399,13 +338,14 @@ class Command(BaseCommand):
dbci_build = jenkins_ci_build.get('dbci_build')
result_numbers = qareport_build.get('numbers_of_result')
+ trigger_dbci_build = CiBuild.objects.get(name=trigger_build.get('name'), number=trigger_build.get('number'))
try:
report_build = ReportBuild.objects.get(group=qareport_build.get('project_group'),
name=qareport_build.get('project_name'),
version=kernel_change.describe)
report_build.kernel_change = kernel_change
report_build.ci_build = dbci_build
- report_build.ci_trigger_build = CiBuild.objects.get(name=trigger_build.get('name'), number=trigger_build.get('number'))
+ report_build.ci_trigger_build = trigger_dbci_build
report_build.number_passed = result_numbers.get('number_passed')
report_build.number_failed = result_numbers.get('number_failed')
report_build.number_total = result_numbers.get('number_total')
@@ -414,13 +354,13 @@ class Command(BaseCommand):
report_build.started_at = trigger_build.get('start_timestamp')
report_build.fetched_at = qareport_build.get('last_fetched_timestamp')
report_build.save()
- except KernelChange.DoesNotExist:
+ except ReportBuild.DoesNotExist:
ReportBuild.objects.create(group=qareport_build.get('project_group'),
name=qareport_build.get('project_name'),
version=kernel_change.describe,
kernel_change=kernel_change,
ci_build=dbci_build,
- ci_trigger_build=CiBuild.objects.get(name=trigger_build.get('name'), number=trigger_build.get('number')),
+ ci_trigger_build=trigger_dbci_build,
number_passed=result_numbers.get('number_passed'),
number_failed=result_numbers.get('number_failed'),
number_total=result_numbers.get('number_total'),
@@ -462,7 +402,7 @@ class Command(BaseCommand):
queued_ci_builds = kernel_change_report.get('queued_ci_builds')
for build in queued_ci_builds:
- inqueuesince = datetime.datetime.fromtimestamp(int(build.get('inQueueSince')/1000))
+ inqueuesince = qa_report_api.get_aware_datetime_from_timestamp(int(build.get('inQueueSince')/1000))
#duration = datetime_now - inqueuesince
print "\t\t %s: still in queue since %s ago" % (build.get('build_name'), timesince(inqueuesince))
diff --git a/lkft/templates/lkft-kernelchanges.html b/lkft/templates/lkft-kernelchanges.html
new file mode 100644
index 0000000..9dc0704
--- /dev/null
+++ b/lkft/templates/lkft-kernelchanges.html
@@ -0,0 +1,46 @@
+{% extends '_layouts/base.html' %}
+
+{% block title %} Summary for Kernel Changes {% endblock %}
+
+{% block headline %}<h1>Summary for Kernel Changes</a></h1>{% endblock %}
+
+{% block content %}
+<div>
+<table border="1">
+ <tr>
+ <th>Index</th>
+ <th>Branch</th>
+ <th>Describe</th>
+ <th>Status</th>
+ <th>StartedAt</th>
+ <th>Duration</th>
+ <th>CI Trigger</th>
+ <th>Pass</th>
+ <th>Fail</th>
+ <th>Total</th>
+ <th>Modules Done</th>
+ <th>Modules Total</th>
+</tr>
+{% for kernelchange in kernelchanges %}
+<tr>
+ <td>{{ forloop.counter }}</td>
+ <td>{{kernelchange.branch}}</td>
+ <td>{{kernelchange.describe}}</td>
+ <td>{{kernelchange.status}}</td>
+ <td><p>Started at {{ kernelchange.start_timestamp|date:'M. d, Y, H:i'}}, &nbsp;{{ kernelchange.start_timestamp|timesince}} ago</p></td>
+ {% if kernelchange.status == 'ALL_COMPLETED' %}
+ <td>Took {{kernelchange.duration}} to finish</td>
+ {% else %}
+ <td>--</td>
+ {% endif %}
+ <td><a href="https://ci.linaro.org/job/{{kernelchange.trigger_name}}/{{kernelchange.trigger_number}}">{{kernelchange.trigger_name}}#{{kernelchange.trigger_number}}</td>
+ <td>{{kernelchange.number_passed}}</td>
+ <td>{{kernelchange.number_failed}}</td>
+ <td>{{kernelchange.number_total}}</td>
+ <td>{{kernelchange.modules_done}}</td>
+ <td>{{kernelchange.modules_total}}</td>
+</tr>
+{% endfor %}
+</table>
+</div>
+{% endblock %}
diff --git a/lkft/urls.py b/lkft/urls.py
index 9c1bebf..7416e8a 100644
--- a/lkft/urls.py
+++ b/lkft/urls.py
@@ -7,6 +7,7 @@ urlpatterns = [
url(r'^$', views.list_projects, name='home'),
url(r'^rc-projects/.*$', views.list_rc_projects, name='list_rc_projects'),
url(r'^projects/.*$', views.list_projects, name='list_projects'),
+ url(r'^kernel-changes/.*$', views.list_kernel_changes, name='list_kernel_changes'),
url(r'^builds/.*$', views.list_builds, name='list_builds'),
url(r'^jobs/.*$', views.list_jobs, name='list_jobs'),
url(r'^file-bug/.*$', views.file_bug, name='file_bug'),
diff --git a/lkft/views.py b/lkft/views.py
index 57df19d..351a281 100644
--- a/lkft/views.py
+++ b/lkft/views.py
@@ -29,6 +29,8 @@ from lcr import qa_report, bugzilla
from lcr.qa_report import DotDict
from lcr.utils import download_urllib
from lkft.lkft_config import find_citrigger, find_cibuild, get_hardware_from_pname, get_version_from_pname, get_kver_with_pname_env
+from lkft.lkft_config import find_expect_cibuilds
+from lkft.lkft_config import get_configs, get_qa_server_project
from .models import KernelChange, CiBuild
@@ -363,7 +365,7 @@ def get_lkft_build_status(build, jobs):
has_unsubmitted = True
break
if job.get('fetched'):
- job_last_fetched_timestamp = datetime.datetime.strptime(job.get('fetched_at'), '%Y-%m-%dT%H:%M:%S.%fZ')
+ job_last_fetched_timestamp = qa_report_api.get_aware_datetime_from_str(job.get('fetched_at'))
if job_last_fetched_timestamp > last_fetched_timestamp:
last_fetched_timestamp = job_last_fetched_timestamp
else:
@@ -383,8 +385,7 @@ def get_project_info(project):
builds = qa_report_api.get_all_builds(project.get('id'), only_first=True)
if len(builds) > 0:
last_build = builds[0]
- created_str = last_build.get('created_at')
- last_build['created_at'] = datetime.datetime.strptime(str(created_str), '%Y-%m-%dT%H:%M:%S.%fZ')
+ last_build['created_at'] = qa_report_api.get_aware_datetime_from_str(last_build.get('fetched_at'))
jobs = qa_report_api.get_jobs_for_build(last_build.get("id"))
last_build['numbers_of_result'] = get_test_result_number_for_build(last_build, jobs)
@@ -403,7 +404,7 @@ def get_project_info(project):
if last_trigger_build:
last_trigger_url = last_trigger_build.get('url')
last_trigger_build = jenkins_api.get_build_details_with_full_url(build_url=last_trigger_url)
- last_trigger_build['start_timestamp'] = datetime.datetime.fromtimestamp(int(last_trigger_build['timestamp'])/1000)
+ last_trigger_build['start_timestamp'] = qa_report_api.get_aware_datetime_from_timestamp(int(last_trigger_build['timestamp'])/1000)
last_trigger_build['duration'] = datetime.timedelta(milliseconds=last_trigger_build['duration'])
project['last_trigger_build'] = last_trigger_build
@@ -436,7 +437,7 @@ def get_project_info(project):
elif ci_build_project.get('lastBuild') is not None:
ci_build_last_url = ci_build_project.get('lastBuild').get('url')
ci_build_last = jenkins_api.get_build_details_with_full_url(build_url=ci_build_last_url)
- ci_build_last_start_timestamp = datetime.datetime.fromtimestamp(int(ci_build_last['timestamp'])/1000)
+ ci_build_last_start_timestamp = qa_report_api.get_aware_datetime_from_timestamp(int(ci_build_last['timestamp'])/1000)
ci_build_last_duration = datetime.timedelta(milliseconds=ci_build_last['duration'])
kernel_version = ci_build_last.get('displayName') # #buildNo.-kernelInfo
@@ -558,8 +559,7 @@ def list_builds(request):
'modules_done': build_modules_done,
'modules_total': build_modules_total,
}
- created_str = build.get('created_at')
- build['created_at'] = datetime.datetime.strptime(str(created_str), '%Y-%m-%dT%H:%M:%S.%fZ')
+ build['created_at'] = qa_report_api.get_aware_datetime_from_str(build.get('created_at'))
build['jobs'] = jobs
return render(request, 'lkft-builds.html',
@@ -1125,3 +1125,188 @@ def new_build(request, branch, describe, name, number):
else:
return HttpResponse("ERROR:%s" % err_msg,
status=200)
+
+
+def list_kernel_changes(request):
+ queued_ci_items = jenkins_api.get_queued_items()
+ lkft_projects = qa_report_api.get_lkft_qa_report_projects()
+ db_kernelchanges = KernelChange.objects.all()
+
+ kernelchanges = []
+
+ for db_kernelchange in db_kernelchanges:
+ kernelchange = {}
+ trigger_url = jenkins_api.get_job_url(name=db_kernelchange.trigger_name, number=db_kernelchange.trigger_number)
+ trigger_build = jenkins_api.get_build_details_with_full_url(build_url=trigger_url)
+ trigger_build['start_timestamp'] = qa_report_api.get_aware_datetime_from_timestamp(int(trigger_build['timestamp'])/1000)
+ kernel_change_finished_timestamp = trigger_build['start_timestamp']
+
+ number_passed = 0
+ number_failed = 0
+ number_total = 0
+ modules_done = 0
+ modules_total = 0
+
+ kernel_change_status = "TRIGGER_BUILD_COMPLETED"
+
+ dbci_builds = CiBuild.objects_kernel_change.get_builds_per_kernel_change(kernel_change=db_kernelchange).order_by('name', '-number')
+ expect_build_names = find_expect_cibuilds(trigger_name=db_kernelchange.trigger_name)
+
+ lkft_build_configs = []
+ jenkins_ci_builds = []
+ ci_build_names = []
+ has_build_inprogress = False
+ for dbci_build in dbci_builds:
+ if dbci_build.name in ci_build_names:
+ continue
+ else:
+ ci_build_names.append(dbci_build.name)
+
+ build_url = jenkins_api.get_job_url(name=dbci_build.name, number=dbci_build.number)
+ build = jenkins_api.get_build_details_with_full_url(build_url=build_url)
+ build['start_timestamp'] = qa_report_api.get_aware_datetime_from_timestamp(int(build['timestamp'])/1000)
+ build['dbci_build'] = dbci_build
+
+ if build.get('building'):
+ build_status = 'INPROGRESS'
+ has_build_inprogress = True
+ else:
+ build_status = build.get('result') # null or SUCCESS, FAILURE, ABORTED
+ build['duration'] = datetime.timedelta(milliseconds=build['duration'])
+
+ build['status'] = build_status
+ build['name'] = dbci_build.name
+ jenkins_ci_builds.append(build)
+ configs = get_configs(ci_build=build)
+ lkft_build_configs.extend(configs)
+
+ not_started_ci_builds = expect_build_names - set(ci_build_names)
+
+ queued_ci_builds = []
+ diabled_ci_builds = []
+ not_reported_ci_builds = []
+ if len(not_started_ci_builds) > 0:
+ for cibuild_name in not_started_ci_builds:
+ is_queued_build = False
+ for queued_item in queued_ci_items:
+ if cibuild_name == queued_item.get('build_name') and \
+ kernel_change.describe == queued_item.get('KERNEL_DESCRIBE'):
+ is_queued_build = True
+ queued_ci_builds.append(queued_item)
+ if is_queued_build:
+ continue
+
+ if jenkins_api.is_build_disabled(cibuild_name):
+ diabled_ci_builds.append(cibuild_name)
+ else:
+ not_reported_ci_builds.append(cibuild_name)
+
+ if queued_ci_builds:
+ kernel_change_status = "CI_BUILDS_IN_QUEUE"
+ elif not_reported_ci_builds:
+ kernel_change_status = "CI_BUILDS_NOT_REPORTED"
+ elif has_build_inprogress:
+ kernel_change_status = "CI_BUILDS_IN_PROGRESS"
+ else:
+ kernel_change_status = "CI_BUILDS_COMPLETED"
+
+ qa_report_builds = []
+ has_jobs_not_submitted = False
+ has_jobs_in_progress = False
+ all_jobs_finished = False
+
+ qareport_project_not_found_configs = []
+ qareport_build_not_found_configs = []
+ for lkft_build_config, ci_build in lkft_build_configs:
+ if ci_build.get('status') != 'SUCCESS':
+ # no need to check the build/job results as the ci build not finished successfully yet
+ continue
+
+ (project_group, project_name) = get_qa_server_project(lkft_build_config_name=lkft_build_config)
+ target_lkft_project_full_name = "%s/%s" % (project_group, project_name)
+
+ target_qareport_project = None
+ for lkft_project in lkft_projects:
+ if lkft_project.get('full_name') == target_lkft_project_full_name:
+ target_qareport_project = lkft_project
+ break
+
+ if target_qareport_project is None:
+ qareport_project_not_found_configs.append(lkft_build_config)
+ continue
+
+ target_qareport_build = None
+ builds = qa_report_api.get_all_builds(target_qareport_project.get('id'))
+ for build in builds:
+ if build.get('version') == db_kernelchange.describe:
+ target_qareport_build = build
+ break
+
+ if target_qareport_build is None:
+ qareport_build_not_found_configs.append(lkft_build_config)
+ continue
+
+ created_str = target_qareport_build.get('created_at')
+ target_qareport_build['created_at'] = qa_report_api.get_aware_datetime_from_str(created_str)
+ jobs = qa_report_api.get_jobs_for_build(target_qareport_build.get("id"))
+ build_status = get_lkft_build_status(target_qareport_build, jobs)
+ if build_status['has_unsubmitted']:
+ target_qareport_build['build_status'] = "JOBSNOTSUBMITTED"
+ has_jobs_not_submitted = True
+ elif build_status['is_inprogress']:
+ target_qareport_build['build_status'] = "JOBSINPROGRESS"
+ has_jobs_in_progress = True
+ else:
+ target_qareport_build['build_status'] = "JOBSCOMPLETED"
+ target_qareport_build['last_fetched_timestamp'] = build_status['last_fetched_timestamp']
+ if kernel_change_finished_timestamp is None or \
+ kernel_change_finished_timestamp < build_status['last_fetched_timestamp']:
+ kernel_change_finished_timestamp = build_status['last_fetched_timestamp']
+
+ numbers_of_result = get_test_result_number_for_build(target_qareport_build, jobs)
+ number_passed = number_passed + numbers_of_result.get('number_passed')
+ number_failed = number_failed + numbers_of_result.get('number_failed')
+ number_total = number_total + numbers_of_result.get('number_total')
+ modules_done = modules_done + numbers_of_result.get('modules_done')
+ modules_total = modules_total + numbers_of_result.get('modules_total')
+
+ has_error = False
+ error_dict = {}
+ if kernel_change_status == "CI_BUILDS_COMPLETED":
+ if qareport_project_not_found_configs or qareport_build_not_found_configs:
+ has_error = True
+ if qareport_project_not_found_configs:
+ kernel_change_status = 'HAS_QA_PROJECT_NOT_FOUND'
+ error_dict['qareport_project_not_found_configs'] = qareport_project_not_found_configs
+ if qareport_build_not_found_configs:
+ kernel_change_status = 'HAS_QA_BUILD_NOT_FOUND'
+ error_dict['qareport_build_not_found_configs'] = qareport_build_not_found_configs
+ elif has_jobs_not_submitted:
+ kernel_change_status = 'HAS_JOBS_NOT_SUBMITTED'
+ elif has_jobs_in_progress:
+ kernel_change_status = 'HAS_JOBS_IN_PROGRESS'
+ else:
+ kernel_change_status = 'ALL_COMPLETED'
+
+ kernelchange['branch'] = db_kernelchange.branch
+ kernelchange['describe'] = db_kernelchange.describe
+ kernelchange['trigger_name'] = db_kernelchange.trigger_name
+ kernelchange['trigger_number'] = db_kernelchange.trigger_number
+ kernelchange['start_timestamp'] = trigger_build['start_timestamp']
+ kernelchange['finished_timestamp'] = kernel_change_finished_timestamp
+ kernelchange['duration'] = kernelchange['finished_timestamp'] - kernelchange['start_timestamp']
+ kernelchange['status'] = kernel_change_status
+ kernelchange['number_passed'] = number_passed
+ kernelchange['number_failed'] = number_failed
+ kernelchange['number_total'] = number_total
+ kernelchange['modules_done'] = modules_done
+ kernelchange['modules_total'] = modules_total
+
+ kernelchanges.append(kernelchange)
+
+
+ return render(request, 'lkft-kernelchanges.html',
+ {
+ "kernelchanges": kernelchanges,
+ }
+ ) \ No newline at end of file