1be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# Copyright 2014 The Chromium Authors. All rights reserved. 2be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# Use of this source code is governed by a BSD-style license that can be 3be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# found in the LICENSE file. 4be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 5be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik""" 6be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris CraikException classes raised by AdbWrapper and DeviceUtils. 7576fd2a645575980f16b6731dab0f4f150100657Chris Craik 8576fd2a645575980f16b6731dab0f4f150100657Chris CraikThe class hierarchy for device exceptions is: 9576fd2a645575980f16b6731dab0f4f150100657Chris Craik 10576fd2a645575980f16b6731dab0f4f150100657Chris Craik base_error.BaseError 11576fd2a645575980f16b6731dab0f4f150100657Chris Craik +-- CommandFailedError 12576fd2a645575980f16b6731dab0f4f150100657Chris Craik | +-- AdbCommandFailedError 13576fd2a645575980f16b6731dab0f4f150100657Chris Craik | | +-- AdbShellCommandFailedError 14576fd2a645575980f16b6731dab0f4f150100657Chris Craik | +-- FastbootCommandFailedError 15576fd2a645575980f16b6731dab0f4f150100657Chris Craik | +-- DeviceVersionError 16576fd2a645575980f16b6731dab0f4f150100657Chris Craik | +-- DeviceChargingError 17576fd2a645575980f16b6731dab0f4f150100657Chris Craik +-- CommandTimeoutError 18576fd2a645575980f16b6731dab0f4f150100657Chris Craik +-- DeviceUnreachableError 19576fd2a645575980f16b6731dab0f4f150100657Chris Craik +-- NoDevicesError 20576fd2a645575980f16b6731dab0f4f150100657Chris Craik +-- MultipleDevicesError 21576fd2a645575980f16b6731dab0f4f150100657Chris Craik +-- NoAdbError 22576fd2a645575980f16b6731dab0f4f150100657Chris Craik 23be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik""" 24be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 25be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikfrom devil import base_error 26be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikfrom devil.utils import cmd_helper 27a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikfrom devil.utils import parallelizer 28be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 29be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 30be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikclass CommandFailedError(base_error.BaseError): 31be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """Exception for command failures.""" 32be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 33be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik def __init__(self, message, device_serial=None): 3433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck device_leader = '(device: %s)' % device_serial 3533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if device_serial is not None and not message.startswith(device_leader): 3633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck message = '%s %s' % (device_leader, message) 37be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self.device_serial = device_serial 38be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik super(CommandFailedError, self).__init__(message) 39be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 4033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __eq__(self, other): 4133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return (super(CommandFailedError, self).__eq__(other) 4233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck and self.device_serial == other.device_serial) 4333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 4433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __ne__(self, other): 4533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return not self == other 4633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 47be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 48be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikclass _BaseCommandFailedError(CommandFailedError): 49be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """Base Exception for adb and fastboot command failures.""" 50be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 51be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik def __init__(self, args, output, status=None, device_serial=None, 52be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik message=None): 53be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self.args = args 54be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self.output = output 55be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self.status = status 56be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if not message: 57be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik adb_cmd = ' '.join(cmd_helper.SingleQuote(arg) for arg in self.args) 58be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik message = ['adb %s: failed ' % adb_cmd] 59be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if status: 60be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik message.append('with exit status %s ' % self.status) 61be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if output: 62be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik message.append('and output:\n') 63be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik message.extend('- %s\n' % line for line in output.splitlines()) 64be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik else: 65be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik message.append('and no output.') 66be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik message = ''.join(message) 67be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik super(_BaseCommandFailedError, self).__init__(message, device_serial) 68be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 6933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __eq__(self, other): 7033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return (super(_BaseCommandFailedError, self).__eq__(other) 7133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck and self.args == other.args 7233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck and self.output == other.output 7333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck and self.status == other.status) 7433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 7533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __ne__(self, other): 7633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return not self == other 7733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 7833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __reduce__(self): 7933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Support pickling.""" 8033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck result = [None, None, None, None, None] 8133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck super_result = super(_BaseCommandFailedError, self).__reduce__() 8233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for i in range(len(super_result)): 8333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck result[i] = super_result[i] 8433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 8533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Update the args used to reconstruct this exception. 8633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck result[1] = ( 8733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.args, self.output, self.status, self.device_serial, self.message) 8833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return tuple(result) 8933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 90be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 91be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikclass AdbCommandFailedError(_BaseCommandFailedError): 92be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """Exception for adb command failures.""" 93be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 94be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik def __init__(self, args, output, status=None, device_serial=None, 95be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik message=None): 96be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik super(AdbCommandFailedError, self).__init__( 97be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik args, output, status=status, message=message, 98be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik device_serial=device_serial) 99be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 100be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 101be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikclass FastbootCommandFailedError(_BaseCommandFailedError): 102be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """Exception for fastboot command failures.""" 103be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 104be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik def __init__(self, args, output, status=None, device_serial=None, 105be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik message=None): 106be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik super(FastbootCommandFailedError, self).__init__( 107be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik args, output, status=status, message=message, 108be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik device_serial=device_serial) 109be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 110be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 111be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikclass DeviceVersionError(CommandFailedError): 112be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """Exception for device version failures.""" 113be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 114be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik def __init__(self, message, device_serial=None): 115be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik super(DeviceVersionError, self).__init__(message, device_serial) 116be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 117be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 118be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikclass AdbShellCommandFailedError(AdbCommandFailedError): 119be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """Exception for shell command failures run via adb.""" 120be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 121be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik def __init__(self, command, output, status, device_serial=None): 122be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self.command = command 123be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik message = ['shell command run via adb failed on the device:\n', 124be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik ' command: %s\n' % command] 125be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik message.append(' exit status: %s\n' % status) 126be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if output: 127be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik message.append(' output:\n') 128be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if isinstance(output, basestring): 129be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik output_lines = output.splitlines() 130be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik else: 131be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik output_lines = output 132be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik message.extend(' - %s\n' % line for line in output_lines) 133be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik else: 134be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik message.append(" output: ''\n") 135be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik message = ''.join(message) 136be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik super(AdbShellCommandFailedError, self).__init__( 137be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik ['shell', command], output, status, device_serial, message) 138be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 13933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __reduce__(self): 14033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Support pickling.""" 14133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck result = [None, None, None, None, None] 14233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck super_result = super(AdbShellCommandFailedError, self).__reduce__() 14333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for i in range(len(super_result)): 14433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck result[i] = super_result[i] 14533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 14633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Update the args used to reconstruct this exception. 14733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck result[1] = (self.command, self.output, self.status, self.device_serial) 14833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return tuple(result) 14933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 150be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 151be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikclass CommandTimeoutError(base_error.BaseError): 152be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """Exception for command timeouts.""" 153be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik pass 154be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 155be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 156be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikclass DeviceUnreachableError(base_error.BaseError): 157be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """Exception for device unreachable failures.""" 158be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik pass 159be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 160be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 161be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikclass NoDevicesError(base_error.BaseError): 162be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """Exception for having no devices attached.""" 163be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 16433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __init__(self, msg=None): 165be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik super(NoDevicesError, self).__init__( 16633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck msg or 'No devices attached.', is_infra_error=True) 167be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 168be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 169a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikclass MultipleDevicesError(base_error.BaseError): 170a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik """Exception for having multiple attached devices without selecting one.""" 171a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 172a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik def __init__(self, devices): 173a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik parallel_devices = parallelizer.Parallelizer(devices) 174a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik descriptions = parallel_devices.pMap( 175a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik lambda d: d.build_description).pGet(None) 176a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik msg = ('More than one device available. Use -d/--device to select a device ' 177a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 'by serial.\n\nAvailable devices:\n') 178a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik for d, desc in zip(devices, descriptions): 179a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik msg += ' %s (%s)\n' % (d, desc) 180a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 181a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik super(MultipleDevicesError, self).__init__(msg, is_infra_error=True) 182a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 183a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 184be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikclass NoAdbError(base_error.BaseError): 185be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """Exception for being unable to find ADB.""" 186be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 187be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik def __init__(self, msg=None): 188be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik super(NoAdbError, self).__init__( 189be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik msg or 'Unable to find adb.', is_infra_error=True) 190be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 191be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 192be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikclass DeviceChargingError(CommandFailedError): 193be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """Exception for device charging errors.""" 194be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 195be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik def __init__(self, message, device_serial=None): 196be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik super(DeviceChargingError, self).__init__(message, device_serial) 197