Skip to content

Commit 3c5ac24

Browse files
author
Jeny Sadadia
committed
Implement results issues command
`kci-dev results issues` command utilities: - Fetch KCIDB issues from the dashboard - Get new issues for checkout with `--new` option - Get failed/inconclusive builds and boots without any associated issues with `--missing` option Signed-off-by: Jeny Sadadia <[email protected]>
1 parent 0b39858 commit 3c5ac24

File tree

3 files changed

+244
-9
lines changed

3 files changed

+244
-9
lines changed

kcidev/libs/dashboard.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -285,23 +285,24 @@ def dashboard_fetch_hardware_tests(name, origin, use_json):
285285
)
286286

287287

288-
def dashboard_fetch_build_issues(build_id, use_json):
288+
def dashboard_fetch_build_issues(build_id, use_json, error_verbose):
289289
endpoint = f"build/{build_id}/issues"
290290
logging.info(f"Fetching build issues for build ID: {build_id}")
291-
return dashboard_api_fetch(endpoint, {}, use_json)
291+
return dashboard_api_fetch(endpoint, {}, use_json, error_verbose=error_verbose)
292292

293293

294-
def dashboard_fetch_boot_issues(test_id, use_json):
294+
def dashboard_fetch_boot_issues(test_id, use_json, error_verbose):
295295
endpoint = f"test/{test_id}/issues"
296296
logging.info(f"Fetching test issues for test ID: {test_id}")
297-
return dashboard_api_fetch(endpoint, {}, use_json)
297+
return dashboard_api_fetch(endpoint, {}, use_json, error_verbose=error_verbose)
298298

299299

300300
def dashboard_fetch_issue_list(origin, days, use_json):
301301
params = {
302-
"filter_origin": origin,
303302
"interval_in_days": days,
304303
}
304+
if origin:
305+
params["filter_origin"] = origin
305306
logging.info(f"Fetching issue list for origin: {origin}")
306307
return dashboard_api_fetch("issue/", params, use_json)
307308

kcidev/subcommands/results/__init__.py

Lines changed: 215 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import click
77
from tabulate import tabulate
88

9-
from kcidev.libs.common import kci_msg, kci_msg_green, kci_msg_red
9+
from kcidev.libs.common import kci_msg, kci_msg_bold, kci_msg_green, kci_msg_red
1010
from kcidev.libs.dashboard import (
1111
dashboard_fetch_boot_issues,
1212
dashboard_fetch_boots,
@@ -16,6 +16,7 @@
1616
dashboard_fetch_commits_history,
1717
dashboard_fetch_issue,
1818
dashboard_fetch_issue_builds,
19+
dashboard_fetch_issue_list,
1920
dashboard_fetch_issue_tests,
2021
dashboard_fetch_issues_extra,
2122
dashboard_fetch_summary,
@@ -40,6 +41,7 @@
4041
cmd_summary,
4142
cmd_tests,
4243
print_issues,
44+
print_missing_data,
4345
)
4446

4547

@@ -475,6 +477,7 @@ def print_stats(data, headers, max_col_width, table_fmt):
475477
def get_new_issues(origin, tree_name, giturl, branch, commit, arch):
476478
"""Get new KCIDB issue for a checkout"""
477479
try:
480+
kci_msg_bold(f"{tree_name}/{branch}:{commit}")
478481
data = dashboard_fetch_summary(origin, giturl, branch, commit, arch, True)
479482
tree_summary = data["summary"]
480483
items = ["builds", "boots", "tests"]
@@ -484,7 +487,7 @@ def get_new_issues(origin, tree_name, giturl, branch, commit, arch):
484487
for i in tree_summary[item]["issues"]:
485488
all_issues.append([i["id"], i["version"]])
486489
if not all_issues:
487-
kci_msg_red(f"{tree_name}/{branch}:{commit} No issues found")
490+
kci_msg("No issues found")
488491
return
489492
issue_extras = dashboard_fetch_issues_extra(all_issues, True)["issues"]
490493
for issue_id, extras in issue_extras.items():
@@ -499,9 +502,10 @@ def get_new_issues(origin, tree_name, giturl, branch, commit, arch):
499502
):
500503
new_issues.append(issue_id)
501504
if not new_issues:
502-
kci_msg_red(f"{tree_name}/{branch}:{commit} No new issues found")
505+
kci_msg("No new issues found")
503506
else:
504-
kci_msg_green(f"{tree_name}/{branch}:{commit} New issues: {new_issues}")
507+
for issue in new_issues:
508+
kci_msg(f"- {issue}")
505509
except click.ClickException as e:
506510
print("Exception:", e.message)
507511

