| 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 |
| 11 import hashlib |
| 11 import itertools | 12 import itertools |
| 13 import json |
| 12 import os | 14 import os |
| 13 import re | 15 import re |
| 14 import sys | 16 import sys |
| 15 import traceback | 17 import traceback |
| 16 | 18 |
| 17 import v8_commands | 19 import v8_commands |
| 18 import v8_suppressions | 20 import v8_suppressions |
| 19 | 21 |
| 20 CONFIGS = dict( | 22 CONFIGS = dict( |
| 21 default=[], | 23 default=[], |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 assert options.first_arch in SUPPORTED_ARCHS | 110 assert options.first_arch in SUPPORTED_ARCHS |
| 109 assert options.second_arch in SUPPORTED_ARCHS | 111 assert options.second_arch in SUPPORTED_ARCHS |
| 110 assert options.first_config in CONFIGS | 112 assert options.first_config in CONFIGS |
| 111 assert options.second_config in CONFIGS | 113 assert options.second_config in CONFIGS |
| 112 | 114 |
| 113 # Ensure we have a test case. | 115 # Ensure we have a test case. |
| 114 assert (os.path.exists(options.testcase) and | 116 assert (os.path.exists(options.testcase) and |
| 115 os.path.isfile(options.testcase)), ( | 117 os.path.isfile(options.testcase)), ( |
| 116 'Test case %s doesn\'t exist' % options.testcase) | 118 'Test case %s doesn\'t exist' % options.testcase) |
| 117 | 119 |
| 120 resources_path = os.path.join( |
| 121 os.path.dirname(options.testcase), |
| 122 'resources' + os.path.basename(options.testcase)[len('fuzz'):]) |
| 123 assert os.path.exists(resources_path), ( |
| 124 'Resources file %s doesn\'t exist' % resources_path) |
| 125 |
| 126 with open(resources_path) as f: |
| 127 resources = f.read().strip().splitlines() |
| 128 assert len(resources) == 1 |
| 129 options.meta_data_path = os.path.join( |
| 130 os.path.dirname(resources_path), resources[0]) |
| 131 assert os.path.exists(options.meta_data_path), ( |
| 132 'Metadata %s doesn\'t exist' % options.meta_data_path) |
| 133 |
| 118 # Use first d8 as default for second d8. | 134 # Use first d8 as default for second d8. |
| 119 options.second_d8 = options.second_d8 or options.first_d8 | 135 options.second_d8 = options.second_d8 or options.first_d8 |
| 120 | 136 |
| 121 # Ensure absolute paths. | 137 # Ensure absolute paths. |
| 122 options.first_d8 = os.path.abspath(options.first_d8) | 138 options.first_d8 = os.path.abspath(options.first_d8) |
| 123 options.second_d8 = os.path.abspath(options.second_d8) | 139 options.second_d8 = os.path.abspath(options.second_d8) |
| 124 | 140 |
| 125 # Ensure executables exist. | 141 # Ensure executables exist. |
| 126 assert os.path.exists(options.first_d8) | 142 assert os.path.exists(options.first_d8) |
| 127 assert os.path.exists(options.second_d8) | 143 assert os.path.exists(options.second_d8) |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 | 190 |
| 175 # Suppressions are architecture and configuration specific. | 191 # Suppressions are architecture and configuration specific. |
| 176 suppress = v8_suppressions.get_suppression( | 192 suppress = v8_suppressions.get_suppression( |
| 177 options.first_arch, options.first_config, | 193 options.first_arch, options.first_config, |
| 178 options.second_arch, options.second_config, | 194 options.second_arch, options.second_config, |
| 179 ) | 195 ) |
| 180 | 196 |
| 181 if test_pattern_bailout(options.testcase, suppress.ignore): | 197 if test_pattern_bailout(options.testcase, suppress.ignore): |
| 182 return RETURN_FAIL | 198 return RETURN_FAIL |
| 183 | 199 |
| 200 # Get metadata. |
| 201 with open(options.meta_data_path) as f: |
| 202 metadata = json.load(f) |
| 203 |
| 184 common_flags = FLAGS + ['--random-seed', str(options.random_seed)] | 204 common_flags = FLAGS + ['--random-seed', str(options.random_seed)] |
| 185 first_config_flags = common_flags + CONFIGS[options.first_config] | 205 first_config_flags = common_flags + CONFIGS[options.first_config] |
| 186 second_config_flags = common_flags + CONFIGS[options.second_config] | 206 second_config_flags = common_flags + CONFIGS[options.second_config] |
| 187 | 207 |
| 188 def run_d8(d8, config_flags): | 208 def run_d8(d8, config_flags): |
| 189 args = [d8] + config_flags + PREAMBLE + [options.testcase] | 209 args = [d8] + config_flags + PREAMBLE + [options.testcase] |
| 190 if d8.endswith('.py'): | 210 if d8.endswith('.py'): |
| 191 # Wrap with python in tests. | 211 # Wrap with python in tests. |
| 192 args = [sys.executable] + args | 212 args = [sys.executable] + args |
| 193 return v8_commands.Execute( | 213 return v8_commands.Execute( |
| (...skipping 18 matching lines...) Expand all Loading... |
| 212 if fail_bailout(second_config_output, suppress.ignore_by_output2): | 232 if fail_bailout(second_config_output, suppress.ignore_by_output2): |
| 213 return RETURN_FAIL | 233 return RETURN_FAIL |
| 214 | 234 |
| 215 difference = suppress.diff( | 235 difference = suppress.diff( |
| 216 first_config_output.stdout, second_config_output.stdout) | 236 first_config_output.stdout, second_config_output.stdout) |
| 217 if difference: | 237 if difference: |
| 218 # The first three entries will be parsed by clusterfuzz. Format changes | 238 # The first three entries will be parsed by clusterfuzz. Format changes |
| 219 # will require changes on the clusterfuzz side. | 239 # will require changes on the clusterfuzz side. |
| 220 first_config_label = '%s,%s' % (options.first_arch, options.first_config) | 240 first_config_label = '%s,%s' % (options.first_arch, options.first_config) |
| 221 second_config_label = '%s,%s' % (options.second_arch, options.second_config) | 241 second_config_label = '%s,%s' % (options.second_arch, options.second_config) |
| 242 hsh = lambda x: hashlib.sha1(x).hexdigest()[:8] |
| 222 print FAILURE_TEMPLATE % dict( | 243 print FAILURE_TEMPLATE % dict( |
| 223 configs='%s:%s' % (first_config_label, second_config_label), | 244 configs='%s:%s' % (first_config_label, second_config_label), |
| 224 sources='', # TODO | 245 sources=','.join(map(hsh, metadata['sources'])), |
| 225 suppression='', # We can't tie bugs to differences. | 246 suppression='', # We can't tie bugs to differences. |
| 226 first_config_label=first_config_label, | 247 first_config_label=first_config_label, |
| 227 second_config_label=second_config_label, | 248 second_config_label=second_config_label, |
| 228 first_config_flags=' '.join(first_config_flags), | 249 first_config_flags=' '.join(first_config_flags), |
| 229 second_config_flags=' '.join(second_config_flags), | 250 second_config_flags=' '.join(second_config_flags), |
| 230 first_config_output=first_config_output.stdout, | 251 first_config_output=first_config_output.stdout, |
| 231 second_config_output=second_config_output.stdout, | 252 second_config_output=second_config_output.stdout, |
| 232 difference=difference, | 253 difference=difference, |
| 233 ) | 254 ) |
| 234 return RETURN_FAIL | 255 return RETURN_FAIL |
| (...skipping 16 matching lines...) Expand all Loading... |
| 251 configs='', sources='', suppression='wrong_usage') | 272 configs='', sources='', suppression='wrong_usage') |
| 252 result = RETURN_FAIL | 273 result = RETURN_FAIL |
| 253 except Exception as e: | 274 except Exception as e: |
| 254 print FAILURE_HEADER_TEMPLATE % dict( | 275 print FAILURE_HEADER_TEMPLATE % dict( |
| 255 configs='', sources='', suppression='internal_error') | 276 configs='', sources='', suppression='internal_error') |
| 256 print '# Internal error: %s' % e | 277 print '# Internal error: %s' % e |
| 257 traceback.print_exc(file=sys.stdout) | 278 traceback.print_exc(file=sys.stdout) |
| 258 result = RETURN_FAIL | 279 result = RETURN_FAIL |
| 259 | 280 |
| 260 sys.exit(result) | 281 sys.exit(result) |
| OLD | NEW |