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]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to