| OLD | NEW |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 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 import logging | 4 import logging |
| 5 import os | 5 import os |
| 6 import time | 6 import time |
| 7 import traceback | 7 import traceback |
| 8 import urlparse | 8 import urlparse |
| 9 import random | 9 import random |
| 10 | 10 |
| 11 from telemetry import browser_gone_exception | 11 from telemetry import browser_gone_exception |
| 12 from telemetry import page_test | 12 from telemetry import page_test |
| 13 from telemetry import tab_crash_exception | 13 from telemetry import tab_crash_exception |
| 14 from telemetry import util | 14 from telemetry import util |
| 15 from telemetry import wpr_modes | 15 from telemetry import wpr_modes |
| 16 | 16 |
| 17 class PageState(object): | 17 class PageState(object): |
| 18 def __init__(self): | 18 def __init__(self): |
| 19 self.did_login = False | 19 self.did_login = False |
| 20 | 20 |
| 21 class _RunState(object): | 21 class _RunState(object): |
| 22 def __init__(self): | 22 def __init__(self): |
| 23 self.first_browser = True | 23 self.first_browser = True |
| 24 self.browser = None | 24 self.browser = None |
| 25 self.tab = None | 25 self.tab = None |
| 26 self.trace_tab = None | 26 self.is_tracing = False |
| 27 | 27 |
| 28 def Close(self): | 28 def Close(self): |
| 29 if self.trace_tab: | |
| 30 self.trace_tab.Disconnect() | |
| 31 self.trace_tab = None | |
| 32 | |
| 33 if self.tab: | 29 if self.tab: |
| 34 self.tab.Disconnect() | 30 self.tab.Disconnect() |
| 35 self.tab = None | 31 self.tab = None |
| 36 | 32 |
| 37 if self.browser: | 33 if self.browser: |
| 38 self.browser.Close() | 34 self.browser.Close() |
| 39 self.browser = None | 35 self.browser = None |
| 40 | 36 |
| 41 def _ShufflePageSet(page_set, options): | 37 def _ShufflePageSet(page_set, options): |
| 42 if options.test_shuffle_order_file and not options.test_shuffle: | 38 if options.test_shuffle_order_file and not options.test_shuffle: |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 except tab_crash_exception.TabCrashException: | 125 except tab_crash_exception.TabCrashException: |
| 130 if not options.show_stdout: | 126 if not options.show_stdout: |
| 131 stdout = state.browser.GetStandardOutput() | 127 stdout = state.browser.GetStandardOutput() |
| 132 stdout = (('\nStandard Output:\n') + | 128 stdout = (('\nStandard Output:\n') + |
| 133 ('*' * 80) + | 129 ('*' * 80) + |
| 134 '\n\t' + stdout.replace('\n', '\n\t') + '\n' + | 130 '\n\t' + stdout.replace('\n', '\n\t') + '\n' + |
| 135 ('*' * 80)) | 131 ('*' * 80)) |
| 136 logging.warning('Tab crashed: %s%s', page.url, stdout) | 132 logging.warning('Tab crashed: %s%s', page.url, stdout) |
| 137 state.Close() | 133 state.Close() |
| 138 | 134 |
| 139 if options.trace_dir and state.trace_tab: | 135 if options.trace_dir: |
| 140 self._EndTracing(state, options, page) | 136 self._EndTracing(state, options, page) |
| 141 break | 137 break |
| 142 except browser_gone_exception.BrowserGoneException: | 138 except browser_gone_exception.BrowserGoneException: |
| 143 logging.warning('Lost connection to browser. Retrying.') | 139 logging.warning('Lost connection to browser. Retrying.') |
| 144 state.Close() | 140 state.Close() |
| 145 tries -= 1 | 141 tries -= 1 |
| 146 if not tries: | 142 if not tries: |
| 147 logging.error('Lost connection to browser 3 times. Failing.') | 143 logging.error('Lost connection to browser 3 times. Failing.') |
| 148 raise | 144 raise |
| 149 finally: | 145 finally: |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 state.browser.credentials.credentials_path = credentials_path | 217 state.browser.credentials.credentials_path = credentials_path |
| 222 test.SetUpBrowser(state.browser) | 218 test.SetUpBrowser(state.browser) |
| 223 | 219 |
| 224 if state.first_browser: | 220 if state.first_browser: |
| 225 state.browser.credentials.WarnIfMissingCredentials(self.page_set) | 221 state.browser.credentials.WarnIfMissingCredentials(self.page_set) |
| 226 state.first_browser = False | 222 state.first_browser = False |
| 227 | 223 |
| 228 state.browser.SetReplayArchivePath(archive_path) | 224 state.browser.SetReplayArchivePath(archive_path) |
| 229 | 225 |
| 230 def _SetupTracingTab(self, state): | 226 def _SetupTracingTab(self, state): |
| 231 if not state.trace_tab: | 227 if state.browser.supports_tracing: |
| 232 # Swap the two tabs because new tabs open to about:blank, and we | 228 state.is_tracing = True |
| 233 # can't navigate across protocols to chrome://tracing. The initial | 229 state.browser.StartTracing() |
| 234 # tab starts at chrome://newtab, so it works for that tab. | |
| 235 # TODO(dtu): If the trace_tab crashes, we're hosed. | |
| 236 state.trace_tab = state.tab | |
| 237 state.tab = state.browser.tabs.New() | |
| 238 | |
| 239 state.trace_tab.page.Navigate('chrome://tracing') | |
| 240 state.trace_tab.WaitForDocumentReadyStateToBeInteractiveOrBetter() | |
| 241 | |
| 242 # Start tracing. | |
| 243 state.trace_tab.runtime.Execute('tracingController.beginTracing(' | |
| 244 'tracingController.supportsSystemTracing);') | |
| 245 | 230 |
| 246 def _EndTracing(self, state, options, page): | 231 def _EndTracing(self, state, options, page): |
| 247 def IsTracingRunning(): | 232 if state.is_tracing: |
| 248 return state.trace_tab.runtime.Evaluate( | 233 state.is_tracing = False |
| 249 'tracingController.isTracingEnabled') | 234 state.browser.StopTracing() |
| 250 # Tracing might have ended already if the buffer filled up. | 235 trace = state.browser.GetTrace() |
| 251 if IsTracingRunning(): | 236 logging.info('Processing trace...') |
| 252 state.trace_tab.runtime.Execute('tracingController.endTracing()') | |
| 253 util.WaitFor(lambda: not IsTracingRunning(), 10) | |
| 254 | 237 |
| 255 logging.info('Processing trace...') | 238 trace_file_base = os.path.join( |
| 239 options.trace_dir, page.url_as_file_safe_name) |
| 256 | 240 |
| 257 trace_file_base = os.path.join( | 241 if options.page_repeat != 1 or options.pageset_repeat != 1: |
| 258 options.trace_dir, page.url_as_file_safe_name) | 242 trace_file_index = 0 |
| 259 | 243 |
| 260 if options.page_repeat != 1 or options.pageset_repeat != 1: | 244 while True: |
| 261 trace_file_index = 0 | 245 trace_file = '%s_%03d.json' % (trace_file_base, trace_file_index) |
| 262 | 246 if not os.path.exists(trace_file): |
| 263 while True: | 247 break |
| 264 trace_file = '%s_%03d.json' % (trace_file_base, trace_file_index) | 248 trace_file_index = trace_file_index + 1 |
| 265 if not os.path.exists(trace_file): | 249 else: |
| 266 break | 250 trace_file = '%s.json' % trace_file_base |
| 267 trace_file_index = trace_file_index + 1 | 251 with open(trace_file, 'w') as trace_file: |
| 268 else: | 252 trace_file.write(trace) |
| 269 trace_file = '%s.json' % trace_file_base | 253 logging.info('Trace saved.') |
| 270 | |
| 271 with open(trace_file, 'w') as trace_file: | |
| 272 trace_file.write(state.trace_tab.runtime.Evaluate(""" | |
| 273 JSON.stringify({ | |
| 274 traceEvents: tracingController.traceEvents, | |
| 275 systemTraceEvents: tracingController.systemTraceEvents, | |
| 276 clientInfo: tracingController.clientInfo_, | |
| 277 gpuInfo: tracingController.gpuInfo_ | |
| 278 }); | |
| 279 """)) | |
| 280 logging.info('Trace saved.') | |
| 281 | 254 |
| 282 def _PreparePage(self, page, tab, page_state, results): | 255 def _PreparePage(self, page, tab, page_state, results): |
| 283 parsed_url = urlparse.urlparse(page.url) | 256 parsed_url = urlparse.urlparse(page.url) |
| 284 if parsed_url[0] == 'file': | 257 if parsed_url[0] == 'file': |
| 285 dirname, filename = page.url_base_dir_and_file | 258 dirname, filename = page.url_base_dir_and_file |
| 286 tab.browser.SetHTTPServerDirectory(dirname) | 259 tab.browser.SetHTTPServerDirectory(dirname) |
| 287 target_side_url = tab.browser.http_server.UrlOf(filename) | 260 target_side_url = tab.browser.http_server.UrlOf(filename) |
| 288 else: | 261 else: |
| 289 target_side_url = page.url | 262 target_side_url = page.url |
| 290 | 263 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 310 return True | 283 return True |
| 311 | 284 |
| 312 def _CleanUpPage(self, page, tab, page_state): # pylint: disable=R0201 | 285 def _CleanUpPage(self, page, tab, page_state): # pylint: disable=R0201 |
| 313 if page.credentials and page_state.did_login: | 286 if page.credentials and page_state.did_login: |
| 314 tab.browser.credentials.LoginNoLongerNeeded(tab, page.credentials) | 287 tab.browser.credentials.LoginNoLongerNeeded(tab, page.credentials) |
| 315 try: | 288 try: |
| 316 tab.runtime.Evaluate("""window.chrome && chrome.benchmarking && | 289 tab.runtime.Evaluate("""window.chrome && chrome.benchmarking && |
| 317 chrome.benchmarking.closeConnections()""") | 290 chrome.benchmarking.closeConnections()""") |
| 318 except Exception: | 291 except Exception: |
| 319 pass | 292 pass |
| OLD | NEW |