| Index: Tools/Scripts/webkitpy/layout_tests/port/android.py
|
| diff --git a/Tools/Scripts/webkitpy/layout_tests/port/android.py b/Tools/Scripts/webkitpy/layout_tests/port/android.py
|
| index fef6cdfec39aca43f6037ba94f92fbbe696f0d6f..ae509609deca8aea77caa16e3a1aa1ef7607d6a0 100644
|
| --- a/Tools/Scripts/webkitpy/layout_tests/port/android.py
|
| +++ b/Tools/Scripts/webkitpy/layout_tests/port/android.py
|
| @@ -62,8 +62,8 @@ DEVICE_SOURCE_ROOT_DIR = '/data/local/tmp/'
|
| DEVICE_WEBKIT_BASE_DIR = DEVICE_SOURCE_ROOT_DIR + 'third_party/WebKit/'
|
| DEVICE_LAYOUT_TESTS_DIR = DEVICE_WEBKIT_BASE_DIR + 'LayoutTests/'
|
|
|
| -SCALING_GOVERNORS_PATTERN = "/sys/devices/system/cpu/cpu*/cpufreq/scaling_governor"
|
| -KPTR_RESTRICT_PATH = "/proc/sys/kernel/kptr_restrict"
|
| +SCALING_GOVERNORS_PATTERN = '/sys/devices/system/cpu/cpu*/cpufreq/scaling_governor'
|
| +KPTR_RESTRICT_PATH = '/proc/sys/kernel/kptr_restrict'
|
|
|
| # All the test cases are still served to the test runner through file protocol,
|
| # but we use a file-to-http feature to bridge the file request to host's http
|
| @@ -121,7 +121,10 @@ HOST_FONT_FILES = [
|
| [['/usr/share/fonts/truetype/ttf-indic-fonts-core/'], 'lohit_ta.ttf', 'ttf-indic-fonts-core'],
|
| [['/usr/share/fonts/truetype/ttf-indic-fonts-core/'], 'MuktiNarrow.ttf', 'ttf-indic-fonts-core'],
|
| [['/usr/share/fonts/truetype/thai/', '/usr/share/fonts/truetype/tlwg/'], 'Garuda.ttf', 'fonts-tlwg-garuda'],
|
| - [['/usr/share/fonts/truetype/ttf-indic-fonts-core/', '/usr/share/fonts/truetype/ttf-punjabi-fonts/'], 'lohit_pa.ttf', 'ttf-indic-fonts-core'],
|
| + [['/usr/share/fonts/truetype/ttf-indic-fonts-core/',
|
| + '/usr/share/fonts/truetype/ttf-punjabi-fonts/'],
|
| + 'lohit_pa.ttf',
|
| + 'ttf-indic-fonts-core'],
|
| ]
|
|
|
| # Test resources that need to be accessed as files directly.
|
| @@ -146,6 +149,7 @@ MD5SUM_DEVICE_PATH = '/data/local/tmp/' + MD5SUM_DEVICE_FILE_NAME
|
|
|
| # Information required when running layout tests using content_shell as the test runner.
|
| class ContentShellDriverDetails():
|
| +
|
| def device_cache_directory(self):
|
| return self.device_directory() + 'cache/'
|
|
|
| @@ -254,7 +258,10 @@ class AndroidCommands(object):
|
| else:
|
| error_handler = None
|
|
|
| - result = self._executive.run_command(self.adb_command() + command, error_handler=error_handler, debug_logging=self._debug_logging)
|
| + result = self._executive.run_command(
|
| + self.adb_command() + command,
|
| + error_handler=error_handler,
|
| + debug_logging=self._debug_logging)
|
|
|
| # We limit the length to avoid outputting too verbose commands, such as "adb logcat".
|
| self._log_debug('Run adb result: ' + result[:80])
|
| @@ -283,7 +290,7 @@ class AndroidCommands(object):
|
| path_version = AndroidCommands._determine_adb_version(path_option, executive, debug_logging)
|
| if not path_version:
|
| continue
|
| - if command_version != None and path_version < command_version:
|
| + if command_version is not None and path_version < command_version:
|
| continue
|
|
|
| command_path = path_option
|
| @@ -361,7 +368,7 @@ class AndroidDevices(object):
|
| commands = AndroidCommands(executive, device_serial, self._debug_logging)
|
| if self._battery_level_for_device(commands) < AndroidDevices.MINIMUM_BATTERY_PERCENTAGE:
|
| _log.warning('Device with serial "%s" skipped because it has less than %d percent battery.'
|
| - % (commands.get_serial(), AndroidDevices.MINIMUM_BATTERY_PERCENTAGE))
|
| + % (commands.get_serial(), AndroidDevices.MINIMUM_BATTERY_PERCENTAGE))
|
| continue
|
|
|
| if not self._is_device_screen_on(commands):
|
| @@ -441,7 +448,7 @@ class AndroidPort(base.Port):
|
|
|
| # Tell AndroidCommands where to search for the "adb" command.
|
| AndroidCommands.set_adb_command_path_options(['adb',
|
| - self.path_from_chromium_base('third_party', 'android_tools', 'sdk', 'platform-tools', 'adb')])
|
| + self.path_from_chromium_base('third_party', 'android_tools', 'sdk', 'platform-tools', 'adb')])
|
|
|
| prepared_devices = self.get_option('prepared_devices', [])
|
| for serial in prepared_devices:
|
| @@ -476,7 +483,9 @@ class AndroidPort(base.Port):
|
| def default_child_processes(self):
|
| usable_devices = self._devices.usable_devices(self._executive)
|
| if not usable_devices:
|
| - raise test_run_results.TestRunException(test_run_results.NO_DEVICES_EXIT_STATUS, "Unable to find any attached Android devices.")
|
| + raise test_run_results.TestRunException(
|
| + test_run_results.NO_DEVICES_EXIT_STATUS,
|
| + 'Unable to find any attached Android devices.')
|
| return len(usable_devices)
|
|
|
| def check_wdiff(self, logging=True):
|
| @@ -502,7 +511,7 @@ class AndroidPort(base.Port):
|
| self._executive.run_command(['adb', 'devices'])
|
| pids = self._executive.running_pids(lambda name: 'adb' in name)
|
| if not pids:
|
| - _log.error("The adb daemon does not appear to be running.")
|
| + _log.error('The adb daemon does not appear to be running.')
|
| return False
|
|
|
| for pid in pids:
|
| @@ -535,17 +544,17 @@ class AndroidPort(base.Port):
|
| callback = printer.write_update
|
| lock.acquire()
|
| try:
|
| - callback("[%s] %s" % (serial, msg))
|
| + callback('[%s] %s' % (serial, msg))
|
| finally:
|
| lock.release()
|
|
|
| - log_safely("preparing device", throttled=False)
|
| + log_safely('preparing device', throttled=False)
|
| try:
|
| d._setup_test(log_safely)
|
| - log_safely("device prepared", throttled=False)
|
| + log_safely('device prepared', throttled=False)
|
| except (ScriptError, driver.DeviceFailure) as e:
|
| lock.acquire()
|
| - _log.warning("[%s] failed to prepare_device: %s" % (serial, str(e)))
|
| + _log.warning('[%s] failed to prepare_device: %s' % (serial, str(e)))
|
| lock.release()
|
| except KeyboardInterrupt:
|
| if pool:
|
| @@ -594,7 +603,9 @@ class AndroidPort(base.Port):
|
| exists = True
|
| break
|
| if not exists:
|
| - _log.error('You are missing %s under %s. Try installing %s. See build instructions.' % (font_file, font_dirs, package))
|
| + _log.error(
|
| + 'You are missing %s under %s. Try installing %s. See build instructions.' %
|
| + (font_file, font_dirs, package))
|
| return test_run_results.SYS_DEPS_EXIT_STATUS
|
| return test_run_results.OK_EXIT_STATUS
|
|
|
| @@ -668,7 +679,7 @@ class AndroidPerf(SingleFileOutputProfiler):
|
| _have_searched_for_perf_host = False
|
|
|
| def __init__(self, host, executable_path, output_dir, android_commands, symfs_path, kallsyms_path, identifier=None):
|
| - super(AndroidPerf, self).__init__(host, executable_path, output_dir, "data", identifier)
|
| + super(AndroidPerf, self).__init__(host, executable_path, output_dir, 'data', identifier)
|
| self._android_commands = android_commands
|
| self._perf_process = None
|
| self._symfs_path = symfs_path
|
| @@ -677,12 +688,12 @@ class AndroidPerf(SingleFileOutputProfiler):
|
| def check_configuration(self):
|
| # Check that perf is installed
|
| if not self._android_commands.file_exists('/system/bin/perf'):
|
| - print "Cannot find /system/bin/perf on device %s" % self._android_commands.get_serial()
|
| + print 'Cannot find /system/bin/perf on device %s' % self._android_commands.get_serial()
|
| return False
|
|
|
| # Check that the device is a userdebug build (or at least has the necessary libraries).
|
| if self._android_commands.run(['shell', 'getprop', 'ro.build.type']).strip() != 'userdebug':
|
| - print "Device %s is not flashed with a userdebug build of Android" % self._android_commands.get_serial()
|
| + print 'Device %s is not flashed with a userdebug build of Android' % self._android_commands.get_serial()
|
| return False
|
|
|
| # FIXME: Check that the binary actually is perf-able (has stackframe pointers)?
|
| @@ -711,7 +722,7 @@ http://goto.google.com/cr-android-perf-howto
|
|
|
| def attach_to_pid(self, pid):
|
| assert(pid)
|
| - assert(self._perf_process == None)
|
| + assert(self._perf_process is None)
|
| # FIXME: This can't be a fixed timeout!
|
| cmd = self._android_commands.adb_command() + ['shell', 'perf', 'record', '-g', '-p', pid, 'sleep', 30]
|
| self._perf_process = self._host.executive.popen(cmd)
|
| @@ -739,7 +750,7 @@ http://goto.google.com/cr-android-perf-howto
|
| return self._cached_perf_host_path
|
|
|
| def _first_ten_lines_of_profile(self, perf_output):
|
| - match = re.search("^#[^\n]*\n((?: [^\n]*\n){1,10})", perf_output, re.MULTILINE)
|
| + match = re.search('^#[^\n]*\n((?: [^\n]*\n){1,10})', perf_output, re.MULTILINE)
|
| return match.group(1) if match else None
|
|
|
| def profile_after_exit(self):
|
| @@ -778,11 +789,12 @@ http://crbug.com/165250 discusses making these pre-built binaries externally ava
|
| """
|
|
|
| perfhost_display_patch = perfhost_path if perfhost_path else 'perfhost_linux'
|
| - print "To view the full profile, run:"
|
| + print 'To view the full profile, run:'
|
| print ' '.join([perfhost_display_patch] + perfhost_report_command)
|
|
|
|
|
| class ChromiumAndroidDriver(driver.Driver):
|
| +
|
| def __init__(self, port, worker_number, pixel_tests, driver_details, android_devices, no_timeout=False):
|
| super(ChromiumAndroidDriver, self).__init__(port, worker_number, pixel_tests, no_timeout)
|
| self._in_fifo_path = driver_details.device_fifo_directory() + 'stdin.fifo'
|
| @@ -803,13 +815,13 @@ class ChromiumAndroidDriver(driver.Driver):
|
|
|
| # FIXME: If we taught ProfileFactory about "target" devices we could
|
| # just use the logic in Driver instead of duplicating it here.
|
| - if self._port.get_option("profile"):
|
| + if self._port.get_option('profile'):
|
| # FIXME: This should be done once, instead of per-driver!
|
| symfs_path = self._find_or_create_symfs()
|
| kallsyms_path = self._update_kallsyms_cache(symfs_path)
|
| # FIXME: We should pass this some sort of "Bridge" object abstraction around ADB instead of a path/device pair.
|
| self._profiler = AndroidPerf(self._port.host, self._port._path_to_driver(), self._port.results_directory(),
|
| - self._android_commands, symfs_path, kallsyms_path)
|
| + self._android_commands, symfs_path, kallsyms_path)
|
| # FIXME: This is a layering violation and should be moved to Port.check_sys_deps
|
| # once we have an abstraction around an adb_path/device_serial pair to make it
|
| # easy to make these class methods on AndroidPerf.
|
| @@ -825,7 +837,7 @@ class ChromiumAndroidDriver(driver.Driver):
|
| super(ChromiumAndroidDriver, self).__del__()
|
|
|
| def _update_kallsyms_cache(self, output_dir):
|
| - kallsyms_name = "%s-kallsyms" % self._android_commands.get_serial()
|
| + kallsyms_name = '%s-kallsyms' % self._android_commands.get_serial()
|
| kallsyms_cache_path = self._port.host.filesystem.join(output_dir, kallsyms_name)
|
|
|
| self._android_commands.restart_as_root()
|
| @@ -833,8 +845,8 @@ class ChromiumAndroidDriver(driver.Driver):
|
| saved_kptr_restrict = self._android_commands.run(['shell', 'cat', KPTR_RESTRICT_PATH]).strip()
|
| self._android_commands.run(['shell', 'echo', '0', '>', KPTR_RESTRICT_PATH])
|
|
|
| - print "Updating kallsyms file (%s) from device" % kallsyms_cache_path
|
| - self._android_commands.pull("/proc/kallsyms", kallsyms_cache_path)
|
| + print 'Updating kallsyms file (%s) from device' % kallsyms_cache_path
|
| + self._android_commands.pull('/proc/kallsyms', kallsyms_cache_path)
|
|
|
| self._android_commands.run(['shell', 'echo', saved_kptr_restrict, '>', KPTR_RESTRICT_PATH])
|
|
|
| @@ -849,16 +861,21 @@ class ChromiumAndroidDriver(driver.Driver):
|
| symfs_path = env['ANDROID_SYMFS']
|
| else:
|
| symfs_path = fs.join(self._port.results_directory(), 'symfs')
|
| - print "ANDROID_SYMFS not set, using %s" % symfs_path
|
| + print 'ANDROID_SYMFS not set, using %s' % symfs_path
|
|
|
| # find the installed path, and the path of the symboled built library
|
| # FIXME: We should get the install path from the device!
|
| - symfs_library_path = fs.join(symfs_path, "data/app-lib/%s-1/%s" % (self._driver_details.package_name(), self._driver_details.library_name()))
|
| + symfs_library_path = fs.join(
|
| + symfs_path,
|
| + 'data/app-lib/%s-1/%s' %
|
| + (self._driver_details.package_name(),
|
| + self._driver_details.library_name()))
|
| built_library_path = self._port._build_path('lib', self._driver_details.library_name())
|
| assert(fs.exists(built_library_path))
|
|
|
| - # FIXME: Ideally we'd check the sha1's first and make a soft-link instead of copying (since we probably never care about windows).
|
| - print "Updating symfs libary (%s) from built copy (%s)" % (symfs_library_path, built_library_path)
|
| + # FIXME: Ideally we'd check the sha1's first and make a soft-link instead
|
| + # of copying (since we probably never care about windows).
|
| + print 'Updating symfs libary (%s) from built copy (%s)' % (symfs_library_path, built_library_path)
|
| fs.maybe_make_directory(fs.dirname(symfs_library_path))
|
| fs.copyfile(built_library_path, symfs_library_path)
|
|
|
| @@ -924,37 +941,49 @@ class ChromiumAndroidDriver(driver.Driver):
|
| def _files_match(self, host_file, device_file):
|
| assert self._port.host.filesystem.exists(host_file)
|
| device_hashes = self._extract_hashes_from_md5sum_output(
|
| - self._port.host.executive.popen(self._android_commands.adb_command() + ['shell', MD5SUM_DEVICE_PATH, device_file],
|
| - stdout=subprocess.PIPE).stdout)
|
| + self._port.host.executive.popen(self._android_commands.adb_command() + ['shell', MD5SUM_DEVICE_PATH, device_file],
|
| + stdout=subprocess.PIPE).stdout)
|
| host_hashes = self._extract_hashes_from_md5sum_output(
|
| - self._port.host.executive.popen(args=['%s_host' % self._md5sum_path, host_file],
|
| - stdout=subprocess.PIPE).stdout)
|
| + self._port.host.executive.popen(args=['%s_host' % self._md5sum_path, host_file],
|
| + stdout=subprocess.PIPE).stdout)
|
| return host_hashes and device_hashes == host_hashes
|
|
|
| def _push_file_if_needed(self, host_file, device_file, log_callback):
|
| basename = self._port.host.filesystem.basename(host_file)
|
| - log_callback("checking %s" % basename)
|
| + log_callback('checking %s' % basename)
|
| if not self._files_match(host_file, device_file):
|
| - log_callback("pushing %s" % basename)
|
| + log_callback('pushing %s' % basename)
|
| self._android_commands.push(host_file, device_file)
|
|
|
| def _push_executable(self, log_callback):
|
| self._push_file_if_needed(self._port.path_to_forwarder(), self._driver_details.device_forwarder_path(), log_callback)
|
| for resource in self._driver_details.additional_resources():
|
| - self._push_file_if_needed(self._port._build_path(resource), self._driver_details.device_directory() + resource, log_callback)
|
| -
|
| - self._push_file_if_needed(self._port._build_path('android_main_fonts.xml'), self._driver_details.device_directory() + 'android_main_fonts.xml', log_callback)
|
| - self._push_file_if_needed(self._port._build_path('android_fallback_fonts.xml'), self._driver_details.device_directory() + 'android_fallback_fonts.xml', log_callback)
|
| -
|
| - log_callback("checking apk")
|
| + self._push_file_if_needed(
|
| + self._port._build_path(resource),
|
| + self._driver_details.device_directory() +
|
| + resource,
|
| + log_callback)
|
| +
|
| + self._push_file_if_needed(
|
| + self._port._build_path('android_main_fonts.xml'),
|
| + self._driver_details.device_directory() +
|
| + 'android_main_fonts.xml',
|
| + log_callback)
|
| + self._push_file_if_needed(
|
| + self._port._build_path('android_fallback_fonts.xml'),
|
| + self._driver_details.device_directory() +
|
| + 'android_fallback_fonts.xml',
|
| + log_callback)
|
| +
|
| + log_callback('checking apk')
|
| if self._files_match(self._port._build_path('apks', 'ContentShell.apk'),
|
| '/data/app/org.chromium.content_shell_apk-1.apk'):
|
| return
|
|
|
| - log_callback("uninstalling apk")
|
| + log_callback('uninstalling apk')
|
| self._android_commands.run(['uninstall', self._driver_details.package_name()])
|
| driver_host_path = self._port._path_to_driver()
|
| - log_callback("installing apk")
|
| + log_callback('installing apk')
|
| install_result = self._android_commands.run(['install', driver_host_path])
|
| if install_result.find('Success') == -1:
|
| self._abort('Failed to install %s onto device: %s' % (driver_host_path, install_result))
|
| @@ -966,11 +995,21 @@ class ChromiumAndroidDriver(driver.Driver):
|
| for host_dir in host_dirs:
|
| host_font_path = host_dir + font_file
|
| if self._port._check_file_exists(host_font_path, '', logging=False):
|
| - self._push_file_if_needed(host_font_path, self._driver_details.device_fonts_directory() + font_file, log_callback)
|
| + self._push_file_if_needed(
|
| + host_font_path,
|
| + self._driver_details.device_fonts_directory() +
|
| + font_file,
|
| + log_callback)
|
|
|
| def _push_test_resources(self, log_callback):
|
| for resource in TEST_RESOURCES_TO_PUSH:
|
| - self._push_file_if_needed(self._port.layout_tests_dir() + '/' + resource, DEVICE_LAYOUT_TESTS_DIR + resource, log_callback)
|
| + self._push_file_if_needed(
|
| + self._port.layout_tests_dir() +
|
| + '/' +
|
| + resource,
|
| + DEVICE_LAYOUT_TESTS_DIR +
|
| + resource,
|
| + log_callback)
|
|
|
| def _get_last_stacktrace(self):
|
| tombstones = self._android_commands.run(['shell', 'ls', '-n', '/data/tombstones/tombstone_*'])
|
| @@ -1038,7 +1077,8 @@ class ChromiumAndroidDriver(driver.Driver):
|
| if not self._port.get_option('disable_breakpad'):
|
| crashes = self._pull_crash_dumps_from_device()
|
| for crash in crashes:
|
| - stderr += '********* [%s] breakpad minidump %s:\n%s' % (self._port.host.filesystem.basename(crash), self._android_commands.get_serial(), self._port._dump_reader._get_stack_from_dump(crash))
|
| + stderr += '********* [%s] breakpad minidump %s:\n%s' % (self._port.host.filesystem.basename(
|
| + crash), self._android_commands.get_serial(), self._port._dump_reader._get_stack_from_dump(crash))
|
|
|
| return super(ChromiumAndroidDriver, self)._get_crash_log(stdout, stderr, newer_than)
|
|
|
| @@ -1088,7 +1128,7 @@ class ChromiumAndroidDriver(driver.Driver):
|
|
|
| def _start(self, pixel_tests, per_test_args):
|
| if not self._android_devices.is_device_prepared(self._android_commands.get_serial()):
|
| - raise driver.DeviceFailure("%s is not prepared in _start()" % self._android_commands.get_serial())
|
| + raise driver.DeviceFailure('%s is not prepared in _start()' % self._android_commands.get_serial())
|
|
|
| for retries in range(3):
|
| try:
|
| @@ -1118,19 +1158,28 @@ class ChromiumAndroidDriver(driver.Driver):
|
|
|
| cmd_line_file_path = self._driver_details.command_line_file()
|
| original_cmd_line_file_path = cmd_line_file_path + '.orig'
|
| - if self._android_commands.file_exists(cmd_line_file_path) and not self._android_commands.file_exists(original_cmd_line_file_path):
|
| + if self._android_commands.file_exists(
|
| + cmd_line_file_path) and not self._android_commands.file_exists(original_cmd_line_file_path):
|
| # We check for both the normal path and the backup because we do not want to step
|
| # on the backup. Otherwise, we'd clobber the backup whenever we changed the
|
| # command line during the run.
|
| self._android_commands.run(['shell', 'mv', cmd_line_file_path, original_cmd_line_file_path])
|
|
|
| - self._android_commands.run(['shell', 'echo'] + self._android_driver_cmd_line(pixel_tests, per_test_args) + ['>', self._driver_details.command_line_file()])
|
| + self._android_commands.run(['shell', 'echo'] +
|
| + self._android_driver_cmd_line(pixel_tests, per_test_args) +
|
| + ['>', self._driver_details.command_line_file()])
|
| self._created_cmd_line = True
|
|
|
| self._android_commands.run(['shell', 'rm', '-rf', self._driver_details.device_crash_dumps_directory()])
|
| self._android_commands.mkdir(self._driver_details.device_crash_dumps_directory(), chmod='777')
|
|
|
| - start_result = self._android_commands.run(['shell', 'am', 'start', '-e', 'RunInSubThread', '-n', self._driver_details.activity_name()])
|
| + start_result = self._android_commands.run(['shell',
|
| + 'am',
|
| + 'start',
|
| + '-e',
|
| + 'RunInSubThread',
|
| + '-n',
|
| + self._driver_details.activity_name()])
|
| if start_result.find('Exception') != -1:
|
| self._log_error('Failed to start the content_shell application. Exception:\n' + start_result)
|
| return False
|
| @@ -1184,7 +1233,7 @@ class ChromiumAndroidDriver(driver.Driver):
|
|
|
| # Inform the deadlock detector that the startup is successful without deadlock.
|
| normal_startup_event.set()
|
| - self._log_debug("content_shell is ready")
|
| + self._log_debug('content_shell is ready')
|
| return True
|
|
|
| def _pid_from_android_ps_output(self, ps_output, package_name):
|
|
|