Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(230)

Side by Side Diff: tools/foozzie/v8_suppressions.py

Issue 2632623002: [foozzie] Fix failure state for non-existing source output (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/foozzie/v8_foozzie.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2016 the V8 project authors. All rights reserved. 1 # Copyright 2016 the V8 project authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """ 5 """
6 Suppressions for V8 correctness fuzzer failures. 6 Suppressions for V8 correctness fuzzer failures.
7 7
8 We support three types of suppressions: 8 We support three types of suppressions:
9 1. Ignore test case by pattern. 9 1. Ignore test case by pattern.
10 Map a regular expression to a bug entry. A new failure will be reported 10 Map a regular expression to a bug entry. A new failure will be reported
11 when the pattern matches a JS test case. 11 when the pattern matches a JS test case.
12 Subsequent matches will be recoreded under the first failure. 12 Subsequent matches will be recoreded under the first failure.
13 13
14 2. Ignore test run by output pattern: 14 2. Ignore test run by output pattern:
15 Map a regular expression to a bug entry. A new failure will be reported 15 Map a regular expression to a bug entry. A new failure will be reported
16 when the pattern matches the output of a particular run. 16 when the pattern matches the output of a particular run.
17 Subsequent matches will be recoreded under the first failure. 17 Subsequent matches will be recoreded under the first failure.
18 18
19 3. Relax line-to-line comparisons with expressions of lines to ignore and 19 3. Relax line-to-line comparisons with expressions of lines to ignore and
20 lines to be normalized (i.e. ignore only portions of lines). 20 lines to be normalized (i.e. ignore only portions of lines).
21 These are not tied to bugs, be careful to not silently switch off this tool! 21 These are not tied to bugs, be careful to not silently switch off this tool!
22 22
23 Alternatively, think about adding a behavior change to v8_suppressions.js 23 Alternatively, think about adding a behavior change to v8_suppressions.js
24 to silence a particular class of problems. 24 to silence a particular class of problems.
25 """ 25 """
26 26
27 import hashlib
27 import itertools 28 import itertools
28 import re 29 import re
29 30
30 # Max line length for regular experessions checking for lines to ignore. 31 # Max line length for regular experessions checking for lines to ignore.
31 MAX_LINE_LENGTH = 512 32 MAX_LINE_LENGTH = 512
32 33
33 # For ignoring lines before carets and to ignore caret positions. 34 # For ignoring lines before carets and to ignore caret positions.
34 CARET_RE = re.compile(r'^\s*\^\s*$') 35 CARET_RE = re.compile(r'^\s*\^\s*$')
35 36
36 # Ignore by original source files. Map from bug->relative file paths in V8, 37 # Ignore by original source files. Map from bug->relative file paths in V8,
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 ] 142 ]
142 143
143 144
144 ############################################################################### 145 ###############################################################################
145 # Implementation - you should not need to change anything below this point. 146 # Implementation - you should not need to change anything below this point.
146 147
147 # Compile regular expressions. 148 # Compile regular expressions.
148 ALLOWED_LINE_DIFFS = [re.compile(exp) for exp in ALLOWED_LINE_DIFFS] 149 ALLOWED_LINE_DIFFS = [re.compile(exp) for exp in ALLOWED_LINE_DIFFS]
149 IGNORE_LINES = [re.compile(exp) for exp in IGNORE_LINES] 150 IGNORE_LINES = [re.compile(exp) for exp in IGNORE_LINES]
150 151
152 # The number of hex digits used from the hash of the original source file path.
153 # Keep the number small to avoid duplicate explosion.
154 SOURCE_HASH_LENGTH = 3
155
151 ORIGINAL_SOURCE_PREFIX = 'v8-foozzie source: ' 156 ORIGINAL_SOURCE_PREFIX = 'v8-foozzie source: '
152 157
153 def line_pairs(lines): 158 def line_pairs(lines):
154 return itertools.izip_longest( 159 return itertools.izip_longest(
155 lines, itertools.islice(lines, 1, None), fillvalue=None) 160 lines, itertools.islice(lines, 1, None), fillvalue=None)
156 161
157 162
158 def caret_match(line1, line2): 163 def caret_match(line1, line2):
159 if (not line1 or 164 if (not line1 or
160 not line2 or 165 not line2 or
(...skipping 18 matching lines...) Expand all
179 match2 = exp.match(line2) 184 match2 = exp.match(line2)
180 if match1 and match2: 185 if match1 and match2:
181 # If there are groups in the regexp, ensure the groups matched the same 186 # If there are groups in the regexp, ensure the groups matched the same
182 # things. 187 # things.
183 if match1.groups() == match2.groups(): # tuple comparison 188 if match1.groups() == match2.groups(): # tuple comparison
184 return True 189 return True
185 return False 190 return False
186 191
187 192
188 def diff_output(output1, output2, allowed, ignore1, ignore2): 193 def diff_output(output1, output2, allowed, ignore1, ignore2):
189 """Returns a tuple (difference, source). 194 """Returns a tuple (difference, source_key).
190 195
191 The difference is None if there's no difference, otherwise a string 196 The difference is None if there's no difference, otherwise a string
192 with a readable diff. 197 with a readable diff.
193 198
194 The source is a string with the last source output within the test case. 199 The source_key is a short hash of the last source output within the test
195 It is the string 'none' if no such output existed. 200 case. It is the string 'none' if no such output existed.
196 """ 201 """
197 def useful_line(ignore): 202 def useful_line(ignore):
198 def fun(line): 203 def fun(line):
199 return all(not e.match(line) for e in ignore) 204 return all(not e.match(line) for e in ignore)
200 return fun 205 return fun
201 206
202 lines1 = filter(useful_line(ignore1), output1) 207 lines1 = filter(useful_line(ignore1), output1)
203 lines2 = filter(useful_line(ignore2), output2) 208 lines2 = filter(useful_line(ignore2), output2)
204 209
205 # This keeps track where we are in the original source file of the fuzz 210 # This keeps track where we are in the original source file of the fuzz
206 # test case. 211 # test case.
207 source = 'none' 212 source_key = 'none'
208 213
209 for ((line1, lookahead1), (line2, lookahead2)) in itertools.izip_longest( 214 for ((line1, lookahead1), (line2, lookahead2)) in itertools.izip_longest(
210 line_pairs(lines1), line_pairs(lines2), fillvalue=(None, None)): 215 line_pairs(lines1), line_pairs(lines2), fillvalue=(None, None)):
211 216
212 # Only one of the two iterators should run out. 217 # Only one of the two iterators should run out.
213 assert not (line1 is None and line2 is None) 218 assert not (line1 is None and line2 is None)
214 219
215 # One iterator ends earlier. 220 # One iterator ends earlier.
216 if line1 is None: 221 if line1 is None:
217 return '+ %s' % short_line_output(line2), source 222 return '+ %s' % short_line_output(line2), source_key
218 if line2 is None: 223 if line2 is None:
219 return '- %s' % short_line_output(line1), source 224 return '- %s' % short_line_output(line1), source_key
220 225
221 # If lines are equal, no further checks are necessary. 226 # If lines are equal, no further checks are necessary.
222 if line1 == line2: 227 if line1 == line2:
223 # Instrumented original-source-file output must be equal in both 228 # Instrumented original-source-file output must be equal in both
224 # versions. It only makes sense to update it here when both lines 229 # versions. It only makes sense to update it here when both lines
225 # are equal. 230 # are equal.
226 if line1.startswith(ORIGINAL_SOURCE_PREFIX): 231 if line1.startswith(ORIGINAL_SOURCE_PREFIX):
227 source = line1[len(ORIGINAL_SOURCE_PREFIX):] 232 source = line1[len(ORIGINAL_SOURCE_PREFIX):]
233 source_key = hashlib.sha1(source).hexdigest()[:SOURCE_HASH_LENGTH]
Michael Achenbach 2017/01/13 08:13:40 Maybe not ideal that this is in this file. The has
228 continue 234 continue
229 235
230 # Look ahead. If next line is a caret, ignore this line. 236 # Look ahead. If next line is a caret, ignore this line.
231 if caret_match(lookahead1, lookahead2): 237 if caret_match(lookahead1, lookahead2):
232 continue 238 continue
233 239
234 # Check if a regexp allows these lines to be different. 240 # Check if a regexp allows these lines to be different.
235 if ignore_by_regexp(line1, line2, allowed): 241 if ignore_by_regexp(line1, line2, allowed):
236 continue 242 continue
237 243
238 # Lines are different. 244 # Lines are different.
239 return ( 245 return (
240 '- %s\n+ %s' % (short_line_output(line1), short_line_output(line2)), 246 '- %s\n+ %s' % (short_line_output(line1), short_line_output(line2)),
241 source, 247 source_key,
242 ) 248 )
243 249
244 # No difference found. 250 # No difference found.
245 return None, source 251 return None, source_key
246 252
247 253
248 def get_suppression(arch1, config1, arch2, config2): 254 def get_suppression(arch1, config1, arch2, config2):
249 return V8Suppression(arch1, config1, arch2, config2) 255 return V8Suppression(arch1, config1, arch2, config2)
250 256
251 257
252 class Suppression(object): 258 class Suppression(object):
253 def diff(self, output1, output2): 259 def diff(self, output1, output2):
254 return None 260 return None
255 261
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 bug = check(IGNORE_OUTPUT.get(arch, {})) 318 bug = check(IGNORE_OUTPUT.get(arch, {}))
313 if bug: 319 if bug:
314 return bug 320 return bug
315 bug = check(IGNORE_OUTPUT.get(config, {})) 321 bug = check(IGNORE_OUTPUT.get(config, {}))
316 if bug: 322 if bug:
317 return bug 323 return bug
318 bug = check(IGNORE_OUTPUT.get('%s,%s' % (arch, config), {})) 324 bug = check(IGNORE_OUTPUT.get('%s,%s' % (arch, config), {}))
319 if bug: 325 if bug:
320 return bug 326 return bug
321 return None 327 return None
OLDNEW
« no previous file with comments | « tools/foozzie/v8_foozzie.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698