OLD | NEW |
1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import contextlib | 5 import contextlib |
| 6 import json |
6 import logging | 7 import logging |
7 import os | 8 import os |
8 import posixpath | 9 import posixpath |
9 import re | 10 import re |
10 import sys | 11 import sys |
11 import tempfile | 12 import tempfile |
12 import time | 13 import time |
13 | 14 |
14 from devil.android import crash_handler | 15 from devil.android import crash_handler |
15 from devil.android import device_errors | 16 from devil.android import device_errors |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 | 58 |
58 LOGCAT_FILTERS = ['*:e', 'chromium:v', 'cr_*:v', 'DEBUG:I', | 59 LOGCAT_FILTERS = ['*:e', 'chromium:v', 'cr_*:v', 'DEBUG:I', |
59 'StrictMode:D', '%s:I' % _TAG] | 60 'StrictMode:D', '%s:I' % _TAG] |
60 | 61 |
61 EXTRA_SCREENSHOT_FILE = ( | 62 EXTRA_SCREENSHOT_FILE = ( |
62 'org.chromium.base.test.ScreenshotOnFailureStatement.ScreenshotFile') | 63 'org.chromium.base.test.ScreenshotOnFailureStatement.ScreenshotFile') |
63 | 64 |
64 EXTRA_UI_CAPTURE_DIR = ( | 65 EXTRA_UI_CAPTURE_DIR = ( |
65 'org.chromium.base.test.util.Screenshooter.ScreenshotDir') | 66 'org.chromium.base.test.util.Screenshooter.ScreenshotDir') |
66 | 67 |
| 68 _EXTRA_TEST_LIST = ( |
| 69 'org.chromium.base.test.BaseChromiumAndroidJUnitRunner.TestList') |
| 70 |
67 UI_CAPTURE_DIRS = ['chromium_tests_root', 'UiCapture'] | 71 UI_CAPTURE_DIRS = ['chromium_tests_root', 'UiCapture'] |
68 | 72 |
69 FEATURE_ANNOTATION = 'Feature' | 73 FEATURE_ANNOTATION = 'Feature' |
70 RENDER_TEST_FEATURE_ANNOTATION = 'RenderTest' | 74 RENDER_TEST_FEATURE_ANNOTATION = 'RenderTest' |
71 | 75 |
72 # This needs to be kept in sync with formatting in |RenderUtils.imageName| | 76 # This needs to be kept in sync with formatting in |RenderUtils.imageName| |
73 RE_RENDER_IMAGE_NAME = re.compile( | 77 RE_RENDER_IMAGE_NAME = re.compile( |
74 r'(?P<test_class>\w+)\.' | 78 r'(?P<test_class>\w+)\.' |
75 r'(?P<description>[-\w]+)\.' | 79 r'(?P<description>[-\w]+)\.' |
76 r'(?P<device_model_sdk>[-\w]+)\.png') | 80 r'(?P<device_model_sdk>[-\w]+)\.png') |
77 | 81 |
78 @contextlib.contextmanager | 82 @contextlib.contextmanager |
79 def _LogTestEndpoints(device, test_name): | 83 def _LogTestEndpoints(device, test_name): |
80 device.RunShellCommand( | 84 device.RunShellCommand( |
81 ['log', '-p', 'i', '-t', _TAG, 'START %s' % test_name], | 85 ['log', '-p', 'i', '-t', _TAG, 'START %s' % test_name], |
82 check_return=True) | 86 check_return=True) |
83 try: | 87 try: |
84 yield | 88 yield |
85 finally: | 89 finally: |
86 device.RunShellCommand( | 90 device.RunShellCommand( |
87 ['log', '-p', 'i', '-t', _TAG, 'END %s' % test_name], | 91 ['log', '-p', 'i', '-t', _TAG, 'END %s' % test_name], |
88 check_return=True) | 92 check_return=True) |
89 | 93 |
90 # TODO(jbudorick): Make this private once the instrumentation test_runner is | 94 # TODO(jbudorick): Make this private once the instrumentation test_runner |
91 # deprecated. | 95 # is deprecated. |
92 def DidPackageCrashOnDevice(package_name, device): | 96 def DidPackageCrashOnDevice(package_name, device): |
93 # Dismiss any error dialogs. Limit the number in case we have an error | 97 # Dismiss any error dialogs. Limit the number in case we have an error |
94 # loop or we are failing to dismiss. | 98 # loop or we are failing to dismiss. |
95 try: | 99 try: |
96 for _ in xrange(10): | 100 for _ in xrange(10): |
97 package = device.DismissCrashDialogIfNeeded() | 101 package = device.DismissCrashDialogIfNeeded() |
98 if not package: | 102 if not package: |
99 return False | 103 return False |
100 # Assume test package convention of ".test" suffix | 104 # Assume test package convention of ".test" suffix |
101 if package in package_name: | 105 if package in package_name: |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 if not str(device) in self._flag_changers: | 302 if not str(device) in self._flag_changers: |
299 self._flag_changers[str(device)] = flag_changer.FlagChanger( | 303 self._flag_changers[str(device)] = flag_changer.FlagChanger( |
300 device, self._test_instance.package_info.cmdline_file) | 304 device, self._test_instance.package_info.cmdline_file) |
301 | 305 |
302 #override | 306 #override |
303 def _CreateShards(self, tests): | 307 def _CreateShards(self, tests): |
304 return tests | 308 return tests |
305 | 309 |
306 #override | 310 #override |
307 def _GetTests(self): | 311 def _GetTests(self): |
308 tests = self._test_instance.GetTests() | 312 tests = None |
| 313 if self._test_instance.junit4_runner_class: |
| 314 raw_tests = self._GetTestsFromRunner() |
| 315 tests = self._test_instance.ProcessRawTests(raw_tests) |
| 316 else: |
| 317 tests = self._test_instance.GetTests() |
309 tests = self._ApplyExternalSharding( | 318 tests = self._ApplyExternalSharding( |
310 tests, self._test_instance.external_shard_index, | 319 tests, self._test_instance.external_shard_index, |
311 self._test_instance.total_external_shards) | 320 self._test_instance.total_external_shards) |
312 return tests | 321 return tests |
313 | 322 |
314 #override | 323 #override |
315 def _GetUniqueTestName(self, test): | 324 def _GetUniqueTestName(self, test): |
316 return instrumentation_test_instance.GetUniqueTestName(test) | 325 return instrumentation_test_instance.GetUniqueTestName(test) |
317 | 326 |
318 #override | 327 #override |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 extras.update( | 372 extras.update( |
364 self._test_instance.GetDriverEnvironmentVars( | 373 self._test_instance.GetDriverEnvironmentVars( |
365 test_list=test_names)) | 374 test_list=test_names)) |
366 timeout = sum(timeouts) | 375 timeout = sum(timeouts) |
367 else: | 376 else: |
368 test_name = instrumentation_test_instance.GetTestName(test) | 377 test_name = instrumentation_test_instance.GetTestName(test) |
369 test_display_name = self._GetUniqueTestName(test) | 378 test_display_name = self._GetUniqueTestName(test) |
370 if test['is_junit4']: | 379 if test['is_junit4']: |
371 target = '%s/%s' % ( | 380 target = '%s/%s' % ( |
372 self._test_instance.test_package, | 381 self._test_instance.test_package, |
373 self._test_instance.test_runner_junit4) | 382 self._test_instance.junit4_runner_class) |
374 else: | 383 else: |
375 target = '%s/%s' % ( | 384 target = '%s/%s' % ( |
376 self._test_instance.test_package, self._test_instance.test_runner) | 385 self._test_instance.test_package, |
| 386 self._test_instance.junit3_runner_class) |
377 extras['class'] = test_name | 387 extras['class'] = test_name |
378 if 'flags' in test and test['flags']: | 388 if 'flags' in test and test['flags']: |
379 flags_to_add.extend(test['flags']) | 389 flags_to_add.extend(test['flags']) |
380 timeout = self._GetTimeoutFromAnnotations( | 390 timeout = self._GetTimeoutFromAnnotations( |
381 test['annotations'], test_display_name) | 391 test['annotations'], test_display_name) |
382 | 392 |
383 test_timeout_scale = self._GetTimeoutScaleFromAnnotations( | 393 test_timeout_scale = self._GetTimeoutScaleFromAnnotations( |
384 test['annotations']) | 394 test['annotations']) |
385 if test_timeout_scale and test_timeout_scale != 1: | 395 if test_timeout_scale and test_timeout_scale != 1: |
386 valgrind_tools.SetChromeTimeoutScale( | 396 valgrind_tools.SetChromeTimeoutScale( |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 time.strftime('%Y%m%dT%H%M%S-UTC', time.gmtime()), | 553 time.strftime('%Y%m%dT%H%M%S-UTC', time.gmtime()), |
544 device.serial) | 554 device.serial) |
545 tombstones_url = logdog_helper.text( | 555 tombstones_url = logdog_helper.text( |
546 stream_name, '\n'.join(resolved_tombstones)) | 556 stream_name, '\n'.join(resolved_tombstones)) |
547 result.SetLink('tombstones', tombstones_url) | 557 result.SetLink('tombstones', tombstones_url) |
548 | 558 |
549 if self._env.concurrent_adb: | 559 if self._env.concurrent_adb: |
550 post_test_step_thread_group.JoinAll() | 560 post_test_step_thread_group.JoinAll() |
551 return results, None | 561 return results, None |
552 | 562 |
| 563 def _GetTestsFromRunner(self): |
| 564 test_apk_path = self._test_instance.test_apk.path |
| 565 pickle_path = '%s-runner.pickle' % test_apk_path |
| 566 try: |
| 567 return instrumentation_test_instance.GetTestsFromPickle( |
| 568 pickle_path, test_apk_path) |
| 569 except instrumentation_test_instance.TestListPickleException as e: |
| 570 logging.info('Could not get tests from pickle: %s', e) |
| 571 logging.info('Getting tests by having %s list them.', |
| 572 self._test_instance.junit4_runner_class) |
| 573 def list_tests(dev): |
| 574 with device_temp_file.DeviceTempFile( |
| 575 dev.adb, suffix='.json', |
| 576 dir=dev.GetExternalStoragePath()) as dev_test_list_json: |
| 577 junit4_runner_class = self._test_instance.junit4_runner_class |
| 578 test_package = self._test_instance.test_package |
| 579 extras = {} |
| 580 extras['log'] = 'true' |
| 581 extras['package'] = '.'.join(test_package.split('.')[:2]) |
| 582 extras[_EXTRA_TEST_LIST] = dev_test_list_json.name |
| 583 target = '%s/%s' % (test_package, junit4_runner_class) |
| 584 output_string = ''.join(dev.StartInstrumentation( |
| 585 target, extras=extras)) |
| 586 if output_string: |
| 587 error_message = ( |
| 588 'List test through {} failed on dev:{} Are you using {}'.format( |
| 589 junit4_runner_class, output_string, |
| 590 'org.chromium.base.test.BaseChromiumAndroidJUnitRunner')) |
| 591 raise device_errors.CommandFailedError(error_message, dev.serial) |
| 592 with tempfile_ext.NamedTemporaryDirectory() as host_dir: |
| 593 host_file = os.path.join(host_dir, 'list_tests.json') |
| 594 dev.PullFile(dev_test_list_json.name, host_file) |
| 595 with open(host_file, 'r') as host_file: |
| 596 return json.load(host_file) |
| 597 |
| 598 raw_test_lists = self._env.parallel_devices.pMap(list_tests).pGet(None) |
| 599 |
| 600 # If all devices failed to list tests, raise an exception. |
| 601 # Check that tl is not None and is not empty. |
| 602 if all(not tl for tl in raw_test_lists): |
| 603 raise device_errors.CommandFailedError( |
| 604 'Failed to list tests on any device') |
| 605 |
| 606 # Get the first viable list of raw tests |
| 607 raw_tests = [tl for tl in raw_test_lists if tl][0] |
| 608 |
| 609 instrumentation_test_instance.SaveTestsToPickle( |
| 610 pickle_path, test_apk_path, raw_tests) |
| 611 return raw_tests |
| 612 |
553 def _SaveScreenshot(self, device, screenshot_host_dir, screenshot_device_file, | 613 def _SaveScreenshot(self, device, screenshot_host_dir, screenshot_device_file, |
554 test_name, results): | 614 test_name, results): |
555 if screenshot_host_dir: | 615 if screenshot_host_dir: |
556 screenshot_host_file = os.path.join( | 616 screenshot_host_file = os.path.join( |
557 screenshot_host_dir, | 617 screenshot_host_dir, |
558 '%s-%s.png' % ( | 618 '%s-%s.png' % ( |
559 test_name, | 619 test_name, |
560 time.strftime('%Y%m%dT%H%M%S-UTC', time.gmtime()))) | 620 time.strftime('%Y%m%dT%H%M%S-UTC', time.gmtime()))) |
561 if device.FileExists(screenshot_device_file.name): | 621 if device.FileExists(screenshot_device_file.name): |
562 try: | 622 try: |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
712 timeout *= cls._GetTimeoutScaleFromAnnotations(annotations) | 772 timeout *= cls._GetTimeoutScaleFromAnnotations(annotations) |
713 | 773 |
714 return timeout | 774 return timeout |
715 | 775 |
716 def _IsRenderTest(test): | 776 def _IsRenderTest(test): |
717 """Determines if a test or list of tests has a RenderTest amongst them.""" | 777 """Determines if a test or list of tests has a RenderTest amongst them.""" |
718 if not isinstance(test, list): | 778 if not isinstance(test, list): |
719 test = [test] | 779 test = [test] |
720 return any([RENDER_TEST_FEATURE_ANNOTATION in t['annotations'].get( | 780 return any([RENDER_TEST_FEATURE_ANNOTATION in t['annotations'].get( |
721 FEATURE_ANNOTATION, {}).get('value', ()) for t in test]) | 781 FEATURE_ANNOTATION, {}).get('value', ()) for t in test]) |
OLD | NEW |