text: # Copyright 2019 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.
  
  import textwrap
  
  from recipe_engine import post_process
  from recipe_engine import recipe_api
  
  DEPS = [
    'gclient',
    'presubmit',
    'recipe_engine/buildbucket',
    'recipe_engine/context',
    'recipe_engine/cq',
    'recipe_engine/json',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/runtime',
  ]
  
  
  PROPERTIES = {
    'patch_project': recipe_api.Property(None),
    'patch_repository_url': recipe_api.Property(None),
  }
  
  
  def RunSteps(api, patch_project, patch_repository_url):
    api.gclient.set_config('infra')
    with api.context(cwd=api.path['cache'].join('builder')):
      bot_update_step = api.presubmit.prepare()
      return api.presubmit.execute(bot_update_step)
  
  
  def GenTests(api):
    yield (
        api.test('success') +
        api.runtime(is_experimental=False, is_luci=True) +
        api.buildbucket.try_build(project='infra') +
        api.step_data(
            'presubmit',
            api.json.output({'errors': [], 'notifications': [], 'warnings': []}),
        ) +
        api.post_process(post_process.StatusSuccess) +
        api.post_process(post_process.DropExpectation)
    )
  
    yield (
        api.test('cq_dry_run') +
        api.runtime(is_experimental=False, is_luci=True) +
        api.buildbucket.try_build(project='infra') +
        api.cq(dry_run=True) +
        api.post_process(post_process.StatusSuccess) +
        api.post_process(post_process.StepCommandContains, 'presubmit', ['--dry_run']) +
        api.post_process(post_process.DropExpectation)
    )
  
    yield (
        api.test('root_vpython') +
        api.runtime(is_experimental=False, is_luci=True) +
        api.buildbucket.try_build(project='infra') +
        api.presubmit(vpython_spec_path='.vpython') +
        api.post_process(post_process.StatusSuccess) +
        api.post_process(post_process.DropExpectation)
    )
  
    yield (
        api.test('timeout') +
        api.runtime(is_experimental=False, is_luci=True) +
        api.buildbucket.try_build(project='infra') +
        api.presubmit(timeout_s=600) +
        api.step_data(
            'presubmit',
            api.json.output({'errors': [], 'notifications': [], 'warnings': []}),
            times_out_after=1200,
        ) +
        api.post_process(post_process.StatusFailure) +
        api.post_process(
            post_process.ResultReason,
           (u'#### There are 0 error(s), 0 warning(s), and 0 notifications(s).'
            ' Here are the errors:'
            '\n\nTimeout occurred during presubmit step.')) +
        api.post_process(post_process.DropExpectation)
    )
  
    yield (
        api.test('failure') +
        api.runtime(is_experimental=False, is_luci=True) +
        api.buildbucket.try_build(project='infra') +
        api.step_data('presubmit', api.json.output(
            {
              'errors': [
                {
                  'message': 'Missing LGTM',
                  'long_text': 'Here are some suggested OWNERS: fake@',
                  'items': [],
                  'fatal': True
                },
                {
                  'message': 'Syntax error in fake.py',
                  'long_text': 'Expected "," after item in list',
                  'items': [],
                  'fatal': True
                }
              ],
              'notifications': [
                {
                  'message': 'If there is a bug associated please add it.',
                  'long_text': '',
                  'items': [],
                  'fatal': False
                }
              ],
              'warnings': [
                {
                  'message': 'Line 100 has more than 80 characters',
                  'long_text': '',
                  'items': [],
                  'fatal': False
                }
              ]
            }, retcode=1)
        ) +
        api.post_process(post_process.StatusFailure) +
        api.post_process(post_process.ResultReason, textwrap.dedent(u'''
            #### There are 2 error(s), 1 warning(s), and 1 notifications(s). Here are the errors:
  
            **ERROR**
            ```
            Missing LGTM
            Here are some suggested OWNERS: fake@
            ```
  
            **ERROR**
            ```
            Syntax error in fake.py
            Expected "," after item in list
            ```
  
            #### To see notifications and warnings, look at the stdout of the presubmit step.
          ''').strip()
        ) +
        api.post_process(post_process.DropExpectation)
    )
  
    long_message = (u'Here are some suggested OWNERS:' +
      u'\nreallyLongFakeAccountNameEmail@chromium.org' * 10)
    yield (
        api.test('failure-long-message') +
        api.runtime(is_experimental=False, is_luci=True) +
        api.buildbucket.try_build(project='infra') +
        api.step_data('presubmit', api.json.output(
            {
              'errors': [
                {
                  'message': 'Missing LGTM',
                  'long_text': long_message,
                  'items': [],
                  'fatal': True
                }
              ],
              'notifications': [],
              'warnings': []
            }, retcode=1)
        ) +
        api.post_process(post_process.StatusFailure) +
        api.post_process(post_process.ResultReason, textwrap.dedent('''
            #### There are 1 error(s), 0 warning(s), and 0 notifications(s). Here are the errors:
  
            **ERROR**
            ```
            Missing LGTM
            Here are some suggested OWNERS:
            reallyLongFakeAccountNameEmail@chromium.org
            reallyLongFakeAccountNameEmail@chromium.org
            reallyLongFakeAccountNameEmail@chromium.org
            reallyLongFakeAccountNameEmail@chromium.org
            reallyLongFakeAccountNameEmail@chromium.org
            reallyLongFakeAccountNameEmail@chromium.org
            reallyLongFakeAccountNameEmail@chromium.org
            reallyLongFakeAccountNameEmail@chromium.org
            reallyLongFakeAccountNameEmail@chromium.org
            ```
  
            **Error size > 450 chars, there are 2 more error(s) (15 total)**
            **The complete output can be found at the bottom of the presubmit stdout.**
          ''').strip()
        ) +
        api.post_process(post_process.DropExpectation)
    )
  
    yield (
        api.test('infra-failure') +
        api.runtime(is_experimental=False, is_luci=True) +
        api.buildbucket.try_build(project='infra') +
        api.step_data('presubmit', api.json.output(
            {
              'errors': [
                {
                  'message': 'Infra Failure',
                  'long_text': '',
                  'items': [],
                  'fatal': True
                }
              ],
              'notifications': [],
              'warnings': []
            }, retcode=2)
        ) +
        api.post_process(post_process.StatusException) +
        api.post_process(post_process.ResultReason, textwrap.dedent(u'''
          #### There are 1 error(s), 0 warning(s), and 0 notifications(s). Here are the errors:
  
          **ERROR**
          ```
          Infra Failure
  
          ```
          ''').strip()
        ) +
        api.post_process(post_process.DropExpectation)
    )
  
    bug_msg = (
      'Something unexpected occurred'
      ' while running presubmit checks.'
      ' Please [file a bug](https://bugs.chromium.org'
      '/p/chromium/issues/entry?components='
      'Infra%3EClient%3EChrome&status=Untriaged)'
    )
    yield (
        api.test('failure-no-json') +
        api.runtime(is_experimental=False, is_luci=True) +
        api.buildbucket.try_build(project='infra') +
        api.step_data('presubmit', api.json.output(None, retcode=1)) +
        api.post_process(post_process.StatusException) +
        api.post_process(post_process.ResultReason, bug_msg) +
        api.post_process(post_process.DropExpectation)
    )
  
    yield (
        api.test('infra-failure-no-json') +
        api.runtime(is_experimental=False, is_luci=True) +
        api.buildbucket.try_build(project='infra') +
        api.step_data('presubmit', api.json.output(None, retcode=2)) +
        api.post_process(post_process.StatusException) +
        api.post_process(post_process.ResultReason, bug_msg) +
        api.post_process(post_process.DropExpectation)
    )
  
  