OLD | NEW |
---|---|
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 logging | 5 import logging |
6 import os | 6 import os |
7 import shutil | 7 import shutil |
8 import sys | 8 import sys |
9 import tempfile | 9 import tempfile |
10 | 10 |
11 _SRC_DIR = os.path.abspath(os.path.join( | 11 _SRC_DIR = os.path.abspath(os.path.join( |
12 os.path.dirname(__file__), '..', '..', '..')) | 12 os.path.dirname(__file__), '..', '..', '..')) |
13 | 13 |
14 sys.path.append(os.path.join(_SRC_DIR, 'third_party', 'catapult', 'devil')) | 14 sys.path.append(os.path.join(_SRC_DIR, 'third_party', 'catapult', 'devil')) |
15 from devil.android import device_utils | 15 from devil.android import device_utils |
16 | 16 |
17 import chrome_cache | 17 import chrome_cache |
18 import controller | 18 import controller |
19 import devtools_monitor | 19 import devtools_monitor |
20 import device_setup | 20 import device_setup |
21 import loading_trace | 21 import loading_trace |
22 | 22 |
23 | 23 |
24 # Standard filenames in the sandwich runner's output directory. | 24 # Standard filenames in the sandwich runner's output directory. |
25 ERROR_FILENAME = 'error' | |
25 TRACE_FILENAME = 'trace.json' | 26 TRACE_FILENAME = 'trace.json' |
26 VIDEO_FILENAME = 'video.mp4' | 27 VIDEO_FILENAME = 'video.mp4' |
27 WPR_LOG_FILENAME = 'wpr.log' | 28 WPR_LOG_FILENAME = 'wpr.log' |
28 | 29 |
29 # Memory dump category used to get memory metrics. | 30 # Memory dump category used to get memory metrics. |
30 MEMORY_DUMP_CATEGORY = 'disabled-by-default-memory-infra' | 31 MEMORY_DUMP_CATEGORY = 'disabled-by-default-memory-infra' |
31 | 32 |
32 # Devtools timeout of 1 minute to avoid websocket timeout on slow | 33 # Devtools timeout of 1 minute to avoid websocket timeout on slow |
33 # network condition. | 34 # network condition. |
34 _DEVTOOLS_TIMEOUT = 60 | 35 _DEVTOOLS_TIMEOUT = 60 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
133 | 134 |
134 def _RunNavigation(self, clear_cache, run_id=None): | 135 def _RunNavigation(self, clear_cache, run_id=None): |
135 """Run a page navigation to the given URL. | 136 """Run a page navigation to the given URL. |
136 | 137 |
137 Args: | 138 Args: |
138 clear_cache: Whether if the cache should be cleared before navigation. | 139 clear_cache: Whether if the cache should be cleared before navigation. |
139 run_id: Id of the run in the output directory. If it is None, then no | 140 run_id: Id of the run in the output directory. If it is None, then no |
140 trace or video will be saved. | 141 trace or video will be saved. |
141 """ | 142 """ |
142 run_path = None | 143 run_path = None |
143 if self.output_dir is not None and run_id is not None: | 144 if run_id is not None: |
pasko
2016/06/06 13:58:52
yeah, I always wondered why we needed SandwichRunn
gabadie
2016/06/06 14:03:55
No that was just to not record the trace for WPR r
| |
144 run_path = os.path.join(self.output_dir, str(run_id)) | 145 run_path = os.path.join(self.output_dir, str(run_id)) |
145 if not os.path.isdir(run_path): | 146 if not os.path.isdir(run_path): |
146 os.makedirs(run_path) | 147 os.makedirs(run_path) |
147 self._chrome_ctl.SetNetworkEmulation( | 148 self._chrome_ctl.SetNetworkEmulation( |
148 self._GetEmulatorNetworkCondition('browser')) | 149 self._GetEmulatorNetworkCondition('browser')) |
149 additional_categories = [] | 150 additional_categories = [] |
150 if self.record_memory_dumps: | 151 if self.record_memory_dumps: |
151 additional_categories = [MEMORY_DUMP_CATEGORY] | 152 additional_categories = [MEMORY_DUMP_CATEGORY] |
152 # TODO(gabadie): add a way to avoid recording a trace. | 153 # TODO(gabadie): add a way to avoid recording a trace. |
153 with self._chrome_ctl.Open() as connection: | 154 with self._chrome_ctl.Open() as connection: |
(...skipping 30 matching lines...) Expand all Loading... | |
184 clear_cache = False | 185 clear_cache = False |
185 if self.cache_operation == CacheOperation.CLEAR: | 186 if self.cache_operation == CacheOperation.CLEAR: |
186 clear_cache = True | 187 clear_cache = True |
187 elif self.cache_operation == CacheOperation.PUSH: | 188 elif self.cache_operation == CacheOperation.PUSH: |
188 self._chrome_ctl.PushBrowserCache(self._local_cache_directory_path) | 189 self._chrome_ctl.PushBrowserCache(self._local_cache_directory_path) |
189 elif self.cache_operation == CacheOperation.SAVE: | 190 elif self.cache_operation == CacheOperation.SAVE: |
190 clear_cache = run_id == 0 | 191 clear_cache = run_id == 0 |
191 self._RunNavigation(clear_cache=clear_cache, run_id=run_id) | 192 self._RunNavigation(clear_cache=clear_cache, run_id=run_id) |
192 break | 193 break |
193 except controller.ChromeControllerError as error: | 194 except controller.ChromeControllerError as error: |
195 if error.IsIntermittent() and attempt_id + 1 != self._ATTEMPT_COUNT: | |
196 dump_filename = 'intermittent_failure{}'.format(attempt_id) | |
197 dump_path = os.path.join(self.output_dir, str(run_id), dump_filename) | |
198 else: | |
199 dump_path = os.path.join(self.output_dir, ERROR_FILENAME) | |
200 with open(dump_path, 'w') as dump_output: | |
201 error.Dump(dump_output) | |
194 if not error.IsIntermittent(): | 202 if not error.IsIntermittent(): |
195 raise | 203 error.RaiseOriginal() |
pasko
2016/06/06 13:58:52
what does not work with raising ChromeControllerEr
gabadie
2016/06/06 14:03:55
'raise' would raise the previously catched excepti
mattcary
2016/06/06 14:37:09
A disadvantage of this approach is that we lose th
gabadie
2016/06/06 14:55:14
I don't see where the disadvantage is. The point o
| |
196 if self.output_dir is not None: | |
197 dump_path = os.path.join(self.output_dir, str(run_id), | |
198 'error{}'.format(attempt_id)) | |
199 with open(dump_path, 'w') as dump_output: | |
200 error.Dump(dump_output) | |
201 else: | 204 else: |
202 logging.error('Failed to navigate to %s after %d attemps' % \ | 205 logging.error('Failed to navigate to %s after %d attemps' % \ |
203 (self.url, self._ATTEMPT_COUNT)) | 206 (self.url, self._ATTEMPT_COUNT)) |
204 raise | 207 raise |
205 | 208 |
206 def _PullCacheFromDevice(self): | 209 def _PullCacheFromDevice(self): |
207 assert self.cache_operation == CacheOperation.SAVE | 210 assert self.cache_operation == CacheOperation.SAVE |
208 assert self.cache_archive_path, 'Need to specify where to save the cache' | 211 assert self.cache_archive_path, 'Need to specify where to save the cache' |
209 | 212 |
210 cache_directory_path = self._chrome_ctl.PullBrowserCache() | 213 cache_directory_path = self._chrome_ctl.PullBrowserCache() |
211 chrome_cache.ZipDirectoryContent( | 214 chrome_cache.ZipDirectoryContent( |
212 cache_directory_path, self.cache_archive_path) | 215 cache_directory_path, self.cache_archive_path) |
213 shutil.rmtree(cache_directory_path) | 216 shutil.rmtree(cache_directory_path) |
214 | 217 |
215 def Run(self): | 218 def Run(self): |
216 """SandwichRunner main entry point meant to be called once configured.""" | 219 """SandwichRunner main entry point meant to be called once configured.""" |
220 assert self.output_dir is not None | |
217 assert self._chrome_ctl == None | 221 assert self._chrome_ctl == None |
218 assert self._local_cache_directory_path == None | 222 assert self._local_cache_directory_path == None |
219 if self.output_dir: | 223 self._CleanTraceOutputDirectory() |
220 self._CleanTraceOutputDirectory() | |
221 | 224 |
222 if self.android_device: | 225 if self.android_device: |
223 self._chrome_ctl = controller.RemoteChromeController(self.android_device) | 226 self._chrome_ctl = controller.RemoteChromeController(self.android_device) |
224 else: | 227 else: |
225 self._chrome_ctl = controller.LocalChromeController() | 228 self._chrome_ctl = controller.LocalChromeController() |
226 self._chrome_ctl.AddChromeArguments(['--disable-infobars']) | 229 self._chrome_ctl.AddChromeArguments(['--disable-infobars']) |
227 self._chrome_ctl.AddChromeArguments(self.chrome_args) | 230 self._chrome_ctl.AddChromeArguments(self.chrome_args) |
228 if self.cache_operation == CacheOperation.SAVE: | 231 if self.cache_operation == CacheOperation.SAVE: |
229 self._chrome_ctl.SetSlowDeath() | 232 self._chrome_ctl.SetSlowDeath() |
230 | |
231 wpr_log_path = None | |
232 if self.output_dir: | |
233 wpr_log_path = os.path.join(self.output_dir, WPR_LOG_FILENAME) | |
234 | |
235 try: | 233 try: |
236 if self.cache_operation == CacheOperation.PUSH: | 234 if self.cache_operation == CacheOperation.PUSH: |
237 assert os.path.isfile(self.cache_archive_path) | 235 assert os.path.isfile(self.cache_archive_path) |
238 self._local_cache_directory_path = tempfile.mkdtemp(suffix='.cache') | 236 self._local_cache_directory_path = tempfile.mkdtemp(suffix='.cache') |
239 chrome_cache.UnzipDirectoryContent( | 237 chrome_cache.UnzipDirectoryContent( |
240 self.cache_archive_path, self._local_cache_directory_path) | 238 self.cache_archive_path, self._local_cache_directory_path) |
241 | 239 |
242 with self._chrome_ctl.OpenWprHost(self.wpr_archive_path, | 240 with self._chrome_ctl.OpenWprHost(self.wpr_archive_path, |
243 record=self.wpr_record, | 241 record=self.wpr_record, |
244 network_condition_name=self._GetEmulatorNetworkCondition('wpr'), | 242 network_condition_name=self._GetEmulatorNetworkCondition('wpr'), |
245 disable_script_injection=self.disable_wpr_script_injection, | 243 disable_script_injection=self.disable_wpr_script_injection, |
246 out_log_path=wpr_log_path): | 244 out_log_path=os.path.join(self.output_dir, WPR_LOG_FILENAME)): |
247 for repeat_id in xrange(self.repeat): | 245 for repeat_id in xrange(self.repeat): |
248 self._RunUrl(run_id=repeat_id) | 246 self._RunUrl(run_id=repeat_id) |
249 finally: | 247 finally: |
250 if self._local_cache_directory_path: | 248 if self._local_cache_directory_path: |
251 shutil.rmtree(self._local_cache_directory_path) | 249 shutil.rmtree(self._local_cache_directory_path) |
252 self._local_cache_directory_path = None | 250 self._local_cache_directory_path = None |
253 if self.cache_operation == CacheOperation.SAVE: | 251 if self.cache_operation == CacheOperation.SAVE: |
254 self._PullCacheFromDevice() | 252 self._PullCacheFromDevice() |
255 | 253 |
256 self._chrome_ctl = None | 254 self._chrome_ctl = None |
(...skipping 11 matching lines...) Expand all Loading... | |
268 if not os.path.isdir(repeat_dir): | 266 if not os.path.isdir(repeat_dir): |
269 continue | 267 continue |
270 try: | 268 try: |
271 repeat_id = int(node_name) | 269 repeat_id = int(node_name) |
272 except ValueError: | 270 except ValueError: |
273 continue | 271 continue |
274 yield repeat_id, repeat_dir | 272 yield repeat_id, repeat_dir |
275 repeated_run_count += 1 | 273 repeated_run_count += 1 |
276 assert repeated_run_count > 0, ('Error: not a sandwich runner output ' | 274 assert repeated_run_count > 0, ('Error: not a sandwich runner output ' |
277 'directory: {}').format(runner_output_dir) | 275 'directory: {}').format(runner_output_dir) |
OLD | NEW |