def Shell(self, command, expect_status=0, 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. 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) 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: logging.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', '0123456789abcdeffedcba9876543210 ' '/storage/emulated/legacy/test/file.dat', ] error = device_errors.AdbShellCommandFailedError('cmd', 'out', 2) device.RunShellCommand = mock.Mock(side_effect=(error, '', device_md5sum_output)) with 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('0123456789abcdeffedcba9876543210', 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 Shell(self, command, expect_rc=0, timeout=_DEFAULT_TIMEOUT, retries=_DEFAULT_RETRIES): """Runs a shell command on the device. Args: command: The shell command to run. expect_rc: (optional) Check that the command's return code matches this value. Default is 0. If set to None the test is skipped. 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 return code doesn't match |expect_rc|. """ if expect_rc is None: actual_command = command else: actual_command = '%s; echo %%$?;' % command.rstrip() output = self._DeviceAdbCmd(['shell', actual_command], timeout, retries, check_error=False) if expect_rc is not None: output_end = output.rfind('%') if output_end < 0: # causes the string for rc to become empty and also raise a ValueError output_end = len(output) try: rc = int(output[output_end + 1:]) except ValueError: raise device_errors.AdbCommandFailedError( ['shell'], 'command %r on device produced output %r where no' ' valid return code was found' % (actual_command, output), self._device_serial) output = output[:output_end] if rc != expect_rc: raise device_errors.AdbShellCommandFailedError( command, rc, output, self._device_serial) return output
def action(cmd, *args, **kwargs): raise device_errors.AdbShellCommandFailedError( cmd, output, status, str(self.device))