@@ -681,6 +685,213 @@ def detect(
681685
print_stats(stats, headers, max_col_width, table_fmt)
682686

683687

688+
def get_missing_issue_items(
689+
ctx, origin, item_type, giturl, branch, commit, tree_name, arch
690+
):
691+
"""Get information of failed or inconclusive builds/boots for which KCIDB
692+
issues don't exist"""
693+
try:
694+
if item_type == "builds":
695+
results_cmd = builds
696+
dashboard_func = dashboard_fetch_build_issues
697+
elif item_type == "boots":
698+
results_cmd = boots
699+
dashboard_func = dashboard_fetch_boot_issues
700+
else:
701+
kci_msg_red("Please specify 'builds' or 'boots' as items type")
702+
return []
703+
704+
dashboard_items = ctx.invoke(
705+
results_cmd,
706+
origin=origin,
707+
giturl=giturl,
708+
branch=branch,
709+
commit=commit,
710+
status="all",
711+
count=True,
712+
verbose=False,
713+
arch=arch,
714+
)
715+
716+
missing_ids = []
717+
for item in dashboard_items:
718+
# Exclude passed builds/boots
719+
if item["status"] == "PASS":
720+
continue
721+
item_id = item["id"]
722+
try:
723+
_ = dashboard_func(item_id, False, error_verbose=False)
724+
except click.ClickException as e:
725+
if "No issues" in e.message:
726+
missing_ids.append(item_id)
727+
if missing_ids:
728+
return [f"{tree_name}/{branch}", commit, missing_ids]
729+
return []
730+
except click.Abort:
731+
kci_msg_red(
732+
f"{tree_name}/{branch}: Aborted while fetching dashboard builds/boots"
733+
)
734+
return []
735+
except click.ClickException as e:
736+
kci_msg_red(f"{tree_name}/{branch}: {e.message}")
737+
return []
738+
739+
740+
@results.command(
741+
name="issues",
742+
help="""Fetch KCIDB issues from the dashboard
743+
744+
\b
745+
Examples:
746+
# Get issues
747+
kci-dev results issues --origin <origin> --days <number-of-days>
748+
# Get new issues for all checkouts
749+
kci-dev issues --new --days <number-of-days> --origin <origin>
750+
# Get new issues for a checkout
751+
kci-dev issues --new --giturl <git-url> --branch <git-branch> --commit <commit> --origin <origin>
752+
# Get failed or inconclusive builds and boots without any issue for all checkouts
753+
kci-dev issues --missing
754+
# Get failed or inconclusive builds and boots without any issue for specific checkout
755+
kci-dev issues --missing --giturl <git-url> --branch <git-branch> --commit <commit> --origin <origin>
756+
# Get failed/inconclusive builds without issues
757+
kci-dev issues --missing --builds
758+
# Get failed/inconclusive boots without issues
759+
kci-dev issues --missing --boots
760+
""",
761+
)
762+
@click.option(
763+
"--origin",
764+
help="Select KCIDB origin",
765+
default="maestro",
766+
)
767+
@click.option(
768+
"--days",
769+
help="Provide a period of time in days to get results for",
770+
type=int,
771+
default="5",
772+
)
773+
@click.option(
774+
"--new",
775+
is_flag=True,
776+
help="Fetch new KCIDB issues for a checkout",
777+
)
778+
@click.option(
779+
"--giturl",
780+
help="Git URL of kernel tree",
781+
)
782+
@click.option(
783+
"--branch",
784+
help="Branch to get results for",
785+
)
786+
@click.option(
787+
"--commit",
788+
help="Commit or tag to get results for",
789+
)
790+
@click.option(
791+
"--git-folder",
792+
help="Path of git repository folder",
793+
type=click.Path(exists=True, file_okay=False, dir_okay=True),
794+
)
795+
@click.option(
796+
"--latest",
797+
is_flag=True,
798+
help="Select latest results available",
799+
)
800+
@click.option(
801+
"--missing",
802+
is_flag=True,
803+
help="List all failed/incomplete builds and boots without any issue associated to them",
804+
)
805+
@click.option(
806+
"--builds",
807+
is_flag=True,
808+
help="The option can be used along with '--missing' to list only builds",
809+
)
810+
@click.option(
811+
"--boots",
812+
is_flag=True,
813+
help="The option can be used along with '--missing' to list only boots",
814+
)
815+
@click.option("--arch", help="Filter by arch")
816+
@click.pass_context
817+
@results_display_options
818+
def issues(
819+
ctx,
820+
origin,
821+
days,
822+
new,
823+
giturl,
824+
branch,
825+
commit,
826+
use_json,
827+
latest,
828+
git_folder,
829+
arch,
830+
missing,
831+
builds,
832+
boots,
833+
):
834+
"""Issues command handler"""
835+
if not new and not missing:
836+
data = dashboard_fetch_issue_list(origin, days, use_json)
837+
print_issues(data["issues"], use_json)
838+
if new:
839+
if not all([giturl, branch, commit]):
840+
kci_msg("Fetching new issues for all checkouts...")
841+
trees_list = ctx.invoke(trees, origin=origin, days=days, verbose=False)
842+
for tree in trees_list:
843+
giturl = tree["git_repository_url"]
844+
branch = tree["git_repository_branch"]
845+
commit = tree["git_commit_hash"]
846+
tree_name = tree["tree_name"]
847+
get_new_issues(origin, tree_name, giturl, branch, commit, arch)
848+
return
849+
kci_msg("Fetching new issues for the checkout...")
850+
giturl, branch, commit = set_giturl_branch_commit(
851+
origin, giturl, branch, commit, latest, git_folder
852+
)
853+
tree_name = get_tree_name(origin, giturl, branch)
854+
get_new_issues(origin, tree_name, giturl, branch, commit, arch)
855+
if missing:
856+
if builds:
857+
item_types = ["builds"]
858+
elif boots:
859+
item_types = ["boots"]
860+
else:
861+
item_types = ["builds", "boots"]
862+
863+
if all([giturl, branch, commit]):
864+
tree_name = get_tree_name(origin, giturl, branch)
865+
for item_type in item_types:
866+
final_stats = []
867+
kci_msg_green(f"Fetching data for {item_type}...")
868+
stats = get_missing_issue_items(
869+
ctx, origin, item_type, giturl, branch, commit, tree_name, arch
870+
)
871+
if stats:
872+
final_stats.append(stats)
873+
if final_stats:
874+
print_missing_data(final_stats)
875+
876+
else:
877+
trees_list = ctx.invoke(trees, origin=origin, days=days, verbose=False)
878+
for item_type in item_types:
879+
kci_msg_green(f"Fetching data for {item_type}...")
880+
final_stats = []
881+
for tree in trees_list:
882+
giturl = tree["git_repository_url"]
883+
branch = tree["git_repository_branch"]
884+
commit = tree["git_commit_hash"]
885+
tree_name = tree["tree_name"]
886+
stats = get_missing_issue_items(
887+
ctx, origin, item_type, giturl, branch, commit, tree_name, arch
888+
)
889+
if stats:
890+
final_stats.append(stats)
891+
if final_stats:
892+
print_missing_data(final_stats)
893+
894+
684895
@results.command(
685896
name="issue",
686897
help="""Fetch KCIDB issue matching provided ID.

kcidev/subcommands/results/parser.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -969,3 +969,26 @@ def print_issues(issues, use_json):
969969
kci_msg(issue["categories"])
970970

971971
kci_msg("")
972+
973+
974+
def print_missing_data(data):
975+
"""Print builds/tests for which KCIDB issues are missing"""
976+
from collections import defaultdict
977+
978+
tree_groups = defaultdict(list)
979+
980+
for row in data:
981+
try:
982+
tree_branch = row[0]
983+
commit = row[1]
984+
missing_ids = row[2]
985+
except IndexError:
986+
kci_msg_red("Failed to extract data for list view")
987+
continue
988+
tree_groups[tree_branch].append({"commit": commit, "missing_ids": missing_ids})
989+
for tree_branch, commits in tree_groups.items():
990+
kci_msg_bold(f"{tree_branch}: ")
991+
for commit in commits:
992+
kci_msg(f" - Commit:{commit['commit']}")
993+
for id in missing_ids:
994+
kci_msg(f" {id}")

0 commit comments

Comments
 (0)