All of lore.kernel.org
 help / color / mirror / Atom feed
From: michael.opdenacker@bootlin.com
To: openembedded-core@lists.openembedded.org
Cc: Michael Opdenacker <michael.opdenacker@bootlin.com>,
	Richard Purdie <richard.purdie@linuxfoundation.org>,
	Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
	Bruce Ashfield <bruce.ashfield@gmail.com>
Subject: [RFC][PATCH] oeqa/runtime/cases: new image_upgrade test
Date: Thu, 25 Apr 2024 17:46:07 +0200	[thread overview]
Message-ID: <20240425154607.566716-1-michael.opdenacker@bootlin.com> (raw)

From: Michael Opdenacker <michael.opdenacker@bootlin.com>

New oe-selftest and associated "testimage" test to check that generated
package feeds can be used to update the latest image built
by the Yocto Project autobuilder.

Currently, only the "core-image-full-cmdline" image with IPK packages
and the "poky-altcfg" distro is supported.

Test it by running:
oe-selftest -r image_upgrade

Signed-off-by: Michael Opdenacker <michael.opdenacker@bootlin.com>
Suggested-by: Richard Purdie <richard.purdie@linuxfoundation.org>
CC: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
CC: Bruce Ashfield <bruce.ashfield@gmail.com>

---
Tested on the latest master against yocto-5.0_M3

Interested in your feedback about which settings (such as IMAGE)
can be hardcoded in the scripts or provided by the calling environment.
---
 .../lib/oeqa/runtime/cases/opkg_sysupgrade.py |  68 ++++++++++
 meta/lib/oeqa/selftest/cases/image_upgrade.py | 124 ++++++++++++++++++
 2 files changed, 192 insertions(+)
 create mode 100644 meta/lib/oeqa/runtime/cases/opkg_sysupgrade.py
 create mode 100755 meta/lib/oeqa/selftest/cases/image_upgrade.py

