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

Side by Side Diff: tools/chrome_proxy/webdriver/common.py

Issue 2578713002: Add logging to TestDriver (Closed)
Patch Set: Nits. Created 4 years 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2016 The Chromium Authors. All rights reserved. 1 # Copyright 2016 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 argparse 5 import argparse
6 import json 6 import json
7 import logging
7 import os 8 import os
8 import re 9 import re
9 import socket 10 import socket
10 import shlex 11 import shlex
11 import sys 12 import sys
12 import time 13 import time
13 import traceback 14 import traceback
14 import unittest 15 import unittest
15 16
16 sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 17 sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir,
17 os.pardir, 'third_party', 'webdriver', 'pylib')) 18 os.pardir, 'third_party', 'webdriver', 'pylib'))
18 from selenium import webdriver 19 from selenium import webdriver
19 from selenium.webdriver.chrome.options import Options 20 from selenium.webdriver.chrome.options import Options
20 21
21 # TODO(robertogden): Add logging.
22
23
24 def ParseFlags(): 22 def ParseFlags():
25 """Parses the given command line arguments. 23 """Parses the given command line arguments.
26 24
27 Returns: 25 Returns:
28 A new Namespace object with class properties for each argument added below. 26 A new Namespace object with class properties for each argument added below.
29 See pydoc for argparse. 27 See pydoc for argparse.
30 """ 28 """
31 parser = argparse.ArgumentParser() 29 parser = argparse.ArgumentParser()
32 parser.add_argument('--browser_args', type=str, help='Override browser flags ' 30 parser.add_argument('--browser_args', type=str, help='Override browser flags '
33 'in code with these flags') 31 'in code with these flags')
34 parser.add_argument('--via_header_value', 32 parser.add_argument('--via_header_value',
35 default='1.1 Chrome-Compression-Proxy', help='What the via should match to ' 33 default='1.1 Chrome-Compression-Proxy', help='What the via should match to '
36 'be considered valid') 34 'be considered valid')
37 parser.add_argument('--android', help='If given, attempts to run the test on ' 35 parser.add_argument('--android', help='If given, attempts to run the test on '
38 'Android via adb. Ignores usage of --chrome_exec', action='store_true') 36 'Android via adb. Ignores usage of --chrome_exec', action='store_true')
39 parser.add_argument('--android_package', 37 parser.add_argument('--android_package',
40 default='com.android.chrome', help='Set the android package for Chrome') 38 default='com.android.chrome', help='Set the android package for Chrome')
41 parser.add_argument('--chrome_exec', type=str, help='The path to ' 39 parser.add_argument('--chrome_exec', type=str, help='The path to '
42 'the Chrome or Chromium executable') 40 'the Chrome or Chromium executable')
43 parser.add_argument('chrome_driver', type=str, help='The path to ' 41 parser.add_argument('chrome_driver', type=str, help='The path to '
44 'the ChromeDriver executable. If not given, the default system chrome ' 42 'the ChromeDriver executable. If not given, the default system chrome '
45 'will be used.') 43 'will be used.')
46 parser.add_argument('--disable_buffer', help='Causes stdout and stderr from ' 44 parser.add_argument('--disable_buffer', help='Causes stdout and stderr from '
47 'tests to output normally. Otherwise, the standard output and standard ' 45 'tests to output normally. Otherwise, the standard output and standard '
48 'error streams are buffered during the test run, and output during a ' 46 'error streams are buffered during the test run, and output from a '
49 'passing test is discarded. Output will always be echoed normally on test ' 47 'passing test is discarded. Output will always be echoed normally on test '
50 'fail or error and is added to the failure messages.', action='store_true') 48 'fail or error and is added to the failure messages.', action='store_true')
51 parser.add_argument('-c', '--catch', help='Control-C during the test run ' 49 parser.add_argument('-c', '--catch', help='Control-C during the test run '
52 'waits for the current test to end and then reports all the results so ' 50 'waits for the current test to end and then reports all the results so '
53 'far. A second Control-C raises the normal KeyboardInterrupt exception.', 51 'far. A second Control-C raises the normal KeyboardInterrupt exception.',
54 action='store_true') 52 action='store_true')
55 parser.add_argument('-f', '--failfast', help='Stop the test run on the first ' 53 parser.add_argument('-f', '--failfast', help='Stop the test run on the first '
56 'error or failure.', action='store_true') 54 'error or failure.', action='store_true')
57 # TODO(robertogden): Log sys.argv here. 55 parser.add_argument('--logging_level', choices=['DEBUG', 'INFO', 'WARN',
56 'ERROR', 'CRIT'], default='ERROR', help='The logging verbosity for log '
57 'messages, printed to stderr. To see stderr logging output during a '
58 'successful test run, also pass --disable_buffer. Default=ERROR')
59 parser.add_argument('--log_file', help='If given, write logging statements '
60 'to the given file instead of stderr.')
58 return parser.parse_args(sys.argv[1:]) 61 return parser.parse_args(sys.argv[1:])
59 62
63 def GetLogger(name='common'):
64 """Creates a Logger instance with the given name and returns it.
65
66 If a logger has already been created with the same name, that instance is
67 returned instead.
68
69 Args:
70 name: The name of the logger to return.
71 Returns:
72 A logger with the given name.
73 """
74 logger = logging.getLogger(name)
75 if hasattr(logger, "initialized"):
76 return logger
77 logging_level = ParseFlags().logging_level
78 if logging_level == 'DEBUG':
79 logger.setLevel(logging.DEBUG)
80 elif logging_level == 'INFO':
81 logger.setLevel(logging.INFO)
82 elif logging_level == 'WARN':
83 logger.setLevel(logging.WARNING)
84 elif logging_level == 'ERROR':
85 logger.setLevel(logging.ERROR)
86 elif logging_level == 'CRIT':
87 logger.setLevel(logging.CRITICAL)
88 else:
89 logger.setLevel(logging.NOTSET)
90 formatter = logging.Formatter('%(asctime)s %(funcName)s() %(levelname)s: '
91 '%(message)s')
92 if ParseFlags().log_file:
93 fh = logging.FileHandler(ParseFlags().log_file)
94 fh.setFormatter(formatter)
95 logger.addHandler(fh)
96 else:
97 ch = logging.StreamHandler(sys.stderr)
98 ch.setFormatter(formatter)
99 logger.addHandler(ch)
100 logger.initialized = True
101 return logger
60 102
61 class TestDriver: 103 class TestDriver:
62 """The main driver for an integration test. 104 """The main driver for an integration test.
63 105
64 This class is the tool that is used by every integration test to interact with 106 This class is the tool that is used by every integration test to interact with
65 the Chromium browser and validate proper functionality. This class sits on top 107 the Chromium browser and validate proper functionality. This class sits on top
66 of the Selenium Chrome Webdriver with added utility and helper functions for 108 of the Selenium Chrome Webdriver with added utility and helper functions for
67 Chrome-Proxy. This class should be used with Python's 'with' operator. 109 Chrome-Proxy. This class should be used with Python's 'with' operator.
68 110
69 Attributes: 111 Attributes:
70 _flags: A Namespace object from the call to ParseFlags() 112 _flags: A Namespace object from the call to ParseFlags()
71 _driver: A reference to the driver object from the Chrome Driver library. 113 _driver: A reference to the driver object from the Chrome Driver library.
72 _chrome_args: A set of string arguments to start Chrome with. 114 _chrome_args: A set of string arguments to start Chrome with.
73 _url: The string URL that Chrome will navigate to for this test. 115 _url: The string URL that Chrome will navigate to for this test.
74 """ 116 """
75 117
76 def __init__(self): 118 def __init__(self):
77 self._flags = ParseFlags() 119 self._flags = ParseFlags()
78 self._driver = None 120 self._driver = None
79 self._chrome_args = set() 121 self._chrome_args = set()
80 self._url = '' 122 self._url = ''
123 self._logger = GetLogger(name='TestDriver')
81 124
82 def __enter__(self): 125 def __enter__(self):
83 return self 126 return self
84 127
85 def __exit__(self, exc_type, exc_value, tb): 128 def __exit__(self, exc_type, exc_value, tb):
86 if self._driver: 129 if self._driver:
87 self._StopDriver() 130 self._StopDriver()
88 131
89 def _OverrideChromeArgs(self): 132 def _OverrideChromeArgs(self):
90 """Overrides any given arguments in the code with those given on the command 133 """Overrides any given arguments in the code with those given on the command
91 line. 134 line.
92 135
93 Arguments that need to be overridden may contain different values for 136 Arguments that need to be overridden may contain different values for
94 a flag given in the code. In that case, check by the flag whether to 137 a flag given in the code. In that case, check by the flag whether to
95 override the argument. 138 override the argument.
96 """ 139 """
97 def GetDictKey(argument): 140 def GetDictKey(argument):
98 return argument.split('=', 1)[0] 141 return argument.split('=', 1)[0]
99 if self._flags.browser_args and len(self._flags.browser_args) > 0: 142 if self._flags.browser_args and len(self._flags.browser_args) > 0:
100 # Build a dict of flags mapped to the whole argument. 143 # Build a dict of flags mapped to the whole argument.
101 original_args = {} 144 original_args = {}
102 for arg in self._chrome_args: 145 for arg in self._chrome_args:
103 original_args[GetDictKey(arg)] = arg 146 original_args[GetDictKey(arg)] = arg
104 # Override flags given in code with any command line arguments. 147 # Override flags given in code with any command line arguments.
105 for override_arg in shlex.split(self._flags.browser_args): 148 for override_arg in shlex.split(self._flags.browser_args):
106 arg_key = GetDictKey(override_arg) 149 arg_key = GetDictKey(override_arg)
107 if arg_key in original_args: 150 if arg_key in original_args:
108 self._chrome_args.remove(original_args[arg_key]) 151 self._chrome_args.remove(original_args[arg_key])
152 self._logger.info('Removed Chrome flag. %s', original_args[arg_key])
109 self._chrome_args.add(override_arg) 153 self._chrome_args.add(override_arg)
154 self._logger.info('Added Chrome flag. %s', override_arg)
110 # Always add the flag that allows histograms to be queried in javascript. 155 # Always add the flag that allows histograms to be queried in javascript.
111 self._chrome_args.add('--enable-stats-collection-bindings') 156 self._chrome_args.add('--enable-stats-collection-bindings')
112 157
113 def _StartDriver(self): 158 def _StartDriver(self):
114 """Parses the flags to pass to Chromium, then starts the ChromeDriver. 159 """Parses the flags to pass to Chromium, then starts the ChromeDriver.
115 160
116 If running Android, the Android package name is passed to ChromeDriver here. 161 If running Android, the Android package name is passed to ChromeDriver here.
117 """ 162 """
118 self._OverrideChromeArgs() 163 self._OverrideChromeArgs()
119 capabilities = { 164 capabilities = {
120 'loggingPrefs': {'performance': 'INFO'}, 165 'loggingPrefs': {'performance': 'INFO'},
121 'chromeOptions': { 166 'chromeOptions': {
122 'args': list(self._chrome_args) 167 'args': list(self._chrome_args)
123 } 168 }
124 } 169 }
125 if self._flags.android: 170 if self._flags.android:
126 capabilities['chromeOptions'].update({ 171 capabilities['chromeOptions'].update({
127 'androidPackage': self._flags.android_package, 172 'androidPackage': self._flags.android_package,
128 }) 173 })
174 self._logger.debug('Will use Chrome on Android')
129 elif self._flags.chrome_exec: 175 elif self._flags.chrome_exec:
130 capabilities['chrome.binary'] = self._flags.chrome_exec 176 capabilities['chrome.binary'] = self._flags.chrome_exec
177 self._logger.info('Using the Chrome binary at this path: %s',
178 self._flags.chrome_exec)
179 self._logger.info('Starting Chrome with these flags: %s',
180 str(self._chrome_args))
181 self._logger.debug('Starting ChromeDriver with these capabilities: %s',
182 json.dumps(capabilities))
131 driver = webdriver.Chrome(executable_path=self._flags.chrome_driver, 183 driver = webdriver.Chrome(executable_path=self._flags.chrome_driver,
132 desired_capabilities=capabilities) 184 desired_capabilities=capabilities)
133 driver.command_executor._commands.update({ 185 driver.command_executor._commands.update({
134 'getAvailableLogTypes': ('GET', '/session/$sessionId/log/types'), 186 'getAvailableLogTypes': ('GET', '/session/$sessionId/log/types'),
135 'getLog': ('POST', '/session/$sessionId/log')}) 187 'getLog': ('POST', '/session/$sessionId/log')})
136 self._driver = driver 188 self._driver = driver
137 189
138 def _StopDriver(self): 190 def _StopDriver(self):
139 """Nicely stops the ChromeDriver. 191 """Nicely stops the ChromeDriver.
140 """ 192 """
193 self._logger.debug('Stopping ChromeDriver')
141 self._driver.quit() 194 self._driver.quit()
142 self._driver = None 195 self._driver = None
143 196
144 def AddChromeArgs(self, args): 197 def AddChromeArgs(self, args):
145 """Adds multiple arguments that will be passed to Chromium at start. 198 """Adds multiple arguments that will be passed to Chromium at start.
146 199
147 Args: 200 Args:
148 args: An iterable of strings, each an argument to pass to Chrome at start. 201 args: An iterable of strings, each an argument to pass to Chrome at start.
149 """ 202 """
150 for arg in args: 203 for arg in args:
151 self._chrome_args.add(arg) 204 self._chrome_args.add(arg)
152 205
153 def AddChromeArg(self, arg): 206 def AddChromeArg(self, arg):
154 """Adds a single argument that will be passed to Chromium at start. 207 """Adds a single argument that will be passed to Chromium at start.
155 208
156 Args: 209 Args:
157 arg: a string argument to pass to Chrome at start 210 arg: a string argument to pass to Chrome at start
158 """ 211 """
159 self._chrome_args.add(arg) 212 self._chrome_args.add(arg)
213 self._logger.debug('Adding Chrome arg: %s', arg)
160 214
161 def RemoveChromeArgs(self, args): 215 def RemoveChromeArgs(self, args):
162 """Removes multiple arguments that will no longer be passed to Chromium at 216 """Removes multiple arguments that will no longer be passed to Chromium at
163 start. 217 start.
164 218
165 Args: 219 Args:
166 args: An iterable of strings to no longer use the next time Chrome 220 args: An iterable of strings to no longer use the next time Chrome
167 starts. 221 starts.
168 """ 222 """
169 for arg in args: 223 for arg in args:
170 self._chrome_args.discard(arg) 224 self._chrome_args.discard(arg)
171 225
172 def RemoveChromeArg(self, arg): 226 def RemoveChromeArg(self, arg):
173 """Removes a single argument that will no longer be passed to Chromium at 227 """Removes a single argument that will no longer be passed to Chromium at
174 start. 228 start.
175 229
176 Args: 230 Args:
177 arg: A string flag to no longer use the next time Chrome starts. 231 arg: A string flag to no longer use the next time Chrome starts.
178 """ 232 """
179 self._chrome_args.discard(arg) 233 self._chrome_args.discard(arg)
234 self._logger.debug('Removing Chrome arg: %s', arg)
180 235
181 def ClearChromeArgs(self): 236 def ClearChromeArgs(self):
182 """Removes all arguments from Chromium at start. 237 """Removes all arguments from Chromium at start.
183 """ 238 """
184 self._chrome_args.clear() 239 self._chrome_args.clear()
240 self._logger.debug('Clearing all Chrome args')
185 241
186 def ClearCache(self): 242 def ClearCache(self):
187 """Clears the browser cache. 243 """Clears the browser cache.
188 244
189 Important note: ChromeDriver automatically starts 245 Important note: ChromeDriver automatically starts
190 a clean copy of Chrome on every instantiation. 246 a clean copy of Chrome on every instantiation.
191 """ 247 """
192 self.ExecuteJavascript('if(window.chrome && chrome.benchmarking && ' 248 res = self.ExecuteJavascript('if(window.chrome && chrome.benchmarking && '
193 'chrome.benchmarking.clearCache){chrome.benchmarking.clearCache(); ' 249 'chrome.benchmarking.clearCache){chrome.benchmarking.clearCache(); '
194 'chrome.benchmarking.clearPredictorCache();chrome.benchmarking.' 250 'chrome.benchmarking.clearPredictorCache();chrome.benchmarking.'
195 'clearHostResolverCache();}') 251 'clearHostResolverCache();}')
252 self._logger.info('Cleared browser cache. Returned=%s', str(res))
196 253
197 def LoadURL(self, url, timeout=30): 254 def LoadURL(self, url, timeout=30):
198 """Starts Chromium with any arguments previously given and navigates to the 255 """Starts Chromium with any arguments previously given and navigates to the
199 given URL. 256 given URL.
200 257
201 Args: 258 Args:
202 url: The URL to navigate to. 259 url: The URL to navigate to.
203 timeout: The time in seconds to load the page before timing out. 260 timeout: The time in seconds to load the page before timing out.
204 """ 261 """
205 self._url = url 262 self._url = url
206 if not self._driver: 263 if not self._driver:
207 self._StartDriver() 264 self._StartDriver()
208 self._driver.set_page_load_timeout(timeout) 265 self._driver.set_page_load_timeout(timeout)
266 self._logger.debug('Set page load timeout to %f seconds', timeout)
209 self._driver.get(self._url) 267 self._driver.get(self._url)
268 self._logger.debug('Loaded page %s', url)
210 269
211 def ExecuteJavascript(self, script, timeout=30): 270 def ExecuteJavascript(self, script, timeout=30):
212 """Executes the given javascript in the browser's current page in an 271 """Executes the given javascript in the browser's current page in an
213 anonymous function. 272 anonymous function.
214 273
215 If you expect a result and don't get one, try adding a return statement or 274 If you expect a result and don't get one, try adding a return statement or
216 using ExecuteJavascriptStatement() below. 275 using ExecuteJavascriptStatement() below.
217 276
218 Args: 277 Args:
219 script: A string of Javascript code. 278 script: A string of Javascript code.
220 timeout: Timeout for the Javascript code to return in seconds. 279 timeout: Timeout for the Javascript code to return in seconds.
221 Returns: 280 Returns:
222 A string of the verbatim output from the Javascript execution. 281 A string of the verbatim output from the Javascript execution.
223 """ 282 """
224 if not self._driver: 283 if not self._driver:
225 self._StartDriver() 284 self._StartDriver()
226 # TODO(robertogden): Use 'driver.set_script_timeout(timeout)' instead after 285 # TODO(robertogden): Use 'driver.set_script_timeout(timeout)' instead after
227 # crbug/672114 is fixed. 286 # crbug/672114 is fixed.
228 default_timeout = socket.getdefaulttimeout() 287 default_timeout = socket.getdefaulttimeout()
229 socket.setdefaulttimeout(timeout) 288 socket.setdefaulttimeout(timeout)
289 self._logger.debug('Set socket timeout to %f seconds', timeout)
230 script_result = self._driver.execute_script(script) 290 script_result = self._driver.execute_script(script)
291 self._logger.debug('Executed Javascript in browser: %s', script)
231 socket.setdefaulttimeout(default_timeout) 292 socket.setdefaulttimeout(default_timeout)
293 self._logger.debug('Set socket timeout to %s', str(default_timeout))
232 return script_result 294 return script_result
233 295
234 def ExecuteJavascriptStatement(self, script, timeout=30): 296 def ExecuteJavascriptStatement(self, script, timeout=30):
235 """Wraps ExecuteJavascript() for use with a single statement. 297 """Wraps ExecuteJavascript() for use with a single statement.
236 298
237 Behavior is analogous to 'function(){ return <script> }();' 299 Behavior is analogous to 'function(){ return <script> }();'
238 300
239 Args: 301 Args:
240 script: A string of Javascript code. 302 script: A string of Javascript code.
241 timeout: Timeout for the Javascript code to return in seconds. 303 timeout: Timeout for the Javascript code to return in seconds.
242 Returns: 304 Returns:
243 A string of the verbatim output from the Javascript execution. 305 A string of the verbatim output from the Javascript execution.
244 """ 306 """
245 return self.ExecuteJavascript("return " + script, timeout) 307 return self.ExecuteJavascript("return " + script, timeout)
246 308
247 def GetHistogram(self, histogram): 309 def GetHistogram(self, histogram):
248 js_query = 'statsCollectionController.getBrowserHistogram("%s")' % histogram 310 js_query = 'statsCollectionController.getBrowserHistogram("%s")' % histogram
249 string_response = self.ExecuteJavascriptStatement(js_query) 311 string_response = self.ExecuteJavascriptStatement(js_query)
312 self._logger.debug('Got %s histogram=%s', histogram, string_response)
250 return json.loads(string_response) 313 return json.loads(string_response)
251 314
252 def WaitForJavascriptExpression(self, expression, timeout, min_poll=0.1, 315 def WaitForJavascriptExpression(self, expression, timeout, min_poll=0.1,
253 max_poll=1): 316 max_poll=1):
254 """Waits for the given Javascript expression to evaluate to True within the 317 """Waits for the given Javascript expression to evaluate to True within the
255 given timeout. This method polls the Javascript expression within the range 318 given timeout. This method polls the Javascript expression within the range
256 of |min_poll| and |max_poll|. 319 of |min_poll| and |max_poll|.
257 320
258 Args: 321 Args:
259 expression: The Javascript expression to poll, as a string. 322 expression: The Javascript expression to poll, as a string.
260 min_poll: The most frequently to poll as a float. 323 min_poll: The most frequently to poll as a float.
261 max_poll: The least frequently to poll as a float. 324 max_poll: The least frequently to poll as a float.
262 Returns: The result of the expression. 325 Returns: The result of the expression.
263 """ 326 """
264 poll_interval = max(min(max_poll, float(timeout) / 10.0), min_poll) 327 poll_interval = max(min(max_poll, float(timeout) / 10.0), min_poll)
328 self._logger.debug('Poll interval=%f seconds', poll_interval)
265 result = self.ExecuteJavascriptStatement(expression) 329 result = self.ExecuteJavascriptStatement(expression)
266 total_waited_time = 0 330 total_waited_time = 0
267 while not result and total_waited_time < timeout: 331 while not result and total_waited_time < timeout:
268 time.sleep(poll_interval) 332 time.sleep(poll_interval)
269 total_waited_time += poll_interval 333 total_waited_time += poll_interval
270 result = self.ExecuteJavascriptStatement(expression) 334 result = self.ExecuteJavascriptStatement(expression)
271 if not result: 335 if not result:
336 self._logger.error('%s not true after %f seconds' % (expression, timeout))
272 raise Exception('%s not true after %f seconds' % (expression, timeout)) 337 raise Exception('%s not true after %f seconds' % (expression, timeout))
273 return result 338 return result
274 339
275 def GetPerformanceLogs(self, method_filter=r'Network\.responseReceived'): 340 def GetPerformanceLogs(self, method_filter=r'Network\.responseReceived'):
276 """Returns all logged Performance events from Chrome. 341 """Returns all logged Performance events from Chrome.
277 342
278 Args: 343 Args:
279 method_filter: A regex expression to match the method of logged events 344 method_filter: A regex expression to match the method of logged events
280 against. Only logs who's method matches the regex will be returned. 345 against. Only logs who's method matches the regex will be returned.
281 Returns: 346 Returns:
282 Performance logs as a list of dicts, since the last time this function was 347 Performance logs as a list of dicts, since the last time this function was
283 called. 348 called.
284 """ 349 """
285 all_messages = [] 350 all_messages = []
286 for log in self._driver.execute('getLog', {'type': 'performance'})['value']: 351 for log in self._driver.execute('getLog', {'type': 'performance'})['value']:
287 message = json.loads(log['message'])['message'] 352 message = json.loads(log['message'])['message']
353 self._logger.debug('Got Performance log: %s', log['message'])
288 if re.match(method_filter, message['method']): 354 if re.match(method_filter, message['method']):
289 all_messages.append(message) 355 all_messages.append(message)
356 self._logger.info('Got %d performance logs with filter method=%s',
357 len(all_messages), method_filter)
290 return all_messages 358 return all_messages
291 359
292 def GetHTTPResponses(self, include_favicon=False): 360 def GetHTTPResponses(self, include_favicon=False):
293 """Parses the Performance Logs and returns a list of HTTPResponse objects. 361 """Parses the Performance Logs and returns a list of HTTPResponse objects.
294 362
295 Use caution when calling this function multiple times. Only responses 363 Use caution when calling this function multiple times. Only responses
296 since the last time this function was called are returned (or since Chrome 364 since the last time this function was called are returned (or since Chrome
297 started, whichever is later). 365 started, whichever is later).
298 366
299 Args: 367 Args:
(...skipping 15 matching lines...) Expand all
315 else '', 383 else '',
316 'port': response_dict['remotePort'] if 'remotePort' in response_dict 384 'port': response_dict['remotePort'] if 'remotePort' in response_dict
317 else -1, 385 else -1,
318 'status': response_dict['status'] if 'status' in response_dict else -1, 386 'status': response_dict['status'] if 'status' in response_dict else -1,
319 'request_type': params['type'] if 'type' in params else '' 387 'request_type': params['type'] if 'type' in params else ''
320 } 388 }
321 return HTTPResponse(**http_response_dict) 389 return HTTPResponse(**http_response_dict)
322 all_responses = [] 390 all_responses = []
323 for message in self.GetPerformanceLogs(): 391 for message in self.GetPerformanceLogs():
324 response = MakeHTTPResponse(message) 392 response = MakeHTTPResponse(message)
393 self._logger.debug('New HTTPResponse: %s', str(response))
325 is_favicon = response.url.endswith('favicon.ico') 394 is_favicon = response.url.endswith('favicon.ico')
326 if not is_favicon or include_favicon: 395 if not is_favicon or include_favicon:
327 all_responses.append(response) 396 all_responses.append(response)
397 self._logger.info('%d new HTTPResponse objects found in the logs %s '
398 'favicons', len(all_responses), ('including' if include_favicon else
399 'not including'))
328 return all_responses 400 return all_responses
329 401
330 class HTTPResponse: 402 class HTTPResponse:
331 """This class represents a single HTTP transaction (request and response) by 403 """This class represents a single HTTP transaction (request and response) by
332 Chrome. 404 Chrome.
333 405
334 This class also includes several convenience functions for ChromeProxy 406 This class also includes several convenience functions for ChromeProxy
335 specific assertions. 407 specific assertions.
336 408
337 Attributes: 409 Attributes:
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 expected_via_header = ParseFlags().via_header_value 512 expected_via_header = ParseFlags().via_header_value
441 self.assertNotIn('via', http_response.response_headers) 513 self.assertNotIn('via', http_response.response_headers)
442 if 'via' in http_response.response_headers: 514 if 'via' in http_response.response_headers:
443 self.assertNotIn(expected_via_header, 515 self.assertNotIn(expected_via_header,
444 http_response.response_headers['via']) 516 http_response.response_headers['via'])
445 517
446 @staticmethod 518 @staticmethod
447 def RunAllTests(): 519 def RunAllTests():
448 """A simple helper method to run all tests using unittest.main(). 520 """A simple helper method to run all tests using unittest.main().
449 """ 521 """
522 flags = ParseFlags()
523 logger = GetLogger()
524 logger.debug('Command line args: %s', str(sys.argv))
525 logger.info('sys.argv parsed to %s', str(flags))
450 # The unittest library uses sys.argv itself and is easily confused by our 526 # The unittest library uses sys.argv itself and is easily confused by our
451 # command line options. Pass it a simpler argv instead, while working in the 527 # command line options. Pass it a simpler argv instead, while working in the
452 # unittest command line args functionality. 528 # unittest command line args functionality.
453 flags = ParseFlags()
454 unittest.main(argv=[sys.argv[0]], verbosity=2, failfast=flags.failfast, 529 unittest.main(argv=[sys.argv[0]], verbosity=2, failfast=flags.failfast,
455 catchbreak=flags.catch, buffer=(not flags.disable_buffer)) 530 catchbreak=flags.catch, buffer=(not flags.disable_buffer))
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698