This looks alright, but it really does need tests, in meta/lib/oeqa/selftest/cases/devtool.py
Alex On Thu, 8 Jan 2026 at 00:12, Tom Geelen <[email protected]> wrote: > > Based of a feature of AUH this is a plugin to run a testimage directly with > one packages installed that you are working on via devtool. > > Inputs would be a: > - target image > - target packages > > The tool will take care to make sure it also installs the minimal necessary > dependencies to be able to run ptest on the target image. > Logs will be captured and stored in the devtool workspace for easy access. > > Minimal example to test: > - modify a package via devtool > - call this new method with said package and for instance core-image-minimal > > Signed-off-by: Tom Geelen <[email protected]> > --- > scripts/lib/devtool/testimage.py | 122 +++++++++++++++++++++++++++++++ > 1 file changed, 122 insertions(+) > create mode 100644 scripts/lib/devtool/testimage.py > > diff --git a/scripts/lib/devtool/testimage.py > b/scripts/lib/devtool/testimage.py > new file mode 100644 > index 0000000000..809bd4bfb2 > --- /dev/null > +++ b/scripts/lib/devtool/testimage.py > @@ -0,0 +1,122 @@ > +# Development tool - test-image plugin > +# > +# Copyright (C) 2026 Authors > +# > +# SPDX-License-Identifier: GPL-2.0-only > + > +"""Devtool plugin containing the test-image subcommand. > + > +Builds a target image, installs specified package(s) from the workspace or > +layer, and runs the image's test suite via the BitBake `testimage` task. > +""" > + > +import os > +import logging > + > +from devtool import setup_tinfoil, parse_recipe, DevtoolError > +from devtool.build_image import build_image_task > + > +logger = logging.getLogger('devtool') > + > + > +def _collect_install_packages(tinfoil, config, package_names): > + """Return list of packages to install, including -ptest when available. > + > + package_names: list of PN values (typically recipe names). > + """ > + install = [] > + for pn in package_names: > + rd = parse_recipe(config, tinfoil, pn, True) > + if not rd: > + # parse_recipe already logs errors > + raise DevtoolError(f'Unable to find or parse recipe for package > {pn}') > + > + install.append(pn) > + packages_var = rd.getVar('PACKAGES') or '' > + packages = packages_var.split() > + ptest_pkg = f'{pn}-ptest' > + if ptest_pkg in packages: > + install.append(ptest_pkg) > + logger.info('Including ptest package %s', ptest_pkg) > + else: > + logger.debug('No ptest package found for %s', pn) > + return install > + > + > +def test_image(args, config, basepath, workspace): > + """Entry point for the devtool 'test-image' subcommand.""" > + > + if not args.imagename: > + raise DevtoolError('Image recipe to test must be specified') > + if not args.package: > + raise DevtoolError('Package(s) to install must be specified via > -p/--package') > + > + package_names = [p.strip() for p in args.package.split(',') if p.strip()] > + if not package_names: > + raise DevtoolError('No valid package name(s) provided') > + > + # Prepare a bbappend with IMAGE_INSTALL and testimage variables > + tinfoil = setup_tinfoil(basepath=basepath) > + try: > + install_pkgs = _collect_install_packages(tinfoil, config, > package_names) > + finally: > + tinfoil.shutdown() > + > + logdir = os.path.join(config.workspace_path, 'testimage-logs') > + try: > + os.makedirs(logdir, exist_ok=True) > + except Exception as exc: > + raise DevtoolError(f'Failed to create test logs directory {logdir}: > {exc}') > + > + pkg_append = ' '.join(sorted(set(install_pkgs))) > + extra_append = [ > + f'TEST_LOG_DIR = "{logdir}"', > + # Ensure changes to these vars retrigger testimage and are visible > + 'TESTIMAGE_UPDATE_VARS:append = " TEST_LOG_DIR IMAGE_CLASSES > TEST_SUITES DISTRO_FEATURES"', > + # Ensure runtime test framework is enabled even if image/distro > omitted it > + 'IMAGE_CLASSES:append = " testimage"', > + 'TEST_SUITES = "ping ssh ptest"', > + 'DISTRO_FEATURES:append = " ptest"', > + 'TEST_RUNQEMUPARAMS = "slirp"', > + # Ensure requested packages (and -ptest where available) are > installed > + f'IMAGE_INSTALL:append = " {pkg_append}"', > + ] > + > + logger.info('Building and testing image %s with packages: %s', > + args.imagename, ' '.join(install_pkgs)) > + > + # Reuse build_image_task to run -c testimage with our bbappend > + result, _outputdir = build_image_task( > + config, > + basepath, > + workspace, > + args.imagename, > + add_packages=install_pkgs, > + task='testimage', > + extra_append=extra_append, > + ) > + > + if result == 0: > + logger.info('Testimage completed. Logs are in %s', logdir) > + return result > + > + > +def register_commands(subparsers, context): > + """Register devtool subcommands from the test-image plugin""" > + parser = subparsers.add_parser( > + 'test-image', > + help='Build image, install package(s), and run testimage', > + description=( > + 'Builds an image, installs specified package(s), and runs the\n' > + 'BitBake testimage task to validate on-target functionality.' > + ), > + group='testbuild', > + order=-9, > + ) > + parser.add_argument('imagename', help='Image recipe to test') > + parser.add_argument( > + '-p', '--package', '--packages', > + help='Package(s) to install into the image (comma-separated)', > + metavar='PACKAGES', > + ) > + parser.set_defaults(func=test_image) > -- > 2.43.0 >
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#229059): https://lists.openembedded.org/g/openembedded-core/message/229059 Mute This Topic: https://lists.openembedded.org/mt/117144059/21656 Group Owner: [email protected] Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
