1#!/usr/bin/env python 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 4# found in the LICENSE file. 5 6import os 7import subprocess 8import sys 9import unittest 10 11import v8_foozzie 12import v8_fuzz_config 13import v8_suppressions 14 15BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 16FOOZZIE = os.path.join(BASE_DIR, 'v8_foozzie.py') 17TEST_DATA = os.path.join(BASE_DIR, 'testdata') 18 19 20class ConfigTest(unittest.TestCase): 21 def testExperiments(self): 22 """Test that probabilities add up to 100 and that all config names exist. 23 """ 24 EXPERIMENTS = v8_fuzz_config.FOOZZIE_EXPERIMENTS 25 CONFIGS = v8_foozzie.CONFIGS 26 assert sum(x[0] for x in EXPERIMENTS) == 100 27 assert all(map(lambda x: x[1] in CONFIGS, EXPERIMENTS)) 28 assert all(map(lambda x: x[2] in CONFIGS, EXPERIMENTS)) 29 assert all(map(lambda x: x[3].endswith('d8'), EXPERIMENTS)) 30 31 def testConfig(self): 32 """Smoke test how to choose experiments. 33 34 When experiment distribution changes this test might change, too. 35 """ 36 class Rng(object): 37 def random(self): 38 return 0.5 39 self.assertEqual( 40 [ 41 '--first-config=ignition', 42 '--second-config=ignition_turbo', 43 '--second-d8=d8', 44 ], 45 v8_fuzz_config.Config('foo', Rng()).choose_foozzie_flags(), 46 ) 47 48 49class UnitTest(unittest.TestCase): 50 def testDiff(self): 51 # TODO(machenbach): Mock out suppression configuration. 52 suppress = v8_suppressions.get_suppression( 53 'x64', 'ignition', 'x64', 'ignition_turbo') 54 one = '' 55 two = '' 56 diff = None, None 57 self.assertEquals(diff, suppress.diff(one, two)) 58 59 one = 'a \n b\nc();' 60 two = 'a \n b\nc();' 61 diff = None, None 62 self.assertEquals(diff, suppress.diff(one, two)) 63 64 # Ignore line before caret, caret position and error message. 65 one = """ 66undefined 67weird stuff 68 ^ 69somefile.js: TypeError: undefined is not a function 70 undefined 71""" 72 two = """ 73undefined 74other weird stuff 75 ^ 76somefile.js: TypeError: baz is not a function 77 undefined 78""" 79 diff = None, None 80 self.assertEquals(diff, suppress.diff(one, two)) 81 82 one = """ 83Still equal 84Extra line 85""" 86 two = """ 87Still equal 88""" 89 diff = '- Extra line', None 90 self.assertEquals(diff, suppress.diff(one, two)) 91 92 one = """ 93Still equal 94""" 95 two = """ 96Still equal 97Extra line 98""" 99 diff = '+ Extra line', None 100 self.assertEquals(diff, suppress.diff(one, two)) 101 102 one = """ 103undefined 104somefile.js: TypeError: undefined is not a constructor 105""" 106 two = """ 107undefined 108otherfile.js: TypeError: undefined is not a constructor 109""" 110 diff = """- somefile.js: TypeError: undefined is not a constructor 111+ otherfile.js: TypeError: undefined is not a constructor""", None 112 self.assertEquals(diff, suppress.diff(one, two)) 113 114 115def cut_verbose_output(stdout): 116 return '\n'.join(stdout.split('\n')[2:]) 117 118 119def run_foozzie(first_d8, second_d8): 120 return subprocess.check_output([ 121 sys.executable, FOOZZIE, 122 '--random-seed', '12345', 123 '--first-d8', os.path.join(TEST_DATA, first_d8), 124 '--second-d8', os.path.join(TEST_DATA, second_d8), 125 '--first-config', 'ignition', 126 '--second-config', 'ignition_turbo', 127 os.path.join(TEST_DATA, 'fuzz-123.js'), 128 ]) 129 130 131class SystemTest(unittest.TestCase): 132 def testSyntaxErrorDiffPass(self): 133 stdout = run_foozzie('test_d8_1.py', 'test_d8_2.py') 134 self.assertEquals('# V8 correctness - pass\n', cut_verbose_output(stdout)) 135 136 def testDifferentOutputFail(self): 137 with open(os.path.join(TEST_DATA, 'failure_output.txt')) as f: 138 expected_output = f.read() 139 with self.assertRaises(subprocess.CalledProcessError) as ctx: 140 run_foozzie('test_d8_1.py', 'test_d8_3.py') 141 e = ctx.exception 142 self.assertEquals(v8_foozzie.RETURN_FAIL, e.returncode) 143 self.assertEquals(expected_output, cut_verbose_output(e.output)) 144 145 146if __name__ == '__main__': 147 unittest.main() 148