yocto-autobuilder-helper/scripts/build-perf-test-wrapper
Richard Purdie 5e62bc3f9c build-perf-test-wrapper: Fix missing module reference
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2019-02-09 21:18:03 +00:00

244 lines
9.1 KiB
Python
Executable File

#!/usr/bin/env python3
#
# Build performance test script wrapper
#
# Copyright (c) 2019, Linux Foundation
#
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
# version 2, as published by the Free Software Foundation.
#
# This program is distributed in the hope it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# 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
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
if args.email_addr:
try:
subprocess.check_output(["which", "phantomjs"])
except subprocess.CalledProcessError:
print("Please install phantomjs to email reports")
sys.exit(1)
try:
subprocess.check_output(["which", "optipng"])
except subprocess.CalledProcessError:
print("Please install optipng to email reports")
sys.exit(1)
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)
os.makedirs(args.work_dir + "/conf", exist_ok=True)
# copy in auto.conf
subprocess.check_call("cp -r %s/build/conf/auto.conf %s/conf" % (gitdir, 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()
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)
# 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)
#
# Figure out which branch we might need to compare against
#
def getcomparisionbranch(ourconfig, reponame, branchname):
base = None
basebranch = None
if (reponame + ":" + branchname) in utils.getconfig("BUILD_HISTORY_FORKPUSH", ourconfig):
base = utils.getconfig("BUILD_HISTORY_FORKPUSH", ourconfig)[reponame + ":" + branchname]
if base:
baserepo, basebranch = base.split(":")
return basebranch
# 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, gitrev)
comparebranch = getcomparisionbranch(ourconfig, args.repo, args.branch)
if comparebranch:
extraopts = " --branch %s --branch2 %s --commit %s" % (comparebranch, branch, gitrev)
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"
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 + " --html " + report_html
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)
print("DONE")