def main(): parser = _CreateOptionParser() options, _ = parser.parse_args() devil_chromium.Initialize() devices = device_utils.DeviceUtils.HealthyDevices() device = devices[0] if len(devices) != 1 and options.device is None: logging.error( 'Several devices attached, must specify one with --device.') sys.exit(0) if options.device is not None: matching_devices = [d for d in devices if str(d) == options.device] if len(matching_devices) == 0: logging.error('Device not found.') sys.exit(0) device = matching_devices[0] with SetupWpr(device, options.wpr_archive, options.record, options.network_condition, options.wpr_log) as wpr_attributes: chrome_args = (_CHROME_ARGS + ['--prerender=' + options.prerender_mode] + wpr_attributes.chrome_args) with device_setup.FlagReplacer(device, '/data/local/tmp/chrome-command-line', chrome_args): LoopOnDevice(device, options.url, options.warmup, options.prerender_mode, options.delay_to_may_launch_url, options.delay_to_launch_url, options.cold, options.output_file, options.once)
def _Setup(device, database_filename): """Sets up a device and returns an instance of RemoteChromeController.""" chrome_controller = prefetch_predictor_common.Setup(device, ['']) chrome_package = OPTIONS.ChromePackage() device.ForceStop(chrome_package.package) chrome_controller.ResetBrowserState() device_database_filename = prefetch_predictor_common.DatabaseDevicePath() owner = group = None # Make sure that the speculative prefetch predictor is enabled to ensure # that the disk database is re-created. command_line_path = '/data/local/tmp/chrome-command-line' with device_setup.FlagReplacer(device, command_line_path, ['--disable-fre', _EXTERNAL_PREFETCH_FLAG]): # Launch Chrome for the first time to recreate the local state. launch_intent = intent.Intent(action='android.intent.action.MAIN', package=chrome_package.package, activity=chrome_package.activity) device.StartActivity(launch_intent, blocking=True) time.sleep(5) device.ForceStop(chrome_package.package) assert device.FileExists(device_database_filename) stats = device.StatPath(device_database_filename) owner = stats['st_owner'] group = stats['st_group'] # Now push the database. Needs to be done after the first launch, otherwise # the profile directory is owned by root. Also change the owner of the # database, since adb push sets it to root. database_content = open(database_filename, 'r').read() device.WriteFile(device_database_filename, database_content, force_push=True) command = 'chown %s:%s \'%s\'' % (owner, group, device_database_filename) device.RunShellCommand(command, as_root=True)
def RunOnce(device, url, warmup, speculation_mode, delay_to_may_launch_url, delay_to_launch_url, cold, chrome_args): """Runs a test on a device once. Args: device: (DeviceUtils) device to run the tests on. url: (str) URL to load. warmup: (bool) Whether to call warmup. speculation_mode: (str) Speculation Mode. delay_to_may_launch_url: (int) Delay to mayLaunchUrl() in ms. delay_to_launch_url: (int) Delay to launchUrl() in ms. cold: (bool) Whether the page cache should be dropped. chrome_args: ([str]) List of arguments to pass to Chrome. Returns: The output line (str), like this (one line only): <warmup>,<prerender_mode>,<delay_to_may_launch_url>,<delay_to_launch>, <intent_sent_ms>,<page_load_started_ms>,<page_load_finished_ms>, <first_contentful_paint> or None on error. """ if not device.HasRoot(): device.EnableRoot() with device_setup.FlagReplacer(device, _COMMAND_LINE_PATH, chrome_args): launch_intent = intent.Intent( action='android.intent.action.MAIN', package=_TEST_APP_PACKAGE_NAME, activity='org.chromium.customtabs.test.MainActivity', extras={ 'url': str(url), 'warmup': warmup, 'speculation_mode': str(speculation_mode), 'delay_to_may_launch_url': delay_to_may_launch_url, 'delay_to_launch_url': delay_to_launch_url }) result_line_re = re.compile(r'CUSTOMTABSBENCH.*: (.*)') logcat_monitor = device.GetLogcatMonitor(clear=True) logcat_monitor.Start() device.ForceStop(_CHROME_PACKAGE) device.ForceStop(_TEST_APP_PACKAGE_NAME) ResetChromeLocalState(device) if cold: cache_control.CacheControl(device).DropRamCaches() device.StartActivity(launch_intent, blocking=True) match = None try: match = logcat_monitor.WaitFor(result_line_re, timeout=20) except device_errors.CommandTimeoutError as _: logging.warning('Timeout waiting for the result line') logcat_monitor.Stop() logcat_monitor.Close() return match.group(1) if match is not None else None
def Open(self): """Overridden connection creation.""" if self._wpr_attributes: assert self._wpr_attributes.chrome_env_override == {}, \ 'Remote controller doesn\'t support chrome environment variables.' package_info = OPTIONS.ChromePackage() command_line_path = '/data/local/chrome-command-line' self._device.ForceStop(package_info.package) chrome_args = self._GetChromeArguments() logging.info( 'Launching %s with flags: %s' % (package_info.package, subprocess.list2cmdline(chrome_args))) with device_setup.FlagReplacer(self._device, command_line_path, self._GetChromeArguments()): start_intent = intent.Intent(package=package_info.package, activity=package_info.activity, data='about:blank') self._device.adb.Logcat(clear=True, dump=True) self._device.StartActivity(start_intent, blocking=True) try: for attempt_id in xrange(self.DEVTOOLS_CONNECTION_ATTEMPTS): logging.info('Devtools connection attempt %d' % attempt_id) with device_setup.ForwardPort( self._device, 'tcp:%d' % OPTIONS.devtools_port, 'localabstract:chrome_devtools_remote'): try: connection = devtools_monitor.DevToolsConnection( OPTIONS.devtools_hostname, OPTIONS.devtools_port) self._StartConnection(connection) except socket.error as e: if e.errno != errno.ECONNRESET: raise time.sleep( self. DEVTOOLS_CONNECTION_ATTEMPT_INTERVAL_SECONDS) continue yield connection if self._slow_death: self._device.adb.Shell( 'am start com.google.android.launcher') time.sleep(self.TIME_TO_IDLE_SECONDS) break else: raise ChromeControllerInternalError( 'Failed to connect to Chrome devtools after {} ' 'attempts.'.format(self.DEVTOOLS_CONNECTION_ATTEMPTS)) except: logcat = ''.join( [l + '\n' for l in self._device.adb.Logcat(dump=True)]) raise ChromeControllerError(log=logcat) finally: self._device.ForceStop(package_info.package)
def Open(self): """Overridden connection creation.""" package_info = OPTIONS.ChromePackage() command_line_path = '/data/local/chrome-command-line' self._device.KillAll(package_info.package, quiet=True) chrome_args = self._GetChromeArguments() logging.info( 'Launching %s with flags: %s' % (package_info.package, subprocess.list2cmdline(chrome_args))) with device_setup.FlagReplacer(self._device, command_line_path, self._GetChromeArguments()): start_intent = intent.Intent(package=package_info.package, activity=package_info.activity, data='about:blank') self._device.StartActivity(start_intent, blocking=True) try: for attempt_id in xrange(self.DEVTOOLS_CONNECTION_ATTEMPTS + 1): if attempt_id == self.DEVTOOLS_CONNECTION_ATTEMPTS: raise RuntimeError( 'Failed to connect to chrome devtools after {} ' 'attempts.'.format(attempt_id)) logging.info('Devtools connection attempt %d' % attempt_id) with device_setup.ForwardPort( self._device, 'tcp:%d' % OPTIONS.devtools_port, 'localabstract:chrome_devtools_remote'): try: connection = devtools_monitor.DevToolsConnection( OPTIONS.devtools_hostname, OPTIONS.devtools_port) self._StartConnection(connection) except socket.error as e: assert str(e).startswith( '[Errno 104] Connection reset by peer') time.sleep( self. DEVTOOLS_CONNECTION_ATTEMPT_INTERVAL_SECONDS) continue logging.info('Devtools connection success') yield connection if self._slow_death: self._device.adb.Shell( 'am start com.google.android.launcher') time.sleep(self.TIME_TO_IDLE_SECONDS) break finally: self._device.KillAll(package_info.package, quiet=True)
def RunChrome(device, cold, chrome_args, package_info): """Runs Chrome on the device. Args: device: (DeviceUtils) device to run the tests on. cold: (bool) Whether caches should be dropped. chrome_args: ([str]) List of arguments to pass to Chrome. package_info: (PackageInfo) Chrome package info. """ if not device.HasRoot(): device.EnableRoot() cmdline_file = package_info.cmdline_file package = package_info.package with device_setup.FlagReplacer(device, cmdline_file, chrome_args): device.ForceStop(package) if cold: chrome_setup.ResetChromeLocalState(device, package) cache_control.CacheControl(device).DropRamCaches() start_intent = intent.Intent(package=package, data='about:blank', activity=package_info.activity) try: device.StartActivity(start_intent, blocking=True) print('\n\n' ' +---------------------------------------------+\n' ' | Chrome launched, press Ctrl-C to interrupt. |\n' ' +---------------------------------------------+') while True: time.sleep(1) except KeyboardInterrupt: pass finally: device.ForceStop(package)
def Open(self): """Overridden connection creation.""" if self._wpr_attributes: assert self._wpr_attributes.chrome_env_override == {}, \ 'Remote controller doesn\'t support chrome environment variables.' package_info = OPTIONS.ChromePackage() command_line_path = '/data/local/chrome-command-line' self._device.ForceStop(package_info.package) chrome_args = self._GetChromeArguments() logging.info( 'Launching %s with flags: %s' % (package_info.package, subprocess.list2cmdline(chrome_args))) with device_setup.FlagReplacer(self._device, command_line_path, self._GetChromeArguments()): self._DismissCrashDialogIfNeeded() start_intent = intent.Intent(package=package_info.package, activity=package_info.activity, data='about:blank') self._device.adb.Logcat(clear=True, dump=True) self._device.StartActivity(start_intent, blocking=True) try: for attempt_id in xrange(self.DEVTOOLS_CONNECTION_ATTEMPTS): logging.info('Devtools connection attempt %d' % attempt_id) # Adb forwarding does not provide a way to print the port number if # it is allocated atomically by the OS by passing port=0, but we need # dynamically allocated listening port here to handle parallel run on # different devices. host_side_port = _AllocateTcpListeningPort() logging.info( 'Allocated host sided listening port for devtools ' 'connection: %d', host_side_port) try: with device_setup.ForwardPort( self._device, 'tcp:%d' % host_side_port, 'localabstract:chrome_devtools_remote'): try: connection = devtools_monitor.DevToolsConnection( OPTIONS.devtools_hostname, host_side_port) self._StartConnection(connection) except socket.error as e: if e.errno != errno.ECONNRESET: raise time.sleep( self. DEVTOOLS_CONNECTION_ATTEMPT_INTERVAL_SECONDS ) continue yield connection if self._slow_death: self._device.adb.Shell( 'am start com.google.android.launcher') time.sleep(self.TIME_TO_IDLE_SECONDS) break except device_errors.AdbCommandFailedError as error: _KNOWN_ADB_FORWARDER_FAILURES = [ 'cannot bind to socket: Address already in use', 'cannot rebind existing socket: Resource temporarily unavailable' ] for message in _KNOWN_ADB_FORWARDER_FAILURES: if message in error.message: break else: raise continue else: raise ChromeControllerInternalError( 'Failed to connect to Chrome devtools after {} ' 'attempts.'.format(self.DEVTOOLS_CONNECTION_ATTEMPTS)) except ChromeControllerError._PASSTHROUGH_WHITE_LIST: raise except Exception: logcat = ''.join( [l + '\n' for l in self._device.adb.Logcat(dump=True)]) raise ChromeControllerError(log=logcat) finally: self._device.ForceStop(package_info.package) self._DismissCrashDialogIfNeeded()