diff options
author | dennisjeffrey@chromium.org <dennisjeffrey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-10 03:50:52 +0000 |
---|---|---|
committer | dennisjeffrey@chromium.org <dennisjeffrey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-10 03:50:52 +0000 |
commit | 648a09f7e21ae155958066287da7461e4d649dff (patch) | |
tree | aab1fddbac5bca0989a4750bd2512f4558f4819d /chrome/test/pyautolib | |
parent | fb275729bbd8e5622fb22124e5ea3f21377dcc94 (diff) | |
download | chromium_src-648a09f7e21ae155958066287da7461e4d649dff.zip chromium_src-648a09f7e21ae155958066287da7461e4d649dff.tar.gz chromium_src-648a09f7e21ae155958066287da7461e4d649dff.tar.bz2 |
Pyauto tests can now request DOM node/event listener counts from a Chrome tab.
This CL adds functionality to the pyauto module that interacts with Chrome's
remote inspector to allow DOM node count and event listener count information
to be obtained from the remote inspector. The Chrome Endure tests have
also been revised to account for this newly-available information.
BUG=chromium-os:24888
TEST=None
Review URL: http://codereview.chromium.org/9158007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@117001 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/test/pyautolib')
-rwxr-xr-x | chrome/test/pyautolib/perf_snapshot.py | 92 |
1 files changed, 84 insertions, 8 deletions
diff --git a/chrome/test/pyautolib/perf_snapshot.py b/chrome/test/pyautolib/perf_snapshot.py index e27d638..577a709 100755 --- a/chrome/test/pyautolib/perf_snapshot.py +++ b/chrome/test/pyautolib/perf_snapshot.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -82,7 +82,7 @@ class _V8HeapSnapshotParser(object): Returns: A dictionary containing the summarized v8 heap snapshot data: { - 'total_node_count': integer, # Total number of nodes in the v8 heap. + 'total_v8_node_count': integer, # Total number of nodes in the v8 heap. 'total_shallow_size': integer, # Total heap size, in bytes. } """ @@ -162,7 +162,7 @@ class _V8HeapSnapshotParser(object): # TODO(dennisjeffrey): Have this function also return more detailed v8 # heap snapshot data when a need for it arises (e.g., using |constructors|). result = {} - result['total_node_count'] = total_node_count + result['total_v8_node_count'] = total_node_count result['total_shallow_size'] = total_shallow_size return result @@ -411,7 +411,7 @@ class _RemoteInspectorBaseThread(threading.Thread): result handling needs to be performed. run: Starts the thread of execution for this object. Invoked implicitly by calling the start() method on this object. Should be overridden - by a subclass. + by a subclass, and should call self._client.close() when done. """ def __init__(self, tab_index, verbose, show_socket_messages): """Initialize. @@ -692,7 +692,7 @@ class _PerformanceSnapshotterThread(_RemoteInspectorBaseThread): result = parser.ParseSnapshotData(raw_snapshot_data) self._logger.debug('Time to parse data: %.2f sec', time.time() - time_start) - num_nodes = result['total_node_count'] + num_nodes = result['total_v8_node_count'] total_size = result['total_shallow_size'] total_size_str = self._ConvertBytesToHumanReadableString(total_size) timestamp = time.time() @@ -700,7 +700,7 @@ class _PerformanceSnapshotterThread(_RemoteInspectorBaseThread): self.collected_heap_snapshot_data.append( {'url': self._url, 'timestamp': timestamp, - 'total_node_count': num_nodes, + 'total_v8_node_count': num_nodes, 'total_heap_size': total_size,}) if self._output_file: @@ -836,7 +836,56 @@ class _GarbageCollectThread(_RemoteInspectorBaseThread): return time.sleep(0.1) self._client.close() - return + + +class _MemoryCountThread(_RemoteInspectorBaseThread): + """Manages communication with a remote Chrome to get memory count info.""" + + _MEMORY_COUNT_MESSAGES = [ + 'Memory.getDOMNodeCount', + ] + + def HandleReply(self, reply_dict): + """Processes a reply message received from the remote Chrome instance. + + Args: + reply_dict: A dictionary object representing the reply message received + from the remote Chrome instance. + """ + if 'result' in reply_dict and 'count' in reply_dict['result']: + dom_group_list = reply_dict['result']['count'] + for dom_group in dom_group_list: + listener_array = dom_group['listenerCount'] + for listener in listener_array: + self.event_listener_count += listener['count'] + dom_node_array = dom_group['nodeCount'] + for dom_element in dom_node_array: + self.dom_node_count += dom_element['count'] + + def run(self): + """Start _MemoryCountThread; overridden from threading.Thread.""" + if self._killed: + return + + self.dom_node_count = 0 + self.event_listener_count = 0 + + # Prepare the request list. + for message in self._MEMORY_COUNT_MESSAGES: + self._requests.append( + _DevToolsSocketRequest(message, self._next_request_id)) + self._next_request_id += 1 + + # Send out each request. Wait until each request is complete before sending + # the next request. + for request in self._requests: + self._FillInParams(request) + self._client.SendMessage(str(request)) + while not request.is_complete: + if self._killed: + return + time.sleep(0.1) + self._client.close() # TODO(dennisjeffrey): The "verbose" option used in this file should re-use @@ -898,7 +947,7 @@ class PerformanceSnapshotter(object): { 'url': string, # URL of the webpage that was snapshotted. 'timestamp': float, # Time when snapshot taken (seconds since epoch). - 'total_node_count': integer, # Total number of nodes in the v8 heap. + 'total_v8_node_count': integer, # Total number of nodes in the v8 heap. 'total_heap_size': integer, # Total heap size (number of bytes). } """ @@ -932,6 +981,33 @@ class PerformanceSnapshotter(object): pass gc_thread.join() + def GetMemoryObjectCounts(self): + """Retrieves memory object count information. + + Returns: + A dictionary containing the memory object count information: + { + 'DOMNodeCount': integer, # Total number of DOM nodes. + 'EventListenerCount': integer, # Total number of event listeners. + } + """ + mem_count_thread = _MemoryCountThread(self._tab_index, self._verbose, + self._show_socket_messages) + mem_count_thread.start() + try: + while asyncore.socket_map: + if not mem_count_thread.is_alive(): + break + asyncore.loop(timeout=1, count=1) + except KeyboardInterrupt: + pass + mem_count_thread.join() + result = { + 'DOMNodeCount': mem_count_thread.dom_node_count, + 'EventListenerCount': mem_count_thread.event_listener_count, + } + return result + def SetInteractiveMode(self): """Sets the current object to take snapshots in interactive mode.""" self._interactive_mode = True |