1ca89b8c71
Currently, probabilities for extra flags are calculated in the correctness fuzzer harness, which makes the RNG fragile when bisecting backwards, when the script's config changes during bisection. This adds the possibility to pass extra flags on command line to the script. After a grace period, we will migrate the flag calculation to clusterfuzz. NOTRY=true Bug: chromium:813833 Change-Id: I515181847474515089b847f8aaffc7c6560d9390 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1675945 Reviewed-by: Tamer Tas <tmrts@chromium.org> Commit-Queue: Michael Achenbach <machenbach@chromium.org> Cr-Commit-Position: refs/heads/master@{#62359}
160 lines
4.5 KiB
Python
Executable File
160 lines
4.5 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# Copyright 2016 the V8 project authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import unittest
|
|
|
|
import v8_foozzie
|
|
import v8_fuzz_config
|
|
import v8_suppressions
|
|
|
|
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
FOOZZIE = os.path.join(BASE_DIR, 'v8_foozzie.py')
|
|
TEST_DATA = os.path.join(BASE_DIR, 'testdata')
|
|
|
|
|
|
class ConfigTest(unittest.TestCase):
|
|
def testExperiments(self):
|
|
"""Test that probabilities add up to 100 and that all config names exist.
|
|
"""
|
|
EXPERIMENTS = v8_fuzz_config.FOOZZIE_EXPERIMENTS
|
|
CONFIGS = v8_foozzie.CONFIGS
|
|
assert sum(x[0] for x in EXPERIMENTS) == 100
|
|
assert all(map(lambda x: x[1] in CONFIGS, EXPERIMENTS))
|
|
assert all(map(lambda x: x[2] in CONFIGS, EXPERIMENTS))
|
|
assert all(map(lambda x: x[3].endswith('d8'), EXPERIMENTS))
|
|
|
|
def testConfig(self):
|
|
"""Smoke test how to choose experiments.
|
|
|
|
When experiment distribution changes this test might change, too.
|
|
"""
|
|
class Rng(object):
|
|
def random(self):
|
|
return 0.5
|
|
self.assertEqual(
|
|
[
|
|
'--first-config=ignition',
|
|
'--second-config=ignition_turbo',
|
|
'--second-d8=d8',
|
|
],
|
|
v8_fuzz_config.Config('foo', Rng()).choose_foozzie_flags(),
|
|
)
|
|
|
|
|
|
class UnitTest(unittest.TestCase):
|
|
def testDiff(self):
|
|
# TODO(machenbach): Mock out suppression configuration.
|
|
suppress = v8_suppressions.get_suppression(
|
|
'x64', 'ignition', 'x64', 'ignition_turbo')
|
|
one = ''
|
|
two = ''
|
|
diff = None, None
|
|
self.assertEquals(diff, suppress.diff(one, two))
|
|
|
|
one = 'a \n b\nc();'
|
|
two = 'a \n b\nc();'
|
|
diff = None, None
|
|
self.assertEquals(diff, suppress.diff(one, two))
|
|
|
|
# Ignore line before caret, caret position and error message.
|
|
one = """
|
|
undefined
|
|
weird stuff
|
|
^
|
|
somefile.js: TypeError: undefined is not a function
|
|
undefined
|
|
"""
|
|
two = """
|
|
undefined
|
|
other weird stuff
|
|
^
|
|
somefile.js: TypeError: baz is not a function
|
|
undefined
|
|
"""
|
|
diff = None, None
|
|
self.assertEquals(diff, suppress.diff(one, two))
|
|
|
|
one = """
|
|
Still equal
|
|
Extra line
|
|
"""
|
|
two = """
|
|
Still equal
|
|
"""
|
|
diff = '- Extra line', None
|
|
self.assertEquals(diff, suppress.diff(one, two))
|
|
|
|
one = """
|
|
Still equal
|
|
"""
|
|
two = """
|
|
Still equal
|
|
Extra line
|
|
"""
|
|
diff = '+ Extra line', None
|
|
self.assertEquals(diff, suppress.diff(one, two))
|
|
|
|
one = """
|
|
undefined
|
|
somefile.js: TypeError: undefined is not a constructor
|
|
"""
|
|
two = """
|
|
undefined
|
|
otherfile.js: TypeError: undefined is not a constructor
|
|
"""
|
|
diff = """- somefile.js: TypeError: undefined is not a constructor
|
|
+ otherfile.js: TypeError: undefined is not a constructor""", None
|
|
self.assertEquals(diff, suppress.diff(one, two))
|
|
|
|
|
|
def cut_verbose_output(stdout):
|
|
# This removes first lines containing d8 commands.
|
|
return '\n'.join(stdout.split('\n')[4:])
|
|
|
|
|
|
def run_foozzie(first_d8, second_d8, *extra_flags):
|
|
return subprocess.check_output([
|
|
sys.executable, FOOZZIE,
|
|
'--random-seed', '12345',
|
|
'--first-d8', os.path.join(TEST_DATA, first_d8),
|
|
'--second-d8', os.path.join(TEST_DATA, second_d8),
|
|
'--first-config', 'ignition',
|
|
'--second-config', 'ignition_turbo',
|
|
os.path.join(TEST_DATA, 'fuzz-123.js'),
|
|
] + list(extra_flags))
|
|
|
|
|
|
class SystemTest(unittest.TestCase):
|
|
def testSyntaxErrorDiffPass(self):
|
|
stdout = run_foozzie('test_d8_1.py', 'test_d8_2.py', '--skip-sanity-checks')
|
|
self.assertEquals('# V8 correctness - pass\n', cut_verbose_output(stdout))
|
|
|
|
def testDifferentOutputFail(self):
|
|
with open(os.path.join(TEST_DATA, 'failure_output.txt')) as f:
|
|
expected_output = f.read()
|
|
with self.assertRaises(subprocess.CalledProcessError) as ctx:
|
|
run_foozzie('test_d8_1.py', 'test_d8_3.py', '--skip-sanity-checks',
|
|
'--first-config-extra-flags=--flag1',
|
|
'--first-config-extra-flags=--flag2=0',
|
|
'--second-config-extra-flags=--flag3')
|
|
e = ctx.exception
|
|
self.assertEquals(v8_foozzie.RETURN_FAIL, e.returncode)
|
|
self.assertEquals(expected_output, cut_verbose_output(e.output))
|
|
|
|
def testSanityCheck(self):
|
|
with open(os.path.join(TEST_DATA, 'sanity_check_output.txt')) as f:
|
|
expected_output = f.read()
|
|
with self.assertRaises(subprocess.CalledProcessError) as ctx:
|
|
run_foozzie('test_d8_1.py', 'test_d8_3.py')
|
|
e = ctx.exception
|
|
self.assertEquals(v8_foozzie.RETURN_FAIL, e.returncode)
|
|
self.assertEquals(expected_output, e.output)
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|