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

from recipe_engine import recipe_api
from collections import OrderedDict
import json, re

PATH_FILTERS = [
    r'(out|xcodebuild)[/\\](Release|Debug|Product)\w*[/\\]' +
    r'(clang_\w*[/\\])?(generated_tests|obj)[/\\]',
    r'tools[/\\]sdks',
    r'xcodebuild[/\\](Release|Debug|Product)\w*[/\\]sdk[/\\]xcode_links',
]


def path_filter(checkout):
  # The 'isolate' script with the RBE-CAS backend applies the path filter to
  # absolute paths, so we compute the complete paths using the regular
  # expressions in PATH_FILTERS.
  root = checkout.replace('\\', r'\\')
  return '|'.join(
      r'(^%s[/\\]%s)' % (root, path_expr) for path_expr in PATH_FILTERS)


ISOLATE_PACKAGE = 'infra/tools/luci/isolate/${platform}'
ISOLATE_VERSION = 'git_revision:640ada9f79ee41d5f837d701e0540ed9f387a90f'
CAS_INSTANCE = 'chromium-swarm'

TEST_PY_PATH = 'tools/test.py'
BUILD_PY_PATH = 'tools/build.py'
GN_PY_PATH = 'tools/gn.py'

_chrome_prefix = '--chrome=third_party/browsers/chrome/'
CHROME_PATH_ARGUMENT = {
    'linux': _chrome_prefix + 'chrome/google-chrome',
    'mac': _chrome_prefix + 'Google Chrome.app/Contents/MacOS/Google Chrome',
    'win': _chrome_prefix + 'Chrome/Application/chrome.exe'
}

_firefox_prefix = '--firefox=third_party/browsers/firefox/'
FIREFOX_PATH_ARGUMENT = {
    'linux': _firefox_prefix + 'firefox/firefox',
    'mac': _firefox_prefix + 'Firefox.app/Contents/MacOS/firefox',
    'win': _firefox_prefix + 'firefox/firefox.exe'
}

CO19_PACKAGE = 'dart/third_party/co19'
CO19_LEGACY_PACKAGE = 'dart/third_party/co19/legacy'
CHROME_PACKAGE = 'dart/browsers/chrome/${platform}'
FIREFOX_PACKAGE = 'dart/browsers/firefox/${platform}'
SDK_PACKAGE = 'dart/dart-sdk/${platform}'
CIPD_SERVER_URL = 'https://chrome-infra-packages.appspot.com'


def _to_lines(list):
  """Convert a list to a string containing one item on each line, terminated
     by a newline, or the empty string for an empty list."""
  return '\n'.join(list + [''])


