From patchwork Tue May 26 19:33:12 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trevor Gamblin X-Patchwork-Id: 88751 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 16496CD5BD1 for ; Tue, 26 May 2026 19:33:30 +0000 (UTC) Received: from mail-qt1-f181.google.com (mail-qt1-f181.google.com [209.85.160.181]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.4337.1779824004817618018 for ; Tue, 26 May 2026 12:33:25 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@baylibre.com header.s=google header.b=FQJ592LP; spf=pass (domain: baylibre.com, ip: 209.85.160.181, mailfrom: tgamblin@baylibre.com) Received: by mail-qt1-f181.google.com with SMTP id d75a77b69052e-516d65a15f6so46690421cf.1 for ; Tue, 26 May 2026 12:33:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre.com; s=google; t=1779824004; x=1780428804; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=fuZq/V4VDEhysWnMGKe/+mPgKXQw1dWcpdid9hcwc/Y=; b=FQJ592LP1vHOP28GDRp2aUyqp+as/ISgfFxk4ku3VdX4cZOmZlBxCnlBXPQhOAXa+x aHTkXsU30zN0fBj4GQzJqRiuJsTjNl+AVvrAygj8lY011fVEroNkyhPrznttRkT6UydQ HwZybOfzKY7bwMUQzH7HfIkbsUTNO8vE53ENiqV2QsGXASjSnh304hy1DiAbh7KdmZpb v+PQd1qyUBswOFICCoRTChQ7bCQwoZwbJjrSouxFx0H4Z9p6ewfWnbLhp4Yd7ZY/1uar cOiRtiFZxMcMzQh5e9KuUBZqBVkbRifVBz3dSWpNIXiCnJslLwT58g5XZI0amzBBRzOn 2ufw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779824004; x=1780428804; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=fuZq/V4VDEhysWnMGKe/+mPgKXQw1dWcpdid9hcwc/Y=; b=aFk9YToQ+7HiWesiVZKXm7zk5y21UQ9ieBz5XbHuvZp3cSBOEvvogq98V+wPmITsmH odJZ8W5UKy4Yvgbflm7brl7Yy4oEemM3e8y78JLtRC/tdWqZpFDcXAC4j7WQ8giZh5TS ndwXDv7SAhO7rlEIHmM6SwdnaozBJF1I/CoWgVlYRFjelvGsa5D+Fo1Wky/FQO/VJXvM g8lNOQcDYTDod1AKMkaeI2Ae2jyeIGiDgJSONqO6mUoE+DfLIDjwYO+W+EgmzWSFeriS OD8SagtRJWgVgEMpix/mbWtKhwggD60kjIPzedvKlvKhr9JoJcNHgn4P1AtKbI4X4ghP qJPQ== X-Gm-Message-State: AOJu0Yx9gHABRoqYQiuwutMpzDKJHg7t5XLPC+ipZ2yqWZbDuJt77YWk 0EuWXd7pHvGq5s99Fi5jMlB5xKCF8HC/LhJm4/HEO2gfq0IBjZ4F+qOUxGdohzxT+VpJh9kuzA/ iogh9sVw= X-Gm-Gg: Acq92OHfMoHtKmnrYAYfaWVOOhr7ld4oPVdpckxq2d5zHw2KTeOG9ln846QTTb9H48B CCBENc4Pi9d7EjXCSo7BJKLo5oZTNuYaNjiDJGgkJ/Ze68JqPl4qcnBSXFcIxiHCq6q+Xufzwwx VnT/jphR30GexT8QbK1Fm3f2ADzfOpcILegOu2vego86wII1p8CALCkFf4xju8H1kgDPDimdA2U FdAB/nwoJirnYGN8dLjRti2LGkcOLg8L+PdW/qhkMyc2rguRZCLiuwKmRGukbe/OhSXhZonJJ2h /d/ZypoyFKffeGm1mxqAlEejt+7nfOryVr0BE8lox67UAN4Q7m4A/ETKG11VITQ5vPMNb+gfbYR +mrFFCx8/WkaCzAP0i80fy7QsPIGvVzVglpWCuosRPOaUBVLUrq4ZOulDg03s/sgclZ/S5SnvIb lKcDL8uVaVCuJosC15WyrU81W+SA== X-Received: by 2002:a05:622a:a90d:b0:516:6818:6d74 with SMTP id d75a77b69052e-516c5628070mr224617621cf.34.1779824003731; Tue, 26 May 2026 12:33:23 -0700 (PDT) Received: from localhost ([2001:1970:3847:e000:537:a9f7:1a84:f246]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-517069ecb93sm30062471cf.4.2026.05.26.12.33.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 May 2026 12:33:22 -0700 (PDT) From: Trevor Gamblin To: openembedded-core@lists.openembedded.org Cc: yoann.congal@smile.fr Subject: [OE-core][PATCH 1/6] patchtest: refactor and simplify script Date: Tue, 26 May 2026 15:33:12 -0400 Message-ID: <20260526193317.807459-2-tgamblin@baylibre.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260526193317.807459-1-tgamblin@baylibre.com> References: <20260526193317.807459-1-tgamblin@baylibre.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Tue, 26 May 2026 19:33:30 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/237619 Remove a variety of unused code blocks and inconsistent formatting, then simplify the results-generation logic. This includes removing the 'finally:' block which was never actually reached. AI-Generated: Uses Claude Code Signed-off-by: Trevor Gamblin --- scripts/patchtest | 159 ++++++++++++++++++---------------------------- 1 file changed, 62 insertions(+), 97 deletions(-) diff --git a/scripts/patchtest b/scripts/patchtest index 143cf08572..6dbb5adb15 100755 --- a/scripts/patchtest +++ b/scripts/patchtest @@ -12,6 +12,7 @@ import json import logging import os +import subprocess import sys import traceback import unittest @@ -30,37 +31,50 @@ loggerhandler = logging.StreamHandler() loggerhandler.setFormatter(logging.Formatter("%(message)s")) logger.addHandler(loggerhandler) logger.setLevel(logging.INFO) -info = logger.info -error = logger.error -def getResult(patch, mergepatch, logfile=None): + +def _format_test_description(test): + return (test.id().split('.')[-1] + .replace('_', ' ') + .replace("cve", "CVE") + .replace("signed off by", "Signed-off-by") + .replace("upstream status", "Upstream-Status") + .replace("non auh", "non-AUH") + .replace("presence format", "presence")) + + +def _emit(line, logfile=None): + print(line) + if logfile: + with open(logfile, "a") as f: + f.write(line + "\n") + + +def make_result_class(patch, mergepatch, logfile=None): class PatchTestResult(unittest.TextTestResult): """ Patchtest TextTestResult """ shouldStop = True longMessage = False - success = 'PASS' - fail = 'FAIL' - skip = 'SKIP' + success = 'PASS' + fail = 'FAIL' + skip = 'SKIP' def startTestRun(self): - # let's create the repo already, it can be used later on - repoargs = { - "repodir": PatchtestParser.repodir, - "commit": PatchtestParser.basecommit, - "branch": PatchtestParser.basebranch, - "patch": patch, - } - - self.repo_error = False - self.test_error = False - self.test_failure = False + self.repo_error = False + self.test_error = False + self.test_failure = False try: - self.repo = PatchtestParser.repo = PatchTestRepo(**repoargs) - except: - logger.error(traceback.print_exc()) + self.repo = PatchtestParser.repo = PatchTestRepo( + patch=patch, + repodir=PatchtestParser.repodir, + commit=PatchtestParser.basecommit, + branch=PatchtestParser.basebranch, + ) + except Exception: + traceback.print_exc() self.repo_error = True self.stop() return @@ -70,100 +84,59 @@ def getResult(patch, mergepatch, logfile=None): def addError(self, test, err): self.test_error = True - (ty, va, trace) = err - logger.error(traceback.print_exc()) + traceback.print_exc() def addFailure(self, test, err): - test_description = test.id().split('.')[-1].replace('_', ' ').replace("cve", "CVE").replace("signed off by", - "Signed-off-by").replace("upstream status", - "Upstream-Status").replace("non auh", - "non-AUH").replace("presence format", "presence") self.test_failure = True - fail_str = '{}: {}: {} ({})'.format(self.fail, - test_description, json.loads(str(err[1]))["issue"], - test.id()) - print(fail_str) - if logfile: - with open(logfile, "a") as f: - f.write(fail_str + "\n") + desc = _format_test_description(test) + issue = json.loads(str(err[1]))["issue"] + _emit('{}: {}: {} ({})'.format(self.fail, desc, issue, test.id()), logfile) def addSuccess(self, test): - test_description = test.id().split('.')[-1].replace('_', ' ').replace("cve", "CVE").replace("signed off by", - "Signed-off-by").replace("upstream status", - "Upstream-Status").replace("non auh", - "non-AUH").replace("presence format", "presence") - success_str = '{}: {} ({})'.format(self.success, - test_description, test.id()) - print(success_str) - if logfile: - with open(logfile, "a") as f: - f.write(success_str + "\n") + desc = _format_test_description(test) + _emit('{}: {} ({})'.format(self.success, desc, test.id()), logfile) def addSkip(self, test, reason): - test_description = test.id().split('.')[-1].replace('_', ' ').replace("cve", "CVE").replace("signed off by", - "Signed-off-by").replace("upstream status", - "Upstream-Status").replace("non auh", - "non-AUH").replace("presence format", "presence") - skip_str = '{}: {}: {} ({})'.format(self.skip, - test_description, json.loads(str(reason))["issue"], - test.id()) - print(skip_str) - if logfile: - with open(logfile, "a") as f: - f.write(skip_str + "\n") + desc = _format_test_description(test) + issue = json.loads(str(reason))["issue"] + _emit('{}: {}: {} ({})'.format(self.skip, desc, issue, test.id()), logfile) def stopTestRun(self): - - # in case there was an error on repo object creation, just return - if self.repo_error: - return - - self.repo.clean() + if not self.repo_error: + self.repo.clean() return PatchTestResult def _runner(resultklass, prefix=None): - # load test with the corresponding prefix loader = unittest.TestLoader() if prefix: loader.testMethodPrefix = prefix - # create the suite with discovered tests and the corresponding runner suite = loader.discover( start_dir=PatchtestParser.testdir, pattern=PatchtestParser.pattern, top_level_dir=PatchtestParser.topdir, ) - ntc = suite.countTestCases() - # if there are no test cases, just quit - if not ntc: + if not suite.countTestCases(): return 2 - runner = unittest.TextTestRunner(resultclass=resultklass, verbosity=0) + runner = unittest.TextTestRunner(resultclass=resultklass, verbosity=0) try: result = runner.run(suite) - except: - logger.error(traceback.print_exc()) + except Exception: + traceback.print_exc() logger.error('patchtest: something went wrong') return 1 - if result.test_failure or result.test_error: - return 1 - return 0 + return 1 if (result.test_failure or result.test_error) else 0 def run(patch, logfile=None): """ Load, setup and run pre and post-merge tests """ - # Get the result class and install the control-c handler unittest.installHandler() - # run pre-merge tests, meaning those methods with 'pretest' as prefix - premerge_resultklass = getResult(patch, False, logfile) - premerge_result = _runner(premerge_resultklass, 'pretest') - - # run post-merge tests, meaning those methods with 'test' as prefix - postmerge_resultklass = getResult(patch, True, logfile) - postmerge_result = _runner(postmerge_resultklass, 'test') + premerge_result = _runner(make_result_class(patch, False, logfile), 'pretest') + postmerge_result = _runner(make_result_class(patch, True, logfile), 'test') print_result_message(premerge_result, postmerge_result) return premerge_result or postmerge_result @@ -183,24 +156,23 @@ def print_result_message(preresult, postresult): print("----------------------------------------------------------------------\n") def main(): - ret = 0 - tmp_patch = False patch_path = PatchtestParser.patch_path - log_results = PatchtestParser.log_results - log_path = None - patch_list = None - git_status = os.popen("(cd %s && git status)" % PatchtestParser.repodir).read() + git_status = subprocess.run( + ['git', '-C', PatchtestParser.repodir, 'status'], + capture_output=True, text=True, + ).stdout status_matches = ["Changes not staged for commit", "Changes to be committed"] - if any([match in git_status for match in status_matches]): + if any(match in git_status for match in status_matches): logger.error("patchtest: there are uncommitted changes in the target repo that would be overwritten. Please commit or restore them before running patchtest") return 1 if os.path.isdir(patch_path): - patch_list = [os.path.join(patch_path, filename) for filename in sorted(os.listdir(patch_path))] + patch_list = [os.path.join(patch_path, f) for f in sorted(os.listdir(patch_path))] else: patch_list = [patch_path] + ret = 0 for patch in patch_list: if os.path.getsize(patch) == 0: logger.error('patchtest: patch is empty') @@ -208,19 +180,13 @@ def main(): logger.info('Testing patch %s' % patch) - if log_results: + log_path = None + if PatchtestParser.log_results: log_path = patch + ".testresult" with open(log_path, "a") as f: f.write("Patchtest results for patch '%s':\n\n" % patch) - try: - if log_path: - ret = run(patch, log_path) - else: - ret = run(patch) - finally: - if tmp_patch: - os.remove(patch) + ret = run(patch, log_path) return ret @@ -241,7 +207,6 @@ if __name__ == '__main__': try: ret = main() except Exception: - import traceback traceback.print_exc(5) sys.exit(ret) From patchwork Tue May 26 19:33:13 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trevor Gamblin X-Patchwork-Id: 88750 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 527A2CD5BB1 for ; Tue, 26 May 2026 19:33:29 +0000 (UTC) Received: from mail-qk1-f173.google.com (mail-qk1-f173.google.com [209.85.222.173]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.4338.1779824006756417948 for ; Tue, 26 May 2026 12:33:26 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@baylibre.com header.s=google header.b=mmSY/Wqo; spf=pass (domain: baylibre.com, ip: 209.85.222.173, mailfrom: tgamblin@baylibre.com) Received: by mail-qk1-f173.google.com with SMTP id af79cd13be357-911501a99feso1318109585a.2 for ; Tue, 26 May 2026 12:33:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre.com; s=google; t=1779824006; x=1780428806; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=TCCoyw6Rug39R0VC3VSTMPTPxiRaCmlAZVV0gF/9w2U=; b=mmSY/Wqojr6IM0oYMgcPhf+qskOJFpMsPeORkqKGC3lQ451YrwvukN0H2dOx1lDJqm LNEao5Hcj6hqo+694cEGUmNsRCw4IDjEfxMdVAuJFXXIYkQhwsYOswRRmEt0AcgT8Kc1 q/LNxwiuX68KZRe6Z0jiik5uRnsIYRGoU6RkxWTGetXWuUEZ4tzzUL05hRnQGWFyZkJ6 ndr6dh4BHXAM1BB9mIM2q5FpHVg76Nm1UAK8YuY51qOV3G8c6zFrzMv7YHR+1v2rzZ1T UkFm5AvlxYvQ5IK7/ozp+oFQecNh2/qLGGtTF0QqUtpKOG5dti6Gm+2rYrkToupR9HoY MIwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779824006; x=1780428806; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=TCCoyw6Rug39R0VC3VSTMPTPxiRaCmlAZVV0gF/9w2U=; b=fYqZ7EaSAf1FKKv7wyzp3MC8PRCa+QCQ6XNOC70vLIQ5aD1fighJaM1ShvNjwNVcER XJJbfBQvqnYQ9oORpGeJBjpbvMxeC1gpKjBmf027IyFXkgCoWiovzfiCvqsCl58qpiIj LzK1p/6rPGB46HoXcVvPIwccsb/Gj6UeDBJHPmMTz0lIHAsocTTWlAuKcK+yVXSBE3CU M9LtX5OnT0RYHKJg9zS+NesZbL9MuCXXhDvaK/auBRjYfSxq29LQvsVQuUCggWdIyVUY rjQ7FkNVXR5DGLtZLfWaa+y8wzIYNRgDhbAv/KWBGQvMMwsr7e63DVDdGIBgxsw5SGlo o/YA== X-Gm-Message-State: AOJu0Yxm0oj8LkPc9rAx4hl85PmW4nAtxgmZjOGGvuDEp69BLLy5CjrF w+zOG5UX3TUlrch+gB/+2CZNoQqNKDYVRIcwj/2mge1OPDXapIPCV0Yqvj8iwxfeYwAoy7p8L9F 0mkMc8Q8= X-Gm-Gg: Acq92OHxj1JzqfwLOYa3xeAWwDrGUyZ3xz27EnNJUYPdMHW/OBCG55/CAWERK3CW7jw xN+kgCUef194vj7RsKjnovA6kMtyt8gtfAI3fY7vTZCvzYFJio9G9/jp6kq7ZCPvisqvmB60FAl eTCJxdtnfQ3qq5QVI1v1a/5LUyxBTgW4ZD063uwYxWCyA/PCc27cm/+QT894TEX56+mlxIB6hk6 Ndp2pAaI91y7K4upLpi3/lsD1nywGu7YCE/kuULQQQX9pO7OZinyCkUFUaIzKySTLhdRVD9kfZd hkxCGZyot0UByUjmzzdBlN+9olamLYohjrN6BxaRaVHeYx9WxV7EWgoQvwDQP18yYjCMw5SApMF vu1OsqzC5oG61EyoU/IQrv9voFEde+uuGUHee91Ad0bOalEUvJ4ZV4qHtEbvKu4oCM2lT4UU++f xVvrBnWCALPcfZ2gkiEJGJEKWjYg== X-Received: by 2002:a05:620a:a2ce:20b0:908:8470:4e8e with SMTP id af79cd13be357-914b49a10a3mr2121733785a.37.1779824005760; Tue, 26 May 2026 12:33:25 -0700 (PDT) Received: from localhost ([2001:1970:3847:e000:537:a9f7:1a84:f246]) by smtp.gmail.com with ESMTPSA id af79cd13be357-914f87d1744sm293111285a.22.2026.05.26.12.33.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 May 2026 12:33:24 -0700 (PDT) From: Trevor Gamblin To: openembedded-core@lists.openembedded.org Cc: yoann.congal@smile.fr Subject: [OE-core][PATCH 2/6] patchtest: check for meta-selftest Date: Tue, 26 May 2026 15:33:13 -0400 Message-ID: <20260526193317.807459-3-tgamblin@baylibre.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260526193317.807459-1-tgamblin@baylibre.com> References: <20260526193317.807459-1-tgamblin@baylibre.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Tue, 26 May 2026 19:33:29 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/237620 The patchtest suite (in particular, the selftests) makes use of the meta-selftest layer for full operation. Make sure that the layer is added to bblayers.conf before kicking off any test runs. Signed-off-by: Trevor Gamblin --- scripts/patchtest | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/scripts/patchtest b/scripts/patchtest index 6dbb5adb15..e8ace03905 100755 --- a/scripts/patchtest +++ b/scripts/patchtest @@ -167,6 +167,17 @@ def main(): logger.error("patchtest: there are uncommitted changes in the target repo that would be overwritten. Please commit or restore them before running patchtest") return 1 + builddir = os.environ.get('BUILDDIR') + if builddir: + bblayers_conf = os.path.join(builddir, 'conf', 'bblayers.conf') + if os.path.exists(bblayers_conf): + with open(bblayers_conf) as f: + if 'meta-selftest' not in f.read(): + logger.error( + "patchtest: meta-selftest layer not found in %s - add it to BBLAYERS before running patchtest" % bblayers_conf + ) + return 1 + if os.path.isdir(patch_path): patch_list = [os.path.join(patch_path, f) for f in sorted(os.listdir(patch_path))] else: From patchwork Tue May 26 19:33:14 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trevor Gamblin X-Patchwork-Id: 88753 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6C045CD5BC8 for ; Tue, 26 May 2026 19:33:39 +0000 (UTC) Received: from mail-qv1-f52.google.com (mail-qv1-f52.google.com [209.85.219.52]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.4340.1779824009952393997 for ; Tue, 26 May 2026 12:33:30 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@baylibre.com header.s=google header.b=UNfnIXkr; spf=pass (domain: baylibre.com, ip: 209.85.219.52, mailfrom: tgamblin@baylibre.com) Received: by mail-qv1-f52.google.com with SMTP id 6a1803df08f44-8ca12973e15so149180126d6.1 for ; Tue, 26 May 2026 12:33:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre.com; s=google; t=1779824009; x=1780428809; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0HmS9x5ugKbKASDa7jIXw23cGS5L4PbHdS6hY+8XCe8=; b=UNfnIXkrRqLbQZO9hP8VDrVoVvUB0pseYXIk9Xw+ez0mzsXhfnp9etBv7L9tptM05Y gl5C9/ulMpg3wEf5aLss948z03ps+3BzdxV7nBXc6/Y42YzHOGvGcYjfd0Jx1qjremAi kyidVo/uIDSaT6hdOWH5LaaT61kF0rPPljx3fXClNb6bv2j7aOgRgPK3gvrCEl//dppw +kU/zpe99W/PLq2a7SlZ4DaDEAD227JnYJC3xdt4GBvWh1pnojl9HOkIC5wCR+xTNenE gN+W75Z7O6l7OT+spndDX4Jp5EHt0yyJIaAqMdST3+qUZ23lkXLxyGi5jlUSXmCn7mK7 wyDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779824009; x=1780428809; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=0HmS9x5ugKbKASDa7jIXw23cGS5L4PbHdS6hY+8XCe8=; b=IFi1I5xvtqmWVfeJKMNa2Teau/Ky0z9XmggefxU5XLaYGHC6cAKBngkeE4wzKQu2Xg KCXaPnQUPkpW63b7J/WMG2kw9YqSJYsqxXUtD2u7HmHE/xZz/HjpBGTMUFzI61ZfMgWZ adO0RxfXYPZwewzwm1SLePbrGUq+Y8pGsYdlRPvQXGQvS/l9Kyl1V7RC+XpZc5aCBQUq Ndl3ZWqG5dBZqAjM+jrC39x2oPOeybZ8uDW+mjjySBkGkM1zFrln4QMI69/T5nrkw3Dt 1l72DHCTOGZBXRlCllK44+fgvxnClI9mijWSPuo9XyfHuJN1Z4Uhf9hZVF4ZVgCRCpLp c5Uw== X-Gm-Message-State: AOJu0YzW8WhtYQgV1UWUiCCgfgovv/wh8/ECDotPLAJKc4J00o312J7J asz65P85mhGshVIixBtAEbzv4+Qm6pAqHz3bGZN8y2rk5IN0nLGBdVBEINM9sH9zQ5XIMDiT0FS xCvcrq1g= X-Gm-Gg: Acq92OH3+RWrISbp57WEl+buN2x8OvVe12S1q4/vM3scyRRCzEEXHxByuSnOEwWXaCm Y9C5Gbxe0KciTYxSzUO32D6pC8vwxJkTE4R4nlq1nOOIrgiiPWgVrTxIaS4qtoHooP7Gj45pVOw Ouv9Jm4u7pTwKI1WYfw6ds6uLCEznpLU36ngKhEcKOup7Jqeg43sxNEL9JTW11q9pSRqHdDdS1J lfkhpOKKQMGgp58CG5+SAMQQ5qrRuFJ4KkYO3dEI2IUiBEkAUAZKsYf2yFWKnzThBYn5LcO7CvK /RQNtP8LhQ2lt3qEsr6hXDUbO0Yl/QmTaSjApoodfKUMocJ427HGMELILqi2PYrx7N032mKFwJH OPRY2DbTXc1joJXlPROU6CZSlBLDjNLn21ISMxXZTo9PVrdOSw4NuKQabe2+5ZEvT2t/ETcDin5 FXnTJ4kK47sDkAlZVFWZVw3K2hYA== X-Received: by 2002:a05:6214:451d:b0:8cc:3546:2613 with SMTP id 6a1803df08f44-8cc7b69f724mr331460426d6.42.1779824008834; Tue, 26 May 2026 12:33:28 -0700 (PDT) Received: from localhost ([2001:1970:3847:e000:537:a9f7:1a84:f246]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-8cca4705c62sm62121016d6.27.2026.05.26.12.33.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 May 2026 12:33:27 -0700 (PDT) From: Trevor Gamblin To: openembedded-core@lists.openembedded.org Cc: yoann.congal@smile.fr Subject: [OE-core][PATCH 3/6] patchtest: tests: cleanup test suites Date: Tue, 26 May 2026 15:33:14 -0400 Message-ID: <20260526193317.807459-4-tgamblin@baylibre.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260526193317.807459-1-tgamblin@baylibre.com> References: <20260526193317.807459-1-tgamblin@baylibre.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Tue, 26 May 2026 19:33:39 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/237621 Do a sweep of the test suites to remove redundant code, make variable names more explicit, and fix some formatting. Some logic (such as the bits for checking valid Upstream-Status tags) are also moved directly to the relevant functions, instead of being left in the setup stage. This should make maintenance easier going forward. AI-Generated: Uses Claude Code Signed-off-by: Trevor Gamblin --- meta/lib/patchtest/tests/base.py | 4 --- meta/lib/patchtest/tests/test_mbox.py | 10 +++--- meta/lib/patchtest/tests/test_metadata.py | 32 ++++++------------ meta/lib/patchtest/tests/test_patch.py | 33 ++++++++----------- .../lib/patchtest/tests/test_python_pylint.py | 8 ++--- 5 files changed, 33 insertions(+), 54 deletions(-) diff --git a/meta/lib/patchtest/tests/base.py b/meta/lib/patchtest/tests/base.py index 919ca136bb..8263932dda 100644 --- a/meta/lib/patchtest/tests/base.py +++ b/meta/lib/patchtest/tests/base.py @@ -22,10 +22,6 @@ info = logger.info warn = logger.warn error = logger.error -Commit = collections.namedtuple( - "Commit", ["author", "subject", "commit_message", "shortlog", "payload"] -) - Commit = collections.namedtuple('Commit', ['author', 'subject', 'commit_message', 'shortlog', 'payload']) class PatchtestOEError(Exception): diff --git a/meta/lib/patchtest/tests/test_mbox.py b/meta/lib/patchtest/tests/test_mbox.py index 5cf02af7bd..feb87fa2ae 100644 --- a/meta/lib/patchtest/tests/test_mbox.py +++ b/meta/lib/patchtest/tests/test_mbox.py @@ -74,11 +74,11 @@ class TestMbox(base.Base): shortlog = re.sub(r'^(\[.*?\])+ ', '', commit.shortlog) if shortlog.startswith('Revert "'): continue - l = len(shortlog) - if l > patchtest_patterns.mbox_shortlog_maxlength: + length = len(shortlog) + if length > patchtest_patterns.mbox_shortlog_maxlength: self.fail( "Edit shortlog so that it is %d characters or less (currently %d characters)" - % (patchtest_patterns.mbox_shortlog_maxlength, l), + % (patchtest_patterns.mbox_shortlog_maxlength, length), commit=commit, ) @@ -120,7 +120,7 @@ class TestMbox(base.Base): folders = patch.path.split('/') base_path = folders[0] for project in [self.bitbake, self.doc, self.oe, self.poky]: - if base_path in project.paths: + if base_path in project.paths: self.fail('Series sent to the wrong mailing list or some patches from the series correspond to different mailing lists', data=[('Suggested ML', '%s [%s]' % (project.listemail, project.gitrepo)), ('Patch\'s path:', patch.path)]) @@ -173,7 +173,7 @@ class TestMbox(base.Base): for commit in self.commits: if patchtest_patterns.auh_email in commit.commit_message: self.fail( - "Invalid author %s. Resend the series with a valid patch author" + "Commit message contains AUH email address %s. Resend the series with a valid patch author" % patchtest_patterns.auh_email, commit=commit, ) diff --git a/meta/lib/patchtest/tests/test_metadata.py b/meta/lib/patchtest/tests/test_metadata.py index 30da8dbe60..442e80973d 100644 --- a/meta/lib/patchtest/tests/test_metadata.py +++ b/meta/lib/patchtest/tests/test_metadata.py @@ -8,7 +8,6 @@ import base import collections import os import patchtest_patterns -import pyparsing from patchtest_parser import PatchtestParser # Data store commonly used to share values between pre and post-merge tests @@ -108,39 +107,28 @@ class TestMetadata(base.Metadata): ], ) - def pretest_src_uri_left_files(self): - # these tests just make sense on patches that can be merged - if not PatchtestParser.repo.canbemerged(): - self.skip("Patch cannot be merged") - if not self.modified: - self.skip('No modified recipes, skipping pretest') - - # get the proper metadata values + def _collect_src_uri(self, key_prefix): for pn in self.modified: - # we are not interested in images if 'core-image' in pn: continue rd = self.tinfoil.parse_recipe(pn) PatchTestDataStore[ - "%s-%s-%s" % (self.shortid(), patchtest_patterns.metadata_src_uri, pn) + "%s-%s-%s" % (key_prefix, patchtest_patterns.metadata_src_uri, pn) ] = rd.getVar(patchtest_patterns.metadata_src_uri) - def test_src_uri_left_files(self): - # these tests just make sense on patches that can be merged + def pretest_src_uri_left_files(self): if not PatchtestParser.repo.canbemerged(): self.skip("Patch cannot be merged") if not self.modified: self.skip('No modified recipes, skipping pretest') + self._collect_src_uri(self.shortid()) - # get the proper metadata values - for pn in self.modified: - # we are not interested in images - if 'core-image' in pn: - continue - rd = self.tinfoil.parse_recipe(pn) - PatchTestDataStore[ - "%s-%s-%s" % (self.shortid(), patchtest_patterns.metadata_src_uri, pn) - ] = rd.getVar(patchtest_patterns.metadata_src_uri) + def test_src_uri_left_files(self): + if not PatchtestParser.repo.canbemerged(): + self.skip("Patch cannot be merged") + if not self.modified: + self.skip('No modified recipes, skipping test') + self._collect_src_uri(self.shortid()) for pn in self.modified: pretest_src_uri = PatchTestDataStore[ diff --git a/meta/lib/patchtest/tests/test_patch.py b/meta/lib/patchtest/tests/test_patch.py index 3b33b5a199..9f1d7d2c8f 100644 --- a/meta/lib/patchtest/tests/test_patch.py +++ b/meta/lib/patchtest/tests/test_patch.py @@ -28,21 +28,16 @@ class TestPatch(base.Base): def setUp(self): if self.unidiff_parse_error: self.skip('Parse error %s' % self.unidiff_parse_error) - - self.valid_status = ", ".join(patchtest_patterns.upstream_status_nonliteral_valid_status) - self.standard_format = "Upstream-Status: " - - # we are just interested in series that introduce CVE patches, thus discard other - # possibilities: modification to current CVEs, patch directly introduced into the - # recipe, upgrades already including the CVE, etc. - new_cves = [p for p in self.patchset if p.path.endswith('.patch') and p.is_added_file] - if not new_cves: + if not TestPatch.newpatches: self.skip('No new CVE patches introduced') def test_upstream_status_presence_format(self): if not TestPatch.newpatches: self.skip("There are no new software patches, no reason to test Upstream-Status presence/format") + valid_status = ", ".join(patchtest_patterns.upstream_status_nonliteral_valid_status) + standard_format = "Upstream-Status: " + for newpatch in TestPatch.newpatches: payload = newpatch.__str__() lines = payload.splitlines() @@ -71,16 +66,16 @@ class TestPatch(base.Base): 'Upstream-Status is present only after the patch scissors. ' "It must be placed in the patch header before the scissors line.", data=[ - ("Standard format", self.standard_format), - ("Valid status", self.valid_status), + ("Standard format", standard_format), + ("Valid status", valid_status), ], ) else: self.fail( "Added patch file is missing Upstream-Status: in the commit message", data=[ - ("Standard format", self.standard_format), - ("Valid status", self.valid_status), + ("Standard format", standard_format), + ("Valid status", valid_status), ], ) @@ -97,8 +92,8 @@ class TestPatch(base.Base): "but was found afterwards.", data=[ ("Current", line.lstrip("+")), - ("Standard format", self.standard_format), - ("Valid status", self.valid_status), + ("Standard format", standard_format), + ("Valid status", valid_status), ], ) @@ -142,14 +137,14 @@ class TestPatch(base.Base): "Upstream-Status is in incorrect format", data=[ ("Current", pe.pstr), - ("Standard format", self.standard_format), - ("Valid status", self.valid_status), + ("Standard format", standard_format), + ("Valid status", valid_status), ], ) def test_signed_off_by_presence(self): if not TestPatch.newpatches: - self.skip("There are no new software patches, no reason to test %s presence" % PatchSignedOffBy.mark) + self.skip("There are no new software patches, no reason to test %s presence" % TestPatch.mark) for newpatch in TestPatch.newpatches: payload = newpatch.__str__() @@ -162,7 +157,7 @@ class TestPatch(base.Base): self.fail('A patch file has been added without a Signed-off-by tag: \'%s\'' % os.path.basename(newpatch.path)) def test_cve_tag_format(self): - for commit in TestPatch.commits: + for commit in self.commits: if patchtest_patterns.cve.search_string( commit.shortlog ) or patchtest_patterns.cve.search_string(commit.commit_message): diff --git a/meta/lib/patchtest/tests/test_python_pylint.py b/meta/lib/patchtest/tests/test_python_pylint.py index ec9129bc79..37d1de9436 100644 --- a/meta/lib/patchtest/tests/test_python_pylint.py +++ b/meta/lib/patchtest/tests/test_python_pylint.py @@ -47,7 +47,7 @@ class PyLint(base.Base): for pythonpatch in self.pythonpatches: # a condition checking whether a file is renamed or not # unidiff doesn't support this yet - if pythonpatch.target_file is not pythonpatch.path: + if pythonpatch.target_file != pythonpatch.path: path = pythonpatch.target_file[2:] else: path = pythonpatch.path @@ -55,9 +55,9 @@ class PyLint(base.Base): reporter = TextReporter(pylint_output) lint.Run([self.pylint_options, pythonpatch.path], reporter=reporter, exit=False) for line in pylint_output.readlines(): - if not '*' in line: - if line.strip(): - self.pylint_test[line.strip().split(' ',1)[0]] = line.strip().split(' ',1)[1] + if not '*' in line: + if line.strip(): + self.pylint_test[line.strip().split(' ',1)[0]] = line.strip().split(' ',1)[1] for issue in self.pylint_test: if self.pylint_test[issue] not in self.pylint_pretest.values(): From patchwork Tue May 26 19:33:15 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trevor Gamblin X-Patchwork-Id: 88754 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 90637CD5BD5 for ; Tue, 26 May 2026 19:33:39 +0000 (UTC) Received: from mail-qv1-f45.google.com (mail-qv1-f45.google.com [209.85.219.45]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.4341.1779824011649329328 for ; Tue, 26 May 2026 12:33:31 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@baylibre.com header.s=google header.b=iybJfY44; spf=pass (domain: baylibre.com, ip: 209.85.219.45, mailfrom: tgamblin@baylibre.com) Received: by mail-qv1-f45.google.com with SMTP id 6a1803df08f44-8b3d6b215cfso186559886d6.3 for ; Tue, 26 May 2026 12:33:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre.com; s=google; t=1779824011; x=1780428811; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Pn1BjXyFVGNnfSHz7r25Zr8s13XXZed/5vWqHlM9M9c=; b=iybJfY44Y34VgBQ3FRFGrRZScw6CBlrWC2rdF+BA8w8XkW2LmItWMYM5zVQ3Iw9bJ0 8+IlRZWLloBOa21Zw4iqTUSfcdvqkzBVLIn6sVDKuitYg0GARGlXJ/H5KBFqbRH9Jljs UI2UINkE3naxPdaB06OlTBudBY5wcGDJ3zMxSYTMBFcfXqN1iSw8kP+vZJ79xSxcuscc F7T7JxNDLKRA+kdzNZVFZgP8a1VL8qE0MVTiUoX1pFnOGeTyDOmAqyN083gwF2SCid6j p0L1UPfVLYXGuP49SpB0Fj9vo6c97DBUS3BgdXnwfPxjaw6jpnDoo0fBCHaWXyJ5ft1X TWEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779824011; x=1780428811; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=Pn1BjXyFVGNnfSHz7r25Zr8s13XXZed/5vWqHlM9M9c=; b=WQqPMsQYYjie0q7/UkWTfveG8/hvgAtmjGpJEt+MlzEUhrc3sR6/I+IzhtS53fITRw 73YgnswVzsht+ruzBSomVOxdZ5OGVHCwPxXpDdtAzcxBvZwRDm9MZexmevrqG7y0T/1S Gno+crwru2sFGncNAPNLUrQi7ByaPPtq1Yj9nyeHdIa8gHkiEk9EBpjK9SLS5fmNNU26 9LY/RBz2OalmRs8YqxRNCzuOnNQllbbsa3i3kAPsL2/VTBrmher7wYNma3DoY8/W+kc9 twN8g0QQ/XJEwBu0cO5JItKHODkQoL2yInztjmTc5b/ANPF2v8TTq0V3SZJCDK7WROr1 htnw== X-Gm-Message-State: AOJu0Yx4Er+kaQZob9CF1cJwubENUWgtzhFwf6PreoZgQt9++d3mBB1k /Jznf1AYpef/hfIN/tuCU/tdZHd9KpzHZlSHgq9a5Wq9pN/urcQys5uvanLPNrIPNAsj+ryxhry Vs+7gUg8= X-Gm-Gg: Acq92OG8poLpP6xJVZ5+eIJyzIHzSyiNeIZKyb5xzMI1CH4NyP2UNwxaC5Dl0+xcrAN DduNWpxzs3gpD5TgNHlkxMdqWjU1spB8WfWUBSDeWPD+QyWAPvhcdon60YSpisgN8kShWwz6dPD He2aIl+X+4Da06rjKzLwAou6K96wr2WyOYxG+2mom5N/b0D8Aktx57xBDa+OH4Zcc77C/e+jxwF UnmABRwbfoyHNPs5zukPOHKre7l1TkLHv1nS5u79ZI29ekF5BJzPO06mkLDIe46S5YU5Pydst0s Pzo9Ne0AOban4PE0aAW+FLUYaOdSwi3E1hcW1g7dMJ6gseuzr5fs2y+RnODTEwNkKKn7hTNKNrY g8aSmNWjMcobsbe96zphSZP0ezABq34C/6SVe0x7pXf3Y9M5ZerICttYrjcbhaftv4nQ90nvH8S 9ZwatsqC+BPTId1lMFieZjOtGGNUejobZ5h9R5 X-Received: by 2002:a05:622a:480d:b0:516:d66e:7b1f with SMTP id d75a77b69052e-516d66ebfe7mr262354931cf.31.1779824010626; Tue, 26 May 2026 12:33:30 -0700 (PDT) Received: from localhost ([2001:1970:3847:e000:537:a9f7:1a84:f246]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-8cc8131fc67sm152521136d6.45.2026.05.26.12.33.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 May 2026 12:33:29 -0700 (PDT) From: Trevor Gamblin To: openembedded-core@lists.openembedded.org Cc: yoann.congal@smile.fr Subject: [OE-core][PATCH 4/6] patchtest: correctly abort --directory test Date: Tue, 26 May 2026 15:33:15 -0400 Message-ID: <20260526193317.807459-5-tgamblin@baylibre.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260526193317.807459-1-tgamblin@baylibre.com> References: <20260526193317.807459-1-tgamblin@baylibre.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Tue, 26 May 2026 19:33:39 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/237622 Currently, patchtest run with --directory responds to a CTRL+C press by aborting only the current patch being tested, and moves onto the next. Instead, this key press should stop the test entirely. Remove usage of the unittest.installHandler() function (which intercepts the signal) and handle it ourselves. Also make sure that the branch is properly reset with git am --abort afterwards, and that the return code is properly set in the sigint handler function. Finally, update patchtest_parser.py so that the helper info reflects this change. AI-Generated: Uses Claude Code Signed-off-by: Trevor Gamblin --- meta/lib/patchtest/patchtest_parser.py | 2 +- meta/lib/patchtest/repo.py | 4 ++++ scripts/patchtest | 31 +++++++++++++++++++++++--- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/meta/lib/patchtest/patchtest_parser.py b/meta/lib/patchtest/patchtest_parser.py index 2a11cb76c2..69bcb4b8e5 100644 --- a/meta/lib/patchtest/patchtest_parser.py +++ b/meta/lib/patchtest/patchtest_parser.py @@ -37,7 +37,7 @@ class PatchtestParser(object): help='The patch to be tested') target_patch_group.add_argument('--directory', metavar='DIRECTORY', dest='patch_path', - help='The directory containing patches to be tested') + help='The directory containing patches to be tested. CTRL+C aborts the entire directory test.') parser.add_argument('--repodir', metavar='REPO', default=default_repodir, diff --git a/meta/lib/patchtest/repo.py b/meta/lib/patchtest/repo.py index 6a7d7d2d3b..b4cf9e8ded 100644 --- a/meta/lib/patchtest/repo.py +++ b/meta/lib/patchtest/repo.py @@ -85,6 +85,10 @@ class PatchTestRepo(object): self._patchmerged = True def clean(self): + try: + self.repo.git.execute(['git', 'am', '--abort']) + except git.exc.GitCommandError: + pass self.repo.git.execute(['git', 'checkout', self.current_branch if self.current_branch else self.current_commit]) self.repo.git.execute(['git', 'branch', '-D', self._workingbranch]) self._patchmerged = False diff --git a/scripts/patchtest b/scripts/patchtest index e8ace03905..435610b54f 100755 --- a/scripts/patchtest +++ b/scripts/patchtest @@ -12,6 +12,7 @@ import json import logging import os +import signal import subprocess import sys import traceback @@ -133,8 +134,6 @@ def _runner(resultklass, prefix=None): def run(patch, logfile=None): """ Load, setup and run pre and post-merge tests """ - unittest.installHandler() - premerge_result = _runner(make_result_class(patch, False, logfile), 'pretest') postmerge_result = _runner(make_result_class(patch, True, logfile), 'test') @@ -183,10 +182,26 @@ def main(): else: patch_list = [patch_path] + interrupted = False + previous_sigint = signal.getsignal(signal.SIGINT) + + def _sigint_handler(signum, frame): + nonlocal interrupted + interrupted = True + # Restore previous handler so a second CTRL+C exits immediately + signal.signal(signal.SIGINT, previous_sigint) + signal.default_int_handler(signum, frame) + + signal.signal(signal.SIGINT, _sigint_handler) + ret = 0 for patch in patch_list: + if interrupted: + break + if os.path.getsize(patch) == 0: logger.error('patchtest: patch is empty') + signal.signal(signal.SIGINT, previous_sigint) return 1 logger.info('Testing patch %s' % patch) @@ -197,8 +212,18 @@ def main(): with open(log_path, "a") as f: f.write("Patchtest results for patch '%s':\n\n" % patch) - ret = run(patch, log_path) + try: + result = run(patch, log_path) + ret = ret or result + except KeyboardInterrupt: + interrupted = True + + if interrupted: + logger.error('\npatchtest: interrupted') + signal.signal(signal.SIGINT, previous_sigint) + return 1 + signal.signal(signal.SIGINT, previous_sigint) return ret if __name__ == '__main__': From patchwork Tue May 26 19:33:16 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trevor Gamblin X-Patchwork-Id: 88755 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 732CCCD5BD1 for ; Tue, 26 May 2026 19:33:39 +0000 (UTC) Received: from mail-qk1-f176.google.com (mail-qk1-f176.google.com [209.85.222.176]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.4344.1779824014625463234 for ; Tue, 26 May 2026 12:33:34 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@baylibre.com header.s=google header.b=kuyv8LBH; spf=pass (domain: baylibre.com, ip: 209.85.222.176, mailfrom: tgamblin@baylibre.com) Received: by mail-qk1-f176.google.com with SMTP id af79cd13be357-914cf9248ceso271906885a.1 for ; Tue, 26 May 2026 12:33:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre.com; s=google; t=1779824014; x=1780428814; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Wh5zO5eMw6EF2svQ49U8kHpnlE3VQeKYz8FEUFx2/x4=; b=kuyv8LBHGd2EbukvpBrBPsd6vEwJeQz0a4F+wZUqLwKHfE7Aqjf2Qe3uJ9/fDtP13/ vSWTmWgXbcO9YcSAkI5mrAOw7G5psXqZm3OKlkUfdlIA+pSUWIPzGaZ4fh/3E/mhry1n b9Dp9rV0KNtBx9+HkSawTAs2dldwAdB3+XyzWLOwFVdtVfOgqeL1I/m8RHqbh33a9fCS EVMvBMdZlAbZBUxJaaYvdua5QzT0Gp11FNtFyBwRSLGanEW15/fSCS9nnaFAr0Zp0eR1 S+QRMBEjdnwD3zVLo9L7lg8X6VcRbR2QrGf6hnJpfn+/eEo732y1umd4ubN0/uYtMy/u J8Dw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779824014; x=1780428814; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=Wh5zO5eMw6EF2svQ49U8kHpnlE3VQeKYz8FEUFx2/x4=; b=EzM8slCEK31+vrkxM1NoOxgcXXasdPd6tGN29gXDBSKgyhh81YaEjnMBzEq2NOG5Lg MgytVgEpCNDcD4lvPAbZwnvtJgG4u2KLeL+gtA0rB1Sz4n7si5b9aZ9FehMq6rc0FzKO ci+8hwHU/gpad8VbuEch2zBVw/gLYKEBGkldb+2Rv3xfDE+tLIN+E8NIYVhHM3RFJCuL luTCnAZt3u65FCmlLtA5evMKgR+RixV6HimjLJz85Md8DOwHMQyWhV/7aLPQs5ZIbn1b TzyvCSYQxrUfEQgSf+JvBIk4BXU7byzjiU4XulmjHh8oJZdAekVzZFP7euiLLlQ3dPxd MTOw== X-Gm-Message-State: AOJu0Yzjf95ychHJ6A7lTJQWZDEdC+XvJqZ2fJjQg8cLGJPhinvkox8R SUIAW2dlqEdkPaTBtB3YRmzZiIHY0xALHlmeHDHBO1U5Q9KsbebjqchQ5iqEKE/yJAfvrr0ztDu Kt2J5H3E= X-Gm-Gg: Acq92OFMU6wQIDGVl0hGH3MY1vXGCwVghPvN7BQ3ENAgby0NTSNzcxp8cth0GTdJZfg FvyjEhvOiZKoCJdkycF8oMisdP2nft1uuxVDpzP8m/2dEZFAX460A6ozXBIxiekdSaI91bfcJlR vJcNkd8ozXBNV4M3Tk+7Ym/iqsFh2iHsjw+VMb2gSZZ+myl4se2jzjZjx90X91pjDav5HzSPYB4 lQmsU19x4j9aMQrDaA/y9RESifdlEnLPlAEER/67MEZclXC5iIA4vlAgZJwIsAZ0XQLtOsNzVTF QTGBitbRQUlifT3zBWsGNWPFrhjB6id6XniUY0bqNuRiBNIUcQh0Ax6XAICrSVPLx+eTc4FdzdS ksDClRlTO69gMVF4+EqqS09Uw0ZOF+smZQcrzajew9drYaGrn0RwGFUP2k7xuXbqwMIkX9ht3fo BvVgstpxD/izZfAPOL1g03i5l6CNWrg8e95nSJE+HfnKUtjOY= X-Received: by 2002:a05:620a:2794:b0:90f:fdb3:b752 with SMTP id af79cd13be357-914b4934c7cmr2844477285a.17.1779824013499; Tue, 26 May 2026 12:33:33 -0700 (PDT) Received: from localhost ([2001:1970:3847:e000:537:a9f7:1a84:f246]) by smtp.gmail.com with ESMTPSA id af79cd13be357-914f87d2060sm297631885a.23.2026.05.26.12.33.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 May 2026 12:33:31 -0700 (PDT) From: Trevor Gamblin To: openembedded-core@lists.openembedded.org Cc: yoann.congal@smile.fr Subject: [OE-core][PATCH 5/6] patchtest: tests: base: add helper functions, cleanup Date: Tue, 26 May 2026 15:33:16 -0400 Message-ID: <20260526193317.807459-6-tgamblin@baylibre.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260526193317.807459-1-tgamblin@baylibre.com> References: <20260526193317.807459-1-tgamblin@baylibre.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Tue, 26 May 2026 19:33:39 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/237623 - Encapsulate the package name acquisition logic in _find_pn() - Simplify the _getvar() function used across the test suite - Drastically shorten the get_metadata_stats() function - Reword and clean up some vague comments and typos AI-Generated: Uses Claude Code Signed-off-by: Trevor Gamblin --- meta/lib/patchtest/tests/base.py | 112 ++++++++++++------------------- 1 file changed, 44 insertions(+), 68 deletions(-) diff --git a/meta/lib/patchtest/tests/base.py b/meta/lib/patchtest/tests/base.py index 8263932dda..30c207f016 100644 --- a/meta/lib/patchtest/tests/base.py +++ b/meta/lib/patchtest/tests/base.py @@ -133,18 +133,17 @@ class Metadata(Base): def setUpClassLocal(cls): cls.tinfoil = cls.setup_tinfoil() - # get info about added/modified/remove recipes + # get info about added/modified/removed recipes cls.added, cls.modified, cls.removed = cls.get_metadata_stats(cls.patchset) @classmethod def tearDownClassLocal(cls): - cls.tinfoil.shutdown() + if cls.tinfoil: + cls.tinfoil.shutdown() @classmethod def setup_tinfoil(cls, config_only=False): - """Initialize tinfoil api from bitbake""" - - # import relevant libraries + """Initialize tinfoil api from bitbake.""" try: scripts_path = os.path.join(PatchtestParser.repodir, "scripts", "lib") if scripts_path not in sys.path: @@ -156,21 +155,19 @@ class Metadata(Base): raise PatchtestOEError('Could not import tinfoil module') orig_cwd = os.path.abspath(os.curdir) - - # Load tinfoil tinfoil = None try: builddir = os.environ.get('BUILDDIR') if not builddir: logger.warn('Bitbake environment not loaded?') - return tinfoil + return None os.chdir(builddir) tinfoil = bb.tinfoil.Tinfoil() tinfoil.prepare(config_only=config_only) - except bb.tinfoil.TinfoilUIException as te: + except bb.tinfoil.TinfoilUIException: if tinfoil: tinfoil.shutdown() - raise PatchtestOEError('Could not prepare properly tinfoil (TinfoilUIException)') + raise PatchtestOEError('Could not properly configure tinfoil (TinfoilUIException)') except Exception as e: if tinfoil: tinfoil.shutdown() @@ -180,69 +177,48 @@ class Metadata(Base): return tinfoil + @staticmethod + def _find_pn(data, path): + """Find the PN from tinfoil recipe cache data for a given file path.""" + pn = None + pn_native = None + for _path, _pn in data: + if path in _path: + if 'native' in _pn: + pn_native = _pn + else: + pn = _pn + break + else: + if pn_native: + return pn_native + path_basename = path.split('_')[0] + for _path, _pn in data: + _path_basename = _path.split('_')[0] + if path_basename == _path_basename: + pn = _pn + return pn + @classmethod - def get_metadata_stats(cls, patchset): - """Get lists of added, modified and removed metadata files""" + def _getvar(cls, path, varname): + """Return a recipe variable value via tinfoil if available.""" + if cls.tinfoil: + data = list(cls.tinfoil.cooker.recipecaches[''].pkg_fn.items()) + pn = cls._find_pn(data, path) + rd = cls.tinfoil.parse_recipe(pn) + return rd.getVar(varname) - def find_pn(data, path): - """Find the PN from data""" - pn = None - pn_native = None - for _path, _pn in data: - if path in _path: - if 'native' in _pn: - # store the native PN but look for the non-native one first - pn_native = _pn - else: - pn = _pn - break - else: - # sent the native PN if found previously - if pn_native: - return pn_native - - # on renames (usually upgrades), we need to check (FILE) base names - # because the unidiff library does not provided the new filename, just the modified one - # and tinfoil datastore, once the patch is merged, will contain the new filename - path_basename = path.split('_')[0] - for _path, _pn in data: - _path_basename = _path.split('_')[0] - if path_basename == _path_basename: - pn = _pn - return pn - - if not cls.tinfoil: - cls.tinfoil = cls.setup_tinfoil() - - added_paths, modified_paths, removed_paths = [], [], [] + @classmethod + def get_metadata_stats(cls, patchset): + """Return lists of absolute paths for added, modified and removed recipe files.""" added, modified, removed = [], [], [] - - # get metadata filename additions, modification and removals for patch in patchset: if patch.path.endswith('.bb') or patch.path.endswith('.bbappend') or patch.path.endswith('.inc'): + abspath = os.path.join(os.path.abspath(PatchtestParser.repodir), patch.path) if patch.is_added_file: - added_paths.append( - os.path.join( - os.path.abspath(PatchtestParser.repodir), patch.path - ) - ) + added.append(abspath) elif patch.is_modified_file: - modified_paths.append( - os.path.join( - os.path.abspath(PatchtestParser.repodir), patch.path - ) - ) + modified.append(abspath) elif patch.is_removed_file: - removed_paths.append( - os.path.join( - os.path.abspath(PatchtestParser.repodir), patch.path - ) - ) - - data = cls.tinfoil.cooker.recipecaches[''].pkg_fn.items() - - added = [find_pn(data,path) for path in added_paths] - modified = [find_pn(data,path) for path in modified_paths] - removed = [find_pn(data,path) for path in removed_paths] - - return [a for a in added if a], [m for m in modified if m], [r for r in removed if r] + removed.append(abspath) + return added, modified, removed From patchwork Tue May 26 19:33:17 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trevor Gamblin X-Patchwork-Id: 88752 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 684E4CD5BB1 for ; Tue, 26 May 2026 19:33:39 +0000 (UTC) Received: from mail-qk1-f172.google.com (mail-qk1-f172.google.com [209.85.222.172]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.4346.1779824017189066236 for ; Tue, 26 May 2026 12:33:37 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@baylibre.com header.s=google header.b=X1Wf5ETD; spf=pass (domain: baylibre.com, ip: 209.85.222.172, mailfrom: tgamblin@baylibre.com) Received: by mail-qk1-f172.google.com with SMTP id af79cd13be357-9102e90bcbeso1133842285a.1 for ; Tue, 26 May 2026 12:33:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre.com; s=google; t=1779824016; x=1780428816; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=kD5tf2eJUjl3Ip+QSmOLOroF/BAi7xUhsy1nf8vyCp4=; b=X1Wf5ETDokZMtiuCHA+yyLZz5E63HxtB4usYeWCBPNKKZibiT/QnMpC+6M7ChN/a5s 3e6oMUtNVtx62xq1tHJdINbNLpD/dtlMNgyfUfzlP58wGsYqTYsBxCeboKBOQ+svAmip ruDGklG0RqbMPRQZPJM5A1vVKqnzFhGurU8u+HHHQdjWOYGldTHkj7Gr3R/6B1n6bJ7Z YPhwAv0C0MiCJ9NVVZepKjwLvU6VpV0FwthLW+45SWYDnjL8+J+cr7fJZAIm1rG6nAiH 8tl4R50r1rlYdwL1/XBhRzT5jFPkVpege0ijQfviFgv2LCn4KFWsCtOFggVktHHkovt5 7nKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779824016; x=1780428816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=kD5tf2eJUjl3Ip+QSmOLOroF/BAi7xUhsy1nf8vyCp4=; b=nVBJXegTB3mJRuOyeOIVUAaZTK2/upk3vahFSQFNWBSwTEl8GkvbzNGpfWdupVjeLX iqMGeYyfDem6gI+4SQtihXDaTDIgks3HWPT1ZSHxXb+hHDpayxMbPwbjvkXPx+ujznKE zrjvZAi2LyOLLYWz1Rr71tDtd5xg/OycAWILPxvQwV6AF8xny2xQ3O4PuMhXXwSM9z2x mrOfksog5KFdmW43WbMxKEbY3rA3zV3EjkU/3uPvzIR8fVM8TrC+pjR5RCr3uJ15uGBm +ey67QvMUDjIg4wT+v3a7DZHMupUQjnh9Pp6M8g1hddhHGH3LqKKMDXgGihg40JYY3h1 LGvA== X-Gm-Message-State: AOJu0YzW1kc5/PhNiLlavzYhXxGtONNX6s01wEqzfswdFhliKaH14hqy A2+Z4gGaOcmH8bFQyimEEuXlgDyeqhXCtSB6Pe0FHl/dz7lCfcIM1j4zRfXswncWmq3iaHFRYcg hT7Cjxr8= X-Gm-Gg: Acq92OFp7ugKIR2E6qbxsfDjHgy41I7u3CWofzTeCD5H7q0Tx98+oPX5PCrdXGy+ypu xT1Gb3oUPJkUoJ1bx/ZmX7ohq6XVP6Xzhzb8KkzijjkY8Uj6ZWZGFCVH1S1L8Ed//WWwtbhTzCt GHp1II2EXNWiNjw1sCZoxbkYxBNoTnVyTEEXXts6yPLvKF9bWR+odYqeM4xSnPYH3O9rzwNfV+2 1hPUsE4NqSdiJIPikT7F1THEzaZjBkeSo0F7jZdpXFMa0r5uebKonBgjt9srt6ixaip8fknhh0Y HFHVw6sHVSBfN6W2odwciOYuQo04xUnSVRUK8cbhaFQQF6NKqDDXbcTHAW/Cv3s+y6jC+1SapM4 x4NAI9utoucSQgTg5JOPp8n8a2WLEepcidvqUsNXdXWdcll7wqDXKnM4Wabj/uMqBEq5jzM4Hxm RmA2JrQfRoERoMNbD123xoOltWKCbjC3Wk4v/C X-Received: by 2002:a05:620a:8393:b0:910:4023:4fca with SMTP id af79cd13be357-914b492de5emr2874033385a.18.1779824016232; Tue, 26 May 2026 12:33:36 -0700 (PDT) Received: from localhost ([2001:1970:3847:e000:537:a9f7:1a84:f246]) by smtp.gmail.com with ESMTPSA id af79cd13be357-914f87cd9fcsm285264985a.25.2026.05.26.12.33.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 May 2026 12:33:34 -0700 (PDT) From: Trevor Gamblin To: openembedded-core@lists.openembedded.org Cc: yoann.congal@smile.fr Subject: [OE-core][PATCH 6/6] patchtest: tests: test_metadata: cleanup Date: Tue, 26 May 2026 15:33:17 -0400 Message-ID: <20260526193317.807459-7-tgamblin@baylibre.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260526193317.807459-1-tgamblin@baylibre.com> References: <20260526193317.807459-1-tgamblin@baylibre.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Tue, 26 May 2026 19:33:39 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/237624 - Use the new _getvar() version - Replace usage of "pn" as a variable with the more explicit "path" - Fix some vague comments and typos AI-Generated: Uses Claude Code Signed-off-by: Trevor Gamblin --- meta/lib/patchtest/tests/test_metadata.py | 62 ++++++++++------------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/meta/lib/patchtest/tests/test_metadata.py b/meta/lib/patchtest/tests/test_metadata.py index 442e80973d..f180309991 100644 --- a/meta/lib/patchtest/tests/test_metadata.py +++ b/meta/lib/patchtest/tests/test_metadata.py @@ -19,32 +19,28 @@ class TestMetadata(base.Metadata): if not self.added: self.skip('No added recipes, skipping test') - # TODO: this is a workaround so we can parse the recipe not - # containing the LICENSE var: add some default license instead - # of INVALID into auto.conf, then remove this line at the end + # workaround: set a default license so tinfoil can parse recipes + # that don't have LICENSE set yet auto_conf = os.path.join(os.environ.get('BUILDDIR'), 'conf', 'auto.conf') open_flag = 'w' if os.path.exists(auto_conf): open_flag = 'a' with open(auto_conf, open_flag) as fd: - for pn in self.added: + for path in self.added: fd.write('LICENSE ??= "%s"\n' % patchtest_patterns.invalid_license) no_license = False - for pn in self.added: - rd = self.tinfoil.parse_recipe(pn) - license = rd.getVar(patchtest_patterns.metadata_lic) - if license == patchtest_patterns.invalid_license: + for path in self.added: + license = self._getvar(path, patchtest_patterns.metadata_lic) + if not license or license == patchtest_patterns.invalid_license: no_license = True break - # remove auto.conf line or the file itself if open_flag == 'w': os.remove(auto_conf) else: - fd = open(auto_conf, 'r') - lines = fd.readlines() - fd.close() + with open(auto_conf, 'r') as fd: + lines = fd.readlines() with open(auto_conf, 'w') as fd: fd.write(''.join(lines[:-1])) @@ -55,14 +51,13 @@ class TestMetadata(base.Metadata): if not self.added: self.skip('No added recipes, skipping test') - for pn in self.added: - rd = self.tinfoil.parse_recipe(pn) - pathname = rd.getVar('FILE') + for path in self.added: + pathname = self._getvar(path, 'FILE') or path # we are not interested in images if '/images/' in pathname: continue - lic_files_chksum = rd.getVar(patchtest_patterns.metadata_chksum) - if rd.getVar(patchtest_patterns.license_var) == patchtest_patterns.closed: + lic_files_chksum = self._getvar(path, patchtest_patterns.metadata_chksum) + if self._getvar(path, patchtest_patterns.license_var) == patchtest_patterns.closed: continue if not lic_files_chksum: self.fail( @@ -108,13 +103,13 @@ class TestMetadata(base.Metadata): ) def _collect_src_uri(self, key_prefix): - for pn in self.modified: - if 'core-image' in pn: + for path in self.modified: + if 'core-image' in os.path.basename(path): continue - rd = self.tinfoil.parse_recipe(pn) + src_uri = self._getvar(path, patchtest_patterns.metadata_src_uri) PatchTestDataStore[ - "%s-%s-%s" % (key_prefix, patchtest_patterns.metadata_src_uri, pn) - ] = rd.getVar(patchtest_patterns.metadata_src_uri) + "%s-%s-%s" % (key_prefix, patchtest_patterns.metadata_src_uri, path) + ] = src_uri or '' def pretest_src_uri_left_files(self): if not PatchtestParser.repo.canbemerged(): @@ -130,12 +125,12 @@ class TestMetadata(base.Metadata): self.skip('No modified recipes, skipping test') self._collect_src_uri(self.shortid()) - for pn in self.modified: + for path in self.modified: pretest_src_uri = PatchTestDataStore[ - "pre%s-%s-%s" % (self.shortid(), patchtest_patterns.metadata_src_uri, pn) + "pre%s-%s-%s" % (self.shortid(), patchtest_patterns.metadata_src_uri, path) ].split() test_src_uri = PatchTestDataStore[ - "%s-%s-%s" % (self.shortid(), patchtest_patterns.metadata_src_uri, pn) + "%s-%s-%s" % (self.shortid(), patchtest_patterns.metadata_src_uri, path) ].split() pretest_files = set([os.path.basename(patch.split(';')[0]) for patch in pretest_src_uri if patch.startswith('file://')]) @@ -154,7 +149,7 @@ class TestMetadata(base.Metadata): filesremoved_from_usr_uri = pretest_files - test_files # finally, get those patches removed at SRC_URI and not removed from the patchset - # TODO: we are not taking into account renames, so test may raise false positives + # TODO: we are not taking into account renames, so test may raise false positives not_removed = filesremoved_from_usr_uri - filesremoved_from_patchset if not_removed: self.fail('Patches not removed from tree. Remove them and amend the submitted mbox', @@ -164,15 +159,15 @@ class TestMetadata(base.Metadata): if not self.added: self.skip('No added recipes, skipping test') - for pn in self.added: + for path in self.added: + pn = os.path.basename(path).split('_')[0] # we are not interested in images if 'core-image' in pn: continue - rd = self.tinfoil.parse_recipe(pn) - summary = rd.getVar(patchtest_patterns.metadata_summary) + summary = self._getvar(path, patchtest_patterns.metadata_summary) # "${PN} version ${PN}-${PR}" is the default, so fail if default - if summary.startswith("%s version" % pn): + if not summary or summary.startswith("%s version" % pn): self.fail( "%s is missing in newly added recipe" % patchtest_patterns.metadata_summary ) @@ -186,12 +181,11 @@ class TestMetadata(base.Metadata): or PatchtestParser.repo.patch.branch == "dunfell" ): self.skip("No modified recipes or older target branch, skipping test") - for pn in self.modified: + for path in self.modified: # we are not interested in images - if 'core-image' in pn: + if 'core-image' in os.path.basename(path): continue - rd = self.tinfoil.parse_recipe(pn) - cve_check_ignore = rd.getVar(patchtest_patterns.cve_check_ignore_var) + cve_check_ignore = self._getvar(path, patchtest_patterns.cve_check_ignore_var) if cve_check_ignore is not None: self.fail(