yocto-autobuilder-helper/scripts/build-perf-test-wrapper
Richard Purdie 8702fdbb72 Clarify license and copyright information
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2022-05-17 10:29:45 +01:00

8.3 KiB
Executable File

#!/usr/bin/env python3

Build performance test script wrapper

Copyright (c) 2019, Linux Foundation

SPDX-License-Identifier: GPL-2.0-only

This script is a simple wrapper around the build performance tests

import os import fcntl import errno import utils import subprocess import sys import datetime

import utils

parser = utils.ArgParser(description='Run a build performance test and process the results.')

parser.add_argument('-b', '--branch', action='store', help="Branch being tested") parser.add_argument('-R', '--repo', action='store', help="Repository name being tested") parser.add_argument('-d', '--download-dir', action='store', help="Directory to download sources into") parser.add_argument('-E', '--email-addr', action='store', help="Send an email report to this address") parser.add_argument('-P', '--push-remote', action='store', help="Push git changes to this remote repository") parser.add_argument('-r', '--results-dir', action='store', help="Where to store results artefacts") parser.add_argument('-w', '--work-dir', action='store', help="build directory to run the tests in") parser.add_argument('-p', '--publish-dir', action='store', help="directory to publish into")

args = parser.parse_args()

scriptsdir = os.path.dirname(os.path.realpath(file)) ourconfig = utils.loadconfig()

git_repo = None archive_dir = None global_results = None archiveopts = "" if args.push_remote: archiveopts += "--push " + args.push_remote if args.results_dir: archive_dir = args.results_dir + "/archive" git_repo = args.results_dir + "/archive-repo" global_results = args.results_dir

op = fcntl.LOCK_EX try: lf = open("/tmp/oe-build-perf-test-wrapper.lock", 'a+') fileno = lf.fileno() fcntl.flock(fileno, op) except OSError as e: print("Another version of the script is running") try: lf.close() except Exception: pass sys.exit(1)

hostname = os.uname()[1]

print("Running on " + hostname)

try: gitdir = subprocess.check_output("git rev-parse --show-toplevel", shell=True).decode("utf-8").strip() except subprocess.CalledProcessError: print("The current working dir doesn't seem to be a git clone. Please cd there before running " + sys.argv[0]) sys.exit(1)

os.chdir(gitdir)

Determine name of the current branch

branch = args.branch if not args.branch: branch = subprocess.check_output("git symbolic-ref HEAD 2> /dev/null", shell=True).decode("utf-8").strip() # Strip refs/heads/ branch = branch[11:]

if not args.work_dir: args.work_dir = gitdir + "/build-perf-test" if not archive_dir: archive_dir = gitdir + "/archive-results" os.makedirs(archive_dir, exist_ok=True)

Ensure we start with a clean build buil directory

subprocess.check_call("rm -rf %s/*" % args.work_dir, shell=True)

print("Using working dir " + args.work_dir)

if not args.download_dir: args.download_dir = args.work_dir + "/downloads" os.makedirs(args.download_dir, exist_ok=True)

if not global_results: global_results = args.work_dir os.makedirs(global_results, exist_ok=True)

timestamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S')

gitrev = subprocess.check_output("git rev-parse --short HEAD", shell=True).decode("utf-8").strip() gitrevfull = subprocess.check_output("git rev-parse HEAD", shell=True).decode("utf-8").strip() build_dir = args.work_dir + "/build-" + gitrev + "-" + timestamp results_tmpdir = args.work_dir + "/results-" + gitrev + "-" + timestamp globalres_log = global_results + "/globalres.log" machine = "qemux86"

os.makedirs(args.work_dir, exist_ok=True) os.makedirs(build_dir + "/conf", exist_ok=True)

copy in auto.conf

subprocess.check_call("cp -r %s/build/conf/auto.conf %s/conf" % (gitdir, build_dir), shell=True)

Run actual test script

ret = subprocess.call("BDIR=%s . ./oe-init-build-env >/dev/null; oe-build-perf-test --out-dir %s --globalres-file %s --lock-file %s/oe-build-perf.lock" % (build_dir, results_tmpdir, globalres_log, args.work_dir), shell=True)

if ret == 1: print("ERROR: oe-build-perf-test script failed!") sys.exit(1)

if ret == 2: print("ERROR: some tests failed!")

