OLD | NEW |
---|---|
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # | 2 # |
3 # Copyright 2016 The Chromium Authors. All rights reserved. | 3 # Copyright 2016 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 """Loads a web page with speculative prefetch, and collects loading metrics.""" | 7 """Loads a web page with speculative prefetch, and collects loading metrics.""" |
8 | 8 |
9 import argparse | 9 import argparse |
10 import logging | 10 import logging |
11 import os | 11 import os |
12 import random | |
12 import sys | 13 import sys |
13 import time | 14 import time |
14 | 15 |
15 _SRC_PATH = os.path.abspath(os.path.join( | 16 _SRC_PATH = os.path.abspath(os.path.join( |
16 os.path.dirname(__file__), os.pardir, os.pardir)) | 17 os.path.dirname(__file__), os.pardir, os.pardir)) |
17 | 18 |
18 sys.path.append(os.path.join( | 19 sys.path.append(os.path.join( |
19 _SRC_PATH, 'tools', 'android', 'customtabs_benchmark', 'scripts')) | 20 _SRC_PATH, 'tools', 'android', 'customtabs_benchmark', 'scripts')) |
20 import customtabs_benchmark | 21 import customtabs_benchmark |
21 import device_setup | 22 import device_setup |
22 | 23 |
23 sys.path.append(os.path.join(_SRC_PATH, 'tools', 'android', 'loading')) | 24 sys.path.append(os.path.join(_SRC_PATH, 'tools', 'android', 'loading')) |
25 import controller | |
24 from options import OPTIONS | 26 from options import OPTIONS |
25 | 27 |
26 sys.path.append(os.path.join(_SRC_PATH, 'build', 'android')) | 28 sys.path.append(os.path.join(_SRC_PATH, 'build', 'android')) |
27 import devil_chromium | 29 import devil_chromium |
28 | 30 |
29 sys.path.append(os.path.join(_SRC_PATH, 'third_party', 'catapult', 'devil')) | 31 sys.path.append(os.path.join(_SRC_PATH, 'third_party', 'catapult', 'devil')) |
30 from devil.android.sdk import intent | 32 from devil.android.sdk import intent |
31 | 33 |
32 import prefetch_predictor_common | 34 import prefetch_predictor_common |
33 | 35 |
34 | 36 |
35 _EXTERNAL_PREFETCH_FLAG = ( | 37 _EXTERNAL_PREFETCH_FLAG = ( |
36 '--speculative-resource-prefetching=enabled-external-only') | 38 '--speculative-resource-prefetching=enabled-external-only') |
37 | 39 |
38 | 40 |
39 def _CreateArgumentParser(): | 41 def _CreateArgumentParser(): |
40 """Creates and returns the argument parser.""" | 42 """Creates and returns the argument parser.""" |
41 parser = argparse.ArgumentParser( | 43 parser = argparse.ArgumentParser( |
42 ('Loads a URL with the resource_prefetch_predictor and prints loading ' | 44 ('Loads a URL with the resource_prefetch_predictor and prints loading ' |
43 'metrics.'), parents=[OPTIONS.GetParentParser()]) | 45 'metrics.'), parents=[OPTIONS.GetParentParser()]) |
44 parser.add_argument('--device', help='Device ID') | 46 parser.add_argument('--device', help='Device ID') |
45 parser.add_argument('--database', | 47 parser.add_argument('--database', |
46 help=('File containing the predictor database, as ' | 48 help=('File containing the predictor database, as ' |
47 'obtained from generate_database.py.')) | 49 'obtained from generate_database.py.')) |
48 parser.add_argument('--url', help='URL to load.') | 50 parser.add_argument('--url', help='URL to load.') |
49 parser.add_argument('--prefetch_delay_ms', | 51 parser.add_argument('--prefetch_delays_ms', |
50 help='Prefetch delay in ms. -1 to disable prefetch.') | 52 help='List of prefetch delays in ms. -1 to disable ' |
53 'prefetch. Runs will randomly select one delay in the ' | |
pasko
2016/12/12 18:07:10
Are you looking for the delay that produces best r
Benoit L
2016/12/14 17:39:39
No, it's to disable the prefetcher, with something
pasko
2016/12/14 19:38:33
if that's the only usecase, let's have a hardcoded
Benoit L
2016/12/16 14:27:00
Well, I would also like to see the impact of sever
pasko
2016/12/16 16:49:54
This contradicts to the "No, it's to disable the p
| |
54 'list.') | |
51 parser.add_argument('--output_filename', | 55 parser.add_argument('--output_filename', |
52 help='CSV file to append the result to.') | 56 help='CSV file to append the result to.') |
57 parser.add_argument('--network_condition', | |
58 help='Network condition for emulation.') | |
59 parser.add_argument('--wpr_archive', help='WPR archive path.') | |
60 parser.add_argument('--once', help='Only run once.', action='store_true') | |
53 return parser | 61 return parser |
54 | 62 |
55 | 63 |
56 def _Setup(device, database_filename): | 64 def _Setup(device, database_filename): |
57 """Sets up a device and returns an instance of RemoteChromeController.""" | 65 """Sets up a device and returns an instance of RemoteChromeController.""" |
58 chrome_controller = prefetch_predictor_common.Setup(device, ['']) | 66 chrome_controller = prefetch_predictor_common.Setup(device, ['']) |
59 chrome_package = OPTIONS.ChromePackage() | 67 chrome_package = OPTIONS.ChromePackage() |
60 device.ForceStop(chrome_package.package) | 68 device.ForceStop(chrome_package.package) |
61 chrome_controller.ResetBrowserState() | 69 chrome_controller.ResetBrowserState() |
62 device_database_filename = prefetch_predictor_common.DatabaseDevicePath() | 70 device_database_filename = prefetch_predictor_common.DatabaseDevicePath() |
(...skipping 18 matching lines...) Expand all Loading... | |
81 group = stats['st_group'] | 89 group = stats['st_group'] |
82 # Now push the database. Needs to be done after the first launch, otherwise | 90 # Now push the database. Needs to be done after the first launch, otherwise |
83 # the profile directory is owned by root. Also change the owner of the | 91 # the profile directory is owned by root. Also change the owner of the |
84 # database, since adb push sets it to root. | 92 # database, since adb push sets it to root. |
85 database_content = open(database_filename, 'r').read() | 93 database_content = open(database_filename, 'r').read() |
86 device.WriteFile(device_database_filename, database_content, force_push=True) | 94 device.WriteFile(device_database_filename, database_content, force_push=True) |
87 command = 'chown %s:%s \'%s\'' % (owner, group, device_database_filename) | 95 command = 'chown %s:%s \'%s\'' % (owner, group, device_database_filename) |
88 device.RunShellCommand(command, as_root=True) | 96 device.RunShellCommand(command, as_root=True) |
89 | 97 |
90 | 98 |
91 def _Go(device, url, prefetch_delay_ms): | 99 def _Go(device, url, prefetch_delay_ms, wpr_archive, network_condition): |
92 disable_prefetch = prefetch_delay_ms == -1 | 100 disable_prefetch = prefetch_delay_ms == -1 |
93 # Startup tracing to ease debugging. | 101 # Startup tracing to ease debugging. |
94 chrome_args = (customtabs_benchmark.CHROME_ARGS | 102 chrome_args = (customtabs_benchmark.CHROME_ARGS |
95 + ['--trace-startup', '--trace-startup-duration=20']) | 103 + ['--trace-startup', '--trace-startup-duration=20']) |
96 if not disable_prefetch: | 104 if not disable_prefetch: |
97 chrome_args.append(_EXTERNAL_PREFETCH_FLAG) | 105 chrome_args.append(_EXTERNAL_PREFETCH_FLAG) |
98 prefetch_mode = 'disabled' if disable_prefetch else 'speculative_prefetch' | 106 |
99 result = customtabs_benchmark.RunOnce( | 107 chrome_controller = controller.RemoteChromeController(device) |
100 device, url, warmup=True, speculation_mode=prefetch_mode, | 108 device.ForceStop(OPTIONS.ChromePackage().package) |
101 delay_to_may_launch_url=2000, | 109 chrome_controller.AddChromeArguments(chrome_args) |
102 delay_to_launch_url=prefetch_delay_ms, cold=False, | 110 |
103 chrome_args=chrome_args, reset_chrome_state=False) | 111 with device_setup.RemoteWprHost( |
112 device, wpr_archive, record=False, | |
113 network_condition_name=network_condition) as wpr: | |
114 print wpr.chrome_args | |
pasko
2016/12/14 19:38:33
nit: looks like debug code left here, but if you w
Benoit L
2016/12/16 14:27:00
Done.
| |
115 chrome_args += wpr.chrome_args | |
116 prefetch_mode = 'disabled' if disable_prefetch else 'speculative_prefetch' | |
117 result = customtabs_benchmark.RunOnce( | |
118 device, url, warmup=True, speculation_mode=prefetch_mode, | |
119 delay_to_may_launch_url=2000, | |
120 delay_to_launch_url=prefetch_delay_ms, cold=False, | |
121 chrome_args=chrome_args, reset_chrome_state=False) | |
104 return customtabs_benchmark.ParseResult(result) | 122 return customtabs_benchmark.ParseResult(result) |
105 | 123 |
106 | 124 |
125 def _RunOnce(device, database_filename, url, prefetch_delay_ms, | |
126 output_filename, wpr_archive, network_condition): | |
127 _Setup(device, database_filename) | |
128 result = _Go(device, url, prefetch_delay_ms, wpr_archive, network_condition) | |
pasko
2016/12/12 18:07:09
naming: When given a "Go" and "RunOnce" and knowin
Benoit L
2016/12/14 17:39:39
Done.
| |
129 with open(output_filename, 'a') as f: | |
130 f.write(','.join(str(x) for x in result) + '\n') | |
pasko
2016/12/12 18:07:09
please print CSV columns as the first line of the
Benoit L
2016/12/14 17:39:39
Done.
| |
131 | |
132 | |
107 def main(): | 133 def main(): |
108 logging.basicConfig(level=logging.INFO) | 134 logging.basicConfig(level=logging.INFO) |
109 devil_chromium.Initialize() | 135 devil_chromium.Initialize() |
110 | 136 |
111 parser = _CreateArgumentParser() | 137 parser = _CreateArgumentParser() |
112 args = parser.parse_args() | 138 args = parser.parse_args() |
113 OPTIONS.SetParsedArgs(args) | 139 OPTIONS.SetParsedArgs(args) |
114 device = prefetch_predictor_common.FindDevice(args.device) | 140 device = prefetch_predictor_common.FindDevice(args.device) |
115 if device is None: | 141 if device is None: |
116 logging.error('Could not find device: %s.', args.device) | 142 logging.error('Could not find device: %s.', args.device) |
117 sys.exit(1) | 143 sys.exit(1) |
118 | 144 |
119 _Setup(device, args.database) | 145 delays = [int(x) for x in args.prefetch_delays_ms.split(',')] |
120 result = _Go(device, args.url, int(args.prefetch_delay_ms)) | 146 |
121 print result | 147 while True: |
122 with open(args.output_filename, 'a') as f: | 148 delay = delays[random.randint(0, len(delays) - 1)] |
123 f.write(','.join(str(x) for x in result) + '\n') | 149 _RunOnce(device, args.database, args.url, delay, args.output_filename, |
pasko
2016/12/12 18:07:09
for extra robustness against data mis-interpretati
Benoit L
2016/12/14 17:39:39
Done.
| |
150 args.wpr_archive, args.network_condition) | |
151 if args.once: | |
152 return | |
124 | 153 |
125 | 154 |
126 if __name__ == '__main__': | 155 if __name__ == '__main__': |
127 main() | 156 main() |
OLD | NEW |