# Copyright (c) 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.


"""Utility class to build the Skia master BuildFactory's.

Based on gclient_factory.py and adds Skia-specific steps."""


from buildbot.process.properties import WithProperties
from buildbot.status import builder
from config_private import AUTOGEN_SVN_BASEURL, SKIA_GIT_URL
from master.factory import gclient_factory
from master.factory.build_factory import BuildFactory
from skia_master_scripts import commands as skia_commands

import builder_name_schema
import config
import config_private
import ntpath
import os
import posixpath
import skia_vars
import utils


# TODO(epoger): My intent is to make the build steps identical on all platforms
# and thus remove the need for the whole target_platform parameter.
# For now, these must match the target_platform values used in
# third_party/chromium_buildbot/scripts/master/factory/gclient_factory.py ,
# because we pass these values into GClientFactory.__init__() .
TARGET_PLATFORM_LINUX = 'linux'
TARGET_PLATFORM_MAC = 'mac'
TARGET_PLATFORM_WIN32 = 'win32'

CONFIG_DEBUG = 'Debug'
CONFIG_RELEASE = 'Release'
CONFIGURATIONS = [CONFIG_DEBUG, CONFIG_RELEASE]


_RUNGYP_STEP_DESCRIPTION = 'RunGYP'
_COMPILE_STEP_PREFIX = 'Build'
_COMPILE_RETRY_PREFIX = 'Retry_' + _COMPILE_STEP_PREFIX
_COMPILE_NO_WERR_PREFIX = 'Retry_NoWarningsAsErrors_' + _COMPILE_STEP_PREFIX


