# 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.

"""
Suppressions for V8 correctness fuzzer failures.

We support three types of suppressions:
1. Ignore test case by pattern.
Map a regular expression to a bug entry. A new failure will be reported
when the pattern matches a JS test case.
Subsequent matches will be recoreded under the first failure.

2. Ignore test run by output pattern:
Map a regular expression to a bug entry. A new failure will be reported
when the pattern matches the output of a particular run.
Subsequent matches will be recoreded under the first failure.

3. Relax line-to-line comparisons with expressions of lines to ignore and
lines to be normalized (i.e. ignore only portions of lines).
These are not tied to bugs, be careful to not silently switch off this tool!

Alternatively, think about adding a behavior change to v8_suppressions.js
to silence a particular class of problems.
"""

import itertools
import re

# Max line length for regular experessions checking for lines to ignore.
MAX_LINE_LENGTH = 512

# For ignoring lines before carets and to ignore caret positions.
CARET_RE = re.compile(r'^\s*\^\s*$')

# Ignore by original source files. Map from bug->list of relative file paths in
# V8, e.g. '/v8/test/mjsunit/d8-performance-now.js' including /v8/. A test will
# be suppressed if one of the files below was used to mutate the test.
IGNORE_SOURCES = {
  # This contains a usage of f.arguments that often fires.
  'crbug.com/662424': [
    '/v8/test/mjsunit/bugs/bug-222.js',
    '/v8/test/mjsunit/bugs/bug-941049.js',
    '/v8/test/mjsunit/regress/regress-crbug-668795.js',
    '/v8/test/mjsunit/regress/regress-1079.js',
    '/v8/test/mjsunit/regress/regress-2989.js',
  ],

  'crbug.com/688159': [
    '/v8/test/mjsunit/es7/exponentiation-operator.js',
  ],

  # TODO(machenbach): Implement blacklisting files for particular configs only,
  # here ignition_eager.
  'crbug.com/691589': [
    '/v8/test/mjsunit/regress/regress-1200351.js',
  ],

  'crbug.com/691587': [
    '/v8/test/mjsunit/asm/regress-674089.js',
  ],

  'crbug.com/774805': [
    '/v8/test/mjsunit/console.js',
  ],
}

# Ignore by test case pattern. Map from config->bug->regexp. Config '' is used
# to match all configurations. Otherwise use either a compiler configuration,
# e.g. ignition or validate_asm or an architecture, e.g. x64 or ia32.
# Bug is preferred to be a crbug.com/XYZ, but can be any short distinguishable
# label.
# Regular expressions are assumed to be compiled. We use regexp.search.
IGNORE_TEST_CASES = {
  'slow_path': {
    'crbug.com/800651':
        re.compile(r'async', re.S),
  },
  'slow_path_opt': {
    'crbug.com/800651':
        re.compile(r'async', re.S),
  },
}

# Ignore by output pattern. Map from config->bug->regexp. See IGNORE_TEST_CASES
# on how to specify config keys.
# Bug is preferred to be a crbug.com/XYZ, but can be any short distinguishable
# label.
# Regular expressions are assumed to be compiled. We use regexp.search.
IGNORE_OUTPUT = {
  '': {
    'crbug.com/664068':
        re.compile(r'RangeError(?!: byte length)', re.S),
    'crbug.com/667678':
        re.compile(r'\[native code\]', re.S),
    'crbug.com/689877':
        re.compile(r'^.*SyntaxError: .*Stack overflow$', re.M),
  },
}

# Lines matching any of the following regular expressions will be ignored
# if appearing on both sides. The capturing groups need to match exactly.
# Use uncompiled regular expressions - they'll be compiled later.
ALLOWED_LINE_DIFFS = [
  # Ignore caret position in stack traces.
  r'^\s*\^\s*$',

  # Ignore some stack trace headers as messages might not match.
  r'^(.*)TypeError: .* is not a function$',
  r'^(.*)TypeError: .* is not a constructor$',
  r'^(.*)TypeError: (.*) is not .*$',
  r'^(.*)ReferenceError: .* is not defined$',
  r'^(.*):\d+: ReferenceError: .* is not defined$',

  # These are rarely needed. It includes some cases above.
  r'^\w*Error: .* is not .*$',
  r'^(.*) \w*Error: .* is not .*$',
  r'^(.*):\d+: \w*Error: .* is not .*$',

  # Some test cases just print the message.
  r'^.* is not a function(.*)$',
  r'^(.*) is not a .*$',

  # crbug.com/680064. This subsumes one of the above expressions.
  r'^(.*)TypeError: .* function$',

  # crbug.com/664068
  r'^(.*)(?:Array buffer allocation failed|Invalid array buffer length)(.*)$',
]

# Lines matching any of the following regular expressions will be ignored.
# Use uncompiled regular expressions - they'll be compiled later.
IGNORE_LINES = [
  r'^Warning: unknown flag .*$',
  r'^Warning: .+ is deprecated.*$',
  r'^Try --help for options$',

  # crbug.com/705962
  r'^\s\[0x[0-9a-f]+\]$',
]


###############################################################################
# Implementation - you should not need to change anything below this point.

