summaryrefslogtreecommitdiffstats
path: root/meta/lib/patchtest
diff options
context:
space:
mode:
authorTrevor Gamblin <tgamblin@baylibre.com>2024-09-24 07:55:01 -0400
committerRichard Purdie <richard.purdie@linuxfoundation.org>2024-09-30 17:00:50 +0100
commit4c378fc89566a329d0974bbcfefc7405779bc919 (patch)
tree4175c6d63b024e39dc9a7f02a77f1ff3cab8088f /meta/lib/patchtest
parent18a65c77c0e729dd1835852336e57ff4922f2674 (diff)
downloadpoky-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.py48
-rw-r--r--meta/lib/patchtest/tests/test_mbox.py69
-rw-r--r--meta/lib/patchtest/tests/test_metadata.py91
-rw-r--r--meta/lib/patchtest/tests/test_patch.py95
-rw-r--r--meta/lib/patchtest/tests/test_python_pylint.py3
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
16import os 16import os
17import argparse 17import argparse
18import collections
19import logging
20
21logger=logging.getLogger('patchtest')
22info=logger.info
23 18
24default_testdir = os.path.abspath(os.path.dirname(__file__) + "/tests") 19default_testdir = os.path.abspath(os.path.dirname(__file__) + "/tests")
25default_repodir = os.path.abspath(os.path.dirname(__file__) + "/../../..") 20default_repodir = os.path.abspath(os.path.dirname(__file__) + "/../../..")
26 21
27# Data store commonly used to share values between pre and post-merge tests 22class PatchtestParser(object):
28PatchTestDataStore = collections.defaultdict(str)
29
30class 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
7import pyparsing 7import pyparsing
8import re
8 9
9# general 10# general
10colon = pyparsing.Literal(":") 11colon = pyparsing.Literal(":")
@@ -34,10 +35,16 @@ lic_chksum_added = pyparsing.AtLineStart("+" + metadata_chksum)
34lic_chksum_removed = pyparsing.AtLineStart("-" + metadata_chksum) 35lic_chksum_removed = pyparsing.AtLineStart("-" + metadata_chksum)
35add_mark = pyparsing.Regex('\\+ ') 36add_mark = pyparsing.Regex('\\+ ')
36patch_max_line_length = 200 37patch_max_line_length = 200
37metadata_src_uri = 'SRC_URI' 38metadata_src_uri = "SRC_URI"
38metadata_summary = 'SUMMARY' 39metadata_summary = "SUMMARY"
39cve_check_ignore_var = 'CVE_CHECK_IGNORE' 40cve_check_ignore_var = "CVE_CHECK_IGNORE"
40cve_status_var = 'CVE_STATUS' 41cve_status_var = "CVE_STATUS"
42endcommit_messages_regex = re.compile(
43 r"\(From \w+-\w+ rev:|(?<!\S)Signed-off-by|(?<!\S)---\n"
44)
45patchmetadata_regex = re.compile(
46 r"-{3} \S+|\+{3} \S+|@{2} -\d+,\d+ \+\d+,\d+ @{2} \S+"
47)
41 48
42# mbox 49# mbox
43auh_email = 'auh@yoctoproject.org' 50auh_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
8import logging 8import logging
9import json 9import json
10import unidiff 10import unidiff
11from data import PatchTestInput 11from patchtest_parser import PatchtestParser
12import mailbox 12import mailbox
13import patchtest_patterns
13import collections 14import collections
14import sys 15import sys
15import os 16import os
16import re 17import re
17 18
18sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'pyparsing')) 19logger = logging.getLogger("patchtest")
20debug = logger.debug
21info = logger.info
22warn = logger.warn
23error = logger.error
19 24
20logger = logging.getLogger('patchtest') 25Commit = collections.namedtuple(
21debug=logger.debug 26 "Commit", ["author", "subject", "commit_message", "shortlog", "payload"]
22info=logger.info 27)
23warn=logger.warn
24error=logger.error
25 28
26Commit = collections.namedtuple('Commit', ['author', 'subject', 'commit_message', 'shortlog', 'payload']) 29Commit = collections.namedtuple('Commit', ['author', 'subject', 'commit_message', 'shortlog', 'payload'])
27 30
@@ -34,9 +37,6 @@ class PatchtestOEError(Exception):
34class Base(unittest.TestCase): 37class 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
7import base 7import base
8import collections 8import collections
9import patterns 9import patchtest_patterns
10import pyparsing 10import pyparsing
11import re 11import re
12import subprocess 12import subprocess
13from data import PatchTestInput 13from patchtest_parser import PatchtestParser
14 14
15def headlog(): 15def 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
7import base 7import base
8import collections
8import os 9import os
9import patterns 10import patchtest_patterns
10import pyparsing 11import pyparsing
11from data import PatchTestInput, PatchTestDataStore 12from patchtest_parser import PatchtestParser
13
14# Data store commonly used to share values between pre and post-merge tests
15PatchTestDataStore = collections.defaultdict(str)
12 16
13class TestMetadata(base.Metadata): 17class 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
8import base 8import base
9import os 9import os
10import patterns 10import patchtest_patterns
11import pyparsing 11import pyparsing
12 12
13class TestPatch(base.Base): 13class 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
7import base 7import base
8import patterns
9from io import StringIO 8from io import StringIO
10from data import PatchTestInput 9from patchtest_parser import PatchtestParser
11from pylint.reporters.text import TextReporter 10from pylint.reporters.text import TextReporter
12import pylint.lint as lint 11import pylint.lint as lint
13 12