Index: chrome/test/pyautolib/remote_inspector_client.py |
diff --git a/chrome/test/pyautolib/remote_inspector_client.py b/chrome/test/pyautolib/remote_inspector_client.py |
index ed9844451e22a2f3111e4dccb80d81252870cecf..442f53be60fe8139549dc1fcac2817915e462116 100755 |
--- a/chrome/test/pyautolib/remote_inspector_client.py |
+++ b/chrome/test/pyautolib/remote_inspector_client.py |
@@ -41,6 +41,7 @@ import datetime |
import logging |
import optparse |
import pprint |
+import re |
import simplejson |
import socket |
import sys |
@@ -280,10 +281,11 @@ class _RemoteInspectorThread(threading.Thread): |
the lower-level work of socket communication. |
""" |
- def __init__(self, tab_index, tab_filter, verbose, show_socket_messages): |
+ def __init__(self, url, tab_index, tab_filter, verbose, show_socket_messages): |
"""Initialize. |
Args: |
+ url: The base URL to connent to. |
tab_index: The integer index of the tab in the remote Chrome instance to |
use for snapshotting. |
tab_filter: When specified, is run over tabs of the remote Chrome |
@@ -309,7 +311,8 @@ class _RemoteInspectorThread(threading.Thread): |
# Create a DevToolsSocket client and wait for it to complete the remote |
# debugging protocol handshake with the remote Chrome instance. |
- result = self._IdentifyDevToolsSocketConnectionInfo(tab_index, tab_filter) |
+ result = self._IdentifyDevToolsSocketConnectionInfo( |
+ url, tab_index, tab_filter) |
self._client = _DevToolsSocketClient( |
verbose, show_socket_messages, result['host'], result['port'], |
result['path']) |
@@ -511,7 +514,7 @@ class _RemoteInspectorThread(threading.Thread): |
if request.method == 'Profiler.takeHeapSnapshot': |
# We always want detailed v8 heap snapshot information. |
request.params = {'detailed': True} |
- elif request.method == 'Profiler.getProfile': |
+ elif request.method == 'Profiler.getHeapSnapshot': |
# To actually request the snapshot data from a previously-taken snapshot, |
# we need to specify the unique uid of the snapshot we want. |
# The relevant uid should be contained in the last |
@@ -519,13 +522,20 @@ class _RemoteInspectorThread(threading.Thread): |
last_req = self._GetLatestRequestOfType(request, |
'Profiler.takeHeapSnapshot') |
if last_req and 'uid' in last_req.results: |
+ request.params = {'uid': last_req.results['uid']} |
+ elif request.method == 'Profiler.getProfile': |
+ # TODO(eustas): Remove this case after M27 is released. |
+ last_req = self._GetLatestRequestOfType(request, |
+ 'Profiler.takeHeapSnapshot') |
+ if last_req and 'uid' in last_req.results: |
request.params = {'type': 'HEAP', 'uid': last_req.results['uid']} |
@staticmethod |
- def _IdentifyDevToolsSocketConnectionInfo(tab_index, tab_filter): |
+ def _IdentifyDevToolsSocketConnectionInfo(url, tab_index, tab_filter): |
"""Identifies DevToolsSocket connection info from a remote Chrome instance. |
Args: |
+ url: The base URL to connent to. |
tab_index: The integer index of the tab in the remote Chrome instance to |
which to connect. |
tab_filter: When specified, is run over tabs of the remote Chrome instance |
@@ -543,9 +553,7 @@ class _RemoteInspectorThread(threading.Thread): |
RuntimeError: When DevToolsSocket connection info cannot be identified. |
""" |
try: |
- # TODO(dennisjeffrey): Do not assume port 9222. The port should be passed |
- # as input to this function. |
- f = urllib2.urlopen('http://localhost:9222/json') |
+ f = urllib2.urlopen(url + '/json') |
result = f.read() |
logging.debug(result) |
result = simplejson.loads(result) |
@@ -844,9 +852,15 @@ class RemoteInspectorClient(object): |
self._remote_inspector_thread = None |
self._remote_inspector_driver_thread = None |
+ # TODO(dennisjeffrey): Do not assume port 9222. The port should be passed |
+ # as input to this function. |
+ url = 'http://localhost:9222' |
+ |
+ self._webkit_version = self._GetWebkitVersion(url) |
+ |
# Start up a thread for long-term communication with the remote inspector. |
self._remote_inspector_thread = _RemoteInspectorThread( |
- tab_index, tab_filter, verbose, show_socket_messages) |
+ url, tab_index, tab_filter, verbose, show_socket_messages) |
self._remote_inspector_thread.start() |
# At this point, a connection has already been made to the remote inspector. |
@@ -883,12 +897,18 @@ class RemoteInspectorClient(object): |
# Only if |include_summary| is True. |
} |
""" |
+ # TODO(eustas): Remove this hack after M27 is released. |
+ if self._IsWebkitVersionNotOlderThan(537, 27): |
+ get_heap_snapshot_method = 'Profiler.getHeapSnapshot' |
+ else: |
+ get_heap_snapshot_method = 'Profiler.getProfile' |
+ |
HEAP_SNAPSHOT_MESSAGES = [ |
('Page.getResourceTree', {}), |
('Debugger.enable', {}), |
('Profiler.clearProfiles', {}), |
('Profiler.takeHeapSnapshot', {}), |
- ('Profiler.getProfile', {}), |
+ (get_heap_snapshot_method, {}), |
] |
self._current_heap_snapshot = [] |
@@ -1208,3 +1228,70 @@ class RemoteInspectorClient(object): |
return '%.2f KB' % (num_bytes / 1024.0) |
else: |
return '%.2f MB' % (num_bytes / 1048576.0) |
+ |
+ @staticmethod |
+ def _GetWebkitVersion(endpoint): |
+ """Fetches Webkit version information from a remote Chrome instance. |
+ |
+ Args: |
+ endpoint: The base URL to connent to. |
+ |
+ Returns: |
+ A dictionary containing Webkit version information: |
+ { |
+ 'major': integer, |
+ 'minor': integer, |
+ } |
+ |
+ Raises: |
+ RuntimeError: When Webkit version info can't be fetched or parsed. |
+ """ |
+ try: |
+ f = urllib2.urlopen(endpoint + '/json/version') |
+ result = f.read(); |
+ result = simplejson.loads(result) |
+ except urllib2.URLError, e: |
+ raise RuntimeError( |
+ 'Error accessing Chrome instance debugging port: ' + str(e)) |
+ |
+ if 'WebKit-Version' not in result: |
+ raise RuntimeError('WebKit-Version is not specified.') |
+ |
+ parsed = re.search('^(\d+)\.(\d+)', result['WebKit-Version']) |
+ if parsed is None: |
+ raise RuntimeError('WebKit-Version cannot be parsed.') |
+ |
+ try: |
+ info = { |
+ 'major': int(parsed.group(1)), |
+ 'minor': int(parsed.group(2)), |
+ } |
+ except ValueError: |
+ raise RuntimeError('WebKit-Version cannot be parsed.') |
+ |
+ return info |
+ |
+ def _IsWebkitVersionNotOlderThan(self, major, minor): |
+ """Compares remote Webkit version with specified one. |
+ |
+ Args: |
+ major: Major Webkit version. |
+ minor: Minor Webkit version. |
+ |
+ Returns: |
+ True if remote Webkit version is same or newer than specified, |
+ False otherwise. |
+ |
+ Raises: |
+ RuntimeError: If remote Webkit version hasn't been fetched yet. |
+ """ |
+ if not hasattr(self, '_webkit_version'): |
+ raise RuntimeError('WebKit version has not been fetched yet.') |
+ version = self._webkit_version |
+ |
+ if version['major'] < major: |
+ return False |
+ elif version['major'] == major and version['minor'] < minor: |
+ return False |
+ else: |
+ return True |