# Copyright 2013 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 argparse
import ast
import base64
from collections import defaultdict
import contextlib
import datetime
import difflib
import functools
import random
import re
import urllib

# pylint: disable=relative-import
from builders import TestSpec
from recipe_engine.types import freeze
from recipe_engine import recipe_api
from . import bisection
from . import builders as v8_builders
from . import testing


MILO_HOST = 'luci-milo.appspot.com'
V8_URL = 'https://chromium.googlesource.com/v8/v8'

COMMIT_TEMPLATE = '%s/+/%%s' % V8_URL

# Regular expressions for v8 branch names.
RELEASE_BRANCH_RE = re.compile(r'^refs/branch-heads/\d+\.\d+$')

# Regular expressions for getting target bits from gn args.
TARGET_CPU_RE = re.compile(r'.*target_cpu\s+=\s+"([^"]*)".*')

# With more than 23 letters, labels are to big for buildbot's popup boxes.
MAX_LABEL_SIZE = 23

# Make sure that a step is not flooded with log lines.
MAX_FAILURE_LOGS = 10

# Factor by which the considered failure for bisection must be faster than the
# ongoing build's total.
BISECT_DURATION_FACTOR = 5

TEST_RUNNER_PARSER = argparse.ArgumentParser()
TEST_RUNNER_PARSER.add_argument('--extra-flags')

VERSION_LINE_RE = r'^#define %s\s+(\d*)$'
VERSION_LINE_REPLACEMENT = '#define %s %s'
V8_MAJOR = 'V8_MAJOR_VERSION'
V8_MINOR = 'V8_MINOR_VERSION'
V8_BUILD = 'V8_BUILD_NUMBER'
V8_PATCH = 'V8_PATCH_LEVEL'

LCOV_IMAGE = 'lcov:2018-01-18_17-03'


class V8Version(object):
  """A v8 version as used for tagging (with patch level), e.g. '3.4.5.1'."""

  def __init__(self, major, minor, build, patch):
    self.major = major
    self.minor = minor
    self.build = build
    self.patch = patch

  def __eq__(self, other):
    return (self.major == other.major and
            self.minor == other.minor and
            self.build == other.build and
            self.patch == other.patch)

  def __str__(self):
    patch_str = '.%s' % self.patch if self.patch and self.patch != '0' else ''
    return '%s.%s.%s%s' % (self.major, self.minor, self.build, patch_str)

  def with_incremented_patch(self):
    return V8Version(
        self.major, self.minor, self.build, str(int(self.patch) + 1))

  def update_version_file_blob(self, blob):
    """Takes a version file's text and returns it with this object's version.
    """
    def sub(label, value, text):
      return re.sub(
          VERSION_LINE_RE % label,
          VERSION_LINE_REPLACEMENT % (label, value),
          text,
          flags=re.M,
      )
    blob = sub(V8_MAJOR, self.major, blob)
    blob = sub(V8_MINOR, self.minor, blob)
    blob = sub(V8_BUILD, self.build, blob)
    return sub(V8_PATCH, self.patch, blob)