diff --git a/meta/lib/oeqa/runtime/cases/opkg_sysupgrade.py b/meta/lib/oeqa/runtime/cases/opkg_sysupgrade.py
new file mode 100644
index 0000000000..05b5847b4a
--- /dev/null
+++ b/meta/lib/oeqa/runtime/cases/opkg_sysupgrade.py
@@ -0,0 +1,68 @@
+#
+# Copyright OpenEmbedded Contributors
+#
+# Test that generated ipk packages can be used to upgrade
+# an older image version.
+#
+# This is done by the meta/lib/oeqa/selftest/cases/image_upgrade.py oe-selftest
+# replacing the newly generated image by an older image
+# generated by the Yocto Project autobuilder.
+#
+# Here, we replace the package feeds in our image by our own
+#
+# This test is not meant to be used as a regular "testimage" test
+# run on the fresh image.
+#
+# SPDX-License-Identifier: MIT
+#
+
+import os
+from oeqa.utils.httpserver import HTTPService
+from oeqa.runtime.case import OERuntimeTestCase
+from oeqa.core.decorator.data import skipIfNotDataVar, skipIfNotFeature, skipIfFeature
+from oeqa.runtime.decorator.package import OEHasPackage
+
+class OpkgSysUpgradeTest(OERuntimeTestCase):
+
+    def pkg(self, command, expected = 0):
+        command = 'opkg %s' % command
+        status, output = self.target.run(command, 1500)
+        message = os.linesep.join([command, output])
+        self.assertEqual(status, expected, message)
+        return output
+
+class OpkgRepoTest(OpkgSysUpgradeTest):
+
+    @classmethod
+    def setUp(cls):
+        service_repo = os.path.join(cls.tc.td['DEPLOY_DIR_IPK'])
+        cls.repo_server = HTTPService(service_repo,
+                                      '0.0.0.0', port=cls.tc.target.server_port,
+                                      logger=cls.tc.logger)
+        cls.repo_server.start()
+
+    @classmethod
+    def tearDown(cls):
+        cls.repo_server.stop()
+
+    def setup_source_config_for_package_install(self):
+        source_server = 'http://%s:%s' % (self.tc.target.server_ip, self.repo_server.port)
+        sourceslist_dir = '/etc/opkg'
+        pkgarch = self.tc.td["TUNE_PKGARCH"]
+        machinedir = self.tc.td["MACHINE"].replace("-", "_")
+        self.target.run('cd %s; echo src/gz all %s/all > base-feeds.conf' % (sourceslist_dir, source_server))
+        self.target.run('cd %s; echo src/gz %s %s/%s >> base-feeds.conf' % (sourceslist_dir, pkgarch, source_server, pkgarch))
+        self.target.run('cd %s; echo src/gz %s %s/%s >> base-feeds.conf' % (sourceslist_dir, machinedir, source_server, machinedir))
+
+    @skipIfNotFeature('package-management',
+                      'Test requires package-management to be in IMAGE_FEATURES')
+    @skipIfNotDataVar('IMAGE_PKGTYPE', 'ipk',
+                      'IPK is not the primary package manager')
+    @skipIfFeature('read-only-rootfs',
+                   'Test does not work with read-only-rootfs in IMAGE_FEATURES')
+    @OEHasPackage(['opkg'])
+    def test_opkg_system_upgrade_from_repo(self):
+        self.setup_source_config_for_package_install()
+        self.pkg('update')
+        self.pkg('upgrade')
+
diff --git a/meta/lib/oeqa/selftest/cases/image_upgrade.py b/meta/lib/oeqa/selftest/cases/image_upgrade.py
new file mode 100755
index 0000000000..3e26c7eed0
--- /dev/null
+++ b/meta/lib/oeqa/selftest/cases/image_upgrade.py
@@ -0,0 +1,124 @@
+#
+# Copyright OpenEmbedded Contributors
+#
+# SPDX-License-Identifier: MIT
+#
+
+import os
+import subprocess
+from oeqa.selftest.case import OESelftestTestCase
+from oeqa.utils.commands import bitbake, runCmd, get_bb_var
+from oeqa.core.decorator.data import skipIfNotQemu
+
+basepath = os.path.abspath(os.path.dirname(__file__) + '/../../../../../')
+
+# Version string utilities copied from yocto-autobuilder-helper/scripts/utils.py
+
+def get_string_from_version(version, milestone=None, rc=None):
+    """ Point releases finishing by 0 (e.g 4.0.0, 4.1.0) do no exists,
+    those are major releases
+    """
+    if len(version) == 3 and version[-1] == 0:
+        version = version[:-1]
+
+    result = ".".join(list(map(str, version)))
+    if milestone:
+        result += "_M" + str(milestone)
+    if rc:
+        result += ".rc" + str(rc)
+    return result
+
+def get_tag_from_version(version, milestone):
+    if not milestone:
+        return "yocto-" + get_string_from_version(version, milestone)
+    return get_string_from_version(version, milestone)
+
+def get_version_from_string(raw_version):
+    """ Get version as list of int from raw_version.
+
+    Raw version _can_ be prefixed by "yocto-",
+    Raw version _can_ be suffixed by "_MX"
+    Raw version _can_ be suffixed by ".rcY"
+    """
+    version = None
+    milestone = None
+    rc = None
+    if raw_version[:6] == "yocto-":
+        raw_version = raw_version[6:]
+    raw_version = raw_version.split(".")
+    if raw_version[-1][:2] == "rc":
+        rc = int(raw_version[-1][-1])
+        raw_version = raw_version[:-1]
+    if raw_version[-1][-3:-1] == "_M":
+        milestone = int(raw_version[-1][-1])
+        raw_version = raw_version[:-1] + [raw_version[-1][:-3]]
+    version = list(map(int, raw_version))
+    """ Point releases finishing by 0 (e.g 4.0.0, 4.1.0) do no exists,
+    those are major releases
+    """
+    if len(version) == 3 and version[-1] == 0:
+        version = version[:-1]
+    return version, milestone, rc
+
+def get_latest_image_url(machine, machine_variant, image_file):
+
+    """Returns the URL of the latest generated image for the current branch"""
+
+    baseversion, milestone, _ = get_version_from_string(subprocess.check_output(["git", "describe", "--abbrev=0"], cwd=basepath).decode('utf-8').strip())
+    tag = get_tag_from_version(baseversion, milestone)
+    downloads_base = "https://downloads.yoctoproject.org/releases/yocto/"
+
+    if milestone is not None:
+        downloads_base += "milestones/yocto-%s" % tag
+    else:
+        downloads_base += tag
+
+    return "%s/machines/qemu/%s%s/%s" % (downloads_base, machine, machine_variant, image_file)
+
+class ImageIpkUpgrade(OESelftestTestCase):
+
+    @skipIfNotQemu()
+    def test_image_upgrade(self):
+        """
+        Summary: Test that generated ipk packages can
+        be used to upgrade an older image version.
+        This is done by generating an image but then replacing it
+        by an older image shared by the Yocto Project autobuilder.
+        We then run QEMU on the old image and replace the original
+        original package feeds by our own.
+        """
+
+        image = 'core-image-full-cmdline'
+        machine = get_bb_var("MACHINE")
+
+        features = 'DISTRO = "poky-altcfg"\n'
+        features += 'EXTRA_IMAGE_FEATURES += "package-management"\n'
+        features += 'PACKAGE_CLASSES = "package_ipk"\n'
+        features += 'IMAGE_CLASSES += "testimage"\n'
+        features += 'TEST_SUITES="opkg_sysupgrade"\n'
+        self.write_config(features)
+
+        # Need to build a full image to build the .json file needed by QEMU.
+        # Therefore, it is not sufficient to run only "package_write_ipk" for the image.
+
+        self.logger.info("Generating '%s' and package index for latest commit in this branch..." % image)
+        bitbake(image)
+        bitbake('package-index')
+
+        # Download previously generated image
+
+        image_file = '%s-%s.rootfs.ext4' % (image, machine)
+        image_path = '%s/tmp/deploy/images/%s/%s' % (self.builddir, machine, image_file)
+        machine_variant = '-alt'
+
+        os.remove(image_path)
+        image_url = get_latest_image_url(machine, machine_variant, image_file)
+        self.logger.info("Downloading image: %s..." % image_url)
+        cmd = 'wget -O %s %s' % (image_path, image_url)
+        result = runCmd(cmd)
+        self.assertEqual(0, result.status, cmd + ' returned a non 0 status: %s' % result.output)
+
+        # Now run the upgrade tests on the old image
+
+        self.logger.info("Running upgrade tests on the downloaded image, using the package feeds generated here...")
+        bitbake(image + ' -c testimage')
-- 
2.34.1



             reply	other threads:[~2024-04-25 15:46 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-25 15:46 michael.opdenacker [this message]
2024-04-25 20:40 ` [RFC][PATCH] oeqa/runtime/cases: new image_upgrade test Richard Purdie
2024-04-29 15:21   ` [OE-core] " Michael Opdenacker
2024-04-29 16:14     ` Richard Purdie
2024-04-26  8:20 ` Alexander Kanavin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240425154607.566716-1-michael.opdenacker@bootlin.com \
    --to=michael.opdenacker@bootlin.com \
    --cc=bruce.ashfield@gmail.com \
    --cc=openembedded-core@lists.openembedded.org \
    --cc=richard.purdie@linuxfoundation.org \
    --cc=thomas.petazzoni@bootlin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.