| Index: tools/bisect-perf-regression.py
|
| diff --git a/tools/bisect-perf-regression.py b/tools/bisect-perf-regression.py
|
| index 2db8c8d66e068575c059bf467fca071855385a86..7444d3700321c08f42f489157f561cf8e9f6836f 100755
|
| --- a/tools/bisect-perf-regression.py
|
| +++ b/tools/bisect-perf-regression.py
|
| @@ -54,7 +54,7 @@ import zipfile
|
| sys.path.append(os.path.join(os.path.dirname(__file__), 'telemetry'))
|
|
|
| import bisect_utils
|
| -import post_perf_builder_job
|
| +import post_perf_builder_job as bisect_builder
|
| from telemetry.page import cloud_storage
|
|
|
| # The additional repositories that might need to be bisected.
|
| @@ -1584,7 +1584,7 @@ class BisectPerformanceMetrics(object):
|
|
|
| if not fetch_build_func():
|
| if not self.PostBuildRequestAndWait(revision,
|
| - condition=fetch_build_func,
|
| + fetch_build=fetch_build_func,
|
| patch=patch):
|
| raise RuntimeError('Somewthing went wrong while processing build'
|
| 'request for: %s' % revision)
|
| @@ -1616,7 +1616,59 @@ class BisectPerformanceMetrics(object):
|
| os.remove(downloaded_file)
|
| return False
|
|
|
| - def PostBuildRequestAndWait(self, revision, condition, patch=None):
|
| + def WaitUntilBuildIsReady(self, fetch_build, bot_name, builder_host,
|
| + builder_port, build_request_id, max_timeout):
|
| + """Waits until build is produced by bisect builder on tryserver.
|
| +
|
| + Args:
|
| + fetch_build: Function to check and download build from cloud storage.
|
| + bot_name: Builder bot name on tryserver.
|
| + builder_host Tryserver hostname.
|
| + builder_port: Tryserver port.
|
| + build_request_id: A unique ID of the build request posted to tryserver.
|
| + max_timeout: Maximum time to wait for the build.
|
| +
|
| + Returns:
|
| + True if build exists and download is successful, otherwise throws
|
| + RuntimeError exception when time elapse.
|
| + """
|
| + # Build number on the tryserver.
|
| + build_num = None
|
| + # Interval to check build on cloud storage.
|
| + poll_interval = 60
|
| + # Interval to check build status on tryserver.
|
| + status_check_interval = 600
|
| + last_status_check = time.time()
|
| + start_time = time.time()
|
| + while True:
|
| + # Checks for build on gs://chrome-perf and download if exists.
|
| + res = fetch_build()
|
| + if res:
|
| + return (res, 'Build successfully found')
|
| + elapsed_status_check = time.time() - last_status_check
|
| + # To avoid overloading tryserver with status check requests, we check
|
| + # build status for every 10 mins.
|
| + if elapsed_status_check > status_check_interval:
|
| + last_status_check = time.time()
|
| + if not build_num:
|
| + # Get the build number on tryserver for the current build.
|
| + build_num = bisect_builder.GetBuildNumFromBuilder(
|
| + build_request_id, bot_name, builder_host, builder_port)
|
| + # Check the status of build using the build number.
|
| + # Note: Build is treated as PENDING if build number is not found
|
| + # on the the tryserver.
|
| + build_status, status_link = bisect_builder.GetBuildStatus(
|
| + build_num, bot_name, builder_host, builder_port)
|
| + if build_status == bisect_builder.FAILED:
|
| + return (False, 'Failed to produce build, log: %s' % status_link)
|
| + elapsed_time = time.time() - start_time
|
| + if elapsed_time > max_timeout:
|
| + return (False, 'Timed out: %ss without build' % max_timeout)
|
| +
|
| + print 'Time elapsed: %ss without build.' % elapsed_time
|
| + time.sleep(poll_interval)
|
| +
|
| + def PostBuildRequestAndWait(self, revision, fetch_build, patch=None):
|
| """POSTs the build request job to the tryserver instance."""
|
|
|
| def GetBuilderNameAndBuildTime(target_arch='ia32'):
|
| @@ -1632,19 +1684,20 @@ class BisectPerformanceMetrics(object):
|
| if IsMac():
|
| return ('mac_perf_bisect_builder', MAX_MAC_BUILD_TIME)
|
| raise NotImplementedError('Unsupported Platform "%s".' % sys.platform)
|
| - if not condition:
|
| + if not fetch_build:
|
| return False
|
|
|
| bot_name, build_timeout = GetBuilderNameAndBuildTime(self.opts.target_arch)
|
| -
|
| - # Create a unique ID for each build request posted to try server builders.
|
| + builder_host = self.opts.builder_host
|
| + builder_port = self.opts.builder_port
|
| + # Create a unique ID for each build request posted to tryserver builders.
|
| # This ID is added to "Reason" property in build's json.
|
| - # TODO: Use this id to track the build status.
|
| - build_request_id = GetSHA1HexDigest('%s-%s' % (revision, patch))
|
| + build_request_id = GetSHA1HexDigest(
|
| + '%s-%s-%s' % (revision, patch, time.time()))
|
|
|
| # Creates a try job description.
|
| - job_args = {'host': self.opts.builder_host,
|
| - 'port': self.opts.builder_port,
|
| + job_args = {'host': builder_host,
|
| + 'port': builder_port,
|
| 'revision': 'src@%s' % revision,
|
| 'bot': bot_name,
|
| 'name': build_request_id
|
| @@ -1653,20 +1706,16 @@ class BisectPerformanceMetrics(object):
|
| if patch:
|
| job_args['patch'] = patch
|
| # Posts job to build the revision on the server.
|
| - if post_perf_builder_job.PostTryJob(job_args):
|
| - poll_interval = 60
|
| - start_time = time.time()
|
| - while True:
|
| - res = condition()
|
| - if res:
|
| - return res
|
| - elapsed_time = time.time() - start_time
|
| - if elapsed_time > build_timeout:
|
| - raise RuntimeError('Timed out while waiting %ds for %s build.' %
|
| - (build_timeout, revision))
|
| - print ('Time elapsed: %ss, still waiting for %s build' %
|
| - (elapsed_time, revision))
|
| - time.sleep(poll_interval)
|
| + if bisect_builder.PostTryJob(job_args):
|
| + status, error_msg = self.WaitUntilBuildIsReady(fetch_build,
|
| + bot_name,
|
| + builder_host,
|
| + builder_port,
|
| + build_request_id,
|
| + build_timeout)
|
| + if not status:
|
| + raise RuntimeError('%s [revision: %s]' % (error_msg, revision))
|
| + return True
|
| return False
|
|
|
| def IsDownloadable(self, depot):
|
|
|