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

Side by Side Diff: tools/telemetry/telemetry/page/page_runner.py

Issue 12294002: Revert 182991 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 10 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
(Empty)
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
3 # found in the LICENSE file.
4 import codecs
5 import logging
6 import os
7 import time
8 import traceback
9 import urlparse
10 import random
11
12 from telemetry.core import util
13 from telemetry.core import wpr_modes
14 from telemetry.core import exceptions
15 from telemetry.page import page_filter as page_filter_module
16 from telemetry.page import page_test
17
18 class PageState(object):
19 def __init__(self):
20 self.did_login = False
21
22 class _RunState(object):
23 def __init__(self):
24 self.first_browser = True
25 self.browser = None
26 self.tab = None
27 self.is_tracing = False
28
29 def Close(self):
30 self.is_tracing = False
31
32 if self.tab:
33 self.tab.Disconnect()
34 self.tab = None
35
36 if self.browser:
37 self.browser.Close()
38 self.browser = None
39
40 def _ShuffleAndFilterPageSet(page_set, options):
41 if options.pageset_shuffle_order_file and not options.pageset_shuffle:
42 raise Exception('--pageset-shuffle-order-file requires --pageset-shuffle.')
43
44 if options.pageset_shuffle_order_file:
45 return page_set.ReorderPageSet(options.pageset_shuffle_order_file)
46
47 page_filter = page_filter_module.PageFilter(options)
48 pages = [page for page in page_set.pages[:]
49 if not page.disabled and page_filter.IsSelected(page)]
50
51 if options.pageset_shuffle:
52 random.Random().shuffle(pages)
53 return [page
54 for _ in xrange(int(options.pageset_repeat))
55 for page in pages
56 for _ in xrange(int(options.page_repeat))]
57
58 class PageRunner(object):
59 """Runs a given test against a given test."""
60 def __init__(self, page_set):
61 self.page_set = page_set
62
63 def __enter__(self):
64 return self
65
66 def __exit__(self, *args):
67 self.Close()
68
69 def Run(self, options, possible_browser, test, results):
70 # Check if we can run against WPR.
71 for page in self.page_set.pages:
72 parsed_url = urlparse.urlparse(page.url)
73 if parsed_url.scheme == 'file':
74 continue
75 if not page.archive_path:
76 logging.warning("""
77 No page set archive provided for the page %s. Benchmarking against live sites!
78 Results won't be repeatable or comparable.
79 """, page.url)
80 elif options.wpr_mode != wpr_modes.WPR_RECORD:
81 # The page has an archive, and we're not recording.
82 if not os.path.isfile(page.archive_path):
83 logging.warning("""
84 The page set archive %s for page %s does not exist, benchmarking against live
85 sites! Results won't be repeatable or comparable.
86
87 To fix this, either add svn-internal to your .gclient using
88 http://goto/read-src-internal, or create a new archive using record_wpr.
89 """, os.path.relpath(page.archive_path), page.url)
90
91 # Verify credentials path.
92 credentials_path = None
93 if self.page_set.credentials_path:
94 credentials_path = os.path.join(os.path.dirname(self.page_set.file_path),
95 self.page_set.credentials_path)
96 if not os.path.exists(credentials_path):
97 credentials_path = None
98
99 # Set up user agent.
100 if self.page_set.user_agent_type:
101 options.browser_user_agent_type = self.page_set.user_agent_type
102
103 for page in self.page_set:
104 test.CustomizeBrowserOptionsForPage(page, possible_browser.options)
105
106 # Check tracing directory.
107 if options.trace_dir:
108 if not os.path.exists(options.trace_dir):
109 os.mkdir(options.trace_dir)
110 if not os.path.isdir(options.trace_dir):
111 raise Exception('--trace-dir isn\'t a directory: %s' %
112 options.trace_dir)
113 elif os.listdir(options.trace_dir):
114 raise Exception('Trace directory isn\'t empty: %s' % options.trace_dir)
115
116 # Reorder page set based on options.
117 pages = _ShuffleAndFilterPageSet(self.page_set, options)
118
119 state = _RunState()
120 last_archive_path = None
121 try:
122 for page in pages:
123 if options.wpr_mode != wpr_modes.WPR_RECORD:
124 if page.archive_path and os.path.isfile(page.archive_path):
125 possible_browser.options.wpr_mode = wpr_modes.WPR_REPLAY
126 else:
127 possible_browser.options.wpr_mode = wpr_modes.WPR_OFF
128 if last_archive_path != page.archive_path:
129 state.Close()
130 state = _RunState()
131 last_archive_path = page.archive_path
132 tries = 3
133 while tries:
134 try:
135 if not state.browser:
136 self._SetupBrowser(state, test, possible_browser,
137 credentials_path, page.archive_path)
138 if not state.tab:
139 if len(state.browser.tabs) == 0:
140 state.browser.tabs.New()
141 state.tab = state.browser.tabs[0]
142 if options.trace_dir:
143 self._SetupTracingTab(state)
144
145 try:
146 self._RunPage(options, page, state.tab, test, results)
147 except exceptions.TabCrashException:
148 stdout = ''
149 if not options.show_stdout:
150 stdout = state.browser.GetStandardOutput()
151 stdout = (('\nStandard Output:\n') +
152 ('*' * 80) +
153 '\n\t' + stdout.replace('\n', '\n\t') + '\n' +
154 ('*' * 80))
155 logging.warning('Tab crashed: %s%s', page.url, stdout)
156 state.Close()
157
158 if options.trace_dir:
159 self._EndTracing(state, options, page)
160
161 if test.needs_browser_restart_after_each_run:
162 state.Close()
163
164 break
165 except exceptions.BrowserGoneException:
166 logging.warning('Lost connection to browser. Retrying.')
167 state.Close()
168 tries -= 1
169 if not tries:
170 logging.error('Lost connection to browser 3 times. Failing.')
171 raise
172 finally:
173 state.Close()
174
175 def _RunPage(self, options, page, tab, test, results):
176 if not test.CanRunForPage(page):
177 logging.warning('Skiping test: it cannot run for %s', page.url)
178 results.AddSkippedPage(page, 'Test cannot run', '')
179 return
180
181 logging.info('Running %s' % page.url)
182
183 page_state = PageState()
184 try:
185 did_prepare = self._PreparePage(page, tab, page_state, test, results)
186 except util.TimeoutException, ex:
187 logging.warning('Timed out waiting for reply on %s. This is unusual.',
188 page.url)
189 results.AddFailure(page, ex, traceback.format_exc())
190 return
191 except exceptions.TabCrashException, ex:
192 results.AddFailure(page, ex, traceback.format_exc())
193 raise
194 except exceptions.BrowserGoneException:
195 raise
196 except Exception, ex:
197 logging.error('Unexpected failure while running %s: %s',
198 page.url, traceback.format_exc())
199 self._CleanUpPage(page, tab, page_state)
200 raise
201
202 if not did_prepare:
203 self._CleanUpPage(page, tab, page_state)
204 return
205
206 try:
207 test.Run(options, page, tab, results)
208 except page_test.Failure, ex:
209 logging.info('%s: %s', ex, page.url)
210 results.AddFailure(page, ex, traceback.format_exc())
211 return
212 except util.TimeoutException, ex:
213 logging.warning('Timed out while running %s', page.url)
214 results.AddFailure(page, ex, traceback.format_exc())
215 return
216 except exceptions.TabCrashException, ex:
217 results.AddFailure(page, ex, traceback.format_exc())
218 raise
219 except exceptions.BrowserGoneException:
220 raise
221 except Exception, ex:
222 logging.error('Unexpected failure while running %s: %s',
223 page.url, traceback.format_exc())
224 raise
225 finally:
226 self._CleanUpPage(page, tab, page_state)
227
228 results.AddSuccess(page)
229
230 def Close(self):
231 pass
232
233 def _SetupBrowser(self, state, test, possible_browser, credentials_path,
234 archive_path):
235 assert not state.tab
236 state.browser = possible_browser.Create()
237 state.browser.credentials.credentials_path = credentials_path
238 test.SetUpBrowser(state.browser)
239
240 if state.first_browser:
241 state.browser.credentials.WarnIfMissingCredentials(self.page_set)
242 state.first_browser = False
243
244 state.browser.SetReplayArchivePath(archive_path)
245
246 def _SetupTracingTab(self, state):
247 if state.browser.supports_tracing:
248 state.is_tracing = True
249 state.browser.StartTracing()
250
251 def _EndTracing(self, state, options, page):
252 if state.is_tracing:
253 assert state.browser
254 state.is_tracing = False
255 state.browser.StopTracing()
256 trace_result = state.browser.GetTraceResultAndReset()
257 logging.info('Processing trace...')
258
259 trace_file_base = os.path.join(
260 options.trace_dir, page.url_as_file_safe_name)
261
262 if options.page_repeat != 1 or options.pageset_repeat != 1:
263 trace_file_index = 0
264
265 while True:
266 trace_file = '%s_%03d.json' % (trace_file_base, trace_file_index)
267 if not os.path.exists(trace_file):
268 break
269 trace_file_index = trace_file_index + 1
270 else:
271 trace_file = '%s.json' % trace_file_base
272 with codecs.open(trace_file, 'w',
273 encoding='utf-8') as trace_file:
274 trace_result.Serialize(trace_file)
275 logging.info('Trace saved.')
276
277 def _PreparePage(self, page, tab, page_state, test, results):
278 parsed_url = urlparse.urlparse(page.url)
279 if parsed_url[0] == 'file':
280 dirname, filename = page.url_base_dir_and_file
281 tab.browser.SetHTTPServerDirectory(dirname)
282 target_side_url = tab.browser.http_server.UrlOf(filename)
283 else:
284 target_side_url = page.url
285
286 if page.credentials:
287 page_state.did_login = tab.browser.credentials.LoginNeeded(
288 tab, page.credentials)
289 if not page_state.did_login:
290 msg = 'Could not login to %s on %s' % (page.credentials,
291 target_side_url)
292 logging.info(msg)
293 results.AddFailure(page, msg, "")
294 return False
295
296 test.WillNavigateToPage(page, tab)
297 tab.Navigate(target_side_url)
298 test.DidNavigateToPage(page, tab)
299
300 # Wait for unpredictable redirects.
301 if page.wait_time_after_navigate:
302 time.sleep(page.wait_time_after_navigate)
303 page.WaitToLoad(tab, 60)
304 tab.WaitForDocumentReadyStateToBeInteractiveOrBetter()
305
306 return True
307
308 def _CleanUpPage(self, page, tab, page_state): # pylint: disable=R0201
309 if page.credentials and page_state.did_login:
310 tab.browser.credentials.LoginNoLongerNeeded(tab, page.credentials)
311 try:
312 tab.EvaluateJavaScript("""window.chrome && chrome.benchmarking &&
313 chrome.benchmarking.closeConnections()""")
314 except Exception:
315 pass
316
317 @staticmethod
318 def AddCommandLineOptions(parser):
319 page_filter_module.PageFilter.AddCommandLineOptions(parser)
OLDNEW
« no previous file with comments | « tools/telemetry/telemetry/page/page_filter.py ('k') | tools/telemetry/telemetry/page/page_runner_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698