 Chromium Code Reviews
 Chromium Code Reviews Issue 2620343005:
  [foozzie] Improve failure state deduplication  (Closed)
    
  
    Issue 2620343005:
  [foozzie] Improve failure state deduplication  (Closed) 
  | OLD | NEW | 
|---|---|
| 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 | 
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 141 ] | 141 ] | 
| 142 | 142 | 
| 143 | 143 | 
| 144 ############################################################################### | 144 ############################################################################### | 
| 145 # Implementation - you should not need to change anything below this point. | 145 # Implementation - you should not need to change anything below this point. | 
| 146 | 146 | 
| 147 # Compile regular expressions. | 147 # Compile regular expressions. | 
| 148 ALLOWED_LINE_DIFFS = [re.compile(exp) for exp in ALLOWED_LINE_DIFFS] | 148 ALLOWED_LINE_DIFFS = [re.compile(exp) for exp in ALLOWED_LINE_DIFFS] | 
| 149 IGNORE_LINES = [re.compile(exp) for exp in IGNORE_LINES] | 149 IGNORE_LINES = [re.compile(exp) for exp in IGNORE_LINES] | 
| 150 | 150 | 
| 151 ORIGINAL_SOURCE_PREFIX = 'v8-foozzie source: ' | |
| 151 | 152 | 
| 152 def line_pairs(lines): | 153 def line_pairs(lines): | 
| 153 return itertools.izip_longest( | 154 return itertools.izip_longest( | 
| 154 lines, itertools.islice(lines, 1, None), fillvalue=None) | 155 lines, itertools.islice(lines, 1, None), fillvalue=None) | 
| 155 | 156 | 
| 156 | 157 | 
| 157 def caret_match(line1, line2): | 158 def caret_match(line1, line2): | 
| 158 if (not line1 or | 159 if (not line1 or | 
| 159 not line2 or | 160 not line2 or | 
| 160 len(line1) > MAX_LINE_LENGTH or | 161 len(line1) > MAX_LINE_LENGTH or | 
| (...skipping 17 matching lines...) Expand all Loading... | |
| 178 match2 = exp.match(line2) | 179 match2 = exp.match(line2) | 
| 179 if match1 and match2: | 180 if match1 and match2: | 
| 180 # If there are groups in the regexp, ensure the groups matched the same | 181 # If there are groups in the regexp, ensure the groups matched the same | 
| 181 # things. | 182 # things. | 
| 182 if match1.groups() == match2.groups(): # tuple comparison | 183 if match1.groups() == match2.groups(): # tuple comparison | 
| 183 return True | 184 return True | 
| 184 return False | 185 return False | 
| 185 | 186 | 
| 186 | 187 | 
| 187 def diff_output(output1, output2, allowed, ignore1, ignore2): | 188 def diff_output(output1, output2, allowed, ignore1, ignore2): | 
| 189 """Returns a tuple (difference, source). | |
| 190 | |
| 191 The difference is None if there's no difference, otherwise a string | |
| 192 with a readable diff. | |
| 193 | |
| 194 The source is a string with the last source output within the test case. | |
| 195 It is the string 'none' if no such output existed. | |
| 
tandrii(chromium)
2017/01/13 06:38:34
i don't understand why 'none' is a good choice, bu
 
Michael Achenbach
2017/01/13 07:49:52
It's a random string. Could be anything (except on
 
Michael Achenbach
2017/01/13 07:52:39
But there's of course a bug :/. The none value sho
 | |
| 196 """ | |
| 188 def useful_line(ignore): | 197 def useful_line(ignore): | 
| 189 def fun(line): | 198 def fun(line): | 
| 190 return all(not e.match(line) for e in ignore) | 199 return all(not e.match(line) for e in ignore) | 
| 191 return fun | 200 return fun | 
| 192 | 201 | 
| 193 lines1 = filter(useful_line(ignore1), output1) | 202 lines1 = filter(useful_line(ignore1), output1) | 
| 194 lines2 = filter(useful_line(ignore2), output2) | 203 lines2 = filter(useful_line(ignore2), output2) | 
| 195 | 204 | 
| 205 # This keeps track where we are in the original source file of the fuzz | |
| 206 # test case. | |
| 207 source = 'none' | |
| 208 | |
| 196 for ((line1, lookahead1), (line2, lookahead2)) in itertools.izip_longest( | 209 for ((line1, lookahead1), (line2, lookahead2)) in itertools.izip_longest( | 
| 197 line_pairs(lines1), line_pairs(lines2), fillvalue=(None, None)): | 210 line_pairs(lines1), line_pairs(lines2), fillvalue=(None, None)): | 
| 198 | 211 | 
| 199 # Only one of the two iterators should run out. | 212 # Only one of the two iterators should run out. | 
| 200 assert not (line1 is None and line2 is None) | 213 assert not (line1 is None and line2 is None) | 
| 201 | 214 | 
| 202 # One iterator ends earlier. | 215 # One iterator ends earlier. | 
| 203 if line1 is None: | 216 if line1 is None: | 
| 204 return '+ %s' % short_line_output(line2) | 217 return '+ %s' % short_line_output(line2), source | 
| 205 if line2 is None: | 218 if line2 is None: | 
| 206 return '- %s' % short_line_output(line1) | 219 return '- %s' % short_line_output(line1), source | 
| 207 | 220 | 
| 208 # If lines are equal, no further checks are necessary. | 221 # If lines are equal, no further checks are necessary. | 
| 209 if line1 == line2: | 222 if line1 == line2: | 
| 223 # Instrumented original-source-file output must be equal in both | |
| 224 # versions. It only makes sense to update it here when both lines | |
| 225 # are equal. | |
| 226 if line1.startswith(ORIGINAL_SOURCE_PREFIX): | |
| 227 source = line1[len(ORIGINAL_SOURCE_PREFIX):] | |
| 210 continue | 228 continue | 
| 211 | 229 | 
| 212 # Look ahead. If next line is a caret, ignore this line. | 230 # Look ahead. If next line is a caret, ignore this line. | 
| 213 if caret_match(lookahead1, lookahead2): | 231 if caret_match(lookahead1, lookahead2): | 
| 214 continue | 232 continue | 
| 215 | 233 | 
| 216 # Check if a regexp allows these lines to be different. | 234 # Check if a regexp allows these lines to be different. | 
| 217 if ignore_by_regexp(line1, line2, allowed): | 235 if ignore_by_regexp(line1, line2, allowed): | 
| 218 continue | 236 continue | 
| 219 | 237 | 
| 220 # Lines are different. | 238 # Lines are different. | 
| 221 return '- %s\n+ %s' % (short_line_output(line1), short_line_output(line2)) | 239 return ( | 
| 240 '- %s\n+ %s' % (short_line_output(line1), short_line_output(line2)), | |
| 241 source, | |
| 242 ) | |
| 222 | 243 | 
| 223 # No difference found. | 244 # No difference found. | 
| 224 return None | 245 return None, source | 
| 225 | 246 | 
| 226 | 247 | 
| 227 def get_suppression(arch1, config1, arch2, config2): | 248 def get_suppression(arch1, config1, arch2, config2): | 
| 228 return V8Suppression(arch1, config1, arch2, config2) | 249 return V8Suppression(arch1, config1, arch2, config2) | 
| 229 | 250 | 
| 230 | 251 | 
| 231 class Suppression(object): | 252 class Suppression(object): | 
| 232 def diff(self, output1, output2): | 253 def diff(self, output1, output2): | 
| 233 return None | 254 return None | 
| 234 | 255 | 
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 291 bug = check(IGNORE_OUTPUT.get(arch, {})) | 312 bug = check(IGNORE_OUTPUT.get(arch, {})) | 
| 292 if bug: | 313 if bug: | 
| 293 return bug | 314 return bug | 
| 294 bug = check(IGNORE_OUTPUT.get(config, {})) | 315 bug = check(IGNORE_OUTPUT.get(config, {})) | 
| 295 if bug: | 316 if bug: | 
| 296 return bug | 317 return bug | 
| 297 bug = check(IGNORE_OUTPUT.get('%s,%s' % (arch, config), {})) | 318 bug = check(IGNORE_OUTPUT.get('%s,%s' % (arch, config), {})) | 
| 298 if bug: | 319 if bug: | 
| 299 return bug | 320 return bug | 
| 300 return None | 321 return None | 
| OLD | NEW |