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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 # This path is defined in Chromium's base/test/test_support_android.cc. | 55 # This path is defined in Chromium's base/test/test_support_android.cc. |
56 DEVICE_SOURCE_ROOT_DIR = '/data/local/tmp/' | 56 DEVICE_SOURCE_ROOT_DIR = '/data/local/tmp/' |
57 | 57 |
58 # The layout tests directory on device, which has two usages: | 58 # The layout tests directory on device, which has two usages: |
59 # 1. as a virtual path in file urls that will be bridged to HTTP. | 59 # 1. as a virtual path in file urls that will be bridged to HTTP. |
60 # 2. pointing to some files that are pushed to the device for tests that | 60 # 2. pointing to some files that are pushed to the device for tests that |
61 # don't work on file-over-http (e.g. blob protocol tests). | 61 # don't work on file-over-http (e.g. blob protocol tests). |
62 DEVICE_WEBKIT_BASE_DIR = DEVICE_SOURCE_ROOT_DIR + 'third_party/WebKit/' | 62 DEVICE_WEBKIT_BASE_DIR = DEVICE_SOURCE_ROOT_DIR + 'third_party/WebKit/' |
63 DEVICE_LAYOUT_TESTS_DIR = DEVICE_WEBKIT_BASE_DIR + 'LayoutTests/' | 63 DEVICE_LAYOUT_TESTS_DIR = DEVICE_WEBKIT_BASE_DIR + 'LayoutTests/' |
64 | 64 |
65 SCALING_GOVERNORS_PATTERN = "/sys/devices/system/cpu/cpu*/cpufreq/scaling_govern
or" | 65 SCALING_GOVERNORS_PATTERN = '/sys/devices/system/cpu/cpu*/cpufreq/scaling_govern
or' |
66 KPTR_RESTRICT_PATH = "/proc/sys/kernel/kptr_restrict" | 66 KPTR_RESTRICT_PATH = '/proc/sys/kernel/kptr_restrict' |
67 | 67 |
68 # All the test cases are still served to the test runner through file protocol, | 68 # All the test cases are still served to the test runner through file protocol, |
69 # but we use a file-to-http feature to bridge the file request to host's http | 69 # but we use a file-to-http feature to bridge the file request to host's http |
70 # server to get the real test files and corresponding resources. | 70 # server to get the real test files and corresponding resources. |
71 # See webkit/support/platform_support_android.cc for the other side of this brid
ge. | 71 # See webkit/support/platform_support_android.cc for the other side of this brid
ge. |
72 PERF_TEST_PATH_PREFIX = '/all-perf-tests' | 72 PERF_TEST_PATH_PREFIX = '/all-perf-tests' |
73 LAYOUT_TEST_PATH_PREFIX = '/all-tests' | 73 LAYOUT_TEST_PATH_PREFIX = '/all-tests' |
74 | 74 |
75 # All ports the Android forwarder to forward. | 75 # All ports the Android forwarder to forward. |
76 # 8000, 8080 and 8443 are for http/https tests. | 76 # 8000, 8080 and 8443 are for http/https tests. |
(...skipping 37 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/', |
| 125 '/usr/share/fonts/truetype/ttf-punjabi-fonts/'], |
| 126 'lohit_pa.ttf', |
| 127 'ttf-indic-fonts-core'], |
125 ] | 128 ] |
126 | 129 |
127 # Test resources that need to be accessed as files directly. | 130 # Test resources that need to be accessed as files directly. |
128 # Each item can be the relative path of a directory or a file. | 131 # Each item can be the relative path of a directory or a file. |
129 TEST_RESOURCES_TO_PUSH = [ | 132 TEST_RESOURCES_TO_PUSH = [ |
130 # Blob tests need to access files directly. | 133 # Blob tests need to access files directly. |
131 'editing/pasteboard/resources', | 134 'editing/pasteboard/resources', |
132 'fast/files/resources', | 135 'fast/files/resources', |
133 'http/tests/local/resources', | 136 'http/tests/local/resources', |
134 'http/tests/local/formdata/resources', | 137 'http/tests/local/formdata/resources', |
135 # User style URLs are accessed as local files in webkit_support. | 138 # User style URLs are accessed as local files in webkit_support. |
136 'http/tests/security/resources/cssStyle.css', | 139 'http/tests/security/resources/cssStyle.css', |
137 # Media tests need to access audio/video as files. | 140 # Media tests need to access audio/video as files. |
138 'media/content', | 141 'media/content', |
139 'compositing/resources/video.mp4', | 142 'compositing/resources/video.mp4', |
140 ] | 143 ] |
141 | 144 |
142 MD5SUM_DEVICE_FILE_NAME = 'md5sum_bin' | 145 MD5SUM_DEVICE_FILE_NAME = 'md5sum_bin' |
143 MD5SUM_HOST_FILE_NAME = 'md5sum_bin_host' | 146 MD5SUM_HOST_FILE_NAME = 'md5sum_bin_host' |
144 MD5SUM_DEVICE_PATH = '/data/local/tmp/' + MD5SUM_DEVICE_FILE_NAME | 147 MD5SUM_DEVICE_PATH = '/data/local/tmp/' + MD5SUM_DEVICE_FILE_NAME |
145 | 148 |
146 | 149 |
147 # Information required when running layout tests using content_shell as the test
runner. | 150 # Information required when running layout tests using content_shell as the test
runner. |
148 class ContentShellDriverDetails(): | 151 class ContentShellDriverDetails(): |
| 152 |
149 def device_cache_directory(self): | 153 def device_cache_directory(self): |
150 return self.device_directory() + 'cache/' | 154 return self.device_directory() + 'cache/' |
151 | 155 |
152 def device_fonts_directory(self): | 156 def device_fonts_directory(self): |
153 return self.device_directory() + 'fonts/' | 157 return self.device_directory() + 'fonts/' |
154 | 158 |
155 def device_forwarder_path(self): | 159 def device_forwarder_path(self): |
156 return self.device_directory() + 'forwarder' | 160 return self.device_directory() + 'forwarder' |
157 | 161 |
158 def device_fifo_directory(self): | 162 def device_fifo_directory(self): |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 pass | 251 pass |
248 return pids | 252 return pids |
249 | 253 |
250 def run(self, command, ignore_error=False): | 254 def run(self, command, ignore_error=False): |
251 self._log_debug('Run adb command: ' + str(command)) | 255 self._log_debug('Run adb command: ' + str(command)) |
252 if ignore_error: | 256 if ignore_error: |
253 error_handler = self._executive.ignore_error | 257 error_handler = self._executive.ignore_error |
254 else: | 258 else: |
255 error_handler = None | 259 error_handler = None |
256 | 260 |
257 result = self._executive.run_command(self.adb_command() + command, error
_handler=error_handler, debug_logging=self._debug_logging) | 261 result = self._executive.run_command( |
| 262 self.adb_command() + command, |
| 263 error_handler=error_handler, |
| 264 debug_logging=self._debug_logging) |
258 | 265 |
259 # We limit the length to avoid outputting too verbose commands, such as
"adb logcat". | 266 # We limit the length to avoid outputting too verbose commands, such as
"adb logcat". |
260 self._log_debug('Run adb result: ' + result[:80]) | 267 self._log_debug('Run adb result: ' + result[:80]) |
261 return result | 268 return result |
262 | 269 |
263 def get_serial(self): | 270 def get_serial(self): |
264 return self._device_serial | 271 return self._device_serial |
265 | 272 |
266 def adb_command(self): | 273 def adb_command(self): |
267 return [AndroidCommands.adb_command_path(self._executive, self._debug_lo
gging), '-s', self._device_serial] | 274 return [AndroidCommands.adb_command_path(self._executive, self._debug_lo
gging), '-s', self._device_serial] |
268 | 275 |
269 @staticmethod | 276 @staticmethod |
270 def set_adb_command_path_options(paths): | 277 def set_adb_command_path_options(paths): |
271 AndroidCommands._adb_command_path_options = paths | 278 AndroidCommands._adb_command_path_options = paths |
272 | 279 |
273 @staticmethod | 280 @staticmethod |
274 def adb_command_path(executive, debug_logging): | 281 def adb_command_path(executive, debug_logging): |
275 if AndroidCommands._adb_command_path: | 282 if AndroidCommands._adb_command_path: |
276 return AndroidCommands._adb_command_path | 283 return AndroidCommands._adb_command_path |
277 | 284 |
278 assert AndroidCommands._adb_command_path_options, 'No commands paths hav
e been set to look for the "adb" command.' | 285 assert AndroidCommands._adb_command_path_options, 'No commands paths hav
e been set to look for the "adb" command.' |
279 | 286 |
280 command_path = None | 287 command_path = None |
281 command_version = None | 288 command_version = None |
282 for path_option in AndroidCommands._adb_command_path_options: | 289 for path_option in AndroidCommands._adb_command_path_options: |
283 path_version = AndroidCommands._determine_adb_version(path_option, e
xecutive, debug_logging) | 290 path_version = AndroidCommands._determine_adb_version(path_option, e
xecutive, debug_logging) |
284 if not path_version: | 291 if not path_version: |
285 continue | 292 continue |
286 if command_version != None and path_version < command_version: | 293 if command_version is not None and path_version < command_version: |
287 continue | 294 continue |
288 | 295 |
289 command_path = path_option | 296 command_path = path_option |
290 command_version = path_version | 297 command_version = path_version |
291 | 298 |
292 assert command_path, 'Unable to locate the "adb" command. Are you using
an Android checkout of Chromium?' | 299 assert command_path, 'Unable to locate the "adb" command. Are you using
an Android checkout of Chromium?' |
293 | 300 |
294 AndroidCommands._adb_command_path = command_path | 301 AndroidCommands._adb_command_path = command_path |
295 return command_path | 302 return command_path |
296 | 303 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 result = executive.run_command([AndroidCommands.adb_command_path(executi
ve, debug_logging=self._debug_logging), 'devices'], | 361 result = executive.run_command([AndroidCommands.adb_command_path(executi
ve, debug_logging=self._debug_logging), 'devices'], |
355 error_handler=executive.ignore_error, deb
ug_logging=self._debug_logging) | 362 error_handler=executive.ignore_error, deb
ug_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_BA
TTERY_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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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', |
444 self.path_from_chromium_base('third_party', 'android_tools', 'sdk',
'platform-tools', 'adb')]) | 451 self.path_from_chromium_ba
se('third_party', 'android_tools', 'sdk', '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): |
(...skipping 14 matching lines...) Expand all Loading... |
469 # marked as slow tests on desktop platforms. | 476 # marked as slow tests on desktop platforms. |
470 return 10 * 1000 | 477 return 10 * 1000 |
471 | 478 |
472 def driver_stop_timeout(self): | 479 def driver_stop_timeout(self): |
473 # The driver doesn't respond to closing stdin, so we might as well stop
the driver immediately. | 480 # The driver doesn't respond to closing stdin, so we might as well stop
the driver immediately. |
474 return 0.0 | 481 return 0.0 |
475 | 482 |
476 def default_child_processes(self): | 483 def default_child_processes(self): |
477 usable_devices = self._devices.usable_devices(self._executive) | 484 usable_devices = self._devices.usable_devices(self._executive) |
478 if not usable_devices: | 485 if not usable_devices: |
479 raise test_run_results.TestRunException(test_run_results.NO_DEVICES_
EXIT_STATUS, "Unable to find any attached Android devices.") | 486 raise test_run_results.TestRunException( |
| 487 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 check_wdiff(self, logging=True): | 491 def check_wdiff(self, logging=True): |
483 return self._host_port.check_wdiff(logging) | 492 return self._host_port.check_wdiff(logging) |
484 | 493 |
485 def check_build(self, needs_http, printer): | 494 def check_build(self, needs_http, printer): |
486 exit_status = super(AndroidPort, self).check_build(needs_http, printer) | 495 exit_status = super(AndroidPort, self).check_build(needs_http, printer) |
487 if exit_status: | 496 if exit_status: |
488 return exit_status | 497 return exit_status |
489 | 498 |
490 result = self._check_file_exists(self.path_to_md5sum(), 'md5sum utility'
) | 499 result = self._check_file_exists(self.path_to_md5sum(), 'md5sum utility'
) |
491 result = self._check_file_exists(self.path_to_md5sum_host(), 'md5sum hos
t utility') and result | 500 result = self._check_file_exists(self.path_to_md5sum_host(), 'md5sum hos
t utility') and result |
492 result = self._check_file_exists(self.path_to_forwarder(), 'forwarder ut
ility') and result | 501 result = self._check_file_exists(self.path_to_forwarder(), 'forwarder ut
ility') and result |
493 | 502 |
494 if not result: | 503 if not result: |
495 # There is a race condition in adb at least <= 4.3 on Linux that cau
ses it to go offline periodically | 504 # There is a race condition in adb at least <= 4.3 on Linux that cau
ses it to go offline periodically |
496 # We set the processor affinity for any running adb process to attem
pt to work around this. | 505 # We set the processor affinity for any running adb process to attem
pt to work around this. |
497 # See crbug.com/268450 | 506 # See crbug.com/268450 |
498 if self.host.platform.is_linux(): | 507 if self.host.platform.is_linux(): |
499 pids = self._executive.running_pids(lambda name: 'adb' in name) | 508 pids = self._executive.running_pids(lambda name: 'adb' in name) |
500 if not pids: | 509 if not pids: |
501 # Apparently adb is not running, which is unusual. Running a
ny adb command should start it. | 510 # Apparently adb is not running, which is unusual. Running a
ny adb command should start it. |
502 self._executive.run_command(['adb', 'devices']) | 511 self._executive.run_command(['adb', 'devices']) |
503 pids = self._executive.running_pids(lambda name: 'adb' in na
me) | 512 pids = self._executive.running_pids(lambda name: 'adb' in na
me) |
504 if not pids: | 513 if not pids: |
505 _log.error("The adb daemon does not appear to be running.") | 514 _log.error('The adb daemon does not appear to be running.') |
506 return False | 515 return False |
507 | 516 |
508 for pid in pids: | 517 for pid in pids: |
509 self._executive.run_command(['taskset', '-p', '-c', '0', str
(pid)]) | 518 self._executive.run_command(['taskset', '-p', '-c', '0', str
(pid)]) |
510 | 519 |
511 if not result: | 520 if not result: |
512 _log.error('For complete Android build requirements, please see:') | 521 _log.error('For complete Android build requirements, please see:') |
513 _log.error('') | 522 _log.error('') |
514 _log.error(' http://code.google.com/p/chromium/wiki/AndroidBuildI
nstructions') | 523 _log.error(' http://code.google.com/p/chromium/wiki/AndroidBuildI
nstructions') |
515 return test_run_results.UNEXPECTED_ERROR_EXIT_STATUS | 524 return test_run_results.UNEXPECTED_ERROR_EXIT_STATUS |
(...skipping 12 matching lines...) Expand all Loading... |
528 d = self.create_driver(worker_number) | 537 d = self.create_driver(worker_number) |
529 serial = d._android_commands.get_serial() | 538 serial = d._android_commands.get_serial() |
530 | 539 |
531 def log_safely(msg, throttled=True): | 540 def log_safely(msg, throttled=True): |
532 if throttled: | 541 if throttled: |
533 callback = printer.write_throttled_update | 542 callback = printer.write_throttled_update |
534 else: | 543 else: |
535 callback = printer.write_update | 544 callback = printer.write_update |
536 lock.acquire() | 545 lock.acquire() |
537 try: | 546 try: |
538 callback("[%s] %s" % (serial, msg)) | 547 callback('[%s] %s' % (serial, msg)) |
539 finally: | 548 finally: |
540 lock.release() | 549 lock.release() |
541 | 550 |
542 log_safely("preparing device", throttled=False) | 551 log_safely('preparing device', throttled=False) |
543 try: | 552 try: |
544 d._setup_test(log_safely) | 553 d._setup_test(log_safely) |
545 log_safely("device prepared", throttled=False) | 554 log_safely('device prepared', throttled=False) |
546 except (ScriptError, driver.DeviceFailure) as e: | 555 except (ScriptError, driver.DeviceFailure) as e: |
547 lock.acquire() | 556 lock.acquire() |
548 _log.warning("[%s] failed to prepare_device: %s" % (serial, str(
e))) | 557 _log.warning('[%s] failed to prepare_device: %s' % (serial, str(
e))) |
549 lock.release() | 558 lock.release() |
550 except KeyboardInterrupt: | 559 except KeyboardInterrupt: |
551 if pool: | 560 if pool: |
552 pool.terminate() | 561 pool.terminate() |
553 | 562 |
554 # FIXME: It would be nice if we knew how many workers we needed. | 563 # FIXME: It would be nice if we knew how many workers we needed. |
555 num_workers = self.default_child_processes() | 564 num_workers = self.default_child_processes() |
556 num_child_processes = int(self.get_option('child_processes')) | 565 num_child_processes = int(self.get_option('child_processes')) |
557 if num_child_processes: | 566 if num_child_processes: |
558 num_workers = min(num_workers, num_child_processes) | 567 num_workers = min(num_workers, num_child_processes) |
(...skipping 28 matching lines...) Expand all Loading... |
587 | 596 |
588 def check_sys_deps(self, needs_http): | 597 def check_sys_deps(self, needs_http): |
589 for (font_dirs, font_file, package) in HOST_FONT_FILES: | 598 for (font_dirs, font_file, package) in HOST_FONT_FILES: |
590 exists = False | 599 exists = False |
591 for font_dir in font_dirs: | 600 for font_dir in font_dirs: |
592 font_path = font_dir + font_file | 601 font_path = font_dir + font_file |
593 if self._check_file_exists(font_path, '', logging=False): | 602 if self._check_file_exists(font_path, '', logging=False): |
594 exists = True | 603 exists = True |
595 break | 604 break |
596 if not exists: | 605 if not exists: |
597 _log.error('You are missing %s under %s. Try installing %s. See
build instructions.' % (font_file, font_dirs, package)) | 606 _log.error( |
| 607 'You are missing %s under %s. Try installing %s. See build i
nstructions.' % |
| 608 (font_file, font_dirs, package)) |
598 return test_run_results.SYS_DEPS_EXIT_STATUS | 609 return test_run_results.SYS_DEPS_EXIT_STATUS |
599 return test_run_results.OK_EXIT_STATUS | 610 return test_run_results.OK_EXIT_STATUS |
600 | 611 |
601 def requires_http_server(self): | 612 def requires_http_server(self): |
602 """Chromium Android runs tests on devices, and uses the HTTP server to | 613 """Chromium Android runs tests on devices, and uses the HTTP server to |
603 serve the actual layout tests to the test driver.""" | 614 serve the actual layout tests to the test driver.""" |
604 return True | 615 return True |
605 | 616 |
606 def start_http_server(self, additional_dirs, number_of_drivers): | 617 def start_http_server(self, additional_dirs, number_of_drivers): |
607 additional_dirs[PERF_TEST_PATH_PREFIX] = self.perf_tests_dir() | 618 additional_dirs[PERF_TEST_PATH_PREFIX] = self.perf_tests_dir() |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 def _android_server_process_constructor(port, server_name, cmd_line, env=Non
e, logging=False): | 672 def _android_server_process_constructor(port, server_name, cmd_line, env=Non
e, logging=False): |
662 return server_process.ServerProcess(port, server_name, cmd_line, env, | 673 return server_process.ServerProcess(port, server_name, cmd_line, env, |
663 universal_newlines=True, treat_no_da
ta_as_crash=True, logging=logging) | 674 universal_newlines=True, treat_no_da
ta_as_crash=True, logging=logging) |
664 | 675 |
665 | 676 |
666 class AndroidPerf(SingleFileOutputProfiler): | 677 class AndroidPerf(SingleFileOutputProfiler): |
667 _cached_perf_host_path = None | 678 _cached_perf_host_path = None |
668 _have_searched_for_perf_host = False | 679 _have_searched_for_perf_host = False |
669 | 680 |
670 def __init__(self, host, executable_path, output_dir, android_commands, symf
s_path, kallsyms_path, identifier=None): | 681 def __init__(self, host, executable_path, output_dir, android_commands, symf
s_path, kallsyms_path, identifier=None): |
671 super(AndroidPerf, self).__init__(host, executable_path, output_dir, "da
ta", identifier) | 682 super(AndroidPerf, self).__init__(host, executable_path, output_dir, 'da
ta', identifier) |
672 self._android_commands = android_commands | 683 self._android_commands = android_commands |
673 self._perf_process = None | 684 self._perf_process = None |
674 self._symfs_path = symfs_path | 685 self._symfs_path = symfs_path |
675 self._kallsyms_path = kallsyms_path | 686 self._kallsyms_path = kallsyms_path |
676 | 687 |
677 def check_configuration(self): | 688 def check_configuration(self): |
678 # Check that perf is installed | 689 # Check that perf is installed |
679 if not self._android_commands.file_exists('/system/bin/perf'): | 690 if not self._android_commands.file_exists('/system/bin/perf'): |
680 print "Cannot find /system/bin/perf on device %s" % self._android_co
mmands.get_serial() | 691 print 'Cannot find /system/bin/perf on device %s' % self._android_co
mmands.get_serial() |
681 return False | 692 return False |
682 | 693 |
683 # Check that the device is a userdebug build (or at least has the necess
ary libraries). | 694 # Check that the device is a userdebug build (or at least has the necess
ary libraries). |
684 if self._android_commands.run(['shell', 'getprop', 'ro.build.type']).str
ip() != 'userdebug': | 695 if self._android_commands.run(['shell', 'getprop', 'ro.build.type']).str
ip() != 'userdebug': |
685 print "Device %s is not flashed with a userdebug build of Android" %
self._android_commands.get_serial() | 696 print 'Device %s is not flashed with a userdebug build of Android' %
self._android_commands.get_serial() |
686 return False | 697 return False |
687 | 698 |
688 # FIXME: Check that the binary actually is perf-able (has stackframe poi
nters)? | 699 # FIXME: Check that the binary actually is perf-able (has stackframe poi
nters)? |
689 # objdump -s a function and make sure it modifies the fp? | 700 # objdump -s a function and make sure it modifies the fp? |
690 # Instruct users to rebuild after export GYP_DEFINES="profiling=1 $GYP_D
EFINES" | 701 # Instruct users to rebuild after export GYP_DEFINES="profiling=1 $GYP_D
EFINES" |
691 return True | 702 return True |
692 | 703 |
693 def print_setup_instructions(self): | 704 def print_setup_instructions(self): |
694 print """ | 705 print """ |
695 perf on android requires a 'userdebug' build of Android, see: | 706 perf on android requires a 'userdebug' build of Android, see: |
696 http://source.android.com/source/building-devices.html" | 707 http://source.android.com/source/building-devices.html" |
697 | 708 |
698 The perf command can be built from: | 709 The perf command can be built from: |
699 https://android.googlesource.com/platform/external/linux-tools-perf/ | 710 https://android.googlesource.com/platform/external/linux-tools-perf/ |
700 and requires libefl, libebl, libdw, and libdwfl available in: | 711 and requires libefl, libebl, libdw, and libdwfl available in: |
701 https://android.googlesource.com/platform/external/elfutils/ | 712 https://android.googlesource.com/platform/external/elfutils/ |
702 | 713 |
703 The test driver must be built with profiling=1, make sure you've done: | 714 The test driver must be built with profiling=1, make sure you've done: |
704 export GYP_DEFINES="profiling=1 $GYP_DEFINES" | 715 export GYP_DEFINES="profiling=1 $GYP_DEFINES" |
705 update-webkit --chromium-android | 716 update-webkit --chromium-android |
706 build-webkit --chromium-android | 717 build-webkit --chromium-android |
707 | 718 |
708 Googlers should read: | 719 Googlers should read: |
709 http://goto.google.com/cr-android-perf-howto | 720 http://goto.google.com/cr-android-perf-howto |
710 """ | 721 """ |
711 | 722 |
712 def attach_to_pid(self, pid): | 723 def attach_to_pid(self, pid): |
713 assert(pid) | 724 assert(pid) |
714 assert(self._perf_process == None) | 725 assert(self._perf_process is None) |
715 # FIXME: This can't be a fixed timeout! | 726 # FIXME: This can't be a fixed timeout! |
716 cmd = self._android_commands.adb_command() + ['shell', 'perf', 'record',
'-g', '-p', pid, 'sleep', 30] | 727 cmd = self._android_commands.adb_command() + ['shell', 'perf', 'record',
'-g', '-p', pid, 'sleep', 30] |
717 self._perf_process = self._host.executive.popen(cmd) | 728 self._perf_process = self._host.executive.popen(cmd) |
718 | 729 |
719 def _perf_version_string(self, perf_path): | 730 def _perf_version_string(self, perf_path): |
720 try: | 731 try: |
721 return self._host.executive.run_command([perf_path, '--version']) | 732 return self._host.executive.run_command([perf_path, '--version']) |
722 except: | 733 except: |
723 return None | 734 return None |
724 | 735 |
725 def _find_perfhost_binary(self): | 736 def _find_perfhost_binary(self): |
726 perfhost_version = self._perf_version_string('perfhost_linux') | 737 perfhost_version = self._perf_version_string('perfhost_linux') |
727 if perfhost_version: | 738 if perfhost_version: |
728 return 'perfhost_linux' | 739 return 'perfhost_linux' |
729 perf_version = self._perf_version_string('perf') | 740 perf_version = self._perf_version_string('perf') |
730 if perf_version: | 741 if perf_version: |
731 return 'perf' | 742 return 'perf' |
732 return None | 743 return None |
733 | 744 |
734 def _perfhost_path(self): | 745 def _perfhost_path(self): |
735 if self._have_searched_for_perf_host: | 746 if self._have_searched_for_perf_host: |
736 return self._cached_perf_host_path | 747 return self._cached_perf_host_path |
737 self._have_searched_for_perf_host = True | 748 self._have_searched_for_perf_host = True |
738 self._cached_perf_host_path = self._find_perfhost_binary() | 749 self._cached_perf_host_path = self._find_perfhost_binary() |
739 return self._cached_perf_host_path | 750 return self._cached_perf_host_path |
740 | 751 |
741 def _first_ten_lines_of_profile(self, perf_output): | 752 def _first_ten_lines_of_profile(self, perf_output): |
742 match = re.search("^#[^\n]*\n((?: [^\n]*\n){1,10})", perf_output, re.MUL
TILINE) | 753 match = re.search('^#[^\n]*\n((?: [^\n]*\n){1,10})', perf_output, re.MUL
TILINE) |
743 return match.group(1) if match else None | 754 return match.group(1) if match else None |
744 | 755 |
745 def profile_after_exit(self): | 756 def profile_after_exit(self): |
746 perf_exitcode = self._perf_process.wait() | 757 perf_exitcode = self._perf_process.wait() |
747 if perf_exitcode != 0: | 758 if perf_exitcode != 0: |
748 print "Perf failed (exit code: %i), can't process results." % perf_e
xitcode | 759 print "Perf failed (exit code: %i), can't process results." % perf_e
xitcode |
749 return | 760 return |
750 | 761 |
751 self._android_commands.pull('/data/perf.data', self._output_path) | 762 self._android_commands.pull('/data/perf.data', self._output_path) |
752 | 763 |
(...skipping 18 matching lines...) Expand all Loading... |
771 also, modern versions of perf (available from apt-get install goobuntu-kernel-to
ols-common) | 782 also, modern versions of perf (available from apt-get install goobuntu-kernel-to
ols-common) |
772 may also be able to process the perf.data files from the device. | 783 may also be able to process the perf.data files from the device. |
773 | 784 |
774 Googlers should read: | 785 Googlers should read: |
775 http://goto.google.com/cr-android-perf-howto | 786 http://goto.google.com/cr-android-perf-howto |
776 for instructions on installing pre-built copies of perfhost_linux | 787 for instructions on installing pre-built copies of perfhost_linux |
777 http://crbug.com/165250 discusses making these pre-built binaries externally ava
ilable. | 788 http://crbug.com/165250 discusses making these pre-built binaries externally ava
ilable. |
778 """ | 789 """ |
779 | 790 |
780 perfhost_display_patch = perfhost_path if perfhost_path else 'perfhost_l
inux' | 791 perfhost_display_patch = perfhost_path if perfhost_path else 'perfhost_l
inux' |
781 print "To view the full profile, run:" | 792 print 'To view the full profile, run:' |
782 print ' '.join([perfhost_display_patch] + perfhost_report_command) | 793 print ' '.join([perfhost_display_patch] + perfhost_report_command) |
783 | 794 |
784 | 795 |
785 class ChromiumAndroidDriver(driver.Driver): | 796 class ChromiumAndroidDriver(driver.Driver): |
| 797 |
786 def __init__(self, port, worker_number, pixel_tests, driver_details, android
_devices, no_timeout=False): | 798 def __init__(self, port, worker_number, pixel_tests, driver_details, android
_devices, no_timeout=False): |
787 super(ChromiumAndroidDriver, self).__init__(port, worker_number, pixel_t
ests, no_timeout) | 799 super(ChromiumAndroidDriver, self).__init__(port, worker_number, pixel_t
ests, no_timeout) |
788 self._in_fifo_path = driver_details.device_fifo_directory() + 'stdin.fif
o' | 800 self._in_fifo_path = driver_details.device_fifo_directory() + 'stdin.fif
o' |
789 self._out_fifo_path = driver_details.device_fifo_directory() + 'test.fif
o' | 801 self._out_fifo_path = driver_details.device_fifo_directory() + 'test.fif
o' |
790 self._err_fifo_path = driver_details.device_fifo_directory() + 'stderr.f
ifo' | 802 self._err_fifo_path = driver_details.device_fifo_directory() + 'stderr.f
ifo' |
791 self._read_stdout_process = None | 803 self._read_stdout_process = None |
792 self._read_stderr_process = None | 804 self._read_stderr_process = None |
793 self._forwarder_process = None | 805 self._forwarder_process = None |
794 self._original_governors = {} | 806 self._original_governors = {} |
795 self._original_kptr_restrict = None | 807 self._original_kptr_restrict = None |
796 | 808 |
797 self._android_devices = android_devices | 809 self._android_devices = android_devices |
798 self._android_commands = android_devices.get_device(port._executive, wor
ker_number) | 810 self._android_commands = android_devices.get_device(port._executive, wor
ker_number) |
799 self._driver_details = driver_details | 811 self._driver_details = driver_details |
800 self._debug_logging = self._port._debug_logging | 812 self._debug_logging = self._port._debug_logging |
801 self._created_cmd_line = False | 813 self._created_cmd_line = False |
802 self._device_failed = False | 814 self._device_failed = False |
803 | 815 |
804 # FIXME: If we taught ProfileFactory about "target" devices we could | 816 # FIXME: If we taught ProfileFactory about "target" devices we could |
805 # just use the logic in Driver instead of duplicating it here. | 817 # just use the logic in Driver instead of duplicating it here. |
806 if self._port.get_option("profile"): | 818 if self._port.get_option('profile'): |
807 # FIXME: This should be done once, instead of per-driver! | 819 # FIXME: This should be done once, instead of per-driver! |
808 symfs_path = self._find_or_create_symfs() | 820 symfs_path = self._find_or_create_symfs() |
809 kallsyms_path = self._update_kallsyms_cache(symfs_path) | 821 kallsyms_path = self._update_kallsyms_cache(symfs_path) |
810 # FIXME: We should pass this some sort of "Bridge" object abstractio
n around ADB instead of a path/device pair. | 822 # FIXME: We should pass this some sort of "Bridge" object abstractio
n around ADB instead of a path/device pair. |
811 self._profiler = AndroidPerf(self._port.host, self._port._path_to_dr
iver(), self._port.results_directory(), | 823 self._profiler = AndroidPerf(self._port.host, self._port._path_to_dr
iver(), self._port.results_directory(), |
812 self._android_commands, symfs_path, kallsyms_path) | 824 self._android_commands, symfs_path, kal
lsyms_path) |
813 # FIXME: This is a layering violation and should be moved to Port.ch
eck_sys_deps | 825 # FIXME: This is a layering violation and should be moved to Port.ch
eck_sys_deps |
814 # once we have an abstraction around an adb_path/device_serial pair
to make it | 826 # once we have an abstraction around an adb_path/device_serial pair
to make it |
815 # easy to make these class methods on AndroidPerf. | 827 # easy to make these class methods on AndroidPerf. |
816 if not self._profiler.check_configuration(): | 828 if not self._profiler.check_configuration(): |
817 self._profiler.print_setup_instructions() | 829 self._profiler.print_setup_instructions() |
818 sys.exit(1) | 830 sys.exit(1) |
819 else: | 831 else: |
820 self._profiler = None | 832 self._profiler = None |
821 | 833 |
822 def __del__(self): | 834 def __del__(self): |
823 self._teardown_performance() | 835 self._teardown_performance() |
824 self._clean_up_cmd_line() | 836 self._clean_up_cmd_line() |
825 super(ChromiumAndroidDriver, self).__del__() | 837 super(ChromiumAndroidDriver, self).__del__() |
826 | 838 |
827 def _update_kallsyms_cache(self, output_dir): | 839 def _update_kallsyms_cache(self, output_dir): |
828 kallsyms_name = "%s-kallsyms" % self._android_commands.get_serial() | 840 kallsyms_name = '%s-kallsyms' % self._android_commands.get_serial() |
829 kallsyms_cache_path = self._port.host.filesystem.join(output_dir, kallsy
ms_name) | 841 kallsyms_cache_path = self._port.host.filesystem.join(output_dir, kallsy
ms_name) |
830 | 842 |
831 self._android_commands.restart_as_root() | 843 self._android_commands.restart_as_root() |
832 | 844 |
833 saved_kptr_restrict = self._android_commands.run(['shell', 'cat', KPTR_R
ESTRICT_PATH]).strip() | 845 saved_kptr_restrict = self._android_commands.run(['shell', 'cat', KPTR_R
ESTRICT_PATH]).strip() |
834 self._android_commands.run(['shell', 'echo', '0', '>', KPTR_RESTRICT_PAT
H]) | 846 self._android_commands.run(['shell', 'echo', '0', '>', KPTR_RESTRICT_PAT
H]) |
835 | 847 |
836 print "Updating kallsyms file (%s) from device" % kallsyms_cache_path | 848 print 'Updating kallsyms file (%s) from device' % kallsyms_cache_path |
837 self._android_commands.pull("/proc/kallsyms", kallsyms_cache_path) | 849 self._android_commands.pull('/proc/kallsyms', kallsyms_cache_path) |
838 | 850 |
839 self._android_commands.run(['shell', 'echo', saved_kptr_restrict, '>', K
PTR_RESTRICT_PATH]) | 851 self._android_commands.run(['shell', 'echo', saved_kptr_restrict, '>', K
PTR_RESTRICT_PATH]) |
840 | 852 |
841 return kallsyms_cache_path | 853 return kallsyms_cache_path |
842 | 854 |
843 def _find_or_create_symfs(self): | 855 def _find_or_create_symfs(self): |
844 environment = self._port.host.copy_current_environment() | 856 environment = self._port.host.copy_current_environment() |
845 env = environment.to_dictionary() | 857 env = environment.to_dictionary() |
846 fs = self._port.host.filesystem | 858 fs = self._port.host.filesystem |
847 | 859 |
848 if 'ANDROID_SYMFS' in env: | 860 if 'ANDROID_SYMFS' in env: |
849 symfs_path = env['ANDROID_SYMFS'] | 861 symfs_path = env['ANDROID_SYMFS'] |
850 else: | 862 else: |
851 symfs_path = fs.join(self._port.results_directory(), 'symfs') | 863 symfs_path = fs.join(self._port.results_directory(), 'symfs') |
852 print "ANDROID_SYMFS not set, using %s" % symfs_path | 864 print 'ANDROID_SYMFS not set, using %s' % symfs_path |
853 | 865 |
854 # find the installed path, and the path of the symboled built library | 866 # find the installed path, and the path of the symboled built library |
855 # FIXME: We should get the install path from the device! | 867 # FIXME: We should get the install path from the device! |
856 symfs_library_path = fs.join(symfs_path, "data/app-lib/%s-1/%s" % (self.
_driver_details.package_name(), self._driver_details.library_name())) | 868 symfs_library_path = fs.join( |
| 869 symfs_path, |
| 870 'data/app-lib/%s-1/%s' % |
| 871 (self._driver_details.package_name(), |
| 872 self._driver_details.library_name())) |
857 built_library_path = self._port._build_path('lib', self._driver_details.
library_name()) | 873 built_library_path = self._port._build_path('lib', self._driver_details.
library_name()) |
858 assert(fs.exists(built_library_path)) | 874 assert(fs.exists(built_library_path)) |
859 | 875 |
860 # 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). | 876 # FIXME: Ideally we'd check the sha1's first and make a soft-link instea
d |
861 print "Updating symfs libary (%s) from built copy (%s)" % (symfs_library
_path, built_library_path) | 877 # of copying (since we probably never care about windows). |
| 878 print 'Updating symfs libary (%s) from built copy (%s)' % (symfs_library
_path, built_library_path) |
862 fs.maybe_make_directory(fs.dirname(symfs_library_path)) | 879 fs.maybe_make_directory(fs.dirname(symfs_library_path)) |
863 fs.copyfile(built_library_path, symfs_library_path) | 880 fs.copyfile(built_library_path, symfs_library_path) |
864 | 881 |
865 return symfs_path | 882 return symfs_path |
866 | 883 |
867 def _setup_md5sum_and_push_data_if_needed(self, log_callback): | 884 def _setup_md5sum_and_push_data_if_needed(self, log_callback): |
868 self._md5sum_path = self._port.path_to_md5sum() | 885 self._md5sum_path = self._port.path_to_md5sum() |
869 if not self._android_commands.file_exists(MD5SUM_DEVICE_PATH): | 886 if not self._android_commands.file_exists(MD5SUM_DEVICE_PATH): |
870 if not self._android_commands.push(self._md5sum_path, MD5SUM_DEVICE_
PATH): | 887 if not self._android_commands.push(self._md5sum_path, MD5SUM_DEVICE_
PATH): |
871 self._abort('Could not push md5sum to device') | 888 self._abort('Could not push md5sum to device') |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
917 raise driver.DeviceFailure('[%s] %s' % (self._android_commands.get_seria
l(), message)) | 934 raise driver.DeviceFailure('[%s] %s' % (self._android_commands.get_seria
l(), message)) |
918 | 935 |
919 @staticmethod | 936 @staticmethod |
920 def _extract_hashes_from_md5sum_output(md5sum_output): | 937 def _extract_hashes_from_md5sum_output(md5sum_output): |
921 assert md5sum_output | 938 assert md5sum_output |
922 return [line.split(' ')[0] for line in md5sum_output] | 939 return [line.split(' ')[0] for line in md5sum_output] |
923 | 940 |
924 def _files_match(self, host_file, device_file): | 941 def _files_match(self, host_file, device_file): |
925 assert self._port.host.filesystem.exists(host_file) | 942 assert self._port.host.filesystem.exists(host_file) |
926 device_hashes = self._extract_hashes_from_md5sum_output( | 943 device_hashes = self._extract_hashes_from_md5sum_output( |
927 self._port.host.executive.popen(self._android_commands.adb_comma
nd() + ['shell', MD5SUM_DEVICE_PATH, device_file], | 944 self._port.host.executive.popen(self._android_commands.adb_command()
+ ['shell', MD5SUM_DEVICE_PATH, device_file], |
928 stdout=subprocess.PIPE).stdout) | 945 stdout=subprocess.PIPE).stdout) |
929 host_hashes = self._extract_hashes_from_md5sum_output( | 946 host_hashes = self._extract_hashes_from_md5sum_output( |
930 self._port.host.executive.popen(args=['%s_host' % self._md5sum_p
ath, host_file], | 947 self._port.host.executive.popen(args=['%s_host' % self._md5sum_path,
host_file], |
931 stdout=subprocess.PIPE).stdout) | 948 stdout=subprocess.PIPE).stdout) |
932 return host_hashes and device_hashes == host_hashes | 949 return host_hashes and device_hashes == host_hashes |
933 | 950 |
934 def _push_file_if_needed(self, host_file, device_file, log_callback): | 951 def _push_file_if_needed(self, host_file, device_file, log_callback): |
935 basename = self._port.host.filesystem.basename(host_file) | 952 basename = self._port.host.filesystem.basename(host_file) |
936 log_callback("checking %s" % basename) | 953 log_callback('checking %s' % basename) |
937 if not self._files_match(host_file, device_file): | 954 if not self._files_match(host_file, device_file): |
938 log_callback("pushing %s" % basename) | 955 log_callback('pushing %s' % basename) |
939 self._android_commands.push(host_file, device_file) | 956 self._android_commands.push(host_file, device_file) |
940 | 957 |
941 def _push_executable(self, log_callback): | 958 def _push_executable(self, log_callback): |
942 self._push_file_if_needed(self._port.path_to_forwarder(), self._driver_d
etails.device_forwarder_path(), log_callback) | 959 self._push_file_if_needed(self._port.path_to_forwarder(), self._driver_d
etails.device_forwarder_path(), log_callback) |
943 for resource in self._driver_details.additional_resources(): | 960 for resource in self._driver_details.additional_resources(): |
944 self._push_file_if_needed(self._port._build_path(resource), self._dr
iver_details.device_directory() + resource, log_callback) | 961 self._push_file_if_needed( |
| 962 self._port._build_path(resource), |
| 963 self._driver_details.device_directory() + |
| 964 resource, |
| 965 log_callback) |
945 | 966 |
946 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) | 967 self._push_file_if_needed( |
947 self._push_file_if_needed(self._port._build_path('android_fallback_fonts
.xml'), self._driver_details.device_directory() + 'android_fallback_fonts.xml',
log_callback) | 968 self._port._build_path('android_main_fonts.xml'), |
| 969 self._driver_details.device_directory() + |
| 970 'android_main_fonts.xml', |
| 971 log_callback) |
| 972 self._push_file_if_needed( |
| 973 self._port._build_path('android_fallback_fonts.xml'), |
| 974 self._driver_details.device_directory() + |
| 975 'android_fallback_fonts.xml', |
| 976 log_callback) |
948 | 977 |
949 log_callback("checking apk") | 978 log_callback('checking apk') |
950 if self._files_match(self._port._build_path('apks', 'ContentShell.apk'), | 979 if self._files_match(self._port._build_path('apks', 'ContentShell.apk'), |
951 '/data/app/org.chromium.content_shell_apk-1.apk'): | 980 '/data/app/org.chromium.content_shell_apk-1.apk'): |
952 return | 981 return |
953 | 982 |
954 log_callback("uninstalling apk") | 983 log_callback('uninstalling apk') |
955 self._android_commands.run(['uninstall', self._driver_details.package_na
me()]) | 984 self._android_commands.run(['uninstall', self._driver_details.package_na
me()]) |
956 driver_host_path = self._port._path_to_driver() | 985 driver_host_path = self._port._path_to_driver() |
957 log_callback("installing apk") | 986 log_callback('installing apk') |
958 install_result = self._android_commands.run(['install', driver_host_path
]) | 987 install_result = self._android_commands.run(['install', driver_host_path
]) |
959 if install_result.find('Success') == -1: | 988 if install_result.find('Success') == -1: |
960 self._abort('Failed to install %s onto device: %s' % (driver_host_pa
th, install_result)) | 989 self._abort('Failed to install %s onto device: %s' % (driver_host_pa
th, install_result)) |
961 | 990 |
962 def _push_fonts(self, log_callback): | 991 def _push_fonts(self, log_callback): |
963 path_to_ahem_font = self._port._build_path('AHEM____.TTF') | 992 path_to_ahem_font = self._port._build_path('AHEM____.TTF') |
964 self._push_file_if_needed(path_to_ahem_font, self._driver_details.device
_fonts_directory() + 'AHEM____.TTF', log_callback) | 993 self._push_file_if_needed(path_to_ahem_font, self._driver_details.device
_fonts_directory() + 'AHEM____.TTF', log_callback) |
965 for (host_dirs, font_file, package) in HOST_FONT_FILES: | 994 for (host_dirs, font_file, package) in HOST_FONT_FILES: |
966 for host_dir in host_dirs: | 995 for host_dir in host_dirs: |
967 host_font_path = host_dir + font_file | 996 host_font_path = host_dir + font_file |
968 if self._port._check_file_exists(host_font_path, '', logging=Fal
se): | 997 if self._port._check_file_exists(host_font_path, '', logging=Fal
se): |
969 self._push_file_if_needed(host_font_path, self._driver_detai
ls.device_fonts_directory() + font_file, log_callback) | 998 self._push_file_if_needed( |
| 999 host_font_path, |
| 1000 self._driver_details.device_fonts_directory() + |
| 1001 font_file, |
| 1002 log_callback) |
970 | 1003 |
971 def _push_test_resources(self, log_callback): | 1004 def _push_test_resources(self, log_callback): |
972 for resource in TEST_RESOURCES_TO_PUSH: | 1005 for resource in TEST_RESOURCES_TO_PUSH: |
973 self._push_file_if_needed(self._port.layout_tests_dir() + '/' + reso
urce, DEVICE_LAYOUT_TESTS_DIR + resource, log_callback) | 1006 self._push_file_if_needed( |
| 1007 self._port.layout_tests_dir() + |
| 1008 '/' + |
| 1009 resource, |
| 1010 DEVICE_LAYOUT_TESTS_DIR + |
| 1011 resource, |
| 1012 log_callback) |
974 | 1013 |
975 def _get_last_stacktrace(self): | 1014 def _get_last_stacktrace(self): |
976 tombstones = self._android_commands.run(['shell', 'ls', '-n', '/data/tom
bstones/tombstone_*']) | 1015 tombstones = self._android_commands.run(['shell', 'ls', '-n', '/data/tom
bstones/tombstone_*']) |
977 if not tombstones or tombstones.startswith('/data/tombstones/tombstone_*
: No such file or directory'): | 1016 if not tombstones or tombstones.startswith('/data/tombstones/tombstone_*
: No such file or directory'): |
978 self._log_error('The driver crashed, but no tombstone found!') | 1017 self._log_error('The driver crashed, but no tombstone found!') |
979 return '' | 1018 return '' |
980 | 1019 |
981 if tombstones.startswith('/data/tombstones/tombstone_*: Permission denie
d'): | 1020 if tombstones.startswith('/data/tombstones/tombstone_*: Permission denie
d'): |
982 # FIXME: crbug.com/321489 ... figure out why this happens. | 1021 # FIXME: crbug.com/321489 ... figure out why this happens. |
983 self._log_error('The driver crashed, but we could not read the tombs
tones!') | 1022 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... |
1031 if not stdout: | 1070 if not stdout: |
1032 stdout = '' | 1071 stdout = '' |
1033 stdout += '********* [%s] Logcat:\n%s' % (self._android_commands.get_ser
ial(), self._get_logcat()) | 1072 stdout += '********* [%s] Logcat:\n%s' % (self._android_commands.get_ser
ial(), self._get_logcat()) |
1034 if not stderr: | 1073 if not stderr: |
1035 stderr = '' | 1074 stderr = '' |
1036 stderr += '********* [%s] Tombstone file:\n%s' % (self._android_commands
.get_serial(), self._get_last_stacktrace()) | 1075 stderr += '********* [%s] Tombstone file:\n%s' % (self._android_commands
.get_serial(), self._get_last_stacktrace()) |
1037 | 1076 |
1038 if not self._port.get_option('disable_breakpad'): | 1077 if not self._port.get_option('disable_breakpad'): |
1039 crashes = self._pull_crash_dumps_from_device() | 1078 crashes = self._pull_crash_dumps_from_device() |
1040 for crash in crashes: | 1079 for crash in crashes: |
1041 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)) | 1080 stderr += '********* [%s] breakpad minidump %s:\n%s' % (self._po
rt.host.filesystem.basename( |
| 1081 crash), self._android_commands.get_serial(), self._port._dum
p_reader._get_stack_from_dump(crash)) |
1042 | 1082 |
1043 return super(ChromiumAndroidDriver, self)._get_crash_log(stdout, stderr,
newer_than) | 1083 return super(ChromiumAndroidDriver, self)._get_crash_log(stdout, stderr,
newer_than) |
1044 | 1084 |
1045 def cmd_line(self, pixel_tests, per_test_args): | 1085 def cmd_line(self, pixel_tests, per_test_args): |
1046 # The returned command line is used to start _server_process. In our cas
e, it's an interactive 'adb shell'. | 1086 # The returned command line is used to start _server_process. In our cas
e, it's an interactive 'adb shell'. |
1047 # The command line passed to the driver process is returned by _driver_c
md_line() instead. | 1087 # The command line passed to the driver process is returned by _driver_c
md_line() instead. |
1048 return self._android_commands.adb_command() + ['shell'] | 1088 return self._android_commands.adb_command() + ['shell'] |
1049 | 1089 |
1050 def _android_driver_cmd_line(self, pixel_tests, per_test_args): | 1090 def _android_driver_cmd_line(self, pixel_tests, per_test_args): |
1051 return driver.Driver.cmd_line(self, pixel_tests, per_test_args) | 1091 return driver.Driver.cmd_line(self, pixel_tests, per_test_args) |
(...skipping 29 matching lines...) Expand all Loading... |
1081 if self._current_cmd_line is None: | 1121 if self._current_cmd_line is None: |
1082 self._current_android_cmd_line = None | 1122 self._current_android_cmd_line = None |
1083 if new_cmd_line != self._current_android_cmd_line: | 1123 if new_cmd_line != self._current_android_cmd_line: |
1084 self.stop() | 1124 self.stop() |
1085 self._current_android_cmd_line = new_cmd_line | 1125 self._current_android_cmd_line = new_cmd_line |
1086 | 1126 |
1087 super(ChromiumAndroidDriver, self).start(pixel_tests, per_test_args, dea
dline) | 1127 super(ChromiumAndroidDriver, self).start(pixel_tests, per_test_args, dea
dline) |
1088 | 1128 |
1089 def _start(self, pixel_tests, per_test_args): | 1129 def _start(self, pixel_tests, per_test_args): |
1090 if not self._android_devices.is_device_prepared(self._android_commands.g
et_serial()): | 1130 if not self._android_devices.is_device_prepared(self._android_commands.g
et_serial()): |
1091 raise driver.DeviceFailure("%s is not prepared in _start()" % self._
android_commands.get_serial()) | 1131 raise driver.DeviceFailure('%s is not prepared in _start()' % self._
android_commands.get_serial()) |
1092 | 1132 |
1093 for retries in range(3): | 1133 for retries in range(3): |
1094 try: | 1134 try: |
1095 if self._start_once(pixel_tests, per_test_args): | 1135 if self._start_once(pixel_tests, per_test_args): |
1096 return | 1136 return |
1097 except ScriptError as e: | 1137 except ScriptError as e: |
1098 self._abort('ScriptError("%s") in _start()' % str(e)) | 1138 self._abort('ScriptError("%s") in _start()' % str(e)) |
1099 | 1139 |
1100 self._log_error('Failed to start the content_shell application. Retr
ies=%d. Log:%s' % (retries, self._get_logcat())) | 1140 self._log_error('Failed to start the content_shell application. Retr
ies=%d. Log:%s' % (retries, self._get_logcat())) |
1101 self.stop() | 1141 self.stop() |
1102 time.sleep(2) | 1142 time.sleep(2) |
1103 self._abort('Failed to start the content_shell application multiple time
s. Giving up.') | 1143 self._abort('Failed to start the content_shell application multiple time
s. Giving up.') |
1104 | 1144 |
1105 def _start_once(self, pixel_tests, per_test_args): | 1145 def _start_once(self, pixel_tests, per_test_args): |
1106 super(ChromiumAndroidDriver, self)._start(pixel_tests, per_test_args, wa
it_for_ready=False) | 1146 super(ChromiumAndroidDriver, self)._start(pixel_tests, per_test_args, wa
it_for_ready=False) |
1107 | 1147 |
1108 self._log_debug('Starting forwarder') | 1148 self._log_debug('Starting forwarder') |
1109 self._forwarder_process = self._port._server_process_constructor( | 1149 self._forwarder_process = self._port._server_process_constructor( |
1110 self._port, 'Forwarder', self._android_commands.adb_command() + ['sh
ell', '%s -D %s' % (self._driver_details.device_forwarder_path(), FORWARD_PORTS)
]) | 1150 self._port, 'Forwarder', self._android_commands.adb_command() + ['sh
ell', '%s -D %s' % (self._driver_details.device_forwarder_path(), FORWARD_PORTS)
]) |
1111 self._forwarder_process.start() | 1151 self._forwarder_process.start() |
1112 | 1152 |
1113 deadline = time.time() + DRIVER_START_STOP_TIMEOUT_SECS | 1153 deadline = time.time() + DRIVER_START_STOP_TIMEOUT_SECS |
1114 if not self._wait_for_server_process_output(self._forwarder_process, dea
dline, 'Forwarding device port'): | 1154 if not self._wait_for_server_process_output(self._forwarder_process, dea
dline, 'Forwarding device port'): |
1115 return False | 1155 return False |
1116 | 1156 |
1117 self._android_commands.run(['logcat', '-c']) | 1157 self._android_commands.run(['logcat', '-c']) |
1118 | 1158 |
1119 cmd_line_file_path = self._driver_details.command_line_file() | 1159 cmd_line_file_path = self._driver_details.command_line_file() |
1120 original_cmd_line_file_path = cmd_line_file_path + '.orig' | 1160 original_cmd_line_file_path = cmd_line_file_path + '.orig' |
1121 if self._android_commands.file_exists(cmd_line_file_path) and not self._
android_commands.file_exists(original_cmd_line_file_path): | 1161 if self._android_commands.file_exists( |
| 1162 cmd_line_file_path) and not self._android_commands.file_exists(o
riginal_cmd_line_file_path): |
1122 # We check for both the normal path and the backup because we do not
want to step | 1163 # We check for both the normal path and the backup because we do not
want to step |
1123 # on the backup. Otherwise, we'd clobber the backup whenever we chan
ged the | 1164 # on the backup. Otherwise, we'd clobber the backup whenever we chan
ged the |
1124 # command line during the run. | 1165 # command line during the run. |
1125 self._android_commands.run(['shell', 'mv', cmd_line_file_path, origi
nal_cmd_line_file_path]) | 1166 self._android_commands.run(['shell', 'mv', cmd_line_file_path, origi
nal_cmd_line_file_path]) |
1126 | 1167 |
1127 self._android_commands.run(['shell', 'echo'] + self._android_driver_cmd_
line(pixel_tests, per_test_args) + ['>', self._driver_details.command_line_file(
)]) | 1168 self._android_commands.run(['shell', 'echo'] + |
| 1169 self._android_driver_cmd_line(pixel_tests, pe
r_test_args) + |
| 1170 ['>', self._driver_details.command_line_file(
)]) |
1128 self._created_cmd_line = True | 1171 self._created_cmd_line = True |
1129 | 1172 |
1130 self._android_commands.run(['shell', 'rm', '-rf', self._driver_details.d
evice_crash_dumps_directory()]) | 1173 self._android_commands.run(['shell', 'rm', '-rf', self._driver_details.d
evice_crash_dumps_directory()]) |
1131 self._android_commands.mkdir(self._driver_details.device_crash_dumps_dir
ectory(), chmod='777') | 1174 self._android_commands.mkdir(self._driver_details.device_crash_dumps_dir
ectory(), chmod='777') |
1132 | 1175 |
1133 start_result = self._android_commands.run(['shell', 'am', 'start', '-e',
'RunInSubThread', '-n', self._driver_details.activity_name()]) | 1176 start_result = self._android_commands.run(['shell', |
| 1177 'am', |
| 1178 'start', |
| 1179 '-e', |
| 1180 'RunInSubThread', |
| 1181 '-n', |
| 1182 self._driver_details.activity
_name()]) |
1134 if start_result.find('Exception') != -1: | 1183 if start_result.find('Exception') != -1: |
1135 self._log_error('Failed to start the content_shell application. Exce
ption:\n' + start_result) | 1184 self._log_error('Failed to start the content_shell application. Exce
ption:\n' + start_result) |
1136 return False | 1185 return False |
1137 | 1186 |
1138 if not ChromiumAndroidDriver._loop_with_timeout(self._all_pipes_created,
DRIVER_START_STOP_TIMEOUT_SECS): | 1187 if not ChromiumAndroidDriver._loop_with_timeout(self._all_pipes_created,
DRIVER_START_STOP_TIMEOUT_SECS): |
1139 return False | 1188 return False |
1140 | 1189 |
1141 # Read back the shell prompt to ensure adb shell ready. | 1190 # Read back the shell prompt to ensure adb shell ready. |
1142 deadline = time.time() + DRIVER_START_STOP_TIMEOUT_SECS | 1191 deadline = time.time() + DRIVER_START_STOP_TIMEOUT_SECS |
1143 self._server_process.start() | 1192 self._server_process.start() |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1177 threading.Thread(name='DeadlockDetector', target=deadlock_detector, | 1226 threading.Thread(name='DeadlockDetector', target=deadlock_detector, |
1178 args=([self._server_process, self._read_stdout_process,
self._read_stderr_process], normal_startup_event)).start() | 1227 args=([self._server_process, self._read_stdout_process,
self._read_stderr_process], normal_startup_event)).start() |
1179 | 1228 |
1180 # The test driver might crash during startup or when the deadlock detect
or hits | 1229 # The test driver might crash during startup or when the deadlock detect
or hits |
1181 # a deadlock and kills the fifo reading/writing processes. | 1230 # a deadlock and kills the fifo reading/writing processes. |
1182 if not self._wait_for_server_process_output(self._server_process, deadli
ne, '#READY'): | 1231 if not self._wait_for_server_process_output(self._server_process, deadli
ne, '#READY'): |
1183 return False | 1232 return False |
1184 | 1233 |
1185 # Inform the deadlock detector that the startup is successful without de
adlock. | 1234 # Inform the deadlock detector that the startup is successful without de
adlock. |
1186 normal_startup_event.set() | 1235 normal_startup_event.set() |
1187 self._log_debug("content_shell is ready") | 1236 self._log_debug('content_shell is ready') |
1188 return True | 1237 return True |
1189 | 1238 |
1190 def _pid_from_android_ps_output(self, ps_output, package_name): | 1239 def _pid_from_android_ps_output(self, ps_output, package_name): |
1191 # ps output seems to be fixed width, we only care about the name and the
pid | 1240 # ps output seems to be fixed width, we only care about the name and the
pid |
1192 # u0_a72 21630 125 947920 59364 ffffffff 400beee4 S org.chromium.na
tive_test | 1241 # u0_a72 21630 125 947920 59364 ffffffff 400beee4 S org.chromium.na
tive_test |
1193 for line in ps_output.split('\n'): | 1242 for line in ps_output.split('\n'): |
1194 if line.find(self._driver_details.package_name()) != -1: | 1243 if line.find(self._driver_details.package_name()) != -1: |
1195 match = re.match(r'\S+\s+(\d+)', line) | 1244 match = re.match(r'\S+\s+(\d+)', line) |
1196 return int(match.group(1)) | 1245 return int(match.group(1)) |
1197 | 1246 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1268 return command | 1317 return command |
1269 | 1318 |
1270 def _read_prompt(self, deadline): | 1319 def _read_prompt(self, deadline): |
1271 last_char = '' | 1320 last_char = '' |
1272 while True: | 1321 while True: |
1273 current_char = self._server_process.read_stdout(deadline, 1) | 1322 current_char = self._server_process.read_stdout(deadline, 1) |
1274 if current_char == ' ': | 1323 if current_char == ' ': |
1275 if last_char in ('#', '$'): | 1324 if last_char in ('#', '$'): |
1276 return | 1325 return |
1277 last_char = current_char | 1326 last_char = current_char |
OLD | NEW |