Chromium Code Reviews| 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 codecs | 4 import codecs |
| 5 import glob | 5 import glob |
| 6 import logging | 6 import logging |
| 7 import os | 7 import os |
| 8 import sys | 8 import sys |
| 9 import time | 9 import time |
| 10 import traceback | 10 import traceback |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 64 | 64 |
| 65 # Ensure only one tab is open. | 65 # Ensure only one tab is open. |
| 66 while len(self.browser.tabs) > 1: | 66 while len(self.browser.tabs) > 1: |
| 67 self.browser.tabs[-1].Close() | 67 self.browser.tabs[-1].Close() |
| 68 | 68 |
| 69 if not self.tab: | 69 if not self.tab: |
| 70 self.tab = self.browser.tabs[0] | 70 self.tab = self.browser.tabs[0] |
| 71 | 71 |
| 72 if self.first_page: | 72 if self.first_page: |
| 73 self.first_page = False | 73 self.first_page = False |
| 74 test.WillRunPageSet(self.tab) | |
| 75 | 74 |
| 76 def StopBrowser(self): | 75 def StopBrowser(self): |
| 77 self._is_tracing = False | 76 self._is_tracing = False |
| 78 | 77 |
| 79 if self.tab: | 78 if self.tab: |
| 80 self.tab.Disconnect() | 79 self.tab.Disconnect() |
| 81 self.tab = None | 80 self.tab = None |
| 82 | 81 |
| 83 if self.browser: | 82 if self.browser: |
| 84 self.browser.Close() | 83 self.browser.Close() |
| 85 self.browser = None | 84 self.browser = None |
| 86 | 85 |
| 87 # Restarting the state will also restart the wpr server. If we're | 86 # Restarting the state will also restart the wpr server. If we're |
| 88 # recording, we need to continue adding into the same wpr archive, | 87 # recording, we need to continue adding into the same wpr archive, |
| 89 # not overwrite it. | 88 # not overwrite it. |
| 90 self._append_to_existing_wpr = True | 89 self._append_to_existing_wpr = True |
| 91 | 90 |
| 92 def StartProfiling(self, page, options): | 91 def StartProfiling(self, page, options): |
| 93 output_file = os.path.join(options.profiler_dir, page.url_as_file_safe_name) | 92 output_file = os.path.join(options.profiler_dir, page.url_as_file_safe_name) |
| 94 if options.page_repeat != 1 or options.pageset_repeat != 1: | 93 if (options.page_repeat_iters != 1 or options.pageset_repeat_iters != 1 or |
| 94 options.page_repeat_secs or options.pageset_repeat_secs): | |
| 95 output_file = _GetSequentialFileName(output_file) | 95 output_file = _GetSequentialFileName(output_file) |
| 96 self.browser.StartProfiling(options, output_file) | 96 self.browser.StartProfiling(options, output_file) |
| 97 | 97 |
| 98 def StopProfiling(self): | 98 def StopProfiling(self): |
| 99 self.browser.StopProfiling() | 99 self.browser.StopProfiling() |
| 100 | 100 |
| 101 def StartTracing(self): | 101 def StartTracing(self): |
| 102 if not self.browser.supports_tracing: | 102 if not self.browser.supports_tracing: |
| 103 return | 103 return |
| 104 | 104 |
| 105 self._is_tracing = True | 105 self._is_tracing = True |
| 106 self.browser.StartTracing() | 106 self.browser.StartTracing() |
| 107 | 107 |
| 108 def StopTracing(self, page, options): | 108 def StopTracing(self, page, options): |
| 109 if not self._is_tracing: | 109 if not self._is_tracing: |
| 110 return | 110 return |
| 111 | 111 |
| 112 assert self.browser | 112 assert self.browser |
| 113 self._is_tracing = False | 113 self._is_tracing = False |
| 114 self.browser.StopTracing() | 114 self.browser.StopTracing() |
| 115 trace_result = self.browser.GetTraceResultAndReset() | 115 trace_result = self.browser.GetTraceResultAndReset() |
| 116 logging.info('Processing trace...') | 116 logging.info('Processing trace...') |
| 117 | 117 |
| 118 trace_file = os.path.join(options.trace_dir, page.url_as_file_safe_name) | 118 trace_file = os.path.join(options.trace_dir, page.url_as_file_safe_name) |
| 119 if options.page_repeat != 1 or options.pageset_repeat != 1: | 119 if (options.page_repeat_iters != 1 or options.pageset_repeat_iters != 1 or |
| 120 options.page_repeat_secs or options.pageset_repeat_secs): | |
| 120 trace_file = _GetSequentialFileName(trace_file) | 121 trace_file = _GetSequentialFileName(trace_file) |
| 121 trace_file += '.json' | 122 trace_file += '.json' |
| 122 | 123 |
| 123 with codecs.open(trace_file, 'w', | 124 with codecs.open(trace_file, 'w', |
| 124 encoding='utf-8') as trace_file: | 125 encoding='utf-8') as trace_file: |
| 125 trace_result.Serialize(trace_file) | 126 trace_result.Serialize(trace_file) |
| 126 logging.info('Trace saved.') | 127 logging.info('Trace saved.') |
| 127 | 128 |
| 128 | 129 |
| 129 class PageState(object): | 130 class PageState(object): |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 158 | 159 |
| 159 def CleanUpPage(self, page, tab): | 160 def CleanUpPage(self, page, tab): |
| 160 if page.credentials and self._did_login: | 161 if page.credentials and self._did_login: |
| 161 tab.browser.credentials.LoginNoLongerNeeded(tab, page.credentials) | 162 tab.browser.credentials.LoginNoLongerNeeded(tab, page.credentials) |
| 162 | 163 |
| 163 | 164 |
| 164 def AddCommandLineOptions(parser): | 165 def AddCommandLineOptions(parser): |
| 165 page_filter_module.PageFilter.AddCommandLineOptions(parser) | 166 page_filter_module.PageFilter.AddCommandLineOptions(parser) |
| 166 | 167 |
| 167 | 168 |
| 169 def _PrepareAndRunPage(test, page_set, options, page, credentials_path, | |
| 170 possible_browser, results, state): | |
| 171 if options.wpr_mode != wpr_modes.WPR_RECORD: | |
| 172 if page.archive_path and os.path.isfile(page.archive_path): | |
| 173 possible_browser.options.wpr_mode = wpr_modes.WPR_REPLAY | |
| 174 else: | |
| 175 possible_browser.options.wpr_mode = wpr_modes.WPR_OFF | |
| 176 results_for_current_run = results | |
| 177 if state.first_page and test.discard_first_result: | |
| 178 # If discarding results, substitute a dummy object. | |
| 179 results_for_current_run = type(results)() | |
| 180 results_for_current_run.StartTest(page) | |
| 181 tries = 3 | |
| 182 while tries: | |
| 183 try: | |
| 184 state.StartBrowser(test, page_set, page, possible_browser, | |
| 185 credentials_path, page.archive_path) | |
| 186 | |
| 187 _WaitForThermalThrottlingIfNeeded(state.browser.platform) | |
| 188 | |
| 189 if options.trace_dir: | |
| 190 state.StartTracing() | |
| 191 if options.profiler_dir: | |
| 192 state.StartProfiling(page, options) | |
| 193 | |
| 194 try: | |
| 195 _RunPage(test, page, state.tab, results_for_current_run, options) | |
| 196 _CheckThermalThrottling(state.browser.platform) | |
| 197 except exceptions.TabCrashException: | |
| 198 stdout = '' | |
| 199 if not options.show_stdout: | |
| 200 stdout = state.browser.GetStandardOutput() | |
| 201 stdout = (('\nStandard Output:\n') + | |
| 202 ('*' * 80) + | |
| 203 '\n\t' + stdout.replace('\n', '\n\t') + '\n' + | |
| 204 ('*' * 80)) | |
| 205 logging.warning('Tab crashed: %s%s', page.url, stdout) | |
| 206 state.StopBrowser() | |
| 207 | |
| 208 if options.trace_dir: | |
| 209 state.StopTracing(page, options) | |
| 210 if options.profiler_dir: | |
| 211 state.StopProfiling() | |
| 212 | |
| 213 if test.NeedsBrowserRestartAfterEachRun(state.tab): | |
| 214 state.StopBrowser() | |
| 215 | |
| 216 break | |
| 217 except exceptions.BrowserGoneException: | |
| 218 logging.warning('Lost connection to browser. Retrying.') | |
| 219 state.StopBrowser() | |
| 220 tries -= 1 | |
| 221 if not tries: | |
| 222 logging.error('Lost connection to browser 3 times. Failing.') | |
| 223 raise | |
| 224 results_for_current_run.StopTest(page) | |
| 225 | |
| 226 | |
| 227 def _RunRepeatLoop(test, page_set, options, credentials_path, possible_browser, | |
| 228 results, state, pages): | |
| 229 """Repeats each page or pageset for a specified time or iteration limit | |
|
dennis_jeffrey
2013/07/12 21:36:18
nit: add period at end of sentence
edmundyan
2013/07/12 22:10:21
Done.
| |
| 230 | |
| 231 Uses the '--pageset-repeat' and '--page-repeat' cmd line options | |
|
dennis_jeffrey
2013/07/12 21:36:18
nit: add period at end of sentence
edmundyan
2013/07/12 22:10:21
Done.
| |
| 232 """ | |
| 233 pageset_start_time = time.time() | |
| 234 pageset_iters = 0 | |
| 235 while True: | |
| 236 if (options.pageset_repeat_secs and | |
| 237 time.time() - pageset_start_time > options.pageset_repeat_secs): | |
| 238 break | |
| 239 elif (options.pageset_repeat_iters != 1 and | |
| 240 pageset_iters >= options.pageset_repeat_iters): | |
| 241 break | |
| 242 pageset_iters += 1 | |
| 243 for page in pages: | |
| 244 page_start_time = time.time() | |
| 245 page_iters = 0 | |
| 246 while True: | |
| 247 if (options.page_repeat_secs and | |
| 248 time.time() - page_start_time > options.page_repeat_secs): | |
| 249 break | |
| 250 elif (options.page_repeat_iters != 1 and | |
| 251 page_iters >= options.page_repeat_iters): | |
| 252 break | |
| 253 page_iters += 1 | |
| 254 _PrepareAndRunPage(test, page_set, options, page, credentials_path, | |
| 255 possible_browser, results, state) | |
| 256 | |
|
dennis_jeffrey
2013/07/12 21:36:18
add 1 more blank line here
edmundyan
2013/07/12 22:10:21
Done.
| |
| 168 def Run(test, page_set, options): | 257 def Run(test, page_set, options): |
| 169 """Runs a given test against a given page_set with the given options.""" | 258 """Runs a given test against a given page_set with the given options.""" |
| 170 results = test.PrepareResults(options) | 259 results = test.PrepareResults(options) |
| 171 | 260 |
| 172 # Create a possible_browser with the given options. | 261 # Create a possible_browser with the given options. |
| 173 test.CustomizeBrowserOptions(options) | 262 test.CustomizeBrowserOptions(options) |
| 174 possible_browser = browser_finder.FindBrowser(options) | 263 possible_browser = browser_finder.FindBrowser(options) |
| 175 if not possible_browser: | 264 if not possible_browser: |
| 176 raise Exception('No browser found.\n' | 265 raise Exception('No browser found.\n' |
| 177 'Use --browser=list to figure out which are available.') | 266 'Use --browser=list to figure out which are available.') |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 196 options.browser_user_agent_type = page_set.user_agent_type | 285 options.browser_user_agent_type = page_set.user_agent_type |
| 197 | 286 |
| 198 for page in pages: | 287 for page in pages: |
| 199 test.CustomizeBrowserOptionsForPage(page, possible_browser.options) | 288 test.CustomizeBrowserOptionsForPage(page, possible_browser.options) |
| 200 | 289 |
| 201 _ValidateOrCreateEmptyDirectory('--trace-dir', options.trace_dir) | 290 _ValidateOrCreateEmptyDirectory('--trace-dir', options.trace_dir) |
| 202 _ValidateOrCreateEmptyDirectory('--profiler-dir', options.profiler_dir) | 291 _ValidateOrCreateEmptyDirectory('--profiler-dir', options.profiler_dir) |
| 203 | 292 |
| 204 state = _RunState() | 293 state = _RunState() |
| 205 # TODO(dtu): Move results creation and results_for_current_run into RunState. | 294 # TODO(dtu): Move results creation and results_for_current_run into RunState. |
| 206 results_for_current_run = results | |
| 207 | 295 |
| 208 try: | 296 try: |
| 209 for page in pages: | 297 test.WillRunTest(state.tab) |
| 210 if options.wpr_mode != wpr_modes.WPR_RECORD: | 298 _RunRepeatLoop(test, page_set, options, credentials_path, possible_browser, |
| 211 if page.archive_path and os.path.isfile(page.archive_path): | 299 results, state, pages) |
| 212 possible_browser.options.wpr_mode = wpr_modes.WPR_REPLAY | 300 test.DidRunTest(state.tab, results) |
| 213 else: | |
| 214 possible_browser.options.wpr_mode = wpr_modes.WPR_OFF | |
| 215 results_for_current_run = results | |
| 216 if state.first_page and test.discard_first_result: | |
| 217 # If discarding results, substitute a dummy object. | |
| 218 results_for_current_run = type(results)() | |
| 219 results_for_current_run.StartTest(page) | |
| 220 tries = 3 | |
| 221 while tries: | |
| 222 try: | |
| 223 state.StartBrowser(test, page_set, page, possible_browser, | |
| 224 credentials_path, page.archive_path) | |
| 225 | |
| 226 _WaitForThermalThrottlingIfNeeded(state.browser.platform) | |
| 227 | |
| 228 if options.trace_dir: | |
| 229 state.StartTracing() | |
| 230 if options.profiler_dir: | |
| 231 state.StartProfiling(page, options) | |
| 232 | |
| 233 try: | |
| 234 _RunPage(test, page, state.tab, results_for_current_run, options) | |
| 235 _CheckThermalThrottling(state.browser.platform) | |
| 236 except exceptions.TabCrashException: | |
| 237 stdout = '' | |
| 238 if not options.show_stdout: | |
| 239 stdout = state.browser.GetStandardOutput() | |
| 240 stdout = (('\nStandard Output:\n') + | |
| 241 ('*' * 80) + | |
| 242 '\n\t' + stdout.replace('\n', '\n\t') + '\n' + | |
| 243 ('*' * 80)) | |
| 244 logging.warning('Tab crashed: %s%s', page.url, stdout) | |
| 245 state.StopBrowser() | |
| 246 | |
| 247 if options.trace_dir: | |
| 248 state.StopTracing(page, options) | |
| 249 if options.profiler_dir: | |
| 250 state.StopProfiling() | |
| 251 | |
| 252 if test.NeedsBrowserRestartAfterEachRun(state.tab): | |
| 253 state.StopBrowser() | |
| 254 | |
| 255 break | |
| 256 except exceptions.BrowserGoneException: | |
| 257 logging.warning('Lost connection to browser. Retrying.') | |
| 258 state.StopBrowser() | |
| 259 tries -= 1 | |
| 260 if not tries: | |
| 261 logging.error('Lost connection to browser 3 times. Failing.') | |
| 262 raise | |
| 263 results_for_current_run.StopTest(page) | |
| 264 test.DidRunPageSet(state.tab, results_for_current_run) | |
| 265 finally: | 301 finally: |
| 266 state.StopBrowser() | 302 state.StopBrowser() |
| 267 | 303 |
| 268 return results | 304 return results |
| 269 | 305 |
| 270 | 306 |
| 271 def _ShuffleAndFilterPageSet(page_set, options): | 307 def _ShuffleAndFilterPageSet(page_set, options): |
| 272 if options.pageset_shuffle_order_file and not options.pageset_shuffle: | 308 if options.pageset_shuffle_order_file and not options.pageset_shuffle: |
| 273 raise Exception('--pageset-shuffle-order-file requires --pageset-shuffle.') | 309 raise Exception('--pageset-shuffle-order-file requires --pageset-shuffle.') |
| 274 | 310 |
| 275 if options.pageset_shuffle_order_file: | 311 if options.pageset_shuffle_order_file: |
| 276 return page_set.ReorderPageSet(options.pageset_shuffle_order_file) | 312 return page_set.ReorderPageSet(options.pageset_shuffle_order_file) |
| 277 | 313 |
| 278 page_filter = page_filter_module.PageFilter(options) | 314 page_filter = page_filter_module.PageFilter(options) |
| 279 pages = [page for page in page_set.pages[:] | 315 pages = [page for page in page_set.pages[:] |
| 280 if not page.disabled and page_filter.IsSelected(page)] | 316 if not page.disabled and page_filter.IsSelected(page)] |
| 281 | 317 |
| 282 if options.pageset_shuffle: | 318 if options.pageset_shuffle: |
| 283 random.Random().shuffle(pages) | 319 random.Random().shuffle(pages) |
| 284 return [page | 320 |
| 285 for _ in xrange(int(options.pageset_repeat)) | 321 return pages |
| 286 for page in pages | |
| 287 for _ in xrange(int(options.page_repeat))] | |
| 288 | 322 |
| 289 | 323 |
| 290 def _CheckArchives(page_set, pages, results): | 324 def _CheckArchives(page_set, pages, results): |
| 291 """Returns a subset of pages that are local or have WPR archives. | 325 """Returns a subset of pages that are local or have WPR archives. |
| 292 | 326 |
| 293 Logs warnings if any are missing.""" | 327 Logs warnings if any are missing.""" |
| 294 page_set_has_live_sites = False | 328 page_set_has_live_sites = False |
| 295 for page in pages: | 329 for page in pages: |
| 296 parsed_url = urlparse.urlparse(page.url) | 330 parsed_url = urlparse.urlparse(page.url) |
| 297 if parsed_url.scheme != 'chrome' and parsed_url.scheme != 'file': | 331 if parsed_url.scheme != 'chrome' and parsed_url.scheme != 'file': |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 416 logging.error('Device is thermally throttled before running ' | 450 logging.error('Device is thermally throttled before running ' |
| 417 'performance tests, results will vary.') | 451 'performance tests, results will vary.') |
| 418 | 452 |
| 419 | 453 |
| 420 def _CheckThermalThrottling(platform): | 454 def _CheckThermalThrottling(platform): |
| 421 if not platform.CanMonitorThermalThrottling(): | 455 if not platform.CanMonitorThermalThrottling(): |
| 422 return | 456 return |
| 423 if platform.HasBeenThermallyThrottled(): | 457 if platform.HasBeenThermallyThrottled(): |
| 424 logging.error('Device has been thermally throttled during ' | 458 logging.error('Device has been thermally throttled during ' |
| 425 'performance tests, results will vary.') | 459 'performance tests, results will vary.') |
| OLD | NEW |