mirror of
git://git.yoctoproject.org/poky.git
synced 2025-07-05 05:04:44 +02:00

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: f8c9c511b5f1b7dbd45b77f345cb6c048ae6763e) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
246 lines
7.8 KiB
Python
Executable File
246 lines
7.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# devtool stress tester
|
|
#
|
|
# Written by: Paul Eggleton <paul.eggleton@linux.intel.com>
|
|
#
|
|
# Copyright 2015 Intel Corporation
|
|
#
|
|
# SPDX-License-Identifier: GPL-2.0-only
|
|
#
|
|
|
|
import sys
|
|
import os
|
|
import os.path
|
|
import subprocess
|
|
import re
|
|
import argparse
|
|
import logging
|
|
import tempfile
|
|
import shutil
|
|
import signal
|
|
import fnmatch
|
|
|
|
scripts_lib_path = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'lib'))
|
|
sys.path.insert(0, scripts_lib_path)
|
|
import scriptutils
|
|
import argparse_oe
|
|
logger = scriptutils.logger_create('devtool-stress')
|
|
|
|
def select_recipes(args):
|
|
import bb.tinfoil
|
|
tinfoil = bb.tinfoil.Tinfoil()
|
|
tinfoil.prepare(False)
|
|
|
|
pkg_pn = tinfoil.cooker.recipecaches[''].pkg_pn
|
|
(latest_versions, preferred_versions) = bb.providers.findProviders(tinfoil.config_data, tinfoil.cooker.recipecaches[''], pkg_pn)
|
|
|
|
skip_classes = args.skip_classes.split(',')
|
|
|
|
recipelist = []
|
|
for pn in sorted(pkg_pn):
|
|
pref = preferred_versions[pn]
|
|
inherits = [os.path.splitext(os.path.basename(f))[0] for f in tinfoil.cooker.recipecaches[''].inherits[pref[1]]]
|
|
for cls in skip_classes:
|
|
if cls in inherits:
|
|
break
|
|
else:
|
|
recipelist.append(pn)
|
|
|
|
tinfoil.shutdown()
|
|
|
|
resume_from = args.resume_from
|
|
if resume_from:
|
|
if not resume_from in recipelist:
|
|
print('%s is not a testable recipe' % resume_from)
|
|
return 1
|
|
if args.only:
|
|
only = args.only.split(',')
|
|
for onlyitem in only:
|
|
for pn in recipelist:
|
|
if fnmatch.fnmatch(pn, onlyitem):
|
|
break
|
|
else:
|
|
print('%s does not match any testable recipe' % onlyitem)
|
|
return 1
|
|
else:
|
|
only = None
|
|
if args.skip:
|
|
skip = args.skip.split(',')
|
|
else:
|
|
skip = []
|
|
|
|
recipes = []
|
|
for pn in recipelist:
|
|
if resume_from:
|
|
if pn == resume_from:
|
|
resume_from = None
|
|
else:
|
|
continue
|
|
|
|
if args.only:
|
|
for item in only:
|
|
if fnmatch.fnmatch(pn, item):
|
|
break
|
|
else:
|
|
continue
|
|
|
|
skipit = False
|
|
for item in skip:
|
|
if fnmatch.fnmatch(pn, item):
|
|
skipit = True
|
|
if skipit:
|
|
continue
|
|
|
|
recipes.append(pn)
|
|
|
|
return recipes
|
|
|
|
|
|
def stress_extract(args):
|
|
import bb.process
|
|
|
|
recipes = select_recipes(args)
|
|
|
|
failures = 0
|
|
tmpdir = tempfile.mkdtemp()
|
|
os.setpgrp()
|
|
try:
|
|
for pn in recipes:
|
|
sys.stdout.write('Testing %s ' % (pn + ' ').ljust(40, '.'))
|
|
sys.stdout.flush()
|
|
failed = False
|
|
skipped = None
|
|
|
|
srctree = os.path.join(tmpdir, pn)
|
|
try:
|
|
bb.process.run('devtool extract %s %s' % (pn, srctree))
|
|
except bb.process.ExecutionError as exc:
|
|
if exc.exitcode == 4:
|
|
skipped = 'incompatible'
|
|
else:
|
|
failed = True
|
|
with open('stress_%s_extract.log' % pn, 'w') as f:
|
|
f.write(str(exc))
|
|
|
|
if os.path.exists(srctree):
|
|
shutil.rmtree(srctree)
|
|
|
|
if failed:
|
|
print('failed')
|
|
failures += 1
|
|
elif skipped:
|
|
print('skipped (%s)' % skipped)
|
|
else:
|
|
print('ok')
|
|
except KeyboardInterrupt:
|
|
# We want any child processes killed. This is crude, but effective.
|
|
os.killpg(0, signal.SIGTERM)
|
|
|
|
if failures:
|
|
return 1
|
|
else:
|
|
return 0
|
|
|
|
|
|
def stress_modify(args):
|
|
import bb.process
|
|
|
|
recipes = select_recipes(args)
|
|
|
|
failures = 0
|
|
tmpdir = tempfile.mkdtemp()
|
|
os.setpgrp()
|
|
try:
|
|
for pn in recipes:
|
|
sys.stdout.write('Testing %s ' % (pn + ' ').ljust(40, '.'))
|
|
sys.stdout.flush()
|
|
failed = False
|
|
reset = True
|
|
skipped = None
|
|
|
|
srctree = os.path.join(tmpdir, pn)
|
|
try:
|
|
bb.process.run('devtool modify -x %s %s' % (pn, srctree))
|
|
except bb.process.ExecutionError as exc:
|
|
if exc.exitcode == 4:
|
|
skipped = 'incompatible'
|
|
else:
|
|
with open('stress_%s_modify.log' % pn, 'w') as f:
|
|
f.write(str(exc))
|
|
failed = 'modify'
|
|
reset = False
|
|
|
|
if not skipped:
|
|
if not failed:
|
|
try:
|
|
bb.process.run('bitbake -c install %s' % pn)
|
|
except bb.process.CmdError as exc:
|
|
with open('stress_%s_install.log' % pn, 'w') as f:
|
|
f.write(str(exc))
|
|
failed = 'build'
|
|
if reset:
|
|
try:
|
|
bb.process.run('devtool reset %s' % pn)
|
|
except bb.process.CmdError as exc:
|
|
print('devtool reset failed: %s' % str(exc))
|
|
break
|
|
|
|
if os.path.exists(srctree):
|
|
shutil.rmtree(srctree)
|
|
|
|
if failed:
|
|
print('failed (%s)' % failed)
|
|
failures += 1
|
|
elif skipped:
|
|
print('skipped (%s)' % skipped)
|
|
else:
|
|
print('ok')
|
|
except KeyboardInterrupt:
|
|
# We want any child processes killed. This is crude, but effective.
|
|
os.killpg(0, signal.SIGTERM)
|
|
|
|
if failures:
|
|
return 1
|
|
else:
|
|
return 0
|
|
|
|
|
|
def main():
|
|
parser = argparse_oe.ArgumentParser(description="devtool stress tester",
|
|
epilog="Use %(prog)s <subcommand> --help to get help on a specific command")
|
|
parser.add_argument('-d', '--debug', help='Enable debug output', action='store_true')
|
|
parser.add_argument('-r', '--resume-from', help='Resume from specified recipe', metavar='PN')
|
|
parser.add_argument('-o', '--only', help='Only test specified recipes (comma-separated without spaces, wildcards allowed)', metavar='PNLIST')
|
|
parser.add_argument('-s', '--skip', help='Skip specified recipes (comma-separated without spaces, wildcards allowed)', metavar='PNLIST', default='gcc-source-*,kernel-devsrc,package-index,perf,meta-world-pkgdata,glibc-locale,glibc-mtrace,glibc-scripts,os-release')
|
|
parser.add_argument('-c', '--skip-classes', help='Skip recipes inheriting specified classes (comma-separated) - default %(default)s', metavar='CLASSLIST', default='native,nativesdk,cross,cross-canadian,image,populate_sdk,meta,packagegroup')
|
|
subparsers = parser.add_subparsers(title='subcommands', metavar='<subcommand>')
|
|
subparsers.required = True
|
|
|
|
parser_modify = subparsers.add_parser('modify',
|
|
help='Run "devtool modify" followed by a build with bitbake on matching recipes',
|
|
description='Runs "devtool modify" followed by a build with bitbake on matching recipes')
|
|
parser_modify.set_defaults(func=stress_modify)
|
|
|
|
parser_extract = subparsers.add_parser('extract',
|
|
help='Run "devtool extract" on matching recipes',
|
|
description='Runs "devtool extract" on matching recipes')
|
|
parser_extract.set_defaults(func=stress_extract)
|
|
|
|
args = parser.parse_args()
|
|
|
|
if args.debug:
|
|
logger.setLevel(logging.DEBUG)
|
|
|
|
import scriptpath
|
|
bitbakepath = scriptpath.add_bitbake_lib_path()
|
|
if not bitbakepath:
|
|
logger.error("Unable to find bitbake by searching parent directory of this script or PATH")
|
|
return 1
|
|
logger.debug('Found bitbake path: %s' % bitbakepath)
|
|
|
|
ret = args.func(args)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|