Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(296)

Side by Side Diff: build/android/pylib/local/device/local_device_instrumentation_test_run.py

Issue 2854823007: Move screenshot capture to Java-side. (Closed)
Patch Set: Yoland's comments Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/test/android/javatests/src/org/chromium/base/test/ScreenshotOnFailureStatement.java ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 device_temp_file
12 from devil.android import flag_changer 13 from devil.android import flag_changer
13 from devil.android.sdk import shared_prefs 14 from devil.android.sdk import shared_prefs
14 from devil.utils import reraiser_thread 15 from devil.utils import reraiser_thread
15 from pylib import valgrind_tools 16 from pylib import valgrind_tools
16 from pylib.android import logdog_logcat_monitor 17 from pylib.android import logdog_logcat_monitor
17 from pylib.base import base_test_result 18 from pylib.base import base_test_result
18 from pylib.instrumentation import instrumentation_test_instance 19 from pylib.instrumentation import instrumentation_test_instance
19 from pylib.local.device import local_device_environment 20 from pylib.local.device import local_device_environment
20 from pylib.local.device import local_device_test_run 21 from pylib.local.device import local_device_test_run
21 from pylib.utils import google_storage_helper 22 from pylib.utils import google_storage_helper
(...skipping 10 matching lines...) Expand all
32 ('IntegrationTest', 30 * 60), 33 ('IntegrationTest', 30 * 60),
33 ('External', 10 * 60), 34 ('External', 10 * 60),
34 ('EnormousTest', 10 * 60), 35 ('EnormousTest', 10 * 60),
35 ('LargeTest', 5 * 60), 36 ('LargeTest', 5 * 60),
36 ('MediumTest', 3 * 60), 37 ('MediumTest', 3 * 60),
37 ('SmallTest', 1 * 60), 38 ('SmallTest', 1 * 60),
38 ] 39 ]
39 40
40 LOGCAT_FILTERS = ['*:e', 'chromium:v', 'cr_*:v'] 41 LOGCAT_FILTERS = ['*:e', 'chromium:v', 'cr_*:v']
41 42
43 EXTRA_SCREENSHOT_FILE = (
44 'org.chromium.base.test.ScreenshotOnFailureStatement.ScreenshotFile')
42 45
43 # TODO(jbudorick): Make this private once the instrumentation test_runner is 46 # TODO(jbudorick): Make this private once the instrumentation test_runner is
44 # deprecated. 47 # deprecated.
45 def DidPackageCrashOnDevice(package_name, device): 48 def DidPackageCrashOnDevice(package_name, device):
46 # Dismiss any error dialogs. Limit the number in case we have an error 49 # Dismiss any error dialogs. Limit the number in case we have an error
47 # loop or we are failing to dismiss. 50 # loop or we are failing to dismiss.
48 try: 51 try:
49 for _ in xrange(10): 52 for _ in xrange(10):
50 package = device.DismissCrashDialogIfNeeded() 53 package = device.DismissCrashDialogIfNeeded()
51 if not package: 54 if not package:
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 def set_debug_app(): 128 def set_debug_app():
126 # Set debug app in order to enable reading command line flags on user 129 # Set debug app in order to enable reading command line flags on user
127 # builds 130 # builds
128 if self._test_instance.flags: 131 if self._test_instance.flags:
129 if not self._test_instance.package_info: 132 if not self._test_instance.package_info:
130 logging.error("Couldn't set debug app: no package info") 133 logging.error("Couldn't set debug app: no package info")
131 elif not self._test_instance.package_info.package: 134 elif not self._test_instance.package_info.package:
132 logging.error("Couldn't set debug app: no package defined") 135 logging.error("Couldn't set debug app: no package defined")
133 else: 136 else:
134 dev.RunShellCommand(['am', 'set-debug-app', '--persistent', 137 dev.RunShellCommand(['am', 'set-debug-app', '--persistent',
135 self._test_instance.package_info.package], 138 self._test_instance.package_info.package],
136 check_return=True) 139 check_return=True)
137 @trace_event.traced 140 @trace_event.traced
138 def edit_shared_prefs(): 141 def edit_shared_prefs():
139 for pref in self._test_instance.edit_shared_prefs: 142 for pref in self._test_instance.edit_shared_prefs:
140 prefs = shared_prefs.SharedPrefs(dev, pref['package'], 143 prefs = shared_prefs.SharedPrefs(dev, pref['package'],
141 pref['filename']) 144 pref['filename'])
142 prefs.Load() 145 prefs.Load()
143 for key in pref.get('remove', []): 146 for key in pref.get('remove', []):
144 try: 147 try:
145 prefs.Remove(key) 148 prefs.Remove(key)
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 test_timeout_scale = None 253 test_timeout_scale = None
251 if self._test_instance.coverage_directory: 254 if self._test_instance.coverage_directory:
252 coverage_basename = '%s.ec' % ('%s_group' % test[0]['method'] 255 coverage_basename = '%s.ec' % ('%s_group' % test[0]['method']
253 if isinstance(test, list) else test['method']) 256 if isinstance(test, list) else test['method'])
254 extras['coverage'] = 'true' 257 extras['coverage'] = 'true'
255 coverage_directory = os.path.join( 258 coverage_directory = os.path.join(
256 device.GetExternalStoragePath(), 'chrome', 'test', 'coverage') 259 device.GetExternalStoragePath(), 'chrome', 'test', 'coverage')
257 coverage_device_file = os.path.join( 260 coverage_device_file = os.path.join(
258 coverage_directory, coverage_basename) 261 coverage_directory, coverage_basename)
259 extras['coverageFile'] = coverage_device_file 262 extras['coverageFile'] = coverage_device_file
263 # Save screenshot if screenshot dir is specified (save locally) or if
264 # a GS bucket is passed (save in cloud).
265 screenshot_device_file = None
266 if (self._test_instance.screenshot_dir or
267 self._test_instance.gs_results_bucket):
268 screenshot_device_file = device_temp_file.DeviceTempFile(
269 device.adb, suffix='.png', dir=device.GetExternalStoragePath())
270 extras[EXTRA_SCREENSHOT_FILE] = screenshot_device_file.name
260 271
261 if isinstance(test, list): 272 if isinstance(test, list):
262 if not self._test_instance.driver_apk: 273 if not self._test_instance.driver_apk:
263 raise Exception('driver_apk does not exist. ' 274 raise Exception('driver_apk does not exist. '
264 'Please build it and try again.') 275 'Please build it and try again.')
265 if any(t.get('is_junit4') for t in test): 276 if any(t.get('is_junit4') for t in test):
266 raise Exception('driver apk does not support JUnit4 tests') 277 raise Exception('driver apk does not support JUnit4 tests')
267 278
268 def name_and_timeout(t): 279 def name_and_timeout(t):
269 n = instrumentation_test_instance.GetTestName(t) 280 n = instrumentation_test_instance.GetTestName(t)
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 # - clearing the application state while persisting permissions 390 # - clearing the application state while persisting permissions
380 if any(r.GetType() not in (base_test_result.ResultType.PASS, 391 if any(r.GetType() not in (base_test_result.ResultType.PASS,
381 base_test_result.ResultType.SKIP) 392 base_test_result.ResultType.SKIP)
382 for r in results): 393 for r in results):
383 with contextlib_ext.Optional( 394 with contextlib_ext.Optional(
384 tempfile_ext.NamedTemporaryDirectory(), 395 tempfile_ext.NamedTemporaryDirectory(),
385 self._test_instance.screenshot_dir is None and 396 self._test_instance.screenshot_dir is None and
386 self._test_instance.gs_results_bucket) as screenshot_host_dir: 397 self._test_instance.gs_results_bucket) as screenshot_host_dir:
387 screenshot_host_dir = ( 398 screenshot_host_dir = (
388 self._test_instance.screenshot_dir or screenshot_host_dir) 399 self._test_instance.screenshot_dir or screenshot_host_dir)
389 if screenshot_host_dir: 400 self._SaveScreenshot(device, screenshot_host_dir,
390 file_name = '%s-%s.png' % ( 401 screenshot_device_file, test_display_name,
391 test_display_name, 402 results)
392 time.strftime('%Y%m%dT%H%M%S-UTC', time.gmtime()))
393 screenshot_file = device.TakeScreenshot(
394 os.path.join(screenshot_host_dir, file_name))
395 logging.info(
396 'Saved screenshot for %s to %s.',
397 test_display_name, screenshot_file)
398 if self._test_instance.gs_results_bucket:
399 link = google_storage_helper.upload(
400 google_storage_helper.unique_name('screenshot', device=device),
401 screenshot_file,
402 bucket=self._test_instance.gs_results_bucket + '/screenshots')
403 for result in results:
404 result.SetLink('post_test_screenshot', link)
405 403
406 logging.info('detected failure in %s. raw output:', test_display_name) 404 logging.info('detected failure in %s. raw output:', test_display_name)
407 for l in output: 405 for l in output:
408 logging.info(' %s', l) 406 logging.info(' %s', l)
409 if (not self._env.skip_clear_data 407 if (not self._env.skip_clear_data
410 and self._test_instance.package_info): 408 and self._test_instance.package_info):
411 permissions = ( 409 permissions = (
412 self._test_instance.apk_under_test.GetPermissions() 410 self._test_instance.apk_under_test.GetPermissions()
413 if self._test_instance.apk_under_test 411 if self._test_instance.apk_under_test
414 else None) 412 else None)
(...skipping 20 matching lines...) Expand all
435 include_stack_symbols=False, 433 include_stack_symbols=False,
436 wipe_tombstones=True) 434 wipe_tombstones=True)
437 stream_name = 'tombstones_%s_%s' % ( 435 stream_name = 'tombstones_%s_%s' % (
438 time.strftime('%Y%m%dT%H%M%S-UTC', time.gmtime()), 436 time.strftime('%Y%m%dT%H%M%S-UTC', time.gmtime()),
439 device.serial) 437 device.serial)
440 tombstones_url = logdog_helper.text( 438 tombstones_url = logdog_helper.text(
441 stream_name, '\n'.join(resolved_tombstones)) 439 stream_name, '\n'.join(resolved_tombstones))
442 result.SetLink('tombstones', tombstones_url) 440 result.SetLink('tombstones', tombstones_url)
443 return results, None 441 return results, None
444 442
443 def _SaveScreenshot(self, device, screenshot_host_dir, screenshot_device_file,
444 test_name, results):
445 if screenshot_host_dir:
446 screenshot_host_file = os.path.join(
447 screenshot_host_dir,
448 '%s-%s.png' % (
449 test_name,
450 time.strftime('%Y%m%dT%H%M%S-UTC', time.gmtime())))
451 if device.FileExists(screenshot_device_file.name):
452 try:
453 device.PullFile(screenshot_device_file.name, screenshot_host_file)
454 finally:
455 screenshot_device_file.close()
456
457 logging.info(
458 'Saved screenshot for %s to %s.',
459 test_name, screenshot_host_file)
460 if self._test_instance.gs_results_bucket:
461 link = google_storage_helper.upload(
462 google_storage_helper.unique_name(
463 'screenshot', device=device),
464 screenshot_host_file,
465 bucket=('%s/screenshots' %
466 self._test_instance.gs_results_bucket))
467 for result in results:
468 result.SetLink('post_test_screenshot', link)
469
445 #override 470 #override
446 def _ShouldRetry(self, test): 471 def _ShouldRetry(self, test):
447 if 'RetryOnFailure' in test.get('annotations', {}): 472 if 'RetryOnFailure' in test.get('annotations', {}):
448 return True 473 return True
449 474
450 # TODO(jbudorick): Remove this log message once @RetryOnFailure has been 475 # TODO(jbudorick): Remove this log message once @RetryOnFailure has been
451 # enabled for a while. See crbug.com/619055 for more details. 476 # enabled for a while. See crbug.com/619055 for more details.
452 logging.error('Default retries are being phased out. crbug.com/619055') 477 logging.error('Default retries are being phased out. crbug.com/619055')
453 return False 478 return False
454 479
(...skipping 15 matching lines...) Expand all
470 if k in annotations: 495 if k in annotations:
471 timeout = v 496 timeout = v
472 break 497 break
473 else: 498 else:
474 logging.warning('Using default 1 minute timeout for %s', test_name) 499 logging.warning('Using default 1 minute timeout for %s', test_name)
475 timeout = 60 500 timeout = 60
476 501
477 timeout *= cls._GetTimeoutScaleFromAnnotations(annotations) 502 timeout *= cls._GetTimeoutScaleFromAnnotations(annotations)
478 503
479 return timeout 504 return timeout
OLDNEW
« no previous file with comments | « base/test/android/javatests/src/org/chromium/base/test/ScreenshotOnFailureStatement.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698