Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # | 2 # |
| 3 # Copyright 2015 The Chromium Authors. All rights reserved. | 3 # Copyright 2015 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 """Loops Custom Tabs tests and outputs the results into a CSV file.""" | 7 """Loops Custom Tabs tests and outputs the results into a CSV file.""" |
| 8 | 8 |
| 9 import collections | |
| 9 import contextlib | 10 import contextlib |
| 10 import logging | 11 import logging |
| 11 import optparse | 12 import optparse |
| 12 import os | 13 import os |
| 13 import random | 14 import random |
| 14 import re | 15 import re |
| 15 import subprocess | 16 import subprocess |
| 16 import sys | 17 import sys |
| 17 import time | 18 import time |
| 18 | 19 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 31 sys.path.append(os.path.join(_SRC_PATH, 'tools', 'android', 'loading')) | 32 sys.path.append(os.path.join(_SRC_PATH, 'tools', 'android', 'loading')) |
| 32 import device_setup | 33 import device_setup |
| 33 | 34 |
| 34 | 35 |
| 35 # Local build of Chrome (not Chromium). | 36 # Local build of Chrome (not Chromium). |
| 36 _CHROME_PACKAGE = 'com.google.android.apps.chrome' | 37 _CHROME_PACKAGE = 'com.google.android.apps.chrome' |
| 37 _COMMAND_LINE_PATH = '/data/local/tmp/chrome-command-line' | 38 _COMMAND_LINE_PATH = '/data/local/tmp/chrome-command-line' |
| 38 _TEST_APP_PACKAGE_NAME = 'org.chromium.customtabsclient.test' | 39 _TEST_APP_PACKAGE_NAME = 'org.chromium.customtabsclient.test' |
| 39 | 40 |
| 40 # Command line arguments for Chrome. | 41 # Command line arguments for Chrome. |
| 41 _CHROME_ARGS = [ | 42 CHROME_ARGS = [ |
| 42 # Disable backgound network requests that may pollute WPR archive, pollute | 43 # Disable backgound network requests that may pollute WPR archive, pollute |
| 43 # HTTP cache generation, and introduce noise in loading performance. | 44 # HTTP cache generation, and introduce noise in loading performance. |
| 44 '--disable-background-networking', | 45 '--disable-background-networking', |
| 45 '--disable-default-apps', | 46 '--disable-default-apps', |
| 46 '--no-proxy-server', | 47 '--no-proxy-server', |
| 47 # TODO(droger): Remove once crbug.com/354743 is fixed. | 48 # TODO(droger): Remove once crbug.com/354743 is fixed. |
| 48 '--safebrowsing-disable-auto-update', | 49 '--safebrowsing-disable-auto-update', |
| 49 | 50 |
| 50 # Disables actions that chrome performs only on first run or each launches, | 51 # Disables actions that chrome performs only on first run or each launches, |
| 51 # which can interfere with page load performance, or even block its | 52 # which can interfere with page load performance, or even block its |
| 52 # execution by waiting for user input. | 53 # execution by waiting for user input. |
| 53 '--disable-fre', | 54 '--disable-fre', |
| 54 '--no-default-browser-check', | 55 '--no-default-browser-check', |
| 55 '--no-first-run', | 56 '--no-first-run', |
| 56 ] | 57 ] |
| 57 | 58 |
| 58 | 59 |
| 59 def ResetChromeLocalState(device): | 60 def ResetChromeLocalState(device): |
| 60 """Remove the Chrome Profile and the various disk caches.""" | 61 """Remove the Chrome Profile and the various disk caches.""" |
| 61 profile_dirs = ['app_chrome/Default', 'cache', 'app_chrome/ShaderCache', | 62 profile_dirs = ['app_chrome/Default', 'cache', 'app_chrome/ShaderCache', |
| 62 'app_tabs'] | 63 'app_tabs'] |
| 63 cmd = ['rm', '-rf'] | 64 cmd = ['rm', '-rf'] |
| 64 cmd.extend( | 65 cmd.extend( |
| 65 '/data/data/{}/{}'.format(_CHROME_PACKAGE, d) for d in profile_dirs) | 66 '/data/data/{}/{}'.format(_CHROME_PACKAGE, d) for d in profile_dirs) |
| 66 device.adb.Shell(subprocess.list2cmdline(cmd)) | 67 device.adb.Shell(subprocess.list2cmdline(cmd)) |
| 67 | 68 |
| 68 | 69 |
| 69 def RunOnce(device, url, warmup, speculation_mode, delay_to_may_launch_url, | 70 def RunOnce(device, url, warmup, speculation_mode, delay_to_may_launch_url, |
| 70 delay_to_launch_url, cold, chrome_args): | 71 delay_to_launch_url, cold, chrome_args, reset_chrome_state=False): |
|
pasko
2016/11/17 15:59:04
s/=False//
please avoid default arguments, they c
Benoit L
2016/11/21 13:40:32
Done.
| |
| 71 """Runs a test on a device once. | 72 """Runs a test on a device once. |
| 72 | 73 |
| 73 Args: | 74 Args: |
| 74 device: (DeviceUtils) device to run the tests on. | 75 device: (DeviceUtils) device to run the tests on. |
| 75 url: (str) URL to load. | 76 url: (str) URL to load. |
| 76 warmup: (bool) Whether to call warmup. | 77 warmup: (bool) Whether to call warmup. |
| 77 speculation_mode: (str) Speculation Mode. | 78 speculation_mode: (str) Speculation Mode. |
| 78 delay_to_may_launch_url: (int) Delay to mayLaunchUrl() in ms. | 79 delay_to_may_launch_url: (int) Delay to mayLaunchUrl() in ms. |
| 79 delay_to_launch_url: (int) Delay to launchUrl() in ms. | 80 delay_to_launch_url: (int) Delay to launchUrl() in ms. |
| 80 cold: (bool) Whether the page cache should be dropped. | 81 cold: (bool) Whether the page cache should be dropped. |
| 81 chrome_args: ([str]) List of arguments to pass to Chrome. | 82 chrome_args: ([str]) List of arguments to pass to Chrome. |
| 83 reset_chrome_state: (bool) Whether to reset the Chrome local state before | |
| 84 the run. | |
| 82 | 85 |
| 83 Returns: | 86 Returns: |
| 84 The output line (str), like this (one line only): | 87 The output line (str), like this (one line only): |
| 85 <warmup>,<prerender_mode>,<delay_to_may_launch_url>,<delay_to_launch>, | 88 <warmup>,<prerender_mode>,<delay_to_may_launch_url>,<delay_to_launch>, |
| 86 <intent_sent_ms>,<page_load_started_ms>,<page_load_finished_ms>, | 89 <intent_sent_ms>,<page_load_started_ms>,<page_load_finished_ms>, |
| 87 <first_contentful_paint> | 90 <first_contentful_paint> |
| 88 or None on error. | 91 or None on error. |
| 89 """ | 92 """ |
| 90 if not device.HasRoot(): | 93 if not device.HasRoot(): |
| 91 device.EnableRoot() | 94 device.EnableRoot() |
| 92 | 95 |
| 93 with device_setup.FlagReplacer(device, _COMMAND_LINE_PATH, chrome_args): | 96 with device_setup.FlagReplacer(device, _COMMAND_LINE_PATH, chrome_args): |
| 94 launch_intent = intent.Intent( | 97 launch_intent = intent.Intent( |
| 95 action='android.intent.action.MAIN', | 98 action='android.intent.action.MAIN', |
| 96 package=_TEST_APP_PACKAGE_NAME, | 99 package=_TEST_APP_PACKAGE_NAME, |
| 97 activity='org.chromium.customtabs.test.MainActivity', | 100 activity='org.chromium.customtabs.test.MainActivity', |
| 98 extras={'url': str(url), 'warmup': warmup, | 101 extras={'url': str(url), 'warmup': warmup, |
| 99 'speculation_mode': str(speculation_mode), | 102 'speculation_mode': str(speculation_mode), |
| 100 'delay_to_may_launch_url': delay_to_may_launch_url, | 103 'delay_to_may_launch_url': delay_to_may_launch_url, |
| 101 'delay_to_launch_url': delay_to_launch_url}) | 104 'delay_to_launch_url': delay_to_launch_url}) |
| 102 result_line_re = re.compile(r'CUSTOMTABSBENCH.*: (.*)') | 105 result_line_re = re.compile(r'CUSTOMTABSBENCH.*: (.*)') |
| 103 logcat_monitor = device.GetLogcatMonitor(clear=True) | 106 logcat_monitor = device.GetLogcatMonitor(clear=True) |
| 104 logcat_monitor.Start() | 107 logcat_monitor.Start() |
| 105 device.ForceStop(_CHROME_PACKAGE) | 108 device.ForceStop(_CHROME_PACKAGE) |
| 106 device.ForceStop(_TEST_APP_PACKAGE_NAME) | 109 device.ForceStop(_TEST_APP_PACKAGE_NAME) |
| 107 | 110 |
| 108 ResetChromeLocalState(device) | 111 if reset_chrome_state: |
| 112 ResetChromeLocalState(device) | |
| 109 | 113 |
| 110 if cold: | 114 if cold: |
| 111 cache_control.CacheControl(device).DropRamCaches() | 115 cache_control.CacheControl(device).DropRamCaches() |
| 112 | 116 |
| 113 device.StartActivity(launch_intent, blocking=True) | 117 device.StartActivity(launch_intent, blocking=True) |
| 114 | 118 |
| 115 match = None | 119 match = None |
| 116 try: | 120 try: |
| 117 match = logcat_monitor.WaitFor(result_line_re, timeout=20) | 121 match = logcat_monitor.WaitFor(result_line_re, timeout=20) |
| 118 except device_errors.CommandTimeoutError as _: | 122 except device_errors.CommandTimeoutError as _: |
| 119 logging.warning('Timeout waiting for the result line') | 123 logging.warning('Timeout waiting for the result line') |
| 120 logcat_monitor.Stop() | 124 logcat_monitor.Stop() |
| 121 logcat_monitor.Close() | 125 logcat_monitor.Close() |
| 122 return match.group(1) if match is not None else None | 126 return match.group(1) if match is not None else None |
| 123 | 127 |
| 124 | 128 |
| 129 Result = collections.namedtuple('Result', ['warmup', 'speculation_mode', | |
| 130 'delay_to_may_launch_url', | |
| 131 'delay_to_launch_url', | |
| 132 'commit', 'plt', | |
| 133 'first_contentful_paint']) | |
| 134 | |
| 135 | |
| 136 def ParseResult(result_line): | |
| 137 """Parses a result line, and returns it. | |
| 138 | |
| 139 Args: | |
| 140 result_line: (str) A result line, as returned by RunOnce(). | |
| 141 | |
| 142 Returns: | |
| 143 An instance of Result. | |
| 144 """ | |
| 145 tokens = result_line.strip().split(',') | |
| 146 assert len(tokens) == 8 | |
| 147 intent_sent_timestamp = int(tokens[4]) | |
| 148 return Result(bool(tokens[0]), tokens[1], int(tokens[2]), int(tokens[3]), | |
| 149 int(tokens[5]) - intent_sent_timestamp, | |
| 150 int(tokens[6]) - intent_sent_timestamp, int(tokens[7])) | |
| 151 | |
| 152 | |
| 125 def LoopOnDevice(device, configs, output_filename, wpr_archive_path=None, | 153 def LoopOnDevice(device, configs, output_filename, wpr_archive_path=None, |
| 126 wpr_record=None, network_condition=None, wpr_log_path=None, | 154 wpr_record=None, network_condition=None, wpr_log_path=None, |
| 127 once=False, should_stop=None): | 155 once=False, should_stop=None): |
| 128 """Loops the tests on a device. | 156 """Loops the tests on a device. |
| 129 | 157 |
| 130 Args: | 158 Args: |
| 131 device: (DeviceUtils) device to run the tests on. | 159 device: (DeviceUtils) device to run the tests on. |
| 132 configs: ([dict]) | 160 configs: ([dict]) |
| 133 output_filename: (str) Output filename. '-' for stdout. | 161 output_filename: (str) Output filename. '-' for stdout. |
| 134 wpr_archive_path: (str) Path to the WPR archive. | 162 wpr_archive_path: (str) Path to the WPR archive. |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 277 'delay_to_launch_url': options.delay_to_launch_url, | 305 'delay_to_launch_url': options.delay_to_launch_url, |
| 278 'cold': options.cold, | 306 'cold': options.cold, |
| 279 } | 307 } |
| 280 LoopOnDevice(device, [config], options.output_file, options.wpr_archive, | 308 LoopOnDevice(device, [config], options.output_file, options.wpr_archive, |
| 281 options.record, options.network_condition, options.wpr_log, | 309 options.record, options.network_condition, options.wpr_log, |
| 282 once=options.once) | 310 once=options.once) |
| 283 | 311 |
| 284 | 312 |
| 285 if __name__ == '__main__': | 313 if __name__ == '__main__': |
| 286 main() | 314 main() |
| OLD | NEW |