Chromium Code Reviews| 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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 114 [[MS_TRUETYPE_FONTS_DIR], 'Verdana_Italic.ttf', MS_TRUETYPE_FONTS_PACKAGE], | 114 [[MS_TRUETYPE_FONTS_DIR], 'Verdana_Italic.ttf', MS_TRUETYPE_FONTS_PACKAGE], |
| 115 # The Microsoft font EULA | 115 # The Microsoft font EULA |
| 116 [['/usr/share/doc/ttf-mscorefonts-installer/'], 'READ_ME!.gz', MS_TRUETYPE_F ONTS_PACKAGE], | 116 [['/usr/share/doc/ttf-mscorefonts-installer/'], 'READ_ME!.gz', MS_TRUETYPE_F ONTS_PACKAGE], |
| 117 # Other fonts: Arabic, CJK, Indic, Thai, etc. | 117 # Other fonts: Arabic, CJK, Indic, Thai, etc. |
| 118 [['/usr/share/fonts/truetype/ttf-dejavu/'], 'DejaVuSans.ttf', 'ttf-dejavu'], | 118 [['/usr/share/fonts/truetype/ttf-dejavu/'], 'DejaVuSans.ttf', 'ttf-dejavu'], |
| 119 [['/usr/share/fonts/truetype/kochi/'], 'kochi-mincho.ttf', 'ttf-kochi-mincho '], | 119 [['/usr/share/fonts/truetype/kochi/'], 'kochi-mincho.ttf', 'ttf-kochi-mincho '], |
| 120 [['/usr/share/fonts/truetype/ttf-indic-fonts-core/'], 'lohit_hi.ttf', 'ttf-i ndic-fonts-core'], | 120 [['/usr/share/fonts/truetype/ttf-indic-fonts-core/'], 'lohit_hi.ttf', 'ttf-i ndic-fonts-core'], |
| 121 [['/usr/share/fonts/truetype/ttf-indic-fonts-core/'], 'lohit_ta.ttf', 'ttf-i ndic-fonts-core'], | 121 [['/usr/share/fonts/truetype/ttf-indic-fonts-core/'], 'lohit_ta.ttf', 'ttf-i ndic-fonts-core'], |
| 122 [['/usr/share/fonts/truetype/ttf-indic-fonts-core/'], 'MuktiNarrow.ttf', 'tt f-indic-fonts-core'], | 122 [['/usr/share/fonts/truetype/ttf-indic-fonts-core/'], 'MuktiNarrow.ttf', 'tt f-indic-fonts-core'], |
| 123 [['/usr/share/fonts/truetype/thai/', '/usr/share/fonts/truetype/tlwg/'], 'Ga ruda.ttf', 'fonts-tlwg-garuda'], | 123 [['/usr/share/fonts/truetype/thai/', '/usr/share/fonts/truetype/tlwg/'], 'Ga ruda.ttf', 'fonts-tlwg-garuda'], |
| 124 [['/usr/share/fonts/truetype/ttf-indic-fonts-core/', '/usr/share/fonts/truet ype/ttf-punjabi-fonts/'], 'lohit_pa.ttf', 'ttf-indic-fonts-core'], | 124 [['/usr/share/fonts/truetype/ttf-indic-fonts-core/', '/usr/share/fonts/truet ype/ttf-punjabi-fonts/'], 'lohit_pa.ttf', |
| 125 'ttf-indic-fonts-core'], | |
| 125 ] | 126 ] |
| 126 | 127 |
| 127 # Test resources that need to be accessed as files directly. | 128 # Test resources that need to be accessed as files directly. |
| 128 # Each item can be the relative path of a directory or a file. | 129 # Each item can be the relative path of a directory or a file. |
| 129 TEST_RESOURCES_TO_PUSH = [ | 130 TEST_RESOURCES_TO_PUSH = [ |
| 130 # Blob tests need to access files directly. | 131 # Blob tests need to access files directly. |
| 131 'editing/pasteboard/resources', | 132 'editing/pasteboard/resources', |
| 132 'fast/files/resources', | 133 'fast/files/resources', |
| 133 'http/tests/local/resources', | 134 'http/tests/local/resources', |
| 134 'http/tests/local/formdata/resources', | 135 'http/tests/local/formdata/resources', |
| (...skipping 112 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, | |
| 260 debug_logging=self._debug_logging) | |
| 258 | 261 |
| 259 # We limit the length to avoid outputting too verbose commands, such as "adb logcat". | 262 # We limit the length to avoid outputting too verbose commands, such as "adb logcat". |
| 260 self._log_debug('Run adb result: ' + result[:80]) | 263 self._log_debug('Run adb result: ' + result[:80]) |
| 261 return result | 264 return result |
| 262 | 265 |
| 263 def get_serial(self): | 266 def get_serial(self): |
| 264 return self._device_serial | 267 return self._device_serial |
| 265 | 268 |
| 266 def adb_command(self): | 269 def adb_command(self): |
| 267 return [AndroidCommands.adb_command_path(self._executive, self._debug_lo gging), '-s', self._device_serial] | 270 return [AndroidCommands.adb_command_path(self._executive, self._debug_lo gging), '-s', self._device_serial] |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 303 _log.info('[%s] %s' % (self._device_serial, message)) | 306 _log.info('[%s] %s' % (self._device_serial, message)) |
| 304 | 307 |
| 305 def _log_debug(self, message): | 308 def _log_debug(self, message): |
| 306 if self._debug_logging: | 309 if self._debug_logging: |
| 307 _log.debug('[%s] %s' % (self._device_serial, message)) | 310 _log.debug('[%s] %s' % (self._device_serial, message)) |
| 308 | 311 |
| 309 @staticmethod | 312 @staticmethod |
| 310 def _determine_adb_version(adb_command_path, executive, debug_logging): | 313 def _determine_adb_version(adb_command_path, executive, debug_logging): |
| 311 re_version = re.compile('^.*version ([\d\.]+)') | 314 re_version = re.compile('^.*version ([\d\.]+)') |
| 312 try: | 315 try: |
| 313 output = executive.run_command([adb_command_path, 'version'], error_ handler=executive.ignore_error, | 316 output = executive.run_command([adb_command_path, 'version'], |
| 317 error_handler=executive.ignore_error, | |
| 314 debug_logging=debug_logging) | 318 debug_logging=debug_logging) |
| 315 except OSError: | 319 except OSError: |
| 316 return None | 320 return None |
| 317 | 321 |
| 318 result = re_version.match(output) | 322 result = re_version.match(output) |
| 319 if not output or not result: | 323 if not output or not result: |
| 320 return None | 324 return None |
| 321 | 325 |
| 322 return [int(n) for n in result.group(1).split('.')] | 326 return [int(n) for n in result.group(1).split('.')] |
| 323 | 327 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 344 | 348 |
| 345 if self._default_device: | 349 if self._default_device: |
| 346 self._usable_devices = [AndroidCommands(executive, self._default_dev ice, self._debug_logging)] | 350 self._usable_devices = [AndroidCommands(executive, self._default_dev ice, self._debug_logging)] |
| 347 return self._usable_devices | 351 return self._usable_devices |
| 348 | 352 |
| 349 # Example "adb devices" command output: | 353 # Example "adb devices" command output: |
| 350 # List of devices attached | 354 # List of devices attached |
| 351 # 0123456789ABCDEF device | 355 # 0123456789ABCDEF device |
| 352 re_device = re.compile('^([a-zA-Z0-9_:.-]+)\tdevice$', re.MULTILINE) | 356 re_device = re.compile('^([a-zA-Z0-9_:.-]+)\tdevice$', re.MULTILINE) |
| 353 | 357 |
| 354 result = executive.run_command([AndroidCommands.adb_command_path(executi ve, debug_logging=self._debug_logging), 'devices'], | 358 result = executive.run_command( |
| 355 error_handler=executive.ignore_error, deb ug_logging=self._debug_logging) | 359 [AndroidCommands.adb_command_path(executive, |
| 360 debug_logging=self._debug_logging) , 'devices'], | |
| 361 error_handler=executive.ignore_error, | |
| 362 debug_logging=self._debug_logging) | |
| 356 devices = re_device.findall(result) | 363 devices = re_device.findall(result) |
| 357 if not devices: | 364 if not devices: |
| 358 return [] | 365 return [] |
| 359 | 366 |
| 360 for device_serial in sorted(devices): | 367 for device_serial in sorted(devices): |
| 361 commands = AndroidCommands(executive, device_serial, self._debug_log ging) | 368 commands = AndroidCommands(executive, device_serial, self._debug_log ging) |
| 362 if self._battery_level_for_device(commands) < AndroidDevices.MINIMUM _BATTERY_PERCENTAGE: | 369 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.' | 370 _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)) | 371 (commands.get_serial(), AndroidDevices.MINIMUM_BATT ERY_PERCENTAGE)) |
| 365 continue | 372 continue |
| 366 | 373 |
| 367 if not self._is_device_screen_on(commands): | 374 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()) | 375 _log.warning('Device with serial "%s" skipped because the screen must be on.' % commands.get_serial()) |
| 369 continue | 376 continue |
| 370 | 377 |
| 371 self._usable_devices.append(commands) | 378 self._usable_devices.append(commands) |
| 372 | 379 |
| 373 return self._usable_devices | 380 return self._usable_devices |
| 374 | 381 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 433 | 440 |
| 434 # Initialize the AndroidDevices class which tracks available devices. | 441 # Initialize the AndroidDevices class which tracks available devices. |
| 435 default_device = None | 442 default_device = None |
| 436 if hasattr(self._options, 'adb_device') and len(self._options.adb_device ): | 443 if hasattr(self._options, 'adb_device') and len(self._options.adb_device ): |
| 437 default_device = self._options.adb_device | 444 default_device = self._options.adb_device |
| 438 | 445 |
| 439 self._debug_logging = self.get_option('android_logging') | 446 self._debug_logging = self.get_option('android_logging') |
| 440 self._devices = AndroidDevices(self._executive, default_device, self._de bug_logging) | 447 self._devices = AndroidDevices(self._executive, default_device, self._de bug_logging) |
| 441 | 448 |
| 442 # Tell AndroidCommands where to search for the "adb" command. | 449 # Tell AndroidCommands where to search for the "adb" command. |
| 443 AndroidCommands.set_adb_command_path_options(['adb', | 450 AndroidCommands.set_adb_command_path_options(['adb', self.path_from_chro mium_base('third_party', 'android_tools', 'sdk', |
| 444 self.path_from_chromium_base('third_party', 'android_tools', 'sdk', 'platform-tools', 'adb')]) | 451 'platform-tools', 'adb')]) |
| 445 | 452 |
| 446 prepared_devices = self.get_option('prepared_devices', []) | 453 prepared_devices = self.get_option('prepared_devices', []) |
| 447 for serial in prepared_devices: | 454 for serial in prepared_devices: |
| 448 self._devices.set_device_prepared(serial) | 455 self._devices.set_device_prepared(serial) |
| 449 | 456 |
| 450 def default_smoke_test_only(self): | 457 def default_smoke_test_only(self): |
| 451 return True | 458 return True |
| 452 | 459 |
| 453 # Local public methods. | 460 # Local public methods. |
| 454 def path_to_forwarder(self): | 461 def path_to_forwarder(self): |
| 455 return self._build_path('forwarder') | 462 return self._build_path('forwarder') |
| 456 | 463 |
| 457 def path_to_md5sum(self): | 464 def path_to_md5sum(self): |
| 458 return self._build_path(MD5SUM_DEVICE_FILE_NAME) | 465 return self._build_path(MD5SUM_DEVICE_FILE_NAME) |
| 459 | 466 |
| 460 def path_to_md5sum_host(self): | 467 def path_to_md5sum_host(self): |
| 461 return self._build_path(MD5SUM_HOST_FILE_NAME) | 468 return self._build_path(MD5SUM_HOST_FILE_NAME) |
| 462 | 469 |
| 463 def additional_driver_flag(self): | 470 def additional_driver_flag(self): |
| 464 return super(AndroidPort, self).additional_driver_flag() + self._driver_ details.additional_command_line_flags(use_breakpad=not self.get_option('disable_ breakpad')) | 471 return super(AndroidPort, self).additional_driver_flag() + self._driver_ details.additional_command_line_flags( |
| 472 use_breakpad=not self.get_option('disable_breakpad')) | |
| 465 | 473 |
| 466 def default_timeout_ms(self): | 474 def default_timeout_ms(self): |
| 467 # Android platform has less computing power than desktop platforms. | 475 # Android platform has less computing power than desktop platforms. |
| 468 # Using 10 seconds allows us to pass most slow tests which are not | 476 # Using 10 seconds allows us to pass most slow tests which are not |
| 469 # marked as slow tests on desktop platforms. | 477 # marked as slow tests on desktop platforms. |
| 470 return 10 * 1000 | 478 return 10 * 1000 |
| 471 | 479 |
| 472 def driver_stop_timeout(self): | 480 def driver_stop_timeout(self): |
| 473 # The driver doesn't respond to closing stdin, so we might as well stop the driver immediately. | 481 # The driver doesn't respond to closing stdin, so we might as well stop the driver immediately. |
| 474 return 0.0 | 482 return 0.0 |
| 475 | 483 |
| 476 def default_child_processes(self): | 484 def default_child_processes(self): |
| 477 usable_devices = self._devices.usable_devices(self._executive) | 485 usable_devices = self._devices.usable_devices(self._executive) |
| 478 if not usable_devices: | 486 if not usable_devices: |
| 479 raise test_run_results.TestRunException(test_run_results.NO_DEVICES_ EXIT_STATUS, "Unable to find any attached Android devices.") | 487 raise test_run_results.TestRunException(test_run_results.NO_DEVICES_ EXIT_STATUS, |
| 488 "Unable to find any attached Android devices.") | |
| 480 return len(usable_devices) | 489 return len(usable_devices) |
| 481 | 490 |
| 482 def max_drivers_per_process(self): | 491 def max_drivers_per_process(self): |
| 483 # Android falls over when we try to run multiple content_shells per work er. | 492 # Android falls over when we try to run multiple content_shells per work er. |
| 484 # See https://codereview.chromium.org/1158323009/ | 493 # See https://codereview.chromium.org/1158323009/ |
| 485 return 1 | 494 return 1 |
| 486 | 495 |
| 487 def check_wdiff(self, logging=True): | 496 def check_wdiff(self, logging=True): |
| 488 return self._host_port.check_wdiff(logging) | 497 return self._host_port.check_wdiff(logging) |
| 489 | 498 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 592 | 601 |
| 593 def check_sys_deps(self, needs_http): | 602 def check_sys_deps(self, needs_http): |
| 594 for (font_dirs, font_file, package) in HOST_FONT_FILES: | 603 for (font_dirs, font_file, package) in HOST_FONT_FILES: |
| 595 exists = False | 604 exists = False |
| 596 for font_dir in font_dirs: | 605 for font_dir in font_dirs: |
| 597 font_path = font_dir + font_file | 606 font_path = font_dir + font_file |
| 598 if self._check_file_exists(font_path, '', logging=False): | 607 if self._check_file_exists(font_path, '', logging=False): |
| 599 exists = True | 608 exists = True |
| 600 break | 609 break |
| 601 if not exists: | 610 if not exists: |
| 602 _log.error('You are missing %s under %s. Try installing %s. See build instructions.' % (font_file, font_dirs, package)) | 611 _log.error('You are missing %s under %s. Try installing %s. See build instructions.' % |
| 612 (font_file, font_dirs, package)) | |
| 603 return test_run_results.SYS_DEPS_EXIT_STATUS | 613 return test_run_results.SYS_DEPS_EXIT_STATUS |
| 604 return test_run_results.OK_EXIT_STATUS | 614 return test_run_results.OK_EXIT_STATUS |
| 605 | 615 |
| 606 def requires_http_server(self): | 616 def requires_http_server(self): |
| 607 """Chromium Android runs tests on devices, and uses the HTTP server to | 617 """Chromium Android runs tests on devices, and uses the HTTP server to |
| 608 serve the actual layout tests to the test driver.""" | 618 serve the actual layout tests to the test driver.""" |
| 609 return True | 619 return True |
| 610 | 620 |
| 611 def start_http_server(self, additional_dirs, number_of_drivers): | 621 def start_http_server(self, additional_dirs, number_of_drivers): |
| 612 additional_dirs[PERF_TEST_PATH_PREFIX] = self.perf_tests_dir() | 622 additional_dirs[PERF_TEST_PATH_PREFIX] = self.perf_tests_dir() |
| 613 additional_dirs[LAYOUT_TEST_PATH_PREFIX] = self.layout_tests_dir() | 623 additional_dirs[LAYOUT_TEST_PATH_PREFIX] = self.layout_tests_dir() |
| 614 super(AndroidPort, self).start_http_server(additional_dirs, number_of_dr ivers) | 624 super(AndroidPort, self).start_http_server(additional_dirs, number_of_dr ivers) |
| 615 | 625 |
| 616 def create_driver(self, worker_number, no_timeout=False): | 626 def create_driver(self, worker_number, no_timeout=False): |
| 617 return ChromiumAndroidDriver(self, worker_number, pixel_tests=self.get_o ption('pixel_tests'), | 627 return ChromiumAndroidDriver(self, |
| 628 worker_number, | |
| 629 pixel_tests=self.get_option('pixel_tests'), | |
| 618 driver_details=self._driver_details, | 630 driver_details=self._driver_details, |
| 619 android_devices=self._devices, | 631 android_devices=self._devices, |
| 620 # Force no timeout to avoid test driver tim eouts before NRWT. | 632 # Force no timeout to avoid test driver tim eouts before NRWT. |
| 621 no_timeout=True) | 633 no_timeout=True) |
| 622 | 634 |
| 623 def driver_cmd_line(self): | 635 def driver_cmd_line(self): |
| 624 # Override to return the actual test driver's command line. | 636 # Override to return the actual test driver's command line. |
| 625 return self.create_driver(0)._android_driver_cmd_line(self.get_option('p ixel_tests'), []) | 637 return self.create_driver(0)._android_driver_cmd_line(self.get_option('p ixel_tests'), []) |
| 626 | 638 |
| 627 def clobber_old_port_specific_results(self): | 639 def clobber_old_port_specific_results(self): |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 663 # Local private methods. | 675 # Local private methods. |
| 664 | 676 |
| 665 @staticmethod | 677 @staticmethod |
| 666 def _android_server_process_constructor(port, server_name, cmd_line, env=Non e, logging=False): | 678 def _android_server_process_constructor(port, server_name, cmd_line, env=Non e, logging=False): |
| 667 # We need universal_newlines=True, because 'adb shell' for some unknown reason | 679 # We need universal_newlines=True, because 'adb shell' for some unknown reason |
| 668 # does newline conversion of unix-style LF into win-style CRLF (and we n eed | 680 # does newline conversion of unix-style LF into win-style CRLF (and we n eed |
| 669 # to convert that back). This can cause headaches elsewhere because | 681 # to convert that back). This can cause headaches elsewhere because |
| 670 # server_process' stdout and stderr are now unicode file-like objects, | 682 # server_process' stdout and stderr are now unicode file-like objects, |
| 671 # not binary file-like objects like all of the other ports are. | 683 # not binary file-like objects like all of the other ports are. |
| 672 # FIXME: crbug.com/496983. | 684 # FIXME: crbug.com/496983. |
| 673 return server_process.ServerProcess(port, server_name, cmd_line, env, | 685 return server_process.ServerProcess(port, |
| 674 universal_newlines=True, treat_no_da ta_as_crash=True, logging=logging) | 686 server_name, |
| 687 cmd_line, | |
| 688 env, | |
| 689 universal_newlines=True, | |
| 690 treat_no_data_as_crash=True, | |
| 691 logging=logging) | |
| 675 | 692 |
| 676 | 693 |
| 677 class AndroidPerf(SingleFileOutputProfiler): | 694 class AndroidPerf(SingleFileOutputProfiler): |
| 678 _cached_perf_host_path = None | 695 _cached_perf_host_path = None |
| 679 _have_searched_for_perf_host = False | 696 _have_searched_for_perf_host = False |
| 680 | 697 |
| 681 def __init__(self, host, executable_path, output_dir, android_commands, symf s_path, kallsyms_path, identifier=None): | 698 def __init__(self, host, executable_path, output_dir, android_commands, symf s_path, kallsyms_path, identifier=None): |
| 682 super(AndroidPerf, self).__init__(host, executable_path, output_dir, "da ta", identifier) | 699 super(AndroidPerf, self).__init__(host, executable_path, output_dir, "da ta", identifier) |
| 683 self._android_commands = android_commands | 700 self._android_commands = android_commands |
| 684 self._perf_process = None | 701 self._perf_process = None |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 714 The test driver must be built with profiling=1, make sure you've done: | 731 The test driver must be built with profiling=1, make sure you've done: |
| 715 export GYP_DEFINES="profiling=1 $GYP_DEFINES" | 732 export GYP_DEFINES="profiling=1 $GYP_DEFINES" |
| 716 update-webkit --chromium-android | 733 update-webkit --chromium-android |
| 717 build-webkit --chromium-android | 734 build-webkit --chromium-android |
| 718 | 735 |
| 719 Googlers should read: | 736 Googlers should read: |
| 720 http://goto.google.com/cr-android-perf-howto | 737 http://goto.google.com/cr-android-perf-howto |
| 721 """) | 738 """) |
| 722 | 739 |
| 723 def attach_to_pid(self, pid): | 740 def attach_to_pid(self, pid): |
| 724 assert(pid) | 741 assert (pid) |
| 725 assert(self._perf_process == None) | 742 assert (self._perf_process is None) |
|
qyearsley
2016/03/18 00:33:39
== None -> is None was a manual change done in ord
| |
| 726 # FIXME: This can't be a fixed timeout! | 743 # FIXME: This can't be a fixed timeout! |
| 727 cmd = self._android_commands.adb_command() + ['shell', 'perf', 'record', '-g', '-p', pid, 'sleep', 30] | 744 cmd = self._android_commands.adb_command() + ['shell', 'perf', 'record', '-g', '-p', pid, 'sleep', 30] |
| 728 self._perf_process = self._host.executive.popen(cmd) | 745 self._perf_process = self._host.executive.popen(cmd) |
| 729 | 746 |
| 730 def _perf_version_string(self, perf_path): | 747 def _perf_version_string(self, perf_path): |
| 731 try: | 748 try: |
| 732 return self._host.executive.run_command([perf_path, '--version']) | 749 return self._host.executive.run_command([perf_path, '--version']) |
| 733 except: | 750 except: |
| 734 return None | 751 return None |
| 735 | 752 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 757 perf_exitcode = self._perf_process.wait() | 774 perf_exitcode = self._perf_process.wait() |
| 758 if perf_exitcode != 0: | 775 if perf_exitcode != 0: |
| 759 _log.debug("Perf failed (exit code: %i), can't process results." % p erf_exitcode) | 776 _log.debug("Perf failed (exit code: %i), can't process results." % p erf_exitcode) |
| 760 return | 777 return |
| 761 | 778 |
| 762 self._android_commands.pull('/data/perf.data', self._output_path) | 779 self._android_commands.pull('/data/perf.data', self._output_path) |
| 763 | 780 |
| 764 perfhost_path = self._perfhost_path() | 781 perfhost_path = self._perfhost_path() |
| 765 perfhost_report_command = [ | 782 perfhost_report_command = [ |
| 766 'report', | 783 'report', |
| 767 '--input', self._output_path, | 784 '--input', |
| 768 '--symfs', self._symfs_path, | 785 self._output_path, |
| 769 '--kallsyms', self._kallsyms_path, | 786 '--symfs', |
| 787 self._symfs_path, | |
| 788 '--kallsyms', | |
| 789 self._kallsyms_path, | |
| 770 ] | 790 ] |
| 771 if perfhost_path: | 791 if perfhost_path: |
| 772 perfhost_args = [perfhost_path] + perfhost_report_command + ['--call -graph', 'none'] | 792 perfhost_args = [perfhost_path] + perfhost_report_command + ['--call -graph', 'none'] |
| 773 perf_output = self._host.executive.run_command(perfhost_args) | 793 perf_output = self._host.executive.run_command(perfhost_args) |
| 774 # We could save off the full -g report to a file if users found that useful. | 794 # We could save off the full -g report to a file if users found that useful. |
| 775 _log.debug(self._first_ten_lines_of_profile(perf_output)) | 795 _log.debug(self._first_ten_lines_of_profile(perf_output)) |
| 776 else: | 796 else: |
| 777 _log.debug(""" | 797 _log.debug(""" |
| 778 Failed to find perfhost_linux binary, can't process samples from the device. | 798 Failed to find perfhost_linux binary, can't process samples from the device. |
| 779 | 799 |
| 780 perfhost_linux can be built from: | 800 perfhost_linux can be built from: |
| 781 https://android.googlesource.com/platform/external/linux-tools-perf/ | 801 https://android.googlesource.com/platform/external/linux-tools-perf/ |
| 782 also, modern versions of perf (available from apt-get install goobuntu-kernel-to ols-common) | 802 also, modern versions of perf (available from apt-get install goobuntu-kernel-to ols-common) |
| 783 may also be able to process the perf.data files from the device. | 803 may also be able to process the perf.data files from the device. |
| 784 | 804 |
| 785 Googlers should read: | 805 Googlers should read: |
| 786 http://goto.google.com/cr-android-perf-howto | 806 http://goto.google.com/cr-android-perf-howto |
| 787 for instructions on installing pre-built copies of perfhost_linux | 807 for instructions on installing pre-built copies of perfhost_linux |
| 788 http://crbug.com/165250 discusses making these pre-built binaries externally ava ilable. | 808 http://crbug.com/165250 discusses making these pre-built binaries externally ava ilable. |
| 789 """) | 809 """) |
| 790 | 810 |
| 791 perfhost_display_patch = perfhost_path if perfhost_path else 'perfhost_l inux' | 811 perfhost_display_patch = perfhost_path if perfhost_path else 'perfhost_l inux' |
| 792 _log.debug("To view the full profile, run:") | 812 _log.debug("To view the full profile, run:") |
| 793 _log.debug(' '.join([perfhost_display_patch] + perfhost_report_command)) | 813 _log.debug(' '.join([perfhost_display_patch] + perfhost_report_command)) |
| 794 | 814 |
| 795 | 815 |
| 796 class ChromiumAndroidDriver(driver.Driver): | 816 class ChromiumAndroidDriver(driver.Driver): |
| 797 | |
| 798 def __init__(self, port, worker_number, pixel_tests, driver_details, android _devices, no_timeout=False): | 817 def __init__(self, port, worker_number, pixel_tests, driver_details, android _devices, no_timeout=False): |
| 799 super(ChromiumAndroidDriver, self).__init__(port, worker_number, pixel_t ests, no_timeout) | 818 super(ChromiumAndroidDriver, self).__init__(port, worker_number, pixel_t ests, no_timeout) |
| 800 self._in_fifo_path = driver_details.device_fifo_directory() + 'stdin.fif o' | 819 self._in_fifo_path = driver_details.device_fifo_directory() + 'stdin.fif o' |
| 801 self._out_fifo_path = driver_details.device_fifo_directory() + 'test.fif o' | 820 self._out_fifo_path = driver_details.device_fifo_directory() + 'test.fif o' |
| 802 self._err_fifo_path = driver_details.device_fifo_directory() + 'stderr.f ifo' | 821 self._err_fifo_path = driver_details.device_fifo_directory() + 'stderr.f ifo' |
| 803 self._read_stdout_process = None | 822 self._read_stdout_process = None |
| 804 self._read_stderr_process = None | 823 self._read_stderr_process = None |
| 805 self._forwarder_process = None | 824 self._forwarder_process = None |
| 806 self._original_governors = {} | 825 self._original_governors = {} |
| 807 self._original_kptr_restrict = None | 826 self._original_kptr_restrict = None |
| 808 | 827 |
| 809 self._android_devices = android_devices | 828 self._android_devices = android_devices |
| 810 self._android_commands = android_devices.get_device(port._executive, wor ker_number) | 829 self._android_commands = android_devices.get_device(port._executive, wor ker_number) |
| 811 self._driver_details = driver_details | 830 self._driver_details = driver_details |
| 812 self._debug_logging = self._port._debug_logging | 831 self._debug_logging = self._port._debug_logging |
| 813 self._created_cmd_line = False | 832 self._created_cmd_line = False |
| 814 self._device_failed = False | 833 self._device_failed = False |
| 815 | 834 |
| 816 # FIXME: If we taught ProfileFactory about "target" devices we could | 835 # FIXME: If we taught ProfileFactory about "target" devices we could |
| 817 # just use the logic in Driver instead of duplicating it here. | 836 # just use the logic in Driver instead of duplicating it here. |
| 818 if self._port.get_option("profile"): | 837 if self._port.get_option("profile"): |
| 819 # FIXME: This should be done once, instead of per-driver! | 838 # FIXME: This should be done once, instead of per-driver! |
| 820 symfs_path = self._find_or_create_symfs() | 839 symfs_path = self._find_or_create_symfs() |
| 821 kallsyms_path = self._update_kallsyms_cache(symfs_path) | 840 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. | 841 # 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(), | 842 self._profiler = AndroidPerf(self._port.host, self._port._path_to_dr iver(), self._port.results_directory(), |
| 824 self._android_commands, symfs_path, kallsyms_path) | 843 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 | 844 # 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 | 845 # once we have an abstraction around an adb_path/device_serial pair to make it |
| 827 # easy to make these class methods on AndroidPerf. | 846 # easy to make these class methods on AndroidPerf. |
| 828 if not self._profiler.check_configuration(): | 847 if not self._profiler.check_configuration(): |
| 829 self._profiler.print_setup_instructions() | 848 self._profiler.print_setup_instructions() |
| 830 sys.exit(1) | 849 sys.exit(1) |
| 831 else: | 850 else: |
| 832 self._profiler = None | 851 self._profiler = None |
| 833 | 852 |
| 834 def __del__(self): | 853 def __del__(self): |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 858 fs = self._port.host.filesystem | 877 fs = self._port.host.filesystem |
| 859 | 878 |
| 860 if 'ANDROID_SYMFS' in env: | 879 if 'ANDROID_SYMFS' in env: |
| 861 symfs_path = env['ANDROID_SYMFS'] | 880 symfs_path = env['ANDROID_SYMFS'] |
| 862 else: | 881 else: |
| 863 symfs_path = fs.join(self._port.results_directory(), 'symfs') | 882 symfs_path = fs.join(self._port.results_directory(), 'symfs') |
| 864 _log.debug("ANDROID_SYMFS not set, using %s" % symfs_path) | 883 _log.debug("ANDROID_SYMFS not set, using %s" % symfs_path) |
| 865 | 884 |
| 866 # find the installed path, and the path of the symboled built library | 885 # find the installed path, and the path of the symboled built library |
| 867 # FIXME: We should get the install path from the device! | 886 # 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())) | 887 symfs_library_path = fs.join(symfs_path, "data/app-lib/%s-1/%s" % |
| 888 (self._driver_details.package_name(), self. _driver_details.library_name())) | |
| 869 built_library_path = self._port._build_path('lib', self._driver_details. library_name()) | 889 built_library_path = self._port._build_path('lib', self._driver_details. library_name()) |
| 870 assert(fs.exists(built_library_path)) | 890 assert (fs.exists(built_library_path)) |
| 871 | 891 |
| 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). | 892 # FIXME: Ideally we'd check the sha1's first and make a soft-link instea d |
| 893 # 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)) | 894 _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)) | 895 fs.maybe_make_directory(fs.dirname(symfs_library_path)) |
| 875 fs.copyfile(built_library_path, symfs_library_path) | 896 fs.copyfile(built_library_path, symfs_library_path) |
| 876 | 897 |
| 877 return symfs_path | 898 return symfs_path |
| 878 | 899 |
| 879 def _setup_md5sum_and_push_data_if_needed(self, log_callback): | 900 def _setup_md5sum_and_push_data_if_needed(self, log_callback): |
| 880 self._md5sum_path = self._port.path_to_md5sum() | 901 self._md5sum_path = self._port.path_to_md5sum() |
| 881 if not self._android_commands.file_exists(MD5SUM_DEVICE_PATH): | 902 if not self._android_commands.file_exists(MD5SUM_DEVICE_PATH): |
| 882 if not self._android_commands.push(self._md5sum_path, MD5SUM_DEVICE_ PATH): | 903 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)) | 950 raise driver.DeviceFailure('[%s] %s' % (self._android_commands.get_seria l(), message)) |
| 930 | 951 |
| 931 @staticmethod | 952 @staticmethod |
| 932 def _extract_hashes_from_md5sum_output(md5sum_output): | 953 def _extract_hashes_from_md5sum_output(md5sum_output): |
| 933 assert md5sum_output | 954 assert md5sum_output |
| 934 return [line.split(' ')[0] for line in md5sum_output] | 955 return [line.split(' ')[0] for line in md5sum_output] |
| 935 | 956 |
| 936 def _files_match(self, host_file, device_file): | 957 def _files_match(self, host_file, device_file): |
| 937 assert self._port.host.filesystem.exists(host_file) | 958 assert self._port.host.filesystem.exists(host_file) |
| 938 device_hashes = self._extract_hashes_from_md5sum_output( | 959 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], | 960 self._port.host.executive.popen( |
| 940 stdout=subprocess.PIPE).stdout) | 961 self._android_commands.adb_command() + ['shell', MD5SUM_DEVICE_P ATH, device_file], |
| 962 stdout=subprocess.PIPE).stdout) | |
| 941 host_hashes = self._extract_hashes_from_md5sum_output( | 963 host_hashes = self._extract_hashes_from_md5sum_output( |
| 942 self._port.host.executive.popen(args=['%s_host' % self._md5sum_p ath, host_file], | 964 self._port.host.executive.popen( |
| 943 stdout=subprocess.PIPE).stdout) | 965 args=['%s_host' % self._md5sum_path, host_file], |
| 966 stdout=subprocess.PIPE).stdout) | |
| 944 return host_hashes and device_hashes == host_hashes | 967 return host_hashes and device_hashes == host_hashes |
| 945 | 968 |
| 946 def _push_file_if_needed(self, host_file, device_file, log_callback): | 969 def _push_file_if_needed(self, host_file, device_file, log_callback): |
| 947 basename = self._port.host.filesystem.basename(host_file) | 970 basename = self._port.host.filesystem.basename(host_file) |
| 948 log_callback("checking %s" % basename) | 971 log_callback("checking %s" % basename) |
| 949 if not self._files_match(host_file, device_file): | 972 if not self._files_match(host_file, device_file): |
| 950 log_callback("pushing %s" % basename) | 973 log_callback("pushing %s" % basename) |
| 951 self._android_commands.push(host_file, device_file) | 974 self._android_commands.push(host_file, device_file) |
| 952 | 975 |
| 953 def _push_executable(self, log_callback): | 976 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) | 977 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(): | 978 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) | 979 self._push_file_if_needed( |
| 980 self._port._build_path(resource), self._driver_details.device_di rectory() + resource, log_callback) | |
| 957 | 981 |
| 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) | 982 self._push_file_if_needed( |
| 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) | 983 self._port._build_path('android_main_fonts.xml'), self._driver_detai ls.device_directory() + 'android_main_fonts.xml', |
| 984 log_callback) | |
| 985 self._push_file_if_needed( | |
| 986 self._port._build_path('android_fallback_fonts.xml'), | |
| 987 self._driver_details.device_directory() + 'android_fallback_fonts.xm l', log_callback) | |
| 960 | 988 |
| 961 log_callback("checking apk") | 989 log_callback("checking apk") |
| 962 if self._files_match(self._port._build_path('apks', 'ContentShell.apk'), | 990 if self._files_match(self._port._build_path('apks', 'ContentShell.apk'), '/data/app/org.chromium.content_shell_apk-1.apk'): |
| 963 '/data/app/org.chromium.content_shell_apk-1.apk'): | |
| 964 return | 991 return |
| 965 | 992 |
| 966 log_callback("uninstalling apk") | 993 log_callback("uninstalling apk") |
| 967 self._android_commands.run(['uninstall', self._driver_details.package_na me()]) | 994 self._android_commands.run(['uninstall', self._driver_details.package_na me()]) |
| 968 driver_host_path = self._port._path_to_driver() | 995 driver_host_path = self._port._path_to_driver() |
| 969 log_callback("installing apk") | 996 log_callback("installing apk") |
| 970 install_result = self._android_commands.run(['install', driver_host_path ]) | 997 install_result = self._android_commands.run(['install', driver_host_path ]) |
| 971 if install_result.find('Success') == -1: | 998 if install_result.find('Success') == -1: |
| 972 self._abort('Failed to install %s onto device: %s' % (driver_host_pa th, install_result)) | 999 self._abort('Failed to install %s onto device: %s' % (driver_host_pa th, install_result)) |
| 973 | 1000 |
| 974 def _push_fonts(self, log_callback): | 1001 def _push_fonts(self, log_callback): |
| 975 path_to_ahem_font = self._port._build_path('AHEM____.TTF') | 1002 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) | 1003 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: | 1004 for (host_dirs, font_file, package) in HOST_FONT_FILES: |
| 978 for host_dir in host_dirs: | 1005 for host_dir in host_dirs: |
| 979 host_font_path = host_dir + font_file | 1006 host_font_path = host_dir + font_file |
| 980 if self._port._check_file_exists(host_font_path, '', logging=Fal se): | 1007 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) | 1008 self._push_file_if_needed(host_font_path, self._driver_detai ls.device_fonts_directory() + font_file, |
| 1009 log_callback) | |
| 982 | 1010 |
| 983 def _push_test_resources(self, log_callback): | 1011 def _push_test_resources(self, log_callback): |
| 984 for resource in TEST_RESOURCES_TO_PUSH: | 1012 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) | 1013 self._push_file_if_needed(self._port.layout_tests_dir() + '/' + reso urce, DEVICE_LAYOUT_TESTS_DIR + resource, |
| 1014 log_callback) | |
| 986 | 1015 |
| 987 def _get_last_stacktrace(self): | 1016 def _get_last_stacktrace(self): |
| 988 tombstones = self._android_commands.run(['shell', 'ls', '-n', '/data/tom bstones/tombstone_*']) | 1017 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'): | 1018 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!') | 1019 self._log_error('The driver crashed, but no tombstone found!') |
| 991 return '' | 1020 return '' |
| 992 | 1021 |
| 993 if tombstones.startswith('/data/tombstones/tombstone_*: Permission denie d'): | 1022 if tombstones.startswith('/data/tombstones/tombstone_*: Permission denie d'): |
| 994 # FIXME: crbug.com/321489 ... figure out why this happens. | 1023 # FIXME: crbug.com/321489 ... figure out why this happens. |
| 995 self._log_error('The driver crashed, but we could not read the tombs tones!') | 1024 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: | 1072 if not stdout: |
| 1044 stdout = '' | 1073 stdout = '' |
| 1045 stdout += '********* [%s] Logcat:\n%s' % (self._android_commands.get_ser ial(), self._get_logcat()) | 1074 stdout += '********* [%s] Logcat:\n%s' % (self._android_commands.get_ser ial(), self._get_logcat()) |
| 1046 if not stderr: | 1075 if not stderr: |
| 1047 stderr = '' | 1076 stderr = '' |
| 1048 stderr += '********* [%s] Tombstone file:\n%s' % (self._android_commands .get_serial(), self._get_last_stacktrace()) | 1077 stderr += '********* [%s] Tombstone file:\n%s' % (self._android_commands .get_serial(), self._get_last_stacktrace()) |
| 1049 | 1078 |
| 1050 if not self._port.get_option('disable_breakpad'): | 1079 if not self._port.get_option('disable_breakpad'): |
| 1051 crashes = self._pull_crash_dumps_from_device() | 1080 crashes = self._pull_crash_dumps_from_device() |
| 1052 for crash in crashes: | 1081 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)) | 1082 stderr += '********* [%s] breakpad minidump %s:\n%s' % (self._po rt.host.filesystem.basename(crash), |
| 1083 self._an droid_commands.get_serial(), | |
| 1084 self._po rt._dump_reader._get_stack_from_dump(crash)) | |
| 1054 | 1085 |
| 1055 # The parent method expects stdout and stderr to be byte streams, but | 1086 # The parent method expects stdout and stderr to be byte streams, but |
| 1056 # since adb shell does newline conversion, we used universal_newlines | 1087 # since adb shell does newline conversion, we used universal_newlines |
| 1057 # when launching the processes, and hence our stdout and stderr are | 1088 # when launching the processes, and hence our stdout and stderr are |
| 1058 # text objects that need to be encoded back into bytes. | 1089 # text objects that need to be encoded back into bytes. |
| 1059 return super(ChromiumAndroidDriver, self)._get_crash_log( | 1090 return super(ChromiumAndroidDriver, self)._get_crash_log( |
| 1060 stdout.encode('utf8', 'replace'), | 1091 stdout.encode('utf8', 'replace'), stderr.encode('utf8', 'replace'), newer_than) |
| 1061 stderr.encode('utf8', 'replace'), | |
| 1062 newer_than) | |
| 1063 | 1092 |
| 1064 def cmd_line(self, pixel_tests, per_test_args): | 1093 def cmd_line(self, pixel_tests, per_test_args): |
| 1065 # The returned command line is used to start _server_process. In our cas e, it's an interactive 'adb shell'. | 1094 # The returned command line is used to start _server_process. In our cas e, it's an interactive 'adb shell'. |
| 1066 # The command line passed to the driver process is returned by _driver_c md_line() instead. | 1095 # The command line passed to the driver process is returned by _driver_c md_line() instead. |
| 1067 return self._android_commands.adb_command() + ['shell'] | 1096 return self._android_commands.adb_command() + ['shell'] |
| 1068 | 1097 |
| 1069 def _android_driver_cmd_line(self, pixel_tests, per_test_args): | 1098 def _android_driver_cmd_line(self, pixel_tests, per_test_args): |
| 1070 return driver.Driver.cmd_line(self, pixel_tests, per_test_args) | 1099 return driver.Driver.cmd_line(self, pixel_tests, per_test_args) |
| 1071 | 1100 |
| 1072 @staticmethod | 1101 @staticmethod |
| 1073 def _loop_with_timeout(condition, timeout_secs): | 1102 def _loop_with_timeout(condition, timeout_secs): |
| 1074 deadline = time.time() + timeout_secs | 1103 deadline = time.time() + timeout_secs |
| 1075 while time.time() < deadline: | 1104 while time.time() < deadline: |
| 1076 if condition(): | 1105 if condition(): |
| 1077 return True | 1106 return True |
| 1078 return False | 1107 return False |
| 1079 | 1108 |
| 1080 def _all_pipes_created(self): | 1109 def _all_pipes_created(self): |
| 1081 return (self._android_commands.file_exists(self._in_fifo_path) and | 1110 return (self._android_commands.file_exists(self._in_fifo_path) and |
| 1082 self._android_commands.file_exists(self._out_fifo_path) and | 1111 self._android_commands.file_exists(self._out_fifo_path) and self ._android_commands.file_exists(self._err_fifo_path)) |
| 1083 self._android_commands.file_exists(self._err_fifo_path)) | |
| 1084 | 1112 |
| 1085 def _remove_all_pipes(self): | 1113 def _remove_all_pipes(self): |
| 1086 for file in [self._in_fifo_path, self._out_fifo_path, self._err_fifo_pat h]: | 1114 for file in [self._in_fifo_path, self._out_fifo_path, self._err_fifo_pat h]: |
| 1087 self._android_commands.run(['shell', 'rm', file]) | 1115 self._android_commands.run(['shell', 'rm', file]) |
| 1088 | 1116 |
| 1089 return (not self._android_commands.file_exists(self._in_fifo_path) and | 1117 return (not self._android_commands.file_exists(self._in_fifo_path) and |
| 1090 not self._android_commands.file_exists(self._out_fifo_path) and | 1118 not self._android_commands.file_exists(self._out_fifo_path) and |
| 1091 not self._android_commands.file_exists(self._err_fifo_path)) | 1119 not self._android_commands.file_exists(self._err_fifo_path)) |
| 1092 | 1120 |
| 1093 def start(self, pixel_tests, per_test_args, deadline): | 1121 def start(self, pixel_tests, per_test_args, deadline): |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1119 self._log_error('Failed to start the content_shell application. Retr ies=%d. Log:%s' % (retries, self._get_logcat())) | 1147 self._log_error('Failed to start the content_shell application. Retr ies=%d. Log:%s' % (retries, self._get_logcat())) |
| 1120 self.stop() | 1148 self.stop() |
| 1121 time.sleep(2) | 1149 time.sleep(2) |
| 1122 self._abort('Failed to start the content_shell application multiple time s. Giving up.') | 1150 self._abort('Failed to start the content_shell application multiple time s. Giving up.') |
| 1123 | 1151 |
| 1124 def _start_once(self, pixel_tests, per_test_args): | 1152 def _start_once(self, pixel_tests, per_test_args): |
| 1125 super(ChromiumAndroidDriver, self)._start(pixel_tests, per_test_args, wa it_for_ready=False) | 1153 super(ChromiumAndroidDriver, self)._start(pixel_tests, per_test_args, wa it_for_ready=False) |
| 1126 | 1154 |
| 1127 self._log_debug('Starting forwarder') | 1155 self._log_debug('Starting forwarder') |
| 1128 self._forwarder_process = self._port._server_process_constructor( | 1156 self._forwarder_process = self._port._server_process_constructor( |
| 1129 self._port, 'Forwarder', self._android_commands.adb_command() + ['sh ell', '%s -no-spawn-daemon %s' % (self._driver_details.device_forwarder_path(), FORWARD_PORTS)]) | 1157 self._port, 'Forwarder', |
| 1158 self._android_commands.adb_command() + ['shell', '%s -no-spawn-daemo n %s' % | |
| 1159 (self._driver_details.device _forwarder_path(), FORWARD_PORTS)]) | |
| 1130 self._forwarder_process.start() | 1160 self._forwarder_process.start() |
| 1131 | 1161 |
| 1132 deadline = time.time() + DRIVER_START_STOP_TIMEOUT_SECS | 1162 deadline = time.time() + DRIVER_START_STOP_TIMEOUT_SECS |
| 1133 if not self._wait_for_server_process_output(self._forwarder_process, dea dline, 'Forwarding device port'): | 1163 if not self._wait_for_server_process_output(self._forwarder_process, dea dline, 'Forwarding device port'): |
| 1134 return False | 1164 return False |
| 1135 | 1165 |
| 1136 self._android_commands.run(['logcat', '-c']) | 1166 self._android_commands.run(['logcat', '-c']) |
| 1137 | 1167 |
| 1138 cmd_line_file_path = self._driver_details.command_line_file() | 1168 cmd_line_file_path = self._driver_details.command_line_file() |
| 1139 original_cmd_line_file_path = cmd_line_file_path + '.orig' | 1169 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): | 1170 if self._android_commands.file_exists(cmd_line_file_path) and not self._ android_commands.file_exists( |
| 1171 original_cmd_line_file_path): | |
| 1141 # We check for both the normal path and the backup because we do not want to step | 1172 # 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 | 1173 # on the backup. Otherwise, we'd clobber the backup whenever we chan ged the |
| 1143 # command line during the run. | 1174 # command line during the run. |
| 1144 self._android_commands.run(['shell', 'mv', cmd_line_file_path, origi nal_cmd_line_file_path]) | 1175 self._android_commands.run(['shell', 'mv', cmd_line_file_path, origi nal_cmd_line_file_path]) |
| 1145 | 1176 |
| 1146 self._android_commands.run(['shell', 'echo'] + self._android_driver_cmd_ line(pixel_tests, per_test_args) + ['>', self._driver_details.command_line_file( )]) | 1177 self._android_commands.run(['shell', 'echo'] + self._android_driver_cmd_ line(pixel_tests, per_test_args) + |
| 1178 ['>', self._driver_details.command_line_file( )]) | |
| 1147 self._created_cmd_line = True | 1179 self._created_cmd_line = True |
| 1148 | 1180 |
| 1149 self._android_commands.run(['shell', 'rm', '-rf', self._driver_details.d evice_crash_dumps_directory()]) | 1181 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') | 1182 self._android_commands.mkdir(self._driver_details.device_crash_dumps_dir ectory(), chmod='777') |
| 1151 | 1183 |
| 1152 start_result = self._android_commands.run(['shell', 'am', 'start', '-e', 'RunInSubThread', '-n', self._driver_details.activity_name()]) | 1184 start_result = self._android_commands.run(['shell', 'am', 'start', '-e', 'RunInSubThread', '-n', |
| 1185 self._driver_details.activity _name()]) | |
| 1153 if start_result.find('Exception') != -1: | 1186 if start_result.find('Exception') != -1: |
| 1154 self._log_error('Failed to start the content_shell application. Exce ption:\n' + start_result) | 1187 self._log_error('Failed to start the content_shell application. Exce ption:\n' + start_result) |
| 1155 return False | 1188 return False |
| 1156 | 1189 |
| 1157 if not ChromiumAndroidDriver._loop_with_timeout(self._all_pipes_created, DRIVER_START_STOP_TIMEOUT_SECS): | 1190 if not ChromiumAndroidDriver._loop_with_timeout(self._all_pipes_created, DRIVER_START_STOP_TIMEOUT_SECS): |
| 1158 return False | 1191 return False |
| 1159 | 1192 |
| 1160 # Read back the shell prompt to ensure adb shell ready. | 1193 # Read back the shell prompt to ensure adb shell ready. |
| 1161 deadline = time.time() + DRIVER_START_STOP_TIMEOUT_SECS | 1194 deadline = time.time() + DRIVER_START_STOP_TIMEOUT_SECS |
| 1162 self._server_process.start() | 1195 self._server_process.start() |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 1186 # If normal_startup_event is not set in time, the main thread mu st be blocked at | 1219 # If normal_startup_event is not set in time, the main thread mu st be blocked at |
| 1187 # reading/writing the fifo. Kill the fifo reading/writing proces ses to let the | 1220 # reading/writing the fifo. Kill the fifo reading/writing proces ses to let the |
| 1188 # main thread escape from the deadlocked state. After that, the main thread will | 1221 # main thread escape from the deadlocked state. After that, the main thread will |
| 1189 # treat this as a crash. | 1222 # treat this as a crash. |
| 1190 self._log_error('Deadlock detected. Processes killed.') | 1223 self._log_error('Deadlock detected. Processes killed.') |
| 1191 for i in processes: | 1224 for i in processes: |
| 1192 i.kill() | 1225 i.kill() |
| 1193 | 1226 |
| 1194 # Start a thread to kill the pipe reading/writing processes on deadlock of the fifos during startup. | 1227 # Start a thread to kill the pipe reading/writing processes on deadlock of the fifos during startup. |
| 1195 normal_startup_event = threading.Event() | 1228 normal_startup_event = threading.Event() |
| 1196 threading.Thread(name='DeadlockDetector', target=deadlock_detector, | 1229 threading.Thread( |
| 1197 args=([self._server_process, self._read_stdout_process, self._read_stderr_process], normal_startup_event)).start() | 1230 name='DeadlockDetector', |
| 1231 target=deadlock_detector, | |
| 1232 args=([self._server_process, self._read_stdout_process, self._read_s tderr_process], normal_startup_event)).start() | |
| 1198 | 1233 |
| 1199 # The test driver might crash during startup or when the deadlock detect or hits | 1234 # The test driver might crash during startup or when the deadlock detect or hits |
| 1200 # a deadlock and kills the fifo reading/writing processes. | 1235 # a deadlock and kills the fifo reading/writing processes. |
| 1201 if not self._wait_for_server_process_output(self._server_process, deadli ne, '#READY'): | 1236 if not self._wait_for_server_process_output(self._server_process, deadli ne, '#READY'): |
| 1202 return False | 1237 return False |
| 1203 | 1238 |
| 1204 # Inform the deadlock detector that the startup is successful without de adlock. | 1239 # Inform the deadlock detector that the startup is successful without de adlock. |
| 1205 normal_startup_event.set() | 1240 normal_startup_event.set() |
| 1206 self._log_debug("content_shell is ready") | 1241 self._log_debug("content_shell is ready") |
| 1207 return True | 1242 return True |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1287 return command | 1322 return command |
| 1288 | 1323 |
| 1289 def _read_prompt(self, deadline): | 1324 def _read_prompt(self, deadline): |
| 1290 last_char = '' | 1325 last_char = '' |
| 1291 while True: | 1326 while True: |
| 1292 current_char = self._server_process.read_stdout(deadline, 1) | 1327 current_char = self._server_process.read_stdout(deadline, 1) |
| 1293 if current_char == ' ': | 1328 if current_char == ' ': |
| 1294 if last_char in ('#', '$'): | 1329 if last_char in ('#', '$'): |
| 1295 return | 1330 return |
| 1296 last_char = current_char | 1331 last_char = current_char |
| OLD | NEW |