OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2016 the V8 project authors. All rights reserved. | 2 # Copyright 2016 the V8 project authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """ | 6 """ |
7 V8 correctness fuzzer launcher script. | 7 V8 correctness fuzzer launcher script. |
8 """ | 8 """ |
9 | 9 |
10 import argparse | 10 import argparse |
(...skipping 19 matching lines...) Expand all Loading... |
30 ignition_turbo_opt=['--ignition-staging', '--turbo', '--always-opt'], | 30 ignition_turbo_opt=['--ignition-staging', '--turbo', '--always-opt'], |
31 ) | 31 ) |
32 | 32 |
33 # Timeout in seconds for one d8 run. | 33 # Timeout in seconds for one d8 run. |
34 TIMEOUT = 3 | 34 TIMEOUT = 3 |
35 | 35 |
36 # Return codes. | 36 # Return codes. |
37 RETURN_PASS = 0 | 37 RETURN_PASS = 0 |
38 RETURN_FAIL = 2 | 38 RETURN_FAIL = 2 |
39 | 39 |
| 40 # The number of hex digits used from the hash of the original source file path. |
| 41 # Keep the number small to avoid duplicate explosion. |
| 42 SOURCE_HASH_LENGTH = 3 |
| 43 |
40 BASE_PATH = os.path.dirname(os.path.abspath(__file__)) | 44 BASE_PATH = os.path.dirname(os.path.abspath(__file__)) |
41 PREAMBLE = [ | 45 PREAMBLE = [ |
42 os.path.join(BASE_PATH, 'v8_mock.js'), | 46 os.path.join(BASE_PATH, 'v8_mock.js'), |
43 os.path.join(BASE_PATH, 'v8_suppressions.js'), | 47 os.path.join(BASE_PATH, 'v8_suppressions.js'), |
44 ] | 48 ] |
45 | 49 |
46 FLAGS = ['--abort_on_stack_overflow', '--expose-gc', '--allow-natives-syntax', | 50 FLAGS = ['--abort_on_stack_overflow', '--expose-gc', '--allow-natives-syntax', |
47 '--invoke-weak-callbacks', '--omit-quit', '--es-staging'] | 51 '--invoke-weak-callbacks', '--omit-quit', '--es-staging'] |
48 | 52 |
49 SUPPORTED_ARCHS = ['ia32', 'x64', 'arm', 'arm64'] | 53 SUPPORTED_ARCHS = ['ia32', 'x64', 'arm', 'arm64'] |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 def main(): | 199 def main(): |
196 options = parse_args() | 200 options = parse_args() |
197 | 201 |
198 # Suppressions are architecture and configuration specific. | 202 # Suppressions are architecture and configuration specific. |
199 suppress = v8_suppressions.get_suppression( | 203 suppress = v8_suppressions.get_suppression( |
200 options.first_arch, options.first_config, | 204 options.first_arch, options.first_config, |
201 options.second_arch, options.second_config, | 205 options.second_arch, options.second_config, |
202 ) | 206 ) |
203 | 207 |
204 # Get metadata. | 208 # Get metadata. |
| 209 # TODO(machenbach): We probably don't need the metadata file anymore |
| 210 # now that the metadata is printed in the test cases. |
205 with open(options.meta_data_path) as f: | 211 with open(options.meta_data_path) as f: |
206 metadata = json.load(f) | 212 metadata = json.load(f) |
207 | 213 |
208 if metadata_bailout(metadata, suppress.ignore_by_metadata): | 214 if metadata_bailout(metadata, suppress.ignore_by_metadata): |
209 return RETURN_FAIL | 215 return RETURN_FAIL |
210 | 216 |
211 if test_pattern_bailout(options.testcase, suppress.ignore_by_content): | 217 if test_pattern_bailout(options.testcase, suppress.ignore_by_content): |
212 return RETURN_FAIL | 218 return RETURN_FAIL |
213 | 219 |
214 common_flags = FLAGS + ['--random-seed', str(options.random_seed)] | 220 common_flags = FLAGS + ['--random-seed', str(options.random_seed)] |
(...skipping 20 matching lines...) Expand all Loading... |
235 return RETURN_FAIL | 241 return RETURN_FAIL |
236 | 242 |
237 second_config_output = run_d8(options.second_d8, second_config_flags) | 243 second_config_output = run_d8(options.second_d8, second_config_flags) |
238 | 244 |
239 # Bailout based on second run's output. | 245 # Bailout based on second run's output. |
240 if pass_bailout(second_config_output, 2): | 246 if pass_bailout(second_config_output, 2): |
241 return RETURN_PASS | 247 return RETURN_PASS |
242 if fail_bailout(second_config_output, suppress.ignore_by_output2): | 248 if fail_bailout(second_config_output, suppress.ignore_by_output2): |
243 return RETURN_FAIL | 249 return RETURN_FAIL |
244 | 250 |
245 difference = suppress.diff( | 251 difference, source = suppress.diff( |
246 first_config_output.stdout, second_config_output.stdout) | 252 first_config_output.stdout, second_config_output.stdout) |
247 if difference: | 253 if difference: |
248 # The first three entries will be parsed by clusterfuzz. Format changes | 254 # The first three entries will be parsed by clusterfuzz. Format changes |
249 # will require changes on the clusterfuzz side. | 255 # will require changes on the clusterfuzz side. |
250 first_config_label = '%s,%s' % (options.first_arch, options.first_config) | 256 first_config_label = '%s,%s' % (options.first_arch, options.first_config) |
251 second_config_label = '%s,%s' % (options.second_arch, options.second_config) | 257 second_config_label = '%s,%s' % (options.second_arch, options.second_config) |
252 hsh = lambda x: hashlib.sha1(x).hexdigest()[:8] | |
253 print FAILURE_TEMPLATE % dict( | 258 print FAILURE_TEMPLATE % dict( |
254 configs='%s:%s' % (first_config_label, second_config_label), | 259 configs='%s:%s' % (first_config_label, second_config_label), |
255 sources=','.join(map(hsh, metadata['sources'])), | 260 sources=hashlib.sha1(source).hexdigest()[:SOURCE_HASH_LENGTH], |
256 suppression='', # We can't tie bugs to differences. | 261 suppression='', # We can't tie bugs to differences. |
257 first_config_label=first_config_label, | 262 first_config_label=first_config_label, |
258 second_config_label=second_config_label, | 263 second_config_label=second_config_label, |
259 first_config_flags=' '.join(first_config_flags), | 264 first_config_flags=' '.join(first_config_flags), |
260 second_config_flags=' '.join(second_config_flags), | 265 second_config_flags=' '.join(second_config_flags), |
261 first_config_output=first_config_output.stdout, | 266 first_config_output=first_config_output.stdout, |
262 second_config_output=second_config_output.stdout, | 267 second_config_output=second_config_output.stdout, |
263 difference=difference, | 268 difference=difference, |
264 ) | 269 ) |
265 return RETURN_FAIL | 270 return RETURN_FAIL |
(...skipping 16 matching lines...) Expand all Loading... |
282 configs='', sources='', suppression='wrong_usage') | 287 configs='', sources='', suppression='wrong_usage') |
283 result = RETURN_FAIL | 288 result = RETURN_FAIL |
284 except Exception as e: | 289 except Exception as e: |
285 print FAILURE_HEADER_TEMPLATE % dict( | 290 print FAILURE_HEADER_TEMPLATE % dict( |
286 configs='', sources='', suppression='internal_error') | 291 configs='', sources='', suppression='internal_error') |
287 print '# Internal error: %s' % e | 292 print '# Internal error: %s' % e |
288 traceback.print_exc(file=sys.stdout) | 293 traceback.print_exc(file=sys.stdout) |
289 result = RETURN_FAIL | 294 result = RETURN_FAIL |
290 | 295 |
291 sys.exit(result) | 296 sys.exit(result) |
OLD | NEW |