Chromium Code Reviews| 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 logging | 5 import logging |
| 6 import os | 6 import os |
| 7 import posixpath | 7 import posixpath |
| 8 import re | 8 import re |
| 9 import time | 9 import time |
| 10 | 10 |
| 11 from devil.android import device_errors | 11 from devil.android import device_errors |
| 12 from devil.android import flag_changer | 12 from devil.android import flag_changer |
| 13 from devil.android.sdk import shared_prefs | 13 from devil.android.sdk import shared_prefs |
| 14 from devil.utils import reraiser_thread | 14 from devil.utils import reraiser_thread |
| 15 from pylib import valgrind_tools | 15 from pylib import valgrind_tools |
| 16 from pylib.android import logdog_logcat_monitor | 16 from pylib.android import logdog_logcat_monitor |
| 17 from pylib.base import base_test_result | 17 from pylib.base import base_test_result |
| 18 from pylib.instrumentation import instrumentation_test_instance | 18 from pylib.instrumentation import instrumentation_test_instance |
| 19 from pylib.local.device import local_device_environment | 19 from pylib.local.device import local_device_environment |
| 20 from pylib.local.device import local_device_test_run | 20 from pylib.local.device import local_device_test_run |
| 21 from pylib.utils import google_storage_helper | |
| 21 from pylib.utils import logdog_helper | 22 from pylib.utils import logdog_helper |
| 22 from py_trace_event import trace_event | 23 from py_trace_event import trace_event |
| 23 from py_utils import contextlib_ext | 24 from py_utils import contextlib_ext |
| 25 from py_utils import tempfile_ext | |
| 24 import tombstones | 26 import tombstones |
| 25 | 27 |
| 26 _TAG = 'test_runner_py' | 28 _TAG = 'test_runner_py' |
| 27 | 29 |
| 28 TIMEOUT_ANNOTATIONS = [ | 30 TIMEOUT_ANNOTATIONS = [ |
| 29 ('Manual', 10 * 60 * 60), | 31 ('Manual', 10 * 60 * 60), |
| 30 ('IntegrationTest', 30 * 60), | 32 ('IntegrationTest', 30 * 60), |
| 31 ('External', 10 * 60), | 33 ('External', 10 * 60), |
| 32 ('EnormousTest', 10 * 60), | 34 ('EnormousTest', 10 * 60), |
| 33 ('LargeTest', 5 * 60), | 35 ('LargeTest', 5 * 60), |
| 34 ('MediumTest', 3 * 60), | 36 ('MediumTest', 3 * 60), |
| 35 ('SmallTest', 1 * 60), | 37 ('SmallTest', 1 * 60), |
| 36 ] | 38 ] |
| 37 | 39 |
| 38 LOGCAT_FILTERS = ['*:e', 'chromium:v', 'cr_*:v'] | 40 LOGCAT_FILTERS = ['*:e', 'chromium:v', 'cr_*:v'] |
| 39 | 41 |
| 42 | |
| 40 # TODO(jbudorick): Make this private once the instrumentation test_runner is | 43 # TODO(jbudorick): Make this private once the instrumentation test_runner is |
| 41 # deprecated. | 44 # deprecated. |
| 42 def DidPackageCrashOnDevice(package_name, device): | 45 def DidPackageCrashOnDevice(package_name, device): |
| 43 # Dismiss any error dialogs. Limit the number in case we have an error | 46 # Dismiss any error dialogs. Limit the number in case we have an error |
| 44 # loop or we are failing to dismiss. | 47 # loop or we are failing to dismiss. |
| 45 try: | 48 try: |
| 46 for _ in xrange(10): | 49 for _ in xrange(10): |
| 47 package = device.DismissCrashDialogIfNeeded() | 50 package = device.DismissCrashDialogIfNeeded() |
| 48 if not package: | 51 if not package: |
| 49 return False | 52 return False |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 370 if r.GetType() == base_test_result.ResultType.UNKNOWN: | 373 if r.GetType() == base_test_result.ResultType.UNKNOWN: |
| 371 r.SetType(base_test_result.ResultType.CRASH) | 374 r.SetType(base_test_result.ResultType.CRASH) |
| 372 | 375 |
| 373 # Handle failures by: | 376 # Handle failures by: |
| 374 # - optionally taking a screenshot | 377 # - optionally taking a screenshot |
| 375 # - logging the raw output at INFO level | 378 # - logging the raw output at INFO level |
| 376 # - clearing the application state while persisting permissions | 379 # - clearing the application state while persisting permissions |
| 377 if any(r.GetType() not in (base_test_result.ResultType.PASS, | 380 if any(r.GetType() not in (base_test_result.ResultType.PASS, |
| 378 base_test_result.ResultType.SKIP) | 381 base_test_result.ResultType.SKIP) |
| 379 for r in results): | 382 for r in results): |
| 380 if self._test_instance.screenshot_dir: | 383 with contextlib_ext.Optional( |
| 381 file_name = '%s-%s.png' % ( | 384 tempfile_ext.NamedTemporaryDirectory(), |
| 382 test_display_name, | 385 self._test_instance.screenshot_dir is None and |
| 383 time.strftime('%Y%m%dT%H%M%S', time.localtime())) | 386 self._test_instance.gs_results_bucket) as screenshot_dir: |
| 384 saved_dir = device.TakeScreenshot( | 387 screenshot_dir = self._test_instance.screenshot_dir or screenshot_dir |
|
the real yoland
2017/05/03 22:23:38
nit: screenshot_host_dir
mikecase (-- gone --)
2017/05/03 22:45:18
Done
| |
| 385 os.path.join(self._test_instance.screenshot_dir, file_name)) | 388 if screenshot_dir: |
| 386 logging.info( | 389 file_name = '%s-%s.png' % ( |
| 387 'Saved screenshot for %s to %s.', | 390 test_display_name, |
| 388 test_display_name, saved_dir) | 391 time.strftime('%Y%m%dT%H%M%S', time.localtime())) |
|
the real yoland
2017/05/03 22:23:38
same as below, should this just use UTC time?
mikecase (-- gone --)
2017/05/03 22:45:18
Done
| |
| 392 screenshot_file = device.TakeScreenshot( | |
| 393 os.path.join(screenshot_dir, file_name)) | |
| 394 logging.info( | |
| 395 'Saved screenshot for %s to %s.', | |
| 396 test_display_name, screenshot_file) | |
| 397 if self._test_instance.gs_results_bucket: | |
| 398 link = google_storage_helper.upload( | |
| 399 google_storage_helper.unique_name('screenshot', device=device), | |
| 400 screenshot_file, | |
| 401 bucket=self._test_instance.gs_results_bucket + '/screenshots') | |
| 402 for result in results: | |
| 403 result.SetLink('failure_screenshot', link) | |
| 404 | |
| 389 logging.info('detected failure in %s. raw output:', test_display_name) | 405 logging.info('detected failure in %s. raw output:', test_display_name) |
| 390 for l in output: | 406 for l in output: |
| 391 logging.info(' %s', l) | 407 logging.info(' %s', l) |
| 392 if (not self._env.skip_clear_data | 408 if (not self._env.skip_clear_data |
| 393 and self._test_instance.package_info): | 409 and self._test_instance.package_info): |
| 394 permissions = ( | 410 permissions = ( |
| 395 self._test_instance.apk_under_test.GetPermissions() | 411 self._test_instance.apk_under_test.GetPermissions() |
| 396 if self._test_instance.apk_under_test | 412 if self._test_instance.apk_under_test |
| 397 else None) | 413 else None) |
| 398 device.ClearApplicationState(self._test_instance.package_info.package, | 414 device.ClearApplicationState(self._test_instance.package_info.package, |
| 399 permissions=permissions) | 415 permissions=permissions) |
| 400 | |
| 401 else: | 416 else: |
| 402 logging.debug('raw output from %s:', test_display_name) | 417 logging.debug('raw output from %s:', test_display_name) |
| 403 for l in output: | 418 for l in output: |
| 404 logging.debug(' %s', l) | 419 logging.debug(' %s', l) |
| 405 if self._test_instance.coverage_directory: | 420 if self._test_instance.coverage_directory: |
| 406 device.PullFile(coverage_directory, | 421 device.PullFile(coverage_directory, |
| 407 self._test_instance.coverage_directory) | 422 self._test_instance.coverage_directory) |
| 408 device.RunShellCommand( | 423 device.RunShellCommand( |
| 409 'rm -f %s' % posixpath.join(coverage_directory, '*'), | 424 'rm -f %s' % posixpath.join(coverage_directory, '*'), |
| 410 check_return=True, shell=True) | 425 check_return=True, shell=True) |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 454 if k in annotations: | 469 if k in annotations: |
| 455 timeout = v | 470 timeout = v |
| 456 break | 471 break |
| 457 else: | 472 else: |
| 458 logging.warning('Using default 1 minute timeout for %s', test_name) | 473 logging.warning('Using default 1 minute timeout for %s', test_name) |
| 459 timeout = 60 | 474 timeout = 60 |
| 460 | 475 |
| 461 timeout *= cls._GetTimeoutScaleFromAnnotations(annotations) | 476 timeout *= cls._GetTimeoutScaleFromAnnotations(annotations) |
| 462 | 477 |
| 463 return timeout | 478 return timeout |
| OLD | NEW |