def Shell(self, command, expect_status=0, ensure_logs_on_timeout=True, timeout=DEFAULT_TIMEOUT, retries=DEFAULT_RETRIES): """Runs a shell command on the device. Args: command: A string with the shell command to run. expect_status: (optional) Check that the command's exit status matches this value. Default is 0. If set to None the test is skipped. ensure_logs_on_timeout: If True, will use a timeout that is 5% smaller than the remaining time on the thread watchdog for the internal adb command, which allows to retrive logs on timeout. timeout: (optional) Timeout per try in seconds. retries: (optional) Number of retries to attempt. Returns: The output of the shell command as a string. Raises: device_errors.AdbCommandFailedError: If the exit status doesn't match |expect_status|. """ if expect_status is None: args = ['shell', command] else: args = ['shell', '( %s );echo %%$?' % command.rstrip()] output = self._RunDeviceAdbCmd( args, timeout, retries, check_error=False, ensure_logs_on_timeout=ensure_logs_on_timeout) if expect_status is not None: output_end = output.rfind('%') if output_end < 0: # causes the status string to become empty and raise a ValueError output_end = len(output) try: status = int(output[output_end + 1:]) except ValueError: logger.warning('exit status of shell command %r missing.', command) raise device_errors.AdbShellCommandFailedError( command, output, status=None, device_serial=self._device_serial) output = output[:output_end] if status != expect_status: raise device_errors.AdbShellCommandFailedError( command, output, status=status, device_serial=self._device_serial) return output
def testCalculateDeviceMd5Sums_requiresBinary(self): test_path = '/storage/emulated/legacy/test/file.dat' device = mock.NonCallableMock() device.adb = mock.NonCallableMock() device.adb.Push = mock.Mock() device_md5sum_output = [ 'WARNING: linker: /data/local/tmp/md5sum/md5sum_bin: ' 'unused DT entry: type 0x1d arg 0x15db', 'THIS_IS_NOT_A_VALID_CHECKSUM_ZZZ some random text', '0123456789abcdef', ] error = device_errors.AdbShellCommandFailedError('cmd', 'out', 2) device.RunShellCommand = mock.Mock( side_effect=(error, '', device_md5sum_output)) with mock.patch( 'os.path.isdir', return_value=True), (mock.patch( 'os.path.getsize', return_value=1337)): out = md5sum.CalculateDeviceMd5Sums(test_path, device) self.assertEquals(1, len(out)) self.assertTrue('/storage/emulated/legacy/test/file.dat' in out) self.assertEquals('0123456789abcdef', out['/storage/emulated/legacy/test/file.dat']) self.assertEquals(3, len(device.RunShellCommand.call_args_list)) device.adb.Push.assert_called_once_with('test/out/directory/md5sum_dist', '/data/local/tmp/md5sum')
def testPicklable_AdbShellCommandFailedError(self): original = device_errors.AdbShellCommandFailedError( 'foo', 'erroneous foo output', '1', device_serial='0123456789abcdef') self.assertIsPicklable(original)
def mock_run_shell(cmd, **_kwargs): args = cmd.split() if isinstance(cmd, basestring) else cmd try: return self.cmd_outputs[args[0]] except KeyError: raise device_errors.AdbShellCommandFailedError(cmd, None, None)
def _throw_on_grep(cmd): if cmd.startswith('grep'): raise device_errors.AdbShellCommandFailedError(cmd, None, None) else: return []
def _throw_on_ps(cmd): if cmd == 'ps': raise device_errors.AdbShellCommandFailedError(cmd, None, None) else: return []
def action(cmd, *args, **kwargs): raise device_errors.AdbShellCommandFailedError( cmd, output, status, str(self.device))