summaryrefslogtreecommitdiffstats
path: root/scripts/yocto_testresults_query.py
diff options
context:
space:
mode:
authorAlexis Lothoré <alexis.lothore@bootlin.com>2023-02-24 17:45:54 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2023-02-26 11:59:52 +0000
commit7a70dcfea7cde7b28ae3e606b338ff0a6eca0bd6 (patch)
treeda19257a2a386aea335da9be925321ecd3fdf150 /scripts/yocto_testresults_query.py
parent383cd86595c84a6b6e78bc9d15f10052d60d8193 (diff)
downloadpoky-7a70dcfea7cde7b28ae3e606b338ff0a6eca0bd6.tar.gz
scripts: add new helper for regression report generation
Add yocto-testresults-query script. This is a thin wrapper over resulttool which is able to translate tags or branch name to specific revisions, and then to work with those "guessed" revisions with resulttool (From OE-Core rev: b1460201b0f3d8fd7f977ac82f218bf9010d5573) Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts/yocto_testresults_query.py')
-rwxr-xr-xscripts/yocto_testresults_query.py106
1 files changed, 106 insertions, 0 deletions
diff --git a/scripts/yocto_testresults_query.py b/scripts/yocto_testresults_query.py
new file mode 100755
index 0000000000..3b478822dc
--- /dev/null
+++ b/scripts/yocto_testresults_query.py
@@ -0,0 +1,106 @@
1#!/usr/bin/env python3
2
3# Yocto Project test results management tool
4# This script is an thin layer over resulttool to manage tes results and regression reports.
5# Its main feature is to translate tags or branch names to revisions SHA1, and then to run resulttool
6# with those computed revisions
7#
8# Copyright (C) 2023 OpenEmbedded Contributors
9#
10# SPDX-License-Identifier: MIT
11#
12
13import sys
14import os
15import argparse
16import subprocess
17import tempfile
18import lib.scriptutils as scriptutils
19
20script_path = os.path.dirname(os.path.realpath(__file__))
21poky_path = os.path.abspath(os.path.join(script_path, ".."))
22resulttool = os.path.abspath(os.path.join(script_path, "resulttool"))
23logger = scriptutils.logger_create(sys.argv[0])
24testresults_default_url="git://git.yoctoproject.org/yocto-testresults"
25
26def create_workdir():
27 workdir = tempfile.mkdtemp(prefix='yocto-testresults-query.')
28 logger.info(f"Shallow-cloning testresults in {workdir}")
29 subprocess.check_call(["git", "clone", testresults_default_url, workdir, "--depth", "1"])
30 return workdir
31
32def get_sha1(pokydir, revision):
33 rev = subprocess.check_output(["git", "rev-list", "-n", "1", revision], cwd=pokydir).decode('utf-8').strip()
34 logger.info(f"SHA-1 revision for {revision} in {pokydir} is {rev}")
35 return rev
36
37def fetch_testresults(workdir, sha1):
38 logger.info(f"Fetching test results for {sha1} in {workdir}")
39 rawtags = subprocess.check_output(["git", "ls-remote", "--refs", "--tags", "origin", f"*{sha1}*"], cwd=workdir).decode('utf-8').strip()
40 if not rawtags:
41 raise Exception(f"No reference found for commit {sha1} in {workdir}")
42 for rev in [rawtag.split()[1] for rawtag in rawtags.splitlines()]:
43 logger.info(f"Fetching matching revisions: {rev}")
44 subprocess.check_call(["git", "fetch", "--depth", "1", "origin", f"{rev}:{rev}"], cwd=workdir)
45
46def compute_regression_report(workdir, baserevision, targetrevision):
47 logger.info(f"Running resulttool regression between SHA1 {baserevision} and {targetrevision}")
48 report = subprocess.check_output([resulttool, "regression-git", "--commit", baserevision, "--commit2", targetrevision, workdir]).decode("utf-8")
49 return report
50
51def print_report_with_header(report, baseversion, baserevision, targetversion, targetrevision):
52 print("========================== Regression report ==============================")
53 print(f'{"=> Target:": <16}{targetversion: <16}({targetrevision})')
54 print(f'{"=> Base:": <16}{baseversion: <16}({baserevision})')
55 print("===========================================================================\n")
56 print(report, end='')
57
58def regression(args):
59 logger.info(f"Compute regression report between {args.base} and {args.target}")
60 if args.testresultsdir:
61 workdir = args.testresultsdir
62 else:
63 workdir = create_workdir()
64
65 try:
66 baserevision = get_sha1(poky_path, args.base)
67 targetrevision = get_sha1(poky_path, args.target)
68 fetch_testresults(workdir, baserevision)
69 fetch_testresults(workdir, targetrevision)
70 report = compute_regression_report(workdir, baserevision, targetrevision)
71 print_report_with_header(report, args.base, baserevision, args.target, targetrevision)
72 finally:
73 if not args.testresultsdir:
74 subprocess.check_call(["rm", "-rf", workdir])
75
76def main():
77 parser = argparse.ArgumentParser(description="Yocto Project test results helper")
78 subparsers = parser.add_subparsers(
79 help="Supported commands for test results helper",
80 required=True)
81 parser_regression_report = subparsers.add_parser(
82 "regression-report",
83 help="Generate regression report between two fixed revisions. Revisions can be branch name or tag")
84 parser_regression_report.add_argument(
85 'base',
86 help="Revision or tag against which to compare results (i.e: the older)")
87 parser_regression_report.add_argument(
88 'target',
89 help="Revision or tag to compare against the base (i.e: the newer)")
90 parser_regression_report.add_argument(
91 '-t',
92 '--testresultsdir',
93 help=f"An existing test results directory. {sys.argv[0]} will automatically clone it and use default branch if not provided")
94 parser_regression_report.set_defaults(func=regression)
95
96 args = parser.parse_args()
97 args.func(args)
98
99if __name__ == '__main__':
100 try:
101 ret = main()
102 except Exception:
103 ret = 1
104 import traceback
105 traceback.print_exc()
106 sys.exit(ret)