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 |