Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: tools/telemetry/telemetry/core/browser.py

Issue 436873003: Make telemetry platform a singleton (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 # Copyright 2012 The Chromium Authors. All rights reserved. 1 # Copyright 2012 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 os 5 import os
6 6
7 from telemetry import decorators 7 from telemetry import decorators
8 from telemetry.core import browser_credentials 8 from telemetry.core import browser_credentials
9 from telemetry.core import exceptions 9 from telemetry.core import exceptions
10 from telemetry.core import extension_dict 10 from telemetry.core import extension_dict
11 from telemetry.core import local_server 11 from telemetry.core import local_server
12 from telemetry.core import memory_cache_http_server 12 from telemetry.core import memory_cache_http_server
13 from telemetry.core import platform 13 from telemetry.core import platform as platform_module
14 from telemetry.core import tab_list 14 from telemetry.core import tab_list
15 from telemetry.core import wpr_modes 15 from telemetry.core import wpr_modes
16 from telemetry.core import wpr_server 16 from telemetry.core import wpr_server
17 from telemetry.core.backends import browser_backend 17 from telemetry.core.backends import browser_backend
18 from telemetry.core.platform.profiler import profiler_finder 18 from telemetry.core.platform.profiler import profiler_finder
19 19
20 20
21 class Browser(object): 21 class Browser(object):
22 """A running browser instance that can be controlled in a limited way. 22 """A running browser instance that can be controlled in a limited way.
23 23
24 To create a browser instance, use browser_finder.FindBrowser. 24 To create a browser instance, use browser_finder.FindBrowser.
25 25
26 Be sure to clean up after yourself by calling Close() when you are done with 26 Be sure to clean up after yourself by calling Close() when you are done with
27 the browser. Or better yet: 27 the browser. Or better yet:
28 browser_to_create = FindBrowser(options) 28 browser_to_create = FindBrowser(options)
29 with browser_to_create.Create() as browser: 29 with browser_to_create.Create() as browser:
30 ... do all your operations on browser here 30 ... do all your operations on browser here
31 """ 31 """
32 def __init__(self, backend, platform_backend): 32 def __init__(self, backend, platform):
33 assert isinstance(platform, platform_module.Platform)
33 self._browser_backend = backend 34 self._browser_backend = backend
34 self._http_server = None 35 self._http_server = None
35 self._wpr_server = None 36 self._wpr_server = None
36 self._platform_backend = platform_backend 37 self._platform = platform
37 self._platform = platform.Platform(platform_backend)
38 self._active_profilers = [] 38 self._active_profilers = []
39 self._profilers_states = {} 39 self._profilers_states = {}
40 self._local_server_controller = local_server.LocalServerController(backend) 40 self._local_server_controller = local_server.LocalServerController(backend)
41 self._tabs = tab_list.TabList(backend.tab_list_backend) 41 self._tabs = tab_list.TabList(backend.tab_list_backend)
42 self.credentials = browser_credentials.BrowserCredentials() 42 self.credentials = browser_credentials.BrowserCredentials()
43 self._platform.SetFullPerformanceModeEnabled(True) 43 self._platform.SetFullPerformanceModeEnabled(True)
44 44
45 def __enter__(self): 45 def __enter__(self):
46 self.Start() 46 self.Start()
47 return self 47 return self
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 return extension_dict.ExtensionDict(self._browser_backend.extension_backend) 94 return extension_dict.ExtensionDict(self._browser_backend.extension_backend)
95 95
96 @property 96 @property
97 def supports_tracing(self): 97 def supports_tracing(self):
98 return self._browser_backend.supports_tracing 98 return self._browser_backend.supports_tracing
99 99
100 def is_profiler_active(self, profiler_name): 100 def is_profiler_active(self, profiler_name):
101 return profiler_name in [profiler.name() for 101 return profiler_name in [profiler.name() for
102 profiler in self._active_profilers] 102 profiler in self._active_profilers]
103 103
104
104 def _GetStatsCommon(self, pid_stats_function): 105 def _GetStatsCommon(self, pid_stats_function):
105 browser_pid = self._browser_backend.pid 106 browser_pid = self._browser_backend.pid
106 result = { 107 result = {
107 'Browser': dict(pid_stats_function(browser_pid), **{'ProcessCount': 1}), 108 'Browser': dict(pid_stats_function(browser_pid), **{'ProcessCount': 1}),
108 'Renderer': {'ProcessCount': 0}, 109 'Renderer': {'ProcessCount': 0},
109 'Gpu': {'ProcessCount': 0}, 110 'Gpu': {'ProcessCount': 0},
110 'Other': {'ProcessCount': 0} 111 'Other': {'ProcessCount': 0}
111 } 112 }
112 process_count = 1 113 process_count = 1
113 for child_pid in self._platform_backend.GetChildPids(browser_pid): 114 for child_pid in self._platform.GetChildPids(browser_pid):
114 try: 115 try:
115 child_cmd_line = self._platform_backend.GetCommandLine(child_pid) 116 child_cmd_line = self._platform.GetCommandLine(child_pid)
116 child_stats = pid_stats_function(child_pid) 117 child_stats = pid_stats_function(child_pid)
117 except exceptions.ProcessGoneException: 118 except exceptions.ProcessGoneException:
118 # It is perfectly fine for a process to have gone away between calling 119 # It is perfectly fine for a process to have gone away between calling
119 # GetChildPids() and then further examining it. 120 # GetChildPids() and then further examining it.
120 continue 121 continue
121 child_process_name = self._browser_backend.GetProcessName(child_cmd_line) 122 child_process_name = self._browser_backend.GetProcessName(child_cmd_line)
122 process_name_type_key_map = {'gpu-process': 'Gpu', 'renderer': 'Renderer'} 123 process_name_type_key_map = {'gpu-process': 'Gpu', 'renderer': 'Renderer'}
123 if child_process_name in process_name_type_key_map: 124 if child_process_name in process_name_type_key_map:
124 child_process_type_key = process_name_type_key_map[child_process_name] 125 child_process_type_key = process_name_type_key_map[child_process_name]
125 else: 126 else:
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 'WorkingSetSizePeak': U, 169 'WorkingSetSizePeak': U,
169 'ProportionalSetSize': V, 170 'ProportionalSetSize': V,
170 'PrivateDirty': W 171 'PrivateDirty': W
171 }, 172 },
172 'SystemCommitCharge': X, 173 'SystemCommitCharge': X,
173 'SystemTotalPhysicalMemory': Y, 174 'SystemTotalPhysicalMemory': Y,
174 'ProcessCount': Z, 175 'ProcessCount': Z,
175 } 176 }
176 Any of the above keys may be missing on a per-platform basis. 177 Any of the above keys may be missing on a per-platform basis.
177 """ 178 """
178 self._platform_backend.PurgeUnpinnedMemory() 179 self._platform.WillGetMemoryStats()
179 result = self._GetStatsCommon(self._platform_backend.GetMemoryStats) 180 result = self._GetStatsCommon(self._platform.GetMemoryStats)
180 result['SystemCommitCharge'] = \ 181 result['SystemCommitCharge'] = \
181 self._platform_backend.GetSystemCommitCharge() 182 self._platform.GetSystemCommitCharge()
182 result['SystemTotalPhysicalMemory'] = \ 183 result['SystemTotalPhysicalMemory'] = \
183 self._platform_backend.GetSystemTotalPhysicalMemory() 184 self._platform.GetSystemTotalPhysicalMemory()
184 return result 185 return result
185 186
187
186 @property 188 @property
187 def cpu_stats(self): 189 def cpu_stats(self):
tonyg 2014/08/02 15:58:18 I think the root of the problem here is that these
188 """Returns a dict of cpu statistics for the system. 190 """Returns a dict of cpu statistics for the system.
189 { 'Browser': { 191 { 'Browser': {
190 'CpuProcessTime': S, 192 'CpuProcessTime': S,
191 'TotalTime': T 193 'TotalTime': T
192 }, 194 },
193 'Gpu': { 195 'Gpu': {
194 'CpuProcessTime': S, 196 'CpuProcessTime': S,
195 'TotalTime': T 197 'TotalTime': T
196 }, 198 },
197 'Renderer': { 199 'Renderer': {
198 'CpuProcessTime': S, 200 'CpuProcessTime': S,
199 'TotalTime': T 201 'TotalTime': T
200 } 202 }
201 } 203 }
202 Any of the above keys may be missing on a per-platform basis. 204 Any of the above keys may be missing on a per-platform basis.
203 """ 205 """
204 result = self._GetStatsCommon(self._platform_backend.GetCpuStats) 206 result = self._GetStatsCommon(self._platform.GetCpuStats)
205 del result['ProcessCount'] 207 del result['ProcessCount']
206 208
207 # We want a single time value, not the sum for all processes. 209 # We want a single time value, not the sum for all processes.
208 cpu_timestamp = self._platform_backend.GetCpuTimestamp() 210 cpu_timestamp = self._platform.GetCpuTimestamp()
209 for process_type in result: 211 for process_type in result:
210 # Skip any process_types that are empty 212 # Skip any process_types that are empty
211 if not len(result[process_type]): 213 if not len(result[process_type]):
212 continue 214 continue
213 result[process_type].update(cpu_timestamp) 215 result[process_type].update(cpu_timestamp)
214 return result 216 return result
215 217
216 @property 218 @property
217 def io_stats(self): 219 def io_stats(self):
218 """Returns a dict of IO statistics for the browser: 220 """Returns a dict of IO statistics for the browser:
(...skipping 10 matching lines...) Expand all
229 'WriteTransferCount': Z 231 'WriteTransferCount': Z
230 }, 232 },
231 'Renderer': { 233 'Renderer': {
232 'ReadOperationCount': W, 234 'ReadOperationCount': W,
233 'WriteOperationCount': X, 235 'WriteOperationCount': X,
234 'ReadTransferCount': Y, 236 'ReadTransferCount': Y,
235 'WriteTransferCount': Z 237 'WriteTransferCount': Z
236 } 238 }
237 } 239 }
238 """ 240 """
239 result = self._GetStatsCommon(self._platform_backend.GetIOStats) 241 result = self._GetStatsCommon(self._platform.GetIOStats)
240 del result['ProcessCount'] 242 del result['ProcessCount']
241 return result 243 return result
242 244
243 def StartProfiling(self, profiler_name, base_output_file): 245 def StartProfiling(self, profiler_name, base_output_file):
244 """Starts profiling using |profiler_name|. Results are saved to 246 """Starts profiling using |profiler_name|. Results are saved to
245 |base_output_file|.<process_name>.""" 247 |base_output_file|.<process_name>."""
246 assert not self._active_profilers, 'Already profiling. Must stop first.' 248 assert not self._active_profilers, 'Already profiling. Must stop first.'
247 249
248 profiler_class = profiler_finder.FindProfiler(profiler_name) 250 profiler_class = profiler_finder.FindProfiler(profiler_name)
249 251
250 if not profiler_class.is_supported(self._browser_backend.browser_type): 252 if not profiler_class.is_supported(self._browser_backend.browser_type):
251 raise Exception('The %s profiler is not ' 253 raise Exception('The %s profiler is not '
252 'supported on this platform.' % profiler_name) 254 'supported on this platform.' % profiler_name)
253 255
254 if not profiler_class in self._profilers_states: 256 if not profiler_class in self._profilers_states:
255 self._profilers_states[profiler_class] = {} 257 self._profilers_states[profiler_class] = {}
256 258
257 self._active_profilers.append( 259 profiler = self.platform.InstantiateProfiler(
258 profiler_class(self._browser_backend, self._platform_backend, 260 profiler_class,
259 base_output_file, self._profilers_states[profiler_class])) 261 self._browser_backend,
262 base_output_file,
263 self._profilers_states[profiler_class])
264 self._active_profilers.append(profiler)
260 265
261 def StopProfiling(self): 266 def StopProfiling(self):
262 """Stops all active profilers and saves their results. 267 """Stops all active profilers and saves their results.
263 268
264 Returns: 269 Returns:
265 A list of filenames produced by the profiler. 270 A list of filenames produced by the profiler.
266 """ 271 """
267 output_files = [] 272 output_files = []
268 for profiler in self._active_profilers: 273 for profiler in self._active_profilers:
269 output_files.extend(profiler.CollectProfile()) 274 output_files.extend(profiler.CollectProfile())
(...skipping 21 matching lines...) Expand all
291 self.platform.FlushSystemCacheForDirectory( 296 self.platform.FlushSystemCacheForDirectory(
292 self._browser_backend.browser_directory) 297 self._browser_backend.browser_directory)
293 else: 298 else:
294 self.platform.FlushEntireSystemCache() 299 self.platform.FlushEntireSystemCache()
295 300
296 self._browser_backend.SetBrowser(self) 301 self._browser_backend.SetBrowser(self)
297 self._browser_backend.Start() 302 self._browser_backend.Start()
298 303
299 def Close(self): 304 def Close(self):
300 """Closes this browser.""" 305 """Closes this browser."""
301 for profiler_class in self._profilers_states: 306 profiler_classes = list(self._profilers_states.keys())
302 profiler_class.WillCloseBrowser(self._browser_backend, 307 self._platform.WillCloseBrowser(self._browser_backend,
303 self._platform_backend) 308 profiler_classes)
304 309
305 self.platform.SetFullPerformanceModeEnabled(False) 310 self.platform.SetFullPerformanceModeEnabled(False)
306 311
307 if self._wpr_server: 312 if self._wpr_server:
308 self._wpr_server.Close() 313 self._wpr_server.Close()
309 self._wpr_server = None 314 self._wpr_server = None
310 315
311 if self._http_server: 316 if self._http_server:
312 self._http_server.Close() 317 self._http_server.Close()
313 self._http_server = None 318 self._http_server = None
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 398
394 @property 399 @property
395 def supports_system_info(self): 400 def supports_system_info(self):
396 return self._browser_backend.supports_system_info 401 return self._browser_backend.supports_system_info
397 402
398 def GetSystemInfo(self): 403 def GetSystemInfo(self):
399 """Returns low-level information about the system, if available. 404 """Returns low-level information about the system, if available.
400 405
401 See the documentation of the SystemInfo class for more details.""" 406 See the documentation of the SystemInfo class for more details."""
402 return self._browser_backend.GetSystemInfo() 407 return self._browser_backend.GetSystemInfo()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698