OLD | NEW |
---|---|
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import logging | 5 import logging |
6 import re | 6 import re |
7 | 7 |
8 from telemetry.core.backends.chrome import inspector_websocket | 8 from telemetry.core.backends.chrome import inspector_websocket |
9 | 9 |
10 | 10 |
(...skipping 10 matching lines...) Expand all Loading... | |
21 "benchmark," | 21 "benchmark," |
22 "webkit.console," | 22 "webkit.console," |
23 "blink.console," | 23 "blink.console," |
24 "trace_event_overhead") | 24 "trace_event_overhead") |
25 | 25 |
26 | 26 |
27 class TracingUnsupportedException(Exception): | 27 class TracingUnsupportedException(Exception): |
28 pass | 28 pass |
29 | 29 |
30 | 30 |
31 class TracingTimeoutException(Exception): | |
32 pass | |
33 | |
34 | |
31 class CategoryFilter(object): | 35 class CategoryFilter(object): |
32 def __init__(self, filter_string): | 36 def __init__(self, filter_string): |
33 self.excluded = set() | 37 self.excluded = set() |
34 self.included = set() | 38 self.included = set() |
35 self.disabled = set() | 39 self.disabled = set() |
36 self.synthetic_delays = set() | 40 self.synthetic_delays = set() |
37 self.contains_wildcards = False | 41 self.contains_wildcards = False |
38 | 42 |
39 if not filter_string: | 43 if not filter_string: |
40 return | 44 return |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
103 def __init__(self, devtools_port): | 107 def __init__(self, devtools_port): |
104 self._inspector_websocket = inspector_websocket.InspectorWebsocket( | 108 self._inspector_websocket = inspector_websocket.InspectorWebsocket( |
105 self._NotificationHandler, | 109 self._NotificationHandler, |
106 self._ErrorHandler) | 110 self._ErrorHandler) |
107 | 111 |
108 self._inspector_websocket.Connect( | 112 self._inspector_websocket.Connect( |
109 'ws://127.0.0.1:%i/devtools/browser' % devtools_port) | 113 'ws://127.0.0.1:%i/devtools/browser' % devtools_port) |
110 self._category_filter = None | 114 self._category_filter = None |
111 self._nesting = 0 | 115 self._nesting = 0 |
112 self._tracing_data = [] | 116 self._tracing_data = [] |
117 self._is_tracing_running = False | |
113 | 118 |
114 @property | 119 @property |
115 def is_tracing_running(self): | 120 def is_tracing_running(self): |
116 return self._inspector_websocket.is_dispatching_async_notifications | 121 return self._is_tracing_running |
117 | 122 |
118 def StartTracing(self, custom_categories=None, timeout=10): | 123 def StartTracing(self, custom_categories=None, timeout=10): |
119 """ Starts tracing on the first nested call and returns True. Returns False | 124 """ Starts tracing on the first nested call and returns True. Returns False |
120 and does nothing on subsequent nested calls. | 125 and does nothing on subsequent nested calls. |
121 """ | 126 """ |
122 self._nesting += 1 | 127 self._nesting += 1 |
123 if self.is_tracing_running: | 128 if self.is_tracing_running: |
124 new_category_filter = CategoryFilter(custom_categories) | 129 new_category_filter = CategoryFilter(custom_categories) |
125 is_subset = new_category_filter.IsSubset(self._category_filter) | 130 is_subset = new_category_filter.IsSubset(self._category_filter) |
126 assert(is_subset != False) | 131 assert(is_subset != False) |
127 if is_subset == None: | 132 if is_subset == None: |
128 logging.warning('Cannot determine if category filter of nested ' + | 133 logging.warning('Cannot determine if category filter of nested ' + |
129 'StartTracing call is subset of current filter.') | 134 'StartTracing call is subset of current filter.') |
130 return False | 135 return False |
131 self._CheckNotificationSupported() | 136 self._CheckNotificationSupported() |
132 req = {'method': 'Tracing.start'} | 137 req = {'method': 'Tracing.start'} |
133 self._category_filter = CategoryFilter(custom_categories) | 138 self._category_filter = CategoryFilter(custom_categories) |
134 if custom_categories: | 139 if custom_categories: |
135 req['params'] = {'categories': custom_categories} | 140 req['params'] = {'categories': custom_categories} |
136 self._inspector_websocket.SyncRequest(req, timeout) | 141 self._inspector_websocket.SyncRequest(req, timeout) |
137 # Tracing.start will send asynchronous notifications containing trace | 142 self._is_tracing_running = True |
138 # data, until Tracing.end is called. | |
139 self._inspector_websocket.StartAsyncDispatchNotifications() | |
140 return True | 143 return True |
141 | 144 |
142 def StopTracing(self): | 145 def StopTracing(self, timeout=30): |
143 """ Stops tracing on the innermost (!) nested call, because we cannot get | 146 """ Stops tracing on the innermost (!) nested call, because we cannot get |
144 results otherwise. Resets _tracing_data on the outermost nested call. | 147 results otherwise. Resets _tracing_data on the outermost nested call. |
145 Returns the result of the trace, as TracingTimelineData object. | 148 Returns the result of the trace, as TracingTimelineData object. |
146 """ | 149 """ |
147 self._nesting -= 1 | 150 self._nesting -= 1 |
148 assert self._nesting >= 0 | 151 assert self._nesting >= 0 |
149 if self.is_tracing_running: | 152 if self.is_tracing_running: |
150 req = {'method': 'Tracing.end'} | 153 req = {'method': 'Tracing.end'} |
151 self._inspector_websocket.SendAndIgnoreResponse(req) | 154 self._inspector_websocket.SendAndIgnoreResponse(req) |
152 self._inspector_websocket.StopAsyncDispatchNotifications() | 155 # After Tracing.end, chrome browser will send asynchronous notifications |
156 # containing trace data. This is until Tracing.tracingComplete is sent, | |
157 # which means there is no trace buffers pending flush. | |
158 try: | |
159 self._inspector_websocket.DispatchNotificationsUntilDone(timeout) | |
160 except \ | |
161 inspector_websocket.DispatchNotificationsUntilDoneTimeoutException \ | |
162 as err: | |
163 raise TracingTimeoutException( | |
164 'Trace data was not fully received due to timeout after %s ' | |
165 'seconds. If the trace data is big, you may want to increase the ' | |
166 'time out amount.' % err.elapsed_time) | |
chrishenry
2014/07/11 18:27:59
nit: timeout
| |
167 self._is_tracing_running = False | |
153 if self._nesting == 0: | 168 if self._nesting == 0: |
154 self._category_filter = None | 169 self._category_filter = None |
155 return self._GetTraceResultAndReset() | 170 return self._GetTraceResultAndReset() |
156 else: | 171 else: |
157 return self._GetTraceResult() | 172 return self._GetTraceResult() |
158 | 173 |
159 def _GetTraceResult(self): | 174 def _GetTraceResult(self): |
160 assert not self.is_tracing_running | 175 assert not self.is_tracing_running |
161 return self._tracing_data | 176 return self._tracing_data |
162 | 177 |
(...skipping 25 matching lines...) Expand all Loading... | |
188 | 203 |
189 def _CheckNotificationSupported(self): | 204 def _CheckNotificationSupported(self): |
190 """Ensures we're running against a compatible version of chrome.""" | 205 """Ensures we're running against a compatible version of chrome.""" |
191 req = {'method': 'Tracing.hasCompleted'} | 206 req = {'method': 'Tracing.hasCompleted'} |
192 res = self._inspector_websocket.SyncRequest(req) | 207 res = self._inspector_websocket.SyncRequest(req) |
193 if res.get('response'): | 208 if res.get('response'): |
194 raise TracingUnsupportedException( | 209 raise TracingUnsupportedException( |
195 'Tracing not supported for this browser') | 210 'Tracing not supported for this browser') |
196 elif 'error' in res: | 211 elif 'error' in res: |
197 return | 212 return |
OLD | NEW |