
This adds SPDX license headers in place of the wide assortment of things currently in our script headers. We default to GPL-2.0-only except for the oeqa code where it was clearly submitted and marked as MIT on the most part or some scripts which had the "or later" GPL versioning. The patch also drops other obsolete bits of file headers where they were encoountered such as editor modelines, obsolete maintainer information or the phrase "All rights reserved" which is now obsolete and not required in copyright headers (in this case its actually confusing for licensing as all rights were not reserved). More work is needed for OE-Core but this takes care of the bulk of the scripts and meta/lib directories. The top level LICENSE files are tweaked to match the new structure and the SPDX naming. (From OE-Core rev: 3248a9e3c5a197321b1c4417509b9309cc3bae97) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster808@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
6.9 KiB
Executable File
#!/usr/bin/python3
Build performance test script
Copyright (c) 2016, Intel Corporation.
SPDX-License-Identifier: GPL-2.0-only
import argparse import errno import fcntl import json import logging import os import re import shutil import sys from datetime import datetime
sys.path.insert(0, os.path.dirname(os.path.realpath(file)) + '/lib') import scriptpath scriptpath.add_oe_lib_path() scriptpath.add_bitbake_lib_path() import oeqa.buildperf from oeqa.buildperf import (BuildPerfTestLoader, BuildPerfTestResult, BuildPerfTestRunner, KernelDropCaches) from oeqa.utils.commands import runCmd from oeqa.utils.metadata import metadata_from_bb, write_metadata_file
Set-up logging
LOG_FORMAT = '[%(asctime)s] %(levelname)s: %(message)s' logging.basicConfig(level=logging.INFO, format=LOG_FORMAT, datefmt='%Y-%m-%d %H:%M:%S') log = logging.getLogger()
def acquire_lock(lock_f): """Acquire flock on file""" log.debug("Acquiring lock %s", os.path.abspath(lock_f.name)) try: fcntl.flock(lock_f, fcntl.LOCK_EX | fcntl.LOCK_NB) except IOError as err: if err.errno == errno.EAGAIN: return False raise log.debug("Lock acquired") return True
def pre_run_sanity_check(): """Sanity check of build environment""" build_dir = os.environ.get("BUILDDIR") if not build_dir: log.error("BUILDDIR not set. Please run the build environmnent setup " "script.") return False if os.getcwd() != build_dir: log.error("Please run this script under BUILDDIR (%s)", build_dir) return False
ret = runCmd('which bitbake', ignore_status=True)
if ret.status:
log.error("bitbake command not found")
return False
return True
def setup_file_logging(log_file): """Setup loggin to file""" log_dir = os.path.dirname(log_file) if not os.path.exists(log_dir): os.makedirs(log_dir) formatter = logging.Formatter(LOG_FORMAT) handler = logging.FileHandler(log_file) handler.setFormatter(formatter) log.addHandler(handler)
def archive_build_conf(out_dir): """Archive build/conf to test results""" src_dir = os.path.join(os.environ['BUILDDIR'], 'conf') tgt_dir = os.path.join(out_dir, 'build', 'conf') os.makedirs(os.path.dirname(tgt_dir)) shutil.copytree(src_dir, tgt_dir)
def update_globalres_file(result_obj, filename, metadata): """Write results to globalres csv file""" # Map test names to time and size columns in globalres # The tuples represent index and length of times and sizes # respectively gr_map = {'test1': ((0, 1), (8, 1)), 'test12': ((1, 1), (None, None)), 'test13': ((2, 1), (9, 1)), 'test2': ((3, 1), (None, None)), 'test3': ((4, 3), (None, None)), 'test4': ((7, 1), (10, 2))}
values = ['0'] * 12
for status, test, _ in result_obj.all_results():
if status in ['ERROR', 'SKIPPED']:
continue
(t_ind, t_len), (s_ind, s_len) = gr_map[test.name]
if t_ind is not None:
values[t_ind:t_ind + t_len] = test.times
if s_ind is not None:
values[s_ind:s_ind + s_len] = test.sizes
log.debug("Writing globalres log to %s", filename)
rev_info = metadata['layers']['meta']
with open(filename, 'a') as fobj:
fobj.write('{},{}:{},{},'.format(metadata['hostname'],
rev_info['branch'],
rev_info['commit'],
rev_info['commit']))
fobj.write(','.join(values) + '\n')
def parse_args(argv): """Parse command line arguments""" parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-D', '--debug', action='store_true',
help='Enable debug level logging')
parser.add_argument('--globalres-file',
type=os.path.abspath,
help="Append results to 'globalres' csv file")
parser.add_argument('--lock-file', default='./oe-build-perf.lock',
metavar='FILENAME', type=os.path.abspath,
help="Lock file to use")
parser.add_argument('-o', '--out-dir', default='results-{date}',
type=os.path.abspath,
help="Output directory for test results")
parser.add_argument('-x', '--xml', action='store_true',
help='Enable JUnit xml output')
parser.add_argument('--log-file',
default='{out_dir}/oe-build-perf-test.log',
help="Log file of this script")
parser.add_argument('--run-tests', nargs='+', metavar='TEST',
help="List of tests to run")
return parser.parse_args(argv)
def main(argv=None): """Script entry point""" args = parse_args(argv)
# Set-up log file
out_dir = args.out_dir.format(date=datetime.now().strftime('%Y%m%d%H%M%S'))
setup_file_logging(args.log_file.format(out_dir=out_dir))
if args.debug:
log.setLevel(logging.DEBUG)
lock_f = open(args.lock_file, 'w')
if not acquire_lock(lock_f):
log.error("Another instance of this script is running, exiting...")
return 1
if not pre_run_sanity_check():
return 1
# Check our capability to drop caches and ask pass if needed
KernelDropCaches.check()
# Load build perf tests
loader = BuildPerfTestLoader()
if args.run_tests:
suite = loader.loadTestsFromNames(args.run_tests, oeqa.buildperf)
else:
suite = loader.loadTestsFromModule(oeqa.buildperf)
# Save test metadata
metadata = metadata_from_bb()
log.info("Testing Git revision branch:commit %s:%s (%s)",
metadata['layers']['meta']['branch'],
metadata['layers']['meta']['commit'],
metadata['layers']['meta']['commit_count'])
if args.xml:
write_metadata_file(os.path.join(out_dir, 'metadata.xml'), metadata)
else:
with open(os.path.join(out_dir, 'metadata.json'), 'w') as fobj:
json.dump(metadata, fobj, indent=2)
archive_build_conf(out_dir)
runner = BuildPerfTestRunner(out_dir, verbosity=2)
# Suppress logger output to stderr so that the output from unittest
# is not mixed with occasional logger output
log.handlers[0].setLevel(logging.CRITICAL)
# Run actual tests
result = runner.run(suite)
# Restore logger output to stderr
log.handlers[0].setLevel(log.level)
if args.xml:
result.write_results_xml()
else:
result.write_results_json()
result.write_buildstats_json()
if args.globalres_file:
update_globalres_file(result, args.globalres_file, metadata)
if result.wasSuccessful():
return 0
return 2
if name == 'main': sys.exit(main())