1# Copyright 2017 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import logging 6 7from devil import base_error 8from devil.android import device_errors 9 10logger = logging.getLogger(__name__) 11 12 13def RetryOnSystemCrash(f, device, retries=3): 14 """Retries the given function on a device crash. 15 16 If the provided function fails with a DeviceUnreachableError, this will wait 17 for the device to come back online, then retry the function. 18 19 Note that this uses the same retry scheme as timeout_retry.Run. 20 21 Args: 22 f: a unary callable that takes an instance of device_utils.DeviceUtils. 23 device: an instance of device_utils.DeviceUtils. 24 retries: the number of retries. 25 Returns: 26 Whatever f returns. 27 """ 28 num_try = 1 29 while True: 30 try: 31 return f(device) 32 except device_errors.DeviceUnreachableError: 33 if num_try > retries: 34 logger.error('%d consecutive device crashes. No longer retrying.', 35 num_try) 36 raise 37 try: 38 logger.warning('Device is unreachable. Waiting for recovery...') 39 # Treat the device being unreachable as an unexpected reboot and clear 40 # any cached state. 41 device.ClearCache() 42 device.WaitUntilFullyBooted() 43 except base_error.BaseError: 44 logger.exception('Device never recovered. X(') 45 num_try += 1 46