| Index: tools/auto_bisect/bisect_perf_regression.py
|
| diff --git a/tools/auto_bisect/bisect_perf_regression.py b/tools/auto_bisect/bisect_perf_regression.py
|
| index 8e94c4c3f38f93bd79360b6076435f9a3b5033bb..ac71428abad086c03066f80f25113232532d7f11 100755
|
| --- a/tools/auto_bisect/bisect_perf_regression.py
|
| +++ b/tools/auto_bisect/bisect_perf_regression.py
|
| @@ -176,10 +176,10 @@ HIGH_CONFIDENCE = 95
|
| # When a build requested is posted with a patch, bisect builders on try server,
|
| # once build is produced, it reads SHA value from this file and appends it
|
| # to build archive filename.
|
| -DEPS_SHA_PATCH = """diff --git src/DEPS.sha src/DEPS.sha
|
| +DEPS_SHA_PATCH = """diff --git DEPS.sha DEPS.sha
|
| new file mode 100644
|
| --- /dev/null
|
| -+++ src/DEPS.sha
|
| ++++ DEPS.sha
|
| @@ -0,0 +1 @@
|
| +%(deps_sha)s
|
| """
|
| @@ -250,6 +250,20 @@ O O | Visit http://www.chromium.org/developers/core-principles for Chrome's
|
| X | policy on perf regressions. Contact chrome-perf-dashboard-team with any
|
| / \ | questions or suggestions about bisecting. THANK YOU."""
|
|
|
| +# Git branch name used to run bisect try jobs.
|
| +BISECT_TRYJOB_BRANCH = 'bisect-tryjob'
|
| +# Git master branch name.
|
| +BISECT_MASTER_BRANCH = 'master'
|
| +# File to store 'git diff' content.
|
| +BISECT_PATCH_FILE = 'deps_patch.txt'
|
| +# SVN repo where the bisect try jobs are submitted.
|
| +SVN_REPO_URL = 'svn://svn.chromium.org/chrome-try/try-perf'
|
| +
|
| +class RunGitError(Exception):
|
| +
|
| + def __str__(self):
|
| + return '%s\nError executing git command.' % self.args[0]
|
| +
|
|
|
| def _AddAdditionalDepotInfo(depot_info):
|
| """Adds additional depot info to the global depot variables."""
|
| @@ -846,6 +860,95 @@ class DepotDirectoryRegistry(object):
|
| """
|
| os.chdir(self.GetDepotDir(depot_name))
|
|
|
| +def _PrepareBisectBranch(parent_branch, new_branch):
|
| + """Creates a new branch to submit bisect try job.
|
| +
|
| + Args:
|
| + parent_branch: Parent branch to be used to create new branch.
|
| + new_branch: New branch name.
|
| + """
|
| + current_branch, returncode = bisect_utils.RunGit(
|
| + ['rev-parse', '--abbrev-ref', 'HEAD'])
|
| + if returncode:
|
| + raise RunGitError('Must be in a git repository to send changes to trybots.')
|
| +
|
| + current_branch = current_branch.strip()
|
| + # Make sure current branch is master.
|
| + if current_branch != parent_branch:
|
| + output, returncode = bisect_utils.RunGit(['checkout', '-f', parent_branch])
|
| + if returncode:
|
| + raise RunGitError('Failed to checkout branch: %s.' % output)
|
| +
|
| + # Delete new branch if exists.
|
| + output, returncode = bisect_utils.RunGit(['branch', '--list' ])
|
| + if new_branch in output:
|
| + output, returncode = bisect_utils.RunGit(['branch', '-D', new_branch])
|
| + if returncode:
|
| + raise RunGitError('Deleting branch failed, %s', output)
|
| +
|
| + # Check if the tree is dirty: make sure the index is up to date and then
|
| + # run diff-index.
|
| + bisect_utils.RunGit(['update-index', '--refresh', '-q'])
|
| + output, returncode = bisect_utils.RunGit(['diff-index', 'HEAD'])
|
| + if output:
|
| + raise RunGitError('Cannot send a try job with a dirty tree.')
|
| +
|
| + # Create/check out the telemetry-tryjob branch, and edit the configs
|
| + # for the tryjob there.
|
| + output, returncode = bisect_utils.RunGit(['checkout', '-b', new_branch])
|
| + if returncode:
|
| + raise RunGitError('Failed to checkout branch: %s.' % output)
|
| +
|
| + output, returncode = bisect_utils.RunGit(
|
| + ['branch', '--set-upstream-to', parent_branch])
|
| + if returncode:
|
| + raise RunGitError('Error in git branch --set-upstream-to')
|
| +
|
| +
|
| +def _BuilderTryjob(git_revision, bot_name, bisect_job_name, patch=None):
|
| + """Attempts to run a tryjob from the current directory.
|
| +
|
| + Args:
|
| + git_revision: A Git hash revision.
|
| + bot_name: Name of the bisect bot to be used for try job.
|
| + bisect_job_name: Bisect try job name.
|
| + patch: A DEPS patch (used while bisecting 3rd party repositories).
|
| + """
|
| + try:
|
| + # Temporary branch for running tryjob.
|
| + _PrepareBisectBranch(BISECT_MASTER_BRANCH, BISECT_TRYJOB_BRANCH)
|
| + patch_content = '/dev/null'
|
| + # Create a temporary patch file, if it fails raise an exception.
|
| + if patch:
|
| + WriteStringToFile(patch, BISECT_PATCH_FILE)
|
| + patch_content = BISECT_PATCH_FILE
|
| +
|
| + try_cmd = ['try',
|
| + '-b', bot_name,
|
| + '-r', git_revision,
|
| + '-n', bisect_job_name,
|
| + '--svn_repo=%s' % SVN_REPO_URL,
|
| + '--diff=%s' % patch_content
|
| + ]
|
| + # Execute try job to build revision.
|
| + output, returncode = bisect_utils.RunGit(try_cmd)
|
| +
|
| + if returncode:
|
| + raise RunGitError('Could not execute tryjob: %s.\n Error: %s' % (
|
| + 'git %s' % ' '.join(try_cmd), output))
|
| + print ('Try job successfully submitted.\n TryJob Details: %s\n%s' % (
|
| + 'git %s' % ' '.join(try_cmd), output))
|
| + finally:
|
| + # Delete patch file if exists
|
| + try:
|
| + os.remove(BISECT_PATCH_FILE)
|
| + except OSError as e:
|
| + if e.errno != errno.ENOENT:
|
| + raise
|
| + # Checkout master branch and delete bisect-tryjob branch.
|
| + bisect_utils.RunGit(['checkout', '-f', BISECT_MASTER_BRANCH])
|
| + bisect_utils.RunGit(['branch', '-D', BISECT_TRYJOB_BRANCH])
|
| +
|
|
|
| class BisectPerformanceMetrics(object):
|
| """This class contains functionality to perform a bisection of a range of
|
| @@ -1182,7 +1285,7 @@ class BisectPerformanceMetrics(object):
|
| return FetchFromCloudStorage(gs_bucket, source_file, out_dir)
|
| return downloaded_archive
|
|
|
| - def DownloadCurrentBuild(self, revision, build_type='Release', patch=None):
|
| + def DownloadCurrentBuild(self, revision, depot, build_type='Release'):
|
| """Downloads the build archive for the given revision.
|
|
|
| Args:
|
| @@ -1193,7 +1296,12 @@ class BisectPerformanceMetrics(object):
|
| Returns:
|
| True if download succeeds, otherwise False.
|
| """
|
| + patch = None
|
| patch_sha = None
|
| + if depot != 'chromium':
|
| + # Create a DEPS patch with new revision for dependency repository.
|
| + revision, patch = self.CreateDEPSPatch(depot, revision)
|
| +
|
| if patch:
|
| # Get the SHA of the DEPS changes patch.
|
| patch_sha = GetSHA1HexDigest(patch)
|
| @@ -1290,37 +1398,31 @@ class BisectPerformanceMetrics(object):
|
| if not fetch_build:
|
| return False
|
|
|
| - bot_name, build_timeout = GetBuilderNameAndBuildTime(
|
| - self.opts.target_platform, self.opts.target_arch)
|
| - builder_host = self.opts.builder_host
|
| - builder_port = self.opts.builder_port
|
| # Create a unique ID for each build request posted to try server builders.
|
| # This ID is added to "Reason" property of the build.
|
| build_request_id = GetSHA1HexDigest(
|
| '%s-%s-%s' % (git_revision, patch, time.time()))
|
|
|
| - # Creates a try job description.
|
| - # Always use Git hash to post build request since Commit positions are
|
| - # not supported by builders to build.
|
| - job_args = {
|
| - 'revision': 'src@%s' % git_revision,
|
| - 'bot': bot_name,
|
| - 'name': build_request_id,
|
| - }
|
| - # Update patch information if supplied.
|
| - if patch:
|
| - job_args['patch'] = patch
|
| - # Posts job to build the revision on the server.
|
| - if request_build.PostTryJob(builder_host, builder_port, job_args):
|
| + # Reverts any changes to DEPS file.
|
| + self.source_control.CheckoutFileAtRevision(
|
| + bisect_utils.FILE_DEPS, git_revision, cwd=self.src_cwd)
|
| +
|
| + bot_name, build_timeout = GetBuilderNameAndBuildTime(
|
| + self.opts.target_platform, self.opts.target_arch)
|
| + target_file = None
|
| + try:
|
| + # Execute try job request to build revision with patch.
|
| + _BuilderTryjob(git_revision, bot_name, build_request_id, patch)
|
| target_file, error_msg = _WaitUntilBuildIsReady(
|
| - fetch_build, bot_name, builder_host, builder_port, build_request_id,
|
| - build_timeout)
|
| + fetch_build, bot_name, self.opts.builder_host,
|
| + self.opts.builder_port, build_request_id, build_timeout)
|
| if not target_file:
|
| print '%s [revision: %s]' % (error_msg, git_revision)
|
| - return None
|
| - return target_file
|
| - print 'Failed to post build request for revision: [%s]' % git_revision
|
| - return None
|
| + except RunGitError as e:
|
| + print ('Failed to post builder try job for revision: [%s].\n'
|
| + 'Error: %s' % (git_revision, e))
|
| +
|
| + return target_file
|
|
|
| def IsDownloadable(self, depot):
|
| """Checks if build can be downloaded based on target platform and depot."""
|
| @@ -1417,6 +1519,7 @@ class BisectPerformanceMetrics(object):
|
| print 'Something went wrong while updating DEPS file. [%s]' % e
|
| return False
|
|
|
| +
|
| def CreateDEPSPatch(self, depot, revision):
|
| """Modifies DEPS and returns diff as text.
|
|
|
| @@ -1444,8 +1547,8 @@ class BisectPerformanceMetrics(object):
|
| if self.UpdateDeps(revision, depot, deps_file_path):
|
| diff_command = [
|
| 'diff',
|
| - '--src-prefix=src/',
|
| - '--dst-prefix=src/',
|
| + '--src-prefix=',
|
| + '--dst-prefix=',
|
| '--no-ext-diff',
|
| bisect_utils.FILE_DEPS,
|
| ]
|
| @@ -1474,16 +1577,7 @@ class BisectPerformanceMetrics(object):
|
| # Fetch build archive for the given revision from the cloud storage when
|
| # the storage bucket is passed.
|
| if self.IsDownloadable(depot) and revision:
|
| - deps_patch = None
|
| - if depot != 'chromium':
|
| - # Create a DEPS patch with new revision for dependency repository.
|
| - revision, deps_patch = self.CreateDEPSPatch(depot, revision)
|
| - if self.DownloadCurrentBuild(revision, patch=deps_patch):
|
| - if deps_patch:
|
| - # Reverts the changes to DEPS file.
|
| - self.source_control.CheckoutFileAtRevision(
|
| - bisect_utils.FILE_DEPS, revision, cwd=self.src_cwd)
|
| - build_success = True
|
| + build_success = self.DownloadCurrentBuild(revision, depot)
|
| else:
|
| # These codes are executed when bisect bots builds binaries locally.
|
| build_success = self.builder.Build(depot, self.opts)
|
| @@ -1779,17 +1873,7 @@ class BisectPerformanceMetrics(object):
|
| Returns:
|
| True if successful.
|
| """
|
| - if depot == 'chromium' or depot == 'android-chrome':
|
| - # Removes third_party/libjingle. At some point, libjingle was causing
|
| - # issues syncing when using the git workflow (crbug.com/266324).
|
| - os.chdir(self.src_cwd)
|
| - if not bisect_utils.RemoveThirdPartyDirectory('libjingle'):
|
| - return False
|
| - # Removes third_party/skia. At some point, skia was causing
|
| - # issues syncing when using the git workflow (crbug.com/377951).
|
| - if not bisect_utils.RemoveThirdPartyDirectory('skia'):
|
| - return False
|
| - elif depot == 'cros':
|
| + if depot == 'cros':
|
| return self.PerformCrosChrootCleanup()
|
| return True
|
|
|
| @@ -2639,7 +2723,8 @@ class BisectPerformanceMetrics(object):
|
| current_data['depot'])
|
| if not cl_link:
|
| cl_link = current_id
|
| - commit_position = self.source_control.GetCommitPosition(current_id)
|
| + commit_position = self.source_control.GetCommitPosition(
|
| + current_id, self.depot_registry.GetDepotDir(current_data['depot']))
|
| commit_position = str(commit_position)
|
| if not commit_position:
|
| commit_position = ''
|
|
|