if args.publish_dir: os.makedirs(args.publish_dir, exist_ok=True) subprocess.check_call("cp -r %s/* %s" % (results_tmpdir, args.publish_dir), shell=True)

Commit results to git

if git_repo: print("\nArchiving results in " + git_repo)

os.makedirs(git_repo, exist_ok=True)
subprocess.check_call("BDIR=%s . ./oe-init-build-env >/dev/null; oe-git-archive " % build_dir + \
    "--git-dir " + git_repo + " " \
    "--branch-name '{hostname}/{branch}/{machine}' " \
    "--tag-name '{hostname}/{branch}/{machine}/{commit_count}-g{commit}/{tag_number}' " \
    "--exclude 'buildstats.json' " \
    "--notes 'buildstats/{branch_name}' " + results_tmpdir + "/buildstats.json " \
    + archiveopts + " " + results_tmpdir, shell=True)

# Generate test reports
sanitized_branch = branch.replace("/", "_")
report_txt = build_dir + "/" + hostname + "_" + sanitized_branch + "_" + machine + ".txt"
report_html = build_dir + "/" + hostname + "_" + sanitized_branch + "_" + machine + ".html"
filename = hostname + "_" + sanitized_branch + "_" + timestamp + "_" + gitrev

extraopts = " --branch %s --commit %s" % (branch, gitrevfull)
if args.repo and args.branch:
    basebranch, comparebranch = utils.getcomparisonbranch(ourconfig, args.repo, args.branch)
    if comparebranch:
        extraopts = extraopts + " --branch2 %s" % (comparebranch)
    else:
        print("No comparision branch found, comparing to master")
        extraopts = extraopts + " --branch2 master"

print("\nGenerating test report")
open(report_txt, "w").close()
if args.publish_dir:
    web_root = utils.getconfig('WEBPUBLISH_DIR', ourconfig)
    web_url = utils.getconfig('WEBPUBLISH_URL', ourconfig)
    url = args.publish_dir.replace(web_root, web_url) + "/" + filename + ".html"

    print("Report URL is %s" % url)

    with open(report_txt, "w") as f:
        f.write("HTML Report/Graphs are available at:\n    %s\n\n" % url)

subprocess.check_call("BDIR=%s . ./oe-init-build-env >/dev/null; oe-build-perf-report -r %s %s >> %s" % (build_dir, git_repo, extraopts, report_txt), shell=True)
subprocess.check_call("BDIR=%s . ./oe-init-build-env >/dev/null; oe-build-perf-report -r %s %s --html > %s " % (build_dir, git_repo, extraopts, report_html), shell=True)

subprocess.check_call("cp %s %s/%s.txt" % (report_txt, global_results, filename), shell=True)
subprocess.check_call("cp %s %s/%s.html" % (report_html, global_results, filename), shell=True)

if args.publish_dir:
    subprocess.check_call("cp %s %s/%s.txt" % (report_txt, args.publish_dir, filename), shell=True)
    subprocess.check_call("cp %s %s/%s.html" % (report_html, args.publish_dir, filename), shell=True)

# Send email report
if args.email_addr:
    print("Emailing test report")

    os_name = subprocess.check_output(". /etc/os-release; eval echo '$'PRETTY_NAME", shell=True).decode("utf-8").strip()
    cmd = scriptsdir + "/oe-build-perf-report-email.py --to '" + args.email_addr + \
          "' --subject 'Build Perf Test Report for " + os_name + "' --text " + \
          report_txt
    try:
        subprocess.check_call(cmd, shell=True)
    except subprocess.CalledProcessError:
        print("ERROR: Send email command %s failed" % cmd)

if archive_dir: print("\n\n-----------------\n") print("Archiving results in " + archive_dir) os.makedirs(archive_dir, exist_ok=True) results_basename = os.path.basename(results_tmpdir) results_dirname = os.path.dirname(results_tmpdir) cmd = "tar -czf %s/%s-%s.tar.gz -C %s %s" % (archive_dir, hostname, results_basename, results_dirname, results_basename) subprocess.check_call(cmd, shell=True)

subprocess.check_call("rm -rf %s" % build_dir, shell=True) subprocess.check_call("rm -rf %s" % results_tmpdir, shell=True) subprocess.check_call("rm -rf *", shell=True)

print("DONE")