class V8Api(recipe_api.RecipeApi):
  VERSION_FILE = 'include/v8-version.h'
  EMPTY_TEST_SPEC = v8_builders.EmptyTestSpec
  TEST_SPEC = v8_builders.TestSpec

  def __init__(self, *args, **kwargs):
    super(V8Api, self).__init__(*args, **kwargs)
    self.test_configs = {}
    self.bot_config = None
    self.rerun_failures_count = None
    self.test_duration_sec = None
    self.isolated_tests = None
    self.build_environment = None
    self.checkout_root = None
    self.revision = None
    self.revision_cp = None
    self.revision_number = None

  def bot_config_by_buildername(
      self, builders=None, use_goma=True):
    default = {}
    if not self.m.properties.get('parent_buildername'):
      # Builders and builder_testers both build and need the following set of
      # default chromium configs:
      if use_goma:
        default['chromium_apply_config'] = ['default_compiler', 'goma', 'mb']
      else:
        default['chromium_apply_config'] = ['default_compiler', 'mb']
    return (builders or {}).get(self.m.buildbucket.builder_name, default)

  def update_bot_config(self, bot_config, binary_size_tracking, build_config,
                        clusterfuzz_archive, coverage, enable_swarming,
                        target_arch, target_platform, track_build_dependencies,
                        triggers, triggers_proxy):
    """Update bot_config dict with src-side properties.

    Args:
      bot_config: The bot_config dict to update.
      binary_size_tracking: Additional configurations to enable binary size
          tracking.
      build_config: Config value for BUILD_CONFIG in chromium recipe module.
      clusterfuzz_archive: Additional configurations set for archiving builds to
          GS buckets for clusterfuzz.
      coverage: Optional coverage setting.
      enable_swarming: Switch to enable/disable swarming.
      target_arch: Config value for TARGET_ARCH in chromium recipe module.
      target_platform: Config value for TARGET_PLATFORM in chromium recipe
          module.
      track_build_dependencies: Weather to track and upload build-dependencies.
      triggers: List of tester names to trigger on success.
      triggers_proxy: Weather to trigger the internal trigger proxy.

    Returns:
      An updated copy of the bot_config dict.
    """
    # TODO(machenbach): Turn the bot_config dict into a proper class.
    # Make mutable copy.
    bot_config = dict(bot_config)
    bot_config['v8_config_kwargs'] = dict(
        bot_config.get('v8_config_kwargs', {}))
    # Update only specified properties.
    for k, v in (
        ('BUILD_CONFIG', build_config),
        ('TARGET_ARCH', target_arch),
        ('TARGET_PLATFORM', target_platform)):
      if v is not None:
        bot_config['v8_config_kwargs'][k] = v
    if coverage is not None:
      bot_config['coverage'] = coverage
    if enable_swarming is not None:
      bot_config['enable_swarming'] = enable_swarming
    if binary_size_tracking is not None:
      bot_config['binary_size_tracking'] = binary_size_tracking
    if clusterfuzz_archive is not None:
      bot_config['clusterfuzz_archive'] = clusterfuzz_archive
    if track_build_dependencies is not None:
      bot_config['track_build_dependencies'] = track_build_dependencies
    # Make mutable copy.
    bot_config['triggers'] = list(bot_config.get('triggers', []))
    bot_config['triggers'].extend(triggers or [])
    # TODO(machenbach): Temporarily also dedupe, during migrating triggers src
    # side. Should be removed when everything has migrated.
    bot_config['triggers'] = sorted(list(set(bot_config['triggers'])))
    bot_config['triggers_proxy'] = triggers_proxy
    return bot_config

  def get_test_roots(self):
    """Returns the list of default and extensible test root directories.

    A test root is a directory with the following layout:
    <root>/infra/testing/config.pyl (optional)
    <root>/infra/testing/builders.pyl
    <root>/test/<test suites> (optional)

    By default, the V8 checkout is a test root, and all matching directories
    under v8/custom_deps.

    Returns: List of paths to test roots.
    """
    result = [self.m.path['checkout']]
    custom_deps_dir = self.m.path['checkout'].join('custom_deps')
    self.m.file.ensure_directory('ensure custom_deps dir', custom_deps_dir)
    for path in self.m.file.listdir('list test roots', custom_deps_dir):
      if self.m.path.exists(path.join('infra', 'testing', 'builders.pyl')):
        assert self.bot_type == 'builder_tester', (
            'Separate test checkouts are only supported on builder_testers. '
            'For separate builders and testers, the test configs need to be '
            'transferred as properties')
        result.append(path)
    return result

  def update_test_configs(self, test_configs):
    """Update test configs without mutating previous copy."""
    self.test_configs = dict(self.test_configs)
    self.test_configs.update(test_configs)

  def load_static_test_configs(self):
    """Set predifined test configs from build repository."""
    self.update_test_configs(testing.TEST_CONFIGS)

  def load_dynamic_test_configs(self, root):
    """Add test configs from configured location.

    The test configs in <root>/infra/testing/config.pyl are expected to follow
    the same structure as the TEST_CONFIGS dict in testing.py.

    Args:
      test_checkout: Path to test root, can either be the V8 checkout or an
          additional test checkout.
    Returns: Test config dict.
    """
    test_config_path = root.join('infra', 'testing', 'config.pyl')

    # Fallback for branch builders.
    if not self.m.path.exists(test_config_path):
      return {}

    try:
      # Eval python literal file.
      test_configs = ast.literal_eval(self.m.file.read_text(
          'read test config (%s)' % self.m.path.basename(root),
          test_config_path,
          test_data='{}',
      ))
    except SyntaxError as e:  # pragma: no cover
      raise self.m.step.InfraFailure(
          'Failed to parse test config "%s": %s' % (test_config_path, e))

    for test_config in test_configs.itervalues():
      # This configures the test runner to set the test root to the
      # test_checkout location for all tests from this checkout.
      # TODO(machenbach): This is starting to get hacky. The test config
      # dicts should be refactored into classes similar to test specs. Maybe
      # the extra configurations from test configs could be added to test
      # specs.
      test_config['test_root'] = str(root.join('test'))

    return test_configs

  def apply_bot_config(self, bot_config):
    """Entry method for using the v8 api."""
    self.bot_config = bot_config

    kwargs = {}
    if self.m.properties.get('parent_build_config'):
      kwargs['BUILD_CONFIG'] = self.m.properties['parent_build_config']
    kwargs.update(self.bot_config.get('v8_config_kwargs', {}))

    self.set_config('v8', optional=True, **kwargs)
    self.m.chromium.set_config('v8', **kwargs)
    self.m.gclient.set_config('v8', **kwargs)

    if self.m.chromium.c.TARGET_PLATFORM in ['android', 'fuchsia']:
      self.m.gclient.apply_config(self.m.chromium.c.TARGET_PLATFORM)

    for c in self.bot_config.get('chromium_apply_config', []):
      self.m.chromium.apply_config(c)

    # On clusterfuzz builders use the default clusterfuzz gn target.
    if self.bot_config.get('clusterfuzz_archive'):
      self.m.chromium.apply_config('default_target_v8_clusterfuzz')

    # Infer gclient variable that instructs sysroot download.
    if (self.m.chromium.c.TARGET_PLATFORM != 'android' and
        self.m.chromium.c.TARGET_ARCH == 'arm'):
      # This grabs both sysroots to not be dependent on additional bitness
      # setting.
      self.m.gclient.c.target_cpu.add('arm')
      self.m.gclient.c.target_cpu.add('arm64')

    # Apply additional configs for coverage builders.
    if self.bot_config.get('coverage') == 'gcov':
      self.bot_config['disable_auto_bisect'] = True
    elif self.bot_config.get('coverage') == 'sanitizer':
      self.m.gclient.apply_config('llvm_compiler_rt')

    if self.bot_config.get('enable_swarming', True):
      self.m.gclient.c.got_revision_reverse_mapping[
          'got_swarming_client_revision'] = ('v8/tools/swarming_client')

    # FIXME(machenbach): Use a context object that stores the state for each
    # test process. Otherwise it's easy to introduce bugs with multiple test
    # processes and stale context data. E.g. during bisection these values
    # change for tests on rerun.

    # Default failure retry.
    self.rerun_failures_count = 2

    # If tests are run, this value will be set to their total duration.
    self.test_duration_sec = 0

    # Contains list of isolated tests, which can be either a list of tests from
    # one or more steps uploading to isolate server, isolate hashes from the
    # build part of the bisect step or a list of values from the swarm_hashes
    # property (parsed by self.m.isolate.isolated_tests property getter invoked
    # here, which returns a new dict each time, thus no need to copy it here).
    self.isolated_tests = self.m.isolate.isolated_tests

    # This is inferred from the run_mb step or from the parent bot. If mb is
    # run multiple times, it is overwritten. It contains gn arguments.
    self.build_environment = self.m.properties.get(
        'parent_build_environment', {})

  def set_gclient_custom_var(self, var_name):
    """Sets the gclient custom var `var_name` if given.

    This customizes gclient sync, based on conditions on the variable in the
    V8 DEPS file.
    """
    if var_name:
      self.m.gclient.c.solutions[0].custom_vars[var_name] = 'True'

  def set_gclient_custom_deps(self, custom_deps):
    """Configures additional gclient custom_deps to be synced."""
    for name, path in (custom_deps or {}).iteritems():
      self.m.gclient.c.solutions[0].custom_deps[name] = path

  def set_chromium_configs(self, clobber, default_targets):
    if clobber:
      self.m.chromium.c.clobber_before_runhooks = clobber
    if default_targets:
      self.m.chromium.c.compile_py.default_targets = default_targets

  def testing_random_seed(self):
    """Return a random seed suitable for v8 testing.

    If there are isolate hashes, build a random seed based on the hashes.
    Otherwise use the system's PRNG. This uses a deterministic seed for
    recipe simulation.
    """
    r = random.Random()
    if self.isolated_tests:
      r.seed(tuple(self.isolated_tests))
    elif self._test_data.enabled:
      r.seed(12345)

    seed = 0
    while not seed:
      # Avoid 0 because v8 switches off usage of random seeds when
      # passing 0 and creates a new one.
      seed = r.randint(-2147483648, 2147483647)
    return seed

  def checkout(self, revision=None, **kwargs):
    # Set revision for bot_update.
    revision = revision or self.m.buildbucket.gitiles_commit.id or 'HEAD'
    solution = self.m.gclient.c.solutions[0]
    branch = self.m.buildbucket.gitiles_commit.ref
    if RELEASE_BRANCH_RE.match(branch):
      revision = '%s:%s' % (branch, revision)
    solution.revision = revision

    self.checkout_root = self.m.path['builder_cache']
    if self.m.runtime.is_luci:
      self.checkout_root = self.m.path['builder_cache']
    else:
      # TODO(sergiyb): Deprecate this after migrating all builders to LUCI.
      safe_buildername = ''.join(
          c if c.isalnum() else '_' for c in self.m.buildbucket.builder_name)
      self.checkout_root = self.m.path['builder_cache'].join(safe_buildername)

    self.m.file.ensure_directory(
        'ensure builder cache dir', self.checkout_root)
    with self.m.context(cwd=self.checkout_root):
      update_step = self.m.bot_update.ensure_checkout(**kwargs)

    assert update_step.json.output['did_run']

    self.parse_revision_props(
        self.m.bot_update.last_returned_properties['got_revision'],
        self.m.bot_update.last_returned_properties.get('got_revision_cp'))
    return update_step

  def parse_revision_props(self, got_revision, got_revision_cp=None):
    """Parses got_revision and got_revision_cp properties.

    Sets self.revision, self.revision_cp and self.revision_number.

    Normally this is called from self.checkout above, but it may also be useful
    on bots where we do not have a checkout but have these properties (e.g. set
    by the parent builder when triggering child) and need to parse them.

    Args:
      got_revision: Full git hash of the commit.
      got_revision_cp: Value of the Cr-Commit-Position commit footer, e.g.
          "refs/heads/master@{#12345}".
    """
    self.revision = got_revision
    self.revision_cp = got_revision_cp

    # Note, a commit position might not be available on feature branches.
    self.revision_number = None
    if self.revision_cp:
      self.revision_number = str(self.m.commit_position.parse_revision(
          self.revision_cp))

  def calculate_patch_base_gerrit(self):
    """Calculates the commit hash a gerrit patch was branched off."""
    commits, _ = self.m.gitiles.log(
        url=V8_URL,
        ref='master..%s' % self.m.tryserver.gerrit_change_fetch_ref,
        limit=100,
        step_name='Get patches',
        step_test_data=self.test_api.example_patch_range,
    )
    # There'll be at least one commit with the patch. Maybe more for dependent
    # CLs.
    assert len(commits) >= 1
    # We don't support merges.
    assert len(commits[-1]['parents']) == 1
    return commits[-1]['parents'][0]

  def set_up_swarming(self):
    if self.bot_config.get('enable_swarming', True):
      self.m.swarming.check_client_version()

    self.m.swarming.set_default_dimension('pool', 'Chrome')
    self.m.swarming.set_default_dimension('os', 'Ubuntu-14.04')
    # TODO(machenbach): Investigate if this is causing a priority inversion
    # with tasks not specifying cores=8. See http://crbug.com/735388
    # self.m.swarming.set_default_dimension('cores', '8')
    self.m.swarming.add_default_tag('project:v8')
    self.m.swarming.default_hard_timeout = 45 * 60

    self.m.swarming.default_idempotent = True

    if self.m.properties['mastername'] == 'tryserver.v8':
      self.m.swarming.add_default_tag('purpose:pre-commit')
      self.m.swarming.default_priority = 30

      changes = self.m.buildbucket.build.input.gerrit_changes
      assert len(changes) <= 1
      if changes and changes[0].project:
        self.m.swarming.add_default_tag('patch_project:%s' % changes[0].project)
    else:
      if self.m.properties['mastername'] in ['client.v8', 'client.v8.ports']:
        self.m.swarming.default_priority = 25
      else:
        # This should be lower than the CQ.
        self.m.swarming.default_priority = 35
      self.m.swarming.add_default_tag('purpose:post-commit')
      self.m.swarming.add_default_tag('purpose:CI')

  def runhooks(self, **kwargs):
    if (self.m.chromium.c.compile_py.compiler and
        self.m.chromium.c.compile_py.compiler.startswith('goma')):
      # Only ensure goma if we want to use it. Otherwise it might break bots
      # that don't support the goma executables.
      self.m.chromium.ensure_goma()
    env = {}
    self.m.chromium.runhooks(env=env, **kwargs)

  @property
  def bot_type(self):
    if self.bot_config.get('triggers') or self.bot_config.get('triggers_proxy'):
      return 'builder'
    if self.m.properties.get('parent_buildername'):
      return 'tester'
    return 'builder_tester'

  @property
  def builderset(self):
    """Returns a list of names of this builder and all its triggered testers."""
    return (
        [self.m.buildbucket.builder_name] +
        list(self.bot_config.get('triggers', []))
    )

  @property
  def should_build(self):
    return self.bot_type in ['builder', 'builder_tester']

  @property
  def should_test(self):
    return self.bot_type in ['tester', 'builder_tester']

  @property
  def should_upload_build(self):
    return self.bot_config.get('triggers_proxy')

  @property
  def relative_path_to_d8(self):
    return self.m.path.join('out', self.m.chromium.c.build_config_fs, 'd8')

  def extra_tests_from_properties(self):
    """Returns runnable testing.BaseTest objects for each extra test specified
    by parent_test_spec property.
    """
    return [
      testing.create_test(test, self.m)
      for test in v8_builders.TestSpec.from_properties_dict(self.m.properties)
    ]

  def extra_tests_from_test_spec(self, test_spec):
    """Returns runnable testing.BaseTest objects for each extra test specified
    in the test spec of the current builder.
    """
    return [
      testing.create_test(test, self.m)
      for test in test_spec.get_tests(self.m.buildbucket.builder_name)
    ]

  def dedupe_tests(self, high_prec_tests, low_prec_tests):
    """Dedupe tests with lower precedence."""
    high_prec_ids = set([test.id for test in high_prec_tests])
    return high_prec_tests + [
      test for test in low_prec_tests if test.id not in high_prec_ids]

  def read_test_spec(self, root):
    """Reads a test specification file under <root>/infra/testing/builders.pyl.

    Args:
      root: Path to checkout root with configurations.
    Returns: v8_builders.TestSpec object, filtered by interesting builders
      (current builder and all its triggered testers).
    """
    test_spec_file = root.join('infra', 'testing', 'builders.pyl')

    # Fallback for branch builders.
    if not self.m.path.exists(test_spec_file):
      return v8_builders.EmptyTestSpec

    try:
      # Eval python literal file.
      full_test_spec = ast.literal_eval(self.m.file.read_text(
          'read test spec (%s)' % self.m.path.basename(root),
          test_spec_file,
          test_data='{}',
      ))
    except SyntaxError as e:  # pragma: no cover
      raise self.m.step.InfraFailure(
          'Failed to parse test specification "%s": %s' % (test_spec_file, e))

    # Transform into object.
    test_spec = TestSpec.from_python_literal(full_test_spec, self.builderset)

    # Log test spec for debuggability.
    self.m.step.active_result.presentation.logs['test_spec'] = (
        test_spec.log_lines())

    return test_spec

  def isolate_targets_from_tests(self, tests):
    """Returns the isolated targets associated with a list of tests.

    Args:
      tests: A list of test names used as keys in the V8 API's test config.
    """
    if not self.bot_config.get('enable_swarming', True):
      return []
    targets = []
    for test in tests:
      config = self.test_configs.get(test) or {}

      # Tests either define an explicit isolate target or use the test
      # names for convenience.
      if config.get('isolated_target'):
        targets.append(config['isolated_target'])
      elif config.get('tests'):
        targets.extend(config['tests'])
    return targets

  def isolate_tests(self, isolate_targets, out_dir=None):
    """Upload isolated tests to isolate server.

    Args:
      isolate_targets: Targets to isolate.
      out_dir: Name of the build output directory, e.g. 'out-ref'. Defaults to
        'out'. Note that it is not a path, but just the name of the directory.
    """
    output_dir = self.m.chromium.output_dir
    if out_dir:
      output_dir = self.m.path['checkout'].join(
          out_dir, self.m.chromium.c.build_config_fs)

    # Special handling for 'perf' target, since perf tests are going to be
    # executed on an internal swarming server and thus need to be uploaded to
    # internal isolate server.
    if 'perf' in isolate_targets:
      isolate_targets.remove('perf')
      self.m.isolate.isolate_server = 'https://chrome-isolated.appspot.com'
      self.m.isolate.isolate_tests(
          output_dir,
          targets=['perf'],
          verbose=True,
          swarm_hashes_property_name=None,
          step_name='isolate tests (perf)',
      )
      self.isolated_tests.update(self.m.isolate.isolated_tests)
      self.m.isolate.isolate_server = 'https://isolateserver.appspot.com'

    if isolate_targets:
      self.m.isolate.isolate_tests(
          output_dir,
          targets=isolate_targets,
          verbose=True,
          swarm_hashes_property_name=None,
      )
      self.isolated_tests.update(self.m.isolate.isolated_tests)

    if self.isolated_tests:
      self.upload_isolated_json()

  def _update_build_environment(self, gn_args):
    """Sets the build_environment property based on gn arguments."""
    self.build_environment = {}
    # Space-join all gn args, except goma_dir.
    self.build_environment['gn_args'] = ' '.join(
        l for l in gn_args.splitlines()
        if not l.startswith('goma_dir'))

  @property
  def target_bits(self):
    """Returns target bits (as int) inferred from gn arguments from MB."""
    match = TARGET_CPU_RE.match(self.build_environment.get('gn_args', ''))
    if match:
      return 64 if '64' in match.group(1) else 32
    # If target_cpu is not set, gn defaults to 64 bits.
    return 64  # pragma: no cover

  def _upload_build_dependencies(self, deps):
    values = {
      'ext_h_avg_deps': deps['by_extension']['h']['avg_deps'],
      'ext_h_top100_avg_deps': deps['by_extension']['h']['top100_avg_deps'],
      'ext_h_top200_avg_deps': deps['by_extension']['h']['top200_avg_deps'],
      'ext_h_top500_avg_deps': deps['by_extension']['h']['top500_avg_deps'],
    }
    points = []
    root = '/'.join(['v8.infra', 'build_dependencies', ''])
    for k, v in values.iteritems():
      p = self.m.perf_dashboard.get_skeleton_point(
          root + k, self.revision_number, str(v))
      p['units'] = 'count'
      p['supplemental_columns'] = {
        'a_default_rev': 'r_v8_git',
        'r_v8_git': self.revision,
      }
      points.append(p)
    if points:
      self.m.perf_dashboard.add_point(points)

  def _track_binary_size(self, binary, category):
    """Track and upload binary size of configured binaries.

    Args:
      binary: Binary name joined to the build output folder.
      category: ChromePerf category for qualifying the graph names, e.g.
          linux32 or linux64.
    """
    size = self.m.file.filesizes(
        'Check binary size', [self.build_output_dir.join(binary)])[0]

    point_defaults = {
      'units': 'bytes',
      'supplemental_columns': {
        'a_default_rev': 'r_v8_git',
        'r_v8_git': self.revision,
      },
    }

    point = self.m.perf_dashboard.get_skeleton_point(
        '/'.join(['v8.infra', 'binary_size', binary]),
        self.revision_number,
        str(size),
        bot=category,
    )
    point.update(point_defaults)
    self.m.perf_dashboard.add_point([point])

  def compile(
      self, test_spec=v8_builders.EmptyTestSpec, mb_config_path=None,
      out_dir=None, **kwargs):
    """Compile all desired targets and isolate tests.

    Args:
      test_spec: Optional TestSpec object as returned by read_test_spec().
          Expected to contain only specifications for the current builder and
          all triggered builders. All corrensponding extra targets will also be
          isolated.
      mb_config_path: Path to the MB config file. Defaults to
          infra/mb/mb_config.py in the checkout.
      out_dir: Name of the build output directory, e.g. 'out-ref'. Defaults to
        'out'. Note that it is not a path, but just the name of the directory.
    """
    with self.m.osx_sdk('mac'):  # this is no-op on non-Mac hosts
      use_goma = (self.m.chromium.c.compile_py.compiler and
                  'goma' in self.m.chromium.c.compile_py.compiler)

      # Calculate targets to isolate from V8-side test specification. The
      # test_spec contains extra TestStepConfig objects for the current builder
      # and all its triggered builders.
      isolate_targets = self.isolate_targets_from_tests(
          test_spec.get_all_test_names())

      # Add the performance-tests isolate everywhere, where the perf-bot proxy
      # is triggered.
      if self.bot_config.get('triggers_proxy', False):
        isolate_targets = isolate_targets + ['perf']

      # Sort and dedupe.
      isolate_targets = sorted(list(set(isolate_targets)))

      build_dir = None
      if out_dir:  # pragma: no cover
        build_dir = '//%s/%s' % (out_dir, self.m.chromium.c.build_config_fs)
      if self.m.chromium.c.project_generator.tool == 'mb':
        mb_config_rel_path = self.m.properties.get(
            'mb_config_path', 'infra/mb/mb_config.pyl')
        gn_args = self.m.chromium.mb_gen(
            self.m.properties['mastername'],
            self.m.buildbucket.builder_name,
            use_goma=use_goma,
            mb_config_path=(
                mb_config_path or
                self.m.path['checkout'].join(*mb_config_rel_path.split('/'))),
            isolated_targets=isolate_targets,
            build_dir=build_dir,
            gn_args_location=self.m.gn.LOGS)

        # Update the build environment dictionary, which is printed to the
        # user on test failures for easier build reproduction.
        self._update_build_environment(gn_args)

        # Create logs surfacing GN arguments. This information is critical to
        # developers for reproducing failures locally.
        if 'gn_args' in self.build_environment:
          self.m.step.active_result.presentation.logs['gn_args'] = (
              self.build_environment['gn_args'].splitlines())
      elif self.m.chromium.c.project_generator.tool == 'gn':
        self.m.chromium.run_gn(use_goma=use_goma, build_dir=build_dir)

      if use_goma:
        kwargs['use_goma_module'] = True
      self.m.chromium.compile(out_dir=out_dir, **kwargs)

      self.isolate_tests(isolate_targets, out_dir=out_dir)

  @property
  def should_collect_post_compile_metrics(self):
    return (
        self.m.v8.bot_config.get('track_build_dependencies') or
        self.m.v8.bot_config.get('binary_size_tracking'))

  def collect_post_compile_metrics(self):
    with self.m.osx_sdk('mac'):  # this is no-op on non-Mac hosts
      if self.bot_config.get('track_build_dependencies', False):
        with self.m.context(env_prefixes={'PATH': [self.depot_tools_path]}):
          deps = self.m.python(
              name='track build dependencies (fyi)',
              script=self.resource('build-dep-stats.py'),
              args=[
                '-C', self.build_output_dir,
                '-x', '/third_party/',
                '-o', self.m.json.output(),
              ],
              step_test_data=self.test_api.example_build_dependencies,
              ok_ret='any',
              venv=True,
          ).json.output
        if deps:
          self._upload_build_dependencies(deps)

      # Track binary size if specified.
      tracking_config = self.bot_config.get('binary_size_tracking', {})
      if tracking_config:
        self._track_binary_size(
          tracking_config['binary'],
          tracking_config['category'],
        )

  @property
  def depot_tools_path(self):
    """Returns path to depot_tools pinned in the V8 checkout."""
    assert 'checkout' in self.m.path, (
        "Pinned depot_tools is not available before checkout has been created")
    return self.m.path['checkout'].join('third_party', 'depot_tools')

  def _get_default_archive(self):
    return 'gs://chromium-v8/archives/%s/%s' % (
        self.m.properties['mastername'],
        self.m.buildbucket.builder_name,
    )

  def upload_build(self, name_suffix='', archive=None):
    self.m.archive.zip_and_upload_build(
          'package build' + name_suffix,
          self.m.chromium.c.build_config_fs,
          archive or self._get_default_archive(),
          src_dir=self.checkout_root.join('v8'))

  @property
  def isolated_archive_path(self):
    buildername = (self.m.properties.get('parent_buildername') or
                   self.m.buildbucket.builder_name)
    return 'chromium-v8/isolated/%s/%s' % (
        self.m.properties['mastername'], buildername)

  def upload_isolated_json(self):
    self.m.gsutil.upload(
        self.m.json.input(self.isolated_tests),
        self.isolated_archive_path,
        '%s.json' % self.revision,
        args=['-a', 'public-read'],
    )

  def maybe_create_clusterfuzz_archive(self, update_step):
    clusterfuzz_archive = self.bot_config.get('clusterfuzz_archive')
    if clusterfuzz_archive:
      kwargs = {}
      if clusterfuzz_archive.get('bitness'):
        kwargs['use_legacy'] = False
        kwargs['bitness'] = clusterfuzz_archive['bitness']
      self.m.archive.clusterfuzz_archive(
          revision_dir='v8',
          build_dir=self.build_output_dir,
          update_properties=update_step.presentation.properties,
          gs_bucket=clusterfuzz_archive.get('bucket'),
          gs_acl='public-read',
          archive_prefix=clusterfuzz_archive.get('name'),
          **kwargs
      )

  def download_isolated_json(self, revision):
    archive = 'gs://' + self.isolated_archive_path + '/%s.json' % revision
    self.m.gsutil.download_url(
        archive,
        self.m.json.output(),
        name='download isolated json',
        step_test_data=lambda: self.m.json.test_api.output(
            {'bot_default': '[dummy hash for bisection]'}),
    )
    step_result = self.m.step.active_result
    self.isolated_tests = step_result.json.output

  @property
  def build_output_dir(self):
    """Absolute path to the build product based on the 'checkout' path."""
    return self.m.chromium.c.build_dir.join(self.m.chromium.c.build_config_fs)

  @property
  def generate_gcov_coverage(self):
    return self.bot_config.get('coverage') == 'gcov'

  def init_gcov_coverage(self):
    """Delete all gcov counter files."""
    self.m.docker.login()
    self.m.docker.run(
        LCOV_IMAGE,
        'lcov zero counters',
        ['lcov', '--directory', self.build_output_dir, '--zerocounters'],
        dir_mapping=[(self.build_output_dir, self.build_output_dir)],
    )

  def upload_gcov_coverage_report(self):
    """Capture coverage data and upload a report."""
    coverage_dir = self.m.path.mkdtemp('gcov_coverage')
    report_dir = self.m.path.mkdtemp('gcov_coverage_html')
    output_file = self.m.path.join(coverage_dir, 'app.info')

    dir_mapping = [
        # We need to map entire checkout, since some of the files generated by
        # lcov inside the build output dir contain relative paths to files in
        # the checkout and without this map, genhtml step below will fail to
        # find them.
        (self.m.path['checkout'], self.m.path['checkout']),
        (coverage_dir, coverage_dir),
        (report_dir, report_dir),
    ]

    # Capture data from gcda and gcno files.
    self.m.docker.run(
        LCOV_IMAGE,
        'lcov capture',
        [
          'lcov',
          '--directory', self.build_output_dir,
          '--capture',
          '--output-file', output_file,
        ],
        dir_mapping,
    )

    # Remove unwanted data.
    self.m.docker.run(
        LCOV_IMAGE,
        'lcov remove',
        [
          'lcov',
          '--directory', self.build_output_dir,
          '--remove', output_file,
          'third_party/*',
          'testing/gtest/*',
          'testing/gmock/*',
          '/usr/include/*',
          '--output-file', output_file,
        ],
        dir_mapping,
    )

    # Generate html report into a temp folder.
    self.m.docker.run(
        LCOV_IMAGE,
        'genhtml',
        [
          'genhtml',
          '--output-directory', report_dir,
          output_file,
        ],
        dir_mapping,
    )

    # Upload report to google storage.
    dest = '%s%d_gcov_rel/%s' % (
        self.m.platform.name, self.target_bits, self.revision)
    result = self.m.gsutil(
        [
          '-m', 'cp', '-a', 'public-read', '-R', report_dir,
          'gs://chromium-v8/%s' % dest,
        ],
        'coverage report',
    )
    result.presentation.links['report'] = (
      'https://storage.googleapis.com/chromium-v8/%s/index.html' % dest)

  @property
  def generate_sanitizer_coverage(self):
    return self.bot_config.get('coverage') == 'sanitizer'

  def create_coverage_context(self):
    if self.generate_sanitizer_coverage:
      return testing.SanitizerCoverageContext(self.m)
    else:
      return testing.NULL_COVERAGE

  def create_test(self, test):
    """Wrapper that allows to shortcut common tests with their names.

    Returns: A runnable test instance.
    """
    return testing.create_test(test, self.m)

  def create_tests(self):
    return [self.create_test(t) for t in self.bot_config.get('tests', [])]

  @property
  def is_pure_swarming_tester(self):
    return (self.bot_type == 'tester' and
            self.bot_config.get('enable_swarming', True))

  @contextlib.contextmanager
  def maybe_nest(self, condition, parent_step_name):
    if not condition:
      yield
    else:
      with self.m.step.nest(parent_step_name):
        yield

  def runtests(self, tests):
    if self.extra_flags:
      result = self.m.step('Customized run with extra flags', cmd=None)
      result.presentation.step_text += ' '.join(self.extra_flags)
      assert all(re.match(r'[\w\-]*', x) for x in self.extra_flags), (
          'no special characters allowed in extra flags')

    start_time_sec = self.m.time.time()
    test_results = testing.TestResults.empty()

    # Apply test filter.
    # TODO(machenbach): Track also the number of tests that ran and throw an
    # error if the overall number of tests from all steps was zero.
    tests = [t for t in tests if t.apply_filter()]

    swarming_tests = [t for t in tests if t.uses_swarming]
    non_swarming_tests = [t for t in tests if not t.uses_swarming]
    failed_tests = []

    # Creates a coverage context if coverage is tracked. Null object otherwise.
    coverage_context = self.create_coverage_context()

    with self.maybe_nest(swarming_tests, 'trigger tests'):
      # Make sure swarming triggers come first.
      # TODO(machenbach): Port this for rerun for bisection.
      for t in swarming_tests + non_swarming_tests:
        try:
          t.pre_run(coverage_context=coverage_context)
        except self.m.step.InfraFailure:  # pragma: no cover
          raise
        except self.m.step.StepFailure:  # pragma: no cover
          failed_tests.append(t)

    # Setup initial zero coverage after all swarming jobs are triggered.
    coverage_context.setup()

    # Make sure non-swarming tests are run before swarming results are
    # collected.
    for t in non_swarming_tests + swarming_tests:
      try:
        test_results += t.run(coverage_context=coverage_context)
      except self.m.step.InfraFailure:  # pragma: no cover
        raise
      except self.m.step.StepFailure:  # pragma: no cover
        failed_tests.append(t)

    # Upload accumulated coverage data.
    coverage_context.maybe_upload()

    if failed_tests:
      failed_tests_names = [t.name for t in failed_tests]
      raise self.m.step.StepFailure(
          '%d tests failed: %r' % (len(failed_tests), failed_tests_names))
    self.test_duration_sec = self.m.time.time() - start_time_sec
    return test_results

  def maybe_bisect(self, test_results):
    """Build-local bisection for one failure."""
    # Don't activate for branch or fyi bots.
    if self.m.properties['mastername'] not in ['client.v8', 'client.v8.ports']:
      return

    if self.bot_config.get('disable_auto_bisect'):  # pragma: no cover
      return

    # Only bisect over failures not flakes. Rerun only the fastest test.
    try:
      failure = min(test_results.failures, key=lambda r: r.duration)
    except ValueError:
      return

    # Only bisect if the fastest failure is significantly faster than the
    # ongoing build's total.
    duration_factor = self.m.properties.get(
        'bisect_duration_factor', BISECT_DURATION_FACTOR)
    if (failure.duration * duration_factor > self.test_duration_sec):
      step_result = self.m.step(
          'Bisection disabled - test too slow', cmd=None)
      return

    # Don't retry failures during bisection.
    self.rerun_failures_count = 0

    # Suppress using shards to be able to rerun single tests.
    self.c.testing.may_shard = False

    # Only rebuild the target of the test to retry.
    targets = [failure.failure_dict.get('target_name', 'All')]

    test = self.create_test(failure.test_step_config)
    def test_func(_):
      return test.rerun(failure_dict=failure.failure_dict)

    def is_bad(revision):
      with self.m.step.nest('Bisect ' + revision[:8]):
        if not self.is_pure_swarming_tester:
          self.checkout(revision, update_presentation=False)
        if self.bot_type == 'builder_tester':
          self.runhooks()
          self.compile(targets=targets)
        elif self.bot_type == 'tester':
          if test.uses_swarming:
            self.download_isolated_json(revision)
          else:  # pragma: no cover
            raise self.m.step.InfraFailure('Swarming required for bisect.')
        else:  # pragma: no cover
          raise self.m.step.InfraFailure(
              'Bot type %s not supported.' % self.bot_type)
        result = test_func(revision)
        if result.infra_failures:  # pragma: no cover
          raise self.m.step.InfraFailure(
              'Cannot continue bisection due to infra failures.')
        return result.failures

    with self.m.step.nest('Bisect'):
      # Setup bisection range ("from" exclusive).
      latest_previous, bisect_range = self.get_change_range()
      if len(bisect_range) <= 1:
        self.m.step('disabled - less than two changes', cmd=None)
        return

      if self.bot_type == 'tester':
        # Filter the bisect range to the revisions for which isolate hashes or
        # archived builds are available, depending on whether swarming is used
        # or not.
        available_bisect_range = self.get_available_range(bisect_range)
      else:
        available_bisect_range = bisect_range

    if is_bad(latest_previous):
      # If latest_previous is already "bad", the test failed before the current
      # build's change range, i.e. it is a recurring failure.
      # TODO: Try to be smarter here, fetch the build data from the previous
      # one or two builds and check if the failure happened in revision
      # latest_previous. Otherwise, the cost of calling is_bad is as much as
      # one bisect step.
      step_result = self.m.step(
          'Bisection disabled - recurring failure', cmd=None)
      step_result.presentation.status = self.m.step.WARNING
      return

    # Log available revisions to ease debugging.
    self.log_available_range(available_bisect_range)

    culprit = bisection.keyed_bisect(available_bisect_range, is_bad)
    culprit_range = self.calc_missing_values_in_sequence(
        bisect_range,
        available_bisect_range,
        culprit,
    )
    self.report_culprits(culprit_range)

  @staticmethod
  def format_duration(duration_in_seconds):
    duration = datetime.timedelta(seconds=duration_in_seconds)
    time = (datetime.datetime.min + duration).time()
    return time.strftime('%M:%S:') + '%03i' % int(time.microsecond / 1000)

  def _duration_results_text(self, test):
    return [
      'Test: %s' % test['name'],
      'Flags: %s' % ' '.join(test['flags']),
      'Command: %s' % test['command'],
      'Duration: %s' % V8Api.format_duration(test['duration']),
    ]

  def _update_durations(self, output, presentation):
    # Slowest tests duration summary.
    lines = []
    for test in output['slowest_tests']:
      suffix = ''
      if test.get('marked_slow') is False:
        suffix = ' *'
      lines.append(
          '%s %s%s' % (V8Api.format_duration(test['duration']),
                       test['name'], suffix))

    # Slowest tests duration details.
    lines.extend(['', 'Details:', ''])
    for test in output['slowest_tests']:
      lines.extend(self._duration_results_text(test))
    presentation.logs['durations'] = lines

  def _get_failure_logs(self, output, failure_factory):
    if not output['results']:
      return {}, [], {}, []

    unique_results = defaultdict(list)
    for result in output['results']:
      # Use test base name as UI label (without suite and directory names).
      label = result['name'].split('/')[-1]
      # Truncate the label if it is still too long.
      if len(label) > MAX_LABEL_SIZE:
        label = label[:MAX_LABEL_SIZE - 2] + '..'
      # Group tests with the same label (usually the same test that ran under
      # different configurations).
      unique_results[label].append(result)

    failure_log = {}
    flake_log = {}
    failures = []
    flakes = []
    for label in sorted(unique_results.keys()[:MAX_FAILURE_LOGS]):
      failure_lines = []
      flake_lines = []

      # Group results by command. The same command might have run multiple
      # times to detect flakes.
      results_per_command = defaultdict(list)
      for result in unique_results[label]:
        results_per_command[result['command']].append(result)

      for results in results_per_command.values():
        # Determine flakiness.
        failure = failure_factory(results)
        if failure.is_flaky:
          # This is a flake.
          flakes.append(failure)
          flake_lines += failure.log_lines()
        else:
          # This is a failure.
          failures.append(failure)
          failure_lines += failure.log_lines()

      if failure_lines:
        failure_log[label] = failure_lines
      if flake_lines:
        flake_log[label] = flake_lines

    return failure_log, failures, flake_log, flakes

  def _update_failure_presentation(self, log, failures, presentation):
    for label in sorted(log):
      presentation.logs[label] = log[label]

    if failures:
      # Number of failures.
      presentation.step_text += ('failures: %d<br/>' % len(failures))

  @property
  def extra_flags(self):
    extra_flags = self.m.properties.get('extra_flags', '')
    if isinstance(extra_flags, basestring):
      extra_flags = extra_flags.split()
    assert isinstance(extra_flags, list) or isinstance(extra_flags, tuple)
    return list(extra_flags)

  def _with_extra_flags(self, args):
    """Returns: the arguments with additional extra flags inserted.

    Extends a possibly existing extra flags option.
    """
    if not self.extra_flags:
      return args

    options, args = TEST_RUNNER_PARSER.parse_known_args(args)

    if options.extra_flags:
      new_flags = [options.extra_flags] + self.extra_flags
    else:
      new_flags = self.extra_flags

    args.extend(['--extra-flags', ' '.join(new_flags)])
    return args

  @property
  def test_filter(self):
    return [f for f in self.m.properties.get('testfilter', [])
            if f != 'defaulttests']

  def _applied_test_filter(self, test):
    """Returns: the list of test filters that match a test configuration."""
    # V8 test filters always include the full suite name, followed
    # by more specific paths and possibly ending with a glob, e.g.:
    # 'mjsunit/regression/prefix*'.
    return [f for f in self.test_filter
              for t in test.get('suite_mapping', test['tests'])
              if f.startswith(t)]

  def _setup_test_runner(self, test, applied_test_filter, test_step_config):
    env = {}
    full_args = [
      '--progress=verbose',
      '--mode', self.m.chromium.c.build_config_fs,
      '--outdir', self.m.path.split(self.m.chromium.c.build_dir)[-1],
      '--buildbot',
      '--timeout=200',
    ]

    # Add optional non-standard root directory for test suites.
    if test.get('test_root'):
      full_args += ['--test-root', test['test_root']]

    # On reruns, there's a fixed random seed set in the test configuration.
    if ('--random-seed' not in test.get('test_args', []) and
        test.get('use_random_seed', True)):
      full_args.append('--random-seed=%d' % self.testing_random_seed())

    # Either run tests as specified by the filter (trybots only) or as
    # specified by the test configuration.
    if applied_test_filter:
      full_args += applied_test_filter
    else:
      full_args += list(test.get('tests', []))

    # Add test-specific test arguments.
    full_args += test.get('test_args', [])

    # Add builder-specific test arguments.
    full_args += self.c.testing.test_args

    # Add builder-, test- and step-specific variants.
    full_args += testing.test_args_from_variants(
        self.bot_config.get('variants'),
        test.get('variants'),
        test_step_config.variants,
    )

    # Add step-specific test arguments.
    full_args += test_step_config.test_args

    full_args = self._with_extra_flags(full_args)

    full_args += [
      '--rerun-failures-count=%d' % self.rerun_failures_count,
    ]

    # TODO(machenbach): This is temporary code for rolling out the new test
    # runner. It should be removed after the roll-out. We skip the branches
    # waterfall, as it runs older versions of the V8 side.
    if self.m.properties['mastername'] != 'client.v8.branches':
      full_args += [
        '--mastername', self.m.properties['mastername'],
        '--buildername', self.m.buildbucket.builder_name,
      ]

    return full_args, env

  @staticmethod
  def _copy_property(src, dest, key):
    if key in src:
      dest[key] = src[key]

  def maybe_trigger(self, test_spec=v8_builders.EmptyTestSpec,
                    **additional_properties):
    triggers = self.bot_config.get('triggers', [])
    triggers_proxy = self.bot_config.get('triggers_proxy', False)
    if not triggers and not triggers_proxy:
      return

    # Careful! Before adding new properties, note the following:
    # Triggered bots on CQ will either need new properties to be explicitly
    # whitelisted or their name should be prefixed with 'parent_'.
    properties = {
      'parent_got_revision': self.revision,
      'parent_buildername': self.m.buildbucket.builder_name,
      'parent_build_config': self.m.chromium.c.BUILD_CONFIG,
    }
    if self.revision_cp:
      properties['parent_got_revision_cp'] = self.revision_cp
    if self.m.tryserver.is_tryserver:
      properties.update(
        category=self.m.properties.get('category', 'manual_ts'),
        reason=str(self.m.properties.get('reason', 'ManualTS')),
        # On tryservers, set revision to the same as on the current bot,
        # as CQ expects builders and testers to match the revision field.
        revision=self.m.buildbucket.gitiles_commit.id or 'HEAD',
        patch_gerrit_url='https://%s' % self.m.tryserver.gerrit_change.host,
        patch_issue=self.m.tryserver.gerrit_change.change,
        patch_project=self.m.tryserver.gerrit_change.project,
        patch_set=self.m.tryserver.gerrit_change.patchset,
        patch_storage='gerrit',
      )
      # TODO(sergiyb): Remove this for-loop after CQ stops using these
      # properties to detect triggered builders.
      for p in ['patch_ref', 'patch_repository_url']:
        try:
          properties[p] = str(self.m.properties[p])
        except KeyError:  # pragma: no cover
          pass
    else:
      # On non-tryservers, we can set the revision to whatever the
      # triggering builder checked out.
      properties['revision'] = self.revision

    if self.m.properties.get('testfilter'):
      properties.update(testfilter=list(self.m.properties['testfilter']))
    self._copy_property(self.m.properties, properties, 'extra_flags')

    # TODO(machenbach): Also set meaningful buildbucket tags of triggering
    # parent.

    # Pass build environment to testers if it doesn't exceed buildbot's
    # limits.
    # TODO(machenbach): Remove the check in the after-buildbot age.
    if len(self.m.json.dumps(self.build_environment)) < 1024:
      properties['parent_build_environment'] = self.build_environment

    swarm_hashes = self.isolated_tests
    if swarm_hashes:
      properties['swarm_hashes'] = swarm_hashes
    properties.update(**additional_properties)

    triggered_build_ids = []
    if triggers:
      if self.m.tryserver.is_tryserver:
        trigger_props = {}
        self._copy_property(self.m.properties, trigger_props, 'git_revision')
        self._copy_property(self.m.properties, trigger_props, 'revision')
        trigger_props.update(properties)
        bucket_name = (
            self.m.buildbucket.bucket_v1 or
            'master.%s' % self.m.properties['mastername'])
        # Generate a list of fake changes from the blamelist property to have
        # correct blamelist displayed on the child build. Unfortunately, this
        # only copies author names, but additional details about the list of
        # changes associated with the build are currently not accessible from
        # the recipe code.
        step_result = self.buildbucket_trigger(
            bucket_name, self.get_changes(),
            [{
              'builder_name': builder_name,
              'properties': dict(
                  trigger_props,
                  **test_spec.as_properties_dict(builder_name)
              ),
            } for builder_name in triggers],
            # Tryserver uses custom buildset that is set by the buildbucket
            # module itself.
            add_buildset_tag=False,
        )
        triggered_build_ids.extend(
            build['build']['id'] for build in step_result.stdout['results'])
      else:
        ci_properties = dict(properties)
        if self.should_upload_build:
          ci_properties['archive'] = self._get_default_archive()
        if self.m.runtime.is_luci:
          self.m.scheduler.emit_triggers(
              [(
                self.m.scheduler.BuildbucketTrigger(
                  properties=dict(
                    ci_properties,
                    **test_spec.as_properties_dict(builder_name)
                  ),
                  tags={
                    'buildset': 'commit/gitiles/chromium.googlesource.com/v8/'
                                'v8/+/%s' % ci_properties['revision']
                  }
                ), 'v8', [builder_name],
              ) for builder_name in triggers],
              step_name='trigger'
          )
        else:
          self.m.trigger(*[{
            'builder_name': builder_name,
            # Attach additional builder-specific test-spec properties.
            'properties': dict(
                ci_properties,
                **test_spec.as_properties_dict(builder_name)
            ),
          } for builder_name in triggers])

    if triggers_proxy:
      proxy_properties = {'archive': self._get_default_archive()}
      proxy_properties.update(properties)
      self.buildbucket_trigger(
          'luci.v8-internal.ci', self.get_changes(),
          [{
            'properties': proxy_properties,
            'builder_name': 'v8_trigger_proxy'
          }],
          step_name='trigger_internal'
      )

    if triggered_build_ids:
      output_properties = self.m.step.active_result.presentation.properties
      output_properties['triggered_build_ids'] = triggered_build_ids

  def get_changes(self):
    # TODO(sergiyb): Remove this after migrating all builders to LUCI as
    # there the revision from the buildset will be used instead.
    blamelist = self.m.properties.get('blamelist', ['fake-author'])
    return [{'author': email} for email in blamelist]

  def buildbucket_trigger(self, bucket, changes, requests, step_name='trigger',
                          service_account='v8-bot', add_buildset_tag=True):
    """Triggers builds via buildbucket.

    Args:
      bucket: Name of the bucket to add builds to.
      changes: List of changes to be associated with the scheduled build. Each
          entry is a dictionary like this: {'author': ..., 'revision': ...}. The
          revision is optional and will be extracted from build propeties if not
          provided. The author is an arbitrary string or an email address.
      requests: List of requests, where each request is a dictionary like this:
          {'builder_name': ..., 'properties': {'revision': ..., ...}}. Note that
          builder_name and revision are mandatory, whereas additional properties
          are optional.
      step_name: Name of the triggering step that appear on the build.
      service_account: Puppet service account to be used for authentication to
          buildbucket.
      add_buildset_tag: Adds a buildset tag based on revision property.
    """
    # TODO(sergiyb): Remove this line after migrating all builders to swarming.
    # There an implicit task account (specified in the cr-buildbucket.cfg) will
    # be used instead.
    if not self.m.runtime.is_luci:
      self.m.buildbucket.use_service_account_key(
          self.m.puppet_service_account.get_key_path(service_account))

    requests = [{
      'bucket': bucket,
      'tags': request.get('tags', {}),
      'parameters': {
        'builder_name': request['builder_name'],
        'properties': request['properties'],
        # This is required by Buildbot to correctly set 'revision' and
        # 'repository' properties, which are used by Milo and the recipe.
        # TODO(sergiyb): Remove this after migrating to LUCI/Swarming.
        'changes': [{
          'author': {'email': change['author']},
          'revision': change.get(
            'revision', request['properties']['revision']),
          'repo_url': 'https://chromium.googlesource.com/v8/v8'
        } for change in changes],
      },
    } for request in requests]

    if add_buildset_tag:
      for request in requests:
        request['tags']['buildset'] = (
            'commit/gitiles/chromium.googlesource.com/v8/v8/+/%s' %
            request['parameters']['properties']['revision'])

    step_result = self.m.buildbucket.put(
        requests,
        name=step_name,
        step_test_data=lambda: (
          self.m.v8.test_api.buildbucket_test_data(len(requests))),
    )

    if 'error' in step_result.stdout:
      step_result.presentation.status = self.m.step.FAILURE

    return step_result

  def get_change_range(self):
    if self.m.properties.get('override_changes'):
      # This can be used for manual testing or on a staging builder that
      # simulates a change range.
      changes = self.m.properties['override_changes']
      step_result = self.m.step('Override changes', cmd=None)
      step_result.presentation.logs['changes'] = self.m.json.dumps(
        changes, indent=2).splitlines()
    else:
      # TODO(sergiyb): Migrate from Milo API to buildbucket v2.
      data_json = self.m.step(
          'Fetch changes',
          [
            'prpc', 'call', '-format=json', MILO_HOST,
            'milo.Buildbot.GetBuildbotBuildJSON'
          ],
          stdin=self.m.json.input({
            'master': self.m.properties['mastername'],
            'builder': self.m.buildbucket.builder_name,
            'buildNum': self.m.buildbucket.build.number,
          }),
          stdout=self.m.json.output(),
          infra_step=True,
          step_test_data=lambda: self.m.json.test_api.output_stream({
            'data': base64.b64encode(
              self.m.json.dumps(self.test_api.example_buildbot_changes())),
          }),
      ).stdout
      change_json = self.m.json.loads(base64.b64decode(data_json['data']))
      changes = change_json['sourceStamp']['changes']

    assert changes
    changes = sorted(changes, key=lambda c: c['when'])
    oldest_change = changes[0]['revision']
    newest_change = changes[-1]['revision']

    # Commits is a list of gitiles commit dicts in reverse chronological order.
    commits, _ = self.m.gitiles.log(
        url=V8_URL,
        ref='%s~2..%s' % (oldest_change, newest_change),
        limit=100,
        step_name='Get change range',
        step_test_data=self.test_api.example_bisection_range
    )

    # We get minimum two commits when the first and last commit are equal (i.e.
    # there was only one commit C). Commits will contain the latest previous
    # commit and C.
    assert len(commits) > 1

    return (
        # Latest previous.
        commits[-1]['commit'],
        # List of commits oldest -> newest, without the latest previous.
        [commit['commit'] for commit in reversed(commits[:-1])],
    )

  def get_available_range(self, bisect_range):
    assert self.bot_type == 'tester'
    archive_url_pattern = 'gs://' + self.isolated_archive_path + '/%s.json'
    # TODO(machenbach): Maybe parallelize this in a wrapper script.
    args = ['ls']
    available_range = []
    # Check all builds except the last as we already know it is "bad".
    for r in bisect_range[:-1]:
      step_result = self.m.gsutil(
          args + [archive_url_pattern % r],
          name='check build %s' % r[:8],
          # Allow failures, as the tool will formally fail for any absent file.
          ok_ret='any',
          stdout=self.m.raw_io.output_text(),
          step_test_data=lambda: self.test_api.example_available_builds(r),
      )
      if r in step_result.stdout.strip():
        available_range.append(r)

    # Always keep the latest revision in the range. The latest build is
    # assumed to be "bad" and won't be tested again.
    available_range.append(bisect_range[-1])
    return available_range

  def calc_missing_values_in_sequence(
        self, sequence, subsequence, value):
    """Calculate a list of missing values from a subsequence.

    Args:
      sequence: The complete sequence including all values.
      subsequence: A subsequence from the sequence above.
      value: An element from subsequence.
    Returns: A subsequence from sequence [a..b], where b is the value and
             for all x in a..b-1 holds x not in subsequence. Also
             a-1 is either in subsequence or value was the first
             element in subsequence.
    """
    from_index = 0
    to_index = sequence.index(value) + 1
    index_on_subsequence = subsequence.index(value)
    if index_on_subsequence > 0:
      # Value is not the first element in subsequence.
      previous = subsequence[index_on_subsequence - 1]
      from_index = sequence.index(previous) + 1
    return sequence[from_index:to_index]

  def log_available_range(self, available_bisect_range):
    step_result = self.m.step('Available range', cmd=None)
    for revision in available_bisect_range:
      step_result.presentation.links[revision[:8]] = COMMIT_TEMPLATE % revision

  def report_culprits(self, culprit_range):
    assert culprit_range
    if len(culprit_range) > 1:
      text = 'Suspecting multiple commits'
    else:
      text = 'Suspecting %s' % culprit_range[0][:8]

    step_result = self.m.step(text, cmd=None)
    for culprit in culprit_range:
      step_result.presentation.links[culprit[:8]] = COMMIT_TEMPLATE % culprit

  def read_version_file(self, ref, step_name_desc):
    """Read and return the version-file content at a paricular ref."""
    with self.m.context(cwd=self.m.path['checkout']):
      return self.m.git(
          'show', '%s:%s' % (ref, self.VERSION_FILE),
          name='Check %s version file' % step_name_desc,
          stdout=self.m.raw_io.output_text(),
      ).stdout

  def read_version_from_ref(self, ref, step_name_desc):
    """Read and return the version at a paricular ref."""
    return V8Api.version_from_file(self.read_version_file(ref, step_name_desc))

  @staticmethod
  def version_from_file(blob):
    major = re.search(VERSION_LINE_RE % V8_MAJOR, blob, re.M).group(1)
    minor = re.search(VERSION_LINE_RE % V8_MINOR, blob, re.M).group(1)
    build = re.search(VERSION_LINE_RE % V8_BUILD, blob, re.M).group(1)
    patch = re.search(VERSION_LINE_RE % V8_PATCH, blob, re.M).group(1)
    return V8Version(major, minor, build, patch)
