mirror of
git://git.yoctoproject.org/poky.git
synced 2025-07-19 21:09:03 +02:00

Consolidate the various mbox tests into a new TestMbox class, metadata tests into TestMetadata, and patch tests into TestPatch. Also update the selftest filenames to match the changes. The test contents are not significantly changed (other than to reference the new class names). While this doesn't improve overall readability, it does result in more obvious categorization, and more importantly reduces the number of calls to setup tinfoil in the tests, resulting in a roughly 25% reduction in runtime. Before: [tgamblin@megalith poky]$ time ./meta/lib/patchtest/selftest/selftest XPASS: PatchSignedOffBy.test_signed_off_by_presence (file: PatchSignedOffBy.test_signed_off_by_presence.pass) XFAIL: Shortlog.test_shortlog_format (file: Shortlog.test_shortlog_format.fail) XFAIL: MboxFormat.test_mbox_format (file: MboxFormat.test_mbox_format.1.fail) XPASS: Shortlog.test_shortlog_length (file: Shortlog.test_shortlog_length.pass) XFAIL: CommitMessage.test_commit_message_presence (file: CommitMessage.test_commit_message_presence.fail) XFAIL: SrcUri.test_src_uri_left_files (file: SrcUri.test_src_uri_left_files.fail) XPASS: Author.test_author_valid (file: Author.test_author_valid.1.pass) XFAIL: LicFilesChkSum.test_lic_files_chksum_modified_not_mentioned (file: LicFilesChkSum.test_lic_files_chksum_modified_not_mentioned.fail) XPASS: CVE.test_cve_tag_format (file: CVE.test_cve_tag_format.pass) XPASS: CVE.test_cve_presence_in_commit_message (file: CVE.test_cve_presence_in_commit_message.pass) XFAIL: CVE.test_cve_tag_format (file: CVE.test_cve_tag_format.fail) XFAIL: Author.test_author_valid (file: Author.test_author_valid.1.fail) XFAIL: LicFilesChkSum.test_lic_files_chksum_presence (file: LicFilesChkSum.test_lic_files_chksum_presence.fail) XSKIP: Merge.test_series_merge_on_head (file: Merge.test_series_merge_on_head.2.skip) XPASS: MboxFormat.test_mbox_format (file: MboxFormat.test_mbox_format.pass) XFAIL: SignedOffBy.test_signed_off_by_presence (file: SignedOffBy.test_signed_off_by_presence.1.fail) XPASS: Shortlog.test_shortlog_format (file: Shortlog.test_shortlog_format.pass) XFAIL: SignedOffBy.test_signed_off_by_presence (file: SignedOffBy.test_signed_off_by_presence.2.fail) XFAIL: MboxFormat.test_mbox_format (file: MboxFormat.test_mbox_format.2.fail) XFAIL: Summary.test_summary_presence (file: Summary.test_summary_presence.fail) XPASS: Author.test_author_valid (file: Author.test_author_valid.2.pass) XSKIP: Merge.test_series_merge_on_head (file: Merge.test_series_merge_on_head.1.skip) XPASS: Bugzilla.test_bugzilla_entry_format (file: Bugzilla.test_bugzilla_entry_format.pass) XFAIL: CVE.test_cve_presence_in_commit_message (file: CVE.test_cve_presence_in_commit_message.fail) XPASS: SignedOffBy.test_signed_off_by_presence (file: SignedOffBy.test_signed_off_by_presence.pass) XPASS: LicFilesChkSum.test_lic_files_chksum_presence (file: LicFilesChkSum.test_lic_files_chksum_presence.pass) XPASS: CommitMessage.test_commit_message_presence (file: CommitMessage.test_commit_message_presence.pass) XPASS: Summary.test_summary_presence (file: Summary.test_summary_presence.pass) XPASS: LicFilesChkSum.test_lic_files_chksum_modified_not_mentioned (file: LicFilesChkSum.test_lic_files_chksum_modified_not_mentioned.pass) XFAIL: Shortlog.test_shortlog_length (file: Shortlog.test_shortlog_length.fail) XFAIL: PatchSignedOffBy.test_signed_off_by_presence (file: PatchSignedOffBy.test_signed_off_by_presence.fail) XFAIL: Bugzilla.test_bugzilla_entry_format (file: Bugzilla.test_bugzilla_entry_format.fail) XPASS: SrcUri.test_src_uri_left_files (file: SrcUri.test_src_uri_left_files.pass) XFAIL: Author.test_author_valid (file: Author.test_author_valid.2.fail) ============================================================================ Testsuite summary for patchtest ============================================================================ ============================================================================ real 24m14.386s user 1m13.599s sys 0m21.477s After: [tgamblin@megalith poky]$ time ./meta/lib/patchtest/selftest/selftest XFAIL: TestMbox.test_bugzilla_entry_format (file: TestMbox.test_bugzilla_entry_format.fail) XPASS: TestMetadata.test_summary_presence (file: TestMetadata.test_summary_presence.pass) XFAIL: TestMbox.test_mbox_format (file: TestMbox.test_mbox_format.1.fail) XFAIL: TestMetadata.test_src_uri_left_files (file: TestMetadata.test_src_uri_left_files.fail) XSKIP: TestMbox.test_series_merge_on_head (file: TestMbox.test_series_merge_on_head.2.skip) XPASS: TestMbox.test_commit_message_presence (file: TestMbox.test_commit_message_presence.pass) XFAIL: TestMbox.test_commit_message_presence (file: TestMbox.test_commit_message_presence.fail) XPASS: TestMbox.test_signed_off_by_presence (file: TestMbox.test_signed_off_by_presence.pass) XFAIL: TestPatch.test_cve_tag_format (file: TestPatch.test_cve_tag_format.fail) XFAIL: TestMbox.test_author_valid (file: TestMbox.test_author_valid.1.fail) XFAIL: TestMbox.test_shortlog_length (file: TestMbox.test_shortlog_length.fail) XPASS: TestMbox.test_mbox_format (file: TestMbox.test_mbox_format.pass) XFAIL: TestPatch.test_signed_off_by_presence (file: TestPatch.test_signed_off_by_presence.fail) XFAIL: TestMbox.test_shortlog_format (file: TestMbox.test_shortlog_format.fail) XFAIL: TestMbox.test_mbox_format (file: TestMbox.test_mbox_format.2.fail) XPASS: TestPatch.test_cve_tag_format (file: TestPatch.test_cve_tag_format.pass) XSKIP: TestMbox.test_series_merge_on_head (file: TestMbox.test_series_merge_on_head.1.skip) XPASS: TestMbox.test_author_valid (file: TestMbox.test_author_valid.2.pass) XPASS: TestMetadata.test_lic_files_chksum_modified_not_mentioned (file: TestMetadata.test_lic_files_chksum_modified_not_mentioned.pass) XPASS: TestMbox.test_bugzilla_entry_format (file: TestMbox.test_bugzilla_entry_format.pass) XPASS: TestMetadata.test_src_uri_left_files (file: TestMetadata.test_src_uri_left_files.pass) XPASS: TestMetadata.test_lic_files_chksum_presence (file: TestMetadata.test_lic_files_chksum_presence.pass) XPASS: TestMbox.test_cve_presence_in_commit_message (file: TestMbox.test_cve_presence_in_commit_message.pass) XFAIL: TestMbox.test_signed_off_by_presence (file: TestMbox.test_signed_off_by_presence.2.fail) XFAIL: TestMbox.test_author_valid (file: TestMbox.test_author_valid.2.fail) XFAIL: TestMetadata.test_lic_files_chksum_presence (file: TestMetadata.test_lic_files_chksum_presence.fail) XPASS: TestMbox.test_shortlog_format (file: TestMbox.test_shortlog_format.pass) XPASS: TestMbox.test_author_valid (file: TestMbox.test_author_valid.1.pass) XPASS: TestPatch.test_signed_off_by_presence (file: TestPatch.test_signed_off_by_presence.pass) XFAIL: TestMetadata.test_lic_files_chksum_modified_not_mentioned (file: TestMetadata.test_lic_files_chksum_modified_not_mentioned.fail) XPASS: TestMbox.test_shortlog_length (file: TestMbox.test_shortlog_length.pass) XFAIL: TestMbox.test_signed_off_by_presence (file: TestMbox.test_signed_off_by_presence.1.fail) XFAIL: TestMbox.test_cve_presence_in_commit_message (file: TestMbox.test_cve_presence_in_commit_message.fail) XFAIL: TestMetadata.test_summary_presence (file: TestMetadata.test_summary_presence.fail) ============================================================================ Testsuite summary for patchtest ============================================================================ ============================================================================ real 18m39.749s user 0m41.857s sys 0m14.708s (From OE-Core rev: f788592da2fd0e21638ce2c3326675a060ba51cf) Signed-off-by: Trevor Gamblin <tgamblin@baylibre.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
184 lines
9.5 KiB
Python
184 lines
9.5 KiB
Python
# Checks related to the patch's author
|
|
#
|
|
# Copyright (C) 2016 Intel Corporation
|
|
#
|
|
# SPDX-License-Identifier: GPL-2.0-only
|
|
|
|
import base
|
|
import collections
|
|
import parse_cve_tags
|
|
import parse_shortlog
|
|
import parse_signed_off_by
|
|
import pyparsing
|
|
import subprocess
|
|
from data import PatchTestInput
|
|
|
|
def headlog():
|
|
output = subprocess.check_output(
|
|
"cd %s; git log --pretty='%%h#%%aN#%%cD:#%%s' -1" % PatchTestInput.repodir,
|
|
universal_newlines=True,
|
|
shell=True
|
|
)
|
|
return output.split('#')
|
|
|
|
class TestMbox(base.Base):
|
|
|
|
auh_email = 'auh@auh.yoctoproject.org'
|
|
|
|
invalids = [pyparsing.Regex("^Upgrade Helper.+"),
|
|
pyparsing.Regex(auh_email),
|
|
pyparsing.Regex("uh@not\.set"),
|
|
pyparsing.Regex("\S+@example\.com")]
|
|
|
|
rexp_detect = pyparsing.Regex('\[\s?YOCTO.*\]')
|
|
rexp_validation = pyparsing.Regex('\[(\s?YOCTO\s?#\s?(\d+)\s?,?)+\]')
|
|
revert_shortlog_regex = pyparsing.Regex('Revert\s+".*"')
|
|
prog = parse_cve_tags.cve_tag
|
|
patch_prog = parse_cve_tags.patch_cve_tag
|
|
signoff_prog = parse_signed_off_by.signed_off_by
|
|
revert_shortlog_regex = pyparsing.Regex('Revert\s+".*"')
|
|
maxlength = 90
|
|
|
|
# base paths of main yocto project sub-projects
|
|
paths = {
|
|
'oe-core': ['meta-selftest', 'meta-skeleton', 'meta', 'scripts'],
|
|
'bitbake': ['bitbake'],
|
|
'documentation': ['documentation'],
|
|
'poky': ['meta-poky','meta-yocto-bsp'],
|
|
'oe': ['meta-gpe', 'meta-gnome', 'meta-efl', 'meta-networking', 'meta-multimedia','meta-initramfs', 'meta-ruby', 'contrib', 'meta-xfce', 'meta-filesystems', 'meta-perl', 'meta-webserver', 'meta-systemd', 'meta-oe', 'meta-python']
|
|
}
|
|
|
|
# scripts folder is a mix of oe-core and poky, most is oe-core code except:
|
|
poky_scripts = ['scripts/yocto-bsp', 'scripts/yocto-kernel', 'scripts/yocto-layer', 'scripts/lib/bsp']
|
|
|
|
Project = collections.namedtuple('Project', ['name', 'listemail', 'gitrepo', 'paths'])
|
|
|
|
bitbake = Project(name='Bitbake', listemail='bitbake-devel@lists.openembedded.org', gitrepo='http://git.openembedded.org/bitbake/', paths=paths['bitbake'])
|
|
doc = Project(name='Documentantion', listemail='yocto@yoctoproject.org', gitrepo='http://git.yoctoproject.org/cgit/cgit.cgi/yocto-docs/', paths=paths['documentation'])
|
|
poky = Project(name='Poky', listemail='poky@yoctoproject.org', gitrepo='http://git.yoctoproject.org/cgit/cgit.cgi/poky/', paths=paths['poky'])
|
|
oe = Project(name='oe', listemail='openembedded-devel@lists.openembedded.org', gitrepo='http://git.openembedded.org/meta-openembedded/', paths=paths['oe'])
|
|
|
|
|
|
def test_signed_off_by_presence(self):
|
|
for commit in TestMbox.commits:
|
|
# skip those patches that revert older commits, these do not required the tag presence
|
|
if self.revert_shortlog_regex.search_string(commit.shortlog):
|
|
continue
|
|
if not self.signoff_prog.search_string(commit.payload):
|
|
self.fail('Mbox is missing Signed-off-by. Add it manually or with "git commit --amend -s"',
|
|
commit=commit)
|
|
|
|
def test_shortlog_format(self):
|
|
for commit in TestMbox.commits:
|
|
shortlog = commit.shortlog
|
|
if not shortlog.strip():
|
|
self.skip('Empty shortlog, no reason to execute shortlog format test')
|
|
else:
|
|
# no reason to re-check on revert shortlogs
|
|
if shortlog.startswith('Revert "'):
|
|
continue
|
|
try:
|
|
parse_shortlog.shortlog.parseString(shortlog)
|
|
except pyparsing.ParseException as pe:
|
|
self.fail('Commit shortlog (first line of commit message) should follow the format "<target>: <summary>"',
|
|
commit=commit)
|
|
|
|
def test_shortlog_length(self):
|
|
for commit in TestMbox.commits:
|
|
# no reason to re-check on revert shortlogs
|
|
shortlog = commit.shortlog
|
|
if shortlog.startswith('Revert "'):
|
|
continue
|
|
l = len(shortlog)
|
|
if l > self.maxlength:
|
|
self.fail('Edit shortlog so that it is %d characters or less (currently %d characters)' % (self.maxlength, l),
|
|
commit=commit)
|
|
|
|
def test_series_merge_on_head(self):
|
|
self.skip("Merge test is disabled for now")
|
|
if PatchTestInput.repo.branch != "master":
|
|
self.skip("Skipping merge test since patch is not intended for master branch. Target detected is %s" % PatchTestInput.repo.branch)
|
|
if not PatchTestInput.repo.ismerged:
|
|
commithash, author, date, shortlog = headlog()
|
|
self.fail('Series does not apply on top of target branch. Rebase your series and ensure the target is correct',
|
|
data=[('Targeted branch', '%s (currently at %s)' % (PatchTestInput.repo.branch, commithash))])
|
|
|
|
def test_target_mailing_list(self):
|
|
"""In case of merge failure, check for other targeted projects"""
|
|
if PatchTestInput.repo.ismerged:
|
|
self.skip('Series merged, no reason to check other mailing lists')
|
|
|
|
# a meta project may be indicted in the message subject, if this is the case, just fail
|
|
# TODO: there may be other project with no-meta prefix, we also need to detect these
|
|
project_regex = pyparsing.Regex("\[(?P<project>meta-.+)\]")
|
|
for commit in TestMbox.commits:
|
|
match = project_regex.search_string(commit.subject)
|
|
if match:
|
|
self.fail('Series sent to the wrong mailing list. Check the project\'s README (%s) and send the patch to the indicated list' % match.group('project'),
|
|
commit=commit)
|
|
|
|
for patch in self.patchset:
|
|
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:
|
|
self.fail('Series sent to the wrong mailing list or some patches from the series correspond to different mailing lists. Send the series again to the correct mailing list (ML)',
|
|
data=[('Suggested ML', '%s [%s]' % (project.listemail, project.gitrepo)),
|
|
('Patch\'s path:', patch.path)])
|
|
|
|
# check for poky's scripts code
|
|
if base_path.startswith('scripts'):
|
|
for poky_file in self.poky_scripts:
|
|
if patch.path.startswith(poky_file):
|
|
self.fail('Series sent to the wrong mailing list or some patches from the series correspond to different mailing lists. Send the series again to the correct mailing list (ML)',
|
|
data=[('Suggested ML', '%s [%s]' % (self.poky.listemail, self.poky.gitrepo)),('Patch\'s path:', patch.path)])
|
|
|
|
def test_mbox_format(self):
|
|
if self.unidiff_parse_error:
|
|
self.fail('Series cannot be parsed correctly due to malformed diff lines. Create the series again using git-format-patch and ensure it can be applied using git am',
|
|
data=[('Diff line',self.unidiff_parse_error)])
|
|
|
|
def test_commit_message_presence(self):
|
|
for commit in TestMbox.commits:
|
|
if not commit.commit_message.strip():
|
|
self.fail('Mbox is missing a descriptive commit message. Please include a commit message on your patch explaining the change', commit=commit)
|
|
|
|
def test_cve_presence_in_commit_message(self):
|
|
if self.unidiff_parse_error:
|
|
self.skip('Parse error %s' % self.unidiff_parse_error)
|
|
|
|
# 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_patches = [p for p in self.patchset if p.path.endswith('.patch') and p.is_added_file]
|
|
if not new_patches:
|
|
self.skip('No new patches introduced')
|
|
|
|
for commit in TestMbox.commits:
|
|
# skip those patches that revert older commits, these do not required the tag presence
|
|
if self.revert_shortlog_regex.search_string(commit.shortlog):
|
|
continue
|
|
if not self.patch_prog.search_string(commit.payload):
|
|
self.skip("No CVE tag in added patch, so not needed in mbox")
|
|
elif not self.prog.search_string(commit.payload):
|
|
self.fail('Missing or incorrectly formatted CVE tag in mbox. Correct or include the CVE tag in the mbox with format: "CVE: CVE-YYYY-XXXX"',
|
|
commit=commit)
|
|
|
|
def test_bugzilla_entry_format(self):
|
|
for commit in TestMbox.commits:
|
|
if not self.rexp_detect.search_string(commit.commit_message):
|
|
self.skip("No bug ID found")
|
|
elif not self.rexp_validation.search_string(commit.commit_message):
|
|
self.fail('Bugzilla issue ID is not correctly formatted - specify it with format: "[YOCTO #<bugzilla ID>]"', commit=commit)
|
|
|
|
def test_author_valid(self):
|
|
for commit in self.commits:
|
|
for invalid in self.invalids:
|
|
if invalid.search_string(commit.author):
|
|
self.fail('Invalid author %s. Resend the series with a valid patch author' % commit.author, commit=commit)
|
|
|
|
def test_non_auh_upgrade(self):
|
|
for commit in self.commits:
|
|
if self.auh_email in commit.payload:
|
|
self.fail('Invalid author %s. Resend the series with a valid patch author' % self.auh_email, commit=commit)
|