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 |