diff options
author | tonyg@chromium.org <tonyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-05 13:43:55 +0000 |
---|---|---|
committer | tonyg@chromium.org <tonyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-05 13:43:55 +0000 |
commit | fdef2ba4d537537757ce6aa220a7c412bac59015 (patch) | |
tree | 6241a391473957fd606649d90484159498bb69d5 /tools | |
parent | eba1403a8a727ade5ac46ff51f9a0d3d29b069dc (diff) | |
download | chromium_src-fdef2ba4d537537757ce6aa220a7c412bac59015.zip chromium_src-fdef2ba4d537537757ce6aa220a7c412bac59015.tar.gz chromium_src-fdef2ba4d537537757ce6aa220a7c412bac59015.tar.bz2 |
[Telemetry] Fix image_decoding_measurement timeout.
util.WaitFor polls which is not appropriate for PerformActionAndWaitForNavigate.
Since DispatchNotifications blocks in recv until it gets some data, there is no
need to poll at an interval. Instead, we should call recv again as soon as
possible after dispatching a notification.
In the case of the image decoding measurement, it runs timeline recording. There
were so many timeline messages to receive that we were not always getting to the
important Page.navigate message before timing out.
Example:
http://build.chromium.org/p/chromium.perf/builders/Linux%20Perf%20%281%29/builds/27098
BUG=314375
Review URL: https://codereview.chromium.org/47013004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@232959 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools')
4 files changed, 28 insertions, 36 deletions
diff --git a/tools/telemetry/telemetry/core/backends/chrome/inspector_backend.py b/tools/telemetry/telemetry/core/backends/chrome/inspector_backend.py index 4770c4e..a680d86 100644 --- a/tools/telemetry/telemetry/core/backends/chrome/inspector_backend.py +++ b/tools/telemetry/telemetry/core/backends/chrome/inspector_backend.py @@ -256,7 +256,7 @@ class InspectorBackend(object): def IsBack(): return self._browser_backend.tab_list_backend.DoesDebuggerUrlExist( self._debugger_url) - util.WaitFor(IsBack, 512, 0.5) + util.WaitFor(IsBack, 512) sys.stderr.write('\n') sys.stderr.write('Inspector\'s UI closed. Telemetry will now resume.\n') self._Connect() diff --git a/tools/telemetry/telemetry/core/backends/chrome/inspector_page.py b/tools/telemetry/telemetry/core/backends/chrome/inspector_page.py index 99890c3..d815f17 100644 --- a/tools/telemetry/telemetry/core/backends/chrome/inspector_page.py +++ b/tools/telemetry/telemetry/core/backends/chrome/inspector_page.py @@ -3,8 +3,7 @@ # found in the LICENSE file. import json import logging - -from telemetry.core import util +import time class InspectorPage(object): def __init__(self, inspector_backend): @@ -30,40 +29,37 @@ class InspectorPage(object): def _OnClose(self): pass - def PerformActionAndWaitForNavigate(self, action_function, timeout=60): - """Executes action_function, and waits for the navigation to complete. - - action_function is expect to result in a navigation. This function returns - when the navigation is complete or when the timeout has been exceeded. - """ - - # Turn on notifications. We need them to get the Page.frameNavigated event. + def _EnablePageNotifications(self): request = { 'method': 'Page.enable' } - res = self._inspector_backend.SyncRequest(request, timeout) + res = self._inspector_backend.SyncRequest(request) assert len(res['result'].keys()) == 0 - def DisablePageNotifications(): - request = { - 'method': 'Page.disable' - } - res = self._inspector_backend.SyncRequest(request, timeout) - assert len(res['result'].keys()) == 0 + def _DisablePageNotifications(self): + request = { + 'method': 'Page.disable' + } + res = self._inspector_backend.SyncRequest(request) + assert len(res['result'].keys()) == 0 + + def PerformActionAndWaitForNavigate(self, action_function, timeout=60): + """Executes action_function, and waits for the navigation to complete. - self._navigation_pending = True + action_function is expect to result in a navigation. This function returns + when the navigation is complete or when the timeout has been exceeded. + """ + self._EnablePageNotifications() try: action_function() - except: - DisablePageNotifications() - raise - - def IsNavigationDone(time_left): - self._inspector_backend.DispatchNotifications(time_left) - return not self._navigation_pending - util.WaitFor(IsNavigationDone, timeout, pass_time_left_to_func=True) - - DisablePageNotifications() + start_time = time.time() + remaining_time = timeout + self._navigation_pending = True + while self._navigation_pending and remaining_time > 0: + remaining_time = max(timeout - (time.time() - start_time), 0.0) + self._inspector_backend.DispatchNotifications(remaining_time) + finally: + self._DisablePageNotifications() def Navigate(self, url, script_to_evaluate_on_commit=None, timeout=60): """Navigates to |url|. diff --git a/tools/telemetry/telemetry/core/util.py b/tools/telemetry/telemetry/core/util.py index 8d8eefb..5252398 100644 --- a/tools/telemetry/telemetry/core/util.py +++ b/tools/telemetry/telemetry/core/util.py @@ -39,7 +39,7 @@ def AddDirToPythonPath(*path_parts): sys.path.append(path) -def WaitFor(condition, timeout, pass_time_left_to_func=False): +def WaitFor(condition, timeout): """Waits for up to |timeout| secs for the function |condition| to return True. Polling frequency is (elapsed_time / 10), with a min of .1s and max of 5s. @@ -50,11 +50,7 @@ def WaitFor(condition, timeout, pass_time_left_to_func=False): start_time = time.time() while True: elapsed_time = time.time() - start_time - if pass_time_left_to_func: - remaining_time = timeout - elapsed_time - res = condition(max(remaining_time, 0.0)) - else: - res = condition() + res = condition() if res: return res if elapsed_time > timeout: diff --git a/tools/telemetry/telemetry/page/html_page_measurement_results_unittest.py b/tools/telemetry/telemetry/page/html_page_measurement_results_unittest.py index 9cd70ba..043bf7a 100644 --- a/tools/telemetry/telemetry/page/html_page_measurement_results_unittest.py +++ b/tools/telemetry/telemetry/page/html_page_measurement_results_unittest.py @@ -38,7 +38,7 @@ class StringIOFile(StringIO.StringIO): class HtmlPageMeasurementResultsTest(unittest.TestCase): # TODO(tonyg): Remove this backfill when we can assume python 2.7 everywhere. - def assertIn(self, first, second, msg=None): + def assertIn(self, first, second, _=None): self.assertTrue(first in second, msg="'%s' not found in '%s'" % (first, second)) |