summaryrefslogtreecommitdiffstats
path: root/meta/lib/patchtest
diff options
context:
space:
mode:
authorTrevor Gamblin <tgamblin@baylibre.com>2024-09-24 07:54:58 -0400
committerRichard Purdie <richard.purdie@linuxfoundation.org>2024-09-30 17:00:50 +0100
commitbb0f1625d7655d04c6df3c144e488f676ff2f762 (patch)
tree3e3a07f71c4e1950f5e7cc47dbdd1605888d0d16 /meta/lib/patchtest
parentdd3a73961b49b508771a8cd579ebf1004f786f12 (diff)
downloadpoky-bb0f1625d7655d04c6df3c144e488f676ff2f762.tar.gz
patchtest: patterns: add module, refactor
Currently, patchtest has a lot of spread-out definitions for patterns used in various setup and test functions. Organize these by putting them all into a new patterns.py module. This allows the tests/pyparsing directory to be removed, as it is now redundant. Also remove some definitions where they were duplicated or unused, and perform some renames to improve readability and avoid collisions. Many of these variables are composed from others, so the file is only partially sorted. (From OE-Core rev: 1ab55d495957918be532a36224b5598c9955a44d) 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/patterns.py92
-rw-r--r--meta/lib/patchtest/tests/pyparsing/common.py26
-rw-r--r--meta/lib/patchtest/tests/pyparsing/parse_cve_tags.py18
-rw-r--r--meta/lib/patchtest/tests/pyparsing/parse_shortlog.py14
-rw-r--r--meta/lib/patchtest/tests/pyparsing/parse_signed_off_by.py22
-rw-r--r--meta/lib/patchtest/tests/pyparsing/parse_upstream_status.py24
-rw-r--r--meta/lib/patchtest/tests/test_mbox.py36
-rw-r--r--meta/lib/patchtest/tests/test_metadata.py56
-rw-r--r--meta/lib/patchtest/tests/test_patch.py31
-rw-r--r--meta/lib/patchtest/tests/test_python_pylint.py1
10 files changed, 137 insertions, 183 deletions
diff --git a/meta/lib/patchtest/patterns.py b/meta/lib/patchtest/patterns.py
new file mode 100644
index 0000000000..ba97a4ffe9
--- /dev/null
+++ b/meta/lib/patchtest/patterns.py
@@ -0,0 +1,92 @@
1# common pyparsing variables
2#
3# Copyright (C) 2016 Intel Corporation
4#
5# SPDX-License-Identifier: GPL-2.0-only
6
7import pyparsing
8
9# general
10colon = pyparsing.Literal(":")
11line_start = pyparsing.LineStart()
12line_end = pyparsing.LineEnd()
13at = pyparsing.Literal("@")
14lessthan = pyparsing.Literal("<")
15greaterthan = pyparsing.Literal(">")
16opensquare = pyparsing.Literal("[")
17closesquare = pyparsing.Literal("]")
18inappropriate = pyparsing.CaselessLiteral("Inappropriate")
19submitted = pyparsing.CaselessLiteral("Submitted")
20
21# word related
22nestexpr = pyparsing.nestedExpr(opener='[', closer=']')
23inappropriateinfo = pyparsing.Literal("Inappropriate") + nestexpr
24submittedinfo = pyparsing.Literal("Submitted") + nestexpr
25word = pyparsing.Word(pyparsing.alphas)
26worddot = pyparsing.Word(pyparsing.alphas+".")
27
28# metadata
29
30metadata_lic = 'LICENSE'
31invalid_license = 'PATCHTESTINVALID'
32metadata_chksum = 'LIC_FILES_CHKSUM'
33license_var = 'LICENSE'
34closed = 'CLOSED'
35lictag_re = pyparsing.AtLineStart("License-Update:")
36lic_chksum_added = pyparsing.AtLineStart("+" + metadata_chksum)
37lic_chksum_removed = pyparsing.AtLineStart("-" + metadata_chksum)
38add_mark = pyparsing.Regex('\\+ ')
39patch_max_line_length = 200
40metadata_src_uri = 'SRC_URI'
41metadata_summary = 'SUMMARY'
42cve_check_ignore_var = 'CVE_CHECK_IGNORE'
43cve_status_var = 'CVE_STATUS'
44
45# mbox
46auh_email = 'auh@yoctoproject.org'
47
48invalid_submitters = [pyparsing.Regex("^Upgrade Helper.+"),
49 pyparsing.Regex(auh_email),
50 pyparsing.Regex("uh@not\.set"),
51 pyparsing.Regex("\S+@example\.com")]
52
53mbox_bugzilla = pyparsing.Regex('\[\s?YOCTO.*\]')
54mbox_bugzilla_validation = pyparsing.Regex('\[(\s?YOCTO\s?#\s?(\d+)\s?,?)+\]')
55mbox_revert_shortlog_regex = pyparsing.Regex('Revert\s+".*"')
56mbox_shortlog_maxlength = 90
57
58# patch
59
60cve = pyparsing.Regex("CVE\-\d{4}\-\d+")
61cve_payload_tag = pyparsing.Regex("\+CVE:(\s+CVE\-\d{4}\-\d+)+")
62upstream_status_regex = pyparsing.AtLineStart("+" + "Upstream-Status")
63
64# shortlog
65
66shortlog_target = pyparsing.OneOrMore(pyparsing.Word(pyparsing.printables.replace(':','')))
67shortlog_summary = pyparsing.OneOrMore(pyparsing.Word(pyparsing.printables))
68shortlog = line_start + shortlog_target + colon + shortlog_summary + line_end
69
70# signed-off-bys
71
72email_pattern = pyparsing.Regex(r"(?P<user>[A-Za-z0-9._%+-]+)@(?P<hostname>[A-Za-z0-9.-]+)\.(?P<domain>[A-Za-z]{2,})")
73
74signed_off_by_prefix = pyparsing.Literal("Signed-off-by:")
75signed_off_by_name = pyparsing.Regex('\S+.*(?= <)')
76signed_off_by_email = lessthan + email_pattern + greaterthan
77signed_off_by = pyparsing.AtLineStart(signed_off_by_prefix + signed_off_by_name + signed_off_by_email)
78patch_signed_off_by = pyparsing.AtLineStart("+" + signed_off_by_prefix + signed_off_by_name + signed_off_by_email)
79
80# upstream-status
81
82upstream_status_literal_valid_status = ["Pending", "Backport", "Denied", "Inappropriate", "Submitted"]
83upstream_status_nonliteral_valid_status = ["Pending", "Backport", "Denied", "Inappropriate [reason]", "Submitted [where]"]
84
85upstream_status_valid_status = pyparsing.Or(
86 [pyparsing.Literal(status) for status in upstream_status_literal_valid_status]
87)
88
89upstream_status_prefix = pyparsing.Literal("Upstream-Status")
90upstream_status = line_start + upstream_status_prefix + colon + upstream_status_valid_status
91upstream_status_inappropriate_info = line_start + upstream_status_prefix + colon + inappropriateinfo
92upstream_status_submitted_info = line_start + upstream_status_prefix + colon + submittedinfo
diff --git a/meta/lib/patchtest/tests/pyparsing/common.py b/meta/lib/patchtest/tests/pyparsing/common.py
deleted file mode 100644
index cbce4c38bc..0000000000
--- a/meta/lib/patchtest/tests/pyparsing/common.py
+++ /dev/null
@@ -1,26 +0,0 @@
1# common pyparsing variables
2#
3# Copyright (C) 2016 Intel Corporation
4#
5# SPDX-License-Identifier: GPL-2.0-only
6
7import pyparsing
8
9# general
10colon = pyparsing.Literal(":")
11start = pyparsing.LineStart()
12end = pyparsing.LineEnd()
13at = pyparsing.Literal("@")
14lessthan = pyparsing.Literal("<")
15greaterthan = pyparsing.Literal(">")
16opensquare = pyparsing.Literal("[")
17closesquare = pyparsing.Literal("]")
18inappropriate = pyparsing.CaselessLiteral("Inappropriate")
19submitted = pyparsing.CaselessLiteral("Submitted")
20
21# word related
22nestexpr = pyparsing.nestedExpr(opener='[', closer=']')
23inappropriateinfo = pyparsing.Literal("Inappropriate") + nestexpr
24submittedinfo = pyparsing.Literal("Submitted") + nestexpr
25word = pyparsing.Word(pyparsing.alphas)
26worddot = pyparsing.Word(pyparsing.alphas+".")
diff --git a/meta/lib/patchtest/tests/pyparsing/parse_cve_tags.py b/meta/lib/patchtest/tests/pyparsing/parse_cve_tags.py
deleted file mode 100644
index f7fb82ec2b..0000000000
--- a/meta/lib/patchtest/tests/pyparsing/parse_cve_tags.py
+++ /dev/null
@@ -1,18 +0,0 @@
1# signed-off-by pyparsing definition
2#
3# Copyright (C) 2016 Intel Corporation
4#
5# SPDX-License-Identifier: GPL-2.0-only
6
7
8import pyparsing
9import common
10
11name = pyparsing.Regex('\S+.*(?= <)')
12username = pyparsing.OneOrMore(common.worddot)
13domain = pyparsing.OneOrMore(common.worddot)
14cve = pyparsing.Regex('CVE\-\d{4}\-\d+')
15cve_mark = pyparsing.Literal("CVE:")
16
17cve_tag = pyparsing.AtLineStart(cve_mark + cve)
18patch_cve_tag = pyparsing.AtLineStart("+" + cve_mark + cve)
diff --git a/meta/lib/patchtest/tests/pyparsing/parse_shortlog.py b/meta/lib/patchtest/tests/pyparsing/parse_shortlog.py
deleted file mode 100644
index 30d3ab35b3..0000000000
--- a/meta/lib/patchtest/tests/pyparsing/parse_shortlog.py
+++ /dev/null
@@ -1,14 +0,0 @@
1# subject pyparsing definition
2#
3# Copyright (C) 2016 Intel Corporation
4#
5# SPDX-License-Identifier: GPL-2.0-only
6
7# NOTE:This is an oversimplified syntax of the mbox's summary
8
9import pyparsing
10import common
11
12target = pyparsing.OneOrMore(pyparsing.Word(pyparsing.printables.replace(':','')))
13summary = pyparsing.OneOrMore(pyparsing.Word(pyparsing.printables))
14shortlog = common.start + target + common.colon + summary + common.end
diff --git a/meta/lib/patchtest/tests/pyparsing/parse_signed_off_by.py b/meta/lib/patchtest/tests/pyparsing/parse_signed_off_by.py
deleted file mode 100644
index 692ebec3ff..0000000000
--- a/meta/lib/patchtest/tests/pyparsing/parse_signed_off_by.py
+++ /dev/null
@@ -1,22 +0,0 @@
1# signed-off-by pyparsing definition
2#
3# Copyright (C) 2016 Intel Corporation
4#
5# SPDX-License-Identifier: GPL-2.0-only
6
7
8import pyparsing
9import common
10
11name = pyparsing.Regex('\S+.*(?= <)')
12username = pyparsing.OneOrMore(common.worddot)
13domain = pyparsing.OneOrMore(common.worddot)
14
15# taken from https://pyparsing-public.wikispaces.com/Helpful+Expressions
16email = pyparsing.Regex(r"(?P<user>[A-Za-z0-9._%+-]+)@(?P<hostname>[A-Za-z0-9.-]+)\.(?P<domain>[A-Za-z]{2,})")
17
18email_enclosed = common.lessthan + email + common.greaterthan
19
20signed_off_by_mark = pyparsing.Literal("Signed-off-by:")
21signed_off_by = pyparsing.AtLineStart(signed_off_by_mark + name + email_enclosed)
22patch_signed_off_by = pyparsing.AtLineStart("+" + signed_off_by_mark + name + email_enclosed)
diff --git a/meta/lib/patchtest/tests/pyparsing/parse_upstream_status.py b/meta/lib/patchtest/tests/pyparsing/parse_upstream_status.py
deleted file mode 100644
index bc6c427c4c..0000000000
--- a/meta/lib/patchtest/tests/pyparsing/parse_upstream_status.py
+++ /dev/null
@@ -1,24 +0,0 @@
1# upstream-status pyparsing definition
2#
3# Copyright (C) 2016 Intel Corporation
4#
5# SPDX-License-Identifier: GPL-2.0-only
6
7
8import common
9import pyparsing
10
11upstream_status_literal_valid_status = ["Pending", "Backport", "Denied", "Inappropriate", "Submitted"]
12upstream_status_nonliteral_valid_status = ["Pending", "Backport", "Denied", "Inappropriate [reason]", "Submitted [where]"]
13
14upstream_status_valid_status = pyparsing.Or(
15 [pyparsing.Literal(status) for status in upstream_status_literal_valid_status]
16)
17
18upstream_status_mark = pyparsing.Literal("Upstream-Status")
19inappropriate_status_mark = common.inappropriate
20submitted_status_mark = common.submitted
21
22upstream_status = common.start + upstream_status_mark + common.colon + upstream_status_valid_status
23upstream_status_inappropriate_info = common.start + upstream_status_mark + common.colon + common.inappropriateinfo
24upstream_status_submitted_info = common.start + upstream_status_mark + common.colon + common.submittedinfo
diff --git a/meta/lib/patchtest/tests/test_mbox.py b/meta/lib/patchtest/tests/test_mbox.py
index cd76e58a71..e6b8ad21f8 100644
--- a/meta/lib/patchtest/tests/test_mbox.py
+++ b/meta/lib/patchtest/tests/test_mbox.py
@@ -6,8 +6,7 @@
6 6
7import base 7import base
8import collections 8import collections
9import parse_shortlog 9import patterns
10import parse_signed_off_by
11import pyparsing 10import pyparsing
12import re 11import re
13import subprocess 12import subprocess
@@ -23,19 +22,6 @@ def headlog():
23 22
24class TestMbox(base.Base): 23class TestMbox(base.Base):
25 24
26 auh_email = 'auh@yoctoproject.org'
27
28 invalids = [pyparsing.Regex("^Upgrade Helper.+"),
29 pyparsing.Regex(auh_email),
30 pyparsing.Regex("uh@not\.set"),
31 pyparsing.Regex("\S+@example\.com")]
32
33 rexp_detect = pyparsing.Regex('\[\s?YOCTO.*\]')
34 rexp_validation = pyparsing.Regex('\[(\s?YOCTO\s?#\s?(\d+)\s?,?)+\]')
35 signoff_prog = parse_signed_off_by.signed_off_by
36 revert_shortlog_regex = pyparsing.Regex('Revert\s+".*"')
37 maxlength = 90
38
39 # base paths of main yocto project sub-projects 25 # base paths of main yocto project sub-projects
40 paths = { 26 paths = {
41 'oe-core': ['meta-selftest', 'meta-skeleton', 'meta', 'scripts'], 27 'oe-core': ['meta-selftest', 'meta-skeleton', 'meta', 'scripts'],
@@ -59,9 +45,9 @@ class TestMbox(base.Base):
59 def test_signed_off_by_presence(self): 45 def test_signed_off_by_presence(self):
60 for commit in TestMbox.commits: 46 for commit in TestMbox.commits:
61 # 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
62 if self.revert_shortlog_regex.search_string(commit.shortlog): 48 if patterns.mbox_revert_shortlog_regex.search_string(commit.shortlog):
63 continue 49 continue
64 if not self.signoff_prog.search_string(commit.payload): 50 if not patterns.signed_off_by.search_string(commit.payload):
65 self.fail('Mbox is missing Signed-off-by. Add it manually or with "git commit --amend -s"', 51 self.fail('Mbox is missing Signed-off-by. Add it manually or with "git commit --amend -s"',
66 commit=commit) 52 commit=commit)
67 53
@@ -75,7 +61,7 @@ class TestMbox(base.Base):
75 if shortlog.startswith('Revert "'): 61 if shortlog.startswith('Revert "'):
76 continue 62 continue
77 try: 63 try:
78 parse_shortlog.shortlog.parseString(shortlog) 64 patterns.shortlog.parseString(shortlog)
79 except pyparsing.ParseException as pe: 65 except pyparsing.ParseException as pe:
80 self.fail('Commit shortlog (first line of commit message) should follow the format "<target>: <summary>"', 66 self.fail('Commit shortlog (first line of commit message) should follow the format "<target>: <summary>"',
81 commit=commit) 67 commit=commit)
@@ -87,8 +73,8 @@ class TestMbox(base.Base):
87 if shortlog.startswith('Revert "'): 73 if shortlog.startswith('Revert "'):
88 continue 74 continue
89 l = len(shortlog) 75 l = len(shortlog)
90 if l > self.maxlength: 76 if l > patterns.mbox_shortlog_maxlength:
91 self.fail('Edit shortlog so that it is %d characters or less (currently %d characters)' % (self.maxlength, l), 77 self.fail('Edit shortlog so that it is %d characters or less (currently %d characters)' % (patterns.mbox_shortlog_maxlength, l),
92 commit=commit) 78 commit=commit)
93 79
94 def test_series_merge_on_head(self): 80 def test_series_merge_on_head(self):
@@ -142,18 +128,18 @@ class TestMbox(base.Base):
142 128
143 def test_bugzilla_entry_format(self): 129 def test_bugzilla_entry_format(self):
144 for commit in TestMbox.commits: 130 for commit in TestMbox.commits:
145 if not self.rexp_detect.search_string(commit.commit_message): 131 if not patterns.mbox_bugzilla.search_string(commit.commit_message):
146 self.skip("No bug ID found") 132 self.skip("No bug ID found")
147 elif not self.rexp_validation.search_string(commit.commit_message): 133 elif not patterns.mbox_bugzilla_validation.search_string(commit.commit_message):
148 self.fail('Bugzilla issue ID is not correctly formatted - specify it with format: "[YOCTO #<bugzilla ID>]"', commit=commit) 134 self.fail('Bugzilla issue ID is not correctly formatted - specify it with format: "[YOCTO #<bugzilla ID>]"', commit=commit)
149 135
150 def test_author_valid(self): 136 def test_author_valid(self):
151 for commit in self.commits: 137 for commit in self.commits:
152 for invalid in self.invalids: 138 for invalid in patterns.invalid_submitters:
153 if invalid.search_string(commit.author): 139 if invalid.search_string(commit.author):
154 self.fail('Invalid author %s. Resend the series with a valid patch author' % commit.author, commit=commit) 140 self.fail('Invalid author %s. Resend the series with a valid patch author' % commit.author, commit=commit)
155 141
156 def test_non_auh_upgrade(self): 142 def test_non_auh_upgrade(self):
157 for commit in self.commits: 143 for commit in self.commits:
158 if self.auh_email in commit.commit_message: 144 if patterns.auh_email in commit.commit_message:
159 self.fail('Invalid author %s. Resend the series with a valid patch author' % self.auh_email, commit=commit) 145 self.fail('Invalid author %s. Resend the series with a valid patch author' % patterns.auh_email, commit=commit)
diff --git a/meta/lib/patchtest/tests/test_metadata.py b/meta/lib/patchtest/tests/test_metadata.py
index f5dbcf01ed..8c2305a184 100644
--- a/meta/lib/patchtest/tests/test_metadata.py
+++ b/meta/lib/patchtest/tests/test_metadata.py
@@ -6,27 +6,11 @@
6 6
7import base 7import base
8import os 8import os
9import patterns
9import pyparsing 10import pyparsing
10from data import PatchTestInput, PatchTestDataStore 11from data import PatchTestInput, PatchTestDataStore
11 12
12class TestMetadata(base.Metadata): 13class TestMetadata(base.Metadata):
13 metadata_lic = 'LICENSE'
14 invalid_license = 'PATCHTESTINVALID'
15 metadata_chksum = 'LIC_FILES_CHKSUM'
16 license_var = 'LICENSE'
17 closed = 'CLOSED'
18 lictag_re = pyparsing.AtLineStart("License-Update:")
19 lic_chksum_added = pyparsing.AtLineStart("+" + metadata_chksum)
20 lic_chksum_removed = pyparsing.AtLineStart("-" + metadata_chksum)
21 add_mark = pyparsing.Regex('\\+ ')
22 max_length = 200
23 metadata_src_uri = 'SRC_URI'
24 md5sum = 'md5sum'
25 sha256sum = 'sha256sum'
26 git_regex = pyparsing.Regex('^git\\:\\/\\/.*')
27 metadata_summary = 'SUMMARY'
28 cve_check_ignore_var = 'CVE_CHECK_IGNORE'
29 cve_status_var = 'CVE_STATUS'
30 14
31 def test_license_presence(self): 15 def test_license_presence(self):
32 if not self.added: 16 if not self.added:
@@ -41,13 +25,13 @@ class TestMetadata(base.Metadata):
41 open_flag = 'a' 25 open_flag = 'a'
42 with open(auto_conf, open_flag) as fd: 26 with open(auto_conf, open_flag) as fd:
43 for pn in self.added: 27 for pn in self.added:
44 fd.write('LICENSE ??= "%s"\n' % self.invalid_license) 28 fd.write('LICENSE ??= "%s"\n' % patterns.invalid_license)
45 29
46 no_license = False 30 no_license = False
47 for pn in self.added: 31 for pn in self.added:
48 rd = self.tinfoil.parse_recipe(pn) 32 rd = self.tinfoil.parse_recipe(pn)
49 license = rd.getVar(self.metadata_lic) 33 license = rd.getVar(patterns.metadata_lic)
50 if license == self.invalid_license: 34 if license == patterns.invalid_license:
51 no_license = True 35 no_license = True
52 break 36 break
53 37
@@ -74,11 +58,11 @@ class TestMetadata(base.Metadata):
74 # we are not interested in images 58 # we are not interested in images
75 if '/images/' in pathname: 59 if '/images/' in pathname:
76 continue 60 continue
77 lic_files_chksum = rd.getVar(self.metadata_chksum) 61 lic_files_chksum = rd.getVar(patterns.metadata_chksum)
78 if rd.getVar(self.license_var) == self.closed: 62 if rd.getVar(patterns.license_var) == patterns.closed:
79 continue 63 continue
80 if not lic_files_chksum: 64 if not lic_files_chksum:
81 self.fail('%s is missing in newly added recipe' % self.metadata_chksum) 65 self.fail('%s is missing in newly added recipe' % patterns.metadata_chksum)
82 66
83 def test_lic_files_chksum_modified_not_mentioned(self): 67 def test_lic_files_chksum_modified_not_mentioned(self):
84 if not self.modified: 68 if not self.modified:
@@ -89,10 +73,10 @@ class TestMetadata(base.Metadata):
89 if patch.path.endswith('.patch'): 73 if patch.path.endswith('.patch'):
90 continue 74 continue
91 payload = str(patch) 75 payload = str(patch)
92 if (self.lic_chksum_added.search_string(payload) or self.lic_chksum_removed.search_string(payload)): 76 if (patterns.lic_chksum_added.search_string(payload) or patterns.lic_chksum_removed.search_string(payload)):
93 # if any patch on the series contain reference on the metadata, fail 77 # if any patch on the series contain reference on the metadata, fail
94 for commit in self.commits: 78 for commit in self.commits:
95 if self.lictag_re.search_string(commit.commit_message): 79 if patterns.lictag_re.search_string(commit.commit_message):
96 break 80 break
97 else: 81 else:
98 self.fail('LIC_FILES_CHKSUM changed without "License-Update:" tag and description in commit message') 82 self.fail('LIC_FILES_CHKSUM changed without "License-Update:" tag and description in commit message')
@@ -104,10 +88,10 @@ class TestMetadata(base.Metadata):
104 continue 88 continue
105 payload = str(patch) 89 payload = str(patch)
106 for line in payload.splitlines(): 90 for line in payload.splitlines():
107 if self.add_mark.search_string(line): 91 if patterns.add_mark.search_string(line):
108 current_line_length = len(line[1:]) 92 current_line_length = len(line[1:])
109 if current_line_length > self.max_length: 93 if current_line_length > patterns.patch_max_line_length:
110 self.fail('Patch line too long (current length %s, maximum is %s)' % (current_line_length, self.max_length), 94 self.fail('Patch line too long (current length %s, maximum is %s)' % (current_line_length, patterns.patch_max_line_length),
111 data=[('Patch', patch.path), ('Line', '%s ...' % line[0:80])]) 95 data=[('Patch', patch.path), ('Line', '%s ...' % line[0:80])])
112 96
113 def pretest_src_uri_left_files(self): 97 def pretest_src_uri_left_files(self):
@@ -123,7 +107,7 @@ class TestMetadata(base.Metadata):
123 if 'core-image' in pn: 107 if 'core-image' in pn:
124 continue 108 continue
125 rd = self.tinfoil.parse_recipe(pn) 109 rd = self.tinfoil.parse_recipe(pn)
126 PatchTestDataStore['%s-%s-%s' % (self.shortid(), self.metadata_src_uri, pn)] = rd.getVar(self.metadata_src_uri) 110 PatchTestDataStore['%s-%s-%s' % (self.shortid(), patterns.metadata_src_uri, pn)] = rd.getVar(patterns.metadata_src_uri)
127 111
128 def test_src_uri_left_files(self): 112 def test_src_uri_left_files(self):
129 # these tests just make sense on patches that can be merged 113 # these tests just make sense on patches that can be merged
@@ -138,11 +122,11 @@ class TestMetadata(base.Metadata):
138 if 'core-image' in pn: 122 if 'core-image' in pn:
139 continue 123 continue
140 rd = self.tinfoil.parse_recipe(pn) 124 rd = self.tinfoil.parse_recipe(pn)
141 PatchTestDataStore['%s-%s-%s' % (self.shortid(), self.metadata_src_uri, pn)] = rd.getVar(self.metadata_src_uri) 125 PatchTestDataStore['%s-%s-%s' % (self.shortid(), patterns.metadata_src_uri, pn)] = rd.getVar(patterns.metadata_src_uri)
142 126
143 for pn in self.modified: 127 for pn in self.modified:
144 pretest_src_uri = PatchTestDataStore['pre%s-%s-%s' % (self.shortid(), self.metadata_src_uri, pn)].split() 128 pretest_src_uri = PatchTestDataStore['pre%s-%s-%s' % (self.shortid(), patterns.metadata_src_uri, pn)].split()
145 test_src_uri = PatchTestDataStore['%s-%s-%s' % (self.shortid(), self.metadata_src_uri, pn)].split() 129 test_src_uri = PatchTestDataStore['%s-%s-%s' % (self.shortid(), patterns.metadata_src_uri, pn)].split()
146 130
147 pretest_files = set([os.path.basename(patch) for patch in pretest_src_uri if patch.startswith('file://')]) 131 pretest_files = set([os.path.basename(patch) for patch in pretest_src_uri if patch.startswith('file://')])
148 test_files = set([os.path.basename(patch) for patch in test_src_uri if patch.startswith('file://')]) 132 test_files = set([os.path.basename(patch) for patch in test_src_uri if patch.startswith('file://')])
@@ -175,11 +159,11 @@ class TestMetadata(base.Metadata):
175 if 'core-image' in pn: 159 if 'core-image' in pn:
176 continue 160 continue
177 rd = self.tinfoil.parse_recipe(pn) 161 rd = self.tinfoil.parse_recipe(pn)
178 summary = rd.getVar(self.metadata_summary) 162 summary = rd.getVar(patterns.metadata_summary)
179 163
180 # "${PN} version ${PN}-${PR}" is the default, so fail if default 164 # "${PN} version ${PN}-${PR}" is the default, so fail if default
181 if summary.startswith('%s version' % pn): 165 if summary.startswith('%s version' % pn):
182 self.fail('%s is missing in newly added recipe' % self.metadata_summary) 166 self.fail('%s is missing in newly added recipe' % patterns.metadata_summary)
183 167
184 def test_cve_check_ignore(self): 168 def test_cve_check_ignore(self):
185 # Skip if we neither modified a recipe or target branches are not 169 # Skip if we neither modified a recipe or target branches are not
@@ -191,7 +175,7 @@ class TestMetadata(base.Metadata):
191 if 'core-image' in pn: 175 if 'core-image' in pn:
192 continue 176 continue
193 rd = self.tinfoil.parse_recipe(pn) 177 rd = self.tinfoil.parse_recipe(pn)
194 cve_check_ignore = rd.getVar(self.cve_check_ignore_var) 178 cve_check_ignore = rd.getVar(patterns.cve_check_ignore_var)
195 179
196 if cve_check_ignore is not None: 180 if cve_check_ignore is not None:
197 self.fail('%s is deprecated and should be replaced by %s' % (self.cve_check_ignore_var, self.cve_status_var)) 181 self.fail('%s is deprecated and should be replaced by %s' % (patterns.cve_check_ignore_var, patterns.cve_status_var))
diff --git a/meta/lib/patchtest/tests/test_patch.py b/meta/lib/patchtest/tests/test_patch.py
index d7187a0cb1..d856b216f0 100644
--- a/meta/lib/patchtest/tests/test_patch.py
+++ b/meta/lib/patchtest/tests/test_patch.py
@@ -7,16 +7,11 @@
7 7
8import base 8import base
9import os 9import os
10import parse_signed_off_by 10import patterns
11import parse_upstream_status
12import pyparsing 11import pyparsing
13 12
14class TestPatch(base.Base): 13class TestPatch(base.Base):
15 14
16 re_cve_pattern = pyparsing.Regex("CVE\-\d{4}\-\d+")
17 re_cve_payload_tag = pyparsing.Regex("\+CVE:(\s+CVE\-\d{4}\-\d+)+")
18 upstream_status_regex = pyparsing.AtLineStart("+" + "Upstream-Status")
19
20 @classmethod 15 @classmethod
21 def setUpClassLocal(cls): 16 def setUpClassLocal(cls):
22 cls.newpatches = [] 17 cls.newpatches = []
@@ -25,16 +20,16 @@ class TestPatch(base.Base):
25 if patch.path.endswith('.patch') and patch.is_added_file: 20 if patch.path.endswith('.patch') and patch.is_added_file:
26 cls.newpatches.append(patch) 21 cls.newpatches.append(patch)
27 22
28 cls.mark = str(parse_signed_off_by.signed_off_by_mark).strip('"') 23 cls.mark = str(patterns.signed_off_by_prefix).strip('"')
29 24
30 # match PatchSignedOffBy.mark with '+' preceding it 25 # match PatchSignedOffBy.mark with '+' preceding it
31 cls.prog = parse_signed_off_by.patch_signed_off_by 26 cls.prog = patterns.patch_signed_off_by
32 27
33 def setUp(self): 28 def setUp(self):
34 if self.unidiff_parse_error: 29 if self.unidiff_parse_error:
35 self.skip('Parse error %s' % self.unidiff_parse_error) 30 self.skip('Parse error %s' % self.unidiff_parse_error)
36 31
37 self.valid_status = ', '.join(parse_upstream_status.upstream_status_nonliteral_valid_status) 32 self.valid_status = ', '.join(patterns.upstream_status_nonliteral_valid_status)
38 self.standard_format = 'Upstream-Status: <Valid status>' 33 self.standard_format = 'Upstream-Status: <Valid status>'
39 34
40 # 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
@@ -50,28 +45,28 @@ class TestPatch(base.Base):
50 45
51 for newpatch in TestPatch.newpatches: 46 for newpatch in TestPatch.newpatches:
52 payload = newpatch.__str__() 47 payload = newpatch.__str__()
53 if not self.upstream_status_regex.search_string(payload): 48 if not patterns.upstream_status_regex.search_string(payload):
54 self.fail('Added patch file is missing Upstream-Status: <Valid status> in the commit message', 49 self.fail('Added patch file is missing Upstream-Status: <Valid status> in the commit message',
55 data=[('Standard format', self.standard_format), ('Valid status', self.valid_status)]) 50 data=[('Standard format', self.standard_format), ('Valid status', self.valid_status)])
56 for line in payload.splitlines(): 51 for line in payload.splitlines():
57 if self.patchmetadata_regex.match(line): 52 if self.patchmetadata_regex.match(line):
58 continue 53 continue
59 if self.upstream_status_regex.search_string(line): 54 if patterns.upstream_status_regex.search_string(line):
60 if parse_upstream_status.inappropriate_status_mark.searchString(line): 55 if patterns.inappropriate.searchString(line):
61 try: 56 try:
62 parse_upstream_status.upstream_status_inappropriate_info.parseString(line.lstrip('+')) 57 patterns.upstream_status_inappropriate_info.parseString(line.lstrip('+'))
63 except pyparsing.ParseException as pe: 58 except pyparsing.ParseException as pe:
64 self.fail('Upstream-Status is Inappropriate, but no reason was provided', 59 self.fail('Upstream-Status is Inappropriate, but no reason was provided',
65 data=[('Current', pe.pstr), ('Standard format', 'Upstream-Status: Inappropriate [reason]')]) 60 data=[('Current', pe.pstr), ('Standard format', 'Upstream-Status: Inappropriate [reason]')])
66 elif parse_upstream_status.submitted_status_mark.searchString(line): 61 elif patterns.submitted.searchString(line):
67 try: 62 try:
68 parse_upstream_status.upstream_status_submitted_info.parseString(line.lstrip('+')) 63 patterns.upstream_status_submitted_info.parseString(line.lstrip('+'))
69 except pyparsing.ParseException as pe: 64 except pyparsing.ParseException as pe:
70 self.fail('Upstream-Status is Submitted, but it is not mentioned where', 65 self.fail('Upstream-Status is Submitted, but it is not mentioned where',
71 data=[('Current', pe.pstr), ('Standard format', 'Upstream-Status: Submitted [where]')]) 66 data=[('Current', pe.pstr), ('Standard format', 'Upstream-Status: Submitted [where]')])
72 else: 67 else:
73 try: 68 try:
74 parse_upstream_status.upstream_status.parseString(line.lstrip('+')) 69 patterns.upstream_status.parseString(line.lstrip('+'))
75 except pyparsing.ParseException as pe: 70 except pyparsing.ParseException as pe:
76 self.fail('Upstream-Status is in incorrect format', 71 self.fail('Upstream-Status is in incorrect format',
77 data=[('Current', pe.pstr), ('Standard format', self.standard_format), ('Valid status', self.valid_status)]) 72 data=[('Current', pe.pstr), ('Standard format', self.standard_format), ('Valid status', self.valid_status)])
@@ -92,10 +87,10 @@ class TestPatch(base.Base):
92 87
93 def test_cve_tag_format(self): 88 def test_cve_tag_format(self):
94 for commit in TestPatch.commits: 89 for commit in TestPatch.commits:
95 if self.re_cve_pattern.search_string(commit.shortlog) or self.re_cve_pattern.search_string(commit.commit_message): 90 if patterns.cve.search_string(commit.shortlog) or patterns.cve.search_string(commit.commit_message):
96 tag_found = False 91 tag_found = False
97 for line in commit.payload.splitlines(): 92 for line in commit.payload.splitlines():
98 if self.re_cve_payload_tag.search_string(line): 93 if patterns.cve_payload_tag.search_string(line):
99 tag_found = True 94 tag_found = True
100 break 95 break
101 if not tag_found: 96 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 ef315e591c..b03fd6f4f6 100644
--- a/meta/lib/patchtest/tests/test_python_pylint.py
+++ b/meta/lib/patchtest/tests/test_python_pylint.py
@@ -5,6 +5,7 @@
5# SPDX-License-Identifier: GPL-2.0-only 5# SPDX-License-Identifier: GPL-2.0-only
6 6
7import base 7import base
8import patterns
8from io import StringIO 9from io import StringIO
9from data import PatchTestInput 10from data import PatchTestInput
10from pylint.reporters.text import TextReporter 11from pylint.reporters.text import TextReporter