class DartApi(recipe_api.RecipeApi):
  """Recipe module for code commonly used in dart recipes.

  Shouldn't be used elsewhere."""

  def __init__(self, *args, **kwargs):
    super(DartApi, self).__init__(*args, **kwargs)
    self._isolate_client = None

  def _clobber(self):
    out = 'xcodebuild' if self.m.platform.name == 'mac' else 'out'
    out_path = self.m.path['checkout'].join(out)
    if self.m.path.exists(out_path):
      os = self.m.platform.name
      cmd = (['cmd.exe', '/C', 'rmdir', '/Q', '/S']
             if os == 'win' else ['rm', '-rf'])
      self.m.step('clobber', cmd + [out_path])

  def checkout(self, clobber=False, custom_vars={}):
    """Checks out the dart code and prepares it for building."""
    self.m.gclient.set_config('dart')
    self.m.gclient.c.solutions[0].custom_vars = custom_vars

    with self.m.context(cwd=self.m.path['cache'].join('builder')):
      self.m.bot_update.ensure_checkout(timeout=25 * 60)  # 25 minutes
      with self.m.context(cwd=self.m.path['checkout']):
        if clobber:
          self._clobber()
      self.m.gclient.runhooks()


  def get_secret(self, name):
    """Decrypts the specified secret and returns the location of the result"""
    cloudkms_dir = self.m.path['start_dir'].join('cloudkms')
    cloudkms_package = 'infra/tools/luci/cloudkms/${platform}'
    self.m.cipd.ensure(
        cloudkms_dir,
        self.m.cipd.EnsureFile().add_package(cloudkms_package, 'latest'))

    with self.m.context(cwd=self.m.path['cleanup']):
      file_name = '%s.encrypted' % name
      self.m.gsutil.download('dart-ci-credentials', file_name, file_name)

      cloudkms = self._executable(cloudkms_dir, 'cloudkms')
      secret_key = self.m.path['cleanup'].join('%s.key' % name)
      self.m.step('cloudkms get key', [
          cloudkms, 'decrypt', '-input', file_name, '-output', secret_key,
          'projects/dart-ci/locations/'
          'us-central1/keyRings/dart-ci/cryptoKeys/dart-ci'
      ])
      return secret_key


  def kill_tasks(self, ok_ret='any'):
    """Kills leftover tasks from previous runs or steps."""
    self.m.step(
        'kill processes', [
            self.m.build.python, '-u', self.m.path['checkout'].join(
                'tools', 'task_kill.py'), '--kill_browsers=True',
            '--kill_vsbuild=True'
        ],
        ok_ret=ok_ret)


  def _executable(self, path, cmd):
    """Returns the path to the checked-in SDK dart executable."""
    return path.join('%s.exe' % cmd if self.m.platform.name == 'win' else cmd)

  def dart_executable(self):
    """Returns the path to the checked-in SDK dart executable."""
    return self._executable(
        self.m.path['checkout'].join('tools', 'sdks', 'dart-sdk', 'bin'),
        'dart')

  def _commit_id(self):
    """The commit hash of a CI build or the patch set of a CQ build"""
    return str(self.m.buildbucket.gitiles_commit.id or 'refs/changes/%s/%s' %
               (self.m.buildbucket.build.input.gerrit_changes[0].change,
                self.m.buildbucket.build.input.gerrit_changes[0].patchset))


  def upload_isolate(self, isolate_fileset):
    """Builds an isolate"""
    if not self._isolate_client:
      ensure_file = self.m.cipd.EnsureFile().add_package(
          ISOLATE_PACKAGE, ISOLATE_VERSION)
      isolate_cache = self.m.path['cache'].join('isolate')
      self.m.cipd.ensure(isolate_cache, ensure_file)
      self._isolate_client = isolate_cache.join('isolate')
    fileset_path = self.m.path['checkout'].join('%s' % isolate_fileset)
    step_result = self.m.step(
        'upload testing fileset %s' % isolate_fileset,
        [
            self._isolate_client,
            'archive',
            # TODO(https://github.com/dart-lang/sdk/issues/41982):
            #    We currently don't have build targets that produce exactly the
            #    files needed for sharding. Instead, we have catch-all filesets
            #    in the test matrix that include at least the files the shards
            #    need. These filesets are not build outputs and don't know what
            #    files the build actually produced, so they include many files
            #    and directories that will be there in some builds, but not all.
            #    Without -allow-missing-file-dir, these extra files/directories
            #    cause the isolate command to fail.
            '-allow-missing-file-dir',
            '-ignored-path-filter-re=%s' %
            path_filter(str(self.m.path['checkout'])),
            '-isolate=%s' % fileset_path,
            '-isolated=%s.isolated' % fileset_path,
            '-cas-instance=%s' % CAS_INSTANCE,
        ],
        stdout=self.m.raw_io.output('out'))
    output = step_result.stdout.strip()
    # The output of the tool is of the form "uploaded digest: <hash>/<length>",
    # where <hash>/<length> is used to address the content.
    if not re.match('uploaded digest: .*/.*', output):
      raise self.m.step.InfraFailure(
          'isolate tool did not produce expected output, got: "%s"' % output)
    isolate_hash = output.split()[-1]
    step_result.presentation.step_text = 'fileset hash: %s' % isolate_hash
    return isolate_hash


  def shard(self,
            name,
            isolate_hash,
            test_args,
            os,
            cpu='x86-64',
            pool='dart.tests',
            num_shards=0,
            last_shard_is_local=False,
            cipd_ensure_file=None,
            ignore_failure=False):
    """Runs test.py in the given isolate, sharded over several swarming tasks.
       Returns the created tasks, which can be collected with collect_all().
    """
    assert(num_shards > 0)
    if not cipd_ensure_file:  # pragma: no cover
      cipd_ensure_file = self.m.cipd.EnsureFile()
    cipd_ensure_file.add_package(
        'infra/tools/luci/vpython/${platform}',
        'git_revision:b01b3ede35a24f76f21420f11d13f234848e5d34',
        'cipd_bin_packages')
    cipd_ensure_file.add_package(
        'infra/tools/luci/vpython-native/${platform}',
        'git_revision:b01b3ede35a24f76f21420f11d13f234848e5d34',
        'cipd_bin_packages')
    cipd_ensure_file.add_package('infra/3pp/tools/cpython/${platform}',
                                 'version:2.7.17.chromium.24',
                                 'cipd_bin_packages/cpython')
    cipd_ensure_file.add_package('infra/3pp/tools/cpython3/${platform}',
                                 'version:3.8.1rc1.chromium.10',
                                 'cipd_bin_packages/cpython3')
    path_prefixes = [
        'cipd_bin_packages',
        'cipd_bin_packages/bin',
        'cipd_bin_packages/cpython',
        'cipd_bin_packages/cpython/bin',
        'cipd_bin_packages/cpython3',
        'cipd_bin_packages/cpython3/bin',
    ]

    tasks = []
    # TODO(athom) use built-in sharding to remove for loop
    for shard in range(num_shards):
      if last_shard_is_local and shard == num_shards - 1:
        break

      cmd = ((test_args or []) + [
          '--shards=%s' % num_shards,
          '--shard=%s' % (shard + 1), '--output-directory=${ISOLATED_OUTDIR}'
      ])

      # TODO(crbug/1018836): Use distro specific name instead of Linux.
      os_names = {
          'android': 'Android',
          'fuchsia': 'Fuchsia',
          'linux': 'Linux',
          'mac': 'Mac',
          'win': 'Windows',
      }

      dimensions = {
          'os': os_names.get(os, os),
          'cpu': cpu,
          'pool': pool,
          'gpu': None,
      }

      task_request = (
          self.m.swarming.task_request().with_name(
              '%s_shard_%s' % (name, (shard + 1))).
          # Set a priority lower than any builder, to prioritize shards.
          with_priority(25))
      if ignore_failure:
        task_request = task_request.with_tags({'optional': ['true']})

      task_slice = task_request[0] \
        .with_cipd_ensure_file(cipd_ensure_file) \
        .with_command(cmd) \
        .with_containment_type('AUTO') \
        .with_dimensions(**dimensions) \
        .with_env_prefixes(PATH=path_prefixes) \
        .with_env_vars(VPYTHON_VIRTUALENV_ROOT='cache/vpython') \
        .with_execution_timeout_secs(3600) \
        .with_expiration_secs(3600) \
        .with_cas_input_root(isolate_hash) \
        .with_io_timeout_secs(1200) \
        .with_named_caches({ 'vpython' : 'cache/vpython' })

      if 'shard_timeout' in self.m.properties:
        task_slice = (task_slice.with_execution_timeout_secs(
          int(self.m.properties['shard_timeout'])))

      task_request = task_request.with_slice(0, task_slice)
      tasks.append(task_request)
    return self.m.swarming.trigger('trigger shards for %s' % name, tasks)


  def _channel(self):
    channel = self.m.buildbucket.builder_name.split('-')[-1]
    if channel in ['beta', 'dev', 'stable', 'try']:
      return channel
    return 'master'


  def _release_builder(self):
    """Boolean that reports whether the builder is on the
       beta, dev or stable channels. Some steps are only
       run on the master and try builders."""
    return self._channel() in ['beta', 'dev', 'stable']


  def _try_builder(self):
    """Boolean that reports whether this a try builder.
       Some steps are not run on the try builders."""
    return self._channel() == 'try'


  def _branch_builder(self):
    """Returns True if this builder is setup to build a branch (other
       than the branches associated with release channels; see
       _release_builder)."""
    return (self.m.buildbucket.gitiles_commit.ref != "refs/heads/master" and
            not self._release_builder() and not self._try_builder())

  def _supports_result_database(self):
    """Returns True if this builder can send its test results to the test result
       system."""
    # This additional check ensures that builders with names indicating a
    # release builder but that are on the master branch don't send data to the
    # results database.
    # TODO(karlklose): verify in the beginning of the recipe that the builder
    #                  name and the commit ref are consistent.
    if self._release_builder():
      return False
    return (self._try_builder() or self.m.buildbucket.gitiles_commit.ref in [
        "refs/heads/master", "refs/heads/ci-test-data"
    ])

  def _is_bisecting(self):
    return self.m.bisect_build.is_bisecting()


  def collect_all(self, steps):
    """Collects the results of a sharded test run."""
    # Defer results in case one of the shards has a non-zero exit code.
    with self.m.step.defer_results():
      # TODO(athom) collect all the output, and present as a single step
      for step in steps:
        tasks = step.tasks
        step.tasks = []
        for shard in tasks:
          self._collect(step, shard)

  def _collect(self, step, task):
    output_dir = self.m.path.mkdtemp()
    # Every shard is only a single task in swarming
    task_result = self.m.swarming.collect(task.name, [task], output_dir)[0]
    # Swarming uses the task's id as a subdirectory name
    output_dir = output_dir.join(task.id)
    try:
      task_result.analyze()
    except self.m.step.InfraFailure as failure:
      if (task_result.state == self.m.swarming.TaskState.COMPLETED and
          not step.is_test_step):
        self.m.step.active_result.presentation.status = 'FAILURE'
        raise self.m.step.StepFailure(failure.reason)
      else:
        self.m.step.active_result.presentation.status = 'EXCEPTION'
        raise
    except self.m.step.StepFailure as failure:
      assert (task_result.state == self.m.swarming.TaskState.TIMED_OUT)
      self.m.step.active_result.presentation.status = 'EXCEPTION'
      raise self.m.step.InfraFailure(failure.reason)

    bot_name = task_result.bot_id
    task_name = task_result.name
    self._add_results_and_links(output_dir, bot_name, task_name, step.results)

  def _add_results_and_links(self, output_dir, bot_name, task_name, results):
    filenames = ('logs.json', 'results.json')
    for filename in filenames:
      file_path = output_dir.join(filename)
      self.m.path.mock_add_paths(file_path)
      if self.m.path.exists(file_path):
        contents = self.m.file.read_text(
            'read %s for %s' % (filename, task_name), file_path)
        if filename == 'results.json':
          results.add_results(bot_name, contents)
        if filename == 'logs.json':
          results.logs += contents


  def _get_latest_tested_commit(self):
    builder = self._get_builder_dir()
    latest_result = self.m.gsutil.download(
        'dart-test-results',
        'builders/%s/latest' % builder,
        self.m.raw_io.output_text(name='latest', add_output_log=True),
        name='find latest build',
        ok_ret='any') # TODO(athom): succeed only if file does not exist
    latest = latest_result.raw_io.output_texts.get('latest')
    revision = None
    if latest:
      latest = latest.strip()
      revision_result = self.m.gsutil.download(
          'dart-test-results',
          'builders/%s/%s/revision' % (builder, latest),
          self.m.raw_io.output_text(name='revision', add_output_log=True),
          name='get revision for latest build',
          ok_ret='any') # TODO(athom): succeed only if file does not exist
      revision = revision_result.raw_io.output_texts.get('revision')
    return (latest, revision)


  def _get_builder_dir(self):
    builder = self.m.buildbucket.builder_name
    if builder.endswith('-try'):
      builder = builder[:-4]
      target = self.m.tryserver.gerrit_change_target_ref.split('/')[-1]
      if target != 'master':
        builder = '%s-%s' % (builder, target)
    return str(builder)


  def _download_results(self, latest):
    filenames = ['results.json', 'flaky.json']
    builder = self._get_builder_dir()
    results_path = self.m.path['checkout'].join('LATEST')
    self.m.file.ensure_directory('ensure LATEST dir', results_path)
    for filename in filenames:
      self.m.file.write_text(
        'ensure %s exists' % filename, results_path.join(filename), '')
    if latest:
      self.m.gsutil.download(
          'dart-test-results',
          'builders/%s/%s/*.json' % (builder, latest),
          results_path,
          name='download previous results')


  def _deflake_results(self, step):
    step.deflake_list = self.m.step(
        'list tests to deflake (%s)' % step.name, [
            self.dart_executable(),
            self._bot_script('compare_results.dart'),
            '--flakiness-data=LATEST/flaky.json',
            '--changed',
            '--failing',
            '--count=50',
            'LATEST/results.json',
            self.m.raw_io.input_text(step.results.results),
        ],
        stdout=self.m.raw_io.output_text(add_output_log=True)).stdout
    if step.deflake_list:
      self._run_step(step)


  def _update_flakiness_information(self, results_str):
    command_args = [
        '-i', 'LATEST/flaky.json', '-o',
        self.m.raw_io.output_text(name='flaky.json', add_output_log=True),
        '--build-id', self.m.buildbucket.build.id, '--commit',
        self.m.buildbucket.gitiles_commit.id,
        self.m.raw_io.input_text(results_str, name='results.json')
    ]
    if self._try_builder():
      command_args.append('--no-forgive')
    flaky_json = self.m.step(
        'update flakiness information',
        [self.dart_executable(),
         self._bot_script('update_flakiness.dart')] + command_args)
    return flaky_json.raw_io.output_texts.get('flaky.json')

  def _get_results_by_configuration(self, results):
    result = {}
    if not results:
      return result
    for line in results.splitlines():
      result.setdefault(json.loads(line)['configuration'], []).append(line)
    return result

  def _upload_configurations_to_cloud(self, flaky_str, logs_str,
                                      results_by_configuration):

    logs = self._get_results_by_configuration(logs_str)
    flaky = self._get_results_by_configuration(flaky_str)

    for configuration in results_by_configuration:
      self._upload_results_to_cloud(
          _to_lines(flaky.get(configuration, [])),
          _to_lines(logs.get(configuration, [])),
          _to_lines(results_by_configuration[configuration]), configuration)

  def _upload_results_to_cloud(self, flaky_json_str, logs_str, results_str,
                               configuration):
    builder = self.m.buildbucket.builder_name
    build_revision = self.m.buildbucket.gitiles_commit.id
    build_number = str(self.m.buildbucket.build.number)

    if configuration:
      path = 'configuration/%s/%s' % (self._channel(), configuration)
    else:
      path = 'builders/%s' % builder
    if (self.m.runtime.is_experimental):
      path = 'experimental/%s' % path
    self._upload_result(path, build_number, 'revision', build_revision)
    self._upload_result(path, build_number, 'logs.json', logs_str)
    self._upload_result(path, build_number, 'results.json', results_str)
    self._upload_result(path, build_number, 'flaky.json', flaky_json_str)
    if (not self._release_builder() and not configuration and
        not self.m.runtime.is_experimental):
      self._upload_result('builders/current_flakiness', 'single_directory',
                          'flaky_current_%s.json' % builder, flaky_json_str)
    # Update "latest" file, if this is not a bisection build (bisection builds
    # have higher build numbers although they test older commits)
    if not self._is_bisecting():
      new_latest = self.m.raw_io.input_text(build_number, name='latest')
      args = [
          new_latest,
          'dart-test-results',
          '%s/%s' % (path, 'latest'),
      ]
      self.m.gsutil.upload(*args, name='update "latest" reference')

  def _upload_result(self, path, build_number, filename, result_str):
    args = [
        self.m.raw_io.input_text(str(result_str), name=filename),
        'dart-test-results',
        '%s/%s/%s' % (path, build_number, filename),
    ]
    self.m.gsutil.upload(*args, name='upload %s' % filename)

  def _update_blamelist(self, results_by_configuration):
    if not self._supports_result_database() or self.m.runtime.is_experimental:
      return
    access_token = self.m.service_account.default().get_access_token(
        ['https://www.googleapis.com/auth/cloud-platform'])
    for configuration in results_by_configuration:
      results_str = _to_lines(results_by_configuration[configuration])
      command = [
          self.dart_executable(),
          self._bot_script('update_blamelists.dart'), '--results',
          self.m.raw_io.input_text(results_str), '--auth-token',
          self.m.raw_io.input_text(access_token)
      ]
      if self._branch_builder():
        # Write to the staging database (for testing).
        command.append('-s')
      self.m.step('update blamelists for configuration "%s"' % configuration,
                  command)

  def _bot_script(self, script_name):
    return self.m.path['checkout'].join('tools', 'bots', script_name)

  def _publish_results(self, results_str):
    if self._is_bisecting():
      return
    if not self._supports_result_database():
      # Cloud functions can only handle commits on certain branches and
      # CL references (for try jobs).
      return
    if self.m.runtime.is_experimental:
      return
    access_token = self.m.service_account.default().get_access_token(
      ['https://www.googleapis.com/auth/cloud-platform'])
    command = [
        self.dart_executable(),
        self._bot_script('post_results_to_pubsub.dart'), '--result_file',
        self.m.raw_io.input_text(results_str), '--auth_token',
        self.m.raw_io.input_text(access_token), '--id',
        self.m.buildbucket.build.id, '--base_revision',
        self.m.bot_update.last_returned_properties.get(
            'got_revision', 'got_revision property not found')
    ]
    if self._branch_builder():
      # Publish to the staging database (for testing).
      command.append('-s')
    self.m.step('publish results to pub/sub', command)


  def _report_success(self, results_str):
    if results_str:
      access_token = self.m.service_account.default().get_access_token(
          ['https://www.googleapis.com/auth/cloud-platform'])
      try:
        with self.m.context(infra_steps=False):
          command = [
              self.dart_executable(),
              self._bot_script('get_builder_status.dart'), '-b',
              self.m.buildbucket.builder_name, '-n',
              self.m.buildbucket.build.number, '-a',
              self.m.raw_io.input_text(access_token)
          ]
          if self._branch_builder():
            # Get the status from the staging database (for testing).
            command.append('-s')
          self.m.step('test results', command)
      except self.m.step.StepFailure:
        result = self.m.step.active_result
        if result.retcode > 1:
          # Returns codes other than 1 are infra failures
          self.m.step.active_result.presentation.status = 'EXCEPTION'
          raise self.m.step.InfraFailure('failed to get test results')
        raise


  def _extend_results_records(self, results_str, prior_results_path,
                              flaky_json_str, prior_flaky_path, builder_name,
                              build_number, commit_time, commit_id):
    return self.m.step('add fields to result records', [
        self.dart_executable(),
        self._bot_script('extend_results.dart'),
        self.m.raw_io.input_text(results_str,
                                 name='results.json'), prior_results_path,
        self.m.raw_io.input_text(flaky_json_str, name='flaky.json'),
        prior_flaky_path, builder_name, build_number, commit_time, commit_id,
        self.m.raw_io.output_text()
    ]).raw_io.output_text


  def _present_results(self, logs_str, results_str, flaky_json_str):
    args = [
        self.dart_executable(),
        self._bot_script('compare_results.dart'),
        '--flakiness-data',
        self.m.raw_io.input_text(flaky_json_str, name='flaky.json'),
        '--human',
        '--verbose',
        self.m.path['checkout'].join('LATEST', 'results.json'),
        self.m.raw_io.input_text(results_str),
    ]
    args_logs = ["--logs",
                 self.m.raw_io.input_text(logs_str, name='logs.json'),
                 "--logs-only"]
    links = OrderedDict()
    judgement_args = list(args)
    judgement_args.append('--judgement')
    links["new test failures"] = self.m.step(
        'find new test failures',
        args + ["--changed", "--failing"],
        stdout=self.m.raw_io.output_text(add_output_log=True)).stdout
    links["new test failures (logs)"] = self.m.step(
        'find new test failures (logs)',
        args + args_logs + ["--changed", "--failing"],
        stdout=self.m.raw_io.output_text(add_output_log=True)).stdout
    links["tests that began passing"] = self.m.step(
        'find tests that began passing',
        args + ["--changed", "--passing"],
        stdout=self.m.raw_io.output_text(add_output_log=True)).stdout
    judgement_args += ["--changed", "--failing"]
    if self._try_builder():  # pragma: no cover
      judgement_args += ["--passing"]
    else:
      links["ignored flaky test failure logs"] = self.m.step(
          'find ignored flaky test failure logs',
          args + args_logs + ["--flaky"],
          stdout=self.m.raw_io.output_text(add_output_log=True)).stdout
    with self.m.step.defer_results():
      if not self._supports_result_database() or self._is_bisecting():
        with self.m.context(infra_steps=False):
          self.m.step('test results', judgement_args)
      else:
        # This call runs a step that the following links get added to.
        self._report_success(results_str)

      # Add more links and logs to the 'test results' step
      if self._try_builder():
        # Construct different results links for tryjobs and CI jobs
        patchset = self._commit_id().replace('refs/changes/', '')
        log_url = 'https://dart-ci.firebaseapp.com/cl/%s' % patchset
      else:
        log_url = self._results_feed_url(results_str)
      self.m.step.active_result.presentation.links['Test Results'] = log_url
      doc_url = 'https://goto.google.com/dart-status-file-free-workflow'
      self.m.step.active_result.presentation.links['Documentation'] = doc_url
      # Show only the links with non-empty output (something happened).
      for link, contents in links.iteritems():
        if contents != '': # pragma: no cover
          self.m.step.active_result.presentation.logs[link] = [contents]
      self.m.step.active_result.presentation.logs['results.json'] = [
          results_str]

  def _results_feed_url(self, results_str):
    configurations = {
        json.loads(line)['configuration']
        for line in (results_str or '').splitlines()
    }
    results_feed_url = 'https://dart-ci.firebaseapp.com/'
    return '%s#showLatestFailures=true&configurations=%s' % (
        results_feed_url, ','.join(configurations))

  def read_debug_log(self):
    """Reads the debug log file"""
    if self.m.platform.name == 'win':
      self.m.step('debug log',
                  ['cmd.exe', '/c', 'type', '.debug.log'],
                  ok_ret='any')
    else:
      self.m.step('debug log',
                  ['cat', '.debug.log'],
                  ok_ret='any')


  def delete_debug_log(self):
    """Deletes the debug log file"""
    self.m.file.remove('delete debug log',
                       self.m.path['checkout'].join('.debug.log'))


  def test(self, test_data):
    """Reads the test-matrix.json file in the checkout and runs each step listed
    in the file.
    """
    with self.m.context(infra_steps=True):
      test_matrix_path = self.m.path['checkout'].join('tools', 'bots',
                                                      'test_matrix.json')
      read_json = self.m.json.read(
          'read test-matrix.json',
          test_matrix_path,
          step_test_data=lambda: self.m.json.test_api.output(test_data))
      test_matrix = read_json.json.output
      builder = str(self.m.buildbucket.builder_name)
      if builder.endswith(('-be', '-beta', '-dev', '-stable', '-try')):
        builder = builder[0:builder.rfind('-')]
      isolate_hashes = {}
      global_config = test_matrix['global']
      config = None
      for c in test_matrix['builder_configurations']:
        if builder in c['builders']:
          config = c
          break
      if config is None:
        raise self.m.step.InfraFailure(
            'Error, could not find builder by name %s in test-matrix' % builder)
      self.delete_debug_log()
      self._write_file_sets(test_matrix['filesets'])
      self._run_steps(config, isolate_hashes, builder, global_config)


  def _write_file_sets(self, filesets):
    """Writes the fileset to the root of the sdk to allow for swarming to pick
    up the files and isolate the files.
    Args:
      * filesets - Filesets from the test-matrix
    """
    for fileset,files in filesets.iteritems():
      isolate_fileset = { 'variables': { 'files': files } }
      destination_path = self.m.path['checkout'].join(fileset)
      self.m.file.write_text('write fileset %s to sdk root' % fileset,
                            destination_path,
                            str(isolate_fileset))


  def _build_isolates(self, config, isolate_hashes):
    """Isolate filesets from all steps in config and populates a dictionary
    with a mapping from fileset to isolate_hash.
    Args:
      * config (dict) - Configuration of the builder, including the steps
      * isolate_hashes (dict) - A dict that will contain a mapping from
            fileset name to isolate hash upon completion of this method.
    """
    for step in config['steps']:
      if 'fileset' in step and step['fileset'] not in isolate_hashes:
        isolate_hash = self.upload_isolate(step['fileset'])
        isolate_hashes[step['fileset']] = isolate_hash


  def _get_option(self, builder_fragments, options, default_value):
    """Gets an option from builder_fragments in options, or returns the default
    value."""
    intersection = set(builder_fragments) & set(options)
    if len(intersection) == 1:
      return intersection.pop()
    return default_value


  def _get_specific_argument(self, arguments, options):
    for arg in arguments:
      if isinstance(arg, basestring):
        for option in options:
          if arg.startswith(option):
            return arg[len(option):]
    return None


  def _has_specific_argument(self, arguments, options):
    return self._get_specific_argument(arguments, options) is not None


  def _run_steps(self, config, isolate_hashes, builder_name, global_config):
    """Executes all steps from a json test-matrix builder entry"""
    # Find information from the builder name. It should be in the form
    # <info>-<os>-<mode>-<arch>-<runtime> or <info>-<os>-<mode>-<arch>.
    builder_fragments = builder_name.split('-')
    system = self._get_option(builder_fragments,
                              ['android', 'fuchsia', 'linux', 'mac', 'win'],
                              'linux')
    mode = self._get_option(
      builder_fragments,
      ['debug', 'release', 'product'],
      'release')
    arch = self._get_option(builder_fragments, [
        'arm',
        'arm64',
        'arm64c',
        'arm_x64',
        'ia32',
        'simarm',
        'simarm64',
        'simarm64c',
        'simarm_x64',
        'x64',
        'x64c',
    ], 'x64')
    sanitizer = self._get_option(
        builder_fragments, ['asan', 'lsan', 'msan', 'tsan', 'ubsan'], 'none')
    runtime = self._get_option(
      builder_fragments,
      ['none', 'd8', 'jsshell', 'edge', 'ie11', 'firefox', 'safari', 'chrome'],
      None)

    co19_filter = '--filter=%s/%s' % (CIPD_SERVER_URL, CO19_PACKAGE)
    co19_legacy_filter = co19_filter + '/legacy'
    checked_in_sdk_filter = '--filter=%s/%s' % (CIPD_SERVER_URL, SDK_PACKAGE)
    chrome_filter = '--filter=%s/%s' % (CIPD_SERVER_URL, CHROME_PACKAGE)
    firefox_filter = '--filter=%s/%s' % (CIPD_SERVER_URL, FIREFOX_PACKAGE)
    with self.m.context(cwd=self.m.path['checkout']):
      result = self.m.gclient(
          'get package versions', [
              'revinfo',
              '--output-json',
              self.m.json.output(name='revinfo'),
              co19_filter,
              co19_legacy_filter,
              checked_in_sdk_filter,
              chrome_filter,
              firefox_filter,
          ],
          step_test_data=self._canned_revinfo)
    revinfo = result.json.outputs.get('revinfo')
    if not revinfo:
      raise recipe_api.InfraFailure('failed to get package versions')

    packages = {}
    for k, v in revinfo.items():
      path, name = k.split(':')
      path = path[4:]  # Remove "sdk/" prefix
      version = v['rev']
      packages[name] = (name, version, path)

    assert SDK_PACKAGE in packages
    assert CO19_PACKAGE in packages
    assert CO19_LEGACY_PACKAGE in packages
    has_firefox = FIREFOX_PACKAGE in packages
    has_chrome = CHROME_PACKAGE in packages

    out = 'xcodebuild' if self.m.platform.name == 'mac' else 'out'
    build_root = out + '/' + mode.capitalize() + arch.upper()
    environment = {
        'system': system,
        'mode': mode,
        'arch': arch,
        'sanitizer': sanitizer,
        'build_root': build_root,
        'copy-coredumps': False,
        'packages': packages,
        'out': out
    }
    # Linux and vm-*-win builders should use copy-coredumps
    environment['copy-coredumps'] = (system == 'linux' or system == 'mac' or
            (system.startswith('win') and builder_name.startswith('vm-')))

    if runtime is not None:
      if runtime == 'ff':
        runtime = 'firefox' # pragma: no cover
      environment['runtime'] = runtime
      if ((not has_chrome and runtime == 'chrome') or
          (not has_firefox and runtime == 'firefox')):
        # TODO(athom): remove legacy download browser feature when release
        # branches have the browser DEPS (2.9 has merged to stable).
        version = global_config[runtime]
        self.download_browser(runtime, version)
        package = CHROME_PACKAGE if runtime == 'chrome' else FIREFOX_PACKAGE
        path = 'third_party/browsers/%s' % runtime
        packages[package] = (package, 'version:%s' % version, path)
    test_steps = []
    sharded_steps = []
    try:
      with self.m.step.defer_results():
        for index, step_json in enumerate(config['steps']):
          step = self.TestMatrixStep(self.m, builder_name, config, step_json,
                                     environment, index)
          if step.fileset:
            # We build isolates here, every time we see fileset, to wait for the
            # building of Dart, which may be included in the fileset.
            result = self._build_isolates(config, isolate_hashes)
            # Fail the whole deferred block early in case that an isolate upload failed.
            if result and not result.is_ok:
              raise result.get_error()
            step.isolate_hash = isolate_hashes[step.fileset]

          if not step.is_trigger and step.is_test_step:
            test_steps.append(step)
          if step.isolate_hash and not (step.local_shard and step.shards < 2):
            sharded_steps.append(step)
          self._run_step(step)
        self.collect_all(sharded_steps)
    except recipe_api.AggregatedStepFailure as failure:
      if self.has_infra_failure(failure):
        raise recipe_api.InfraFailure(failure.reason)
      else:
        raise
    self._process_test_results(test_steps)


  @recipe_api.non_step
  def _run_step(self, step):
    with self.m.depot_tools.on_path(), self.m.context(
        cwd=self.m.path['checkout'],
        env=step.environment_variables):
      if step.is_gn_step:
        with self.m.context(infra_steps=False):
          self._run_gn(step)
      elif step.is_build_step:
        self._run_build(step)
      elif step.is_trigger:
        self._run_trigger(step)
      elif step.is_test_py_step:
        self._run_test_py(step)
      else:
        with self.m.context(infra_steps=step.is_test_step):
          self._run_script(step)


  @recipe_api.non_step
  def _run_gn(self, step):
    mode = step.environment['mode']
    arch = step.environment['arch']
    sanitizer = step.environment['sanitizer']
    args = step.args
    if not self._has_specific_argument(args, ['-m', '--mode']):
      args = ['-m%s' % mode] + args
    if not self._has_specific_argument(args, ['-a', '--arch']):
      args = ['-a%s' % arch] + args
    if not self._has_specific_argument(args, ['--sanitizer']):
      args = ['--sanitizer=%s' % sanitizer] + args
    self.m.build.gn(name=step.name, args=args)


  @recipe_api.non_step
  def _run_build(self, step):
    mode = step.environment['mode']
    arch = step.environment['arch']
    sanitizer = step.environment['sanitizer']
    args = step.args
    if not self._has_specific_argument(args, ['-m', '--mode']):
      args = ['-m%s' % mode] + args
    if not self._has_specific_argument(args, ['-a', '--arch']):
      args = ['-a%s' % arch] + args
    if not self._has_specific_argument(args, ['--sanitizer']):
      args = ['--sanitizer=%s' % sanitizer] + args
    self.kill_tasks()
    deferred_result = self.m.build.build(name=step.name, args=args)
    deferred_result.get_result() # raises build errors


  def _process_test_results(self, steps):
    # If there are no test steps, steps will be empty.
    if steps:
      with self.m.context(cwd=self.m.path['checkout']):
        with self.m.step.nest('download previous results'):
          if self._is_bisecting():
            # With the new bbagent infrastructure, this value is returned
            # as a floating-point value, not an int.
            latest = int(self.m.bisect_build.get_base_build())
          else:
            latest, _ = self._get_latest_tested_commit()
          self._download_results(latest)
        with self.m.step.nest('deflaking'):
          for step in steps:
            if step.is_test_py_step:
              self._deflake_results(step)
          self.collect_all(steps)
        logs_str = ''.join(
            (step.results.logs for step in steps))
        results_str = ''.join(
            (step.results.results for step in steps))
        flaky_json_str = self._update_flakiness_information(results_str)
        results_str = self._extend_results_records(
            results_str, self.m.path['checkout'].join('LATEST', 'results.json'),
            flaky_json_str,
            self.m.path['checkout'].join('LATEST', 'flaky.json'),
            self.m.buildbucket.builder_name, self.m.buildbucket.build.number,
            self.m.git.get_timestamp(test_data='1234567'), self._commit_id())
        try:
          results_by_configuration = self._get_results_by_configuration(
              results_str)
          # Try builders do not upload results, only publish to pub/sub
          with self.m.step.nest('upload new results'):
            if results_str:
              self._publish_results(results_str)
            if not self._try_builder():
              self._upload_results_to_cloud(flaky_json_str, logs_str,
                                            results_str, None)
              self._upload_configurations_to_cloud(flaky_json_str, logs_str,
                                                   results_by_configuration)
              self._upload_results_to_bq(results_str)
          if self._is_bisecting():
            self._update_blamelist(results_by_configuration)
        finally:
          self._present_results(logs_str, results_str, flaky_json_str)


  def download_browser(self, runtime, version):
    # Download CIPD package
    #  dart/browsers/<runtime>/${platform} <version>
    # to directory
    #  [sdk root]/third_party/browsers
    # Shards must install this CIPD package to the same location -
    # there is an argument to the swarming module task creation api for this.
    browser_path = self.m.path['checkout'].join('third_party', 'browsers',
                                                runtime)
    self.m.file.ensure_directory('create browser cache', browser_path)
    version_tag = 'version:%s' % version
    package = 'dart/browsers/%s/${platform}' % runtime
    ensure_file = self.m.cipd.EnsureFile().add_package(package, version_tag)
    self.m.cipd.ensure(browser_path, ensure_file)
    return browser_path


  def _upload_results_to_bq(self, results_str):
    if self._is_bisecting() or not results_str:
      return  # pragma: no cover
    assert(results_str[-1] == '\n')

    bqupload_path = self.m.path['checkout'].join('bqupload')
    package = r'infra/tools/bqupload/${platform}'
    ensure_file = self.m.cipd.EnsureFile().add_package(package, 'latest')
    self.m.cipd.ensure(bqupload_path, ensure_file)

    bqupload = bqupload_path.join('bqupload')
    cmd = [bqupload , 'dart-ci.results.results']
    with self.m.step.nest('upload test results to big query'):
      # Upload at most 1000 lines at once
      for match in re.finditer(r'(?:.*\n){1,1000}', results_str):
        chunk = match.group(0)
        if not self.m.runtime.is_experimental:
          self.m.step(
              'upload results chunk to big query',
              cmd,
              stdin=self.m.raw_io.input_text(chunk))


  def _run_trigger(self, step):
    trigger_props = {}
    trigger_props['revision'] = self.m.buildbucket.gitiles_commit.id
    trigger_props['parent_buildername'] = self.m.buildbucket.builder_name
    trigger_props['parent_build_id'] = self.m.properties.get('build_id', '')
    if step.isolate_hash:
      trigger_props['parent_fileset'] = step.isolate_hash
      trigger_props['parent_fileset_name'] = step.fileset
    put_result = self.m.buildbucket.put(
        [
          {
            'bucket': 'luci.dart.ci',
            'parameters': {
              'builder_name': builder_name,
              'properties': trigger_props,
              'changes': [
                {
                  'author': {
                    'email': author,
                  },
                }
                for author in self.m.properties.get('blamelist', [])
              ],
            },
          }
          for builder_name in step.triggered_builders
        ])
    self.m.step.active_result.presentation.step_text = step.name
    for build in put_result.stdout['results']:
      builder_tag = (
          x for x in build['build']['tags'] if x.startswith('builder:')).next()
      builder_name = builder_tag[len('builder:'):]
      self.m.step.active_result.presentation.links[builder_name] = (
          build['build']['url'])


  def _run_test_py(self, step):
    """Runs test.py with default arguments, based on configuration from.
    Args:
      * step (TestMatrixStep) - The test-matrix step.
    """
    environment = step.environment
    args = step.args
    shards = step.shards
    if step.deflake_list:
      args = args + ['--repeat=5', '--tests', step.deflake_list]
      shards = min(shards, 1)

    test_args = [
        '--progress=status', '--report', '--time', '--silent-failures',
        '--write-results', '--write-logs', '--clean-exit'
    ]
    args = test_args + args
    if environment['copy-coredumps']:
      args.append('--copy-coredumps')
    system = environment['system']
    # TODO(athom): enable this on stable before 2.12 is merged to stable.
    if system == 'win' and self._channel() != 'stable':
      args.append('--cleanup-dart-processes')
    # The --chrome flag is added here if the runtime for the bot is
    # chrome. This also catches the case where there is a specific
    # argument -r or --runtime. It misses the case where
    # a recipe calls run_script directly with a test.py command.
    # The download of the browser from CIPD should also be moved
    # here (perhaps checking if it is already done) so we catch
    # specific test steps with runtime chrome in a bot without that
    # global runtime.
    ensure_file = self.m.cipd.EnsureFile()

    def _add_package(condition, name, browser_arg):
      if browser_arg and environment['packages'].get(name):
        ensure_file.add_package(*environment['packages'][name])
        args.append(browser_arg)

    _add_package('chrome', CHROME_PACKAGE, CHROME_PATH_ARGUMENT.get(system))
    _add_package('firefox', FIREFOX_PACKAGE, FIREFOX_PATH_ARGUMENT.get(system))

    with self.m.step.defer_results():
      self._run_script(
          step,
          args,
          cipd_ensure_file=ensure_file,
          ignore_failure=step.deflake_list,
          shards=shards)

  def _run_script(self,
                  step,
                  args=None,
                  cipd_ensure_file=None,
                  ignore_failure=False,
                  shards=None):
    """Runs a specific script with current working directory to be checkout. If
    the runtime (passed in environment) is a browser, and the system is linux,
    xvfb is used. If an isolate_hash is passed in, it will swarm the command.
    Args:
      * step (TestMatrixStep) - The test-matrix step.
      * args ([str]) - Overrides the arguments specified in the step.
      * cipd_packages ([tuple]) - list of 3-tuples specifying a cipd package
        to be downloaded
      * ignore_failure ([bool]) - Do not turn step red if this script fails.
      * shards ([int]) - Overrides the number of shards specified in the step.
    """
    environment = step.environment
    if not args:
      args = step.args
    if not cipd_ensure_file:  # pragma: no cover
      cipd_ensure_file = self.m.cipd.EnsureFile()

    def _add_package(name):
      cipd_ensure_file.add_package(*environment['packages'][name])

    _add_package(SDK_PACKAGE)

    if any(arg.startswith('co19_2') for arg in args):
      _add_package(CO19_LEGACY_PACKAGE)
    if any(arg.startswith('co19/') or arg == 'co19' for arg in args):
      _add_package(CO19_PACKAGE)

    ok_ret = 'any' if ignore_failure else {0}
    runtime = environment.get('runtime', None)
    use_xvfb = (runtime in ['chrome', 'firefox'] and
                environment['system'] == 'linux')
    script = step.script
    is_python = str(script).endswith('.py')
    cmd_prefix = []
    if use_xvfb:
      cmd_prefix = [
          '/usr/bin/xvfb-run', '-a', '--server-args=-screen 0 1024x768x24'
      ]
    if is_python:
      python = self.m.build.python
      cmd_prefix += [python, '-u']

    step_name = step.name
    shards = shards or step.shards
    if step.isolate_hash and not (step.local_shard and shards < 2):
      with self.m.step.nest('trigger shards for %s' % step_name):
        arch = environment['arch']
        cpu = arch if arch.startswith('arm') else 'x86-64'
        # arm_x64 -> arm (x64 gen_snapshot creating 32bit arm code).
        cpu = cpu.replace('_x64', '')
        step.tasks += self.shard(
            step_name,
            step.isolate_hash,
            cmd_prefix + [script] + args,
            num_shards=shards,
            last_shard_is_local=step.local_shard,
            cipd_ensure_file=cipd_ensure_file,
            ignore_failure=ignore_failure,
            cpu=cpu,
            os=environment['system'])
      if step.local_shard:
        args = args + [
          '--shards=%s' % shards,
          '--shard=%s' % shards,
        ]
        step_name = '%s_shard_%s' % (step_name, shards)
      else:
        return # Shards have been triggered, no local shard to run.

    output_dir = None
    if step.is_test_step:
      output_dir = self.m.path.mkdtemp()
      args = args + [
          '--output-directory',
          output_dir,
      ]

    cmd = self.m.path['checkout'].join(*script.split('/'))
    self.m.step(step_name, cmd_prefix + [cmd] + args, ok_ret=ok_ret)
    if output_dir:
      self._add_results_and_links(output_dir, self.m.properties.get('bot_id'),
                                  step_name, step.results)


  def _canned_revinfo(self):
    revinfo = {}

    def _add_package(path, package, version):
      revinfo['%s:%s' % (path, package)] = {
          'url': '%s/%s' % (CIPD_SERVER_URL, package),
          'rev': version,
      }

    _add_package('sdk/tests/co19/src', CO19_PACKAGE, 'git_revision:co19_hash')
    _add_package('sdk/tests/co19_2/src', CO19_LEGACY_PACKAGE,
                 'git_revision:co19_2_hash')
    _add_package('sdk/tools/sdks', SDK_PACKAGE, 'version:2.9.0-18.0.dev')

    if 'download_chrome' in self.m.properties.get('custom_vars', {}):
      _add_package('sdk/third_party/browsers/chrome', CHROME_PACKAGE,
                   'version:81')
    if 'download_firefox' in self.m.properties.get('custom_vars', {}):
      _add_package('sdk/third_party/browsers/firefox', FIREFOX_PACKAGE,
                   'version:67')

    return self.m.json.test_api.output(name='revinfo', data=revinfo)

  class TestMatrixStep:
    def __init__(self, m, builder_name, config, step_json, environment, index):
      self.m = m
      self.name = step_json['name']
      self.results = StepResults(m)
      self.deflake_list = []
      self.args = step_json.get('arguments', [])
      self.environment = environment
      self.tasks = []
      self.is_trigger = 'trigger' in step_json
      self.triggered_builders = step_json.get('trigger', [])
      # If script is not defined, use test.py.
      self.script = step_json.get('script', TEST_PY_PATH)
      if self.m.platform.name == 'mac' and self.script.startswith('out/'):
        self.script = self.script.replace('out/', 'xcodebuild/', 1)
      is_dart = self.script.endswith('/dart')
      if is_dart:
        executable_suffix = '.exe' if self.m.platform.name == 'win' else ''
        self.script += executable_suffix

      self.is_build_step = self.script.endswith(BUILD_PY_PATH)
      self.is_gn_step = self.script.endswith(GN_PY_PATH)
      self.is_test_py_step = self.script.endswith(TEST_PY_PATH)
      self.is_test_step = (self.is_test_py_step
          or step_json.get('testRunner', False))

      self.isolate_hash = None
      self.fileset = step_json.get('fileset')
      self.shards = step_json.get('shards', 0)
      self.local_shard = (self.shards > 1 and index == len(config['steps']) - 1
          and not environment['system'] == 'android')

      self.environment_variables = step_json.get('environment', {})

      channels = {
          "refs/heads/ci-test-data": "infra",
          "refs/heads/master": "be",
          "refs/heads/beta": "beta",
          "refs/heads/dev": "dev",
          "refs/heads/stable": "stable",
      }
      channel = channels.get(self.m.buildbucket.gitiles_commit.ref, 'try')
      self.environment_variables['BUILDBOT_BUILDERNAME'] = (
          builder_name + "-%s" % channel)

      # Enable Crashpad integration if a Windows bot wants to copy coredumps.
      if self.environment['copy-coredumps'] and self.m.platform.name == 'win':
        self.environment_variables['DART_USE_CRASHPAD'] = '1'

      def _expand_environment(arg):
        for k, v in environment.iteritems():
          arg = arg.replace('${%s}' % k, str(v))
        return arg

      self.args = [_expand_environment(arg) for arg in self.args]

  def has_infra_failure(self, failure):
    """ Returns whether failure is an aggregated failure that directly or
        indirectly contains an InfraFailure."""
    if not isinstance(failure, recipe_api.AggregatedStepFailure):
      return False
    elif failure.result.contains_infra_failure:
      return True
    else:
      for f in failure.result.failures:
        if self.has_infra_failure(f):
          return True
      return False


class StepResults:
  def __init__(self, m):
    self.logs = ''
    self.results = ''
    self.builder_name = str(m.buildbucket.builder_name) # Returned as unicode
    self.build_number = str(m.buildbucket.build.number)


  def add_results(self, bot_name, results_str):
    extra = ',"bot_name":"%s"}\n' % bot_name
    all_matches = re.finditer(r'(^{.*)(?:})', results_str, flags=re.MULTILINE)
    all_chunks = (chunk for match in all_matches for chunk in (
        match.group(1), extra))
    self.results += ''.join(all_chunks)