# Compile regular expressions.
ALLOWED_LINE_DIFFS = [re.compile(exp) for exp in ALLOWED_LINE_DIFFS]
IGNORE_LINES = [re.compile(exp) for exp in IGNORE_LINES]

ORIGINAL_SOURCE_PREFIX = 'v8-foozzie source: '

def line_pairs(lines):
  return itertools.izip_longest(
      lines, itertools.islice(lines, 1, None), fillvalue=None)


def caret_match(line1, line2):
  if (not line1 or
      not line2 or
      len(line1) > MAX_LINE_LENGTH or
      len(line2) > MAX_LINE_LENGTH):
    return False
  return bool(CARET_RE.match(line1) and CARET_RE.match(line2))


def short_line_output(line):
  if len(line) <= MAX_LINE_LENGTH:
    # Avoid copying.
    return line
  return line[0:MAX_LINE_LENGTH] + '...'


def ignore_by_regexp(line1, line2, allowed):
  if len(line1) > MAX_LINE_LENGTH or len(line2) > MAX_LINE_LENGTH:
    return False
  for exp in allowed:
    match1 = exp.match(line1)
    match2 = exp.match(line2)
    if match1 and match2:
      # If there are groups in the regexp, ensure the groups matched the same
      # things.
      if match1.groups() == match2.groups():  # tuple comparison
        return True
  return False


def diff_output(output1, output2, allowed, ignore1, ignore2):
  """Returns a tuple (difference, source).

  The difference is None if there's no difference, otherwise a string
  with a readable diff.

  The source is the last source output within the test case, or None if no
  such output existed.
  """
  def useful_line(ignore):
    def fun(line):
      return all(not e.match(line) for e in ignore)
    return fun

  lines1 = filter(useful_line(ignore1), output1)
  lines2 = filter(useful_line(ignore2), output2)

  # This keeps track where we are in the original source file of the fuzz
  # test case.
  source = None

  for ((line1, lookahead1), (line2, lookahead2)) in itertools.izip_longest(
      line_pairs(lines1), line_pairs(lines2), fillvalue=(None, None)):

    # Only one of the two iterators should run out.
    assert not (line1 is None and line2 is None)

    # One iterator ends earlier.
    if line1 is None:
      return '+ %s' % short_line_output(line2), source
    if line2 is None:
      return '- %s' % short_line_output(line1), source

    # If lines are equal, no further checks are necessary.
    if line1 == line2:
      # Instrumented original-source-file output must be equal in both
      # versions. It only makes sense to update it here when both lines
      # are equal.
      if line1.startswith(ORIGINAL_SOURCE_PREFIX):
        source = line1[len(ORIGINAL_SOURCE_PREFIX):]
      continue

    # Look ahead. If next line is a caret, ignore this line.
    if caret_match(lookahead1, lookahead2):
      continue

    # Check if a regexp allows these lines to be different.
    if ignore_by_regexp(line1, line2, allowed):
      continue

    # Lines are different.
    return (
        '- %s\n+ %s' % (short_line_output(line1), short_line_output(line2)),
        source,
    )

  # No difference found.
  return None, source


def get_suppression(arch1, config1, arch2, config2):
  return V8Suppression(arch1, config1, arch2, config2)


class Suppression(object):
  def diff(self, output1, output2):
    return None

  def ignore_by_metadata(self, metadata):
    return None

  def ignore_by_content(self, testcase):
    return None

  def ignore_by_output1(self, output):
    return None

  def ignore_by_output2(self, output):
    return None


class V8Suppression(Suppression):
  def __init__(self, arch1, config1, arch2, config2):
    self.arch1 = arch1
    self.config1 = config1
    self.arch2 = arch2
    self.config2 = config2

  def diff(self, output1, output2):
    return diff_output(
        output1.splitlines(),
        output2.splitlines(),
        ALLOWED_LINE_DIFFS,
        IGNORE_LINES,
        IGNORE_LINES,
    )

  def ignore_by_content(self, testcase):
    # Strip off test case preamble.
    try:
      lines = testcase.splitlines()
      lines = lines[lines.index(
          'print("js-mutation: start generated test case");'):]
      content = '\n'.join(lines)
    except ValueError:
      # Search the whole test case if preamble can't be found. E.g. older
      # already minimized test cases might have dropped the delimiter line.
      content = testcase
    for key in ['', self.arch1, self.arch2, self.config1, self.config2]:
      for bug, exp in IGNORE_TEST_CASES.get(key, {}).iteritems():
        if exp.search(content):
          return bug
    return None

  def ignore_by_metadata(self, metadata):
    for bug, sources in IGNORE_SOURCES.iteritems():
      for source in sources:
        if source in metadata['sources']:
          return bug
    return None

  def ignore_by_output1(self, output):
    return self.ignore_by_output(output, self.arch1, self.config1)

  def ignore_by_output2(self, output):
    return self.ignore_by_output(output, self.arch2, self.config2)

  def ignore_by_output(self, output, arch, config):
    def check(mapping):
      for bug, exp in mapping.iteritems():
        if exp.search(output):
          return bug
      return None
    for key in ['', arch, config]:
      bug = check(IGNORE_OUTPUT.get(key, {}))
      if bug:
        return bug
    return None