class SkiaFactory(BuildFactory):
  """Encapsulates data and methods common to the Skia master.cfg files."""

  def __init__(self, other_repos=None, do_upload_render_results=False,
               do_upload_bench_results=False, do_patch_step=False,
               build_subdir='skia', target_platform=None,
               configuration=CONFIG_DEBUG, default_timeout=8*60*60,
               deps_target_os=None, environment_variables=None,
               perf_output_basedir=None, builder_name=None, flavor=None,
               make_flags=None, test_args=None, gm_args=None, bench_args=None,
               bench_pictures_cfg='default', compile_warnings_as_errors=False,
               gyp_defines=None, build_targets=None):
    """Instantiates a SkiaFactory as appropriate for this target_platform.
    do_upload_render_results: whether we should upload render results
    do_upload_bench_results: whether we should upload bench results
    do_patch_step: whether the build should include a step which applies a
        patch.  This is only applicable for trybots.
    build_subdir: subdirectory to check out and then build within
    other_repos: list of other repositories to also check out (or None). Each
        repo is specified as a tuple: (name, url), where "name" is the target
        directory and "url" is the source code url.
    target_platform: a string such as TARGET_PLATFORM_LINUX
    configuration: 'Debug' or 'Release'
    default_timeout: default timeout for each command, in seconds
    deps_target_os: string; the target_os to be specified in the gclient config.
    environment_variables: dictionary of environment variables that should
        be passed to all commands
    perf_output_basedir: path to directory under which to store performance
        data, or None if we don't want to store performance data
    builder_name: name of the builder associated with this factory
    flavor: which "flavor" of slave-side scripts this factory should use
    make_flags: list of extra flags to pass to the compile step
    test_args: list of extra flags to pass to the 'tests' executable
    gm_args: list of extra flags to pass to the 'gm' executable
    bench_args: list of extra flags to pass to the 'bench' executable
    bench_pictures_cfg: config name to use for bench_pictures
    compile_warnings_as_errors: boolean; whether to build with "-Werror" or
        some equivalent.
    gyp_defines: optional dict; GYP_DEFINES to be used in the build.
    build_targets: optional list; the targets to build. Default is set depending
        on which Build() function is called.
    """
    properties = {}

    self.skipsteps = utils.GetListFromEnvVar(
        config_private.SKIPSTEPS_ENVIRONMENT_VARIABLE)
    self.dontskipsteps = utils.GetListFromEnvVar(
        config_private.DONTSKIPSTEPS_ENVIRONMENT_VARIABLE)

    if not make_flags:
      make_flags = []
    self._make_flags = make_flags
    # Platform-specific stuff.
    if target_platform == TARGET_PLATFORM_WIN32:
      self.TargetPath = ntpath
    else:
      self.TargetPath = posixpath

    # Create gclient solutions corresponding to the main build_subdir
    # and other directories we also wish to check out.
    self._gclient_solutions = [gclient_factory.GClientSolution(
        svn_url=SKIA_GIT_URL, name=build_subdir
        ).GetSpec()]

    if not other_repos:
      other_repos = []
    repos_to_checkout = set(other_repos)

    for other_repo in repos_to_checkout:
      self._gclient_solutions.append(gclient_factory.GClientSolution(
          svn_url=other_repo[1], name=other_repo[0]).GetSpec())

    self._deps_target_os = deps_target_os

    # Set _default_clobber based on config.Master
    self._default_clobber = getattr(config.Master, 'default_clobber', False)

    self._do_upload_render_results = do_upload_render_results
    self._do_upload_bench_results = (do_upload_bench_results and
                                     perf_output_basedir != None)
    self._do_patch_step = do_patch_step

    if not environment_variables:
      self._env_vars = {}
    else:
      self._env_vars = dict(environment_variables)

    self._gyp_defines = dict(gyp_defines or {})
    self._gyp_defines['skia_warnings_as_errors'] = \
        '%d' % int(compile_warnings_as_errors)

    self._build_targets = list(build_targets or [])

    # Get an implementation of SkiaCommands as appropriate for
    # this target_platform.
    self._workdir = self.TargetPath.join('build', build_subdir)
    self._skia_cmd_obj = skia_commands.SkiaCommands(
        target_platform=target_platform, factory=self,
        configuration=configuration, workdir=self._workdir,
        target_arch=None, default_timeout=default_timeout,
        environment_variables=self._env_vars)

    self._perf_output_basedir = perf_output_basedir

    self._configuration = configuration
    if self._configuration not in CONFIGURATIONS:
      raise ValueError('Invalid configuration %s.  Must be one of: %s' % (
          self._configuration, CONFIGURATIONS))

    self._skia_svn_username_file = '.skia_svn_username'
    self._skia_svn_password_file = '.skia_svn_password'
    self._autogen_svn_username_file = '.autogen_svn_username'
    self._autogen_svn_password_file = '.autogen_svn_password'
    self._builder_name = builder_name
    self._flavor = flavor

    def _DetermineRevision(build):
      """ Get the 'revision' property at build time. WithProperties returns the
      empty string if 'revision' is not defined, which causes failures when we
      try to pass the revision over a command line, so we use the string "None"
      to indicate that the revision is not defined.

      build: instance of Build for the current build.
      """
      props = build.getProperties().asDict()
      if props.has_key('revision'):
        if props['revision'][0]:
          return props['revision'][0]
      return 'None'

    if not test_args:
      test_args = []
    if not gm_args:
      gm_args = []
    if not bench_args:
      bench_args = []

    self._common_args = [
        '--autogen_svn_baseurl', AUTOGEN_SVN_BASEURL,
        '--configuration', configuration,
        '--deps_target_os', self._deps_target_os or 'None',
        '--builder_name', builder_name,
        '--build_number', WithProperties('%(buildnumber)s'),
        '--target_platform', target_platform,
        '--revision', WithProperties('%(rev)s', rev=_DetermineRevision),
        '--got_revision', WithProperties('%(got_revision:-None)s'),
        '--perf_output_basedir', perf_output_basedir or 'None',
        '--make_flags', '"%s"' % ' '.join(self._make_flags),
        '--test_args', '"%s"' % ' '.join(test_args),
        '--gm_args', '"%s"' % ' '.join(gm_args),
        '--bench_args', '"%s"' % ' '.join(bench_args),
        '--num_cores', WithProperties('%(num_cores:-None)s'),
        '--is_try', str(self._do_patch_step),
        '--bench_pictures_cfg', bench_pictures_cfg,
        ]
    BuildFactory.__init__(self, build_factory_properties=properties)

  def Validate(self):
    """ Validate the Factory against the known good configuration. """
    test_dir = os.path.join(os.path.dirname(__file__), os.pardir, os.pardir,
                            'tools', 'tests', 'factory_configuration')

    # Write the actual configuration.
    actual_dir = os.path.join(test_dir, 'actual')
    if not os.path.exists(actual_dir):
      os.makedirs(actual_dir)
    self_as_string = utils.ToString(self.__dict__)
    with open(os.path.join(actual_dir, self._builder_name), 'w') as f:
      f.write(self_as_string)

    # Read the expected configuration.
    expected_dir = os.path.join(test_dir, 'expected')
    try:
      expectation = open(os.path.join(expected_dir, self._builder_name)).read()
    except IOError:
      msg = 'No expected factory configuration for %s in %s.' % (
          self._builder_name, expected_dir)
      if config_private.die_on_validation_failure:
        raise Exception(msg)
      else:
        print 'Warning: %s' % msg
        return

    # Compare actual to expected.
    if self_as_string != expectation:
      if config_private.die_on_validation_failure:
        raise ValueError('Factory configuration for %s does not match '
                         'expectation in %s!  Here\'s the diff:\n%s\n' %
                         (self._builder_name, expected_dir,
                          utils.StringDiff(expectation, self_as_string)))
      else:
        # We don't print the full diff in this case because:
        # a. It's generally too long to be easily read in a terminal
        # b. All of the printing can noticeably slow down the master startup
        # c. The master prints so much output that it would be easy to miss the
        #    diff if we did print it.
        print 'Warning: Factory configuration for %s does not match ' \
              'expectation!' % self._builder_name

  # TODO(borenet): Can kwargs be used to simplify this function declaration?
  def AddSlaveScript(self, script, description, args=None, timeout=None,
                     halt_on_failure=False,
                     is_upload_render_step=False, is_upload_bench_step=False,
                     is_rebaseline_step=False, get_props_from_stdout=None,
                     workdir=None, do_step_if=None, always_run=False,
                     flunk_on_failure=True, exception_on_failure=False):
    """ Add a BuildStep consisting of a python script.

    script: which slave-side python script to run.
    description: string briefly describing the BuildStep; if this description
        is in the self.skipsteps list, this BuildStep will be skipped--unless
        it's in the self.dontskipsteps list, in which case we run it!
    args: optional list of strings; arguments to pass to the script.
    timeout: optional integer; maximum time for the BuildStep to complete.
    halt_on_failure: boolean indicating whether to continue the build if this
        step fails.
    is_upload_render_step: boolean; if true, only run if
        self._do_upload_render_results is True
    is_upload_bench_step: boolean; if true, only run if
        self._do_upload_bench_results is True
    is_rebaseline_step: boolean indicating whether this step is required for
        rebaseline-only builds.
    get_props_from_stdout: optional dictionary. Keys are strings indicating
        build properties to set based on the output of this step. Values are
        strings containing regular expressions for parsing the property from
        the output of the step.
    workdir: optional string indicating the working directory in which to run
        the script. If this is provided, then the script must be given relative
        to this directory.
    do_step_if: optional, function which determines whether or not to run the
        step.  The function is not evaluated until runtime.
    always_run: boolean indicating whether this step should run even if a
        previous step which had halt_on_failure has failed.
    flunk_on_failure: boolean indicating whether the whole build fails if this
        step fails.
    exception_on_failure: boolean indicating whether to raise an exception if
        this step fails. This causes the step to go purple instead of red, and
        causes the build to stop. Should be used if the build step's failure is
        typically transient or results from an infrastructure failure rather
        than a code change.
    """
    if description not in self.dontskipsteps:
      if description in self.skipsteps:
        return
      if is_upload_render_step and not self._do_upload_render_results:
        return
      if is_upload_bench_step and not self._do_upload_bench_results:
        return

    arguments = list(self._common_args)
    if args:
      arguments += args
    self._skia_cmd_obj.AddSlaveScript(
        script=script,
        args=arguments,
        description=description,
        timeout=timeout,
        halt_on_failure=halt_on_failure,
        is_upload_step=is_upload_render_step or is_upload_bench_step,
        is_rebaseline_step=is_rebaseline_step,
        get_props_from_stdout=get_props_from_stdout,
        workdir=workdir,
        do_step_if=do_step_if,
        always_run=always_run,
        flunk_on_failure=flunk_on_failure,
        exception_on_failure=exception_on_failure)

  def AddFlavoredSlaveScript(self, script, args=None, **kwargs):
    """ Add a flavor-specific BuildStep.

    Finds a script to run by concatenating the flavor of this BuildFactory with
    the provided script name.
    """
    flavor_args = ['--flavor', self._flavor or 'default']
    self.AddSlaveScript(script, args=list(args or []) + flavor_args, **kwargs)

  def RunGYP(self, description=_RUNGYP_STEP_DESCRIPTION, do_step_if=None):
    """ Run GYP to generate build files.

    description: string; description of this BuildStep.
    do_step_if: optional, function which determines whether or not to run this
        step.
    """
    self.AddFlavoredSlaveScript(script='run_gyp.py', description=description,
                                halt_on_failure=True, do_step_if=do_step_if,
                                args=['--gyp_defines',
                                      ' '.join('%s=%s' % (k, v) for k, v in
                                               self._gyp_defines.items())])

  def Make(self, target, description, is_rebaseline_step=False, do_step_if=None,
           always_run=False, flunk_on_failure=True, halt_on_failure=True):
    """ Build a single target.

    target: string; the target to build.
    description: string; description of this BuildStep.
    is_rebaseline_step: optional boolean; whether or not this step is required
        for rebaseline-only builds.
    do_step_if: optional, function which determines whether or not to run this
        step.
    always_run: boolean indicating whether this step should run even if a
        previous step which had halt_on_failure has failed.
    flunk_on_failure: boolean indicating whether the whole build fails if this
        step fails.
    halt_on_failure: boolean indicating whether to continue the build if this
        step fails.
    """
    args = ['--target', target,
            '--gyp_defines',
            ' '.join('%s=%s' % (k, v) for k, v in self._gyp_defines.items())]
    self.AddFlavoredSlaveScript(script='compile.py', args=args,
                                description=description,
                                halt_on_failure=halt_on_failure,
                                is_rebaseline_step=is_rebaseline_step,
                                do_step_if=do_step_if,
                                always_run=always_run,
                                flunk_on_failure=flunk_on_failure)

  def Compile(self, clobber=None, retry_with_clobber_on_failure=True,
              retry_without_werr_on_failure=False):
    """ Compile step. Build everything.

    clobber: optional boolean; whether to 'clean' before building.
    retry_with_clobber_on_failure: optional boolean; if the build fails, clean
        and try again, with the same configuration as before.
    retry_without_werr_on_failure: optional boolean; if the build fails, clean
        and try again *without* warnings-as-errors.
    """
    if clobber is None:
      clobber = self._default_clobber


    if clobber:
      self.AddFlavoredSlaveScript(script='clean.py', description='Clean',
                                  halt_on_failure=True)

    # Only retry with clobber if we've requested it AND we aren't clobbering on
    # the first build.
    maybe_retry_with_clobber = retry_with_clobber_on_failure and not clobber

    def ShouldRetryWithClobber(step):
      """ Determine whether the retry step should run. """
      if not maybe_retry_with_clobber:
        return False
      gyp_or_compile_failed = False
      retry_failed = False
      for build_step in step.build.getStatus().getSteps():
        if (build_step.isFinished() and
            build_step.getResults()[0] == builder.FAILURE):
          if build_step.getName().startswith(_COMPILE_STEP_PREFIX):
            gyp_or_compile_failed = True
          elif build_step.getName() == _RUNGYP_STEP_DESCRIPTION:
            gyp_or_compile_failed = True
          elif build_step.getName().startswith(_COMPILE_RETRY_PREFIX):
            retry_failed = True
      return gyp_or_compile_failed and not retry_failed

    def ShouldRetryWithoutWarnings(step):
      """ Determine whether the retry-without-warnings-as-errors step should
      run. """
      if not retry_without_werr_on_failure:
        return False
      gyp_or_compile_failed = False
      retry_failed = False
      no_warning_retry_failed = False
      for build_step in step.build.getStatus().getSteps():
        if (build_step.isFinished() and
            build_step.getResults()[0] == builder.FAILURE):
          if build_step.getName().startswith(_COMPILE_STEP_PREFIX):
            gyp_or_compile_failed = True
          elif build_step.getName().startswith(_COMPILE_RETRY_PREFIX):
            retry_failed = True
          elif build_step.getName().startswith(
              _COMPILE_NO_WERR_PREFIX):
            no_warning_retry_failed = True
      # If we've already failed a previous retry without warnings, just give up.
      if no_warning_retry_failed:
        return False
      # If we're retrying with clobber, only retry without warnings if a clobber
      # retry has failed.
      if maybe_retry_with_clobber:
        return retry_failed
      # Only run the retry if the initial compile has failed.
      return gyp_or_compile_failed

    for build_target in self._build_targets:
      self.Make(target=build_target,
                description=_COMPILE_STEP_PREFIX + \
                    utils.UnderscoresToCapWords(build_target),
                flunk_on_failure=not maybe_retry_with_clobber,
                halt_on_failure=(not maybe_retry_with_clobber and
                                 not retry_without_werr_on_failure))

    # Try again with a clean build.
    self.AddFlavoredSlaveScript(script='clean.py', description='Clean',
                                do_step_if=ShouldRetryWithClobber)
    for build_target in self._build_targets:
      self.Make(target=build_target,
                description=_COMPILE_RETRY_PREFIX + \
                    utils.UnderscoresToCapWords(build_target),
                flunk_on_failure=True,
                halt_on_failure=not retry_without_werr_on_failure,
                do_step_if=ShouldRetryWithClobber)

    # Try again without warnings-as-errors.
    self._gyp_defines['skia_warnings_as_errors'] = '0'
    self.AddFlavoredSlaveScript(script='clean.py', description='Clean',
                                always_run=True,
                                do_step_if=ShouldRetryWithoutWarnings)
    for build_target in self._build_targets:
      self.Make(target=build_target,
                description=_COMPILE_NO_WERR_PREFIX + \
                    utils.UnderscoresToCapWords(build_target),
                flunk_on_failure=True,
                halt_on_failure=True,
                do_step_if=ShouldRetryWithoutWarnings)

  def Install(self):
    """ Install the compiled executables. """
    self.AddFlavoredSlaveScript(script='install.py', description='Install',
                                halt_on_failure=True, exception_on_failure=True)

  def DownloadSKPs(self):
    """ Download the SKPs. """
    self.AddSlaveScript(script='download_skps.py', description='DownloadSKPs',
                        halt_on_failure=True, exception_on_failure=True)

  def DownloadSKImageFiles(self):
    """ Download image files for running skimage. """
    self.AddSlaveScript(script='download_skimage_files.py',
                        description='DownloadSKImageFiles',
                        halt_on_failure=True, exception_on_failure=True)

  def RunTests(self):
    """ Run the unit tests. """
    self.AddFlavoredSlaveScript(script='run_tests.py', description='RunTests')

  def RunDecodingTests(self):
    """ Run tests of image decoders. """
    self.AddFlavoredSlaveScript(script='run_decoding_tests.py',
                                description='RunDecodingTests')

  def RunDM(self):
    """Run DM."""
    self.AddFlavoredSlaveScript('run_dm.py', description='RunDM')

  def RunGM(self):
    """ Run the "GM" tool, saving the images to disk. """
    self.AddFlavoredSlaveScript(script='run_gm.py', description='GenerateGMs',
                                is_rebaseline_step=True)

  def PreRender(self):
    """ Step to run before the render steps. """
    self.AddFlavoredSlaveScript(script='prerender.py', description='PreRender',
                                exception_on_failure=True)

  def RenderSKPs(self):
    """ Generate images from .skp's. """
    self.AddFlavoredSlaveScript(script='render_skps.py',
                                description='RenderSKPs')

  def RenderPdfs(self):
    """ Run the "render_pdfs" tool to generate pdfs from .skp's. """
    self.AddFlavoredSlaveScript(script='render_pdfs.py',
                                description='RenderPdfs')

  def PostRender(self):
    """ Step to run after the render steps. """
    self.AddFlavoredSlaveScript(script='postrender.py',
                                description='PostRender',
                                exception_on_failure=True)

  def PreBench(self):
    """ Step to run before the benchmarking steps. """
    self.AddFlavoredSlaveScript(script='prebench.py',
                                description='PreBench',
                                exception_on_failure=True)

  def PostBench(self):
    """ Step to run after the benchmarking steps. """
    self.AddFlavoredSlaveScript(script='postbench.py',
                                description='PostBench',
                                exception_on_failure=True)

  def CompareGMs(self):
    """Compare the actually-generated GM images to the checked-in baselines."""
    self.AddSlaveScript(script='compare_gms.py',
                        description='CompareGMs',
                        get_props_from_stdout={
                            'latest_gm_failures_url':
                            '%s([^\n]*)\n' % skia_vars.GetGlobalVariable(
                                'latest_gm_failures_preamble')},
                        is_rebaseline_step=True)

  def CompareRenderedSKPs(self):
    """Compare the actual image results of SKP rendering to expectations."""
    self.AddSlaveScript(script='compare_rendered_skps.py',
                        description='CompareRenderedSKPs',
                        is_rebaseline_step=True)

  def RunBench(self):
    """ Run "bench", piping the output somewhere so we can graph
    results over time. """
    self.AddFlavoredSlaveScript(script='run_bench.py', description='RunBench')

  def BenchPictures(self):
    """ Run "bench_pictures" """
    self.AddFlavoredSlaveScript(script='bench_pictures.py',
                                description='BenchPictures')

  def CheckForRegressions(self):
    """ Check for benchmark regressions. """
    self.AddSlaveScript(script='check_for_regressions.py',
                        description='CheckForRegressions')

  def UpdateScripts(self):
    """ Update the buildbot scripts on the build slave.

    Only runs in production. See http://skbug.com/2432
    """
    description = 'UpdateScripts'
    if ((config_private.Master.get_active_master().is_production_host) or
        (description in self.dontskipsteps)):
      self.AddSlaveScript(
          script=self.TargetPath.join('..', '..', '..', '..',
                                      '..', 'slave',
                                      'skia_slave_scripts',
                                      'update_scripts.py'),
          description=description,
          halt_on_failure=True,
          get_props_from_stdout={'buildbot_revision':
                                   'Skiabot scripts updated to (\w+)'},
          workdir='build',
          exception_on_failure=True)

  def Update(self):
    """ Update the Skia code on the build slave. """
    args = ['--gclient_solutions', '"%s"' % self._gclient_solutions]
    self.AddSlaveScript(
        script=self.TargetPath.join('..', '..', '..', '..', '..', 'slave',
                                   'skia_slave_scripts', 'update.py'),
        description='Update',
        args=args,
        timeout=None,
        halt_on_failure=True,
        is_rebaseline_step=True,
        get_props_from_stdout={'got_revision':'Skia updated to (\w+)'},
        workdir='build',
        exception_on_failure=True)

  def ApplyPatch(self, alternate_workdir=None, alternate_script=None):
    """ Apply a patch to the Skia code on the build slave. """
    def _GetPatch(build):
      """Find information about the patch (if any) to apply.

      Returns:
          An encoded string containing a tuple of the form (level, url) which
              indicates where to go to download the patch.
      """
      if build.getSourceStamp().patch and \
          'patch_file_url' in build.getProperties():
        # The presence of a patch attached to the Source Stamp and the
        # 'patch_file_url' build property indicate that the patch came from the
        # skia_try repo, and was probably submitted using the submit_try script
        # or "gcl/git-cl try".
        patch = (build.getSourceStamp().patch[0],
                 build.getProperty('patch_file_url'))
        return str(patch).encode()
      elif 'issue' in build.getProperties() and \
          'patchset' in build.getProperties():
        # The presence of the 'issue' and 'patchset' build properties indicates
        # that the patch came from Rietveld.
        patch = '%s/download/issue%d_%d.diff' % (
            config_private.CODE_REVIEW_SITE.rstrip('/'),
            build.getProperty('issue'),
            build.getProperty('patchset'))
        # If the patch came from Rietveld, assume it came from a git repo and
        # therefore it has a patch level of 1. If this isn't the case, the
        # slave-side script should detect it and use level 0 instead.
        return str((1, patch)).encode()
      else:
        patch = 'None'
      return patch

    if not bool(alternate_workdir) == bool(alternate_script):
      raise ValueError('alternate_workdir and alternate_script must be provided'
                       ' together.')
    args = ['--patch', WithProperties('%(patch)s', patch=_GetPatch)]
    if alternate_script:
      self.AddSlaveScript(script=alternate_script,
                          description='ApplyPatch',
                          args=args,
                          halt_on_failure=True,
                          workdir=alternate_workdir,
                          exception_on_failure=True)
    else:
      self.AddSlaveScript(script='apply_patch.py',
                          description='ApplyPatch',
                          args=args,
                          halt_on_failure=True,
                          exception_on_failure=True)

  def UpdateSteps(self):
    """ Update the Skia sources. """
    self.UpdateScripts()
    self.Update()
    if self._do_patch_step:
      self.ApplyPatch()

  def UploadBenchResults(self):
    """ Upload bench results (performance data). """
    self.AddSlaveScript(script='upload_bench_results.py',
                        description='UploadBenchResults',
                        exception_on_failure=True,
                        is_upload_bench_step=True)

  def UploadBenchResultsToAppEngine(self):
    """ Upload bench results (performance data) to AppEngine. """
    self.AddSlaveScript(script='upload_bench_results_appengine.py',
                        description='UploadBenchResultsToAppengine',
                        exception_on_failure=True)

  def UploadWebpagePictureBenchResults(self):
    """ Upload webpage picture bench results (performance data). """
    self.AddSlaveScript(script='upload_webpage_picture_bench_results.py',
                        description='UploadWebpagePictureBenchResults',
                        exception_on_failure=True)


  def UploadGMResults(self):
    """ Upload the images generated by GM """
    args = ['--autogen_svn_username_file', self._autogen_svn_username_file,
            '--autogen_svn_password_file', self._autogen_svn_password_file]
    self.AddSlaveScript(script='upload_gm_results.py', args=args,
                        description='UploadGMResults', timeout=5400,
                        is_upload_render_step=True, is_rebaseline_step=True,
                        exception_on_failure=True)

  def UploadRenderedSKPs(self):
    """Upload the actual image results of SKP rendering."""
    # TODO(epoger): Maybe instead of adding these extra args to only CERTAIN
    # steps (and thus requiring a master restart when we want to add them to
    # more steps), maybe we should just provide these extra args to ALL steps?
    args = ['--autogen_svn_username_file', self._autogen_svn_username_file,
            '--autogen_svn_password_file', self._autogen_svn_password_file]
    self.AddSlaveScript(script='upload_rendered_skps.py', args=args,
                        description='UploadRenderedSKPs',
                        is_upload_render_step=True, is_rebaseline_step=True)

  def UploadSKImageResults(self):
    self.AddSlaveScript(script='upload_skimage_results.py',
                        description='UploadSKImageResults',
                        is_upload_render_step=True,
                        exception_on_failure=True)

  def CommonSteps(self, clobber=None):
    """ Steps which are run at the beginning of all builds. """
    self.UpdateSteps()
    self.DownloadSKPs()
    self.Compile(clobber)
    self.Install()

  def NonPerfSteps(self):
    """ Add correctness testing BuildSteps. """
    self.DownloadSKImageFiles()
    self.PreRender()
    self.RunTests()
    self.RunGM()
    self.RenderSKPs()
    self.RenderPdfs()
    self.RunDecodingTests()
    self.PostRender()
    self.UploadGMResults()
    self.UploadRenderedSKPs()
    self.UploadSKImageResults()
    self.CompareGMs()
    self.CompareRenderedSKPs()

  def PerfSteps(self):
    """ Add performance testing BuildSteps. """
    self.PreBench()
    self.RunBench()
    self.BenchPictures()
    self.PostBench()
    self.CheckForRegressions()
    self.UploadBenchResults()

  def Build(self, role=None, clobber=None):
    """Build and return the complete BuildFactory.

    role: string; the intended role of this builder. The role affects which
        steps are run. Known values are given in the utils module.
    clobber: boolean indicating whether we should clean before building
    """
    # Special case: for the ZeroGPUCache bot, we only run GM.
    if 'ZeroGPUCache' in self._builder_name:
      self._build_targets = ['gm']
      self.UpdateSteps()
      self.Compile(clobber)
      self.Install()
      self.PreRender()
      self.RunGM()
      self.PostRender()
    elif ('TSAN' in self._builder_name and
          role == builder_name_schema.BUILDER_ROLE_TEST):
      self._build_targets = ['tests', 'dm']
      self.UpdateSteps()
      self.Compile(clobber)
      self.Install()
      self.RunTests()
      self.RunDM()
    elif ('Valgrind' in self._builder_name and
          role == builder_name_schema.BUILDER_ROLE_TEST):
      if not self._build_targets:
        self._build_targets = ['most']
      self.CommonSteps(clobber)
      # TODO(borenet):When https://code.google.com//p/skia/issues/detail?id=1711
      # is fixed, run self.NonPerfSteps() instead of the below steps.
      self.DownloadSKImageFiles()
      self.PreRender()
      self.RunTests()
      self.RunGM()
      self.RenderSKPs()
      self.RenderPdfs()
      self.RunDecodingTests()
      self.PostRender()
      # (end steps which need to be replaced once #1711 is fixed)

      self.PreBench()
      self.RunBench()
      self.PostBench()
    elif not role:
      # If no role is provided, just run everything.
      if not self._build_targets:
        self._build_targets = ['most']
      self.CommonSteps(clobber)
      self.NonPerfSteps()
      self.PerfSteps()
    elif role == builder_name_schema.BUILDER_ROLE_BUILD:
      # Compile-only builder.
      self.UpdateSteps()
      if not self._build_targets:
        self._build_targets = []
        if (('Win7' in self._builder_name and 'x86_64' in self._builder_name) or
            ('Ubuntu' in self._builder_name and 'x86-' in self._builder_name) or
            'Mac10.6' in self._builder_name or 'Mac10.7' in self._builder_name):
          # Don't compile the debugger in 64-bit Win7, Mac 10.6, Mac 10.7, or
          # 32-bit Linux since the Qt SDK doesn't include libraries for those
          # platforms.
          self._build_targets.append('most')
        else:
          self._build_targets.append('everything')
      self.Compile(clobber=clobber,
                   retry_without_werr_on_failure=True)
    else:
      if not self._build_targets:
        self._build_targets = ['most']
      self.CommonSteps(clobber)
      if role == builder_name_schema.BUILDER_ROLE_TEST:
        # Test-running builder.
        self.NonPerfSteps()
        if self._configuration == CONFIG_DEBUG:
          # Debug-mode testers run all steps, but release-mode testers don't.
          self.PerfSteps()
      elif role == builder_name_schema.BUILDER_ROLE_PERF:
        # Perf-only builder.
        if not self._perf_output_basedir:
          raise ValueError(
              'BuildPerfOnly requires perf_output_basedir to be defined.')
        if self._configuration != CONFIG_RELEASE:
          raise ValueError('BuildPerfOnly should run in %s configuration.' %
                           CONFIG_RELEASE)
        self.PerfSteps()
    self.Validate()
    return self
