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. | |
230 | |
231 Uses the '--pageset-repeat' and '--page-repeat' cmd line options. | |
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 | |
257 | |
168 def Run(test, page_set, options): | 258 def Run(test, page_set, options): |
169 """Runs a given test against a given page_set with the given options.""" | 259 """Runs a given test against a given page_set with the given options.""" |
170 results = test.PrepareResults(options) | 260 results = test.PrepareResults(options) |
171 | 261 |
172 # Create a possible_browser with the given options. | 262 # Create a possible_browser with the given options. |
173 test.CustomizeBrowserOptions(options) | 263 test.CustomizeBrowserOptions(options) |
174 possible_browser = browser_finder.FindBrowser(options) | 264 possible_browser = browser_finder.FindBrowser(options) |
175 if not possible_browser: | 265 if not possible_browser: |
176 raise Exception('No browser found.\n' | 266 raise Exception('No browser found.\n' |
177 'Use --browser=list to figure out which are available.') | 267 '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 | 286 options.browser_user_agent_type = page_set.user_agent_type |
197 | 287 |
198 for page in pages: | 288 for page in pages: |
199 test.CustomizeBrowserOptionsForPage(page, possible_browser.options) | 289 test.CustomizeBrowserOptionsForPage(page, possible_browser.options) |
200 | 290 |
201 _ValidateOrCreateEmptyDirectory('--trace-dir', options.trace_dir) | 291 _ValidateOrCreateEmptyDirectory('--trace-dir', options.trace_dir) |
202 _ValidateOrCreateEmptyDirectory('--profiler-dir', options.profiler_dir) | 292 _ValidateOrCreateEmptyDirectory('--profiler-dir', options.profiler_dir) |
203 | 293 |
204 state = _RunState() | 294 state = _RunState() |
205 # TODO(dtu): Move results creation and results_for_current_run into RunState. | 295 # TODO(dtu): Move results creation and results_for_current_run into RunState. |
206 results_for_current_run = results | |
207 | 296 |
208 try: | 297 try: |
209 for page in pages: | 298 test.WillRunTest(state.tab) |
210 if options.wpr_mode != wpr_modes.WPR_RECORD: | 299 _RunRepeatLoop(test, page_set, options, credentials_path, possible_browser, |
211 if page.archive_path and os.path.isfile(page.archive_path): | 300 results, state, pages) |
212 possible_browser.options.wpr_mode = wpr_modes.WPR_REPLAY | 301 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: | 302 finally: |
266 state.StopBrowser() | 303 state.StopBrowser() |
267 | 304 |
268 return results | 305 return results |
269 | 306 |
270 | 307 |
271 def _ShuffleAndFilterPageSet(page_set, options): | 308 def _ShuffleAndFilterPageSet(page_set, options): |
272 if options.pageset_shuffle_order_file and not options.pageset_shuffle: | 309 if options.pageset_shuffle_order_file and not options.pageset_shuffle: |
273 raise Exception('--pageset-shuffle-order-file requires --pageset-shuffle.') | 310 raise Exception('--pageset-shuffle-order-file requires --pageset-shuffle.') |
274 | 311 |
275 if options.pageset_shuffle_order_file: | 312 if options.pageset_shuffle_order_file: |
276 return page_set.ReorderPageSet(options.pageset_shuffle_order_file) | 313 return page_set.ReorderPageSet(options.pageset_shuffle_order_file) |
277 | 314 |
278 page_filter = page_filter_module.PageFilter(options) | 315 page_filter = page_filter_module.PageFilter(options) |
279 pages = [page for page in page_set.pages[:] | 316 pages = [page for page in page_set.pages[:] |
280 if not page.disabled and page_filter.IsSelected(page)] | 317 if not page.disabled and page_filter.IsSelected(page)] |
281 | 318 |
282 if options.pageset_shuffle: | 319 if options.pageset_shuffle: |
283 random.Random().shuffle(pages) | 320 random.Random().shuffle(pages) |
284 return [page | 321 |
285 for _ in xrange(int(options.pageset_repeat)) | 322 return pages |
286 for page in pages | |
287 for _ in xrange(int(options.page_repeat))] | |
288 | 323 |
289 | 324 |
290 def _CheckArchives(page_set, pages, results): | 325 def _CheckArchives(page_set, pages, results): |
291 """Returns a subset of pages that are local or have WPR archives. | 326 """Returns a subset of pages that are local or have WPR archives. |
292 | 327 |
293 Logs warnings if any are missing.""" | 328 Logs warnings if any are missing.""" |
294 page_set_has_live_sites = False | 329 page_set_has_live_sites = False |
295 for page in pages: | 330 for page in pages: |
296 parsed_url = urlparse.urlparse(page.url) | 331 parsed_url = urlparse.urlparse(page.url) |
297 if parsed_url.scheme != 'chrome' and parsed_url.scheme != 'file': | 332 if parsed_url.scheme != 'chrome' and parsed_url.scheme != 'file': |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
339 for page in pages_missing_archive_path + pages_missing_archive_data: | 374 for page in pages_missing_archive_path + pages_missing_archive_data: |
340 results.StartTest(page) | 375 results.StartTest(page) |
341 results.AddErrorMessage(page, 'Page set archive doesn\'t exist.') | 376 results.AddErrorMessage(page, 'Page set archive doesn\'t exist.') |
342 results.StopTest(page) | 377 results.StopTest(page) |
343 | 378 |
344 return [page for page in pages if page not in | 379 return [page for page in pages if page not in |
345 pages_missing_archive_path + pages_missing_archive_data] | 380 pages_missing_archive_path + pages_missing_archive_data] |
346 | 381 |
347 | 382 |
348 def _RunPage(test, page, tab, results, options): | 383 def _RunPage(test, page, tab, results, options): |
349 if not test.CanRunForPage(page): | 384 if not test.CanRunForPage(page): |
edmundyan1
2013/07/16 21:17:37
Kind of a bug. If we ran --page-repeat=100, we ch
| |
350 logging.warning('Skipping test: it cannot run for %s', page.url) | 385 logging.warning('Skipping test: it cannot run for %s', page.url) |
351 results.AddSkip(page, 'Test cannot run') | 386 results.AddSkip(page, 'Test cannot run') |
352 return | 387 return |
353 | 388 |
354 logging.info('Running %s' % page.url) | 389 logging.info('Running %s' % page.url) |
355 | 390 |
356 page_state = PageState() | 391 page_state = PageState() |
357 | 392 |
358 try: | 393 try: |
359 page_state.PreparePage(page, tab, test) | 394 page_state.PreparePage(page, tab, test) |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
416 logging.error('Device is thermally throttled before running ' | 451 logging.error('Device is thermally throttled before running ' |
417 'performance tests, results will vary.') | 452 'performance tests, results will vary.') |
418 | 453 |
419 | 454 |
420 def _CheckThermalThrottling(platform): | 455 def _CheckThermalThrottling(platform): |
421 if not platform.CanMonitorThermalThrottling(): | 456 if not platform.CanMonitorThermalThrottling(): |
422 return | 457 return |
423 if platform.HasBeenThermallyThrottled(): | 458 if platform.HasBeenThermallyThrottled(): |
424 logging.error('Device has been thermally throttled during ' | 459 logging.error('Device has been thermally throttled during ' |
425 'performance tests, results will vary.') | 460 'performance tests, results will vary.') |
OLD | NEW |