diff options
author | Trevor Gamblin <tgamblin@baylibre.com> | 2024-09-24 07:55:01 -0400 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2024-09-30 17:00:50 +0100 |
commit | 4c378fc89566a329d0974bbcfefc7405779bc919 (patch) | |
tree | 4175c6d63b024e39dc9a7f02a77f1ff3cab8088f /meta/lib/patchtest | |
parent | 18a65c77c0e729dd1835852336e57ff4922f2674 (diff) | |
download | poky-4c378fc89566a329d0974bbcfefc7405779bc919.tar.gz |
patchtest: simplify, rename modules
- simplify base.py, data.py
- move some leftover regex patterns to patterns.py
- remove pyparsing path logic, since this is no longer needed
- rename PatchTestInput class to PatchtestParser
- data.py: rename to patchtest_parser.py
- patterns.py: rename to patchtest_patterns.py
- move PatchTestDataStore to test_metadata.py since that's the only
place it's used
- remove unused logger code
(From OE-Core rev: 1e971b05b036b0b1eb0bdbd9b26b54d06e74294c)
Signed-off-by: Trevor Gamblin <tgamblin@baylibre.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/lib/patchtest')
-rw-r--r-- | meta/lib/patchtest/patchtest_parser.py (renamed from meta/lib/patchtest/data.py) | 10 | ||||
-rw-r--r-- | meta/lib/patchtest/patchtest_patterns.py (renamed from meta/lib/patchtest/patterns.py) | 15 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/base.py | 48 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_mbox.py | 69 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_metadata.py | 91 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_patch.py | 95 | ||||
-rw-r--r-- | meta/lib/patchtest/tests/test_python_pylint.py | 3 |
7 files changed, 215 insertions, 116 deletions
diff --git a/meta/lib/patchtest/data.py b/meta/lib/patchtest/patchtest_parser.py index 356259921d..2a11cb76c2 100644 --- a/meta/lib/patchtest/data.py +++ b/meta/lib/patchtest/patchtest_parser.py | |||
@@ -15,19 +15,11 @@ | |||
15 | 15 | ||
16 | import os | 16 | import os |
17 | import argparse | 17 | import argparse |
18 | import collections | ||
19 | import logging | ||
20 | |||
21 | logger=logging.getLogger('patchtest') | ||
22 | info=logger.info | ||
23 | 18 | ||
24 | default_testdir = os.path.abspath(os.path.dirname(__file__) + "/tests") | 19 | default_testdir = os.path.abspath(os.path.dirname(__file__) + "/tests") |
25 | default_repodir = os.path.abspath(os.path.dirname(__file__) + "/../../..") | 20 | default_repodir = os.path.abspath(os.path.dirname(__file__) + "/../../..") |
26 | 21 | ||
27 | # Data store commonly used to share values between pre and post-merge tests | 22 | class PatchtestParser(object): |
28 | PatchTestDataStore = collections.defaultdict(str) | ||
29 | |||
30 | class PatchTestInput(object): | ||
31 | """Abstract the patchtest argument parser""" | 23 | """Abstract the patchtest argument parser""" |
32 | 24 | ||
33 | @classmethod | 25 | @classmethod |
diff --git a/meta/lib/patchtest/patterns.py b/meta/lib/patchtest/patchtest_patterns.py index b703b0c8b9..8c2e192fc9 100644 --- a/meta/lib/patchtest/patterns.py +++ b/meta/lib/patchtest/patchtest_patterns.py | |||
@@ -5,6 +5,7 @@ | |||
5 | # SPDX-License-Identifier: GPL-2.0-only | 5 | # SPDX-License-Identifier: GPL-2.0-only |
6 | 6 | ||
7 | import pyparsing | 7 | import pyparsing |
8 | import re | ||
8 | 9 | ||
9 | # general | 10 | # general |
10 | colon = pyparsing.Literal(":") | 11 | colon = pyparsing.Literal(":") |
@@ -34,10 +35,16 @@ lic_chksum_added = pyparsing.AtLineStart("+" + metadata_chksum) | |||
34 | lic_chksum_removed = pyparsing.AtLineStart("-" + metadata_chksum) | 35 | lic_chksum_removed = pyparsing.AtLineStart("-" + metadata_chksum) |
35 | add_mark = pyparsing.Regex('\\+ ') | 36 | add_mark = pyparsing.Regex('\\+ ') |
36 | patch_max_line_length = 200 | 37 | patch_max_line_length = 200 |
37 | metadata_src_uri = 'SRC_URI' | 38 | metadata_src_uri = "SRC_URI" |
38 | metadata_summary = 'SUMMARY' | 39 | metadata_summary = "SUMMARY" |
39 | cve_check_ignore_var = 'CVE_CHECK_IGNORE' | 40 | cve_check_ignore_var = "CVE_CHECK_IGNORE" |
40 | cve_status_var = 'CVE_STATUS' | 41 | cve_status_var = "CVE_STATUS" |
42 | endcommit_messages_regex = re.compile( | ||
43 | r"\(From \w+-\w+ rev:|(?<!\S)Signed-off-by|(?<!\S)---\n" | ||
44 | ) | ||
45 | patchmetadata_regex = re.compile( | ||
46 | r"-{3} \S+|\+{3} \S+|@{2} -\d+,\d+ \+\d+,\d+ @{2} \S+" | ||
47 | ) | ||
41 | 48 | ||
42 | # mbox | 49 | # mbox |
43 | auh_email = 'auh@yoctoproject.org' | 50 | auh_email = 'auh@yoctoproject.org' |
diff --git a/meta/lib/patchtest/tests/base.py b/meta/lib/patchtest/tests/base.py index 911addb199..919ca136bb 100644 --- a/meta/lib/patchtest/tests/base.py +++ b/meta/lib/patchtest/tests/base.py | |||
@@ -8,20 +8,23 @@ import unittest | |||
8 | import logging | 8 | import logging |
9 | import json | 9 | import json |
10 | import unidiff | 10 | import unidiff |
11 | from data import PatchTestInput | 11 | from patchtest_parser import PatchtestParser |
12 | import mailbox | 12 | import mailbox |
13 | import patchtest_patterns | ||
13 | import collections | 14 | import collections |
14 | import sys | 15 | import sys |
15 | import os | 16 | import os |
16 | import re | 17 | import re |
17 | 18 | ||
18 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'pyparsing')) | 19 | logger = logging.getLogger("patchtest") |
20 | debug = logger.debug | ||
21 | info = logger.info | ||
22 | warn = logger.warn | ||
23 | error = logger.error | ||
19 | 24 | ||
20 | logger = logging.getLogger('patchtest') | 25 | Commit = collections.namedtuple( |
21 | debug=logger.debug | 26 | "Commit", ["author", "subject", "commit_message", "shortlog", "payload"] |
22 | info=logger.info | 27 | ) |
23 | warn=logger.warn | ||
24 | error=logger.error | ||
25 | 28 | ||
26 | Commit = collections.namedtuple('Commit', ['author', 'subject', 'commit_message', 'shortlog', 'payload']) | 29 | Commit = collections.namedtuple('Commit', ['author', 'subject', 'commit_message', 'shortlog', 'payload']) |
27 | 30 | ||
@@ -34,9 +37,6 @@ class PatchtestOEError(Exception): | |||
34 | class Base(unittest.TestCase): | 37 | class Base(unittest.TestCase): |
35 | # if unit test fails, fail message will throw at least the following JSON: {"id": <testid>} | 38 | # if unit test fails, fail message will throw at least the following JSON: {"id": <testid>} |
36 | 39 | ||
37 | endcommit_messages_regex = re.compile(r'\(From \w+-\w+ rev:|(?<!\S)Signed-off-by|(?<!\S)---\n') | ||
38 | patchmetadata_regex = re.compile(r'-{3} \S+|\+{3} \S+|@{2} -\d+,\d+ \+\d+,\d+ @{2} \S+') | ||
39 | |||
40 | @staticmethod | 40 | @staticmethod |
41 | def msg_to_commit(msg): | 41 | def msg_to_commit(msg): |
42 | payload = msg.get_payload() | 42 | payload = msg.get_payload() |
@@ -49,7 +49,7 @@ class Base(unittest.TestCase): | |||
49 | @staticmethod | 49 | @staticmethod |
50 | def commit_message(payload): | 50 | def commit_message(payload): |
51 | commit_message = payload.__str__() | 51 | commit_message = payload.__str__() |
52 | match = Base.endcommit_messages_regex.search(payload) | 52 | match = patchtest_patterns.endcommit_messages_regex.search(payload) |
53 | if match: | 53 | if match: |
54 | commit_message = payload[:match.start()] | 54 | commit_message = payload[:match.start()] |
55 | return commit_message | 55 | return commit_message |
@@ -65,13 +65,15 @@ class Base(unittest.TestCase): | |||
65 | def setUpClass(cls): | 65 | def setUpClass(cls): |
66 | 66 | ||
67 | # General objects: mailbox.mbox and patchset | 67 | # General objects: mailbox.mbox and patchset |
68 | cls.mbox = mailbox.mbox(PatchTestInput.repo.patch.path) | 68 | cls.mbox = mailbox.mbox(PatchtestParser.repo.patch.path) |
69 | 69 | ||
70 | # Patch may be malformed, so try parsing it | 70 | # Patch may be malformed, so try parsing it |
71 | cls.unidiff_parse_error = '' | 71 | cls.unidiff_parse_error = '' |
72 | cls.patchset = None | 72 | cls.patchset = None |
73 | try: | 73 | try: |
74 | cls.patchset = unidiff.PatchSet.from_filename(PatchTestInput.repo.patch.path, encoding=u'UTF-8') | 74 | cls.patchset = unidiff.PatchSet.from_filename( |
75 | PatchtestParser.repo.patch.path, encoding="UTF-8" | ||
76 | ) | ||
75 | except unidiff.UnidiffParseError as upe: | 77 | except unidiff.UnidiffParseError as upe: |
76 | cls.patchset = [] | 78 | cls.patchset = [] |
77 | cls.unidiff_parse_error = str(upe) | 79 | cls.unidiff_parse_error = str(upe) |
@@ -148,7 +150,7 @@ class Metadata(Base): | |||
148 | 150 | ||
149 | # import relevant libraries | 151 | # import relevant libraries |
150 | try: | 152 | try: |
151 | scripts_path = os.path.join(PatchTestInput.repodir, 'scripts', 'lib') | 153 | scripts_path = os.path.join(PatchtestParser.repodir, "scripts", "lib") |
152 | if scripts_path not in sys.path: | 154 | if scripts_path not in sys.path: |
153 | sys.path.insert(0, scripts_path) | 155 | sys.path.insert(0, scripts_path) |
154 | import scriptpath | 156 | import scriptpath |
@@ -223,11 +225,23 @@ class Metadata(Base): | |||
223 | for patch in patchset: | 225 | for patch in patchset: |
224 | if patch.path.endswith('.bb') or patch.path.endswith('.bbappend') or patch.path.endswith('.inc'): | 226 | if patch.path.endswith('.bb') or patch.path.endswith('.bbappend') or patch.path.endswith('.inc'): |
225 | if patch.is_added_file: | 227 | if patch.is_added_file: |
226 | added_paths.append(os.path.join(os.path.abspath(PatchTestInput.repodir), patch.path)) | 228 | added_paths.append( |
229 | os.path.join( | ||
230 | os.path.abspath(PatchtestParser.repodir), patch.path | ||
231 | ) | ||
232 | ) | ||
227 | elif patch.is_modified_file: | 233 | elif patch.is_modified_file: |
228 | modified_paths.append(os.path.join(os.path.abspath(PatchTestInput.repodir), patch.path)) | 234 | modified_paths.append( |
235 | os.path.join( | ||
236 | os.path.abspath(PatchtestParser.repodir), patch.path | ||
237 | ) | ||
238 | ) | ||
229 | elif patch.is_removed_file: | 239 | elif patch.is_removed_file: |
230 | removed_paths.append(os.path.join(os.path.abspath(PatchTestInput.repodir), patch.path)) | 240 | removed_paths.append( |
241 | os.path.join( | ||
242 | os.path.abspath(PatchtestParser.repodir), patch.path | ||
243 | ) | ||
244 | ) | ||
231 | 245 | ||
232 | data = cls.tinfoil.cooker.recipecaches[''].pkg_fn.items() | 246 | data = cls.tinfoil.cooker.recipecaches[''].pkg_fn.items() |
233 | 247 | ||
diff --git a/meta/lib/patchtest/tests/test_mbox.py b/meta/lib/patchtest/tests/test_mbox.py index 895ffde42b..c0f9970686 100644 --- a/meta/lib/patchtest/tests/test_mbox.py +++ b/meta/lib/patchtest/tests/test_mbox.py | |||
@@ -6,15 +6,15 @@ | |||
6 | 6 | ||
7 | import base | 7 | import base |
8 | import collections | 8 | import collections |
9 | import patterns | 9 | import patchtest_patterns |
10 | import pyparsing | 10 | import pyparsing |
11 | import re | 11 | import re |
12 | import subprocess | 12 | import subprocess |
13 | from data import PatchTestInput | 13 | from patchtest_parser import PatchtestParser |
14 | 14 | ||
15 | def headlog(): | 15 | def headlog(): |
16 | output = subprocess.check_output( | 16 | output = subprocess.check_output( |
17 | "cd %s; git log --pretty='%%h#%%aN#%%cD:#%%s' -1" % PatchTestInput.repodir, | 17 | "cd %s; git log --pretty='%%h#%%aN#%%cD:#%%s' -1" % PatchtestParser.repodir, |
18 | universal_newlines=True, | 18 | universal_newlines=True, |
19 | shell=True | 19 | shell=True |
20 | ) | 20 | ) |
@@ -45,11 +45,13 @@ class TestMbox(base.Base): | |||
45 | def test_signed_off_by_presence(self): | 45 | def test_signed_off_by_presence(self): |
46 | for commit in self.commits: | 46 | for commit in self.commits: |
47 | # skip those patches that revert older commits, these do not required the tag presence | 47 | # skip those patches that revert older commits, these do not required the tag presence |
48 | if patterns.mbox_revert_shortlog_regex.search_string(commit.shortlog): | 48 | if patchtest_patterns.mbox_revert_shortlog_regex.search_string(commit.shortlog): |
49 | continue | 49 | continue |
50 | if not patterns.signed_off_by.search_string(commit.payload): | 50 | if not patchtest_patterns.signed_off_by.search_string(commit.payload): |
51 | self.fail('Mbox is missing Signed-off-by. Add it manually or with "git commit --amend -s"', | 51 | self.fail( |
52 | commit=commit) | 52 | 'Mbox is missing Signed-off-by. Add it manually or with "git commit --amend -s"', |
53 | commit=commit, | ||
54 | ) | ||
53 | 55 | ||
54 | def test_shortlog_format(self): | 56 | def test_shortlog_format(self): |
55 | for commit in self.commits: | 57 | for commit in self.commits: |
@@ -61,7 +63,7 @@ class TestMbox(base.Base): | |||
61 | if shortlog.startswith('Revert "'): | 63 | if shortlog.startswith('Revert "'): |
62 | continue | 64 | continue |
63 | try: | 65 | try: |
64 | patterns.shortlog.parseString(shortlog) | 66 | patchtest_patterns.shortlog.parseString(shortlog) |
65 | except pyparsing.ParseException as pe: | 67 | except pyparsing.ParseException as pe: |
66 | self.fail('Commit shortlog (first line of commit message) should follow the format "<target>: <summary>"', | 68 | self.fail('Commit shortlog (first line of commit message) should follow the format "<target>: <summary>"', |
67 | commit=commit) | 69 | commit=commit) |
@@ -73,22 +75,34 @@ class TestMbox(base.Base): | |||
73 | if shortlog.startswith('Revert "'): | 75 | if shortlog.startswith('Revert "'): |
74 | continue | 76 | continue |
75 | l = len(shortlog) | 77 | l = len(shortlog) |
76 | if l > patterns.mbox_shortlog_maxlength: | 78 | if l > patchtest_patterns.mbox_shortlog_maxlength: |
77 | self.fail('Edit shortlog so that it is %d characters or less (currently %d characters)' % (patterns.mbox_shortlog_maxlength, l), | 79 | self.fail( |
78 | commit=commit) | 80 | "Edit shortlog so that it is %d characters or less (currently %d characters)" |
81 | % (patchtest_patterns.mbox_shortlog_maxlength, l), | ||
82 | commit=commit, | ||
83 | ) | ||
79 | 84 | ||
80 | def test_series_merge_on_head(self): | 85 | def test_series_merge_on_head(self): |
81 | self.skip("Merge test is disabled for now") | 86 | self.skip("Merge test is disabled for now") |
82 | if PatchTestInput.repo.patch.branch != "master": | 87 | if PatchtestParser.repo.patch.branch != "master": |
83 | self.skip( | 88 | self.skip( |
84 | "Skipping merge test since patch is not intended" | 89 | "Skipping merge test since patch is not intended" |
85 | " for master branch. Target detected is %s" | 90 | " for master branch. Target detected is %s" |
86 | % PatchTestInput.repo.patch.branch | 91 | % PatchtestParser.repo.patch.branch |
87 | ) | 92 | ) |
88 | if not PatchTestInput.repo.canbemerged: | 93 | if not PatchtestParser.repo.canbemerged: |
89 | commithash, author, date, shortlog = headlog() | 94 | commithash, author, date, shortlog = headlog() |
90 | self.fail('Series does not apply on top of target branch %s' % PatchTestInput.repo.branch, | 95 | self.fail( |
91 | data=[('Targeted branch', '%s (currently at %s)' % (PatchTestInput.repo.branch, commithash))]) | 96 | "Series does not apply on top of target branch %s" |
97 | % PatchtestParser.repo.patch.branch, | ||
98 | data=[ | ||
99 | ( | ||
100 | "Targeted branch", | ||
101 | "%s (currently at %s)" | ||
102 | % (PatchtestParser.repo.patch.branch, commithash), | ||
103 | ) | ||
104 | ], | ||
105 | ) | ||
92 | 106 | ||
93 | def test_target_mailing_list(self): | 107 | def test_target_mailing_list(self): |
94 | """Check for other targeted projects""" | 108 | """Check for other targeted projects""" |
@@ -129,19 +143,28 @@ class TestMbox(base.Base): | |||
129 | self.fail('Please include a commit message on your patch explaining the change', commit=commit) | 143 | self.fail('Please include a commit message on your patch explaining the change', commit=commit) |
130 | 144 | ||
131 | def test_bugzilla_entry_format(self): | 145 | def test_bugzilla_entry_format(self): |
132 | for commit in TestMbox.commits: | 146 | for commit in self.commits: |
133 | if not patterns.mbox_bugzilla.search_string(commit.commit_message): | 147 | if not patchtest_patterns.mbox_bugzilla.search_string(commit.commit_message): |
134 | self.skip("No bug ID found") | 148 | self.skip("No bug ID found") |
135 | elif not patterns.mbox_bugzilla_validation.search_string(commit.commit_message): | 149 | elif not patchtest_patterns.mbox_bugzilla_validation.search_string( |
136 | self.fail('Bugzilla issue ID is not correctly formatted - specify it with format: "[YOCTO #<bugzilla ID>]"', commit=commit) | 150 | commit.commit_message |
151 | ): | ||
152 | self.fail( | ||
153 | 'Bugzilla issue ID is not correctly formatted - specify it with format: "[YOCTO #<bugzilla ID>]"', | ||
154 | commit=commit, | ||
155 | ) | ||
137 | 156 | ||
138 | def test_author_valid(self): | 157 | def test_author_valid(self): |
139 | for commit in self.commits: | 158 | for commit in self.commits: |
140 | for invalid in patterns.invalid_submitters: | 159 | for invalid in patchtest_patterns.invalid_submitters: |
141 | if invalid.search_string(commit.author): | 160 | if invalid.search_string(commit.author): |
142 | self.fail('Invalid author %s. Resend the series with a valid patch author' % commit.author, commit=commit) | 161 | self.fail('Invalid author %s. Resend the series with a valid patch author' % commit.author, commit=commit) |
143 | 162 | ||
144 | def test_non_auh_upgrade(self): | 163 | def test_non_auh_upgrade(self): |
145 | for commit in self.commits: | 164 | for commit in self.commits: |
146 | if patterns.auh_email in commit.commit_message: | 165 | if patchtest_patterns.auh_email in commit.commit_message: |
147 | self.fail('Invalid author %s. Resend the series with a valid patch author' % patterns.auh_email, commit=commit) | 166 | self.fail( |
167 | "Invalid author %s. Resend the series with a valid patch author" | ||
168 | % patchtest_patterns.auh_email, | ||
169 | commit=commit, | ||
170 | ) | ||
diff --git a/meta/lib/patchtest/tests/test_metadata.py b/meta/lib/patchtest/tests/test_metadata.py index d7e5e187f6..2dee80b002 100644 --- a/meta/lib/patchtest/tests/test_metadata.py +++ b/meta/lib/patchtest/tests/test_metadata.py | |||
@@ -5,10 +5,14 @@ | |||
5 | # SPDX-License-Identifier: GPL-2.0-only | 5 | # SPDX-License-Identifier: GPL-2.0-only |
6 | 6 | ||
7 | import base | 7 | import base |
8 | import collections | ||
8 | import os | 9 | import os |
9 | import patterns | 10 | import patchtest_patterns |
10 | import pyparsing | 11 | import pyparsing |
11 | from data import PatchTestInput, PatchTestDataStore | 12 | from patchtest_parser import PatchtestParser |
13 | |||
14 | # Data store commonly used to share values between pre and post-merge tests | ||
15 | PatchTestDataStore = collections.defaultdict(str) | ||
12 | 16 | ||
13 | class TestMetadata(base.Metadata): | 17 | class TestMetadata(base.Metadata): |
14 | 18 | ||
@@ -25,13 +29,13 @@ class TestMetadata(base.Metadata): | |||
25 | open_flag = 'a' | 29 | open_flag = 'a' |
26 | with open(auto_conf, open_flag) as fd: | 30 | with open(auto_conf, open_flag) as fd: |
27 | for pn in self.added: | 31 | for pn in self.added: |
28 | fd.write('LICENSE ??= "%s"\n' % patterns.invalid_license) | 32 | fd.write('LICENSE ??= "%s"\n' % patchtest_patterns.invalid_license) |
29 | 33 | ||
30 | no_license = False | 34 | no_license = False |
31 | for pn in self.added: | 35 | for pn in self.added: |
32 | rd = self.tinfoil.parse_recipe(pn) | 36 | rd = self.tinfoil.parse_recipe(pn) |
33 | license = rd.getVar(patterns.metadata_lic) | 37 | license = rd.getVar(patchtest_patterns.metadata_lic) |
34 | if license == patterns.invalid_license: | 38 | if license == patchtest_patterns.invalid_license: |
35 | no_license = True | 39 | no_license = True |
36 | break | 40 | break |
37 | 41 | ||
@@ -58,11 +62,13 @@ class TestMetadata(base.Metadata): | |||
58 | # we are not interested in images | 62 | # we are not interested in images |
59 | if '/images/' in pathname: | 63 | if '/images/' in pathname: |
60 | continue | 64 | continue |
61 | lic_files_chksum = rd.getVar(patterns.metadata_chksum) | 65 | lic_files_chksum = rd.getVar(patchtest_patterns.metadata_chksum) |
62 | if rd.getVar(patterns.license_var) == patterns.closed: | 66 | if rd.getVar(patchtest_patterns.license_var) == patchtest_patterns.closed: |
63 | continue | 67 | continue |
64 | if not lic_files_chksum: | 68 | if not lic_files_chksum: |
65 | self.fail('%s is missing in newly added recipe' % patterns.metadata_chksum) | 69 | self.fail( |
70 | "%s is missing in newly added recipe" % patchtest_patterns.metadata_chksum | ||
71 | ) | ||
66 | 72 | ||
67 | def test_lic_files_chksum_modified_not_mentioned(self): | 73 | def test_lic_files_chksum_modified_not_mentioned(self): |
68 | if not self.modified: | 74 | if not self.modified: |
@@ -73,11 +79,13 @@ class TestMetadata(base.Metadata): | |||
73 | if patch.path.endswith('.patch'): | 79 | if patch.path.endswith('.patch'): |
74 | continue | 80 | continue |
75 | payload = str(patch) | 81 | payload = str(patch) |
76 | if (patterns.lic_chksum_added.search_string(payload) or patterns.lic_chksum_removed.search_string(payload)): | 82 | if patchtest_patterns.lic_chksum_added.search_string( |
83 | payload | ||
84 | ) or patchtest_patterns.lic_chksum_removed.search_string(payload): | ||
77 | # if any patch on the series contain reference on the metadata, fail | 85 | # if any patch on the series contain reference on the metadata, fail |
78 | for commit in self.commits: | 86 | for commit in self.commits: |
79 | if patterns.lictag_re.search_string(commit.commit_message): | 87 | if patchtest_patterns.lictag_re.search_string(commit.commit_message): |
80 | break | 88 | break |
81 | else: | 89 | else: |
82 | self.fail('LIC_FILES_CHKSUM changed without "License-Update:" tag and description in commit message') | 90 | self.fail('LIC_FILES_CHKSUM changed without "License-Update:" tag and description in commit message') |
83 | 91 | ||
@@ -88,16 +96,22 @@ class TestMetadata(base.Metadata): | |||
88 | continue | 96 | continue |
89 | payload = str(patch) | 97 | payload = str(patch) |
90 | for line in payload.splitlines(): | 98 | for line in payload.splitlines(): |
91 | if patterns.add_mark.search_string(line): | 99 | if patchtest_patterns.add_mark.search_string(line): |
92 | current_line_length = len(line[1:]) | 100 | current_line_length = len(line[1:]) |
93 | if current_line_length > patterns.patch_max_line_length: | 101 | if current_line_length > patchtest_patterns.patch_max_line_length: |
94 | self.fail('Patch line too long (current length %s, maximum is %s)' % (current_line_length, patterns.patch_max_line_length), | 102 | self.fail( |
95 | data=[('Patch', patch.path), ('Line', '%s ...' % line[0:80])]) | 103 | "Patch line too long (current length %s, maximum is %s)" |
104 | % (current_line_length, patchtest_patterns.patch_max_line_length), | ||
105 | data=[ | ||
106 | ("Patch", patch.path), | ||
107 | ("Line", "%s ..." % line[0:80]), | ||
108 | ], | ||
109 | ) | ||
96 | 110 | ||
97 | def pretest_src_uri_left_files(self): | 111 | def pretest_src_uri_left_files(self): |
98 | # these tests just make sense on patches that can be merged | 112 | # these tests just make sense on patches that can be merged |
99 | if not PatchTestInput.repo.canbemerged: | 113 | if not PatchtestParser.repo.canbemerged: |
100 | self.skip('Patch cannot be merged') | 114 | self.skip("Patch cannot be merged") |
101 | if not self.modified: | 115 | if not self.modified: |
102 | self.skip('No modified recipes, skipping pretest') | 116 | self.skip('No modified recipes, skipping pretest') |
103 | 117 | ||
@@ -107,12 +121,14 @@ class TestMetadata(base.Metadata): | |||
107 | if 'core-image' in pn: | 121 | if 'core-image' in pn: |
108 | continue | 122 | continue |
109 | rd = self.tinfoil.parse_recipe(pn) | 123 | rd = self.tinfoil.parse_recipe(pn) |
110 | PatchTestDataStore['%s-%s-%s' % (self.shortid(), patterns.metadata_src_uri, pn)] = rd.getVar(patterns.metadata_src_uri) | 124 | PatchTestDataStore[ |
125 | "%s-%s-%s" % (self.shortid(), patchtest_patterns.metadata_src_uri, pn) | ||
126 | ] = rd.getVar(patchtest_patterns.metadata_src_uri) | ||
111 | 127 | ||
112 | def test_src_uri_left_files(self): | 128 | def test_src_uri_left_files(self): |
113 | # these tests just make sense on patches that can be merged | 129 | # these tests just make sense on patches that can be merged |
114 | if not PatchTestInput.repo.canbemerged: | 130 | if not PatchtestParser.repo.canbemerged: |
115 | self.skip('Patch cannot be merged') | 131 | self.skip("Patch cannot be merged") |
116 | if not self.modified: | 132 | if not self.modified: |
117 | self.skip('No modified recipes, skipping pretest') | 133 | self.skip('No modified recipes, skipping pretest') |
118 | 134 | ||
@@ -122,11 +138,17 @@ class TestMetadata(base.Metadata): | |||
122 | if 'core-image' in pn: | 138 | if 'core-image' in pn: |
123 | continue | 139 | continue |
124 | rd = self.tinfoil.parse_recipe(pn) | 140 | rd = self.tinfoil.parse_recipe(pn) |
125 | PatchTestDataStore['%s-%s-%s' % (self.shortid(), patterns.metadata_src_uri, pn)] = rd.getVar(patterns.metadata_src_uri) | 141 | PatchTestDataStore[ |
142 | "%s-%s-%s" % (self.shortid(), patchtest_patterns.metadata_src_uri, pn) | ||
143 | ] = rd.getVar(patchtest_patterns.metadata_src_uri) | ||
126 | 144 | ||
127 | for pn in self.modified: | 145 | for pn in self.modified: |
128 | pretest_src_uri = PatchTestDataStore['pre%s-%s-%s' % (self.shortid(), patterns.metadata_src_uri, pn)].split() | 146 | pretest_src_uri = PatchTestDataStore[ |
129 | test_src_uri = PatchTestDataStore['%s-%s-%s' % (self.shortid(), patterns.metadata_src_uri, pn)].split() | 147 | "pre%s-%s-%s" % (self.shortid(), patchtest_patterns.metadata_src_uri, pn) |
148 | ].split() | ||
149 | test_src_uri = PatchTestDataStore[ | ||
150 | "%s-%s-%s" % (self.shortid(), patchtest_patterns.metadata_src_uri, pn) | ||
151 | ].split() | ||
130 | 152 | ||
131 | pretest_files = set([os.path.basename(patch) for patch in pretest_src_uri if patch.startswith('file://')]) | 153 | pretest_files = set([os.path.basename(patch) for patch in pretest_src_uri if patch.startswith('file://')]) |
132 | test_files = set([os.path.basename(patch) for patch in test_src_uri if patch.startswith('file://')]) | 154 | test_files = set([os.path.basename(patch) for patch in test_src_uri if patch.startswith('file://')]) |
@@ -159,23 +181,32 @@ class TestMetadata(base.Metadata): | |||
159 | if 'core-image' in pn: | 181 | if 'core-image' in pn: |
160 | continue | 182 | continue |
161 | rd = self.tinfoil.parse_recipe(pn) | 183 | rd = self.tinfoil.parse_recipe(pn) |
162 | summary = rd.getVar(patterns.metadata_summary) | 184 | summary = rd.getVar(patchtest_patterns.metadata_summary) |
163 | 185 | ||
164 | # "${PN} version ${PN}-${PR}" is the default, so fail if default | 186 | # "${PN} version ${PN}-${PR}" is the default, so fail if default |
165 | if summary.startswith('%s version' % pn): | 187 | if summary.startswith("%s version" % pn): |
166 | self.fail('%s is missing in newly added recipe' % patterns.metadata_summary) | 188 | self.fail( |
189 | "%s is missing in newly added recipe" % patchtest_patterns.metadata_summary | ||
190 | ) | ||
167 | 191 | ||
168 | def test_cve_check_ignore(self): | 192 | def test_cve_check_ignore(self): |
169 | # Skip if we neither modified a recipe or target branches are not | 193 | # Skip if we neither modified a recipe or target branches are not |
170 | # Nanbield and newer. CVE_CHECK_IGNORE was first deprecated in Nanbield. | 194 | # Nanbield and newer. CVE_CHECK_IGNORE was first deprecated in Nanbield. |
171 | if not self.modified or PatchTestInput.repo.patch.branch == "kirkstone" or PatchTestInput.repo.patch.branch == "dunfell": | 195 | if ( |
172 | self.skip('No modified recipes or older target branch, skipping test') | 196 | not self.modified |
197 | or PatchtestParser.repo.patch.branch == "kirkstone" | ||
198 | or PatchtestParser.repo.patch.branch == "dunfell" | ||
199 | ): | ||
200 | self.skip("No modified recipes or older target branch, skipping test") | ||
173 | for pn in self.modified: | 201 | for pn in self.modified: |
174 | # we are not interested in images | 202 | # we are not interested in images |
175 | if 'core-image' in pn: | 203 | if 'core-image' in pn: |
176 | continue | 204 | continue |
177 | rd = self.tinfoil.parse_recipe(pn) | 205 | rd = self.tinfoil.parse_recipe(pn) |
178 | cve_check_ignore = rd.getVar(patterns.cve_check_ignore_var) | 206 | cve_check_ignore = rd.getVar(patchtest_patterns.cve_check_ignore_var) |
179 | 207 | ||
180 | if cve_check_ignore is not None: | 208 | if cve_check_ignore is not None: |
181 | self.fail('%s is deprecated and should be replaced by %s' % (patterns.cve_check_ignore_var, patterns.cve_status_var)) | 209 | self.fail( |
210 | "%s is deprecated and should be replaced by %s" | ||
211 | % (patchtest_patterns.cve_check_ignore_var, patchtest_patterns.cve_status_var) | ||
212 | ) | ||
diff --git a/meta/lib/patchtest/tests/test_patch.py b/meta/lib/patchtest/tests/test_patch.py index d856b216f0..d08b8a5019 100644 --- a/meta/lib/patchtest/tests/test_patch.py +++ b/meta/lib/patchtest/tests/test_patch.py | |||
@@ -7,7 +7,7 @@ | |||
7 | 7 | ||
8 | import base | 8 | import base |
9 | import os | 9 | import os |
10 | import patterns | 10 | import patchtest_patterns |
11 | import pyparsing | 11 | import pyparsing |
12 | 12 | ||
13 | class TestPatch(base.Base): | 13 | class TestPatch(base.Base): |
@@ -20,17 +20,17 @@ class TestPatch(base.Base): | |||
20 | if patch.path.endswith('.patch') and patch.is_added_file: | 20 | if patch.path.endswith('.patch') and patch.is_added_file: |
21 | cls.newpatches.append(patch) | 21 | cls.newpatches.append(patch) |
22 | 22 | ||
23 | cls.mark = str(patterns.signed_off_by_prefix).strip('"') | 23 | cls.mark = str(patchtest_patterns.signed_off_by_prefix).strip('"') |
24 | 24 | ||
25 | # match PatchSignedOffBy.mark with '+' preceding it | 25 | # match PatchSignedOffBy.mark with '+' preceding it |
26 | cls.prog = patterns.patch_signed_off_by | 26 | cls.prog = patchtest_patterns.patch_signed_off_by |
27 | 27 | ||
28 | def setUp(self): | 28 | def setUp(self): |
29 | if self.unidiff_parse_error: | 29 | if self.unidiff_parse_error: |
30 | self.skip('Parse error %s' % self.unidiff_parse_error) | 30 | self.skip('Parse error %s' % self.unidiff_parse_error) |
31 | 31 | ||
32 | self.valid_status = ', '.join(patterns.upstream_status_nonliteral_valid_status) | 32 | self.valid_status = ", ".join(patchtest_patterns.upstream_status_nonliteral_valid_status) |
33 | self.standard_format = 'Upstream-Status: <Valid status>' | 33 | self.standard_format = "Upstream-Status: <Valid status>" |
34 | 34 | ||
35 | # we are just interested in series that introduce CVE patches, thus discard other | 35 | # we are just interested in series that introduce CVE patches, thus discard other |
36 | # possibilities: modification to current CVEs, patch directly introduced into the | 36 | # possibilities: modification to current CVEs, patch directly introduced into the |
@@ -45,31 +45,62 @@ class TestPatch(base.Base): | |||
45 | 45 | ||
46 | for newpatch in TestPatch.newpatches: | 46 | for newpatch in TestPatch.newpatches: |
47 | payload = newpatch.__str__() | 47 | payload = newpatch.__str__() |
48 | if not patterns.upstream_status_regex.search_string(payload): | 48 | if not patchtest_patterns.upstream_status_regex.search_string(payload): |
49 | self.fail('Added patch file is missing Upstream-Status: <Valid status> in the commit message', | 49 | self.fail( |
50 | data=[('Standard format', self.standard_format), ('Valid status', self.valid_status)]) | 50 | "Added patch file is missing Upstream-Status: <Valid status> in the commit message", |
51 | data=[ | ||
52 | ("Standard format", self.standard_format), | ||
53 | ("Valid status", self.valid_status), | ||
54 | ], | ||
55 | ) | ||
51 | for line in payload.splitlines(): | 56 | for line in payload.splitlines(): |
52 | if self.patchmetadata_regex.match(line): | 57 | if patchtest_patterns.patchmetadata_regex.match(line): |
53 | continue | 58 | continue |
54 | if patterns.upstream_status_regex.search_string(line): | 59 | if patchtest_patterns.upstream_status_regex.search_string(line): |
55 | if patterns.inappropriate.searchString(line): | 60 | if patchtest_patterns.inappropriate.searchString(line): |
56 | try: | 61 | try: |
57 | patterns.upstream_status_inappropriate_info.parseString(line.lstrip('+')) | 62 | patchtest_patterns.upstream_status_inappropriate_info.parseString( |
58 | except pyparsing.ParseException as pe: | 63 | line.lstrip("+") |
59 | self.fail('Upstream-Status is Inappropriate, but no reason was provided', | 64 | ) |
60 | data=[('Current', pe.pstr), ('Standard format', 'Upstream-Status: Inappropriate [reason]')]) | 65 | except pyparsing.ParseException as pe: |
61 | elif patterns.submitted.searchString(line): | 66 | self.fail( |
62 | try: | 67 | "Upstream-Status is Inappropriate, but no reason was provided", |
63 | patterns.upstream_status_submitted_info.parseString(line.lstrip('+')) | 68 | data=[ |
64 | except pyparsing.ParseException as pe: | 69 | ("Current", pe.pstr), |
65 | self.fail('Upstream-Status is Submitted, but it is not mentioned where', | 70 | ( |
66 | data=[('Current', pe.pstr), ('Standard format', 'Upstream-Status: Submitted [where]')]) | 71 | "Standard format", |
67 | else: | 72 | "Upstream-Status: Inappropriate [reason]", |
68 | try: | 73 | ), |
69 | patterns.upstream_status.parseString(line.lstrip('+')) | 74 | ], |
70 | except pyparsing.ParseException as pe: | 75 | ) |
71 | self.fail('Upstream-Status is in incorrect format', | 76 | elif patchtest_patterns.submitted.searchString(line): |
72 | data=[('Current', pe.pstr), ('Standard format', self.standard_format), ('Valid status', self.valid_status)]) | 77 | try: |
78 | patchtest_patterns.upstream_status_submitted_info.parseString( | ||
79 | line.lstrip("+") | ||
80 | ) | ||
81 | except pyparsing.ParseException as pe: | ||
82 | self.fail( | ||
83 | "Upstream-Status is Submitted, but it is not mentioned where", | ||
84 | data=[ | ||
85 | ("Current", pe.pstr), | ||
86 | ( | ||
87 | "Standard format", | ||
88 | "Upstream-Status: Submitted [where]", | ||
89 | ), | ||
90 | ], | ||
91 | ) | ||
92 | else: | ||
93 | try: | ||
94 | patchtest_patterns.upstream_status.parseString(line.lstrip("+")) | ||
95 | except pyparsing.ParseException as pe: | ||
96 | self.fail( | ||
97 | "Upstream-Status is in incorrect format", | ||
98 | data=[ | ||
99 | ("Current", pe.pstr), | ||
100 | ("Standard format", self.standard_format), | ||
101 | ("Valid status", self.valid_status), | ||
102 | ], | ||
103 | ) | ||
73 | 104 | ||
74 | def test_signed_off_by_presence(self): | 105 | def test_signed_off_by_presence(self): |
75 | if not TestPatch.newpatches: | 106 | if not TestPatch.newpatches: |
@@ -78,7 +109,7 @@ class TestPatch(base.Base): | |||
78 | for newpatch in TestPatch.newpatches: | 109 | for newpatch in TestPatch.newpatches: |
79 | payload = newpatch.__str__() | 110 | payload = newpatch.__str__() |
80 | for line in payload.splitlines(): | 111 | for line in payload.splitlines(): |
81 | if self.patchmetadata_regex.match(line): | 112 | if patchtest_patterns.patchmetadata_regex.match(line): |
82 | continue | 113 | continue |
83 | if TestPatch.prog.search_string(payload): | 114 | if TestPatch.prog.search_string(payload): |
84 | break | 115 | break |
@@ -87,10 +118,12 @@ class TestPatch(base.Base): | |||
87 | 118 | ||
88 | def test_cve_tag_format(self): | 119 | def test_cve_tag_format(self): |
89 | for commit in TestPatch.commits: | 120 | for commit in TestPatch.commits: |
90 | if patterns.cve.search_string(commit.shortlog) or patterns.cve.search_string(commit.commit_message): | 121 | if patchtest_patterns.cve.search_string( |
122 | commit.shortlog | ||
123 | ) or patchtest_patterns.cve.search_string(commit.commit_message): | ||
91 | tag_found = False | 124 | tag_found = False |
92 | for line in commit.payload.splitlines(): | 125 | for line in commit.payload.splitlines(): |
93 | if patterns.cve_payload_tag.search_string(line): | 126 | if patchtest_patterns.cve_payload_tag.search_string(line): |
94 | tag_found = True | 127 | tag_found = True |
95 | break | 128 | break |
96 | if not tag_found: | 129 | if not tag_found: |
diff --git a/meta/lib/patchtest/tests/test_python_pylint.py b/meta/lib/patchtest/tests/test_python_pylint.py index b03fd6f4f6..ec9129bc79 100644 --- a/meta/lib/patchtest/tests/test_python_pylint.py +++ b/meta/lib/patchtest/tests/test_python_pylint.py | |||
@@ -5,9 +5,8 @@ | |||
5 | # SPDX-License-Identifier: GPL-2.0-only | 5 | # SPDX-License-Identifier: GPL-2.0-only |
6 | 6 | ||
7 | import base | 7 | import base |
8 | import patterns | ||
9 | from io import StringIO | 8 | from io import StringIO |
10 | from data import PatchTestInput | 9 | from patchtest_parser import PatchtestParser |
11 | from pylint.reporters.text import TextReporter | 10 | from pylint.reporters.text import TextReporter |
12 | import pylint.lint as lint | 11 | import pylint.lint as lint |
13 | 12 | ||