summaryrefslogtreecommitdiffstats
path: root/meta/lib/patchtest/tests/test_metadata.py
diff options
context:
space:
mode:
Diffstat (limited to 'meta/lib/patchtest/tests/test_metadata.py')
-rw-r--r--meta/lib/patchtest/tests/test_metadata.py107
1 files changed, 61 insertions, 46 deletions
diff --git a/meta/lib/patchtest/tests/test_metadata.py b/meta/lib/patchtest/tests/test_metadata.py
index f5dbcf01ed..2dee80b002 100644
--- a/meta/lib/patchtest/tests/test_metadata.py
+++ b/meta/lib/patchtest/tests/test_metadata.py
@@ -5,28 +5,16 @@
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
10import patchtest_patterns
9import pyparsing 11import pyparsing
10from 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)
11 16
12class TestMetadata(base.Metadata): 17class 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 18
31 def test_license_presence(self): 19 def test_license_presence(self):
32 if not self.added: 20 if not self.added:
@@ -41,13 +29,13 @@ class TestMetadata(base.Metadata):
41 open_flag = 'a' 29 open_flag = 'a'
42 with open(auto_conf, open_flag) as fd: 30 with open(auto_conf, open_flag) as fd:
43 for pn in self.added: 31 for pn in self.added:
44 fd.write('LICENSE ??= "%s"\n' % self.invalid_license) 32 fd.write('LICENSE ??= "%s"\n' % patchtest_patterns.invalid_license)
45 33
46 no_license = False 34 no_license = False
47 for pn in self.added: 35 for pn in self.added:
48 rd = self.tinfoil.parse_recipe(pn) 36 rd = self.tinfoil.parse_recipe(pn)
49 license = rd.getVar(self.metadata_lic) 37 license = rd.getVar(patchtest_patterns.metadata_lic)
50 if license == self.invalid_license: 38 if license == patchtest_patterns.invalid_license:
51 no_license = True 39 no_license = True
52 break 40 break
53 41
@@ -74,11 +62,13 @@ class TestMetadata(base.Metadata):
74 # we are not interested in images 62 # we are not interested in images
75 if '/images/' in pathname: 63 if '/images/' in pathname:
76 continue 64 continue
77 lic_files_chksum = rd.getVar(self.metadata_chksum) 65 lic_files_chksum = rd.getVar(patchtest_patterns.metadata_chksum)
78 if rd.getVar(self.license_var) == self.closed: 66 if rd.getVar(patchtest_patterns.license_var) == patchtest_patterns.closed:
79 continue 67 continue
80 if not lic_files_chksum: 68 if not lic_files_chksum:
81 self.fail('%s is missing in newly added recipe' % self.metadata_chksum) 69 self.fail(
70 "%s is missing in newly added recipe" % patchtest_patterns.metadata_chksum
71 )
82 72
83 def test_lic_files_chksum_modified_not_mentioned(self): 73 def test_lic_files_chksum_modified_not_mentioned(self):
84 if not self.modified: 74 if not self.modified:
@@ -89,11 +79,13 @@ class TestMetadata(base.Metadata):
89 if patch.path.endswith('.patch'): 79 if patch.path.endswith('.patch'):
90 continue 80 continue
91 payload = str(patch) 81 payload = str(patch)
92 if (self.lic_chksum_added.search_string(payload) or self.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):
93 # 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
94 for commit in self.commits: 86 for commit in self.commits:
95 if self.lictag_re.search_string(commit.commit_message): 87 if patchtest_patterns.lictag_re.search_string(commit.commit_message):
96 break 88 break
97 else: 89 else:
98 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')
99 91
@@ -104,16 +96,22 @@ class TestMetadata(base.Metadata):
104 continue 96 continue
105 payload = str(patch) 97 payload = str(patch)
106 for line in payload.splitlines(): 98 for line in payload.splitlines():
107 if self.add_mark.search_string(line): 99 if patchtest_patterns.add_mark.search_string(line):
108 current_line_length = len(line[1:]) 100 current_line_length = len(line[1:])
109 if current_line_length > self.max_length: 101 if current_line_length > patchtest_patterns.patch_max_line_length:
110 self.fail('Patch line too long (current length %s, maximum is %s)' % (current_line_length, self.max_length), 102 self.fail(
111 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 )
112 110
113 def pretest_src_uri_left_files(self): 111 def pretest_src_uri_left_files(self):
114 # these tests just make sense on patches that can be merged 112 # these tests just make sense on patches that can be merged
115 if not PatchTestInput.repo.canbemerged: 113 if not PatchtestParser.repo.canbemerged:
116 self.skip('Patch cannot be merged') 114 self.skip("Patch cannot be merged")
117 if not self.modified: 115 if not self.modified:
118 self.skip('No modified recipes, skipping pretest') 116 self.skip('No modified recipes, skipping pretest')
119 117
@@ -123,12 +121,14 @@ class TestMetadata(base.Metadata):
123 if 'core-image' in pn: 121 if 'core-image' in pn:
124 continue 122 continue
125 rd = self.tinfoil.parse_recipe(pn) 123 rd = self.tinfoil.parse_recipe(pn)
126 PatchTestDataStore['%s-%s-%s' % (self.shortid(), self.metadata_src_uri, pn)] = rd.getVar(self.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)
127 127
128 def test_src_uri_left_files(self): 128 def test_src_uri_left_files(self):
129 # these tests just make sense on patches that can be merged 129 # these tests just make sense on patches that can be merged
130 if not PatchTestInput.repo.canbemerged: 130 if not PatchtestParser.repo.canbemerged:
131 self.skip('Patch cannot be merged') 131 self.skip("Patch cannot be merged")
132 if not self.modified: 132 if not self.modified:
133 self.skip('No modified recipes, skipping pretest') 133 self.skip('No modified recipes, skipping pretest')
134 134
@@ -138,11 +138,17 @@ class TestMetadata(base.Metadata):
138 if 'core-image' in pn: 138 if 'core-image' in pn:
139 continue 139 continue
140 rd = self.tinfoil.parse_recipe(pn) 140 rd = self.tinfoil.parse_recipe(pn)
141 PatchTestDataStore['%s-%s-%s' % (self.shortid(), self.metadata_src_uri, pn)] = rd.getVar(self.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)
142 144
143 for pn in self.modified: 145 for pn in self.modified:
144 pretest_src_uri = PatchTestDataStore['pre%s-%s-%s' % (self.shortid(), self.metadata_src_uri, pn)].split() 146 pretest_src_uri = PatchTestDataStore[
145 test_src_uri = PatchTestDataStore['%s-%s-%s' % (self.shortid(), self.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()
146 152
147 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://')])
148 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://')])
@@ -175,23 +181,32 @@ class TestMetadata(base.Metadata):
175 if 'core-image' in pn: 181 if 'core-image' in pn:
176 continue 182 continue
177 rd = self.tinfoil.parse_recipe(pn) 183 rd = self.tinfoil.parse_recipe(pn)
178 summary = rd.getVar(self.metadata_summary) 184 summary = rd.getVar(patchtest_patterns.metadata_summary)
179 185
180 # "${PN} version ${PN}-${PR}" is the default, so fail if default 186 # "${PN} version ${PN}-${PR}" is the default, so fail if default
181 if summary.startswith('%s version' % pn): 187 if summary.startswith("%s version" % pn):
182 self.fail('%s is missing in newly added recipe' % self.metadata_summary) 188 self.fail(
189 "%s is missing in newly added recipe" % patchtest_patterns.metadata_summary
190 )
183 191
184 def test_cve_check_ignore(self): 192 def test_cve_check_ignore(self):
185 # 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
186 # Nanbield and newer. CVE_CHECK_IGNORE was first deprecated in Nanbield. 194 # Nanbield and newer. CVE_CHECK_IGNORE was first deprecated in Nanbield.
187 if not self.modified or PatchTestInput.repo.branch == "kirkstone" or PatchTestInput.repo.branch == "dunfell": 195 if (
188 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")
189 for pn in self.modified: 201 for pn in self.modified:
190 # we are not interested in images 202 # we are not interested in images
191 if 'core-image' in pn: 203 if 'core-image' in pn:
192 continue 204 continue
193 rd = self.tinfoil.parse_recipe(pn) 205 rd = self.tinfoil.parse_recipe(pn)
194 cve_check_ignore = rd.getVar(self.cve_check_ignore_var) 206 cve_check_ignore = rd.getVar(patchtest_patterns.cve_check_ignore_var)
195 207
196 if cve_check_ignore is not None: 208 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)) 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 )