| OLD | NEW |
| 1 # Copyright (C) 2012 Google Inc. All rights reserved. | 1 # Copyright (C) 2012 Google Inc. All rights reserved. |
| 2 # | 2 # |
| 3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
| 4 # modification, are permitted provided that the following conditions are | 4 # modification, are permitted provided that the following conditions are |
| 5 # met: | 5 # met: |
| 6 # | 6 # |
| 7 # * Redistributions of source code must retain the above copyright | 7 # * Redistributions of source code must retain the above copyright |
| 8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
| 9 # * Redistributions in binary form must reproduce the above | 9 # * Redistributions in binary form must reproduce the above |
| 10 # copyright notice, this list of conditions and the following disclaimer | 10 # copyright notice, this list of conditions and the following disclaimer |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 'compositing/resources/video.mp4', | 139 'compositing/resources/video.mp4', |
| 140 ] | 140 ] |
| 141 | 141 |
| 142 MD5SUM_DEVICE_FILE_NAME = 'md5sum_bin' | 142 MD5SUM_DEVICE_FILE_NAME = 'md5sum_bin' |
| 143 MD5SUM_HOST_FILE_NAME = 'md5sum_bin_host' | 143 MD5SUM_HOST_FILE_NAME = 'md5sum_bin_host' |
| 144 MD5SUM_DEVICE_PATH = '/data/local/tmp/' + MD5SUM_DEVICE_FILE_NAME | 144 MD5SUM_DEVICE_PATH = '/data/local/tmp/' + MD5SUM_DEVICE_FILE_NAME |
| 145 | 145 |
| 146 | 146 |
| 147 # Information required when running layout tests using content_shell as the test
runner. | 147 # Information required when running layout tests using content_shell as the test
runner. |
| 148 class ContentShellDriverDetails(): | 148 class ContentShellDriverDetails(): |
| 149 |
| 149 def device_cache_directory(self): | 150 def device_cache_directory(self): |
| 150 return self.device_directory() + 'cache/' | 151 return self.device_directory() + 'cache/' |
| 151 | 152 |
| 152 def device_fonts_directory(self): | 153 def device_fonts_directory(self): |
| 153 return self.device_directory() + 'fonts/' | 154 return self.device_directory() + 'fonts/' |
| 154 | 155 |
| 155 def device_forwarder_path(self): | 156 def device_forwarder_path(self): |
| 156 return self.device_directory() + 'forwarder' | 157 return self.device_directory() + 'forwarder' |
| 157 | 158 |
| 158 def device_fifo_directory(self): | 159 def device_fifo_directory(self): |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 pass | 248 pass |
| 248 return pids | 249 return pids |
| 249 | 250 |
| 250 def run(self, command, ignore_error=False): | 251 def run(self, command, ignore_error=False): |
| 251 self._log_debug('Run adb command: ' + str(command)) | 252 self._log_debug('Run adb command: ' + str(command)) |
| 252 if ignore_error: | 253 if ignore_error: |
| 253 error_handler = self._executive.ignore_error | 254 error_handler = self._executive.ignore_error |
| 254 else: | 255 else: |
| 255 error_handler = None | 256 error_handler = None |
| 256 | 257 |
| 257 result = self._executive.run_command(self.adb_command() + command, error
_handler=error_handler, debug_logging=self._debug_logging) | 258 result = self._executive.run_command(self.adb_command() + command, |
| 259 error_handler=error_handler, debug_
logging=self._debug_logging) |
| 258 | 260 |
| 259 # We limit the length to avoid outputting too verbose commands, such as
"adb logcat". | 261 # We limit the length to avoid outputting too verbose commands, such as
"adb logcat". |
| 260 self._log_debug('Run adb result: ' + result[:80]) | 262 self._log_debug('Run adb result: ' + result[:80]) |
| 261 return result | 263 return result |
| 262 | 264 |
| 263 def get_serial(self): | 265 def get_serial(self): |
| 264 return self._device_serial | 266 return self._device_serial |
| 265 | 267 |
| 266 def adb_command(self): | 268 def adb_command(self): |
| 267 return [AndroidCommands.adb_command_path(self._executive, self._debug_lo
gging), '-s', self._device_serial] | 269 return [AndroidCommands.adb_command_path(self._executive, self._debug_lo
gging), '-s', self._device_serial] |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 result = executive.run_command([AndroidCommands.adb_command_path(executi
ve, debug_logging=self._debug_logging), 'devices'], | 356 result = executive.run_command([AndroidCommands.adb_command_path(executi
ve, debug_logging=self._debug_logging), 'devices'], |
| 355 error_handler=executive.ignore_error, deb
ug_logging=self._debug_logging) | 357 error_handler=executive.ignore_error, deb
ug_logging=self._debug_logging) |
| 356 devices = re_device.findall(result) | 358 devices = re_device.findall(result) |
| 357 if not devices: | 359 if not devices: |
| 358 return [] | 360 return [] |
| 359 | 361 |
| 360 for device_serial in sorted(devices): | 362 for device_serial in sorted(devices): |
| 361 commands = AndroidCommands(executive, device_serial, self._debug_log
ging) | 363 commands = AndroidCommands(executive, device_serial, self._debug_log
ging) |
| 362 if self._battery_level_for_device(commands) < AndroidDevices.MINIMUM
_BATTERY_PERCENTAGE: | 364 if self._battery_level_for_device(commands) < AndroidDevices.MINIMUM
_BATTERY_PERCENTAGE: |
| 363 _log.warning('Device with serial "%s" skipped because it has les
s than %d percent battery.' | 365 _log.warning('Device with serial "%s" skipped because it has les
s than %d percent battery.' |
| 364 % (commands.get_serial(), AndroidDevices.MINIMUM_BATTERY_PER
CENTAGE)) | 366 % (commands.get_serial(), AndroidDevices.MINIMUM_BA
TTERY_PERCENTAGE)) |
| 365 continue | 367 continue |
| 366 | 368 |
| 367 if not self._is_device_screen_on(commands): | 369 if not self._is_device_screen_on(commands): |
| 368 _log.warning('Device with serial "%s" skipped because the screen
must be on.' % commands.get_serial()) | 370 _log.warning('Device with serial "%s" skipped because the screen
must be on.' % commands.get_serial()) |
| 369 continue | 371 continue |
| 370 | 372 |
| 371 self._usable_devices.append(commands) | 373 self._usable_devices.append(commands) |
| 372 | 374 |
| 373 return self._usable_devices | 375 return self._usable_devices |
| 374 | 376 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 # Initialize the AndroidDevices class which tracks available devices. | 436 # Initialize the AndroidDevices class which tracks available devices. |
| 435 default_device = None | 437 default_device = None |
| 436 if hasattr(self._options, 'adb_device') and len(self._options.adb_device
): | 438 if hasattr(self._options, 'adb_device') and len(self._options.adb_device
): |
| 437 default_device = self._options.adb_device | 439 default_device = self._options.adb_device |
| 438 | 440 |
| 439 self._debug_logging = self.get_option('android_logging') | 441 self._debug_logging = self.get_option('android_logging') |
| 440 self._devices = AndroidDevices(self._executive, default_device, self._de
bug_logging) | 442 self._devices = AndroidDevices(self._executive, default_device, self._de
bug_logging) |
| 441 | 443 |
| 442 # Tell AndroidCommands where to search for the "adb" command. | 444 # Tell AndroidCommands where to search for the "adb" command. |
| 443 AndroidCommands.set_adb_command_path_options(['adb', | 445 AndroidCommands.set_adb_command_path_options(['adb', |
| 444 self.path_from_chromium_base('third_party', 'android_tools', 'sdk',
'platform-tools', 'adb')]) | 446 self.path_from_chromium_ba
se('third_party', 'android_tools', 'sdk', 'platform-tools', 'adb')]) |
| 445 | 447 |
| 446 prepared_devices = self.get_option('prepared_devices', []) | 448 prepared_devices = self.get_option('prepared_devices', []) |
| 447 for serial in prepared_devices: | 449 for serial in prepared_devices: |
| 448 self._devices.set_device_prepared(serial) | 450 self._devices.set_device_prepared(serial) |
| 449 | 451 |
| 450 def default_smoke_test_only(self): | 452 def default_smoke_test_only(self): |
| 451 return True | 453 return True |
| 452 | 454 |
| 453 # Local public methods. | 455 # Local public methods. |
| 454 def path_to_forwarder(self): | 456 def path_to_forwarder(self): |
| (...skipping 14 matching lines...) Expand all Loading... |
| 469 # marked as slow tests on desktop platforms. | 471 # marked as slow tests on desktop platforms. |
| 470 return 10 * 1000 | 472 return 10 * 1000 |
| 471 | 473 |
| 472 def driver_stop_timeout(self): | 474 def driver_stop_timeout(self): |
| 473 # The driver doesn't respond to closing stdin, so we might as well stop
the driver immediately. | 475 # The driver doesn't respond to closing stdin, so we might as well stop
the driver immediately. |
| 474 return 0.0 | 476 return 0.0 |
| 475 | 477 |
| 476 def default_child_processes(self): | 478 def default_child_processes(self): |
| 477 usable_devices = self._devices.usable_devices(self._executive) | 479 usable_devices = self._devices.usable_devices(self._executive) |
| 478 if not usable_devices: | 480 if not usable_devices: |
| 479 raise test_run_results.TestRunException(test_run_results.NO_DEVICES_
EXIT_STATUS, "Unable to find any attached Android devices.") | 481 raise test_run_results.TestRunException(test_run_results.NO_DEVICES_
EXIT_STATUS, |
| 482 "Unable to find any attached
Android devices.") |
| 480 return len(usable_devices) | 483 return len(usable_devices) |
| 481 | 484 |
| 482 def max_drivers_per_process(self): | 485 def max_drivers_per_process(self): |
| 483 # Android falls over when we try to run multiple content_shells per work
er. | 486 # Android falls over when we try to run multiple content_shells per work
er. |
| 484 # See https://codereview.chromium.org/1158323009/ | 487 # See https://codereview.chromium.org/1158323009/ |
| 485 return 1 | 488 return 1 |
| 486 | 489 |
| 487 def check_wdiff(self, logging=True): | 490 def check_wdiff(self, logging=True): |
| 488 return self._host_port.check_wdiff(logging) | 491 return self._host_port.check_wdiff(logging) |
| 489 | 492 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 | 595 |
| 593 def check_sys_deps(self, needs_http): | 596 def check_sys_deps(self, needs_http): |
| 594 for (font_dirs, font_file, package) in HOST_FONT_FILES: | 597 for (font_dirs, font_file, package) in HOST_FONT_FILES: |
| 595 exists = False | 598 exists = False |
| 596 for font_dir in font_dirs: | 599 for font_dir in font_dirs: |
| 597 font_path = font_dir + font_file | 600 font_path = font_dir + font_file |
| 598 if self._check_file_exists(font_path, '', logging=False): | 601 if self._check_file_exists(font_path, '', logging=False): |
| 599 exists = True | 602 exists = True |
| 600 break | 603 break |
| 601 if not exists: | 604 if not exists: |
| 602 _log.error('You are missing %s under %s. Try installing %s. See
build instructions.' % (font_file, font_dirs, package)) | 605 _log.error('You are missing %s under %s. Try installing %s. See
build instructions.' % |
| 606 (font_file, font_dirs, package)) |
| 603 return test_run_results.SYS_DEPS_EXIT_STATUS | 607 return test_run_results.SYS_DEPS_EXIT_STATUS |
| 604 return test_run_results.OK_EXIT_STATUS | 608 return test_run_results.OK_EXIT_STATUS |
| 605 | 609 |
| 606 def requires_http_server(self): | 610 def requires_http_server(self): |
| 607 """Chromium Android runs tests on devices, and uses the HTTP server to | 611 """Chromium Android runs tests on devices, and uses the HTTP server to |
| 608 serve the actual layout tests to the test driver.""" | 612 serve the actual layout tests to the test driver.""" |
| 609 return True | 613 return True |
| 610 | 614 |
| 611 def start_http_server(self, additional_dirs, number_of_drivers): | 615 def start_http_server(self, additional_dirs, number_of_drivers): |
| 612 additional_dirs[PERF_TEST_PATH_PREFIX] = self.perf_tests_dir() | 616 additional_dirs[PERF_TEST_PATH_PREFIX] = self.perf_tests_dir() |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 814 self._device_failed = False | 818 self._device_failed = False |
| 815 | 819 |
| 816 # FIXME: If we taught ProfileFactory about "target" devices we could | 820 # FIXME: If we taught ProfileFactory about "target" devices we could |
| 817 # just use the logic in Driver instead of duplicating it here. | 821 # just use the logic in Driver instead of duplicating it here. |
| 818 if self._port.get_option("profile"): | 822 if self._port.get_option("profile"): |
| 819 # FIXME: This should be done once, instead of per-driver! | 823 # FIXME: This should be done once, instead of per-driver! |
| 820 symfs_path = self._find_or_create_symfs() | 824 symfs_path = self._find_or_create_symfs() |
| 821 kallsyms_path = self._update_kallsyms_cache(symfs_path) | 825 kallsyms_path = self._update_kallsyms_cache(symfs_path) |
| 822 # FIXME: We should pass this some sort of "Bridge" object abstractio
n around ADB instead of a path/device pair. | 826 # FIXME: We should pass this some sort of "Bridge" object abstractio
n around ADB instead of a path/device pair. |
| 823 self._profiler = AndroidPerf(self._port.host, self._port._path_to_dr
iver(), self._port.results_directory(), | 827 self._profiler = AndroidPerf(self._port.host, self._port._path_to_dr
iver(), self._port.results_directory(), |
| 824 self._android_commands, symfs_path, kallsyms_path) | 828 self._android_commands, symfs_path, kal
lsyms_path) |
| 825 # FIXME: This is a layering violation and should be moved to Port.ch
eck_sys_deps | 829 # FIXME: This is a layering violation and should be moved to Port.ch
eck_sys_deps |
| 826 # once we have an abstraction around an adb_path/device_serial pair
to make it | 830 # once we have an abstraction around an adb_path/device_serial pair
to make it |
| 827 # easy to make these class methods on AndroidPerf. | 831 # easy to make these class methods on AndroidPerf. |
| 828 if not self._profiler.check_configuration(): | 832 if not self._profiler.check_configuration(): |
| 829 self._profiler.print_setup_instructions() | 833 self._profiler.print_setup_instructions() |
| 830 sys.exit(1) | 834 sys.exit(1) |
| 831 else: | 835 else: |
| 832 self._profiler = None | 836 self._profiler = None |
| 833 | 837 |
| 834 def __del__(self): | 838 def __del__(self): |
| (...skipping 23 matching lines...) Expand all Loading... |
| 858 fs = self._port.host.filesystem | 862 fs = self._port.host.filesystem |
| 859 | 863 |
| 860 if 'ANDROID_SYMFS' in env: | 864 if 'ANDROID_SYMFS' in env: |
| 861 symfs_path = env['ANDROID_SYMFS'] | 865 symfs_path = env['ANDROID_SYMFS'] |
| 862 else: | 866 else: |
| 863 symfs_path = fs.join(self._port.results_directory(), 'symfs') | 867 symfs_path = fs.join(self._port.results_directory(), 'symfs') |
| 864 _log.debug("ANDROID_SYMFS not set, using %s" % symfs_path) | 868 _log.debug("ANDROID_SYMFS not set, using %s" % symfs_path) |
| 865 | 869 |
| 866 # find the installed path, and the path of the symboled built library | 870 # find the installed path, and the path of the symboled built library |
| 867 # FIXME: We should get the install path from the device! | 871 # FIXME: We should get the install path from the device! |
| 868 symfs_library_path = fs.join(symfs_path, "data/app-lib/%s-1/%s" % (self.
_driver_details.package_name(), self._driver_details.library_name())) | 872 symfs_library_path = fs.join(symfs_path, "data/app-lib/%s-1/%s" % |
| 873 (self._driver_details.package_name(), self.
_driver_details.library_name())) |
| 869 built_library_path = self._port._build_path('lib', self._driver_details.
library_name()) | 874 built_library_path = self._port._build_path('lib', self._driver_details.
library_name()) |
| 870 assert(fs.exists(built_library_path)) | 875 assert(fs.exists(built_library_path)) |
| 871 | 876 |
| 872 # FIXME: Ideally we'd check the sha1's first and make a soft-link instea
d of copying (since we probably never care about windows). | 877 # FIXME: Ideally we'd check the sha1's first and make a soft-link instea
d |
| 878 # of copying (since we probably never care about windows). |
| 873 _log.debug("Updating symfs library (%s) from built copy (%s)" % (symfs_l
ibrary_path, built_library_path)) | 879 _log.debug("Updating symfs library (%s) from built copy (%s)" % (symfs_l
ibrary_path, built_library_path)) |
| 874 fs.maybe_make_directory(fs.dirname(symfs_library_path)) | 880 fs.maybe_make_directory(fs.dirname(symfs_library_path)) |
| 875 fs.copyfile(built_library_path, symfs_library_path) | 881 fs.copyfile(built_library_path, symfs_library_path) |
| 876 | 882 |
| 877 return symfs_path | 883 return symfs_path |
| 878 | 884 |
| 879 def _setup_md5sum_and_push_data_if_needed(self, log_callback): | 885 def _setup_md5sum_and_push_data_if_needed(self, log_callback): |
| 880 self._md5sum_path = self._port.path_to_md5sum() | 886 self._md5sum_path = self._port.path_to_md5sum() |
| 881 if not self._android_commands.file_exists(MD5SUM_DEVICE_PATH): | 887 if not self._android_commands.file_exists(MD5SUM_DEVICE_PATH): |
| 882 if not self._android_commands.push(self._md5sum_path, MD5SUM_DEVICE_
PATH): | 888 if not self._android_commands.push(self._md5sum_path, MD5SUM_DEVICE_
PATH): |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 929 raise driver.DeviceFailure('[%s] %s' % (self._android_commands.get_seria
l(), message)) | 935 raise driver.DeviceFailure('[%s] %s' % (self._android_commands.get_seria
l(), message)) |
| 930 | 936 |
| 931 @staticmethod | 937 @staticmethod |
| 932 def _extract_hashes_from_md5sum_output(md5sum_output): | 938 def _extract_hashes_from_md5sum_output(md5sum_output): |
| 933 assert md5sum_output | 939 assert md5sum_output |
| 934 return [line.split(' ')[0] for line in md5sum_output] | 940 return [line.split(' ')[0] for line in md5sum_output] |
| 935 | 941 |
| 936 def _files_match(self, host_file, device_file): | 942 def _files_match(self, host_file, device_file): |
| 937 assert self._port.host.filesystem.exists(host_file) | 943 assert self._port.host.filesystem.exists(host_file) |
| 938 device_hashes = self._extract_hashes_from_md5sum_output( | 944 device_hashes = self._extract_hashes_from_md5sum_output( |
| 939 self._port.host.executive.popen(self._android_commands.adb_comma
nd() + ['shell', MD5SUM_DEVICE_PATH, device_file], | 945 self._port.host.executive.popen(self._android_commands.adb_command()
+ ['shell', MD5SUM_DEVICE_PATH, device_file], |
| 940 stdout=subprocess.PIPE).stdout) | 946 stdout=subprocess.PIPE).stdout) |
| 941 host_hashes = self._extract_hashes_from_md5sum_output( | 947 host_hashes = self._extract_hashes_from_md5sum_output( |
| 942 self._port.host.executive.popen(args=['%s_host' % self._md5sum_p
ath, host_file], | 948 self._port.host.executive.popen(args=['%s_host' % self._md5sum_path,
host_file], |
| 943 stdout=subprocess.PIPE).stdout) | 949 stdout=subprocess.PIPE).stdout) |
| 944 return host_hashes and device_hashes == host_hashes | 950 return host_hashes and device_hashes == host_hashes |
| 945 | 951 |
| 946 def _push_file_if_needed(self, host_file, device_file, log_callback): | 952 def _push_file_if_needed(self, host_file, device_file, log_callback): |
| 947 basename = self._port.host.filesystem.basename(host_file) | 953 basename = self._port.host.filesystem.basename(host_file) |
| 948 log_callback("checking %s" % basename) | 954 log_callback("checking %s" % basename) |
| 949 if not self._files_match(host_file, device_file): | 955 if not self._files_match(host_file, device_file): |
| 950 log_callback("pushing %s" % basename) | 956 log_callback("pushing %s" % basename) |
| 951 self._android_commands.push(host_file, device_file) | 957 self._android_commands.push(host_file, device_file) |
| 952 | 958 |
| 953 def _push_executable(self, log_callback): | 959 def _push_executable(self, log_callback): |
| 954 self._push_file_if_needed(self._port.path_to_forwarder(), self._driver_d
etails.device_forwarder_path(), log_callback) | 960 self._push_file_if_needed(self._port.path_to_forwarder(), self._driver_d
etails.device_forwarder_path(), log_callback) |
| 955 for resource in self._driver_details.additional_resources(): | 961 for resource in self._driver_details.additional_resources(): |
| 956 self._push_file_if_needed(self._port._build_path(resource), self._dr
iver_details.device_directory() + resource, log_callback) | 962 self._push_file_if_needed(self._port._build_path( |
| 963 resource), self._driver_details.device_directory() + resource, l
og_callback) |
| 957 | 964 |
| 958 self._push_file_if_needed(self._port._build_path('android_main_fonts.xml
'), self._driver_details.device_directory() + 'android_main_fonts.xml', log_call
back) | 965 self._push_file_if_needed(self._port._build_path('android_main_fonts.xml
'), |
| 959 self._push_file_if_needed(self._port._build_path('android_fallback_fonts
.xml'), self._driver_details.device_directory() + 'android_fallback_fonts.xml',
log_callback) | 966 self._driver_details.device_directory() + 'and
roid_main_fonts.xml', log_callback) |
| 967 self._push_file_if_needed(self._port._build_path('android_fallback_fonts
.xml'), |
| 968 self._driver_details.device_directory() + 'and
roid_fallback_fonts.xml', log_callback) |
| 960 | 969 |
| 961 log_callback("checking apk") | 970 log_callback("checking apk") |
| 962 if self._files_match(self._port._build_path('apks', 'ContentShell.apk'), | 971 if self._files_match(self._port._build_path('apks', 'ContentShell.apk'), |
| 963 '/data/app/org.chromium.content_shell_apk-1.apk'): | 972 '/data/app/org.chromium.content_shell_apk-1.apk'): |
| 964 return | 973 return |
| 965 | 974 |
| 966 log_callback("uninstalling apk") | 975 log_callback("uninstalling apk") |
| 967 self._android_commands.run(['uninstall', self._driver_details.package_na
me()]) | 976 self._android_commands.run(['uninstall', self._driver_details.package_na
me()]) |
| 968 driver_host_path = self._port._path_to_driver() | 977 driver_host_path = self._port._path_to_driver() |
| 969 log_callback("installing apk") | 978 log_callback("installing apk") |
| 970 install_result = self._android_commands.run(['install', driver_host_path
]) | 979 install_result = self._android_commands.run(['install', driver_host_path
]) |
| 971 if install_result.find('Success') == -1: | 980 if install_result.find('Success') == -1: |
| 972 self._abort('Failed to install %s onto device: %s' % (driver_host_pa
th, install_result)) | 981 self._abort('Failed to install %s onto device: %s' % (driver_host_pa
th, install_result)) |
| 973 | 982 |
| 974 def _push_fonts(self, log_callback): | 983 def _push_fonts(self, log_callback): |
| 975 path_to_ahem_font = self._port._build_path('AHEM____.TTF') | 984 path_to_ahem_font = self._port._build_path('AHEM____.TTF') |
| 976 self._push_file_if_needed(path_to_ahem_font, self._driver_details.device
_fonts_directory() + 'AHEM____.TTF', log_callback) | 985 self._push_file_if_needed(path_to_ahem_font, self._driver_details.device
_fonts_directory() + 'AHEM____.TTF', log_callback) |
| 977 for (host_dirs, font_file, package) in HOST_FONT_FILES: | 986 for (host_dirs, font_file, package) in HOST_FONT_FILES: |
| 978 for host_dir in host_dirs: | 987 for host_dir in host_dirs: |
| 979 host_font_path = host_dir + font_file | 988 host_font_path = host_dir + font_file |
| 980 if self._port._check_file_exists(host_font_path, '', logging=Fal
se): | 989 if self._port._check_file_exists(host_font_path, '', logging=Fal
se): |
| 981 self._push_file_if_needed(host_font_path, self._driver_detai
ls.device_fonts_directory() + font_file, log_callback) | 990 self._push_file_if_needed( |
| 991 host_font_path, self._driver_details.device_fonts_direct
ory() + font_file, log_callback) |
| 982 | 992 |
| 983 def _push_test_resources(self, log_callback): | 993 def _push_test_resources(self, log_callback): |
| 984 for resource in TEST_RESOURCES_TO_PUSH: | 994 for resource in TEST_RESOURCES_TO_PUSH: |
| 985 self._push_file_if_needed(self._port.layout_tests_dir() + '/' + reso
urce, DEVICE_LAYOUT_TESTS_DIR + resource, log_callback) | 995 self._push_file_if_needed(self._port.layout_tests_dir() + '/' + reso
urce, |
| 996 DEVICE_LAYOUT_TESTS_DIR + resource, log_ca
llback) |
| 986 | 997 |
| 987 def _get_last_stacktrace(self): | 998 def _get_last_stacktrace(self): |
| 988 tombstones = self._android_commands.run(['shell', 'ls', '-n', '/data/tom
bstones/tombstone_*']) | 999 tombstones = self._android_commands.run(['shell', 'ls', '-n', '/data/tom
bstones/tombstone_*']) |
| 989 if not tombstones or tombstones.startswith('/data/tombstones/tombstone_*
: No such file or directory'): | 1000 if not tombstones or tombstones.startswith('/data/tombstones/tombstone_*
: No such file or directory'): |
| 990 self._log_error('The driver crashed, but no tombstone found!') | 1001 self._log_error('The driver crashed, but no tombstone found!') |
| 991 return '' | 1002 return '' |
| 992 | 1003 |
| 993 if tombstones.startswith('/data/tombstones/tombstone_*: Permission denie
d'): | 1004 if tombstones.startswith('/data/tombstones/tombstone_*: Permission denie
d'): |
| 994 # FIXME: crbug.com/321489 ... figure out why this happens. | 1005 # FIXME: crbug.com/321489 ... figure out why this happens. |
| 995 self._log_error('The driver crashed, but we could not read the tombs
tones!') | 1006 self._log_error('The driver crashed, but we could not read the tombs
tones!') |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1043 if not stdout: | 1054 if not stdout: |
| 1044 stdout = '' | 1055 stdout = '' |
| 1045 stdout += '********* [%s] Logcat:\n%s' % (self._android_commands.get_ser
ial(), self._get_logcat()) | 1056 stdout += '********* [%s] Logcat:\n%s' % (self._android_commands.get_ser
ial(), self._get_logcat()) |
| 1046 if not stderr: | 1057 if not stderr: |
| 1047 stderr = '' | 1058 stderr = '' |
| 1048 stderr += '********* [%s] Tombstone file:\n%s' % (self._android_commands
.get_serial(), self._get_last_stacktrace()) | 1059 stderr += '********* [%s] Tombstone file:\n%s' % (self._android_commands
.get_serial(), self._get_last_stacktrace()) |
| 1049 | 1060 |
| 1050 if not self._port.get_option('disable_breakpad'): | 1061 if not self._port.get_option('disable_breakpad'): |
| 1051 crashes = self._pull_crash_dumps_from_device() | 1062 crashes = self._pull_crash_dumps_from_device() |
| 1052 for crash in crashes: | 1063 for crash in crashes: |
| 1053 stderr += '********* [%s] breakpad minidump %s:\n%s' % (self._po
rt.host.filesystem.basename(crash), self._android_commands.get_serial(), self._p
ort._dump_reader._get_stack_from_dump(crash)) | 1064 stderr += '********* [%s] breakpad minidump %s:\n%s' % (self._po
rt.host.filesystem.basename( |
| 1065 crash), self._android_commands.get_serial(), self._port._dum
p_reader._get_stack_from_dump(crash)) |
| 1054 | 1066 |
| 1055 # The parent method expects stdout and stderr to be byte streams, but | 1067 # The parent method expects stdout and stderr to be byte streams, but |
| 1056 # since adb shell does newline conversion, we used universal_newlines | 1068 # since adb shell does newline conversion, we used universal_newlines |
| 1057 # when launching the processes, and hence our stdout and stderr are | 1069 # when launching the processes, and hence our stdout and stderr are |
| 1058 # text objects that need to be encoded back into bytes. | 1070 # text objects that need to be encoded back into bytes. |
| 1059 return super(ChromiumAndroidDriver, self)._get_crash_log( | 1071 return super(ChromiumAndroidDriver, self)._get_crash_log( |
| 1060 stdout.encode('utf8', 'replace'), | 1072 stdout.encode('utf8', 'replace'), |
| 1061 stderr.encode('utf8', 'replace'), | 1073 stderr.encode('utf8', 'replace'), |
| 1062 newer_than) | 1074 newer_than) |
| 1063 | 1075 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1136 self._android_commands.run(['logcat', '-c']) | 1148 self._android_commands.run(['logcat', '-c']) |
| 1137 | 1149 |
| 1138 cmd_line_file_path = self._driver_details.command_line_file() | 1150 cmd_line_file_path = self._driver_details.command_line_file() |
| 1139 original_cmd_line_file_path = cmd_line_file_path + '.orig' | 1151 original_cmd_line_file_path = cmd_line_file_path + '.orig' |
| 1140 if self._android_commands.file_exists(cmd_line_file_path) and not self._
android_commands.file_exists(original_cmd_line_file_path): | 1152 if self._android_commands.file_exists(cmd_line_file_path) and not self._
android_commands.file_exists(original_cmd_line_file_path): |
| 1141 # We check for both the normal path and the backup because we do not
want to step | 1153 # We check for both the normal path and the backup because we do not
want to step |
| 1142 # on the backup. Otherwise, we'd clobber the backup whenever we chan
ged the | 1154 # on the backup. Otherwise, we'd clobber the backup whenever we chan
ged the |
| 1143 # command line during the run. | 1155 # command line during the run. |
| 1144 self._android_commands.run(['shell', 'mv', cmd_line_file_path, origi
nal_cmd_line_file_path]) | 1156 self._android_commands.run(['shell', 'mv', cmd_line_file_path, origi
nal_cmd_line_file_path]) |
| 1145 | 1157 |
| 1146 self._android_commands.run(['shell', 'echo'] + self._android_driver_cmd_
line(pixel_tests, per_test_args) + ['>', self._driver_details.command_line_file(
)]) | 1158 self._android_commands.run(['shell', 'echo'] + self._android_driver_cmd_
line(pixel_tests, |
| 1159
per_test_args) + ['>', self._driver_details.command_line_file()]) |
| 1147 self._created_cmd_line = True | 1160 self._created_cmd_line = True |
| 1148 | 1161 |
| 1149 self._android_commands.run(['shell', 'rm', '-rf', self._driver_details.d
evice_crash_dumps_directory()]) | 1162 self._android_commands.run(['shell', 'rm', '-rf', self._driver_details.d
evice_crash_dumps_directory()]) |
| 1150 self._android_commands.mkdir(self._driver_details.device_crash_dumps_dir
ectory(), chmod='777') | 1163 self._android_commands.mkdir(self._driver_details.device_crash_dumps_dir
ectory(), chmod='777') |
| 1151 | 1164 |
| 1152 start_result = self._android_commands.run(['shell', 'am', 'start', '-e',
'RunInSubThread', '-n', self._driver_details.activity_name()]) | 1165 start_result = self._android_commands.run( |
| 1166 ['shell', 'am', 'start', '-e', 'RunInSubThread', '-n', self._driver_
details.activity_name()]) |
| 1153 if start_result.find('Exception') != -1: | 1167 if start_result.find('Exception') != -1: |
| 1154 self._log_error('Failed to start the content_shell application. Exce
ption:\n' + start_result) | 1168 self._log_error('Failed to start the content_shell application. Exce
ption:\n' + start_result) |
| 1155 return False | 1169 return False |
| 1156 | 1170 |
| 1157 if not ChromiumAndroidDriver._loop_with_timeout(self._all_pipes_created,
DRIVER_START_STOP_TIMEOUT_SECS): | 1171 if not ChromiumAndroidDriver._loop_with_timeout(self._all_pipes_created,
DRIVER_START_STOP_TIMEOUT_SECS): |
| 1158 return False | 1172 return False |
| 1159 | 1173 |
| 1160 # Read back the shell prompt to ensure adb shell ready. | 1174 # Read back the shell prompt to ensure adb shell ready. |
| 1161 deadline = time.time() + DRIVER_START_STOP_TIMEOUT_SECS | 1175 deadline = time.time() + DRIVER_START_STOP_TIMEOUT_SECS |
| 1162 self._server_process.start() | 1176 self._server_process.start() |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1287 return command | 1301 return command |
| 1288 | 1302 |
| 1289 def _read_prompt(self, deadline): | 1303 def _read_prompt(self, deadline): |
| 1290 last_char = '' | 1304 last_char = '' |
| 1291 while True: | 1305 while True: |
| 1292 current_char = self._server_process.read_stdout(deadline, 1) | 1306 current_char = self._server_process.read_stdout(deadline, 1) |
| 1293 if current_char == ' ': | 1307 if current_char == ' ': |
| 1294 if last_char in ('#', '$'): | 1308 if last_char in ('#', '$'): |
| 1295 return | 1309 return |
| 1296 last_char = current_char | 1310 last_char = current_char |
| OLD | NEW |