Index: tools/bisect-perf-regression.py
|
diff --git a/tools/bisect-perf-regression.py b/tools/bisect-perf-regression.py
|
index 83763dffde8faf7f4bbc30abee66455aa5e170a3..728e3499a7055803ef794ba07eba54b84c65ac95 100755
|
--- a/tools/bisect-perf-regression.py
|
+++ b/tools/bisect-perf-regression.py
|
@@ -46,7 +46,6 @@ import re
|
import shlex
|
import shutil
|
import StringIO
|
-import subprocess
|
import sys
|
import time
|
import zipfile
|
@@ -55,6 +54,7 @@ sys.path.append(os.path.join(os.path.dirname(__file__), 'telemetry'))
|
|
from auto_bisect import bisect_utils
|
from auto_bisect import post_perf_builder_job as bisect_builder
|
+from auto_bisect import source_control as source_control_module
|
from telemetry.util import cloud_storage
|
|
# The additional repositories that might need to be bisected.
|
@@ -143,8 +143,8 @@ DEPOT_DEPS_NAME = {
|
}
|
|
DEPOT_NAMES = DEPOT_DEPS_NAME.keys()
|
+
|
CROS_SDK_PATH = os.path.join('..', 'cros', 'chromite', 'bin', 'cros_sdk')
|
-CROS_VERSION_PATTERN = 'new version number from %s'
|
CROS_CHROMEOS_PATTERN = 'chromeos-base/chromeos-chrome'
|
CROS_TEST_KEY_PATH = os.path.join('..', 'cros', 'chromite', 'ssh_keys',
|
'testing_rsa')
|
@@ -413,82 +413,6 @@ def CalculateStandardError(values):
|
return std_dev / math.sqrt(len(values))
|
|
|
-def IsStringFloat(string_to_check):
|
- """Checks whether or not the given string can be converted to a floating
|
- point number.
|
-
|
- Args:
|
- string_to_check: Input string to check if it can be converted to a float.
|
-
|
- Returns:
|
- True if the string can be converted to a float.
|
- """
|
- try:
|
- float(string_to_check)
|
-
|
- return True
|
- except ValueError:
|
- return False
|
-
|
-
|
-def IsStringInt(string_to_check):
|
- """Checks whether or not the given string can be converted to a integer.
|
-
|
- Args:
|
- string_to_check: Input string to check if it can be converted to an int.
|
-
|
- Returns:
|
- True if the string can be converted to an int.
|
- """
|
- try:
|
- int(string_to_check)
|
-
|
- return True
|
- except ValueError:
|
- return False
|
-
|
-
|
-def IsWindowsHost():
|
- """Checks whether or not the script is running on Windows.
|
-
|
- Returns:
|
- True if running on Windows.
|
- """
|
- return sys.platform == 'cygwin' or sys.platform.startswith('win')
|
-
|
-
|
-def Is64BitWindows():
|
- """Returns whether or not Windows is a 64-bit version.
|
-
|
- Returns:
|
- True if Windows is 64-bit, False if 32-bit.
|
- """
|
- platform = os.environ['PROCESSOR_ARCHITECTURE']
|
- try:
|
- platform = os.environ['PROCESSOR_ARCHITEW6432']
|
- except KeyError:
|
- # Must not be running in WoW64, so PROCESSOR_ARCHITECTURE is correct
|
- pass
|
-
|
- return platform in ['AMD64', 'I64']
|
-
|
-
|
-def IsLinuxHost():
|
- """Checks whether or not the script is running on Linux.
|
-
|
- Returns:
|
- True if running on Linux.
|
- """
|
- return sys.platform.startswith('linux')
|
-
|
-
|
-def IsMacHost():
|
- """Checks whether or not the script is running on Mac.
|
-
|
- Returns:
|
- True if running on Mac.
|
- """
|
- return sys.platform.startswith('darwin')
|
|
|
def GetSHA1HexDigest(contents):
|
@@ -500,16 +424,16 @@ def GetZipFileName(build_revision=None, target_arch='ia32', patch_sha=None):
|
"""Gets the archive file name for the given revision."""
|
def PlatformName():
|
"""Return a string to be used in paths for the platform."""
|
- if IsWindowsHost():
|
+ if bisect_utils.IsWindowsHost():
|
# Build archive for x64 is still stored with 'win32'suffix
|
# (chromium_utils.PlatformName()).
|
- if Is64BitWindows() and target_arch == 'x64':
|
+ if bisect_utils.Is64BitWindows() and target_arch == 'x64':
|
return 'win32'
|
return 'win32'
|
- if IsLinuxHost():
|
+ if bisect_utils.IsLinuxHost():
|
# Android builds too are archived with full-build-linux* prefix.
|
return 'linux'
|
- if IsMacHost():
|
+ if bisect_utils.IsMacHost():
|
return 'mac'
|
raise NotImplementedError('Unknown platform "%s".' % sys.platform)
|
|
@@ -526,15 +450,15 @@ def GetRemoteBuildPath(build_revision, target_platform='chromium',
|
"""Compute the url to download the build from."""
|
def GetGSRootFolderName(target_platform):
|
"""Gets Google Cloud Storage root folder names"""
|
- if IsWindowsHost():
|
- if Is64BitWindows() and target_arch == 'x64':
|
+ if bisect_utils.IsWindowsHost():
|
+ if bisect_utils.Is64BitWindows() and target_arch == 'x64':
|
return 'Win x64 Builder'
|
return 'Win Builder'
|
- if IsLinuxHost():
|
+ if bisect_utils.IsLinuxHost():
|
if target_platform == 'android':
|
return 'android_perf_rel'
|
return 'Linux Builder'
|
- if IsMacHost():
|
+ if bisect_utils.IsMacHost():
|
return 'Mac Builder'
|
raise NotImplementedError('Unsupported Platform "%s".' % sys.platform)
|
|
@@ -600,10 +524,12 @@ def ExtractZip(filename, output_dir, verbose=True):
|
# On Windows, try to use 7z if it is installed, otherwise fall back to python
|
# zip module and pray we don't have files larger than 512MB to unzip.
|
unzip_cmd = None
|
- if ((IsMacHost() and os.path.getsize(filename) < 4 * 1024 * 1024 * 1024)
|
- or IsLinuxHost()):
|
+ if ((bisect_utils.IsMacHost()
|
+ and os.path.getsize(filename) < 4 * 1024 * 1024 * 1024)
|
+ or bisect_utils.IsLinuxHost()):
|
unzip_cmd = ['unzip', '-o']
|
- elif IsWindowsHost() and os.path.exists('C:\\Program Files\\7-Zip\\7z.exe'):
|
+ elif (bisect_utils.IsWindowsHost()
|
+ and os.path.exists('C:\\Program Files\\7-Zip\\7z.exe')):
|
unzip_cmd = ['C:\\Program Files\\7-Zip\\7z.exe', 'x', '-y']
|
|
if unzip_cmd:
|
@@ -612,100 +538,23 @@ def ExtractZip(filename, output_dir, verbose=True):
|
saved_dir = os.getcwd()
|
os.chdir(output_dir)
|
command = unzip_cmd + [filepath]
|
- result = RunProcess(command)
|
+ result = bisect_utils.RunProcess(command)
|
os.chdir(saved_dir)
|
if result:
|
raise IOError('unzip failed: %s => %s' % (str(command), result))
|
else:
|
- assert IsWindowsHost() or IsMacHost()
|
+ assert bisect_utils.IsWindowsHost() or bisect_utils.IsMacHost()
|
zf = zipfile.ZipFile(filename)
|
for name in zf.namelist():
|
if verbose:
|
print 'Extracting %s' % name
|
zf.extract(name, output_dir)
|
- if IsMacHost():
|
+ if bisect_utils.IsMacHost():
|
# Restore permission bits.
|
os.chmod(os.path.join(output_dir, name),
|
zf.getinfo(name).external_attr >> 16L)
|
|
|
-def RunProcess(command):
|
- """Runs an arbitrary command.
|
-
|
- If output from the call is needed, use RunProcessAndRetrieveOutput instead.
|
-
|
- Args:
|
- command: A list containing the command and args to execute.
|
-
|
- Returns:
|
- The return code of the call.
|
- """
|
- # On Windows, use shell=True to get PATH interpretation.
|
- shell = IsWindowsHost()
|
- return subprocess.call(command, shell=shell)
|
-
|
-
|
-def RunProcessAndRetrieveOutput(command, cwd=None):
|
- """Runs an arbitrary command, returning its output and return code.
|
-
|
- Since output is collected via communicate(), there will be no output until
|
- the call terminates. If you need output while the program runs (ie. so
|
- that the buildbot doesn't terminate the script), consider RunProcess().
|
-
|
- Args:
|
- command: A list containing the command and args to execute.
|
- cwd: A directory to change to while running the command. The command can be
|
- relative to this directory. If this is None, the command will be run in
|
- the current directory.
|
-
|
- Returns:
|
- A tuple of the output and return code.
|
- """
|
- if cwd:
|
- original_cwd = os.getcwd()
|
- os.chdir(cwd)
|
-
|
- # On Windows, use shell=True to get PATH interpretation.
|
- shell = IsWindowsHost()
|
- proc = subprocess.Popen(command, shell=shell, stdout=subprocess.PIPE)
|
- (output, _) = proc.communicate()
|
-
|
- if cwd:
|
- os.chdir(original_cwd)
|
-
|
- return (output, proc.returncode)
|
-
|
-
|
-def RunGit(command, cwd=None):
|
- """Run a git subcommand, returning its output and return code.
|
-
|
- Args:
|
- command: A list containing the args to git.
|
- cwd: A directory to change to while running the git command (optional).
|
-
|
- Returns:
|
- A tuple of the output and return code.
|
- """
|
- command = ['git'] + command
|
-
|
- return RunProcessAndRetrieveOutput(command, cwd=cwd)
|
-
|
-
|
-def CheckRunGit(command, cwd=None):
|
- """Run a git subcommand, returning its output and return code. Asserts if
|
- the return code of the call is non-zero.
|
-
|
- Args:
|
- command: A list containing the args to git.
|
-
|
- Returns:
|
- A tuple of the output and return code.
|
- """
|
- (output, return_code) = RunGit(command, cwd=cwd)
|
-
|
- assert not return_code, 'An error occurred while running'\
|
- ' "git %s"' % ' '.join(command)
|
- return output
|
|
|
def SetBuildSystemDefault(build_system, use_goma, goma_dir):
|
@@ -724,7 +573,7 @@ def SetBuildSystemDefault(build_system, use_goma, goma_dir):
|
else:
|
os.environ['GYP_GENERATORS'] = 'ninja'
|
|
- if IsWindowsHost():
|
+ if bisect_utils.IsWindowsHost():
|
os.environ['GYP_DEFINES'] = 'component=shared_library '\
|
'incremental_chrome_dll=1 disable_nacl=1 fastbuild=1 '\
|
'chromium_win_pch=0'
|
@@ -749,7 +598,7 @@ def BuildWithMake(threads, targets, build_type='Release'):
|
|
cmd += targets
|
|
- return_code = RunProcess(cmd)
|
+ return_code = bisect_utils.RunProcess(cmd)
|
|
return not return_code
|
|
@@ -762,7 +611,7 @@ def BuildWithNinja(threads, targets, build_type='Release'):
|
|
cmd += targets
|
|
- return_code = RunProcess(cmd)
|
+ return_code = bisect_utils.RunProcess(cmd)
|
|
return not return_code
|
|
@@ -776,7 +625,7 @@ def BuildWithVisualStudio(targets, build_type='Release'):
|
for t in targets:
|
cmd.extend(['/Project', t])
|
|
- return_code = RunProcess(cmd)
|
+ return_code = bisect_utils.RunProcess(cmd)
|
|
return not return_code
|
|
@@ -818,7 +667,7 @@ class Builder(object):
|
Args:
|
opts: Options parsed from command line.
|
"""
|
- if IsWindowsHost():
|
+ if bisect_utils.IsWindowsHost():
|
if not opts.build_preference:
|
opts.build_preference = 'msvs'
|
|
@@ -863,11 +712,11 @@ class Builder(object):
|
Assumes that the current working directory is the checkout root.
|
"""
|
src_dir = src_dir or 'src'
|
- if opts.build_preference == 'ninja' or IsLinuxHost():
|
+ if opts.build_preference == 'ninja' or bisect_utils.IsLinuxHost():
|
return os.path.join(src_dir, 'out')
|
- if IsMacHost():
|
+ if bisect_utils.IsMacHost():
|
return os.path.join(src_dir, 'xcodebuild')
|
- if IsWindowsHost():
|
+ if bisect_utils.IsWindowsHost():
|
return os.path.join(src_dir, 'build')
|
raise NotImplementedError('Unexpected platform %s' % sys.platform)
|
|
@@ -900,7 +749,7 @@ class DesktopBuilder(Builder):
|
elif opts.build_preference == 'ninja':
|
build_success = BuildWithNinja(threads, targets, opts.target_build_type)
|
elif opts.build_preference == 'msvs':
|
- assert IsWindowsHost(), 'msvs is only supported on Windows.'
|
+ assert bisect_utils.IsWindowsHost(), 'msvs is only supported on Windows.'
|
build_success = BuildWithVisualStudio(targets, opts.target_build_type)
|
else:
|
assert False, 'No build system defined.'
|
@@ -972,7 +821,7 @@ class CrosBuilder(Builder):
|
'--remote=%s' % opts.cros_remote_ip,
|
'--board=%s' % opts.cros_board, '--test', '--verbose']
|
|
- return_code = RunProcess(cmd)
|
+ return_code = bisect_utils.RunProcess(cmd)
|
return not return_code
|
except OSError, e:
|
return False
|
@@ -1000,7 +849,7 @@ class CrosBuilder(Builder):
|
|
cmd += ['BUILDTYPE=%s' % opts.target_build_type, './build_packages',
|
'--board=%s' % opts.cros_board]
|
- return_code = RunProcess(cmd)
|
+ return_code = bisect_utils.RunProcess(cmd)
|
|
return not return_code
|
|
@@ -1028,7 +877,7 @@ class CrosBuilder(Builder):
|
cmd += ['BUILDTYPE=%s' % opts.target_build_type, '--', './build_image',
|
'--board=%s' % opts.cros_board, 'test']
|
|
- return_code = RunProcess(cmd)
|
+ return_code = bisect_utils.RunProcess(cmd)
|
|
return not return_code
|
|
@@ -1048,261 +897,6 @@ class CrosBuilder(Builder):
|
return False
|
|
|
-class SourceControl(object):
|
- """SourceControl is an abstraction over the underlying source control
|
- system used for chromium. For now only git is supported, but in the
|
- future, the svn workflow could be added as well."""
|
- def __init__(self):
|
- super(SourceControl, self).__init__()
|
-
|
- def SyncToRevisionWithGClient(self, revision):
|
- """Uses gclient to sync to the specified revision.
|
-
|
- ie. gclient sync --revision <revision>
|
-
|
- Args:
|
- revision: The git SHA1 or svn CL (depending on workflow).
|
-
|
- Returns:
|
- The return code of the call.
|
- """
|
- return bisect_utils.RunGClient(['sync', '--verbose', '--reset', '--force',
|
- '--delete_unversioned_trees', '--nohooks', '--revision', revision])
|
-
|
- def SyncToRevisionWithRepo(self, timestamp):
|
- """Uses repo to sync all the underlying git depots to the specified
|
- time.
|
-
|
- Args:
|
- timestamp: The unix timestamp to sync to.
|
-
|
- Returns:
|
- The return code of the call.
|
- """
|
- return bisect_utils.RunRepoSyncAtTimestamp(timestamp)
|
-
|
-
|
-class GitSourceControl(SourceControl):
|
- """GitSourceControl is used to query the underlying source control. """
|
- def __init__(self, opts):
|
- super(GitSourceControl, self).__init__()
|
- self.opts = opts
|
-
|
- def IsGit(self):
|
- return True
|
-
|
- def GetRevisionList(self, revision_range_end, revision_range_start, cwd=None):
|
- """Retrieves a list of revisions between |revision_range_start| and
|
- |revision_range_end|.
|
-
|
- Args:
|
- revision_range_end: The SHA1 for the end of the range.
|
- revision_range_start: The SHA1 for the beginning of the range.
|
-
|
- Returns:
|
- A list of the revisions between |revision_range_start| and
|
- |revision_range_end| (inclusive).
|
- """
|
- revision_range = '%s..%s' % (revision_range_start, revision_range_end)
|
- cmd = ['log', '--format=%H', '-10000', '--first-parent', revision_range]
|
- log_output = CheckRunGit(cmd, cwd=cwd)
|
-
|
- revision_hash_list = log_output.split()
|
- revision_hash_list.append(revision_range_start)
|
-
|
- return revision_hash_list
|
-
|
- def SyncToRevision(self, revision, sync_client=None):
|
- """Syncs to the specified revision.
|
-
|
- Args:
|
- revision: The revision to sync to.
|
- use_gclient: Specifies whether or not we should sync using gclient or
|
- just use source control directly.
|
-
|
- Returns:
|
- True if successful.
|
- """
|
-
|
- if not sync_client:
|
- results = RunGit(['checkout', revision])[1]
|
- elif sync_client == 'gclient':
|
- results = self.SyncToRevisionWithGClient(revision)
|
- elif sync_client == 'repo':
|
- results = self.SyncToRevisionWithRepo(revision)
|
-
|
- return not results
|
-
|
- def ResolveToRevision(self, revision_to_check, depot, search, cwd=None):
|
- """If an SVN revision is supplied, try to resolve it to a git SHA1.
|
-
|
- Args:
|
- revision_to_check: The user supplied revision string that may need to be
|
- resolved to a git SHA1.
|
- depot: The depot the revision_to_check is from.
|
- search: The number of changelists to try if the first fails to resolve
|
- to a git hash. If the value is negative, the function will search
|
- backwards chronologically, otherwise it will search forward.
|
-
|
- Returns:
|
- A string containing a git SHA1 hash, otherwise None.
|
- """
|
- # Android-chrome is git only, so no need to resolve this to anything else.
|
- if depot == 'android-chrome':
|
- return revision_to_check
|
-
|
- if depot != 'cros':
|
- if not IsStringInt(revision_to_check):
|
- return revision_to_check
|
-
|
- depot_svn = 'svn://svn.chromium.org/chrome/trunk/src'
|
-
|
- if depot != 'chromium':
|
- depot_svn = DEPOT_DEPS_NAME[depot]['svn']
|
-
|
- svn_revision = int(revision_to_check)
|
- git_revision = None
|
-
|
- if search > 0:
|
- search_range = xrange(svn_revision, svn_revision + search, 1)
|
- else:
|
- search_range = xrange(svn_revision, svn_revision + search, -1)
|
-
|
- for i in search_range:
|
- svn_pattern = 'git-svn-id: %s@%d' % (depot_svn, i)
|
- cmd = ['log', '--format=%H', '-1', '--grep', svn_pattern,
|
- 'origin/master']
|
-
|
- (log_output, return_code) = RunGit(cmd, cwd=cwd)
|
-
|
- assert not return_code, 'An error occurred while running'\
|
- ' "git %s"' % ' '.join(cmd)
|
-
|
- if not return_code:
|
- log_output = log_output.strip()
|
-
|
- if log_output:
|
- git_revision = log_output
|
-
|
- break
|
-
|
- return git_revision
|
- else:
|
- if IsStringInt(revision_to_check):
|
- return int(revision_to_check)
|
- else:
|
- cwd = os.getcwd()
|
- os.chdir(os.path.join(os.getcwd(), 'src', 'third_party',
|
- 'chromiumos-overlay'))
|
- pattern = CROS_VERSION_PATTERN % revision_to_check
|
- cmd = ['log', '--format=%ct', '-1', '--grep', pattern]
|
-
|
- git_revision = None
|
-
|
- log_output = CheckRunGit(cmd, cwd=cwd)
|
- if log_output:
|
- git_revision = log_output
|
- git_revision = int(log_output.strip())
|
- os.chdir(cwd)
|
-
|
- return git_revision
|
-
|
- def IsInProperBranch(self):
|
- """Confirms they're in the master branch for performing the bisection.
|
- This is needed or gclient will fail to sync properly.
|
-
|
- Returns:
|
- True if the current branch on src is 'master'
|
- """
|
- cmd = ['rev-parse', '--abbrev-ref', 'HEAD']
|
- log_output = CheckRunGit(cmd)
|
- log_output = log_output.strip()
|
-
|
- return log_output == "master"
|
-
|
- def SVNFindRev(self, revision, cwd=None):
|
- """Maps directly to the 'git svn find-rev' command.
|
-
|
- Args:
|
- revision: The git SHA1 to use.
|
-
|
- Returns:
|
- An integer changelist #, otherwise None.
|
- """
|
-
|
- cmd = ['svn', 'find-rev', revision]
|
-
|
- output = CheckRunGit(cmd, cwd)
|
- svn_revision = output.strip()
|
-
|
- if IsStringInt(svn_revision):
|
- return int(svn_revision)
|
-
|
- return None
|
-
|
- def QueryRevisionInfo(self, revision, cwd=None):
|
- """Gathers information on a particular revision, such as author's name,
|
- email, subject, and date.
|
-
|
- Args:
|
- revision: Revision you want to gather information on.
|
- Returns:
|
- A dict in the following format:
|
- {
|
- 'author': %s,
|
- 'email': %s,
|
- 'date': %s,
|
- 'subject': %s,
|
- 'body': %s,
|
- }
|
- """
|
- commit_info = {}
|
-
|
- formats = ['%cN', '%cE', '%s', '%cD', '%b']
|
- targets = ['author', 'email', 'subject', 'date', 'body']
|
-
|
- for i in xrange(len(formats)):
|
- cmd = ['log', '--format=%s' % formats[i], '-1', revision]
|
- output = CheckRunGit(cmd, cwd=cwd)
|
- commit_info[targets[i]] = output.rstrip()
|
-
|
- return commit_info
|
-
|
- def CheckoutFileAtRevision(self, file_name, revision, cwd=None):
|
- """Performs a checkout on a file at the given revision.
|
-
|
- Returns:
|
- True if successful.
|
- """
|
- return not RunGit(['checkout', revision, file_name], cwd=cwd)[1]
|
-
|
- def RevertFileToHead(self, file_name):
|
- """Unstages a file and returns it to HEAD.
|
-
|
- Returns:
|
- True if successful.
|
- """
|
- # Reset doesn't seem to return 0 on success.
|
- RunGit(['reset', 'HEAD', file_name])
|
-
|
- return not RunGit(['checkout', bisect_utils.FILE_DEPS_GIT])[1]
|
-
|
- def QueryFileRevisionHistory(self, filename, revision_start, revision_end):
|
- """Returns a list of commits that modified this file.
|
-
|
- Args:
|
- filename: Name of file.
|
- revision_start: Start of revision range.
|
- revision_end: End of revision range.
|
-
|
- Returns:
|
- Returns a list of commits that touched this file.
|
- """
|
- cmd = ['log', '--format=%H', '%s~1..%s' % (revision_start, revision_end),
|
- filename]
|
- output = CheckRunGit(cmd)
|
-
|
- return [o for o in output.split('\n') if o]
|
|
|
class BisectPerformanceMetrics(object):
|
@@ -1363,7 +957,7 @@ class BisectPerformanceMetrics(object):
|
cmd = ['repo', 'forall', '-c',
|
'git log --format=%%ct --before=%d --after=%d' % (
|
revision_range_end, revision_range_start)]
|
- (output, return_code) = RunProcessAndRetrieveOutput(cmd)
|
+ (output, return_code) = bisect_utils.RunProcessAndRetrieveOutput(cmd)
|
|
assert not return_code, 'An error occurred while running'\
|
' "%s"' % ' '.join(cmd)
|
@@ -1371,7 +965,7 @@ class BisectPerformanceMetrics(object):
|
os.chdir(cwd)
|
|
revision_work_list = list(set(
|
- [int(o) for o in output.split('\n') if IsStringInt(o)]))
|
+ [int(o) for o in output.split('\n') if bisect_utils.IsStringInt(o)]))
|
revision_work_list = sorted(revision_work_list, reverse=True)
|
else:
|
cwd = self._GetDepotDirectory(depot)
|
@@ -1383,7 +977,7 @@ class BisectPerformanceMetrics(object):
|
def _GetV8BleedingEdgeFromV8TrunkIfMappable(self, revision):
|
svn_revision = self.source_control.SVNFindRev(revision)
|
|
- if IsStringInt(svn_revision):
|
+ if bisect_utils.IsStringInt(svn_revision):
|
# V8 is tricky to bisect, in that there are only a few instances when
|
# we can dive into bleeding_edge and get back a meaningful result.
|
# Try to detect a V8 "business as usual" case, which is when:
|
@@ -1414,7 +1008,7 @@ class BisectPerformanceMetrics(object):
|
'bleeding_edge revision r')[1]
|
bleeding_edge_revision = int(bleeding_edge_revision.split(')')[0])
|
git_revision = self.source_control.ResolveToRevision(
|
- bleeding_edge_revision, 'v8_bleeding_edge', 1,
|
+ bleeding_edge_revision, 'v8_bleeding_edge', DEPOT_DEPS_NAME, 1,
|
cwd=v8_bleeding_edge_dir)
|
return git_revision
|
except (IndexError, ValueError):
|
@@ -1423,7 +1017,7 @@ class BisectPerformanceMetrics(object):
|
if not git_revision:
|
# Wasn't successful, try the old way of looking for "Prepare push to"
|
git_revision = self.source_control.ResolveToRevision(
|
- int(svn_revision) - 1, 'v8_bleeding_edge', -1,
|
+ int(svn_revision) - 1, 'v8_bleeding_edge', DEPOT_DEPS_NAME, -1,
|
cwd=v8_bleeding_edge_dir)
|
|
if git_revision:
|
@@ -1437,21 +1031,21 @@ class BisectPerformanceMetrics(object):
|
def _GetNearestV8BleedingEdgeFromTrunk(self, revision, search_forward=True):
|
cwd = self._GetDepotDirectory('v8')
|
cmd = ['log', '--format=%ct', '-1', revision]
|
- output = CheckRunGit(cmd, cwd=cwd)
|
+ output = bisect_utils.CheckRunGit(cmd, cwd=cwd)
|
commit_time = int(output)
|
commits = []
|
|
if search_forward:
|
cmd = ['log', '--format=%H', '-10', '--after=%d' % commit_time,
|
'origin/master']
|
- output = CheckRunGit(cmd, cwd=cwd)
|
+ output = bisect_utils.CheckRunGit(cmd, cwd=cwd)
|
output = output.split()
|
commits = output
|
commits = reversed(commits)
|
else:
|
cmd = ['log', '--format=%H', '-10', '--before=%d' % commit_time,
|
'origin/master']
|
- output = CheckRunGit(cmd, cwd=cwd)
|
+ output = bisect_utils.CheckRunGit(cmd, cwd=cwd)
|
output = output.split()
|
commits = output
|
|
@@ -1564,7 +1158,7 @@ class BisectPerformanceMetrics(object):
|
cmd = [CROS_SDK_PATH, '--', 'portageq-%s' % self.opts.cros_board,
|
'best_visible', '/build/%s' % self.opts.cros_board, 'ebuild',
|
CROS_CHROMEOS_PATTERN]
|
- (output, return_code) = RunProcessAndRetrieveOutput(cmd)
|
+ (output, return_code) = bisect_utils.RunProcessAndRetrieveOutput(cmd)
|
|
assert not return_code, 'An error occurred while running' \
|
' "%s"' % ' '.join(cmd)
|
@@ -1588,9 +1182,10 @@ class BisectPerformanceMetrics(object):
|
|
cwd = os.getcwd()
|
self.ChangeToDepotWorkingDirectory('chromium')
|
- return_code = CheckRunGit(['log', '-1', '--format=%H',
|
- '--author=chrome-release@google.com', '--grep=to %s' % version,
|
- 'origin/master'])
|
+ cmd = ['log', '-1', '--format=%H',
|
+ '--author=chrome-release@google.com',
|
+ '--grep=to %s' % version, 'origin/master']
|
+ return_code = bisect_utils.CheckRunGit(cmd)
|
os.chdir(cwd)
|
|
results['chromium'] = output.strip()
|
@@ -1804,15 +1399,15 @@ class BisectPerformanceMetrics(object):
|
"""Gets builder bot name and buildtime in seconds based on platform."""
|
# Bot names should match the one listed in tryserver.chromium's
|
# master.cfg which produces builds for bisect.
|
- if IsWindowsHost():
|
- if Is64BitWindows() and target_arch == 'x64':
|
+ if bisect_utils.IsWindowsHost():
|
+ if bisect_utils.Is64BitWindows() and target_arch == 'x64':
|
return ('win_perf_bisect_builder', MAX_WIN_BUILD_TIME)
|
return ('win_perf_bisect_builder', MAX_WIN_BUILD_TIME)
|
- if IsLinuxHost():
|
+ if bisect_utils.IsLinuxHost():
|
if target_platform == 'android':
|
return ('android_perf_bisect_builder', MAX_LINUX_BUILD_TIME)
|
return ('linux_perf_bisect_builder', MAX_LINUX_BUILD_TIME)
|
- if IsMacHost():
|
+ if bisect_utils.IsMacHost():
|
return ('mac_perf_bisect_builder', MAX_MAC_BUILD_TIME)
|
raise NotImplementedError('Unsupported Platform "%s".' % sys.platform)
|
if not fetch_build:
|
@@ -2008,7 +1603,8 @@ class BisectPerformanceMetrics(object):
|
if not os.path.exists(deps_file_path):
|
raise RuntimeError('DEPS file does not exists.[%s]' % deps_file_path)
|
# Get current chromium revision (git hash).
|
- chromium_sha = CheckRunGit(['rev-parse', 'HEAD']).strip()
|
+ cmd = ['rev-parse', 'HEAD']
|
+ chromium_sha = bisect_utils.CheckRunGit(cmd).strip()
|
if not chromium_sha:
|
raise RuntimeError('Failed to determine Chromium revision for %s' %
|
revision)
|
@@ -2024,7 +1620,8 @@ class BisectPerformanceMetrics(object):
|
'--dst-prefix=src/',
|
'--no-ext-diff',
|
bisect_utils.FILE_DEPS]
|
- diff_text = CheckRunGit(diff_command, cwd=self.src_cwd)
|
+ diff_text = bisect_utils.CheckRunGit(
|
+ diff_command, cwd=self.src_cwd)
|
return (chromium_sha, ChangeBackslashToSlashInPatch(diff_text))
|
else:
|
raise RuntimeError('Failed to update DEPS file for chromium: [%s]' %
|
@@ -2157,7 +1754,8 @@ class BisectPerformanceMetrics(object):
|
mean_stddev_match.group('MEAN')):
|
values_list += [mean_stddev_match.group('MEAN')]
|
|
- values_list = [float(v) for v in values_list if IsStringFloat(v)]
|
+ values_list = [float(v) for v in values_list
|
+ if bisect_utils.IsStringFloat(v)]
|
|
# If the metric is times/t, we need to sum the timings in order to get
|
# similar regression results as the try-bots.
|
@@ -2221,7 +1819,7 @@ class BisectPerformanceMetrics(object):
|
|
if arg_dict.has_key('--profile-dir') and arg_dict.has_key('--browser'):
|
profile_path, profile_type = os.path.split(arg_dict['--profile-dir'])
|
- return not RunProcess(['python', path_to_generate,
|
+ return not bisect_utils.RunProcess(['python', path_to_generate,
|
'--profile-type-to-generate', profile_type,
|
'--browser', arg_dict['--browser'], '--output-dir', profile_path])
|
return False
|
@@ -2245,13 +1843,14 @@ class BisectPerformanceMetrics(object):
|
if self.opts.target_platform in ['android']:
|
# When its a third_party depot, get the chromium revision.
|
if depot != 'chromium':
|
- revision = CheckRunGit(['rev-parse', 'HEAD'], cwd=self.src_cwd).strip()
|
+ revision = bisect_utils.CheckRunGit(
|
+ ['rev-parse', 'HEAD'], cwd=self.src_cwd).strip()
|
svn_revision = self.source_control.SVNFindRev(revision, cwd=self.src_cwd)
|
if not svn_revision:
|
return command_to_run
|
cmd_re = re.compile('--browser=(?P<browser_type>\S+)')
|
matches = cmd_re.search(command_to_run)
|
- if IsStringInt(svn_revision) and matches:
|
+ if bisect_utils.IsStringInt(svn_revision) and matches:
|
cmd_browser = matches.group('browser_type')
|
if svn_revision <= 274857 and cmd_browser == 'android-chrome-shell':
|
return command_to_run.replace(cmd_browser,
|
@@ -2297,7 +1896,7 @@ class BisectPerformanceMetrics(object):
|
# For Windows platform set posix=False, to parse windows paths correctly.
|
# On Windows, path separators '\' or '\\' are replace by '' when posix=True,
|
# refer to http://bugs.python.org/issue1724822. By default posix=True.
|
- args = shlex.split(command_to_run, posix=not IsWindowsHost())
|
+ args = shlex.split(command_to_run, posix=not bisect_utils.IsWindowsHost())
|
|
if not self._GenerateProfileIfNecessary(args):
|
err_text = 'Failed to generate profile for performance test.'
|
@@ -2325,8 +1924,8 @@ class BisectPerformanceMetrics(object):
|
if results_label:
|
current_args.append('--results-label=%s' % results_label)
|
try:
|
- (output, return_code) = RunProcessAndRetrieveOutput(current_args,
|
- cwd=self.src_cwd)
|
+ (output, return_code) = bisect_utils.RunProcessAndRetrieveOutput(
|
+ current_args, cwd=self.src_cwd)
|
except OSError, e:
|
if e.errno == errno.ENOENT:
|
err_text = ('Something went wrong running the performance test. '
|
@@ -2435,7 +2034,8 @@ class BisectPerformanceMetrics(object):
|
for d in DEPOT_DEPS_NAME[depot]['depends']:
|
self.ChangeToDepotWorkingDirectory(d)
|
|
- dependant_rev = self.source_control.ResolveToRevision(svn_rev, d, -1000)
|
+ dependant_rev = self.source_control.ResolveToRevision(
|
+ svn_rev, d, DEPOT_DEPS_NAME, -1000)
|
|
if dependant_rev:
|
revisions_to_sync.append([d, dependant_rev])
|
@@ -2501,7 +2101,7 @@ class BisectPerformanceMetrics(object):
|
cwd = os.getcwd()
|
self.ChangeToDepotWorkingDirectory('cros')
|
cmd = [CROS_SDK_PATH, '--delete']
|
- return_code = RunProcess(cmd)
|
+ return_code = bisect_utils.RunProcess(cmd)
|
os.chdir(cwd)
|
return not return_code
|
|
@@ -2514,7 +2114,7 @@ class BisectPerformanceMetrics(object):
|
cwd = os.getcwd()
|
self.ChangeToDepotWorkingDirectory('cros')
|
cmd = [CROS_SDK_PATH, '--create']
|
- return_code = RunProcess(cmd)
|
+ return_code = bisect_utils.RunProcess(cmd)
|
os.chdir(cwd)
|
return not return_code
|
|
@@ -2574,7 +2174,7 @@ class BisectPerformanceMetrics(object):
|
if depot == 'chromium':
|
if self.source_control.IsGit():
|
cmd = ['diff-tree', '--no-commit-id', '--name-only', '-r', revision]
|
- output = CheckRunGit(cmd)
|
+ output = bisect_utils.CheckRunGit(cmd)
|
|
files = output.splitlines()
|
|
@@ -2931,7 +2531,7 @@ class BisectPerformanceMetrics(object):
|
if len(changes_to_deps) != len(changes_to_gitdeps):
|
# Grab the timestamp of the last DEPS change
|
cmd = ['log', '--format=%ct', '-1', changes_to_deps[0]]
|
- output = CheckRunGit(cmd)
|
+ output = bisect_utils.CheckRunGit(cmd)
|
commit_time = int(output)
|
|
# Try looking for a commit that touches the .DEPS.git file in the
|
@@ -2939,7 +2539,7 @@ class BisectPerformanceMetrics(object):
|
cmd = ['log', '--format=%H', '-1',
|
'--before=%d' % (commit_time + 900), '--after=%d' % commit_time,
|
'origin/master', bisect_utils.FILE_DEPS_GIT]
|
- output = CheckRunGit(cmd)
|
+ output = bisect_utils.CheckRunGit(cmd)
|
output = output.strip()
|
if output:
|
self.warnings.append('Detected change to DEPS and modified '
|
@@ -2967,11 +2567,11 @@ class BisectPerformanceMetrics(object):
|
cmd = ['log', '--format=%ct', '-1', good_revision]
|
cwd = self._GetDepotDirectory(target_depot)
|
|
- output = CheckRunGit(cmd, cwd=cwd)
|
+ output = bisect_utils.CheckRunGit(cmd, cwd=cwd)
|
good_commit_time = int(output)
|
|
cmd = ['log', '--format=%ct', '-1', bad_revision]
|
- output = CheckRunGit(cmd, cwd=cwd)
|
+ output = bisect_utils.CheckRunGit(cmd, cwd=cwd)
|
bad_commit_time = int(output)
|
|
return good_commit_time <= bad_commit_time
|
@@ -2994,7 +2594,8 @@ class BisectPerformanceMetrics(object):
|
"""
|
if self.opts.target_platform == 'android':
|
revision_to_check = self.source_control.SVNFindRev(revision_to_check)
|
- if IsStringInt(revision_to_check) and revision_to_check < 265549:
|
+ if (bisect_utils.IsStringInt(revision_to_check)
|
+ and revision_to_check < 265549):
|
return {'error': (
|
'Bisect cannot conitnue for the given revision range.\n'
|
'It is impossible to bisect Android regressions '
|
@@ -3061,10 +2662,10 @@ class BisectPerformanceMetrics(object):
|
self.ChangeToDepotWorkingDirectory(target_depot)
|
|
# If they passed SVN CL's, etc... we can try match them to git SHA1's.
|
- bad_revision = self.source_control.ResolveToRevision(bad_revision_in,
|
- target_depot, 100)
|
- good_revision = self.source_control.ResolveToRevision(good_revision_in,
|
- target_depot, -100)
|
+ bad_revision = self.source_control.ResolveToRevision(
|
+ bad_revision_in, target_depot, DEPOT_DEPS_NAME, 100)
|
+ good_revision = self.source_control.ResolveToRevision(
|
+ good_revision_in, target_depot, DEPOT_DEPS_NAME, -100)
|
|
os.chdir(cwd)
|
|
@@ -3656,7 +3257,7 @@ class BisectPerformanceMetrics(object):
|
cmd = ['repo', 'forall', '-c',
|
'pwd ; git log --pretty=oneline --before=%d --after=%d' % (
|
last_broken_revision, first_working_revision + 1)]
|
- (output, return_code) = RunProcessAndRetrieveOutput(cmd)
|
+ (output, return_code) = bisect_utils.RunProcessAndRetrieveOutput(cmd)
|
|
changes = []
|
assert not return_code, 'An error occurred while running'\
|
@@ -3784,23 +3385,6 @@ class BisectPerformanceMetrics(object):
|
bisect_utils.OutputAnnotationStepClosed()
|
|
|
-def DetermineAndCreateSourceControl(opts):
|
- """Attempts to determine the underlying source control workflow and returns
|
- a SourceControl object.
|
-
|
- Returns:
|
- An instance of a SourceControl object, or None if the current workflow
|
- is unsupported.
|
- """
|
-
|
- (output, _) = RunGit(['rev-parse', '--is-inside-work-tree'])
|
-
|
- if output.strip() == 'true':
|
- return GitSourceControl(opts)
|
-
|
- return None
|
-
|
-
|
def IsPlatformSupported(opts):
|
"""Checks that this platform and build system are supported.
|
|
@@ -4064,7 +3648,7 @@ class BisectOptions(object):
|
# Run sudo up front to make sure credentials are cached for later.
|
print 'Sudo is required to build cros:'
|
print
|
- RunProcess(['sudo', 'true'])
|
+ bisect_utils.RunProcess(['sudo', 'true'])
|
|
if not opts.cros_board:
|
raise RuntimeError('missing required parameter: --cros_board')
|
@@ -4152,9 +3736,9 @@ def main():
|
if not IsPlatformSupported(opts):
|
raise RuntimeError("Sorry, this platform isn't supported yet.")
|
|
- # Check what source control method they're using. Only support git workflow
|
- # at the moment.
|
- source_control = DetermineAndCreateSourceControl(opts)
|
+ # Check what source control method is being used, and create a
|
+ # SourceControl object if possible.
|
+ source_control = source_control_module.DetermineAndCreateSourceControl(opts)
|
|
if not source_control:
|
raise RuntimeError("Sorry, only the git workflow is supported at the "
|
|