# 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 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._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 = [
        # See http://skbug.com/2663 before deleting the next line.
        '--autogen_svn_baseurl', 'bogusValueToFixSkBug2663',
        '--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),
        '--is_try', str(self._do_patch_step),
        '--bench_pictures_cfg', bench_pictures_cfg,
        '--issue_number', WithProperties('%(issue:-None)s'),
        ]
    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 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 RunNanobench(self):
    """ Run "nanobench" """
    self.AddFlavoredSlaveScript(script='run_nanobench.py',
                                description='RunNanobench')

  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.
        # Don't assume that the 'issue' and 'patchset' build properties are
        # always integer type, even though they should contain integers.
        patch = '%s/download/issue%s_%s.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 """
    self.AddSlaveScript(script='upload_gm_results.py',
                        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."""
    self.AddSlaveScript(script='upload_rendered_skps.py',
                        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.RunDM()
    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.RunNanobench()
    self.PostBench()
    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 = ['dm']
      self.UpdateSteps()
      self.Compile(clobber)
      self.Install()
      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.RunDM()
      self.RunGM()
      self.RenderSKPs()
      self.RenderPdfs()
      self.RunDecodingTests()
      self.PostRender()
      # (end steps which need to be replaced once #1711 is fixed)
      self.PreBench()
      self.RunNanobench()
      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 (('Win' 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 on Windows, 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
