OLD | NEW |
---|---|
1 #! /usr/bin/env python | 1 #! /usr/bin/env python |
2 # Copyright 2016 The Chromium Authors. All rights reserved. | 2 # Copyright 2016 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Instructs Chrome to load series of web pages and reports results. | 6 """Instructs Chrome to load series of web pages and reports results. |
7 | 7 |
8 When running Chrome is sandwiched between preprocessed disk caches and | 8 When running Chrome is sandwiched between preprocessed disk caches and |
9 WepPageReplay serving all connections. | 9 WepPageReplay serving all connections. |
10 | 10 |
(...skipping 17 matching lines...) Expand all Loading... | |
28 | 28 |
29 sys.path.append(os.path.join(_SRC_DIR, 'third_party', 'catapult', 'devil')) | 29 sys.path.append(os.path.join(_SRC_DIR, 'third_party', 'catapult', 'devil')) |
30 from devil.android import device_utils | 30 from devil.android import device_utils |
31 | 31 |
32 sys.path.append(os.path.join(_SRC_DIR, 'build', 'android')) | 32 sys.path.append(os.path.join(_SRC_DIR, 'build', 'android')) |
33 from pylib import constants | 33 from pylib import constants |
34 import devil_chromium | 34 import devil_chromium |
35 | 35 |
36 import device_setup | 36 import device_setup |
37 import devtools_monitor | 37 import devtools_monitor |
38 import json | 38 import options |
39 import page_track | 39 import page_track |
40 import pull_sandwich_metrics | 40 import pull_sandwich_metrics |
41 import trace_recorder | |
41 import tracing | 42 import tracing |
42 | 43 |
43 | 44 |
44 _JOB_SEARCH_PATH = 'sandwich_jobs' | 45 _JOB_SEARCH_PATH = 'sandwich_jobs' |
mattcary
2016/02/19 14:41:05
It's idiomatic to create a global here
OPTIONS =
gabadie
2016/02/19 15:04:35
I have to say I am not a fan options.OPTIONS. It i
mattcary
2016/02/19 15:29:00
The rest of our library depends on the options bei
| |
45 | 46 |
46 # Directory name under --output to save the cache from the device. | 47 # Directory name under --output to save the cache from the device. |
47 _CACHE_DIRECTORY_NAME = 'cache' | 48 _CACHE_DIRECTORY_NAME = 'cache' |
48 | 49 |
49 # Name of cache subdirectory on the device where the cache index is stored. | 50 # Name of cache subdirectory on the device where the cache index is stored. |
50 _INDEX_DIRECTORY_NAME = 'index-dir' | 51 _INDEX_DIRECTORY_NAME = 'index-dir' |
51 | 52 |
52 # Name of the file containing the cache index. This file is stored on the device | 53 # Name of the file containing the cache index. This file is stored on the device |
53 # in the cache directory under _INDEX_DIRECTORY_NAME. | 54 # in the cache directory under _INDEX_DIRECTORY_NAME. |
54 _REAL_INDEX_FILE_NAME = 'the-real-index' | 55 _REAL_INDEX_FILE_NAME = 'the-real-index' |
55 | 56 |
56 # Name of the chrome package. | 57 # Name of the chrome package. |
57 _CHROME_PACKAGE = ( | 58 _CHROME_PACKAGE = constants.PACKAGE_INFO['chrome'].package |
mattcary
2016/02/19 14:41:05
_CHROME_PACKAGE should be taken from options.OPTIO
gabadie
2016/02/19 15:04:35
But options.OPTIONS has not be initialized yet. An
mattcary
2016/02/19 15:29:00
But then you may be using a different chrome packa
| |
58 constants.PACKAGE_INFO[device_setup.DEFAULT_CHROME_PACKAGE].package) | |
59 | 59 |
60 # An estimate of time to wait for the device to become idle after expensive | 60 # An estimate of time to wait for the device to become idle after expensive |
61 # operations, such as opening the launcher activity. | 61 # operations, such as opening the launcher activity. |
62 _TIME_TO_DEVICE_IDLE_SECONDS = 2 | 62 _TIME_TO_DEVICE_IDLE_SECONDS = 2 |
63 | 63 |
64 # Cache directory's path on the device. | 64 # Cache directory's path on the device. |
65 _REMOTE_CACHE_DIRECTORY = '/data/data/' + _CHROME_PACKAGE + '/cache/Cache' | 65 _REMOTE_CACHE_DIRECTORY = '/data/data/' + _CHROME_PACKAGE + '/cache/Cache' |
66 | 66 |
67 | 67 |
68 def _ReadUrlsFromJobDescription(job_name): | 68 def _ReadUrlsFromJobDescription(job_name): |
(...skipping 10 matching lines...) Expand all Loading... | |
79 json_data = json.load(f) | 79 json_data = json.load(f) |
80 | 80 |
81 key = 'urls' | 81 key = 'urls' |
82 if json_data and key in json_data: | 82 if json_data and key in json_data: |
83 url_list = json_data[key] | 83 url_list = json_data[key] |
84 if isinstance(url_list, list) and len(url_list) > 0: | 84 if isinstance(url_list, list) and len(url_list) > 0: |
85 return url_list | 85 return url_list |
86 raise Exception('Job description does not define a list named "urls"') | 86 raise Exception('Job description does not define a list named "urls"') |
87 | 87 |
88 | 88 |
89 def _SaveChromeTrace(events, target_directory): | |
90 """Saves the trace events, ignores IO errors. | |
91 | |
92 Args: | |
93 events: a dict as returned by TracingTrack.ToJsonDict() | |
94 target_directory: Directory path where trace is created. | |
95 """ | |
96 filename = os.path.join(target_directory, 'trace.json') | |
97 try: | |
98 os.makedirs(target_directory) | |
99 with open(filename, 'w') as f: | |
100 json.dump({'traceEvents': events['events'], 'metadata': {}}, f, indent=2) | |
101 except IOError: | |
102 logging.warning('Could not save a trace: %s' % filename) | |
103 # Swallow the exception. | |
104 | |
105 | |
106 def _UpdateTimestampFromAdbStat(filename, stat): | 89 def _UpdateTimestampFromAdbStat(filename, stat): |
107 os.utime(filename, (stat.st_time, stat.st_time)) | 90 os.utime(filename, (stat.st_time, stat.st_time)) |
108 | 91 |
109 | 92 |
110 def _AdbShell(adb, cmd): | 93 def _AdbShell(adb, cmd): |
111 adb.Shell(subprocess.list2cmdline(cmd)) | 94 adb.Shell(subprocess.list2cmdline(cmd)) |
112 | 95 |
113 | 96 |
114 def _AdbUtime(adb, filename, timestamp): | 97 def _AdbUtime(adb, filename, timestamp): |
115 """Adb equivalent of os.utime(filename, (timestamp, timestamp)) | 98 """Adb equivalent of os.utime(filename, (timestamp, timestamp)) |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
270 try: | 253 try: |
271 int(dirname) | 254 int(dirname) |
272 except ValueError: | 255 except ValueError: |
273 continue | 256 continue |
274 shutil.rmtree(directory_path) | 257 shutil.rmtree(directory_path) |
275 | 258 |
276 | 259 |
277 def main(): | 260 def main(): |
278 logging.basicConfig(level=logging.INFO) | 261 logging.basicConfig(level=logging.INFO) |
279 devil_chromium.Initialize() | 262 devil_chromium.Initialize() |
263 options.OPTIONS.ParseArgs([]) | |
mattcary
2016/02/19 15:29:00
You should pass argv, and add your own arguments a
| |
280 | 264 |
281 parser = argparse.ArgumentParser() | 265 parser = argparse.ArgumentParser() |
282 parser.add_argument('--job', required=True, | 266 parser.add_argument('--job', required=True, |
283 help='JSON file with job description.') | 267 help='JSON file with job description.') |
284 parser.add_argument('--output', required=True, | 268 parser.add_argument('--output', required=True, |
285 help='Name of output directory to create.') | 269 help='Name of output directory to create.') |
286 parser.add_argument('--repeat', default=1, type=int, | 270 parser.add_argument('--repeat', default=1, type=int, |
287 help='How many times to run the job') | 271 help='How many times to run the job') |
288 parser.add_argument('--cache-op', | 272 parser.add_argument('--cache-op', |
289 choices=['clear', 'save', 'push', 'reload'], | 273 choices=['clear', 'save', 'push', 'reload'], |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
324 assert os.path.isfile(local_cache_archive_path) | 308 assert os.path.isfile(local_cache_archive_path) |
325 local_cache_directory_path = tempfile.mkdtemp(suffix='.cache') | 309 local_cache_directory_path = tempfile.mkdtemp(suffix='.cache') |
326 _UnzipDirectoryContent(local_cache_archive_path, local_cache_directory_path) | 310 _UnzipDirectoryContent(local_cache_archive_path, local_cache_directory_path) |
327 | 311 |
328 with device_setup.WprHost(device, args.wpr_archive, args.wpr_record, | 312 with device_setup.WprHost(device, args.wpr_archive, args.wpr_record, |
329 args.disable_wpr_script_injection) as additional_flags: | 313 args.disable_wpr_script_injection) as additional_flags: |
330 def _RunNavigation(url, clear_cache, trace_id): | 314 def _RunNavigation(url, clear_cache, trace_id): |
331 with device_setup.DeviceConnection( | 315 with device_setup.DeviceConnection( |
332 device=device, | 316 device=device, |
333 additional_flags=additional_flags) as connection: | 317 additional_flags=additional_flags) as connection: |
334 if clear_cache: | 318 loading_trace = trace_recorder.MonitorUrl( |
335 connection.ClearCache() | 319 connection, url, |
336 page_track.PageTrack(connection) | 320 clear_cache=clear_cache, |
337 tracing_track = tracing.TracingTrack(connection, | |
338 categories=pull_sandwich_metrics.CATEGORIES) | 321 categories=pull_sandwich_metrics.CATEGORIES) |
339 connection.SetUpMonitoring() | |
340 connection.SendAndIgnoreResponse('Page.navigate', {'url': url}) | |
341 connection.StartMonitoring() | |
342 if trace_id != None: | 322 if trace_id != None: |
343 trace_target_directory = os.path.join(args.output, str(trace_id)) | 323 loading_trace_path = os.path.join( |
344 _SaveChromeTrace(tracing_track.ToJsonDict(), trace_target_directory) | 324 args.output, str(trace_id), 'trace.json') |
325 os.makedirs(os.path.dirname(loading_trace_path)) | |
326 loading_trace.SaveToJsonFile(loading_trace_path) | |
345 | 327 |
346 for _ in xrange(args.repeat): | 328 for _ in xrange(args.repeat): |
347 for url in job_urls: | 329 for url in job_urls: |
348 clear_cache = False | 330 clear_cache = False |
349 if args.cache_op == 'clear': | 331 if args.cache_op == 'clear': |
350 clear_cache = True | 332 clear_cache = True |
351 elif args.cache_op == 'push': | 333 elif args.cache_op == 'push': |
352 device.KillAll(_CHROME_PACKAGE, quiet=True) | 334 device.KillAll(_CHROME_PACKAGE, quiet=True) |
353 _PushBrowserCache(device, local_cache_directory_path) | 335 _PushBrowserCache(device, local_cache_directory_path) |
354 elif args.cache_op == 'reload': | 336 elif args.cache_op == 'reload': |
(...skipping 17 matching lines...) Expand all Loading... | |
372 cache_directory_path = _PullBrowserCache(device) | 354 cache_directory_path = _PullBrowserCache(device) |
373 _ZipDirectoryContent(cache_directory_path, local_cache_archive_path) | 355 _ZipDirectoryContent(cache_directory_path, local_cache_archive_path) |
374 shutil.rmtree(cache_directory_path) | 356 shutil.rmtree(cache_directory_path) |
375 | 357 |
376 with open(os.path.join(args.output, 'run_infos.json'), 'w') as file_output: | 358 with open(os.path.join(args.output, 'run_infos.json'), 'w') as file_output: |
377 json.dump(run_infos, file_output, indent=2) | 359 json.dump(run_infos, file_output, indent=2) |
378 | 360 |
379 | 361 |
380 if __name__ == '__main__': | 362 if __name__ == '__main__': |
381 sys.exit(main()) | 363 sys.exit(main()) |
OLD | NEW |