Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(196)

Unified Diff: scripts/slave/recipe_modules/auto_bisect/revision_state.py

Issue 940123005: Adding ability to bisect recipe to bisect into dependency repos. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/build.git@hax
Patch Set: WIP: Early feedback request Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: scripts/slave/recipe_modules/auto_bisect/revision_state.py
diff --git a/scripts/slave/recipe_modules/auto_bisect/revision_state.py b/scripts/slave/recipe_modules/auto_bisect/revision_state.py
index e54f731e826e837b31140d235863d1e49ab70447..c449aa3f5e540b39e29ccc10f1c7d5e873c92db3 100644
--- a/scripts/slave/recipe_modules/auto_bisect/revision_state.py
+++ b/scripts/slave/recipe_modules/auto_bisect/revision_state.py
@@ -9,37 +9,74 @@ class so that the bisect module and recipe can use it.
See perf_revision_state for an example.
"""
+import hashlib
+import os
+import re
+
+from . import depot_config
class RevisionState(object):
qyearsley 2015/02/22 20:37:55 The other files have two blank lines between impor
RobertoCN 2015/02/24 20:01:14 Done.
"""Abstracts the state of a single revision on a bisect job."""
- def __init__(self, revision_string, bisector):
+ def __init__(self, revision_string, bisector, depot='chromium',
+ base_revision=None, deps_revision=None):
"""Create a new instance to track the state of a revision.
+ There are two use cases for this constructor:
+ - Creating a revision state for a chromium revision, OR
+ - Creating a revision state for a chromium revision plus a deps change.
qyearsley 2015/02/22 20:37:55 I'm not sure, but for other people without context
RobertoCN 2015/02/24 20:01:14 Done.
+ In the first case a revision_string and a bisector are needed.
+ In the second case, revision_string must be None, and all of depot,
+ base_revision and deps_revision must be provided.
+
Args:
- revision_string: should be in the following format:
- [(chromium|src)@](<commit_pos>|<commit_hash)(,<repo>@<commit>)*
- E.g.:
- 'a0b1c2ffff89009909090' (full or abbrev. commit hash)
- '123456'
- 'src@123456'
- 'chromium@123456'
- 'src@abc01234ffff,v8@00af5ceb888ff'
- bisector: an instance of Bisector, the object performing the bisection.
+ revision_string (str): A git hash or a commit position in the chromium
+ repository. If None, all kwargs must be given.
+ bisector (Bisector): The object performing the bisection.
+ depot (dict): One of the entries in depot_config.DEPOT_DEPS_NAME that
+ specifies which dependency to do the DEPS change on. It is expected to
+ contain the 'chromium' string instead of None when not bisecting any
+ dependencies.
+ base_revision (RevisionState): The revision state to patch with the deps
+ change.
+ depot_revision: The commit hash of the dependency repo to put in place of
+ the one set for the base_revision.
"""
+ # TODO(robertocn): Evaluate if the logic of this constructor should be
+ # split into separate methods.
super(RevisionState, self).__init__()
self.bisector = bisector
self._good = None
+ self.deps = None
self.build_status_url = None
self.in_progress = False
self.aborted = False
self.next_revision = None
self.previous_revision = None
self.revision_string = revision_string
- self.commit_hash, self.commit_pos = self._commit_from_rev_string()
self.build_job_name = None
self.test_job_name = None
self.built = False
+ if not self.revision_string:
+ assert base_revision
+ assert base_revision.deps_file_contents
+ assert depot != 'chromium'
+ assert deps_revision
+ self.needs_patch = True
+ self.depot = depot['deps_var']
+ self.revision_string = base_revision.revision_string + ',' + self.depot
+ self.revision_string += '@' + deps_revision
+ self.deps_patch, self.deps_file_contents = self.bisector.make_deps_patch(
+ base_revision.commit_hash, base_revision.deps_file_contents,
+ self.depot, deps_revision)
+ self.deps_sha = hashlib.sha1(self.deps_patch).hexdigest()
+ self.deps_patch += self.bisector.make_deps_sha_file(self.deps_sha)
+ self.deps = dict(base_revision.deps)
+ self.deps[self.depot] = deps_revision
+ else:
+ self.needs_patch = False
+ self.depot = depot
+ self.commit_hash, self.commit_pos = self._commit_from_rev_string()
self.build_url = self.bisector.get_platform_gs_prefix() + self._gs_suffix()
@property
@@ -100,6 +137,57 @@ class RevisionState(object):
return True
return False
+
+ def _gen_deps_local_scope(self):
+ """Defines the Var and From functions in a dict for calling exec.
+
+ This is needed for executing the DEPS file.
+ """
+ deps_data = {
+ 'Var': lambda _: deps_data["vars"][_],
qyearsley 2015/02/22 20:37:55 Single quotes.
RobertoCN 2015/02/24 20:01:14 Done.
+ 'From': lambda *args: None,
+ }
+ return deps_data
+
+ def read_deps(self):
+ """Sets the dependencies for this revision from the contents of DEPS."""
+ if self.deps:
+ return
+ deps_contents = self.m.git.cat_file_at_revision(depot_config.FILE_DEPS)
+ try:
+ deps_data = self._gen_deps_local_scope()
+ exec(deps_contents, {}, deps_data)
+ deps_data = deps_data['deps']
+ except ImportError:
+ # TODO(robertocn): Implement manual parsing of DEPS when exec fails.
+ raise NotImplementedError('Path not implemented to manually parse DEPS')
+
+ rxp = re.compile(".git@(?P<revision>[a-fA-F0-9]+)")
qyearsley 2015/02/22 20:37:55 1. Variable name could probably be improved. 2. No
RobertoCN 2015/02/24 20:01:14 Done.
+ results = {}
+ for depot_name, depot_data in depot_config.DEPOT_DEPS_NAME.iteritems():
+ if (depot_data.get('platform') and
+ depot_data.get('platform') != os.name):
+ # TODO(robertocn) we shouldn't be checking the os of the bot running the
+ # bisector, but the os the tester would be running on.
+ continue
+
+ if depot_data.get('recurse') and self.depot in depot_data.get('from'):
+ depot_data_src = depot_data.get('src') or depot_data.get('src_old')
+ src_dir = deps_data.get(depot_data_src)
+ if src_dir:
+ re_results = rxp.search(src_dir)
+ if re_results:
+ results[depot_name] = re_results.group('revision')
+ else:
+ warning_text = ('Could not parse revision for %s while bisecting '
+ '%s' % (depot_name, self.depot))
+ if not warning_text in self.bisector.warnings:
+ self.bisector.warnings.append(warning_text)
+ else:
+ results[depot_name] = None
+ self.deps = results
+ return
+
def update_status(self):
"""Checks on the pending jobs and updates status accordingly.
@@ -137,8 +225,10 @@ class RevisionState(object):
This takes into account whether the build has a deps patch.
"""
- # TODO: Implement the logic for deps patch changes.
- return self.commit_hash + '.zip'
+ name_parts = [self.commit_hash]
+ if self.needs_patch:
+ name_parts.append(self.deps_sha)
+ return '%s.zip' % '_'.join(name_parts)
def _commit_from_rev_string(self):
"""Gets the chromium repo commit hash and position for this revision.

Powered by Google App Engine
This is Rietveld 408576698