diff --git a/docs/results.md b/docs/results.md index 71f44a4..81f23bc 100644 --- a/docs/results.md +++ b/docs/results.md @@ -92,6 +92,16 @@ Example: kci-dev results hardware list --origin maestro --json ``` +#### summary + +Gives a summary on the builds, boots and tests run of the hardware with `name` for the last seven days + +Example: + +```sh +kci-dev results hardware summary --name mediatek,mt8195 --origin maestro --json +``` + ## Common parameters ### --origin diff --git a/kcidev/libs/dashboard.py b/kcidev/libs/dashboard.py index 0cf815a..cd500bd 100644 --- a/kcidev/libs/dashboard.py +++ b/kcidev/libs/dashboard.py @@ -1,5 +1,7 @@ +import json import urllib from datetime import datetime, timedelta +from functools import wraps import requests @@ -8,43 +10,56 @@ DASHBOARD_API = "https://dashboard.kernelci.org/api/" -def dashboard_api_fetch(endpoint, params, use_json, max_retries=3): - base_url = urllib.parse.urljoin(DASHBOARD_API, endpoint) - url = "{}?{}".format(base_url, urllib.parse.urlencode(params)) - retries = 0 - - # Status codes that should trigger a retry - RETRY_STATUS_CODES = [429, 500, 502, 503, 504, 507] - - while retries <= max_retries: - try: - r = requests.get(url) - - if r.status_code in RETRY_STATUS_CODES: - retries += 1 - if retries <= max_retries: - continue - else: - kci_err(f"Failed after {max_retries} retries with 500 error.") +def _dashboard_request(func): + @wraps(func) + def wrapper(endpoint, params, use_json, body=None, max_retries=3): + base_url = urllib.parse.urljoin(DASHBOARD_API, endpoint) + url = "{}?{}".format(base_url, urllib.parse.urlencode(params)) + retries = 0 + + # Status codes that should trigger a retry + RETRY_STATUS_CODES = [429, 500, 502, 503, 504, 507] + + while retries <= max_retries: + try: + r = func(url, params, use_json, body) + if r.status_code in RETRY_STATUS_CODES: + retries += 1 + if retries <= max_retries: + continue + else: + kci_err(f"Failed after {max_retries} retries with 500 error.") + raise click.Abort() + + r.raise_for_status() + + data = r.json() + if "error" in data: + if use_json: + kci_msg(data) + else: + kci_msg("json error: " + str(data["error"])) raise click.Abort() + return data - r.raise_for_status() - - data = r.json() - if "error" in data: - if use_json: - kci_msg(data) - else: - kci_msg("json error: " + str(data["error"])) + except requests.exceptions.RequestException as e: + kci_err(f"Failed to fetch from {DASHBOARD_API}: {str(e)}.") raise click.Abort() - return data - except requests.exceptions.RequestException as e: - kci_err(f"Failed to fetch from {DASHBOARD_API}: {str(e)}.") - raise click.Abort() + kci_err("Unexpected failure in API request") + raise click.Abort() + + return wrapper + - kci_err("Unexpected failure in API request") - raise click.Abort() +@_dashboard_request +def dashboard_api_post(endpoint, params, use_json, body, max_retries=3): + return requests.post(endpoint, json=body) + + +@_dashboard_request +def dashboard_api_fetch(endpoint, params, use_json, max_retries=3): + return requests.get(endpoint) def dashboard_fetch_summary(origin, giturl, branch, commit, arch, use_json): @@ -122,3 +137,19 @@ def dashboard_fetch_hardware_list(origin, use_json): "startTimestampInSeconds": int(last_week.timestamp()), } return dashboard_api_fetch("hardware/", params, use_json) + + +def dashboard_fetch_hardware_summary(name, origin, use_json): + # TODO: add extra filters: Commits, date, filter, origin + now = datetime.today() + last_week = now - timedelta(days=7) + body = { + "origin": origin, + "endTimestampInSeconds": str(int(now.timestamp())), + "startTimestampInSeconds": str(int(last_week.timestamp())), + "selectedCommits": {}, + "filter": {}, + } + return dashboard_api_post( + f"hardware/{urllib.parse.quote_plus(name)}/summary", {}, use_json, body + ) diff --git a/kcidev/subcommands/results/hardware.py b/kcidev/subcommands/results/hardware.py index c5e9743..7e83a96 100644 --- a/kcidev/subcommands/results/hardware.py +++ b/kcidev/subcommands/results/hardware.py @@ -1,7 +1,10 @@ import click -from libs.dashboard import dashboard_fetch_hardware_list +from libs.dashboard import ( + dashboard_fetch_hardware_list, + dashboard_fetch_hardware_summary, +) from subcommands.results.options import results_display_options -from subcommands.results.parser import cmd_hardware_list +from subcommands.results.parser import cmd_hardware_list, cmd_summary @click.group(chain=True, help="Get hardware related information from the dashboard") @@ -16,3 +19,12 @@ def hardware(): def list(origin, use_json): data = dashboard_fetch_hardware_list(origin, use_json) cmd_hardware_list(data, use_json) + + +@hardware.command() +@click.option("--name", required=True, help="Name of the hardware") +@click.option("--origin", default="maestro", help="Select KCIDB origin") +@results_display_options +def summary(name, origin, use_json): + data = dashboard_fetch_hardware_summary(name, origin, use_json) + cmd_summary(data, use_json)