# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""
This recipe can be used by components like v8 to verify blink tests with a
low false positive rate. Similar to a trybot, this recipe compares test
failures from a build with a current component revision with test failures
from a build with a pinned component revision.

Summary of the recipe flow:
1. Sync chromium to HEAD
2. Sync blink to HEAD
3. Sync component X to revision Y
4. Run blink tests
-> In case of failures:
5. Sync chromium to same revision as 1
6. Sync blink to same revision as 2
7. Sync component X to pinned revision from DEPS file
8. Run blink tests
-> If failures in 4 don't happen in 8, then revision Y reveals a problem not
   present in the pinned revision

Revision Y will be the revision property as provided by buildbot or HEAD (i.e.
in a forced build with no revision provided).
"""

from recipe_engine.types import freeze

DEPS = [
  'build/build',
  'build/chromium',
  'build/chromium_checkout',
  'build/chromium_tests',
  'build/test_utils',
  'depot_tools/bot_update',
  'depot_tools/gclient',
  'recipe_engine/context',
  'recipe_engine/path',
  'recipe_engine/platform',
  'recipe_engine/properties',
]


def V8Builder(config, bits, platform):
  return {
    'gclient_apply_config': ['show_v8_revision'],
    'chromium_apply_config': [],
    'chromium_config_kwargs': {
      'BUILD_CONFIG': config,
      'TARGET_BITS': bits,
    },
    'additional_expectations': [
      'v8', 'tools', 'blink_tests', 'TestExpectations',
    ],
    'component': {'path': 'src/v8', 'revision': '%s'},
    'testing': {'platform': platform},
  }


BUILDERS = freeze({
  'client.v8.fyi': {
    'builders': {
      'V8-Blink Win': V8Builder('Release', 32, 'win'),
      'V8-Blink Mac': V8Builder('Release', 64, 'mac'),
      'V8-Blink Linux 64': V8Builder('Release', 64, 'linux'),
      'V8-Blink Linux 64 - future': V8Builder('Release', 64, 'linux'),
      'V8-Blink Linux 64 (dbg)': V8Builder('Debug', 64, 'linux'),
    },
  },
})


def determine_new_future_failures(caller_api, extra_args):
  tests = [
    caller_api.chromium_tests.steps.BlinkTest(
        extra_args=extra_args + [
          '--additional-expectations',
          caller_api.path['checkout'].join(
              'v8', 'tools', 'blink_tests', 'TestExpectationsFuture'),
          '--additional-driver-flag',
          '--js-flags=--future',
        ],
    ),
  ]

  failing_tests = caller_api.test_utils.run_tests_with_patch(
      caller_api, tests, invalid_is_fatal=True)
  if not failing_tests:
    return

  try:
    # HACK(machenbach): Blink tests store state about failing tests. In order
    # to rerun without future, we need to remove the extra args from the
    # existing test object.
    failing_tests[0]._extra_args = extra_args
    caller_api.test_utils.run_tests(caller_api, failing_tests, 'without patch')
  finally:
    with caller_api.step.defer_results():
      for t in failing_tests:
        caller_api.test_utils.summarize_test_with_patch_deapplied(
            caller_api, t, failure_is_fatal=True)


def determine_new_failures(caller_api, tests, deapply_patch_fn):
  """
  Utility function for running steps with a patch applied, and retrying
  failing steps without the patch. Failures from the run without the patch are
  ignored.

  Args:
    caller_api - caller's recipe API; this is needed because self.m here
                 is different than in the caller (different recipe modules
                 get injected depending on caller's DEPS vs. this module's
                 DEPS)
    tests - iterable of objects implementing the Test interface above
    deapply_patch_fn - function that takes a list of failing tests
                       and undoes any effect of the previously applied patch
  """
  # Convert iterable to list, since it is enumerated multiple times.
  tests = list(tests)

  failing_tests = caller_api.test_utils.run_tests_with_patch(
      caller_api, tests, invalid_is_fatal=True)
  if not failing_tests:
    return

  try:
    result = deapply_patch_fn(failing_tests)
    caller_api.test_utils.run_tests(caller_api, failing_tests, 'without patch')
    return result
  finally:
    with caller_api.step.defer_results():
      for t in failing_tests:
        caller_api.test_utils.summarize_test_with_patch_deapplied(
            caller_api, t, failure_is_fatal=True)

def RunSteps(api):
  mastername = api.properties.get('mastername')
  buildername = api.properties.get('buildername')
  master_dict = BUILDERS.get(mastername, {})
  bot_config = master_dict.get('builders', {}).get(buildername)

  # Sync chromium to HEAD.
  api.gclient.set_config('chromium', GIT_MODE=True)
  api.gclient.c.revisions['src'] = 'HEAD'
  api.chromium.set_config('blink',
                          **bot_config.get('chromium_config_kwargs', {}))

  for c in bot_config.get('gclient_apply_config', []):
    api.gclient.apply_config(c)
  api.chromium_tests.set_config('chromium')

  # Sync component to current component revision.
  component_revision = api.properties.get('revision') or 'HEAD'
  api.gclient.c.revisions[bot_config['component']['path']] = (
      bot_config['component']['revision'] % component_revision)

  # Ensure we remember the chromium revision.
  api.gclient.c.got_revision_reverse_mapping['got_cr_revision'] = 'src'
  api.gclient.c.got_revision_mapping.pop('src', None)

  # Run all steps in the checkout dir (consistent with chromium_tests).
  with api.context(cwd=api.chromium_checkout.get_checkout_dir(bot_config)):
    step_result = api.bot_update.ensure_checkout()

    api.chromium.ensure_goma()

    with api.context(cwd=api.path['checkout']):
      api.chromium.runhooks()

    api.chromium_tests.run_mb_and_compile(
        ['blink_tests'], [],
        name_suffix=' (with patch)',
    )

    def component_pinned_fn(_failing_steps):
      bot_update_json = step_result.json.output
      api.gclient.c.revisions['src'] = str(
          bot_update_json['properties']['got_cr_revision'])
      # Reset component revision to the pinned revision from chromium's DEPS
      # for comparison.
      del api.gclient.c.revisions[bot_config['component']['path']]
      # Update without changing got_revision. The first sync is the revision
      # that is tested. The second is just for comparison. Setting got_revision
      # again confuses the waterfall's console view.
      api.bot_update.ensure_checkout(update_presentation=False)

      api.chromium_tests.run_mb_and_compile(
          ['blink_tests'], [],
          name_suffix=' (without patch)',
      )

    extra_args = []
    if bot_config.get('additional_expectations'):
      extra_args.extend([
        '--additional-expectations',
        api.path['checkout'].join(*bot_config['additional_expectations']),
      ])

    tests = [
      api.chromium_tests.steps.BlinkTest(extra_args=extra_args),
    ]

    if 'future' in buildername:
      determine_new_future_failures(api.chromium_tests.m, extra_args)
    else:
      determine_new_failures(api.chromium_tests.m, tests, component_pinned_fn)


def _sanitize_nonalpha(text):
  return ''.join(c if c.isalnum() else '_' for c in text)


def GenTests(api):
  canned_test = api.test_utils.canned_test_output
  with_patch = 'webkit_layout_tests (with patch)'
  without_patch = 'webkit_layout_tests (without patch)'

  def properties(mastername, buildername):
    return (
      api.properties.generic(mastername=mastername,
                             buildername=buildername,
                             revision='a' * 40,
                             path_config='kitchen')
    )

  for mastername, master_config in BUILDERS.iteritems():
    for buildername, bot_config in master_config['builders'].iteritems():
      test_name = 'full_%s_%s' % (_sanitize_nonalpha(mastername),
                                  _sanitize_nonalpha(buildername))
      tests = []
      for (pass_first, suffix) in ((True, '_pass'), (False, '_fail')):
        test = (
          properties(mastername, buildername) +
          api.platform(
              bot_config['testing']['platform'],
              bot_config.get(
                  'chromium_config_kwargs', {}).get('TARGET_BITS', 64)) +
          api.test(test_name + suffix) +
          api.override_step_data(with_patch, canned_test(passing=pass_first))
        )
        if not pass_first:
          test += api.override_step_data(
              without_patch, canned_test(passing=False, minimal=True))
        tests.append(test)

      for test in tests:
        yield test

  # This tests that if the first fails, but the second pass succeeds
  # that we fail the whole build.
  yield (
    api.test('minimal_pass_continues') +
    properties('client.v8.fyi', 'V8-Blink Linux 64') +
    api.override_step_data(with_patch, canned_test(passing=False)) +
    api.override_step_data(without_patch,
                           canned_test(passing=True, minimal=True))
  )


  # This tests what happens if something goes horribly wrong in
  # run_web_tests.py and we return an internal error; the step should
  # be considered a hard failure and we shouldn't try to compare the
  # lists of failing tests.
  # 255 == test_run_results.UNEXPECTED_ERROR_EXIT_STATUS in run_web_tests.py.
  yield (
    api.test('webkit_layout_tests_unexpected_error') +
    properties('client.v8.fyi', 'V8-Blink Linux 64') +
    api.override_step_data(with_patch, canned_test(passing=False, retcode=255))
  )

  # TODO(dpranke): crbug.com/357866 . This tests what happens if we exceed the
  # number of failures specified with --exit-after-n-crashes-or-times or
  # --exit-after-n-failures; the step should be considered a hard failure and
  # we shouldn't try to compare the lists of failing tests.
  # 130 == test_run_results.INTERRUPTED_EXIT_STATUS in run_web_tests.py.
  yield (
    api.test('webkit_layout_tests_interrupted') +
    properties('client.v8.fyi', 'V8-Blink Linux 64') +
    api.override_step_data(with_patch, canned_test(passing=False, retcode=130))
  )

  # This tests what happens if we don't trip the thresholds listed
  # above, but fail more tests than we can safely fit in a return code.
  # (this should be a soft failure and we can still retry w/o the patch
  # and compare the lists of failing tests).
  yield (
    api.test('too_many_failures_for_retcode') +
    properties('client.v8.fyi', 'V8-Blink Linux 64') +
    api.override_step_data(with_patch,
                           canned_test(passing=False,
                                       num_additional_failures=125)) +
    api.override_step_data(without_patch,
                           canned_test(passing=True, minimal=True))
  )
