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 logging | 6 import logging |
6 import os | 7 import os |
7 import posixpath | 8 import posixpath |
8 import re | 9 import re |
9 import tempfile | 10 import tempfile |
10 import time | 11 import time |
11 | 12 |
12 from devil.android import device_errors | 13 from devil.android import device_errors |
13 from devil.android import device_temp_file | 14 from devil.android import device_temp_file |
14 from devil.android import flag_changer | 15 from devil.android import flag_changer |
(...skipping 28 matching lines...) Expand all Loading... |
43 TIMEOUT_ANNOTATIONS = [ | 44 TIMEOUT_ANNOTATIONS = [ |
44 ('Manual', 10 * 60 * 60), | 45 ('Manual', 10 * 60 * 60), |
45 ('IntegrationTest', 30 * 60), | 46 ('IntegrationTest', 30 * 60), |
46 ('External', 10 * 60), | 47 ('External', 10 * 60), |
47 ('EnormousTest', 10 * 60), | 48 ('EnormousTest', 10 * 60), |
48 ('LargeTest', 5 * 60), | 49 ('LargeTest', 5 * 60), |
49 ('MediumTest', 3 * 60), | 50 ('MediumTest', 3 * 60), |
50 ('SmallTest', 1 * 60), | 51 ('SmallTest', 1 * 60), |
51 ] | 52 ] |
52 | 53 |
53 LOGCAT_FILTERS = ['*:e', 'chromium:v', 'cr_*:v', 'DEBUG:I'] | 54 LOGCAT_FILTERS = ['*:e', 'chromium:v', 'cr_*:v', 'DEBUG:I', |
| 55 'StrictMode:D', '%s:I' % _TAG] |
54 | 56 |
55 EXTRA_SCREENSHOT_FILE = ( | 57 EXTRA_SCREENSHOT_FILE = ( |
56 'org.chromium.base.test.ScreenshotOnFailureStatement.ScreenshotFile') | 58 'org.chromium.base.test.ScreenshotOnFailureStatement.ScreenshotFile') |
57 | 59 |
58 FEATURE_ANNOTATION = 'Feature' | 60 FEATURE_ANNOTATION = 'Feature' |
59 RENDER_TEST_FEATURE_ANNOTATION = 'RenderTest' | 61 RENDER_TEST_FEATURE_ANNOTATION = 'RenderTest' |
60 | 62 |
61 # This needs to be kept in sync with formatting in |RenderUtils.imageName| | 63 # This needs to be kept in sync with formatting in |RenderUtils.imageName| |
62 RE_RENDER_IMAGE_NAME = re.compile( | 64 RE_RENDER_IMAGE_NAME = re.compile( |
63 r'(?P<test_class>\w+)\.' | 65 r'(?P<test_class>\w+)\.' |
64 r'(?P<description>\w+)\.' | 66 r'(?P<description>\w+)\.' |
65 r'(?P<device_model>\w+)\.' | 67 r'(?P<device_model>\w+)\.' |
66 r'(?P<orientation>port|land)\.png') | 68 r'(?P<orientation>port|land)\.png') |
67 | 69 |
| 70 @contextlib.contextmanager |
| 71 def _LogTestEndpoints(device, test_name): |
| 72 device.RunShellCommand( |
| 73 ['log', '-p', 'i', '-t', _TAG, 'START %s' % test_name], |
| 74 check_return=True) |
| 75 try: |
| 76 yield |
| 77 finally: |
| 78 device.RunShellCommand( |
| 79 ['log', '-p', 'i', '-t', _TAG, 'END %s' % test_name], |
| 80 check_return=True) |
| 81 |
68 # TODO(jbudorick): Make this private once the instrumentation test_runner is | 82 # TODO(jbudorick): Make this private once the instrumentation test_runner is |
69 # deprecated. | 83 # deprecated. |
70 def DidPackageCrashOnDevice(package_name, device): | 84 def DidPackageCrashOnDevice(package_name, device): |
71 # Dismiss any error dialogs. Limit the number in case we have an error | 85 # Dismiss any error dialogs. Limit the number in case we have an error |
72 # loop or we are failing to dismiss. | 86 # loop or we are failing to dismiss. |
73 try: | 87 try: |
74 for _ in xrange(10): | 88 for _ in xrange(10): |
75 package = device.DismissCrashDialogIfNeeded() | 89 package = device.DismissCrashDialogIfNeeded() |
76 if not package: | 90 if not package: |
77 return False | 91 return False |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 device.GetExternalStoragePath(), | 361 device.GetExternalStoragePath(), |
348 'render_test_output_dir') | 362 'render_test_output_dir') |
349 flags_to_add.append('--render-test-output-dir=%s' % | 363 flags_to_add.append('--render-test-output-dir=%s' % |
350 render_tests_device_output_dir) | 364 render_tests_device_output_dir) |
351 | 365 |
352 if flags_to_add or flags_to_remove: | 366 if flags_to_add or flags_to_remove: |
353 self._CreateFlagChangerIfNeeded(device) | 367 self._CreateFlagChangerIfNeeded(device) |
354 self._flag_changers[str(device)].PushFlags( | 368 self._flag_changers[str(device)].PushFlags( |
355 add=flags_to_add, remove=flags_to_remove) | 369 add=flags_to_add, remove=flags_to_remove) |
356 | 370 |
357 try: | 371 time_ms = lambda: int(time.time() * 1e3) |
358 device.RunShellCommand( | 372 start_ms = time_ms() |
359 ['log', '-p', 'i', '-t', _TAG, 'START %s' % test_name], | |
360 check_return=True) | |
361 time_ms = lambda: int(time.time() * 1e3) | |
362 start_ms = time_ms() | |
363 | 373 |
364 stream_name = 'logcat_%s_%s_%s' % ( | 374 stream_name = 'logcat_%s_%s_%s' % ( |
365 test_name.replace('#', '.'), | 375 test_name.replace('#', '.'), |
366 time.strftime('%Y%m%dT%H%M%S-UTC', time.gmtime()), | 376 time.strftime('%Y%m%dT%H%M%S-UTC', time.gmtime()), |
367 device.serial) | 377 device.serial) |
368 logmon = logdog_logcat_monitor.LogdogLogcatMonitor( | 378 logmon = logdog_logcat_monitor.LogdogLogcatMonitor( |
369 device.adb, stream_name, filter_specs=LOGCAT_FILTERS) | 379 device.adb, stream_name, filter_specs=LOGCAT_FILTERS) |
370 | 380 |
371 with contextlib_ext.Optional( | 381 with contextlib_ext.Optional( |
372 logmon, self._test_instance.should_save_logcat): | 382 logmon, self._test_instance.should_save_logcat): |
| 383 with _LogTestEndpoints(device, test_name): |
373 with contextlib_ext.Optional( | 384 with contextlib_ext.Optional( |
374 trace_event.trace(test_name), | 385 trace_event.trace(test_name), |
375 self._env.trace_output): | 386 self._env.trace_output): |
376 output = device.StartInstrumentation( | 387 output = device.StartInstrumentation( |
377 target, raw=True, extras=extras, timeout=timeout, retries=0) | 388 target, raw=True, extras=extras, timeout=timeout, retries=0) |
378 logcat_url = logmon.GetLogcatURL() | 389 |
379 finally: | 390 logcat_url = logmon.GetLogcatURL() |
380 device.RunShellCommand( | 391 duration_ms = time_ms() - start_ms |
381 ['log', '-p', 'i', '-t', _TAG, 'END %s' % test_name], | 392 if flags_to_add or flags_to_remove: |
382 check_return=True) | 393 self._flag_changers[str(device)].Restore() |
383 duration_ms = time_ms() - start_ms | 394 if test_timeout_scale: |
384 if flags_to_add or flags_to_remove: | 395 valgrind_tools.SetChromeTimeoutScale( |
385 self._flag_changers[str(device)].Restore() | 396 device, self._test_instance.timeout_scale) |
386 if test_timeout_scale: | |
387 valgrind_tools.SetChromeTimeoutScale( | |
388 device, self._test_instance.timeout_scale) | |
389 | 397 |
390 # TODO(jbudorick): Make instrumentation tests output a JSON so this | 398 # TODO(jbudorick): Make instrumentation tests output a JSON so this |
391 # doesn't have to parse the output. | 399 # doesn't have to parse the output. |
392 result_code, result_bundle, statuses = ( | 400 result_code, result_bundle, statuses = ( |
393 self._test_instance.ParseAmInstrumentRawOutput(output)) | 401 self._test_instance.ParseAmInstrumentRawOutput(output)) |
394 results = self._test_instance.GenerateTestResults( | 402 results = self._test_instance.GenerateTestResults( |
395 result_code, result_bundle, statuses, start_ms, duration_ms) | 403 result_code, result_bundle, statuses, start_ms, duration_ms) |
396 for result in results: | 404 for result in results: |
397 if logcat_url: | 405 if logcat_url: |
398 result.SetLink('logcat', logcat_url) | 406 result.SetLink('logcat', logcat_url) |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
646 timeout *= cls._GetTimeoutScaleFromAnnotations(annotations) | 654 timeout *= cls._GetTimeoutScaleFromAnnotations(annotations) |
647 | 655 |
648 return timeout | 656 return timeout |
649 | 657 |
650 def _IsRenderTest(test): | 658 def _IsRenderTest(test): |
651 """Determines if a test or list of tests has a RenderTest amongst them.""" | 659 """Determines if a test or list of tests has a RenderTest amongst them.""" |
652 if not isinstance(test, list): | 660 if not isinstance(test, list): |
653 test = [test] | 661 test = [test] |
654 return any([RENDER_TEST_FEATURE_ANNOTATION in t['annotations'].get( | 662 return any([RENDER_TEST_FEATURE_ANNOTATION in t['annotations'].get( |
655 FEATURE_ANNOTATION, {}).get('value', ()) for t in test]) | 663 FEATURE_ANNOTATION, {}).get('value', ()) for t in test]) |
OLD | NEW |