From 59f911055e912e7c54eb46ce7edc70592e266a4c Mon Sep 17 00:00:00 2001 From: Jeff Irion Date: Tue, 17 Oct 2023 20:46:37 -0700 Subject: [PATCH 1/2] Apply black formatting --- .github/workflows/python-package.yml | 4 +- adb_shell/__init__.py | 2 +- adb_shell/adb_device.py | 275 ++-- adb_shell/adb_device_async.py | 302 +++-- adb_shell/adb_message.py | 13 +- adb_shell/auth/keygen.py | 76 +- adb_shell/auth/sign_cryptography.py | 5 +- adb_shell/auth/sign_pycryptodome.py | 5 +- adb_shell/auth/sign_pythonrsa.py | 22 +- adb_shell/constants.py | 48 +- adb_shell/exceptions.py | 54 +- adb_shell/hidden_helpers.py | 43 +- adb_shell/transport/base_transport.py | 11 +- adb_shell/transport/base_transport_async.py | 8 +- adb_shell/transport/tcp_transport.py | 11 +- adb_shell/transport/tcp_transport_async.py | 13 +- adb_shell/transport/usb_transport.py | 90 +- setup.py | 36 +- tests/async_patchers.py | 8 +- tests/async_wrapper.py | 1 - tests/filesync_helpers.py | 15 +- tests/keygen_stub.py | 15 +- tests/patchers.py | 55 +- tests/test_adb_device.py | 1252 +++++++++++-------- tests/test_adb_device_async.py | 1243 +++++++++++------- tests/test_adb_message.py | 8 +- tests/test_exceptions.py | 11 +- tests/test_hidden_helpers.py | 5 +- tests/test_keygen.py | 12 +- tests/test_sign_cryptography.py | 14 +- tests/test_sign_pycryptodome.py | 14 +- tests/test_sign_pythonrsa.py | 35 +- tests/test_tcp_transport.py | 34 +- tests/test_tcp_transport_async.py | 30 +- tests/test_usb_importerror.py | 2 +- tests/test_usb_transport.py | 28 +- 36 files changed, 2338 insertions(+), 1462 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 3ddde1b3..1df8e555 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -30,9 +30,9 @@ jobs: run: | python -m pip install --upgrade pip make venv - - name: Linting checks with pylint, flake8, and (soon) black + - name: Linting checks with pylint, flake8, and black run: | - make lint-flake8 lint-pylint + make lint - name: Test with pytest env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/adb_shell/__init__.py b/adb_shell/__init__.py index 09ca6aee..17c93e86 100644 --- a/adb_shell/__init__.py +++ b/adb_shell/__init__.py @@ -7,4 +7,4 @@ """ -__version__ = '0.4.4' +__version__ = "0.4.4" diff --git a/adb_shell/adb_device.py b/adb_shell/adb_device.py index 0096950a..8a23dd9b 100644 --- a/adb_shell/adb_device.py +++ b/adb_shell/adb_device.py @@ -84,7 +84,14 @@ from .adb_message import AdbMessage, checksum, int_to_cmd, unpack from .transport.base_transport import BaseTransport from .transport.tcp_transport import TcpTransport -from .hidden_helpers import DeviceFile, _AdbPacketStore, _AdbTransactionInfo, _FileSyncTransactionInfo, get_banner, get_files_to_push +from .hidden_helpers import ( + DeviceFile, + _AdbPacketStore, + _AdbTransactionInfo, + _FileSyncTransactionInfo, + get_banner, + get_files_to_push, +) try: from .transport.usb_transport import UsbTransport @@ -153,9 +160,7 @@ def __init__(self, transport): self._transport_lock = Lock() def close(self): - """Close the connection via the provided transport's ``close()`` method and clear the packet store. - - """ + """Close the connection via the provided transport's ``close()`` method and clear the packet store.""" with self._transport_lock: self._transport.close() @@ -221,11 +226,13 @@ def connect(self, banner, rsa_keys, auth_timeout_s, auth_callback, adb_info): self._transport.connect(adb_info.transport_timeout_s) # 2. Send a ``b'CNXN'`` message - msg = AdbMessage(constants.CNXN, constants.VERSION, constants.MAX_ADB_DATA, b'host::%s\0' % banner) + msg = AdbMessage(constants.CNXN, constants.VERSION, constants.MAX_ADB_DATA, b"host::%s\0" % banner) self._send(msg, adb_info) # 3. Read the response from the device - cmd, arg0, maxdata, banner2 = self._read_expected_packet_from_device([constants.AUTH, constants.CNXN], adb_info) + cmd, arg0, maxdata, banner2 = self._read_expected_packet_from_device( + [constants.AUTH, constants.CNXN], adb_info + ) # 4. If ``cmd`` is not ``b'AUTH'``, then authentication is not necesary and so we are done if cmd != constants.AUTH: @@ -234,14 +241,14 @@ def connect(self, banner, rsa_keys, auth_timeout_s, auth_callback, adb_info): # 5. If no ``rsa_keys`` are provided, raise an exception if not rsa_keys: self._transport.close() - raise exceptions.DeviceAuthError('Device authentication required, no keys available.') + raise exceptions.DeviceAuthError("Device authentication required, no keys available.") # 6. Loop through our keys, signing the last ``banner2`` that we received for rsa_key in rsa_keys: # 6.1. If the last ``arg0`` was not :const:`adb_shell.constants.AUTH_TOKEN`, raise an exception if arg0 != constants.AUTH_TOKEN: self._transport.close() - raise exceptions.InvalidResponseError('Unknown AUTH response: %s %s %s' % (arg0, maxdata, banner2)) + raise exceptions.InvalidResponseError("Unknown AUTH response: %s %s %s" % (arg0, maxdata, banner2)) # 6.2. Sign the last ``banner2`` and send it in an ``b'AUTH'`` message signed_token = rsa_key.Sign(banner2) @@ -249,7 +256,9 @@ def connect(self, banner, rsa_keys, auth_timeout_s, auth_callback, adb_info): self._send(msg, adb_info) # 6.3. Read the response from the device - cmd, arg0, maxdata, banner2 = self._read_expected_packet_from_device([constants.CNXN, constants.AUTH], adb_info) + cmd, arg0, maxdata, banner2 = self._read_expected_packet_from_device( + [constants.CNXN, constants.AUTH], adb_info + ) # 6.4. If ``cmd`` is ``b'CNXN'``, we are done if cmd == constants.CNXN: @@ -258,12 +267,12 @@ def connect(self, banner, rsa_keys, auth_timeout_s, auth_callback, adb_info): # 7. None of the keys worked, so send ``rsa_keys[0]``'s public key; if the response does not time out, we must have connected successfully pubkey = rsa_keys[0].GetPublicKey() if not isinstance(pubkey, (bytes, bytearray)): - pubkey = bytearray(pubkey, 'utf-8') + pubkey = bytearray(pubkey, "utf-8") if auth_callback is not None: auth_callback(self) - msg = AdbMessage(constants.AUTH, constants.AUTH_RSAPUBLICKEY, 0, pubkey + b'\0') + msg = AdbMessage(constants.AUTH, constants.AUTH_RSAPUBLICKEY, 0, pubkey + b"\0") self._send(msg, adb_info) adb_info.transport_timeout_s = auth_timeout_s @@ -311,13 +320,21 @@ def read(self, expected_cmds, adb_info, allow_zeros=False): # First, try reading from the store. This way, you won't be waiting for the transport if it isn't needed with self._store_lock: # Recall that `arg0` from the device corresponds to `adb_info.remote_id` and `arg1` from the device corresponds to `adb_info.local_id` - arg0_arg1 = self._packet_store.find(adb_info.remote_id, adb_info.local_id) if not allow_zeros else self._packet_store.find_allow_zeros(adb_info.remote_id, adb_info.local_id) + arg0_arg1 = ( + self._packet_store.find(adb_info.remote_id, adb_info.local_id) + if not allow_zeros + else self._packet_store.find_allow_zeros(adb_info.remote_id, adb_info.local_id) + ) while arg0_arg1: cmd, arg0, arg1, data = self._packet_store.get(arg0_arg1[0], arg0_arg1[1]) if cmd in expected_cmds: return cmd, arg0, arg1, data - arg0_arg1 = self._packet_store.find(adb_info.remote_id, adb_info.local_id) if not allow_zeros else self._packet_store.find_allow_zeros(adb_info.remote_id, adb_info.local_id) + arg0_arg1 = ( + self._packet_store.find(adb_info.remote_id, adb_info.local_id) + if not allow_zeros + else self._packet_store.find_allow_zeros(adb_info.remote_id, adb_info.local_id) + ) # Start the timer start = time.time() @@ -327,13 +344,21 @@ def read(self, expected_cmds, adb_info, allow_zeros=False): # Try reading from the store (again) in case a packet got added while waiting to acquire the transport lock with self._store_lock: # Recall that `arg0` from the device corresponds to `adb_info.remote_id` and `arg1` from the device corresponds to `adb_info.local_id` - arg0_arg1 = self._packet_store.find(adb_info.remote_id, adb_info.local_id) if not allow_zeros else self._packet_store.find_allow_zeros(adb_info.remote_id, adb_info.local_id) + arg0_arg1 = ( + self._packet_store.find(adb_info.remote_id, adb_info.local_id) + if not allow_zeros + else self._packet_store.find_allow_zeros(adb_info.remote_id, adb_info.local_id) + ) while arg0_arg1: cmd, arg0, arg1, data = self._packet_store.get(arg0_arg1[0], arg0_arg1[1]) if cmd in expected_cmds: return cmd, arg0, arg1, data - arg0_arg1 = self._packet_store.find(adb_info.remote_id, adb_info.local_id) if not allow_zeros else self._packet_store.find_allow_zeros(adb_info.remote_id, adb_info.local_id) + arg0_arg1 = ( + self._packet_store.find(adb_info.remote_id, adb_info.local_id) + if not allow_zeros + else self._packet_store.find_allow_zeros(adb_info.remote_id, adb_info.local_id) + ) # Read from the device cmd, arg0, arg1, data = self._read_packet_from_device(adb_info) @@ -359,7 +384,11 @@ def read(self, expected_cmds, adb_info, allow_zeros=False): break # Timeout - raise exceptions.AdbTimeoutError("Never got one of the expected responses: {} (transport_timeout_s = {}, read_timeout_s = {})".format(expected_cmds, adb_info.transport_timeout_s, adb_info.read_timeout_s)) + raise exceptions.AdbTimeoutError( + "Never got one of the expected responses: {} (transport_timeout_s = {}, read_timeout_s = {})".format( + expected_cmds, adb_info.transport_timeout_s, adb_info.read_timeout_s + ) + ) def send(self, msg, adb_info): """Send a message to the device. @@ -412,7 +441,11 @@ def _read_expected_packet_from_device(self, expected_cmds, adb_info): if time.time() - start > adb_info.read_timeout_s: # Timeout - raise exceptions.AdbTimeoutError("Never got one of the expected responses: {} (transport_timeout_s = {}, read_timeout_s = {})".format(expected_cmds, adb_info.transport_timeout_s, adb_info.read_timeout_s)) + raise exceptions.AdbTimeoutError( + "Never got one of the expected responses: {} (transport_timeout_s = {}, read_timeout_s = {})".format( + expected_cmds, adb_info.transport_timeout_s, adb_info.read_timeout_s + ) + ) def _read_bytes_from_device(self, length, adb_info): """Read ``length`` bytes from the device. @@ -452,7 +485,11 @@ def _read_bytes_from_device(self, length, adb_info): if time.time() - start > adb_info.read_timeout_s: # Timeout - raise exceptions.AdbTimeoutError("Timeout: read {} of {} bytes (transport_timeout_s = {}, read_timeout_s = {})".format(len(data), len(data) + length, adb_info.transport_timeout_s, adb_info.read_timeout_s)) + raise exceptions.AdbTimeoutError( + "Timeout: read {} of {} bytes (transport_timeout_s = {}, read_timeout_s = {})".format( + len(data), len(data) + length, adb_info.transport_timeout_s, adb_info.read_timeout_s + ) + ) return bytes(data) @@ -482,13 +519,16 @@ def _read_packet_from_device(self, adb_info): adb_shell.exceptions.InvalidChecksumError Received checksum does not match the expected checksum - """ + """ msg = self._read_bytes_from_device(constants.MESSAGE_SIZE, adb_info) cmd, arg0, arg1, data_length, data_checksum = unpack(msg) command = constants.WIRE_TO_ID.get(cmd) if not command: - raise exceptions.InvalidCommandError("Unknown command: %d = '%s' (arg0 = %d, arg1 = %d, msg = '%s')" % (cmd, int_to_cmd(cmd), arg0, arg1, msg)) + raise exceptions.InvalidCommandError( + "Unknown command: %d = '%s' (arg0 = %d, arg1 = %d, msg = '%s')" + % (cmd, int_to_cmd(cmd), arg0, arg1, msg) + ) if data_length == 0: return command, arg0, arg1, b"" @@ -563,7 +603,7 @@ class AdbDevice(object): def __init__(self, transport, default_transport_timeout_s=None, banner=None): if banner and not isinstance(banner, (bytes, bytearray)): - self._banner = bytearray(banner, 'utf-8') + self._banner = bytearray(banner, "utf-8") else: self._banner = banner @@ -629,13 +669,18 @@ def _get_transport_timeout_s(self, transport_timeout_s): # # # ======================================================================= # def close(self): - """Close the connection via the provided transport's ``close()`` method. - - """ + """Close the connection via the provided transport's ``close()`` method.""" self._available = False self._io_manager.close() - def connect(self, rsa_keys=None, transport_timeout_s=None, auth_timeout_s=constants.DEFAULT_AUTH_TIMEOUT_S, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, auth_callback=None): + def connect( + self, + rsa_keys=None, + transport_timeout_s=None, + auth_timeout_s=constants.DEFAULT_AUTH_TIMEOUT_S, + read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, + auth_callback=None, + ): """Establish an ADB connection to the device. See :meth:`_AdbIOManager.connect`. @@ -666,13 +711,17 @@ def connect(self, rsa_keys=None, transport_timeout_s=None, auth_timeout_s=consta self._banner = get_banner() # Instantiate the `_AdbTransactionInfo` - adb_info = _AdbTransactionInfo(None, None, self._get_transport_timeout_s(transport_timeout_s), read_timeout_s, None) + adb_info = _AdbTransactionInfo( + None, None, self._get_transport_timeout_s(transport_timeout_s), read_timeout_s, None + ) # Mark the device as unavailable self._available = False # Use the IO manager to connect - self._available, self._maxdata = self._io_manager.connect(self._banner, rsa_keys, auth_timeout_s, auth_callback, adb_info) + self._available, self._maxdata = self._io_manager.connect( + self._banner, rsa_keys, auth_timeout_s, auth_callback, adb_info + ) return self._available @@ -681,7 +730,15 @@ def connect(self, rsa_keys=None, transport_timeout_s=None, auth_timeout_s=consta # Services # # # # ======================================================================= # - def _service(self, service, command, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, timeout_s=None, decode=True): + def _service( + self, + service, + command, + transport_timeout_s=None, + read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, + timeout_s=None, + decode=True, + ): """Send an ADB command to the device. Parameters @@ -707,10 +764,14 @@ def _service(self, service, command, transport_timeout_s=None, read_timeout_s=co """ if decode: - return b''.join(self._streaming_command(service, command, transport_timeout_s, read_timeout_s, timeout_s)).decode('utf8', _DECODE_ERRORS) - return b''.join(self._streaming_command(service, command, transport_timeout_s, read_timeout_s, timeout_s)) - - def _streaming_service(self, service, command, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, decode=True): + return b"".join( + self._streaming_command(service, command, transport_timeout_s, read_timeout_s, timeout_s) + ).decode("utf8", _DECODE_ERRORS) + return b"".join(self._streaming_command(service, command, transport_timeout_s, read_timeout_s, timeout_s)) + + def _streaming_service( + self, service, command, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, decode=True + ): """Send an ADB command to the device, yielding each line of output. Parameters @@ -735,13 +796,20 @@ def _streaming_service(self, service, command, transport_timeout_s=None, read_ti """ stream = self._streaming_command(service, command, transport_timeout_s, read_timeout_s, None) if decode: - for line in (stream_line.decode('utf8', _DECODE_ERRORS) for stream_line in stream): + for line in (stream_line.decode("utf8", _DECODE_ERRORS) for stream_line in stream): yield line else: for line in stream: yield line - def exec_out(self, command, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, timeout_s=None, decode=True): + def exec_out( + self, + command, + transport_timeout_s=None, + read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, + timeout_s=None, + decode=True, + ): """Send an ADB ``exec-out`` command to the device. https://www.linux-magazine.com/Issues/2017/195/Ask-Klaus @@ -767,11 +835,15 @@ def exec_out(self, command, transport_timeout_s=None, read_timeout_s=constants.D """ if not self.available: - raise exceptions.AdbConnectionError("ADB command not sent because a connection to the device has not been established. (Did you call `AdbDevice.connect()`?)") + raise exceptions.AdbConnectionError( + "ADB command not sent because a connection to the device has not been established. (Did you call `AdbDevice.connect()`?)" + ) - return self._service(b'exec', command.encode('utf8'), transport_timeout_s, read_timeout_s, timeout_s, decode) + return self._service(b"exec", command.encode("utf8"), transport_timeout_s, read_timeout_s, timeout_s, decode) - def reboot(self, fastboot=False, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, timeout_s=None): + def reboot( + self, fastboot=False, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, timeout_s=None + ): """Reboot the device. Parameters @@ -788,9 +860,11 @@ def reboot(self, fastboot=False, transport_timeout_s=None, read_timeout_s=consta """ if not self.available: - raise exceptions.AdbConnectionError("ADB command not sent because a connection to the device has not been established. (Did you call `AdbDevice.connect()`?)") + raise exceptions.AdbConnectionError( + "ADB command not sent because a connection to the device has not been established. (Did you call `AdbDevice.connect()`?)" + ) - self._open(b'reboot:bootloader' if fastboot else b'reboot:', transport_timeout_s, read_timeout_s, timeout_s) + self._open(b"reboot:bootloader" if fastboot else b"reboot:", transport_timeout_s, read_timeout_s, timeout_s) def root(self, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, timeout_s=None): """Gain root access. @@ -809,11 +883,20 @@ def root(self, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_T """ if not self.available: - raise exceptions.AdbConnectionError("ADB command not sent because a connection to the device has not been established. (Did you call `AdbDevice.connect()`?)") - - self._service(b'root', b'', transport_timeout_s, read_timeout_s, timeout_s, False) - - def shell(self, command, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, timeout_s=None, decode=True): + raise exceptions.AdbConnectionError( + "ADB command not sent because a connection to the device has not been established. (Did you call `AdbDevice.connect()`?)" + ) + + self._service(b"root", b"", transport_timeout_s, read_timeout_s, timeout_s, False) + + def shell( + self, + command, + transport_timeout_s=None, + read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, + timeout_s=None, + decode=True, + ): """Send an ADB shell command to the device. Parameters @@ -837,11 +920,15 @@ def shell(self, command, transport_timeout_s=None, read_timeout_s=constants.DEFA """ if not self.available: - raise exceptions.AdbConnectionError("ADB command not sent because a connection to the device has not been established. (Did you call `AdbDevice.connect()`?)") + raise exceptions.AdbConnectionError( + "ADB command not sent because a connection to the device has not been established. (Did you call `AdbDevice.connect()`?)" + ) - return self._service(b'shell', command.encode('utf8'), transport_timeout_s, read_timeout_s, timeout_s, decode) + return self._service(b"shell", command.encode("utf8"), transport_timeout_s, read_timeout_s, timeout_s, decode) - def streaming_shell(self, command, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, decode=True): + def streaming_shell( + self, command, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, decode=True + ): """Send an ADB shell command to the device, yielding each line of output. Parameters @@ -863,9 +950,13 @@ def streaming_shell(self, command, transport_timeout_s=None, read_timeout_s=cons """ if not self.available: - raise exceptions.AdbConnectionError("ADB command not sent because a connection to the device has not been established. (Did you call `AdbDevice.connect()`?)") + raise exceptions.AdbConnectionError( + "ADB command not sent because a connection to the device has not been established. (Did you call `AdbDevice.connect()`?)" + ) - for line in self._streaming_service(b'shell', command.encode('utf8'), transport_timeout_s, read_timeout_s, decode): + for line in self._streaming_service( + b"shell", command.encode("utf8"), transport_timeout_s, read_timeout_s, decode + ): yield line # ======================================================================= # @@ -894,7 +985,9 @@ def list(self, device_path, transport_timeout_s=None, read_timeout_s=constants.D if not device_path: raise exceptions.DevicePathInvalidError("Cannot list an empty device path") if not self.available: - raise exceptions.AdbConnectionError("ADB command not sent because a connection to the device has not been established. (Did you call `AdbDevice.connect()`?)") + raise exceptions.AdbConnectionError( + "ADB command not sent because a connection to the device has not been established. (Did you call `AdbDevice.connect()`?)" + ) adb_info = self._open(b"sync:", transport_timeout_s, read_timeout_s, None) filesync_info = _FileSyncTransactionInfo(constants.FILESYNC_LIST_FORMAT, maxdata=self._maxdata) @@ -902,7 +995,9 @@ def list(self, device_path, transport_timeout_s=None, read_timeout_s=constants.D self._filesync_send(constants.LIST, adb_info, filesync_info, data=device_path) files = [] - for cmd_id, header, filename in self._filesync_read_until([constants.DENT], [constants.DONE], adb_info, filesync_info): + for cmd_id, header, filename in self._filesync_read_until( + [constants.DENT], [constants.DONE], adb_info, filesync_info + ): if cmd_id == constants.DONE: break @@ -913,7 +1008,14 @@ def list(self, device_path, transport_timeout_s=None, read_timeout_s=constants.D return files - def pull(self, device_path, local_path, progress_callback=None, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S): + def pull( + self, + device_path, + local_path, + progress_callback=None, + transport_timeout_s=None, + read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, + ): """Pull a file from the device. Parameters @@ -933,11 +1035,13 @@ def pull(self, device_path, local_path, progress_callback=None, transport_timeou if not device_path: raise exceptions.DevicePathInvalidError("Cannot pull from an empty device path") if not self.available: - raise exceptions.AdbConnectionError("ADB command not sent because a connection to the device has not been established. (Did you call `AdbDevice.connect()`?)") + raise exceptions.AdbConnectionError( + "ADB command not sent because a connection to the device has not been established. (Did you call `AdbDevice.connect()`?)" + ) opener = _open_bytesio if isinstance(local_path, BytesIO) else open - with opener(local_path, 'wb') as stream: - adb_info = self._open(b'sync:', transport_timeout_s, read_timeout_s, None) + with opener(local_path, "wb") as stream: + adb_info = self._open(b"sync:", transport_timeout_s, read_timeout_s, None) filesync_info = _FileSyncTransactionInfo(constants.FILESYNC_PULL_FORMAT, maxdata=self._maxdata) try: @@ -977,7 +1081,16 @@ def _pull(self, device_path, stream, progress_callback, adb_info, filesync_info) except: # noqa pylint: disable=bare-except pass - def push(self, local_path, device_path, st_mode=constants.DEFAULT_PUSH_MODE, mtime=0, progress_callback=None, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S): + def push( + self, + local_path, + device_path, + st_mode=constants.DEFAULT_PUSH_MODE, + mtime=0, + progress_callback=None, + transport_timeout_s=None, + read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, + ): """Push a file or directory to the device. Parameters @@ -1001,7 +1114,9 @@ def push(self, local_path, device_path, st_mode=constants.DEFAULT_PUSH_MODE, mti if not device_path: raise exceptions.DevicePathInvalidError("Cannot push to an empty device path") if not self.available: - raise exceptions.AdbConnectionError("ADB command not sent because a connection to the device has not been established. (Did you call `AdbDevice.connect()`?)") + raise exceptions.AdbConnectionError( + "ADB command not sent because a connection to the device has not been established. (Did you call `AdbDevice.connect()`?)" + ) local_path_is_dir, local_paths, device_paths = get_files_to_push(local_path, device_path) @@ -1010,8 +1125,8 @@ def push(self, local_path, device_path, st_mode=constants.DEFAULT_PUSH_MODE, mti for _local_path, _device_path in zip(local_paths, device_paths): opener = _open_bytesio if isinstance(local_path, BytesIO) else open - with opener(_local_path, 'rb') as stream: - adb_info = self._open(b'sync:', transport_timeout_s, read_timeout_s, None) + with opener(_local_path, "rb") as stream: + adb_info = self._open(b"sync:", transport_timeout_s, read_timeout_s, None) filesync_info = _FileSyncTransactionInfo(constants.FILESYNC_PUSH_FORMAT, maxdata=self._maxdata) self._push(stream, _device_path, st_mode, mtime, progress_callback, adb_info, filesync_info) @@ -1042,7 +1157,7 @@ def _push(self, stream, device_path, st_mode, mtime, progress_callback, adb_info Raised on push failure. """ - fileinfo = ('{},{}'.format(device_path, int(st_mode))).encode('utf-8') + fileinfo = ("{},{}".format(device_path, int(st_mode))).encode("utf-8") self._filesync_send(constants.SEND, adb_info, filesync_info, data=fileinfo) @@ -1098,9 +1213,11 @@ def stat(self, device_path, transport_timeout_s=None, read_timeout_s=constants.D if not device_path: raise exceptions.DevicePathInvalidError("Cannot stat an empty device path") if not self.available: - raise exceptions.AdbConnectionError("ADB command not sent because a connection to the device has not been established. (Did you call `AdbDevice.connect()`?)") + raise exceptions.AdbConnectionError( + "ADB command not sent because a connection to the device has not been established. (Did you call `AdbDevice.connect()`?)" + ) - adb_info = self._open(b'sync:', transport_timeout_s, read_timeout_s, None) + adb_info = self._open(b"sync:", transport_timeout_s, read_timeout_s, None) filesync_info = _FileSyncTransactionInfo(constants.FILESYNC_STAT_FORMAT, maxdata=self._maxdata) self._filesync_send(constants.STAT, adb_info, filesync_info, data=device_path) @@ -1179,9 +1296,11 @@ def _open(self, destination, transport_timeout_s, read_timeout_s, timeout_s): if self._local_id == 2**32: self._local_id = 1 - adb_info = _AdbTransactionInfo(self._local_id, None, self._get_transport_timeout_s(transport_timeout_s), read_timeout_s, timeout_s) + adb_info = _AdbTransactionInfo( + self._local_id, None, self._get_transport_timeout_s(transport_timeout_s), read_timeout_s, timeout_s + ) - msg = AdbMessage(constants.OPEN, adb_info.local_id, 0, destination + b'\0') + msg = AdbMessage(constants.OPEN, adb_info.local_id, 0, destination + b"\0") self._io_manager.send(msg, adb_info) _, adb_info.remote_id, _, _ = self._io_manager.read([constants.OKAY], adb_info) @@ -1251,7 +1370,9 @@ def _read_until_close(self, adb_info): # Make sure the ADB command has not timed out if adb_info.timeout_s is not None and time.time() - start > adb_info.timeout_s: - raise exceptions.AdbTimeoutError("The command did not complete within {} seconds".format(adb_info.timeout_s)) + raise exceptions.AdbTimeoutError( + "The command did not complete within {} seconds".format(adb_info.timeout_s) + ) def _streaming_command(self, service, command, transport_timeout_s, read_timeout_s, timeout_s): """One complete set of packets for a single command. @@ -1285,7 +1406,7 @@ def _streaming_command(self, service, command, transport_timeout_s, read_timeout The responses from the service. """ - adb_info = self._open(b'%s:%s' % (service, command), transport_timeout_s, read_timeout_s, timeout_s) + adb_info = self._open(b"%s:%s" % (service, command), transport_timeout_s, read_timeout_s, timeout_s) for data in self._read_until_close(adb_info): yield data @@ -1307,7 +1428,9 @@ def _filesync_flush(self, adb_info, filesync_info): """ # Send the buffer - msg = AdbMessage(constants.WRTE, adb_info.local_id, adb_info.remote_id, filesync_info.send_buffer[:filesync_info.send_idx]) + msg = AdbMessage( + constants.WRTE, adb_info.local_id, adb_info.remote_id, filesync_info.send_buffer[: filesync_info.send_idx] + ) self._io_manager.send(msg, adb_info) # Expect an 'OKAY' in response @@ -1367,11 +1490,11 @@ def _filesync_read(self, expected_ids, adb_info, filesync_info): if command_id not in expected_ids: if command_id == constants.FAIL: - reason = data.decode('utf-8', errors=_DECODE_ERRORS) + reason = data.decode("utf-8", errors=_DECODE_ERRORS) - raise exceptions.AdbCommandFailureException('Command failed: {}'.format(reason)) + raise exceptions.AdbCommandFailureException("Command failed: {}".format(reason)) - raise exceptions.InvalidResponseError('Expected one of %s, got %s' % (expected_ids, command_id)) + raise exceptions.InvalidResponseError("Expected one of %s, got %s" % (expected_ids, command_id)) if not read_data: return command_id, header[1:], None @@ -1438,7 +1561,7 @@ def _filesync_read_until(self, expected_ids, finish_ids, adb_info, filesync_info if cmd_id in finish_ids: # pragma: no cover break - def _filesync_send(self, command_id, adb_info, filesync_info, data=b'', size=None): + def _filesync_send(self, command_id, adb_info, filesync_info, data=b"", size=None): """Send/buffer FileSync packets. Packets are buffered and only flushed when this connection is read from. All @@ -1459,15 +1582,15 @@ def _filesync_send(self, command_id, adb_info, filesync_info, data=b'', size=Non """ if not isinstance(data, bytes): - data = data.encode('utf8') + data = data.encode("utf8") if size is None: size = len(data) if not filesync_info.can_add_to_send_buffer(len(data)): self._filesync_flush(adb_info, filesync_info) - buf = struct.pack(b'<2I', constants.FILESYNC_ID_TO_WIRE[command_id], size) + data - filesync_info.send_buffer[filesync_info.send_idx:filesync_info.send_idx + len(buf)] = buf + buf = struct.pack(b"<2I", constants.FILESYNC_ID_TO_WIRE[command_id], size) + data + filesync_info.send_buffer[filesync_info.send_idx : filesync_info.send_idx + len(buf)] = buf filesync_info.send_idx += len(buf) @@ -1547,7 +1670,9 @@ class AdbDeviceUsb(AdbDevice): def __init__(self, serial=None, port_path=None, default_transport_timeout_s=None, banner=None): if UsbTransport is None: - raise exceptions.InvalidTransportError("To enable USB support you must install this package via `pip install adb-shell[usb]`") + raise exceptions.InvalidTransportError( + "To enable USB support you must install this package via `pip install adb-shell[usb]`" + ) transport = UsbTransport.find_adb(serial, port_path, default_transport_timeout_s) super(AdbDeviceUsb, self).__init__(transport, default_transport_timeout_s, banner) diff --git a/adb_shell/adb_device_async.py b/adb_shell/adb_device_async.py index 84ce5235..9f55e609 100644 --- a/adb_shell/adb_device_async.py +++ b/adb_shell/adb_device_async.py @@ -87,7 +87,14 @@ from .adb_message import AdbMessage, checksum, int_to_cmd, unpack from .transport.base_transport_async import BaseTransportAsync from .transport.tcp_transport_async import TcpTransportAsync -from .hidden_helpers import DeviceFile, _AdbPacketStore, _AdbTransactionInfo, _FileSyncTransactionInfo, get_banner, get_files_to_push +from .hidden_helpers import ( + DeviceFile, + _AdbPacketStore, + _AdbTransactionInfo, + _FileSyncTransactionInfo, + get_banner, + get_files_to_push, +) _LOGGER = logging.getLogger(__name__) @@ -190,9 +197,7 @@ def __init__(self, transport): self._transport_lock = Lock() async def close(self): - """Close the connection via the provided transport's ``close()`` method and clear the packet store. - - """ + """Close the connection via the provided transport's ``close()`` method and clear the packet store.""" async with self._transport_lock: await self._transport.close() @@ -258,11 +263,13 @@ async def connect(self, banner, rsa_keys, auth_timeout_s, auth_callback, adb_inf await self._transport.connect(adb_info.transport_timeout_s) # 2. Send a ``b'CNXN'`` message - msg = AdbMessage(constants.CNXN, constants.VERSION, constants.MAX_ADB_DATA, b'host::%s\0' % banner) + msg = AdbMessage(constants.CNXN, constants.VERSION, constants.MAX_ADB_DATA, b"host::%s\0" % banner) await self._send(msg, adb_info) # 3. Read the response from the device - cmd, arg0, maxdata, banner2 = await self._read_expected_packet_from_device([constants.AUTH, constants.CNXN], adb_info) + cmd, arg0, maxdata, banner2 = await self._read_expected_packet_from_device( + [constants.AUTH, constants.CNXN], adb_info + ) # 4. If ``cmd`` is not ``b'AUTH'``, then authentication is not necesary and so we are done if cmd != constants.AUTH: @@ -271,14 +278,14 @@ async def connect(self, banner, rsa_keys, auth_timeout_s, auth_callback, adb_inf # 5. If no ``rsa_keys`` are provided, raise an exception if not rsa_keys: await self._transport.close() - raise exceptions.DeviceAuthError('Device authentication required, no keys available.') + raise exceptions.DeviceAuthError("Device authentication required, no keys available.") # 6. Loop through our keys, signing the last ``banner2`` that we received for rsa_key in rsa_keys: # 6.1. If the last ``arg0`` was not :const:`adb_shell.constants.AUTH_TOKEN`, raise an exception if arg0 != constants.AUTH_TOKEN: await self._transport.close() - raise exceptions.InvalidResponseError('Unknown AUTH response: %s %s %s' % (arg0, maxdata, banner2)) + raise exceptions.InvalidResponseError("Unknown AUTH response: %s %s %s" % (arg0, maxdata, banner2)) # 6.2. Sign the last ``banner2`` and send it in an ``b'AUTH'`` message signed_token = rsa_key.Sign(banner2) @@ -286,7 +293,9 @@ async def connect(self, banner, rsa_keys, auth_timeout_s, auth_callback, adb_inf await self._send(msg, adb_info) # 6.3. Read the response from the device - cmd, arg0, maxdata, banner2 = await self._read_expected_packet_from_device([constants.CNXN, constants.AUTH], adb_info) + cmd, arg0, maxdata, banner2 = await self._read_expected_packet_from_device( + [constants.CNXN, constants.AUTH], adb_info + ) # 6.4. If ``cmd`` is ``b'CNXN'``, we are done if cmd == constants.CNXN: @@ -295,12 +304,12 @@ async def connect(self, banner, rsa_keys, auth_timeout_s, auth_callback, adb_inf # 7. None of the keys worked, so send ``rsa_keys[0]``'s public key; if the response does not time out, we must have connected successfully pubkey = rsa_keys[0].GetPublicKey() if not isinstance(pubkey, (bytes, bytearray)): - pubkey = bytearray(pubkey, 'utf-8') + pubkey = bytearray(pubkey, "utf-8") if auth_callback is not None: auth_callback(self) - msg = AdbMessage(constants.AUTH, constants.AUTH_RSAPUBLICKEY, 0, pubkey + b'\0') + msg = AdbMessage(constants.AUTH, constants.AUTH_RSAPUBLICKEY, 0, pubkey + b"\0") await self._send(msg, adb_info) adb_info.transport_timeout_s = auth_timeout_s @@ -348,13 +357,21 @@ async def read(self, expected_cmds, adb_info, allow_zeros=False): # First, try reading from the store. This way, you won't be waiting for the transport if it isn't needed async with self._store_lock: # Recall that `arg0` from the device corresponds to `adb_info.remote_id` and `arg1` from the device corresponds to `adb_info.local_id` - arg0_arg1 = self._packet_store.find(adb_info.remote_id, adb_info.local_id) if not allow_zeros else self._packet_store.find_allow_zeros(adb_info.remote_id, adb_info.local_id) + arg0_arg1 = ( + self._packet_store.find(adb_info.remote_id, adb_info.local_id) + if not allow_zeros + else self._packet_store.find_allow_zeros(adb_info.remote_id, adb_info.local_id) + ) while arg0_arg1: cmd, arg0, arg1, data = self._packet_store.get(arg0_arg1[0], arg0_arg1[1]) if cmd in expected_cmds: return cmd, arg0, arg1, data - arg0_arg1 = self._packet_store.find(adb_info.remote_id, adb_info.local_id) if not allow_zeros else self._packet_store.find_allow_zeros(adb_info.remote_id, adb_info.local_id) + arg0_arg1 = ( + self._packet_store.find(adb_info.remote_id, adb_info.local_id) + if not allow_zeros + else self._packet_store.find_allow_zeros(adb_info.remote_id, adb_info.local_id) + ) # Start the timer start = time.time() @@ -364,13 +381,21 @@ async def read(self, expected_cmds, adb_info, allow_zeros=False): # Try reading from the store (again) in case a packet got added while waiting to acquire the transport lock async with self._store_lock: # Recall that `arg0` from the device corresponds to `adb_info.remote_id` and `arg1` from the device corresponds to `adb_info.local_id` - arg0_arg1 = self._packet_store.find(adb_info.remote_id, adb_info.local_id) if not allow_zeros else self._packet_store.find_allow_zeros(adb_info.remote_id, adb_info.local_id) + arg0_arg1 = ( + self._packet_store.find(adb_info.remote_id, adb_info.local_id) + if not allow_zeros + else self._packet_store.find_allow_zeros(adb_info.remote_id, adb_info.local_id) + ) while arg0_arg1: cmd, arg0, arg1, data = self._packet_store.get(arg0_arg1[0], arg0_arg1[1]) if cmd in expected_cmds: return cmd, arg0, arg1, data - arg0_arg1 = self._packet_store.find(adb_info.remote_id, adb_info.local_id) if not allow_zeros else self._packet_store.find_allow_zeros(adb_info.remote_id, adb_info.local_id) + arg0_arg1 = ( + self._packet_store.find(adb_info.remote_id, adb_info.local_id) + if not allow_zeros + else self._packet_store.find_allow_zeros(adb_info.remote_id, adb_info.local_id) + ) # Read from the device cmd, arg0, arg1, data = await self._read_packet_from_device(adb_info) @@ -396,7 +421,11 @@ async def read(self, expected_cmds, adb_info, allow_zeros=False): break # Timeout - raise exceptions.AdbTimeoutError("Never got one of the expected responses: {} (transport_timeout_s = {}, read_timeout_s = {})".format(expected_cmds, adb_info.transport_timeout_s, adb_info.read_timeout_s)) + raise exceptions.AdbTimeoutError( + "Never got one of the expected responses: {} (transport_timeout_s = {}, read_timeout_s = {})".format( + expected_cmds, adb_info.transport_timeout_s, adb_info.read_timeout_s + ) + ) async def send(self, msg, adb_info): """Send a message to the device. @@ -449,7 +478,11 @@ async def _read_expected_packet_from_device(self, expected_cmds, adb_info): if time.time() - start > adb_info.read_timeout_s: # Timeout - raise exceptions.AdbTimeoutError("Never got one of the expected responses: {} (transport_timeout_s = {}, read_timeout_s = {})".format(expected_cmds, adb_info.transport_timeout_s, adb_info.read_timeout_s)) + raise exceptions.AdbTimeoutError( + "Never got one of the expected responses: {} (transport_timeout_s = {}, read_timeout_s = {})".format( + expected_cmds, adb_info.transport_timeout_s, adb_info.read_timeout_s + ) + ) async def _read_bytes_from_device(self, length, adb_info): """Read ``length`` bytes from the device. @@ -489,7 +522,11 @@ async def _read_bytes_from_device(self, length, adb_info): if time.time() - start > adb_info.read_timeout_s: # Timeout - raise exceptions.AdbTimeoutError("Timeout: read {} of {} bytes (transport_timeout_s = {}, read_timeout_s = {})".format(len(data), len(data) + length, adb_info.transport_timeout_s, adb_info.read_timeout_s)) + raise exceptions.AdbTimeoutError( + "Timeout: read {} of {} bytes (transport_timeout_s = {}, read_timeout_s = {})".format( + len(data), len(data) + length, adb_info.transport_timeout_s, adb_info.read_timeout_s + ) + ) return bytes(data) @@ -519,13 +556,16 @@ async def _read_packet_from_device(self, adb_info): adb_shell.exceptions.InvalidChecksumError Received checksum does not match the expected checksum - """ + """ msg = await self._read_bytes_from_device(constants.MESSAGE_SIZE, adb_info) cmd, arg0, arg1, data_length, data_checksum = unpack(msg) command = constants.WIRE_TO_ID.get(cmd) if not command: - raise exceptions.InvalidCommandError("Unknown command: %d = '%s' (arg0 = %d, arg1 = %d, msg = '%s')" % (cmd, int_to_cmd(cmd), arg0, arg1, msg)) + raise exceptions.InvalidCommandError( + "Unknown command: %d = '%s' (arg0 = %d, arg1 = %d, msg = '%s')" + % (cmd, int_to_cmd(cmd), arg0, arg1, msg) + ) if data_length == 0: return command, arg0, arg1, b"" @@ -602,12 +642,14 @@ class AdbDeviceAsync(object): def __init__(self, transport, default_transport_timeout_s=None, banner=None): if banner and not isinstance(banner, (bytes, bytearray)): - self._banner = bytearray(banner, 'utf-8') + self._banner = bytearray(banner, "utf-8") else: self._banner = banner if not isinstance(transport, BaseTransportAsync): - raise exceptions.InvalidTransportError("`transport` must be an instance of a subclass of `BaseTransportAsync`") + raise exceptions.InvalidTransportError( + "`transport` must be an instance of a subclass of `BaseTransportAsync`" + ) self._io_manager = _AdbIOManagerAsync(transport) @@ -668,13 +710,18 @@ def _get_transport_timeout_s(self, transport_timeout_s): # # # ======================================================================= # async def close(self): - """Close the connection via the provided transport's ``close()`` method. - - """ + """Close the connection via the provided transport's ``close()`` method.""" self._available = False await self._io_manager.close() - async def connect(self, rsa_keys=None, transport_timeout_s=None, auth_timeout_s=constants.DEFAULT_AUTH_TIMEOUT_S, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, auth_callback=None): + async def connect( + self, + rsa_keys=None, + transport_timeout_s=None, + auth_timeout_s=constants.DEFAULT_AUTH_TIMEOUT_S, + read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, + auth_callback=None, + ): """Establish an ADB connection to the device. See :meth:`_AdbIOManagerAsync.connect`. @@ -705,13 +752,17 @@ async def connect(self, rsa_keys=None, transport_timeout_s=None, auth_timeout_s= self._banner = await get_running_loop().run_in_executor(None, get_banner) # Instantiate the `_AdbTransactionInfo` - adb_info = _AdbTransactionInfo(None, None, self._get_transport_timeout_s(transport_timeout_s), read_timeout_s, None) + adb_info = _AdbTransactionInfo( + None, None, self._get_transport_timeout_s(transport_timeout_s), read_timeout_s, None + ) # Mark the device as unavailable self._available = False # Use the IO manager to connect - self._available, self._maxdata = await self._io_manager.connect(self._banner, rsa_keys, auth_timeout_s, auth_callback, adb_info) + self._available, self._maxdata = await self._io_manager.connect( + self._banner, rsa_keys, auth_timeout_s, auth_callback, adb_info + ) return self._available @@ -720,7 +771,15 @@ async def connect(self, rsa_keys=None, transport_timeout_s=None, auth_timeout_s= # Services # # # # ======================================================================= # - async def _service(self, service, command, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, timeout_s=None, decode=True): + async def _service( + self, + service, + command, + transport_timeout_s=None, + read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, + timeout_s=None, + decode=True, + ): """Send an ADB command to the device. Parameters @@ -746,10 +805,21 @@ async def _service(self, service, command, transport_timeout_s=None, read_timeou """ if decode: - return b''.join([x async for x in self._streaming_command(service, command, transport_timeout_s, read_timeout_s, timeout_s)]).decode('utf8', 'backslashreplace') - return b''.join([x async for x in self._streaming_command(service, command, transport_timeout_s, read_timeout_s, timeout_s)]) - - async def _streaming_service(self, service, command, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, decode=True): + return b"".join( + [ + x + async for x in self._streaming_command( + service, command, transport_timeout_s, read_timeout_s, timeout_s + ) + ] + ).decode("utf8", "backslashreplace") + return b"".join( + [x async for x in self._streaming_command(service, command, transport_timeout_s, read_timeout_s, timeout_s)] + ) + + async def _streaming_service( + self, service, command, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, decode=True + ): """Send an ADB command to the device, yielding each line of output. Parameters @@ -774,13 +844,20 @@ async def _streaming_service(self, service, command, transport_timeout_s=None, r """ stream = self._streaming_command(service, command, transport_timeout_s, read_timeout_s, None) if decode: - async for line in (stream_line.decode('utf8', 'backslashreplace') async for stream_line in stream): + async for line in (stream_line.decode("utf8", "backslashreplace") async for stream_line in stream): yield line else: async for line in stream: yield line - async def exec_out(self, command, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, timeout_s=None, decode=True): + async def exec_out( + self, + command, + transport_timeout_s=None, + read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, + timeout_s=None, + decode=True, + ): """Send an ADB ``exec-out`` command to the device. https://www.linux-magazine.com/Issues/2017/195/Ask-Klaus @@ -806,11 +883,17 @@ async def exec_out(self, command, transport_timeout_s=None, read_timeout_s=const """ if not self.available: - raise exceptions.AdbConnectionError("ADB command not sent because a connection to the device has not been established. (Did you call `AdbDeviceAsync.connect()`?)") + raise exceptions.AdbConnectionError( + "ADB command not sent because a connection to the device has not been established. (Did you call `AdbDeviceAsync.connect()`?)" + ) - return await self._service(b'exec', command.encode('utf8'), transport_timeout_s, read_timeout_s, timeout_s, decode) + return await self._service( + b"exec", command.encode("utf8"), transport_timeout_s, read_timeout_s, timeout_s, decode + ) - async def reboot(self, fastboot=False, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, timeout_s=None): + async def reboot( + self, fastboot=False, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, timeout_s=None + ): """Reboot the device. Parameters @@ -827,9 +910,13 @@ async def reboot(self, fastboot=False, transport_timeout_s=None, read_timeout_s= """ if not self.available: - raise exceptions.AdbConnectionError("ADB command not sent because a connection to the device has not been established. (Did you call `AdbDeviceAsync.connect()`?)") + raise exceptions.AdbConnectionError( + "ADB command not sent because a connection to the device has not been established. (Did you call `AdbDeviceAsync.connect()`?)" + ) - await self._open(b'reboot:bootloader' if fastboot else b'reboot:', transport_timeout_s, read_timeout_s, timeout_s) + await self._open( + b"reboot:bootloader" if fastboot else b"reboot:", transport_timeout_s, read_timeout_s, timeout_s + ) async def root(self, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, timeout_s=None): """Gain root access. @@ -848,11 +935,20 @@ async def root(self, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_ """ if not self.available: - raise exceptions.AdbConnectionError("ADB command not sent because a connection to the device has not been established. (Did you call `AdbDeviceAsync.connect()`?)") - - await self._service(b'root', b'', transport_timeout_s, read_timeout_s, timeout_s, False) - - async def shell(self, command, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, timeout_s=None, decode=True): + raise exceptions.AdbConnectionError( + "ADB command not sent because a connection to the device has not been established. (Did you call `AdbDeviceAsync.connect()`?)" + ) + + await self._service(b"root", b"", transport_timeout_s, read_timeout_s, timeout_s, False) + + async def shell( + self, + command, + transport_timeout_s=None, + read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, + timeout_s=None, + decode=True, + ): """Send an ADB shell command to the device. Parameters @@ -876,11 +972,17 @@ async def shell(self, command, transport_timeout_s=None, read_timeout_s=constant """ if not self.available: - raise exceptions.AdbConnectionError("ADB command not sent because a connection to the device has not been established. (Did you call `AdbDeviceAsync.connect()`?)") + raise exceptions.AdbConnectionError( + "ADB command not sent because a connection to the device has not been established. (Did you call `AdbDeviceAsync.connect()`?)" + ) - return await self._service(b'shell', command.encode('utf8'), transport_timeout_s, read_timeout_s, timeout_s, decode) + return await self._service( + b"shell", command.encode("utf8"), transport_timeout_s, read_timeout_s, timeout_s, decode + ) - async def streaming_shell(self, command, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, decode=True): + async def streaming_shell( + self, command, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, decode=True + ): """Send an ADB shell command to the device, yielding each line of output. Parameters @@ -902,9 +1004,13 @@ async def streaming_shell(self, command, transport_timeout_s=None, read_timeout_ """ if not self.available: - raise exceptions.AdbConnectionError("ADB command not sent because a connection to the device has not been established. (Did you call `AdbDeviceAsync.connect()`?)") + raise exceptions.AdbConnectionError( + "ADB command not sent because a connection to the device has not been established. (Did you call `AdbDeviceAsync.connect()`?)" + ) - async for line in self._streaming_service(b'shell', command.encode('utf8'), transport_timeout_s, read_timeout_s, decode): + async for line in self._streaming_service( + b"shell", command.encode("utf8"), transport_timeout_s, read_timeout_s, decode + ): yield line # ======================================================================= # @@ -933,15 +1039,19 @@ async def list(self, device_path, transport_timeout_s=None, read_timeout_s=const if not device_path: raise exceptions.DevicePathInvalidError("Cannot list an empty device path") if not self.available: - raise exceptions.AdbConnectionError("ADB command not sent because a connection to the device has not been established. (Did you call `AdbDeviceAsync.connect()`?)") + raise exceptions.AdbConnectionError( + "ADB command not sent because a connection to the device has not been established. (Did you call `AdbDeviceAsync.connect()`?)" + ) - adb_info = await self._open(b'sync:', transport_timeout_s, read_timeout_s, None) + adb_info = await self._open(b"sync:", transport_timeout_s, read_timeout_s, None) filesync_info = _FileSyncTransactionInfo(constants.FILESYNC_LIST_FORMAT, maxdata=self._maxdata) await self._filesync_send(constants.LIST, adb_info, filesync_info, data=device_path) files = [] - async for cmd_id, header, filename in self._filesync_read_until([constants.DENT], [constants.DONE], adb_info, filesync_info): + async for cmd_id, header, filename in self._filesync_read_until( + [constants.DENT], [constants.DONE], adb_info, filesync_info + ): if cmd_id == constants.DONE: break @@ -952,7 +1062,14 @@ async def list(self, device_path, transport_timeout_s=None, read_timeout_s=const return files - async def pull(self, device_path, local_path, progress_callback=None, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S): + async def pull( + self, + device_path, + local_path, + progress_callback=None, + transport_timeout_s=None, + read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, + ): """Pull a file from the device. Parameters @@ -972,11 +1089,13 @@ async def pull(self, device_path, local_path, progress_callback=None, transport_ if not device_path: raise exceptions.DevicePathInvalidError("Cannot pull from an empty device path") if not self.available: - raise exceptions.AdbConnectionError("ADB command not sent because a connection to the device has not been established. (Did you call `AdbDeviceAsync.connect()`?)") + raise exceptions.AdbConnectionError( + "ADB command not sent because a connection to the device has not been established. (Did you call `AdbDeviceAsync.connect()`?)" + ) opener = _open_bytesio if isinstance(local_path, BytesIO) else aiofiles.open - async with opener(local_path, 'wb') as stream: - adb_info = await self._open(b'sync:', transport_timeout_s, read_timeout_s, None) + async with opener(local_path, "wb") as stream: + adb_info = await self._open(b"sync:", transport_timeout_s, read_timeout_s, None) filesync_info = _FileSyncTransactionInfo(constants.FILESYNC_PULL_FORMAT, maxdata=self._maxdata) try: @@ -1005,7 +1124,9 @@ async def _pull(self, device_path, stream, progress_callback, adb_info, filesync total_bytes = (await self.stat(device_path))[1] await self._filesync_send(constants.RECV, adb_info, filesync_info, data=device_path) - async for cmd_id, _, data in self._filesync_read_until([constants.DATA], [constants.DONE], adb_info, filesync_info): + async for cmd_id, _, data in self._filesync_read_until( + [constants.DATA], [constants.DONE], adb_info, filesync_info + ): if cmd_id == constants.DONE: break @@ -1016,7 +1137,16 @@ async def _pull(self, device_path, stream, progress_callback, adb_info, filesync except: # noqa pylint: disable=bare-except pass - async def push(self, local_path, device_path, st_mode=constants.DEFAULT_PUSH_MODE, mtime=0, progress_callback=None, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S): + async def push( + self, + local_path, + device_path, + st_mode=constants.DEFAULT_PUSH_MODE, + mtime=0, + progress_callback=None, + transport_timeout_s=None, + read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, + ): """Push a file or directory to the device. Parameters @@ -1040,17 +1170,21 @@ async def push(self, local_path, device_path, st_mode=constants.DEFAULT_PUSH_MOD if not device_path: raise exceptions.DevicePathInvalidError("Cannot push to an empty device path") if not self.available: - raise exceptions.AdbConnectionError("ADB command not sent because a connection to the device has not been established. (Did you call `AdbDeviceAsync.connect()`?)") + raise exceptions.AdbConnectionError( + "ADB command not sent because a connection to the device has not been established. (Did you call `AdbDeviceAsync.connect()`?)" + ) - local_path_is_dir, local_paths, device_paths = await get_running_loop().run_in_executor(None, get_files_to_push, local_path, device_path) + local_path_is_dir, local_paths, device_paths = await get_running_loop().run_in_executor( + None, get_files_to_push, local_path, device_path + ) if local_path_is_dir: await self.shell("mkdir " + device_path, transport_timeout_s, read_timeout_s) for _local_path, _device_path in zip(local_paths, device_paths): opener = _open_bytesio if isinstance(local_path, BytesIO) else aiofiles.open - async with opener(_local_path, 'rb') as stream: - adb_info = await self._open(b'sync:', transport_timeout_s, read_timeout_s, None) + async with opener(_local_path, "rb") as stream: + adb_info = await self._open(b"sync:", transport_timeout_s, read_timeout_s, None) filesync_info = _FileSyncTransactionInfo(constants.FILESYNC_PUSH_FORMAT, maxdata=self._maxdata) await self._push(stream, _device_path, st_mode, mtime, progress_callback, adb_info, filesync_info) @@ -1081,7 +1215,7 @@ async def _push(self, stream, device_path, st_mode, mtime, progress_callback, ad Raised on push failure. """ - fileinfo = ('{},{}'.format(device_path, int(st_mode))).encode('utf-8') + fileinfo = ("{},{}".format(device_path, int(st_mode))).encode("utf-8") await self._filesync_send(constants.SEND, adb_info, filesync_info, data=fileinfo) @@ -1106,7 +1240,9 @@ async def _push(self, stream, device_path, st_mode, mtime, progress_callback, ad # DONE doesn't send data, but it hides the last bit of data in the size field. await self._filesync_send(constants.DONE, adb_info, filesync_info, size=mtime) - async for cmd_id, _, data in self._filesync_read_until([], [constants.OKAY, constants.FAIL], adb_info, filesync_info): + async for cmd_id, _, data in self._filesync_read_until( + [], [constants.OKAY, constants.FAIL], adb_info, filesync_info + ): if cmd_id == constants.OKAY: return @@ -1137,9 +1273,11 @@ async def stat(self, device_path, transport_timeout_s=None, read_timeout_s=const if not device_path: raise exceptions.DevicePathInvalidError("Cannot stat an empty device path") if not self.available: - raise exceptions.AdbConnectionError("ADB command not sent because a connection to the device has not been established. (Did you call `AdbDeviceAsync.connect()`?)") + raise exceptions.AdbConnectionError( + "ADB command not sent because a connection to the device has not been established. (Did you call `AdbDeviceAsync.connect()`?)" + ) - adb_info = await self._open(b'sync:', transport_timeout_s, read_timeout_s, None) + adb_info = await self._open(b"sync:", transport_timeout_s, read_timeout_s, None) filesync_info = _FileSyncTransactionInfo(constants.FILESYNC_STAT_FORMAT, maxdata=self._maxdata) await self._filesync_send(constants.STAT, adb_info, filesync_info, data=device_path) @@ -1218,9 +1356,11 @@ async def _open(self, destination, transport_timeout_s, read_timeout_s, timeout_ if self._local_id == 2**32: self._local_id = 1 - adb_info = _AdbTransactionInfo(self._local_id, None, self._get_transport_timeout_s(transport_timeout_s), read_timeout_s, timeout_s) + adb_info = _AdbTransactionInfo( + self._local_id, None, self._get_transport_timeout_s(transport_timeout_s), read_timeout_s, timeout_s + ) - msg = AdbMessage(constants.OPEN, adb_info.local_id, 0, destination + b'\0') + msg = AdbMessage(constants.OPEN, adb_info.local_id, 0, destination + b"\0") await self._io_manager.send(msg, adb_info) _, adb_info.remote_id, _, _ = await self._io_manager.read([constants.OKAY], adb_info) @@ -1290,7 +1430,9 @@ async def _read_until_close(self, adb_info): # Make sure the ADB command has not timed out if adb_info.timeout_s is not None and time.time() - start > adb_info.timeout_s: - raise exceptions.AdbTimeoutError("The command did not complete within {} seconds".format(adb_info.timeout_s)) + raise exceptions.AdbTimeoutError( + "The command did not complete within {} seconds".format(adb_info.timeout_s) + ) async def _streaming_command(self, service, command, transport_timeout_s, read_timeout_s, timeout_s): """One complete set of packets for a single command. @@ -1324,7 +1466,7 @@ async def _streaming_command(self, service, command, transport_timeout_s, read_t The responses from the service. """ - adb_info = await self._open(b'%s:%s' % (service, command), transport_timeout_s, read_timeout_s, timeout_s) + adb_info = await self._open(b"%s:%s" % (service, command), transport_timeout_s, read_timeout_s, timeout_s) async for data in self._read_until_close(adb_info): yield data @@ -1346,7 +1488,9 @@ async def _filesync_flush(self, adb_info, filesync_info): """ # Send the buffer - msg = AdbMessage(constants.WRTE, adb_info.local_id, adb_info.remote_id, filesync_info.send_buffer[:filesync_info.send_idx]) + msg = AdbMessage( + constants.WRTE, adb_info.local_id, adb_info.remote_id, filesync_info.send_buffer[: filesync_info.send_idx] + ) await self._io_manager.send(msg, adb_info) # Expect an 'OKAY' in response @@ -1406,11 +1550,11 @@ async def _filesync_read(self, expected_ids, adb_info, filesync_info): if command_id not in expected_ids: if command_id == constants.FAIL: - reason = data.decode('utf-8', errors='backslashreplace') + reason = data.decode("utf-8", errors="backslashreplace") - raise exceptions.AdbCommandFailureException('Command failed: {}'.format(reason)) + raise exceptions.AdbCommandFailureException("Command failed: {}".format(reason)) - raise exceptions.InvalidResponseError('Expected one of %s, got %s' % (expected_ids, command_id)) + raise exceptions.InvalidResponseError("Expected one of %s, got %s" % (expected_ids, command_id)) if not read_data: return command_id, header[1:], None @@ -1477,7 +1621,7 @@ async def _filesync_read_until(self, expected_ids, finish_ids, adb_info, filesyn if cmd_id in finish_ids: # pragma: no cover break - async def _filesync_send(self, command_id, adb_info, filesync_info, data=b'', size=None): + async def _filesync_send(self, command_id, adb_info, filesync_info, data=b"", size=None): """Send/buffer FileSync packets. Packets are buffered and only flushed when this connection is read from. All @@ -1498,15 +1642,15 @@ async def _filesync_send(self, command_id, adb_info, filesync_info, data=b'', si """ if not isinstance(data, bytes): - data = data.encode('utf8') + data = data.encode("utf8") if size is None: size = len(data) if not filesync_info.can_add_to_send_buffer(len(data)): await self._filesync_flush(adb_info, filesync_info) - buf = struct.pack(b'<2I', constants.FILESYNC_ID_TO_WIRE[command_id], size) + data - filesync_info.send_buffer[filesync_info.send_idx:filesync_info.send_idx + len(buf)] = buf + buf = struct.pack(b"<2I", constants.FILESYNC_ID_TO_WIRE[command_id], size) + data + filesync_info.send_buffer[filesync_info.send_idx : filesync_info.send_idx + len(buf)] = buf filesync_info.send_idx += len(buf) diff --git a/adb_shell/adb_message.py b/adb_shell/adb_message.py index f7ebddf3..b61d5c5e 100644 --- a/adb_shell/adb_message.py +++ b/adb_shell/adb_message.py @@ -86,7 +86,7 @@ def int_to_cmd(n): The ADB command (e.g., ``'CNXN'``) """ - return ''.join(chr((n >> (i * 8)) % 256) for i in range(4)).encode('utf-8') + return "".join(chr((n >> (i * 8)) % 256) for i in range(4)).encode("utf-8") def unpack(message): @@ -119,7 +119,9 @@ def unpack(message): try: cmd, arg0, arg1, data_length, data_checksum, _ = struct.unpack(constants.MESSAGE_FORMAT, message) except struct.error as e: - raise ValueError('Unable to unpack ADB command. (length={})'.format(len(message)), constants.MESSAGE_FORMAT, message, e) + raise ValueError( + "Unable to unpack ADB command. (length={})".format(len(message)), constants.MESSAGE_FORMAT, message, e + ) return cmd, arg0, arg1, data_length, data_checksum @@ -152,7 +154,8 @@ class AdbMessage(object): ``self.command`` with its bits flipped; in other words, ``self.command + self.magic == 2**32 - 1`` """ - def __init__(self, command, arg0, arg1, data=b''): + + def __init__(self, command, arg0, arg1, data=b""): self.command = constants.ID_TO_WIRE[command] self.magic = self.command ^ 0xFFFFFFFF self.arg0 = arg0 @@ -168,7 +171,9 @@ def pack(self): The message packed into the format required by ADB """ - return struct.pack(constants.MESSAGE_FORMAT, self.command, self.arg0, self.arg1, len(self.data), self.checksum, self.magic) + return struct.pack( + constants.MESSAGE_FORMAT, self.command, self.arg0, self.arg1, len(self.data), self.checksum, self.magic + ) @property def checksum(self): diff --git a/adb_shell/auth/keygen.py b/adb_shell/auth/keygen.py index 46fe945f..3ab73cbc 100644 --- a/adb_shell/auth/keygen.py +++ b/adb_shell/auth/keygen.py @@ -68,12 +68,12 @@ #: Python representation of "struct RSAPublicKey" ANDROID_RSAPUBLICKEY_STRUCT = ( - '<' # Little-endian - 'L' # uint32_t modulus_size_words; - 'L' # uint32_t n0inv; - '{modulus_size}s' # uint8_t modulus[ANDROID_PUBKEY_MODULUS_SIZE]; - '{modulus_size}s' # uint8_t rr[ANDROID_PUBKEY_MODULUS_SIZE]; - 'L' # uint32_t exponent; + "<" # Little-endian + "L" # uint32_t modulus_size_words; + "L" # uint32_t n0inv; + "{modulus_size}s" # uint8_t modulus[ANDROID_PUBKEY_MODULUS_SIZE]; + "{modulus_size}s" # uint8_t rr[ANDROID_PUBKEY_MODULUS_SIZE]; + "L" # uint32_t exponent; ).format(modulus_size=ANDROID_PUBKEY_MODULUS_SIZE) @@ -81,7 +81,7 @@ ANDROID_PUBKEY_MODULUS_SIZE_WORDS = ANDROID_PUBKEY_MODULUS_SIZE // 4 -def _to_bytes(n, length, endianess='big'): +def _to_bytes(n, length, endianess="big"): """Partial python2 compatibility with int.to_bytes https://stackoverflow.com/a/20793663 @@ -101,10 +101,10 @@ def _to_bytes(n, length, endianess='big'): TODO """ - if not hasattr(n, 'to_bytes'): - h = '{:x}'.format(n) - s = ('0' * (len(h) % 2) + h).zfill(length * 2).decode('hex') - return s if endianess == 'big' else s[::-1] + if not hasattr(n, "to_bytes"): + h = "{:x}".format(n) + s = ("0" * (len(h) % 2) + h).zfill(length * 2).decode("hex") + return s if endianess == "big" else s[::-1] return n.to_bytes(length, endianess) @@ -118,15 +118,17 @@ def decode_pubkey(public_key): """ binary_key_data = base64.b64decode(public_key) - modulus_size_words, n0inv, modulus_bytes, rr_bytes, exponent = struct.unpack(ANDROID_RSAPUBLICKEY_STRUCT, binary_key_data) + modulus_size_words, n0inv, modulus_bytes, rr_bytes, exponent = struct.unpack( + ANDROID_RSAPUBLICKEY_STRUCT, binary_key_data + ) assert modulus_size_words == ANDROID_PUBKEY_MODULUS_SIZE_WORDS modulus = reversed(modulus_bytes) rr = reversed(rr_bytes) - _LOGGER.debug('modulus_size_words: %s', hex(modulus_size_words)) - _LOGGER.debug('n0inv: %s', hex(n0inv)) - _LOGGER.debug('modulus: %s', ':'.join((hex(m) for m in modulus))) - _LOGGER.debug('rr: %s', ':'.join((hex(r) for r in rr))) - _LOGGER.debug('exponent: %s', hex(exponent)) + _LOGGER.debug("modulus_size_words: %s", hex(modulus_size_words)) + _LOGGER.debug("n0inv: %s", hex(n0inv)) + _LOGGER.debug("modulus: %s", ":".join((hex(m) for m in modulus))) + _LOGGER.debug("rr: %s", ":".join((hex(r) for r in rr))) + _LOGGER.debug("exponent: %s", hex(exponent)) def decode_pubkey_file(public_key_path): @@ -138,7 +140,7 @@ def decode_pubkey_file(public_key_path): TODO """ - with open(public_key_path, 'rb') as fd: + with open(public_key_path, "rb") as fd: decode_pubkey(fd.read()) @@ -156,8 +158,12 @@ def encode_pubkey(private_key_path): TODO """ - with open(private_key_path, 'rb') as key_file: - key = serialization.load_pem_private_key(key_file.read(), password=None, backend=default_backend()).private_numbers().public_numbers + with open(private_key_path, "rb") as key_file: + key = ( + serialization.load_pem_private_key(key_file.read(), password=None, backend=default_backend()) + .private_numbers() + .public_numbers + ) # Compute and store n0inv = -1 / N[0] mod 2^32. # BN_set_bit(r32, 32) @@ -173,15 +179,15 @@ def encode_pubkey(private_key_path): # BN_set_bit(rr, ANDROID_PUBKEY_MODULUS_SIZE * 8) rr = 1 << (ANDROID_PUBKEY_MODULUS_SIZE * 8) # BN_mod_sqr(rr, rr, key->n, ctx) - rr = (rr ** 2) % key.n + rr = (rr**2) % key.n return struct.pack( ANDROID_RSAPUBLICKEY_STRUCT, ANDROID_PUBKEY_MODULUS_SIZE_WORDS, n0inv, - _to_bytes(key.n, ANDROID_PUBKEY_MODULUS_SIZE, 'little'), - _to_bytes(rr, ANDROID_PUBKEY_MODULUS_SIZE, 'little'), - key.e + _to_bytes(key.n, ANDROID_PUBKEY_MODULUS_SIZE, "little"), + _to_bytes(rr, ANDROID_PUBKEY_MODULUS_SIZE, "little"), + key.e, ) @@ -197,16 +203,16 @@ def get_user_info(): try: username = os.getlogin() except (FileNotFoundError, OSError): - username = 'unknown' + username = "unknown" if not username: - username = 'unknown' + username = "unknown" hostname = socket.gethostname() if not hostname: - hostname = 'unknown' + hostname = "unknown" - return ' ' + username + '@' + hostname + return " " + username + "@" + hostname def write_public_keyfile(private_key_path, public_key_path): @@ -224,7 +230,7 @@ def write_public_keyfile(private_key_path, public_key_path): public_key = encode_pubkey(private_key_path) assert len(public_key) == struct.calcsize(ANDROID_RSAPUBLICKEY_STRUCT) - with open(public_key_path, 'wb') as public_key_file: + with open(public_key_path, "wb") as public_key_file: public_key_file.write(base64.b64encode(public_key)) public_key_file.write(get_user_info().encode()) @@ -245,7 +251,13 @@ def keygen(filepath): """ private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=default_backend()) - with open(filepath, 'wb') as private_key_file: - private_key_file.write(private_key.private_bytes(encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption())) + with open(filepath, "wb") as private_key_file: + private_key_file.write( + private_key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=serialization.NoEncryption(), + ) + ) - write_public_keyfile(filepath, filepath + '.pub') + write_public_keyfile(filepath, filepath + ".pub") diff --git a/adb_shell/auth/sign_cryptography.py b/adb_shell/auth/sign_cryptography.py index b68e78f8..12ad1be8 100644 --- a/adb_shell/auth/sign_cryptography.py +++ b/adb_shell/auth/sign_cryptography.py @@ -48,11 +48,12 @@ class CryptographySigner(object): The loaded private key """ + def __init__(self, rsa_key_path): - with open(rsa_key_path + '.pub', 'rb') as rsa_pub_file: + with open(rsa_key_path + ".pub", "rb") as rsa_pub_file: self.public_key = rsa_pub_file.read() - with open(rsa_key_path, 'rb') as rsa_prv_file: + with open(rsa_key_path, "rb") as rsa_prv_file: self.rsa_key = serialization.load_pem_private_key(rsa_prv_file.read(), None, default_backend()) def Sign(self, data): diff --git a/adb_shell/auth/sign_pycryptodome.py b/adb_shell/auth/sign_pycryptodome.py index f9a551d3..43c1c532 100644 --- a/adb_shell/auth/sign_pycryptodome.py +++ b/adb_shell/auth/sign_pycryptodome.py @@ -45,14 +45,15 @@ class PycryptodomeAuthSigner(object): The contents of theprivate key """ + def __init__(self, rsa_key_path=None): super(PycryptodomeAuthSigner, self).__init__() if rsa_key_path: - with open(rsa_key_path + '.pub', 'rb') as rsa_pub_file: + with open(rsa_key_path + ".pub", "rb") as rsa_pub_file: self.public_key = rsa_pub_file.read() - with open(rsa_key_path, 'rb') as rsa_priv_file: + with open(rsa_key_path, "rb") as rsa_priv_file: self.rsa_key = RSA.import_key(rsa_priv_file.read()) def Sign(self, data): diff --git a/adb_shell/auth/sign_pythonrsa.py b/adb_shell/auth/sign_pythonrsa.py index 0a9d5366..5beaa29e 100644 --- a/adb_shell/auth/sign_pythonrsa.py +++ b/adb_shell/auth/sign_pythonrsa.py @@ -51,8 +51,9 @@ class _Accum(object): A buffer for storing data before it is signed """ + def __init__(self): - self._buf = b'' + self._buf = b"" def update(self, msg): """Update this hash object's state with the provided ``msg``. @@ -77,8 +78,8 @@ def digest(self): return self._buf -pkcs1.HASH_METHODS['SHA-1-PREHASHED'] = _Accum -pkcs1.HASH_ASN1['SHA-1-PREHASHED'] = pkcs1.HASH_ASN1['SHA-1'] +pkcs1.HASH_METHODS["SHA-1-PREHASHED"] = _Accum +pkcs1.HASH_ASN1["SHA-1-PREHASHED"] = pkcs1.HASH_ASN1["SHA-1"] def _load_rsa_private_key(pem): @@ -105,18 +106,18 @@ def _load_rsa_private_key(pem): """ try: - der = rsa.pem.load_pem(pem, 'PRIVATE KEY') + der = rsa.pem.load_pem(pem, "PRIVATE KEY") keyinfo, _ = decoder.decode(der) - if keyinfo[1][0] != univ.ObjectIdentifier('1.2.840.113549.1.1.1'): - raise ValueError('Not a DER-encoded OpenSSL private RSA key') + if keyinfo[1][0] != univ.ObjectIdentifier("1.2.840.113549.1.1.1"): + raise ValueError("Not a DER-encoded OpenSSL private RSA key") private_key_der = keyinfo[2].asOctets() except IndexError: - raise ValueError('Not a DER-encoded OpenSSL private RSA key') + raise ValueError("Not a DER-encoded OpenSSL private RSA key") - return rsa.PrivateKey.load_pkcs1(private_key_der, format='DER') + return rsa.PrivateKey.load_pkcs1(private_key_der, format="DER") class PythonRSASigner(object): @@ -137,6 +138,7 @@ class PythonRSASigner(object): The contents of the public key file """ + def __init__(self, pub=None, priv=None): self.priv_key = _load_rsa_private_key(priv) self.pub_key = pub @@ -156,7 +158,7 @@ def FromRSAKeyPath(cls, rsa_key_path): A :class:`PythonRSASigner` with private key ``rsa_key_path`` and public key ``rsa_key_path + '.pub'`` """ - with open(rsa_key_path + '.pub') as f: + with open(rsa_key_path + ".pub") as f: pub = f.read() with open(rsa_key_path) as f: priv = f.read() @@ -176,7 +178,7 @@ def Sign(self, data): The signed ``data`` """ - return rsa.sign(data, self.priv_key, 'SHA-1-PREHASHED') + return rsa.sign(data, self.priv_key, "SHA-1-PREHASHED") def GetPublicKey(self): """Returns the public key in PEM format without headers or newlines. diff --git a/adb_shell/constants.py b/adb_shell/constants.py index 5b2c7021..1aa1effe 100644 --- a/adb_shell/constants.py +++ b/adb_shell/constants.py @@ -61,23 +61,23 @@ #: AUTH constant for ``arg0`` AUTH_RSAPUBLICKEY = 3 -AUTH = b'AUTH' -CLSE = b'CLSE' -CNXN = b'CNXN' -FAIL = b'FAIL' -OKAY = b'OKAY' -OPEN = b'OPEN' -SYNC = b'SYNC' -WRTE = b'WRTE' - -DATA = b'DATA' -DENT = b'DENT' -DONE = b'DONE' -LIST = b'LIST' -QUIT = b'QUIT' -RECV = b'RECV' -SEND = b'SEND' -STAT = b'STAT' +AUTH = b"AUTH" +CLSE = b"CLSE" +CNXN = b"CNXN" +FAIL = b"FAIL" +OKAY = b"OKAY" +OPEN = b"OPEN" +SYNC = b"SYNC" +WRTE = b"WRTE" + +DATA = b"DATA" +DENT = b"DENT" +DONE = b"DONE" +LIST = b"LIST" +QUIT = b"QUIT" +RECV = b"RECV" +SEND = b"SEND" +STAT = b"STAT" #: Commands that are recognized by :meth:`adb_shell.adb_device._AdbIOManager._read_packet_from_device` and :meth:`adb_shell.adb_device_async._AdbIOManagerAsync._read_packet_from_device` IDS = (AUTH, CLSE, CNXN, OKAY, OPEN, SYNC, WRTE) @@ -98,25 +98,25 @@ FILESYNC_WIRE_TO_ID = {wire: cmd_id for cmd_id, wire in FILESYNC_ID_TO_WIRE.items()} #: An ADB message is 6 words in little-endian. -MESSAGE_FORMAT = b'<6I' +MESSAGE_FORMAT = b"<6I" #: The format for FileSync "list" messages -FILESYNC_LIST_FORMAT = b'<5I' +FILESYNC_LIST_FORMAT = b"<5I" #: The format for FileSync "pull" messages -FILESYNC_PULL_FORMAT = b'<2I' +FILESYNC_PULL_FORMAT = b"<2I" #: The format for FileSync "push" messages -FILESYNC_PUSH_FORMAT = b'<2I' +FILESYNC_PUSH_FORMAT = b"<2I" #: The format for FileSync "stat" messages -FILESYNC_STAT_FORMAT = b'<4I' +FILESYNC_STAT_FORMAT = b"<4I" #: The size of an ADB message MESSAGE_SIZE = struct.calcsize(MESSAGE_FORMAT) #: Default authentication timeout (in s) for :meth:`adb_shell.adb_device.AdbDevice.connect` and :meth:`adb_shell.adb_device_async.AdbDeviceAsync.connect` -DEFAULT_AUTH_TIMEOUT_S = 10. +DEFAULT_AUTH_TIMEOUT_S = 10.0 #: Default total timeout (in s) for reading data from the device -DEFAULT_READ_TIMEOUT_S = 10. +DEFAULT_READ_TIMEOUT_S = 10.0 diff --git a/adb_shell/exceptions.py b/adb_shell/exceptions.py index 5ade063e..49dcf7cb 100644 --- a/adb_shell/exceptions.py +++ b/adb_shell/exceptions.py @@ -24,78 +24,55 @@ class AdbCommandFailureException(Exception): - """A ``b'FAIL'`` packet was received. - - """ + """A ``b'FAIL'`` packet was received.""" class AdbConnectionError(Exception): - """ADB command not sent because a connection to the device has not been established. - - """ + """ADB command not sent because a connection to the device has not been established.""" class AdbTimeoutError(Exception): - """ADB command did not complete within the specified time. - - """ + """ADB command did not complete within the specified time.""" class DeviceAuthError(Exception): - """Device authentication failed. + """Device authentication failed.""" - """ def __init__(self, message, *args): message %= args super(DeviceAuthError, self).__init__(message, *args) class InvalidChecksumError(Exception): - """Checksum of data didn't match expected checksum. - - """ + """Checksum of data didn't match expected checksum.""" class InvalidCommandError(Exception): - """Got an invalid command. - - """ + """Got an invalid command.""" class InvalidTransportError(Exception): - """The provided transport does not implement the necessary methods: ``close``, ``connect``, ``bulk_read``, and ``bulk_write``. - - """ + """The provided transport does not implement the necessary methods: ``close``, ``connect``, ``bulk_read``, and ``bulk_write``.""" class InvalidResponseError(Exception): - """Got an invalid response to our command. - - """ + """Got an invalid response to our command.""" class DevicePathInvalidError(Exception): - """A file command was passed an invalid path. - - """ + """A file command was passed an invalid path.""" class PushFailedError(Exception): - """Pushing a file failed for some reason. - - """ + """Pushing a file failed for some reason.""" class TcpTimeoutException(Exception): - """TCP connection timed read/write operation exceeded the allowed time. - - """ + """TCP connection timed read/write operation exceeded the allowed time.""" class UsbDeviceNotFoundError(Exception): - """TODO - - """ + """TODO""" class UsbReadFailedError(Exception): @@ -114,15 +91,14 @@ class UsbReadFailedError(Exception): An exception from ``libusb1`` """ + def __init__(self, msg, usb_error): super(UsbReadFailedError, self).__init__(msg, usb_error) self.usb_error = usb_error def __str__(self): - return '%s: %s' % self.args + return "%s: %s" % self.args class UsbWriteFailedError(Exception): - """:meth:`adb_shell.transport.usb_transport.UsbTransport.bulk_write` failed. - - """ + """:meth:`adb_shell.transport.usb_transport.UsbTransport.bulk_write` failed.""" diff --git a/adb_shell/hidden_helpers.py b/adb_shell/hidden_helpers.py index 306a7441..1a3eb338 100644 --- a/adb_shell/hidden_helpers.py +++ b/adb_shell/hidden_helpers.py @@ -64,7 +64,7 @@ from . import constants -DeviceFile = namedtuple('DeviceFile', ['filename', 'mode', 'size', 'mtime']) +DeviceFile = namedtuple("DeviceFile", ["filename", "mode", "size", "mtime"]) def get_files_to_push(local_path, device_path): @@ -89,7 +89,7 @@ def get_files_to_push(local_path, device_path): """ local_path_is_dir = not isinstance(local_path, BytesIO) and os.path.isdir(local_path) local_paths = [local_path] if not local_path_is_dir else os.listdir(local_path) - device_paths = [device_path] if not local_path_is_dir else [device_path + '/' + f for f in local_paths] + device_paths = [device_path] if not local_path_is_dir else [device_path + "/" + f for f in local_paths] return local_path_is_dir, local_paths, device_paths @@ -104,9 +104,9 @@ def get_banner(): """ try: - return bytearray(socket.gethostname(), 'utf-8') + return bytearray(socket.gethostname(), "utf-8") except: # noqa pylint: disable=bare-except - return bytearray('unknown', 'utf-8') + return bytearray("unknown", "utf-8") class _AdbTransactionInfo(object): # pylint: disable=too-few-public-methods @@ -154,12 +154,22 @@ class _AdbTransactionInfo(object): # pylint: disable=too-few-public-methods :meth:`BaseTransportAsync.bulk_write() ` """ - def __init__(self, local_id, remote_id, transport_timeout_s=None, read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, timeout_s=None): + + def __init__( + self, + local_id, + remote_id, + transport_timeout_s=None, + read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S, + timeout_s=None, + ): self.local_id = local_id self.remote_id = remote_id self.timeout_s = timeout_s self.read_timeout_s = read_timeout_s if self.timeout_s is None else min(read_timeout_s, self.timeout_s) - self.transport_timeout_s = self.read_timeout_s if transport_timeout_s is None else min(transport_timeout_s, self.read_timeout_s) + self.transport_timeout_s = ( + self.read_timeout_s if transport_timeout_s is None else min(transport_timeout_s, self.read_timeout_s) + ) def args_match(self, arg0, arg1, allow_zeros=False): """Check if ``arg0`` and ``arg1`` match this object's ``remote_id`` and ``local_id`` attributes, respectively. @@ -212,6 +222,7 @@ class _FileSyncTransactionInfo(object): # pylint: disable=too-few-public-method The index in ``recv_buffer`` that will be the start of the next data packet sent """ + def __init__(self, recv_message_format, maxdata=constants.MAX_ADB_DATA): self.send_buffer = bytearray(maxdata) self.send_idx = 0 @@ -332,10 +343,26 @@ def find(self, arg0, arg1): if arg1 is None: if arg0 is None: # `value = (None, None)` -> search for any non-empty queue - return next(((key0, key1) for key1, val1 in self._dict.items() for key0, val0 in val1.items() if not val0.empty()), None) + return next( + ( + (key0, key1) + for key1, val1 in self._dict.items() + for key0, val0 in val1.items() + if not val0.empty() + ), + None, + ) # Search for a non-empty queue with a key of `arg0 == value[0]` - return next(((arg0, key1) for key1, val1 in self._dict.items() for key0, val0 in val1.items() if key0 == arg0 and not val0.empty()), None) + return next( + ( + (arg0, key1) + for key1, val1 in self._dict.items() + for key0, val0 in val1.items() + if key0 == arg0 and not val0.empty() + ), + None, + ) if arg1 not in self._dict: return None diff --git a/adb_shell/transport/base_transport.py b/adb_shell/transport/base_transport.py index 7e8d5e0e..5fd93030 100644 --- a/adb_shell/transport/base_transport.py +++ b/adb_shell/transport/base_transport.py @@ -20,22 +20,17 @@ from abc import ABCMeta, abstractmethod class ABC(object): # pylint: disable=too-few-public-methods - """A Python2-compatible `ABC` class. + """A Python2-compatible `ABC` class.""" - """ __metaclass__ = ABCMeta class BaseTransport(ABC): - """A base transport class. - - """ + """A base transport class.""" @abstractmethod def close(self): - """Close the connection. - - """ + """Close the connection.""" @abstractmethod def connect(self, transport_timeout_s): diff --git a/adb_shell/transport/base_transport_async.py b/adb_shell/transport/base_transport_async.py index d2d4cd64..9c89db25 100644 --- a/adb_shell/transport/base_transport_async.py +++ b/adb_shell/transport/base_transport_async.py @@ -18,15 +18,11 @@ class BaseTransportAsync(ABC): - """A base transport class. - - """ + """A base transport class.""" @abstractmethod async def close(self): - """Close the connection. - - """ + """Close the connection.""" @abstractmethod async def connect(self, transport_timeout_s): diff --git a/adb_shell/transport/tcp_transport.py b/adb_shell/transport/tcp_transport.py index 1af27d72..6f6fd1b5 100644 --- a/adb_shell/transport/tcp_transport.py +++ b/adb_shell/transport/tcp_transport.py @@ -57,6 +57,7 @@ class TcpTransport(BaseTransport): The device port to which we are connecting (default is 5555) """ + def __init__(self, host, port=5555): self._host = host self._port = port @@ -64,9 +65,7 @@ def __init__(self, host, port=5555): self._connection = None def close(self): - """Close the socket connection. - - """ + """Close the socket connection.""" if self._connection: try: self._connection.shutdown(socket.SHUT_RDWR) @@ -116,7 +115,7 @@ def bulk_read(self, numbytes, transport_timeout_s): if readable: return self._connection.recv(numbytes) - msg = 'Reading from {}:{} timed out ({} seconds)'.format(self._host, self._port, transport_timeout_s) + msg = "Reading from {}:{} timed out ({} seconds)".format(self._host, self._port, transport_timeout_s) raise TcpTimeoutException(msg) def bulk_write(self, data, transport_timeout_s): @@ -144,5 +143,7 @@ def bulk_write(self, data, transport_timeout_s): if writeable: return self._connection.send(data) - msg = 'Sending data to {}:{} timed out after {} seconds. No data was sent.'.format(self._host, self._port, transport_timeout_s) + msg = "Sending data to {}:{} timed out after {} seconds. No data was sent.".format( + self._host, self._port, transport_timeout_s + ) raise TcpTimeoutException(msg) diff --git a/adb_shell/transport/tcp_transport_async.py b/adb_shell/transport/tcp_transport_async.py index 2c0a5dbb..8e1cafa5 100644 --- a/adb_shell/transport/tcp_transport_async.py +++ b/adb_shell/transport/tcp_transport_async.py @@ -44,6 +44,7 @@ class TcpTransportAsync(BaseTransportAsync): Object for writing data to the socket """ + def __init__(self, host, port=5555): self._host = host self._port = port @@ -52,9 +53,7 @@ def __init__(self, host, port=5555): self._writer = None async def close(self): - """Close the socket connection. - - """ + """Close the socket connection.""" if self._writer: try: self._writer.close() @@ -78,7 +77,7 @@ async def connect(self, transport_timeout_s): async with async_timeout.timeout(transport_timeout_s): self._reader, self._writer = await asyncio.open_connection(self._host, self._port) except asyncio.TimeoutError as exc: - msg = 'Connecting to {}:{} timed out ({} seconds)'.format(self._host, self._port, transport_timeout_s) + msg = "Connecting to {}:{} timed out ({} seconds)".format(self._host, self._port, transport_timeout_s) raise TcpTimeoutException(msg) from exc async def bulk_read(self, numbytes, transport_timeout_s): @@ -106,7 +105,7 @@ async def bulk_read(self, numbytes, transport_timeout_s): async with async_timeout.timeout(transport_timeout_s): return await self._reader.read(numbytes) except asyncio.TimeoutError as exc: - msg = 'Reading from {}:{} timed out ({} seconds)'.format(self._host, self._port, transport_timeout_s) + msg = "Reading from {}:{} timed out ({} seconds)".format(self._host, self._port, transport_timeout_s) raise TcpTimeoutException(msg) from exc async def bulk_write(self, data, transport_timeout_s): @@ -136,5 +135,7 @@ async def bulk_write(self, data, transport_timeout_s): await self._writer.drain() return len(data) except asyncio.TimeoutError as exc: - msg = 'Sending data to {}:{} timed out after {} seconds. No data was sent.'.format(self._host, self._port, transport_timeout_s) + msg = "Sending data to {}:{} timed out after {} seconds. No data was sent.".format( + self._host, self._port, transport_timeout_s + ) raise TcpTimeoutException(msg) from exc diff --git a/adb_shell/transport/usb_transport.py b/adb_shell/transport/usb_transport.py index 9ba4c1e9..714daba3 100644 --- a/adb_shell/transport/usb_transport.py +++ b/adb_shell/transport/usb_transport.py @@ -96,7 +96,7 @@ def get_interface(setting): # pragma: no cover return (setting.getClass(), setting.getSubClass(), setting.getProtocol()) -def interface_matcher(clazz, subclass, protocol): # pragma: no cover +def interface_matcher(clazz, subclass, protocol): # pragma: no cover """Returns a matcher that returns the setting with the given interface. Parameters @@ -138,7 +138,7 @@ def matcher(device): return matcher -class UsbTransport(BaseTransport): # pragma: no cover +class UsbTransport(BaseTransport): # pragma: no cover """USB communication object. Not thread-safe. Handles reading and writing over USB with the proper endpoints, exceptions, @@ -177,6 +177,7 @@ class UsbTransport(BaseTransport): # pragma: no cover TODO """ + # We maintain an idempotent `usb1` context object to ensure that device # objects we hand back to callers can be used while this class exists USB1_CTX = usb1.USBContext() @@ -194,21 +195,21 @@ def __init__(self, device, setting, usb_info=None, default_transport_timeout_s=N self._read_endpoint = None self._write_endpoint = None - self._usb_info = usb_info or '' - self._default_transport_timeout_s = default_transport_timeout_s if default_transport_timeout_s is not None else DEFAULT_TIMEOUT_S + self._usb_info = usb_info or "" + self._default_transport_timeout_s = ( + default_transport_timeout_s if default_transport_timeout_s is not None else DEFAULT_TIMEOUT_S + ) self._max_read_packet_len = 0 def close(self): - """Close the USB connection. - - """ + """Close the USB connection.""" if self._transport is None: return try: self._transport.releaseInterface(self._interface_number) self._transport.close() except usb1.USBError: - _LOGGER.info('USBError while closing transport %s: ', self.usb_info, exc_info=True) + _LOGGER.info("USBError while closing transport %s: ", self.usb_info, exc_info=True) finally: self._transport = None @@ -238,10 +239,10 @@ def connect(self, transport_timeout_s=None): transport = self._device.open() iface_number = self._setting.getNumber() try: - if (platform.system() != 'Windows' and transport.kernelDriverActive(iface_number)): + if platform.system() != "Windows" and transport.kernelDriverActive(iface_number): transport.detachKernelDriver(iface_number) except usb1.USBErrorNotFound: # pylint: disable=no-member - warnings.warn('Kernel driver not found for interface: %s.', iface_number) + warnings.warn("Kernel driver not found for interface: %s.", iface_number) # # When this object is deleted, make sure it's closed. # weakref.ref(self, self.close) @@ -275,14 +276,22 @@ def bulk_read(self, numbytes, transport_timeout_s=None): """ if self._transport is None: - raise exceptions.UsbReadFailedError('This transport has been closed, probably due to another being opened.', None) + raise exceptions.UsbReadFailedError( + "This transport has been closed, probably due to another being opened.", None + ) try: # python-libusb1 > 1.6 exposes bytearray()s now instead of bytes/str. # To support older and newer versions, we ensure everything's bytearray() # from here on out. - return bytes(self._transport.bulkRead(self._read_endpoint, numbytes, timeout=self._timeout_ms(transport_timeout_s))) + return bytes( + self._transport.bulkRead(self._read_endpoint, numbytes, timeout=self._timeout_ms(transport_timeout_s)) + ) except usb1.USBError as e: - raise exceptions.UsbReadFailedError('Could not receive data from %s (timeout %sms)' % (self.usb_info, self._timeout_ms(transport_timeout_s)), e) + raise exceptions.UsbReadFailedError( + "Could not receive data from %s (timeout %sms)" + % (self.usb_info, self._timeout_ms(transport_timeout_s)), + e, + ) def bulk_write(self, data, transport_timeout_s=None): """Send data to the USB device. @@ -308,18 +317,20 @@ def bulk_write(self, data, transport_timeout_s=None): """ if self._transport is None: - raise exceptions.UsbWriteFailedError('This transport has been closed, probably due to another being opened.', None) + raise exceptions.UsbWriteFailedError( + "This transport has been closed, probably due to another being opened.", None + ) try: return self._transport.bulkWrite(self._write_endpoint, data, timeout=self._timeout_ms(transport_timeout_s)) except usb1.USBError as e: - raise exceptions.UsbWriteFailedError('Could not send data to %s (timeout %sms)' % (self.usb_info, self._timeout_ms(transport_timeout_s)), e) + raise exceptions.UsbWriteFailedError( + "Could not send data to %s (timeout %sms)" % (self.usb_info, self._timeout_ms(transport_timeout_s)), e + ) def _open(self): - """Opens the USB device for this setting, and claims the interface. - - """ + """Opens the USB device for this setting, and claims the interface.""" # Make sure we close any previous transport open to this usb device. port_path = tuple(self.port_path) with self._HANDLE_CACHE_LOCK: @@ -344,10 +355,10 @@ def _open(self): transport = self._device.open() iface_number = self._setting.getNumber() try: - if (platform.system() != 'Windows' and transport.kernelDriverActive(iface_number)): + if platform.system() != "Windows" and transport.kernelDriverActive(iface_number): transport.detachKernelDriver(iface_number) except usb1.USBErrorNotFound: # pylint: disable=no-member - warnings.warn('Kernel driver not found for interface: %s.', iface_number) + warnings.warn("Kernel driver not found for interface: %s.", iface_number) transport.claimInterface(iface_number) self._transport = transport self._interface_number = iface_number @@ -366,7 +377,9 @@ def _timeout_ms(self, transport_timeout_s): TODO """ - return int(transport_timeout_s * 1000 if transport_timeout_s is not None else self._default_transport_timeout_s * 1000) + return int( + transport_timeout_s * 1000 if transport_timeout_s is not None else self._default_transport_timeout_s * 1000 + ) def _flush_buffers(self): """TODO @@ -427,9 +440,9 @@ def usb_info(self): try: sn = self.serial_number except usb1.USBError: - sn = '' + sn = "" if sn and sn != self._usb_info: - return '%s %s' % (self._usb_info, sn) + return "%s %s" % (self._usb_info, sn) return self._usb_info # ======================================================================= # @@ -508,8 +521,10 @@ def _find(cls, setting_matcher, port_path=None, serial=None, default_transport_t usb_info = serial else: device_matcher = None - usb_info = 'first' - return cls._find_first(setting_matcher, device_matcher, usb_info=usb_info, default_transport_timeout_s=default_transport_timeout_s) + usb_info = "first" + return cls._find_first( + setting_matcher, device_matcher, usb_info=usb_info, default_transport_timeout_s=default_transport_timeout_s + ) @classmethod def _find_and_open(cls, setting_matcher, port_path=None, serial=None, default_transport_timeout_s=None): @@ -532,13 +547,15 @@ def _find_and_open(cls, setting_matcher, port_path=None, serial=None, default_tr TODO """ - dev = cls._find(setting_matcher, port_path=port_path, serial=serial, default_transport_timeout_s=default_transport_timeout_s) + dev = cls._find( + setting_matcher, port_path=port_path, serial=serial, default_transport_timeout_s=default_transport_timeout_s + ) dev._open() # pylint: disable=protected-access dev._flush_buffers() # pylint: disable=protected-access return dev @classmethod - def _find_devices(cls, setting_matcher, device_matcher=None, usb_info='', default_transport_timeout_s=None): + def _find_devices(cls, setting_matcher, device_matcher=None, usb_info="", default_transport_timeout_s=None): """_find and yield the devices that match. Parameters @@ -570,7 +587,7 @@ def _find_devices(cls, setting_matcher, device_matcher=None, usb_info='', defaul yield transport @classmethod - def _find_first(cls, setting_matcher, device_matcher=None, usb_info='', default_transport_timeout_s=None): + def _find_first(cls, setting_matcher, device_matcher=None, usb_info="", default_transport_timeout_s=None): """Find and return the first matching device. Parameters @@ -598,9 +615,16 @@ def _find_first(cls, setting_matcher, device_matcher=None, usb_info='', default_ """ try: - return next(cls._find_devices(setting_matcher, device_matcher=device_matcher, usb_info=usb_info, default_transport_timeout_s=default_transport_timeout_s)) + return next( + cls._find_devices( + setting_matcher, + device_matcher=device_matcher, + usb_info=usb_info, + default_transport_timeout_s=default_transport_timeout_s, + ) + ) except StopIteration: - raise exceptions.UsbDeviceNotFoundError('No device available, or it is in the wrong configuration.') + raise exceptions.UsbDeviceNotFoundError("No device available, or it is in the wrong configuration.") @classmethod def find_adb(cls, serial=None, port_path=None, default_transport_timeout_s=None): @@ -625,7 +649,7 @@ def find_adb(cls, serial=None, port_path=None, default_transport_timeout_s=None) interface_matcher(CLASS, SUBCLASS, PROTOCOL), serial=serial, port_path=port_path, - default_transport_timeout_s=default_transport_timeout_s + default_transport_timeout_s=default_transport_timeout_s, ) @classmethod @@ -643,5 +667,7 @@ def find_all_adb_devices(cls, default_transport_timeout_s=None): A generator which yields each ADB device attached via USB. """ - for dev in cls._find_devices(interface_matcher(CLASS, SUBCLASS, PROTOCOL), default_transport_timeout_s=default_transport_timeout_s): + for dev in cls._find_devices( + interface_matcher(CLASS, SUBCLASS, PROTOCOL), default_transport_timeout_s=default_transport_timeout_s + ): yield dev diff --git a/setup.py b/setup.py index aef6ac7b..f85df619 100644 --- a/setup.py +++ b/setup.py @@ -2,25 +2,27 @@ from setuptools import setup -with open('README.rst') as f: +with open("README.rst") as f: readme = f.read() setup( - name='adb_shell', - version='0.4.4', - description='A Python implementation of ADB with shell and FileSync functionality.', + name="adb_shell", + version="0.4.4", + description="A Python implementation of ADB with shell and FileSync functionality.", long_description=readme, - keywords=['adb', 'android'], - url='https://github.com/JeffLIrion/adb_shell', - author='Jeff Irion', - author_email='jefflirion@users.noreply.github.com', - packages=['adb_shell', 'adb_shell.auth', 'adb_shell.transport'], - install_requires=['cryptography', 'pyasn1', 'rsa'], - tests_require=['pycryptodome', 'libusb1>=1.0.16'], - extras_require={'usb': ['libusb1>=1.0.16'], 'async': ['aiofiles>=0.4.0', 'async_timeout>=3.0.0']}, - classifiers=['Operating System :: OS Independent', - 'License :: OSI Approved :: Apache Software License', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 2'], - test_suite='tests' + keywords=["adb", "android"], + url="https://github.com/JeffLIrion/adb_shell", + author="Jeff Irion", + author_email="jefflirion@users.noreply.github.com", + packages=["adb_shell", "adb_shell.auth", "adb_shell.transport"], + install_requires=["cryptography", "pyasn1", "rsa"], + tests_require=["pycryptodome", "libusb1>=1.0.16"], + extras_require={"usb": ["libusb1>=1.0.16"], "async": ["aiofiles>=0.4.0", "async_timeout>=3.0.0"]}, + classifiers=[ + "Operating System :: OS Independent", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 2", + ], + test_suite="tests", ) diff --git a/tests/async_patchers.py b/tests/async_patchers.py index fbd4aff5..c76c0682 100644 --- a/tests/async_patchers.py +++ b/tests/async_patchers.py @@ -71,14 +71,14 @@ async def drain(self): class FakeStreamReader: async def read(self, numbytes): - return b'TEST' + return b"TEST" class FakeTcpTransportAsync(TcpTransportAsync): def __init__(self, *args, **kwargs): TcpTransportAsync.__init__(self, *args, **kwargs) - self.bulk_read_data = b'' - self.bulk_write_data = b'' + self.bulk_read_data = b"" + self.bulk_write_data = b"" async def close(self): self._reader = None @@ -100,7 +100,7 @@ async def bulk_write(self, data, transport_timeout_s=None): # `TcpTransport` patches -PATCH_TCP_TRANSPORT_ASYNC = patch('adb_shell.adb_device_async.TcpTransportAsync', FakeTcpTransportAsync) +PATCH_TCP_TRANSPORT_ASYNC = patch("adb_shell.adb_device_async.TcpTransportAsync", FakeTcpTransportAsync) def async_patch(*args, **kwargs): diff --git a/tests/async_wrapper.py b/tests/async_wrapper.py index 0dcb5390..759f0d57 100644 --- a/tests/async_wrapper.py +++ b/tests/async_wrapper.py @@ -2,7 +2,6 @@ import warnings - def _await(coro): """Create a new event loop, run the coroutine, then close the event loop.""" loop = asyncio.new_event_loop() diff --git a/tests/filesync_helpers.py b/tests/filesync_helpers.py index a4722ce5..e95626b2 100644 --- a/tests/filesync_helpers.py +++ b/tests/filesync_helpers.py @@ -25,7 +25,8 @@ class FileSyncMessage(object): # pylint: disable=too-few-public-methods The data that will be sent """ - def __init__(self, command, arg0=None, data=b''): + + def __init__(self, command, arg0=None, data=b""): self.command = constants.FILESYNC_ID_TO_WIRE[command] self.arg0 = arg0 or len(data) self.data = data @@ -39,7 +40,7 @@ def pack(self): The message packed into the format required by ADB """ - return struct.pack(b'<2I', self.command, self.arg0) + return struct.pack(b"<2I", self.command, self.arg0) class FileSyncListMessage(object): # pylint: disable=too-few-public-methods @@ -74,7 +75,8 @@ class FileSyncListMessage(object): # pylint: disable=too-few-public-methods TODO """ - def __init__(self, command, arg0, arg1, arg2, data=b''): + + def __init__(self, command, arg0, arg1, arg2, data=b""): self.command = constants.FILESYNC_ID_TO_WIRE[command] self.arg0 = arg0 self.arg1 = arg1 @@ -91,7 +93,7 @@ def pack(self): The message packed into the format required by ADB """ - return struct.pack(b'<5I', self.command, self.arg0, self.arg1, self.arg2, self.arg3) + return struct.pack(b"<5I", self.command, self.arg0, self.arg1, self.arg2, self.arg3) class FileSyncStatMessage(object): # pylint: disable=too-few-public-methods @@ -122,12 +124,13 @@ class FileSyncStatMessage(object): # pylint: disable=too-few-public-methods The data that will be sent (always empty) """ + def __init__(self, command, arg0, arg1, arg2): self.command = constants.FILESYNC_ID_TO_WIRE[command] self.arg0 = arg0 self.arg1 = arg1 self.arg2 = arg2 - self.data = b'' + self.data = b"" def pack(self): """Returns this message in an over-the-wire format. @@ -138,4 +141,4 @@ def pack(self): The message packed into the format required by ADB """ - return struct.pack(b'<4I', self.command, self.arg0, self.arg1, self.arg2) + return struct.pack(b"<4I", self.command, self.arg0, self.arg1, self.arg2) diff --git a/tests/keygen_stub.py b/tests/keygen_stub.py index 27af49ce..0b70b0dc 100644 --- a/tests/keygen_stub.py +++ b/tests/keygen_stub.py @@ -1,4 +1,5 @@ from contextlib import contextmanager + try: from unittest.mock import patch except ImportError: @@ -7,20 +8,20 @@ class FileReadWrite(object): """Mock an opened file that can be read and written to.""" + def __init__(self): - self._content = b'' - self._mode = 'r' + self._content = b"" + self._mode = "r" def read(self): - if self._mode == 'r': + if self._mode == "r": if not isinstance(self._content, str): return self._content.decode() return self._content if isinstance(self._content, str): - return self._content.encode('utf-8') + return self._content.encode("utf-8") return self._content - def write(self, content): self._content = content @@ -31,9 +32,9 @@ def write(self, content): @contextmanager -def open_priv_pub(infile, mode='r'): +def open_priv_pub(infile, mode="r"): try: - if infile.endswith('.pub'): + if infile.endswith(".pub"): PUBLIC_KEY._mode = mode yield PUBLIC_KEY else: diff --git a/tests/patchers.py b/tests/patchers.py index 5c96b61c..aee408f2 100644 --- a/tests/patchers.py +++ b/tests/patchers.py @@ -13,19 +13,39 @@ from adb_shell.transport.tcp_transport import TcpTransport -ASYNC_SKIPPER=unittest.skipIf(sys.version_info.major < 3 or sys.version_info.minor < 7, "Async functionality requires Python 3.7+") - -MSG_CONNECT = AdbMessage(command=constants.CNXN, arg0=constants.PROTOCOL, arg1=constants.MAX_LEGACY_ADB_DATA, data=b'host::unknown\0') -MSG_CONNECT_WITH_AUTH_INVALID = AdbMessage(command=constants.AUTH, arg0=0, arg1=0, data=b'host::unknown\0') -MSG_CONNECT_WITH_AUTH1 = AdbMessage(command=constants.AUTH, arg0=constants.AUTH_TOKEN, arg1=0, data=b'host::unknown\0') -MSG_CONNECT_WITH_AUTH2 = AdbMessage(command=constants.CNXN, arg0=constants.PROTOCOL, arg1=2*constants.MAX_LEGACY_ADB_DATA, data=b'host::unknown\0') -MSG_CONNECT_WITH_AUTH_NEW_KEY2 = AdbMessage(command=constants.AUTH, arg0=0, arg1=0, data=b'host::unknown\0') -MSG_CONNECT_WITH_AUTH_NEW_KEY3 = AdbMessage(command=constants.CNXN, arg0=constants.PROTOCOL, arg1=3*constants.MAX_LEGACY_ADB_DATA, data=b'host::unknown\0') +ASYNC_SKIPPER = unittest.skipIf( + sys.version_info.major < 3 or sys.version_info.minor < 7, "Async functionality requires Python 3.7+" +) + +MSG_CONNECT = AdbMessage( + command=constants.CNXN, arg0=constants.PROTOCOL, arg1=constants.MAX_LEGACY_ADB_DATA, data=b"host::unknown\0" +) +MSG_CONNECT_WITH_AUTH_INVALID = AdbMessage(command=constants.AUTH, arg0=0, arg1=0, data=b"host::unknown\0") +MSG_CONNECT_WITH_AUTH1 = AdbMessage(command=constants.AUTH, arg0=constants.AUTH_TOKEN, arg1=0, data=b"host::unknown\0") +MSG_CONNECT_WITH_AUTH2 = AdbMessage( + command=constants.CNXN, arg0=constants.PROTOCOL, arg1=2 * constants.MAX_LEGACY_ADB_DATA, data=b"host::unknown\0" +) +MSG_CONNECT_WITH_AUTH_NEW_KEY2 = AdbMessage(command=constants.AUTH, arg0=0, arg1=0, data=b"host::unknown\0") +MSG_CONNECT_WITH_AUTH_NEW_KEY3 = AdbMessage( + command=constants.CNXN, arg0=constants.PROTOCOL, arg1=3 * constants.MAX_LEGACY_ADB_DATA, data=b"host::unknown\0" +) BULK_READ_LIST = [MSG_CONNECT.pack(), MSG_CONNECT.data] BULK_READ_LIST_WITH_AUTH_INVALID = [MSG_CONNECT_WITH_AUTH_INVALID.pack(), MSG_CONNECT_WITH_AUTH_INVALID.data] -BULK_READ_LIST_WITH_AUTH = [MSG_CONNECT_WITH_AUTH1.pack(), MSG_CONNECT_WITH_AUTH1.data, MSG_CONNECT_WITH_AUTH2.pack(), MSG_CONNECT_WITH_AUTH2.data] -BULK_READ_LIST_WITH_AUTH_NEW_KEY = [MSG_CONNECT_WITH_AUTH1.pack(), MSG_CONNECT_WITH_AUTH1.data, MSG_CONNECT_WITH_AUTH_NEW_KEY2.pack(), MSG_CONNECT_WITH_AUTH_NEW_KEY2.data, MSG_CONNECT_WITH_AUTH_NEW_KEY3.pack(), MSG_CONNECT_WITH_AUTH_NEW_KEY3.data] +BULK_READ_LIST_WITH_AUTH = [ + MSG_CONNECT_WITH_AUTH1.pack(), + MSG_CONNECT_WITH_AUTH1.data, + MSG_CONNECT_WITH_AUTH2.pack(), + MSG_CONNECT_WITH_AUTH2.data, +] +BULK_READ_LIST_WITH_AUTH_NEW_KEY = [ + MSG_CONNECT_WITH_AUTH1.pack(), + MSG_CONNECT_WITH_AUTH1.data, + MSG_CONNECT_WITH_AUTH_NEW_KEY2.pack(), + MSG_CONNECT_WITH_AUTH_NEW_KEY2.data, + MSG_CONNECT_WITH_AUTH_NEW_KEY3.pack(), + MSG_CONNECT_WITH_AUTH_NEW_KEY3.data, +] StSize = namedtuple("StSize", ["st_size"]) @@ -52,6 +72,7 @@ def write(self, b): _mock_open.written += b else: _mock_open.written = b + def fileno(self): return 123 @@ -67,7 +88,7 @@ def _mock_open(*args, **kwargs): class FakeSocket(object): def __init__(self): - self._recv = b'' + self._recv = b"" def close(self): pass @@ -90,8 +111,8 @@ def shutdown(self, how): class FakeTcpTransport(TcpTransport): def __init__(self, *args, **kwargs): TcpTransport.__init__(self, *args, **kwargs) - self.bulk_read_data = b'' - self.bulk_write_data = b'' + self.bulk_read_data = b"" + self.bulk_write_data = b"" def close(self): self._connection = None @@ -111,14 +132,14 @@ def bulk_write(self, data, transport_timeout_s=None): # `socket` patches -PATCH_CREATE_CONNECTION = patch('socket.create_connection', return_value=FakeSocket()) +PATCH_CREATE_CONNECTION = patch("socket.create_connection", return_value=FakeSocket()) # `select` patches -PATCH_SELECT_SUCCESS = patch('select.select', return_value=(True, True, True)) +PATCH_SELECT_SUCCESS = patch("select.select", return_value=(True, True, True)) -PATCH_SELECT_FAIL = patch('select.select', return_value=(False, False, False)) +PATCH_SELECT_FAIL = patch("select.select", return_value=(False, False, False)) # `TcpTransport` patches -PATCH_TCP_TRANSPORT = patch('adb_shell.adb_device.TcpTransport', FakeTcpTransport) +PATCH_TCP_TRANSPORT = patch("adb_shell.adb_device.TcpTransport", FakeTcpTransport) diff --git a/tests/test_adb_device.py b/tests/test_adb_device.py index 98614041..709bf6b7 100644 --- a/tests/test_adb_device.py +++ b/tests/test_adb_device.py @@ -23,7 +23,7 @@ # https://stackoverflow.com/a/7483862 -_LOGGER = logging.getLogger('adb_shell.adb_device') +_LOGGER = logging.getLogger("adb_shell.adb_device") _LOGGER.setLevel(logging.DEBUG) _LOGGER.addHandler(logging.StreamHandler(sys.stdout)) @@ -31,12 +31,13 @@ def to_int(cmd): return sum(c << (i * 8) for i, c in enumerate(bytearray(cmd))) + def join_messages(*messages): - return b''.join([message.pack() + message.data for message in messages]) + return b"".join([message.pack() + message.data for message in messages]) class AdbMessageForTesting(AdbMessage): - def __init__(self, command, arg0=None, arg1=None, data=b''): + def __init__(self, command, arg0=None, arg1=None, data=b""): self.command = to_int(command) self.magic = self.command ^ 0xFFFFFFFF self.arg0 = arg0 @@ -46,9 +47,9 @@ def __init__(self, command, arg0=None, arg1=None, data=b''): class TestAdbDevice(unittest.TestCase): def setUp(self): - self.transport = patchers.FakeTcpTransport('host', 5555) + self.transport = patchers.FakeTcpTransport("host", 5555) self.device = AdbDevice(transport=self.transport) - self.transport.bulk_read_data = b''.join(patchers.BULK_READ_LIST) + self.transport.bulk_read_data = b"".join(patchers.BULK_READ_LIST) self.progress_callback_count = 0 def _progress_callback(device_path, current, total_bytes): @@ -74,20 +75,20 @@ def test_no_async_references(self): self.assertTrue("AdbDeviceAsync" not in adb_device_source) self.assertTrue("async" not in adb_device_source) self.assertTrue("Async" not in adb_device_source) - self.transport.bulk_read_data = b'' + self.transport.bulk_read_data = b"" def test_adb_connection_error(self): with self.assertRaises(exceptions.AdbConnectionError): - self.device.exec_out('FAIL') + self.device.exec_out("FAIL") with self.assertRaises(exceptions.AdbConnectionError): self.device.root() with self.assertRaises(exceptions.AdbConnectionError): - self.device.shell('FAIL') + self.device.shell("FAIL") with self.assertRaises(exceptions.AdbConnectionError): - ''.join(self.device.streaming_shell('FAIL')) + "".join(self.device.streaming_shell("FAIL")) with self.assertRaises(exceptions.AdbConnectionError): self.device.reboot() @@ -96,22 +97,22 @@ def test_adb_connection_error(self): self.device.root() with self.assertRaises(exceptions.AdbConnectionError): - self.device.list('FAIL') + self.device.list("FAIL") with self.assertRaises(exceptions.AdbConnectionError): - self.device.push('FAIL', 'FAIL') + self.device.push("FAIL", "FAIL") with self.assertRaises(exceptions.AdbConnectionError): - self.device.pull('FAIL', 'FAIL') + self.device.pull("FAIL", "FAIL") with self.assertRaises(exceptions.AdbConnectionError): - self.device.stat('FAIL') + self.device.stat("FAIL") - self.transport.bulk_read_data = b'' + self.transport.bulk_read_data = b"" def test_init_tcp(self): with patchers.PATCH_TCP_TRANSPORT: - tcp_device = AdbDeviceTcp('host') + tcp_device = AdbDeviceTcp("host") tcp_device._io_manager._transport.bulk_read_data = self.transport.bulk_read_data # Make sure that the `connect()` method works @@ -119,42 +120,44 @@ def test_init_tcp(self): self.assertTrue(tcp_device.available) # Clear the `_bulk_read` buffer so that `self.tearDown()` passes - self.transport.bulk_read_data = b'' - + self.transport.bulk_read_data = b"" + def test_init_banner(self): - device_with_banner = AdbDevice(transport=patchers.FakeTcpTransport('host', 5555), banner='banner') - self.assertEqual(device_with_banner._banner, b'banner') + device_with_banner = AdbDevice(transport=patchers.FakeTcpTransport("host", 5555), banner="banner") + self.assertEqual(device_with_banner._banner, b"banner") - device_with_banner2 = AdbDevice(transport=patchers.FakeTcpTransport('host', 5555), banner=bytearray('banner2', 'utf-8')) - self.assertEqual(device_with_banner2._banner, b'banner2') + device_with_banner2 = AdbDevice( + transport=patchers.FakeTcpTransport("host", 5555), banner=bytearray("banner2", "utf-8") + ) + self.assertEqual(device_with_banner2._banner, b"banner2") - device_with_banner3 = AdbDevice(transport=patchers.FakeTcpTransport('host', 5555), banner=u'banner3') - self.assertEqual(device_with_banner3._banner, b'banner3') + device_with_banner3 = AdbDevice(transport=patchers.FakeTcpTransport("host", 5555), banner="banner3") + self.assertEqual(device_with_banner3._banner, b"banner3") - with patch('socket.gethostname', side_effect=Exception): + with patch("socket.gethostname", side_effect=Exception): device_banner_unknown = AdbDevice(transport=self.transport) self.assertTrue(device_banner_unknown.connect()) - self.assertEqual(device_banner_unknown._banner, b'unknown') + self.assertEqual(device_banner_unknown._banner, b"unknown") def test_init_invalid_transport(self): with self.assertRaises(exceptions.InvalidTransportError): device = AdbDevice(transport=123) # Clear the `_bulk_read` buffer so that `self.tearDown()` passes - self.transport.bulk_read_data = b'' + self.transport.bulk_read_data = b"" def test_available(self): self.assertFalse(self.device.available) # Clear the `_bulk_read` buffer so that `self.tearDown()` passes - self.transport.bulk_read_data = b'' + self.transport.bulk_read_data = b"" def test_close(self): self.assertFalse(self.device.close()) self.assertFalse(self.device.available) # Clear the `_bulk_read` buffer so that `self.tearDown()` passes - self.transport.bulk_read_data = b'' + self.transport.bulk_read_data = b"" # ======================================================================= # # # @@ -166,18 +169,20 @@ def test_connect(self): self.assertTrue(self.device.available) def test_connect_no_keys(self): - self.transport.bulk_read_data = b''.join(patchers.BULK_READ_LIST_WITH_AUTH[:2]) + self.transport.bulk_read_data = b"".join(patchers.BULK_READ_LIST_WITH_AUTH[:2]) with self.assertRaises(exceptions.DeviceAuthError): self.device.connect() self.assertFalse(self.device.available) def test_connect_with_key_invalid_response(self): - with patch('adb_shell.auth.sign_pythonrsa.open', open_priv_pub), patch('adb_shell.auth.keygen.open', open_priv_pub): - keygen('tests/adbkey') - signer = PythonRSASigner.FromRSAKeyPath('tests/adbkey') + with patch("adb_shell.auth.sign_pythonrsa.open", open_priv_pub), patch( + "adb_shell.auth.keygen.open", open_priv_pub + ): + keygen("tests/adbkey") + signer = PythonRSASigner.FromRSAKeyPath("tests/adbkey") - self.transport.bulk_read_data = b''.join(patchers.BULK_READ_LIST_WITH_AUTH_INVALID) + self.transport.bulk_read_data = b"".join(patchers.BULK_READ_LIST_WITH_AUTH_INVALID) with self.assertRaises(exceptions.InvalidResponseError): self.device.connect([signer]) @@ -185,35 +190,42 @@ def test_connect_with_key_invalid_response(self): self.assertFalse(self.device.available) def test_connect_with_key(self): - with patch('adb_shell.auth.sign_pythonrsa.open', open_priv_pub), patch('adb_shell.auth.keygen.open', open_priv_pub): - keygen('tests/adbkey') - signer = PythonRSASigner.FromRSAKeyPath('tests/adbkey') + with patch("adb_shell.auth.sign_pythonrsa.open", open_priv_pub), patch( + "adb_shell.auth.keygen.open", open_priv_pub + ): + keygen("tests/adbkey") + signer = PythonRSASigner.FromRSAKeyPath("tests/adbkey") - self.transport.bulk_read_data = b''.join(patchers.BULK_READ_LIST_WITH_AUTH) + self.transport.bulk_read_data = b"".join(patchers.BULK_READ_LIST_WITH_AUTH) self.assertTrue(self.device.connect([signer])) def test_connect_with_new_key(self): - with patch('adb_shell.auth.sign_pythonrsa.open', open_priv_pub), patch('adb_shell.auth.keygen.open', open_priv_pub): - keygen('tests/adbkey') - signer = PythonRSASigner.FromRSAKeyPath('tests/adbkey') - signer.pub_key = u'' + with patch("adb_shell.auth.sign_pythonrsa.open", open_priv_pub), patch( + "adb_shell.auth.keygen.open", open_priv_pub + ): + keygen("tests/adbkey") + signer = PythonRSASigner.FromRSAKeyPath("tests/adbkey") + signer.pub_key = "" - self.transport.bulk_read_data = b''.join(patchers.BULK_READ_LIST_WITH_AUTH_NEW_KEY) + self.transport.bulk_read_data = b"".join(patchers.BULK_READ_LIST_WITH_AUTH_NEW_KEY) self.assertTrue(self.device.connect([signer])) def test_connect_with_new_key_and_callback(self): - with patch('adb_shell.auth.sign_pythonrsa.open', open_priv_pub), patch('adb_shell.auth.keygen.open', open_priv_pub): - keygen('tests/adbkey') - signer = PythonRSASigner.FromRSAKeyPath('tests/adbkey') - signer.pub_key = u'' + with patch("adb_shell.auth.sign_pythonrsa.open", open_priv_pub), patch( + "adb_shell.auth.keygen.open", open_priv_pub + ): + keygen("tests/adbkey") + signer = PythonRSASigner.FromRSAKeyPath("tests/adbkey") + signer.pub_key = "" self._callback_invoked = False + def auth_callback(device): self._callback_invoked = True - self.transport.bulk_read_data = b''.join(patchers.BULK_READ_LIST_WITH_AUTH_NEW_KEY) + self.transport.bulk_read_data = b"".join(patchers.BULK_READ_LIST_WITH_AUTH_NEW_KEY) self.assertTrue(self.device.connect([signer], auth_callback=auth_callback)) self.assertTrue(self._callback_invoked) @@ -234,152 +246,180 @@ def test_shell_no_return(self): self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - self.assertEqual(self.device.shell('TEST'), '') + self.assertEqual(self.device.shell("TEST"), "") def test_shell_return_pass(self): self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'PA'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'SS'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"PA"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"SS"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - self.assertEqual(self.device.shell('TEST'), 'PASS') + self.assertEqual(self.device.shell("TEST"), "PASS") def test_shell_local_id_wraparound(self): self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=2**32 - 1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=2**32 - 1, data=b'PASS1'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=2**32 - 1, data=b''), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'PASS2'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=2**32 - 1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=2**32 - 1, data=b"PASS1"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=2**32 - 1, data=b""), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"PASS2"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) self.device._local_id = 2**32 - 2 - self.assertEqual(self.device.shell('TEST'), 'PASS1') - self.assertEqual(self.device.shell('TEST'), 'PASS2') + self.assertEqual(self.device.shell("TEST"), "PASS1") + self.assertEqual(self.device.shell("TEST"), "PASS2") def test_shell_return_pass_with_unexpected_packet(self): self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'PA'), - AdbMessage(command=constants.AUTH, arg0=1, arg1=1, data=b'UNEXPECTED'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'SS'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"PA"), + AdbMessage(command=constants.AUTH, arg0=1, arg1=1, data=b"UNEXPECTED"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"SS"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - self.assertEqual(self.device.shell('TEST'), 'PASS') + self.assertEqual(self.device.shell("TEST"), "PASS") def test_shell_dont_decode(self): self.assertTrue(self.device.connect()) - + # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'PA'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'SS'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"PA"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"SS"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - self.assertEqual(self.device.shell('TEST', decode=False), b'PASS') + self.assertEqual(self.device.shell("TEST", decode=False), b"PASS") def test_shell_avoid_decode_error(self): self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'\x80abc'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"\x80abc"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - expected = '\\x80abc' if sys.version_info[0] > 2 else u'\ufffdabc' - self.assertEqual(self.device.shell('TEST'), expected) + expected = "\\x80abc" if sys.version_info[0] > 2 else "\ufffdabc" + self.assertEqual(self.device.shell("TEST"), expected) def test_shell_data_length_exceeds_max(self): self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'0'*(constants.MAX_ADB_DATA+1)), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"0" * (constants.MAX_ADB_DATA + 1)), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - self.device.shell('TEST') + self.device.shell("TEST") self.assertTrue(True) def test_shell_multibytes_sequence_exceeds_max(self): self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'0'*(constants.MAX_ADB_DATA-1) + b'\xe3\x81\x82'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage( + command=constants.WRTE, arg0=1, arg1=1, data=b"0" * (constants.MAX_ADB_DATA - 1) + b"\xe3\x81\x82" + ), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - self.assertEqual(u'0'*(constants.MAX_ADB_DATA-1) + u'\u3042', self.device.shell('TEST')) + self.assertEqual("0" * (constants.MAX_ADB_DATA - 1) + "\u3042", self.device.shell("TEST")) def test_shell_with_multibytes_sequence_over_two_messages(self): self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'\xe3'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'\x81\x82'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"\xe3"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"\x81\x82"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - self.assertEqual(u'\u3042', self.device.shell('TEST')) + self.assertEqual("\u3042", self.device.shell("TEST")) def test_shell_multiple_clse(self): # https://github.com/JeffLIrion/adb_shell/issues/15#issuecomment-536795938 self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values - msg1 = AdbMessage(command=constants.OKAY, arg0=2, arg1=2, data=b'') - msg2 = AdbMessage(command=constants.WRTE, arg0=2, arg1=2, data=b'PASS') - msg3 = AdbMessage(command=constants.CLSE, arg0=2, arg1=2, data=b'') - self.transport.bulk_read_data = b''.join([b'OKAY\xd9R\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6', - b'WRTE\xd9R\x00\x00\x01\x00\x00\x00\x01\x00\x00\x002\x00\x00\x00\xa8\xad\xab\xba', - b'2', - b'WRTE\xd9R\x00\x00\x01\x00\x00\x00\x0c\x02\x00\x00\xc0\x92\x00\x00\xa8\xad\xab\xba', - b'Wake Locks: size=2\ncom.google.android.tvlauncher\n\n- STREAM_MUSIC:\n Muted: true\n Min: 0\n Max: 15\n Current: 2 (speaker): 15, 4 (headset): 10, 8 (headphone): 10, 80 (bt_a2dp): 10, 1000 (digital_dock): 10, 4000000 (usb_headset): 3, 40000000 (default): 15\n Devices: speaker\n- STREAM_ALARM:\n Muted: true\n Min: 1\n Max: 7\n Current: 2 (speaker): 7, 4 (headset): 5, 8 (headphone): 5, 80 (bt_a2dp): 5, 1000 (digital_dock): 5, 4000000 (usb_headset): 1, 40000000 (default): 7\n Devices: speaker\n- STREAM_NOTIFICATION:\n', - b'CLSE\xd9R\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba', - msg1.pack(), - b'CLSE\xdaR\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba', - msg2.pack(), - msg2.data, - msg3.pack()]) - - self.device.shell("dumpsys power | grep 'Display Power' | grep -q 'state=ON' && echo -e '1\\c' && dumpsys power | grep mWakefulness | grep -q Awake && echo -e '1\\c' && dumpsys audio | grep paused | grep -qv 'Buffer Queue' && echo -e '1\\c' || (dumpsys audio | grep started | grep -qv 'Buffer Queue' && echo '2\\c' || echo '0\\c') && dumpsys power | grep Locks | grep 'size=' && CURRENT_APP=$(dumpsys window windows | grep mCurrentFocus) && CURRENT_APP=${CURRENT_APP#*{* * } && CURRENT_APP=${CURRENT_APP%%/*} && echo $CURRENT_APP && (dumpsys media_session | grep -A 100 'Sessions Stack' | grep -A 100 $CURRENT_APP | grep -m 1 'state=PlaybackState {' || echo) && dumpsys audio | grep '\\- STREAM_MUSIC:' -A 12") - self.assertEqual(self.device.shell('TEST'), 'PASS') + msg1 = AdbMessage(command=constants.OKAY, arg0=2, arg1=2, data=b"") + msg2 = AdbMessage(command=constants.WRTE, arg0=2, arg1=2, data=b"PASS") + msg3 = AdbMessage(command=constants.CLSE, arg0=2, arg1=2, data=b"") + self.transport.bulk_read_data = b"".join( + [ + b"OKAY\xd9R\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6", + b"WRTE\xd9R\x00\x00\x01\x00\x00\x00\x01\x00\x00\x002\x00\x00\x00\xa8\xad\xab\xba", + b"2", + b"WRTE\xd9R\x00\x00\x01\x00\x00\x00\x0c\x02\x00\x00\xc0\x92\x00\x00\xa8\xad\xab\xba", + b"Wake Locks: size=2\ncom.google.android.tvlauncher\n\n- STREAM_MUSIC:\n Muted: true\n Min: 0\n Max: 15\n Current: 2 (speaker): 15, 4 (headset): 10, 8 (headphone): 10, 80 (bt_a2dp): 10, 1000 (digital_dock): 10, 4000000 (usb_headset): 3, 40000000 (default): 15\n Devices: speaker\n- STREAM_ALARM:\n Muted: true\n Min: 1\n Max: 7\n Current: 2 (speaker): 7, 4 (headset): 5, 8 (headphone): 5, 80 (bt_a2dp): 5, 1000 (digital_dock): 5, 4000000 (usb_headset): 1, 40000000 (default): 7\n Devices: speaker\n- STREAM_NOTIFICATION:\n", + b"CLSE\xd9R\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", + msg1.pack(), + b"CLSE\xdaR\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", + msg2.pack(), + msg2.data, + msg3.pack(), + ] + ) + + self.device.shell( + "dumpsys power | grep 'Display Power' | grep -q 'state=ON' && echo -e '1\\c' && dumpsys power | grep mWakefulness | grep -q Awake && echo -e '1\\c' && dumpsys audio | grep paused | grep -qv 'Buffer Queue' && echo -e '1\\c' || (dumpsys audio | grep started | grep -qv 'Buffer Queue' && echo '2\\c' || echo '0\\c') && dumpsys power | grep Locks | grep 'size=' && CURRENT_APP=$(dumpsys window windows | grep mCurrentFocus) && CURRENT_APP=${CURRENT_APP#*{* * } && CURRENT_APP=${CURRENT_APP%%/*} && echo $CURRENT_APP && (dumpsys media_session | grep -A 100 'Sessions Stack' | grep -A 100 $CURRENT_APP | grep -m 1 'state=PlaybackState {' || echo) && dumpsys audio | grep '\\- STREAM_MUSIC:' -A 12" + ) + self.assertEqual(self.device.shell("TEST"), "PASS") def test_shell_multiple_streams(self): self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=2, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=2, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=2, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=2, data=b'PASS2'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'PASS1'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.CLSE, arg0=1, arg1=2, data=b'')) - - self.assertEqual(self.device.shell('TEST1'), 'PASS1') - self.assertEqual(self.device.shell('TEST2'), 'PASS2') + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=2, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=2, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=2, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=2, data=b"PASS2"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"PASS1"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.CLSE, arg0=1, arg1=2, data=b""), + ) + + self.assertEqual(self.device.shell("TEST1"), "PASS1") + self.assertEqual(self.device.shell("TEST2"), "PASS2") def test_shell_multiple_streams2(self): self.assertTrue(self.device.connect()) def fake_read_packet_from_device(*args, **kwargs): # Mimic the scenario that this stream's packets get read by another stream after the first attempt to read the packet from the device - self.device._io_manager._packet_store.put(arg0=1, arg1=1, cmd=constants.WRTE, data=b'\x00') - self.device._io_manager._packet_store.put(arg0=1, arg1=1, cmd=constants.OKAY, data=b'\x00') - self.device._io_manager._packet_store.put(arg0=2, arg1=2, cmd=constants.OKAY, data=b'\x00') - self.device._io_manager._packet_store.put(arg0=1, arg1=1, cmd=constants.OKAY, data=b'\x00') - self.device._io_manager._packet_store.put(arg0=2, arg1=2, cmd=constants.WRTE, data=b'PASS2') + self.device._io_manager._packet_store.put(arg0=1, arg1=1, cmd=constants.WRTE, data=b"\x00") + self.device._io_manager._packet_store.put(arg0=1, arg1=1, cmd=constants.OKAY, data=b"\x00") + self.device._io_manager._packet_store.put(arg0=2, arg1=2, cmd=constants.OKAY, data=b"\x00") + self.device._io_manager._packet_store.put(arg0=1, arg1=1, cmd=constants.OKAY, data=b"\x00") + self.device._io_manager._packet_store.put(arg0=2, arg1=2, cmd=constants.WRTE, data=b"PASS2") self.device._io_manager._packet_store.put(arg0=1, arg1=1, cmd=constants.WRTE, data=b"PASS1") self.device._io_manager._packet_store.put(arg0=1, arg1=1, cmd=constants.CLSE, data=b"") self.device._io_manager._packet_store.put(arg0=2, arg1=2, cmd=constants.CLSE, data=b"") @@ -388,36 +428,40 @@ def fake_read_packet_from_device(*args, **kwargs): with patch.object(self.device._io_manager, "_read_packet_from_device", fake_read_packet_from_device): # The patch function will only be called once, all subsequent packets will be retrieved from the store - self.assertEqual(self.device.shell('TEST1'), 'PASS1') - self.assertEqual(self.device.shell('TEST2'), 'PASS2') + self.assertEqual(self.device.shell("TEST1"), "PASS1") + self.assertEqual(self.device.shell("TEST2"), "PASS2") def test_shell_local_id2(self): self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=2, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=2, data=b'PASS2'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'PASS1'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.CLSE, arg0=1, arg1=2, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=2, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=2, data=b"PASS2"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"PASS1"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.CLSE, arg0=1, arg1=2, data=b""), + ) - self.assertEqual(self.device.shell('TEST1'), 'PASS1') - self.assertEqual(self.device.shell('TEST2'), 'PASS2') + self.assertEqual(self.device.shell("TEST1"), "PASS1") + self.assertEqual(self.device.shell("TEST2"), "PASS2") def test_shell_remote_id2(self): self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=2, arg1=2, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=2, arg1=2, data=b'PASS2'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'PASS1'), - AdbMessage(command=constants.CLSE, arg0=2, arg1=2, data=b''), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=2, arg1=2, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=2, arg1=2, data=b"PASS2"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"PASS1"), + AdbMessage(command=constants.CLSE, arg0=2, arg1=2, data=b""), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - self.assertEqual(self.device.shell('TEST1'), 'PASS1') - self.assertEqual(self.device.shell('TEST2'), 'PASS2') + self.assertEqual(self.device.shell("TEST1"), "PASS1") + self.assertEqual(self.device.shell("TEST2"), "PASS2") # ======================================================================= # # # @@ -428,11 +472,13 @@ def test_shell_error_local_id_timeout(self): self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1234, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1234, data=b'\x00')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1234, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1234, data=b"\x00"), + ) with self.assertRaises(exceptions.AdbTimeoutError): - self.device.shell('TEST', read_timeout_s=1) + self.device.shell("TEST", read_timeout_s=1) # Close the connection so that the packet store gets cleared self.device.close() @@ -441,137 +487,149 @@ def test_shell_error_unknown_command(self): self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessageForTesting(command=constants.FAIL, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessageForTesting(command=constants.FAIL, arg0=1, arg1=1, data=b"") + ) with self.assertRaises(exceptions.InvalidCommandError): - self.assertEqual(self.device.shell('TEST'), '') + self.assertEqual(self.device.shell("TEST"), "") def test_shell_error_transport_timeout(self): self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"")) with self.assertRaises(exceptions.AdbTimeoutError): - self.device.shell('TEST', read_timeout_s=-1) + self.device.shell("TEST", read_timeout_s=-1) def test_shell_error_read_timeout_multiple_clse(self): self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.CLSE, arg0=2, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.CLSE, arg0=2, arg1=1, data=b""), + ) with self.assertRaises(exceptions.AdbTimeoutError): - self.device.shell('TEST', read_timeout_s=-1) + self.device.shell("TEST", read_timeout_s=-1) def test_shell_error_timeout(self): self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'PA'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'SS'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"PA"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"SS"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) def fake_read_until(*args, **kwargs): time.sleep(0.2) - return b'WRTE', b'PA' + return b"WRTE", b"PA" - with patch('adb_shell.adb_device.AdbDevice._read_until', fake_read_until): + with patch("adb_shell.adb_device.AdbDevice._read_until", fake_read_until): with self.assertRaises(exceptions.AdbTimeoutError): - self.device.shell('TEST', timeout_s=0.5) + self.device.shell("TEST", timeout_s=0.5) # Clear the `_bulk_read` buffer so that `self.tearDown()` passes - self.transport.bulk_read_data = b'' + self.transport.bulk_read_data = b"" def test_shell_error_checksum(self): self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values - msg1 = AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00') - msg2 = AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'PASS') - self.transport.bulk_read_data = b''.join([msg1.pack(), msg1.data, msg2.pack(), msg2.data[:-1] + b'0']) + msg1 = AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00") + msg2 = AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"PASS") + self.transport.bulk_read_data = b"".join([msg1.pack(), msg1.data, msg2.pack(), msg2.data[:-1] + b"0"]) with self.assertRaises(exceptions.InvalidChecksumError): - self.device.shell('TEST') + self.device.shell("TEST") def test_issue29(self): # https://github.com/JeffLIrion/adb_shell/issues/29 - with patch('adb_shell.auth.sign_pythonrsa.open', open_priv_pub), patch('adb_shell.auth.keygen.open', open_priv_pub): - keygen('tests/adbkey') - signer = PythonRSASigner.FromRSAKeyPath('tests/adbkey') - - okay3 = AdbMessage(command=constants.OKAY, arg0=1, arg1=3, data=b'\x00') - clse3 = AdbMessage(command=constants.CLSE, arg0=1, arg1=3, data=b'') - okay5 = AdbMessage(command=constants.OKAY, arg0=1, arg1=5, data=b'\x00') - clse5 = AdbMessage(command=constants.CLSE, arg0=1, arg1=5, data=b'') - okay7 = AdbMessage(command=constants.OKAY, arg0=1, arg1=7, data=b'\x00') - clse7 = AdbMessage(command=constants.CLSE, arg0=1, arg1=7, data=b'') - - self.transport.bulk_read_data = b''.join([b'AUTH\x01\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\xc5\n\x00\x00\xbe\xaa\xab\xb7', # Line 22 - b"\x17\xbf\xbf\xff\xc7\xa2eo'Sh\xdf\x8e\xf5\xff\xe0\tJ6H", # Line 23 - b"CNXN\x00\x00\x00\x01\x00\x10\x00\x00i\x00\x00\x00.'\x00\x00\xbc\xb1\xa7\xb1", # Line 26 - b'device::ro.product.name=once;ro.product.model=MIBOX3;ro.product.device=once;features=stat_v2,cmd,shell_v2', # Line 27 - b'OKAY\x99\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6', # Line 290 (modified --> Line 30) - b'CLSE\xa2\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba', # Line 291 - b'CLSE\xa2\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba', # Line 292 - b'WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x001\x00\x00\x00\xa8\xad\xab\xba', # Line 31 - b'1', # Line 32 - b'WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x001\x00\x00\x00\xa8\xad\xab\xba', # Line 35 - b'1', # Line 36 - b'WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x000\x00\x00\x00\xa8\xad\xab\xba', # Line 39 - b'0', # Line 40 - b'WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x13\x00\x00\x000\x06\x00\x00\xa8\xad\xab\xba', # Line 43 - b'Wake Locks: size=0\n', # Line 44 - b'WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x1e\x00\x00\x00V\x0b\x00\x00\xa8\xad\xab\xba', # Line 47 - b'com.google.android.youtube.tv\n', # Line 48 - b'WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x98\x00\x00\x00\xa13\x00\x00\xa8\xad\xab\xba', # Line 51 - b' state=PlaybackState {state=0, position=0, buffered position=0, speed=0.0, updated=0, actions=0, custom actions=[], active item id=-1, error=null}\n', # Line 52 - b'WRTE\x99\x00\x00\x00\x01\x00\x00\x00.\x01\x00\x00\xceP\x00\x00\xa8\xad\xab\xba', # Line 55 - b'- STREAM_MUSIC:\n Muted: false\n Min: 0\n Max: 15\n Current: 2 (speaker): 11, 4 (headset): 10, 8 (headphone): 10, 400 (hdmi): 6, 40000000 (default): 11\n Devices: hdmi\n- STREAM_ALARM:\n Muted: false\n Min: 0\n Max: 7\n Current: 40000000 (default): 6\n Devices: speaker\n- STREAM_NOTIFICATION:\n', # Line 56 - b'CLSE\x99\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba', # Line 59 - b'AUTH\x01\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x94\t\x00\x00\xbe\xaa\xab\xb7', # Line 297 - b'P\xa5\x86\x97\xe8\x01\xb09\x8c>F\x9d\xc6\xbd\xc0J\x80!\xbb\x1a', # Line 298 - b"CNXN\x00\x00\x00\x01\x00\x10\x00\x00i\x00\x00\x00.'\x00\x00\xbc\xb1\xa7\xb1", # Line 301 - b'device::ro.product.name=once;ro.product.model=MIBOX3;ro.product.device=once;features=stat_v2,cmd,shell_v2', # Line 302 - b'OKAY\xa5\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6', # Line 305 - b'CLSE\xa5\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba', # Line 306 - okay3.pack(), - okay3.data, - clse3.pack(), - b'AUTH\x01\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00e\x0c\x00\x00\xbe\xaa\xab\xb7', # Line 315 - b'\xd3\xef\x7f_\xa6\xc0`b\x19\\z\xe4\xf3\xe2\xed\x8d\xe1W\xfbH', # Line 316 - b"CNXN\x00\x00\x00\x01\x00\x10\x00\x00i\x00\x00\x00.'\x00\x00\xbc\xb1\xa7\xb1", # Line 319 - b'device::ro.product.name=once;ro.product.model=MIBOX3;ro.product.device=once;features=stat_v2,cmd,shell_v2', # Line 320 - b'OKAY\xa7\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6', # Line 323 - b'CLSE\xa7\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba', # Line 324 - okay5.pack(), - okay5.data, - clse5.pack(), - b'AUTH\x01\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x93\x08\x00\x00\xbe\xaa\xab\xb7', # Line 333 - b's\xd4_e\xa4s\x02\x95\x0f\x1e\xec\n\x95Y9[`\x8e\xe1f', # Line 334 - b"CNXN\x00\x00\x00\x01\x00\x10\x00\x00i\x00\x00\x00.'\x00\x00\xbc\xb1\xa7\xb1", # Line 337 - b'device::ro.product.name=once;ro.product.model=MIBOX3;ro.product.device=once;features=stat_v2,cmd,shell_v2', # Line 338 - b'OKAY\xa9\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6', # Line 341 - b'CLSE\xa9\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba', # Line 342 - okay7.pack(), - okay7.data, - clse7.pack()]) + with patch("adb_shell.auth.sign_pythonrsa.open", open_priv_pub), patch( + "adb_shell.auth.keygen.open", open_priv_pub + ): + keygen("tests/adbkey") + signer = PythonRSASigner.FromRSAKeyPath("tests/adbkey") + + okay3 = AdbMessage(command=constants.OKAY, arg0=1, arg1=3, data=b"\x00") + clse3 = AdbMessage(command=constants.CLSE, arg0=1, arg1=3, data=b"") + okay5 = AdbMessage(command=constants.OKAY, arg0=1, arg1=5, data=b"\x00") + clse5 = AdbMessage(command=constants.CLSE, arg0=1, arg1=5, data=b"") + okay7 = AdbMessage(command=constants.OKAY, arg0=1, arg1=7, data=b"\x00") + clse7 = AdbMessage(command=constants.CLSE, arg0=1, arg1=7, data=b"") + + self.transport.bulk_read_data = b"".join( + [ + b"AUTH\x01\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\xc5\n\x00\x00\xbe\xaa\xab\xb7", # Line 22 + b"\x17\xbf\xbf\xff\xc7\xa2eo'Sh\xdf\x8e\xf5\xff\xe0\tJ6H", # Line 23 + b"CNXN\x00\x00\x00\x01\x00\x10\x00\x00i\x00\x00\x00.'\x00\x00\xbc\xb1\xa7\xb1", # Line 26 + b"device::ro.product.name=once;ro.product.model=MIBOX3;ro.product.device=once;features=stat_v2,cmd,shell_v2", # Line 27 + b"OKAY\x99\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6", # Line 290 (modified --> Line 30) + b"CLSE\xa2\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", # Line 291 + b"CLSE\xa2\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", # Line 292 + b"WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x001\x00\x00\x00\xa8\xad\xab\xba", # Line 31 + b"1", # Line 32 + b"WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x001\x00\x00\x00\xa8\xad\xab\xba", # Line 35 + b"1", # Line 36 + b"WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x000\x00\x00\x00\xa8\xad\xab\xba", # Line 39 + b"0", # Line 40 + b"WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x13\x00\x00\x000\x06\x00\x00\xa8\xad\xab\xba", # Line 43 + b"Wake Locks: size=0\n", # Line 44 + b"WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x1e\x00\x00\x00V\x0b\x00\x00\xa8\xad\xab\xba", # Line 47 + b"com.google.android.youtube.tv\n", # Line 48 + b"WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x98\x00\x00\x00\xa13\x00\x00\xa8\xad\xab\xba", # Line 51 + b" state=PlaybackState {state=0, position=0, buffered position=0, speed=0.0, updated=0, actions=0, custom actions=[], active item id=-1, error=null}\n", # Line 52 + b"WRTE\x99\x00\x00\x00\x01\x00\x00\x00.\x01\x00\x00\xceP\x00\x00\xa8\xad\xab\xba", # Line 55 + b"- STREAM_MUSIC:\n Muted: false\n Min: 0\n Max: 15\n Current: 2 (speaker): 11, 4 (headset): 10, 8 (headphone): 10, 400 (hdmi): 6, 40000000 (default): 11\n Devices: hdmi\n- STREAM_ALARM:\n Muted: false\n Min: 0\n Max: 7\n Current: 40000000 (default): 6\n Devices: speaker\n- STREAM_NOTIFICATION:\n", # Line 56 + b"CLSE\x99\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", # Line 59 + b"AUTH\x01\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x94\t\x00\x00\xbe\xaa\xab\xb7", # Line 297 + b"P\xa5\x86\x97\xe8\x01\xb09\x8c>F\x9d\xc6\xbd\xc0J\x80!\xbb\x1a", # Line 298 + b"CNXN\x00\x00\x00\x01\x00\x10\x00\x00i\x00\x00\x00.'\x00\x00\xbc\xb1\xa7\xb1", # Line 301 + b"device::ro.product.name=once;ro.product.model=MIBOX3;ro.product.device=once;features=stat_v2,cmd,shell_v2", # Line 302 + b"OKAY\xa5\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6", # Line 305 + b"CLSE\xa5\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", # Line 306 + okay3.pack(), + okay3.data, + clse3.pack(), + b"AUTH\x01\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00e\x0c\x00\x00\xbe\xaa\xab\xb7", # Line 315 + b"\xd3\xef\x7f_\xa6\xc0`b\x19\\z\xe4\xf3\xe2\xed\x8d\xe1W\xfbH", # Line 316 + b"CNXN\x00\x00\x00\x01\x00\x10\x00\x00i\x00\x00\x00.'\x00\x00\xbc\xb1\xa7\xb1", # Line 319 + b"device::ro.product.name=once;ro.product.model=MIBOX3;ro.product.device=once;features=stat_v2,cmd,shell_v2", # Line 320 + b"OKAY\xa7\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6", # Line 323 + b"CLSE\xa7\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", # Line 324 + okay5.pack(), + okay5.data, + clse5.pack(), + b"AUTH\x01\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x93\x08\x00\x00\xbe\xaa\xab\xb7", # Line 333 + b"s\xd4_e\xa4s\x02\x95\x0f\x1e\xec\n\x95Y9[`\x8e\xe1f", # Line 334 + b"CNXN\x00\x00\x00\x01\x00\x10\x00\x00i\x00\x00\x00.'\x00\x00\xbc\xb1\xa7\xb1", # Line 337 + b"device::ro.product.name=once;ro.product.model=MIBOX3;ro.product.device=once;features=stat_v2,cmd,shell_v2", # Line 338 + b"OKAY\xa9\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6", # Line 341 + b"CLSE\xa9\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", # Line 342 + okay7.pack(), + okay7.data, + clse7.pack(), + ] + ) self.assertTrue(self.device.connect([signer])) - self.device.shell('Android TV update command') - + self.device.shell("Android TV update command") + self.assertTrue(self.device.connect([signer])) - self.device.shell('Android TV update command') - self.device.shell('Android TV update command') + self.device.shell("Android TV update command") + self.device.shell("Android TV update command") self.assertTrue(self.device.connect([signer])) - self.device.shell('Android TV update command') - self.device.shell('Android TV update command') + self.device.shell("Android TV update command") + self.device.shell("Android TV update command") self.assertTrue(self.device.connect([signer])) - self.device.shell('Android TV update command') - self.device.shell('Android TV update command') + self.device.shell("Android TV update command") + self.device.shell("Android TV update command") # ======================================================================= # # # @@ -583,29 +641,28 @@ def test_streaming_shell_decode(self): # Provide the `bulk_read` return values self.transport.bulk_read_data = join_messages( - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'ABC'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'123'), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"ABC"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"123"), ) - generator = self.device.streaming_shell('TEST', decode=True) - self.assertEqual('ABC', next(generator)) - self.assertEqual('123', next(generator)) + generator = self.device.streaming_shell("TEST", decode=True) + self.assertEqual("ABC", next(generator)) + self.assertEqual("123", next(generator)) def test_streaming_shell_dont_decode(self): self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values self.transport.bulk_read_data = join_messages( - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'ABC'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'123'), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"ABC"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"123"), ) - generator = self.device.streaming_shell('TEST', decode=False) - self.assertEqual(b'ABC', next(generator)) - self.assertEqual(b'123', next(generator)) - + generator = self.device.streaming_shell("TEST", decode=False) + self.assertEqual(b"ABC", next(generator)) + self.assertEqual(b"123", next(generator)) # ======================================================================= # # # @@ -615,11 +672,10 @@ def test_streaming_shell_dont_decode(self): def test_reboot(self): self.assertTrue(self.device.connect()) - with patch('adb_shell.adb_device.AdbDevice._open') as patch_open: + with patch("adb_shell.adb_device.AdbDevice._open") as patch_open: self.device.reboot() assert patch_open.call_count == 1 - # ======================================================================= # # # # `root` test # @@ -628,11 +684,10 @@ def test_reboot(self): def test_root(self): self.assertTrue(self.device.connect()) - with patch('adb_shell.adb_device.AdbDevice._service') as patch_service: + with patch("adb_shell.adb_device.AdbDevice._service") as patch_service: self.device.root() assert patch_service.call_count == 1 - # ======================================================================= # # # # `exec_out` test # @@ -642,11 +697,15 @@ def test_exec_out(self): self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = b''.join([b'OKAY\x14\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6', - b'WRTE\x14\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00J\x01\x00\x00\xa8\xad\xab\xba', - b'TEST\n', - b'', - b'CLSE\x14\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba']) + self.transport.bulk_read_data = b"".join( + [ + b"OKAY\x14\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6", + b"WRTE\x14\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00J\x01\x00\x00\xa8\xad\xab\xba", + b"TEST\n", + b"", + b"CLSE\x14\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", + ] + ) self.assertEqual(self.device.exec_out("echo 'TEST'"), "TEST\n") @@ -657,26 +716,44 @@ def test_exec_out(self): # ======================================================================= # def test_list(self): self.assertTrue(self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncListMessage(constants.DENT, 1, 2, 3, data=b'file1'), - FileSyncListMessage(constants.DENT, 4, 5, 6, data=b'file2'), - FileSyncListMessage(constants.DONE, 0, 0, 0))), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncListMessage(constants.DENT, 1, 2, 3, data=b"file1"), + FileSyncListMessage(constants.DENT, 4, 5, 6, data=b"file2"), + FileSyncListMessage(constants.DONE, 0, 0, 0), + ), + ), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.LIST, data=b'/dir'))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages(FileSyncMessage(command=constants.LIST, data=b"/dir")), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - expected_result = [DeviceFile(filename=bytearray(b'file1'), mode=1, size=2, mtime=3), - DeviceFile(filename=bytearray(b'file2'), mode=4, size=5, mtime=6)] + expected_result = [ + DeviceFile(filename=bytearray(b"file1"), mode=1, size=2, mtime=3), + DeviceFile(filename=bytearray(b"file2"), mode=4, size=5, mtime=6), + ] - self.assertEqual(expected_result, self.device.list('/dir')) + self.assertEqual(expected_result, self.device.list("/dir")) self.assertEqual(expected_bulk_write, self.transport.bulk_write_data) def test_list_empty_path(self): @@ -685,169 +762,248 @@ def test_list_empty_path(self): with self.assertRaises(exceptions.DevicePathInvalidError): self.device.list(b"") with self.assertRaises(exceptions.DevicePathInvalidError): - self.device.list(u"") + self.device.list("") with self.assertRaises(exceptions.DevicePathInvalidError): self.device.list(None) # Clear the `_bulk_read` buffer so that `self.tearDown()` passes - self.transport.bulk_read_data = b'' + self.transport.bulk_read_data = b"" def test_push_fail(self): self.assertTrue(self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" mtime = 100 - filedata = b'Ohayou sekai.\nGood morning world!' + filedata = b"Ohayou sekai.\nGood morning world!" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(constants.FAIL, data=b'')))) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage( + command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(constants.FAIL, data=b"")) + ), + ) - with self.assertRaises(exceptions.PushFailedError), patch('adb_shell.adb_device.open', patchers.mock_open(read_data=filedata)): - self.device.push('TEST_FILE', '/data', mtime=mtime) + with self.assertRaises(exceptions.PushFailedError), patch( + "adb_shell.adb_device.open", patchers.mock_open(read_data=filedata) + ): + self.device.push("TEST_FILE", "/data", mtime=mtime) def test_push_file(self): self.assertTrue(self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" mtime = 100 - filedata = b'Ohayou sekai.\nGood morning world!' + filedata = b"Ohayou sekai.\nGood morning world!" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=FileSyncMessage(constants.OKAY).pack()), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=FileSyncMessage(constants.OKAY).pack()), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.SEND, data=b'/data,33272'), - FileSyncMessage(command=constants.DATA, data=filedata), - FileSyncMessage(command=constants.DONE, arg0=mtime, data=b''))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) - - with patch('adb_shell.adb_device.open', patchers.mock_open(read_data=filedata)): + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncMessage(command=constants.SEND, data=b"/data,33272"), + FileSyncMessage(command=constants.DATA, data=filedata), + FileSyncMessage(command=constants.DONE, arg0=mtime, data=b""), + ), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) + + with patch("adb_shell.adb_device.open", patchers.mock_open(read_data=filedata)): self.assertEqual(self.progress_callback_count, 0) with patch("adb_shell.adb_device.os.fstat", return_value=patchers.StSize(12345)): - self.device.push('TEST_FILE', '/data', mtime=mtime, progress_callback=self.progress_callback) + self.device.push("TEST_FILE", "/data", mtime=mtime, progress_callback=self.progress_callback) self.assertEqual(self.progress_callback_count, 1) self.assertEqual(expected_bulk_write, self.transport.bulk_write_data) def test_push_bytesio(self): self.assertTrue(self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" mtime = 100 - filedata = b'Ohayou sekai.\nGood morning world!' + filedata = b"Ohayou sekai.\nGood morning world!" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=FileSyncMessage(constants.OKAY).pack()), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=FileSyncMessage(constants.OKAY).pack()), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.SEND, data=b'/data,33272'), - FileSyncMessage(command=constants.DATA, data=filedata), - FileSyncMessage(command=constants.DONE, arg0=mtime, data=b''))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncMessage(command=constants.SEND, data=b"/data,33272"), + FileSyncMessage(command=constants.DATA, data=filedata), + FileSyncMessage(command=constants.DONE, arg0=mtime, data=b""), + ), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) stream = BytesIO(filedata) - self.device.push(stream, '/data', mtime=mtime) + self.device.push(stream, "/data", mtime=mtime) self.assertEqual(expected_bulk_write, self.transport.bulk_write_data) def test_push_file_exception(self): self.assertTrue(self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" mtime = 100 - filedata = b'Ohayou sekai.\nGood morning world!' + filedata = b"Ohayou sekai.\nGood morning world!" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=FileSyncMessage(constants.OKAY).pack()), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=FileSyncMessage(constants.OKAY).pack()), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.SEND, data=b'/data,33272'), - FileSyncMessage(command=constants.DATA, data=filedata), - FileSyncMessage(command=constants.DONE, arg0=mtime, data=b''))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) - - with patch('adb_shell.adb_device.open', patchers.mock_open(read_data=filedata)): + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncMessage(command=constants.SEND, data=b"/data,33272"), + FileSyncMessage(command=constants.DATA, data=filedata), + FileSyncMessage(command=constants.DONE, arg0=mtime, data=b""), + ), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) + + with patch("adb_shell.adb_device.open", patchers.mock_open(read_data=filedata)): # Set self.progress_callback_count to None so that an exception occurs when self.progress_callback tries to increment it self.progress_callback_count = None with patch("adb_shell.adb_device.os.fstat", return_value=patchers.StSize(12345)): - self.device.push('TEST_FILE', '/data', mtime=mtime, progress_callback=self.progress_callback) - + self.device.push("TEST_FILE", "/data", mtime=mtime, progress_callback=self.progress_callback) + self.assertIsNone(self.progress_callback_count) self.assertEqual(expected_bulk_write, self.transport.bulk_write_data) def test_push_file_mtime0(self): self.assertTrue(self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" mtime = 0 - filedata = b'Ohayou sekai.\nGood morning world!' + filedata = b"Ohayou sekai.\nGood morning world!" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(constants.OKAY, data=b''))), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage( + command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(constants.OKAY, data=b"")) + ), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.SEND, data=b'/data,33272'), - FileSyncMessage(command=constants.DATA, data=filedata), - FileSyncMessage(command=constants.DONE, arg0=mtime))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) - - with patch('adb_shell.adb_device.open', patchers.mock_open(read_data=filedata)), patch('time.time', return_value=mtime): - self.device.push('TEST_FILE', '/data', mtime=mtime) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncMessage(command=constants.SEND, data=b"/data,33272"), + FileSyncMessage(command=constants.DATA, data=filedata), + FileSyncMessage(command=constants.DONE, arg0=mtime), + ), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) + + with patch("adb_shell.adb_device.open", patchers.mock_open(read_data=filedata)), patch( + "time.time", return_value=mtime + ): + self.device.push("TEST_FILE", "/data", mtime=mtime) self.assertEqual(expected_bulk_write, self.transport.bulk_write_data) def test_push_big_file(self): self.assertTrue(self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" mtime = 100 - filedata = b'0' * int(3.5 * self.device.max_chunk_size) + filedata = b"0" * int(3.5 * self.device.max_chunk_size) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(constants.OKAY))), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(constants.OKAY))), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - mcs0, mcs1, mcs2, mcs3 = 0, self.device.max_chunk_size, 2*self.device.max_chunk_size, 3*self.device.max_chunk_size - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages( - FileSyncMessage(command=constants.SEND, data=b'/data,33272'), - FileSyncMessage(command=constants.DATA, data=filedata[mcs0:mcs1]))), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages( - FileSyncMessage(command=constants.DATA, data=filedata[mcs1:mcs2]))), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages( - FileSyncMessage(command=constants.DATA, data=filedata[mcs2:mcs3]), - FileSyncMessage(command=constants.DATA, data=filedata[mcs3:]), - FileSyncMessage(command=constants.DONE, arg0=mtime))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) - - with patch('adb_shell.adb_device.open', patchers.mock_open(read_data=filedata)): + mcs0, mcs1, mcs2, mcs3 = ( + 0, + self.device.max_chunk_size, + 2 * self.device.max_chunk_size, + 3 * self.device.max_chunk_size, + ) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncMessage(command=constants.SEND, data=b"/data,33272"), + FileSyncMessage(command=constants.DATA, data=filedata[mcs0:mcs1]), + ), + ), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages(FileSyncMessage(command=constants.DATA, data=filedata[mcs1:mcs2])), + ), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncMessage(command=constants.DATA, data=filedata[mcs2:mcs3]), + FileSyncMessage(command=constants.DATA, data=filedata[mcs3:]), + FileSyncMessage(command=constants.DONE, arg0=mtime), + ), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) + + with patch("adb_shell.adb_device.open", patchers.mock_open(read_data=filedata)): self.assertEqual(self.progress_callback_count, 0) with patch("adb_shell.adb_device.os.fstat", return_value=patchers.StSize(12345)): - self.device.push('TEST_FILE', '/data', mtime=mtime, progress_callback=self.progress_callback) + self.device.push("TEST_FILE", "/data", mtime=mtime, progress_callback=self.progress_callback) self.assertEqual(self.progress_callback_count, 4) self.assertEqual(expected_bulk_write, self.transport.bulk_write_data) @@ -855,25 +1011,29 @@ def test_push_dir(self): self.assertTrue(self.device.connect()) mtime = 100 - filedata = b'Ohayou sekai.\nGood morning world!' + filedata = b"Ohayou sekai.\nGood morning world!" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.OKAY, arg0=2, arg1=2, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=2, arg1=2, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=2, arg1=2, data=join_messages(FileSyncMessage(constants.OKAY))), - AdbMessage(command=constants.CLSE, arg0=2, arg1=2, data=b''), - AdbMessage(command=constants.OKAY, arg0=3, arg1=3, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=3, arg1=3, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=3, arg1=3, data=join_messages(FileSyncMessage(constants.OKAY))), - AdbMessage(command=constants.CLSE, arg0=3, arg1=3, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.OKAY, arg0=2, arg1=2, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=2, arg1=2, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=2, arg1=2, data=join_messages(FileSyncMessage(constants.OKAY))), + AdbMessage(command=constants.CLSE, arg0=2, arg1=2, data=b""), + AdbMessage(command=constants.OKAY, arg0=3, arg1=3, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=3, arg1=3, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=3, arg1=3, data=join_messages(FileSyncMessage(constants.OKAY))), + AdbMessage(command=constants.CLSE, arg0=3, arg1=3, data=b""), + ) # Expected `bulk_write` values - #TODO + # TODO - with patch('adb_shell.adb_device.open', patchers.mock_open(read_data=filedata)), patch('os.path.isdir', lambda x: x == 'TEST_DIR/'), patch('os.listdir', return_value=['TEST_FILE1', 'TEST_FILE2']): - self.device.push('TEST_DIR/', '/data', mtime=mtime) + with patch("adb_shell.adb_device.open", patchers.mock_open(read_data=filedata)), patch( + "os.path.isdir", lambda x: x == "TEST_DIR/" + ), patch("os.listdir", return_value=["TEST_FILE1", "TEST_FILE2"]): + self.device.push("TEST_DIR/", "/data", mtime=mtime) def test_push_empty_path(self): with self.assertRaises(exceptions.DevicePathInvalidError): @@ -881,35 +1041,50 @@ def test_push_empty_path(self): with self.assertRaises(exceptions.DevicePathInvalidError): self.device.push("NOTHING", b"") with self.assertRaises(exceptions.DevicePathInvalidError): - self.device.push("NOTHING", u"") + self.device.push("NOTHING", "") with self.assertRaises(exceptions.DevicePathInvalidError): self.device.push("NOTHING", None) # Clear the `_bulk_read` buffer so that `self.tearDown()` passes - self.transport.bulk_read_data = b'' + self.transport.bulk_read_data = b"" def test_pull_file(self): self.assertTrue(self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" - filedata = b'Ohayou sekai.\nGood morning world!' + filedata = b"Ohayou sekai.\nGood morning world!" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.DATA, data=filedata), - FileSyncMessage(command=constants.DONE))), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncMessage(command=constants.DATA, data=filedata), FileSyncMessage(command=constants.DONE) + ), + ), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.RECV, data=b'/data'))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages(FileSyncMessage(command=constants.RECV, data=b"/data")), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - with patch('adb_shell.adb_device.open', patchers.mock_open()) as m: + with patch("adb_shell.adb_device.open", patchers.mock_open()) as m: self.assertEqual(self.progress_callback_count, 0) with patch("adb_shell.adb_device.AdbDevice.stat", self.fake_stat): - self.device.pull('/data', 'TEST_FILE', progress_callback=self.progress_callback) + self.device.pull("/data", "TEST_FILE", progress_callback=self.progress_callback) self.assertEqual(self.progress_callback_count, 1) self.assertEqual(m.written, filedata) @@ -917,53 +1092,83 @@ def test_pull_file(self): def test_pull_bytesio(self): self.assertTrue(self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" - filedata = b'Ohayou sekai.\nGood morning world!' + filedata = b"Ohayou sekai.\nGood morning world!" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.DATA, data=filedata), - FileSyncMessage(command=constants.DONE))), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncMessage(command=constants.DATA, data=filedata), FileSyncMessage(command=constants.DONE) + ), + ), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.RECV, data=b'/data'))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages(FileSyncMessage(command=constants.RECV, data=b"/data")), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) stream = BytesIO() - self.device.pull('/data', stream) - + self.device.pull("/data", stream) + self.assertEqual(expected_bulk_write, self.transport.bulk_write_data) - self.assertEqual(stream.getvalue(), filedata) + self.assertEqual(stream.getvalue(), filedata) def test_pull_file_exception(self): self.assertTrue(self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" - filedata = b'Ohayou sekai.\nGood morning world!' + filedata = b"Ohayou sekai.\nGood morning world!" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.DATA, data=filedata), - FileSyncMessage(command=constants.DONE))), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncMessage(command=constants.DATA, data=filedata), FileSyncMessage(command=constants.DONE) + ), + ), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.RECV, data=b'/data'))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages(FileSyncMessage(command=constants.RECV, data=b"/data")), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - with patch('adb_shell.adb_device.open', patchers.mock_open()) as m: + with patch("adb_shell.adb_device.open", patchers.mock_open()) as m: # Set self.progress_callback_count to None so that an exception occurs when self.progress_callback tries to increment it self.progress_callback_count = None with patch("adb_shell.adb_device.AdbDevice.stat", self.fake_stat): - self.device.pull('/data', 'TEST_FILE', progress_callback=self.progress_callback) + self.device.pull("/data", "TEST_FILE", progress_callback=self.progress_callback) self.assertIsNone(self.progress_callback_count) self.assertEqual(m.written, filedata) @@ -971,28 +1176,43 @@ def test_pull_file_exception(self): def test_pull_big_file(self): self.assertTrue(self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" - filedata = b'0' * int(1.5 * constants.MAX_ADB_DATA) + filedata = b"0" * int(1.5 * constants.MAX_ADB_DATA) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.DATA, data=filedata), - FileSyncMessage(command=constants.DONE))), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncMessage(command=constants.DATA, data=filedata), FileSyncMessage(command=constants.DONE) + ), + ), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.RECV, data=b'/data'))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages(FileSyncMessage(command=constants.RECV, data=b"/data")), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - with patch('adb_shell.adb_device.open', patchers.mock_open()) as m: + with patch("adb_shell.adb_device.open", patchers.mock_open()) as m: self.assertEqual(self.progress_callback_count, 0) with patch("adb_shell.adb_device.AdbDevice.stat", self.fake_stat): - self.device.pull('/data', 'TEST_FILE', progress_callback=self.progress_callback) - + self.device.pull("/data", "TEST_FILE", progress_callback=self.progress_callback) + self.assertEqual(self.progress_callback_count, 1) self.assertEqual(m.written, filedata) self.assertEqual(expected_bulk_write, self.transport.bulk_write_data) @@ -1003,70 +1223,105 @@ def test_pull_empty_path(self): with self.assertRaises(exceptions.DevicePathInvalidError): self.device.pull(b"", "NOWHERE") with self.assertRaises(exceptions.DevicePathInvalidError): - self.device.pull(u"", "NOWHERE") + self.device.pull("", "NOWHERE") with self.assertRaises(exceptions.DevicePathInvalidError): self.device.pull(None, "NOWHERE") # Clear the `_bulk_read` buffer so that `self.tearDown()` passes - self.transport.bulk_read_data = b'' + self.transport.bulk_read_data = b"" def test_pull_non_existant_path(self): self.assertTrue(self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'FAIL&\x00\x00\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'open failed: No such file or directory'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"FAIL&\x00\x00\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"open failed: No such file or directory"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.RECV, data=b'/does/not/exist'))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages(FileSyncMessage(command=constants.RECV, data=b"/does/not/exist")), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) with self.assertRaises(exceptions.AdbCommandFailureException): self.device.pull("/does/not/exist", "NOWHERE") self.assertEqual(expected_bulk_write, self.transport.bulk_write_data) def test_pull_non_existant_path_2(self): self.assertTrue(self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'FAIL&\x00\x00\x00open failed: No such file or directory'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage( + command=constants.WRTE, arg0=1, arg1=1, data=b"FAIL&\x00\x00\x00open failed: No such file or directory" + ), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.RECV, data=b'/does/not/exist'))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages(FileSyncMessage(command=constants.RECV, data=b"/does/not/exist")), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) with self.assertRaises(exceptions.AdbCommandFailureException): self.device.pull("/does/not/exist", "NOWHERE") self.assertEqual(expected_bulk_write, self.transport.bulk_write_data) def test_stat(self): self.assertTrue(self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncStatMessage(constants.STAT, 1, 2, 3), - FileSyncStatMessage(constants.DONE, 0, 0, 0))), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncStatMessage(constants.STAT, 1, 2, 3), FileSyncStatMessage(constants.DONE, 0, 0, 0) + ), + ), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.STAT, data=b'/data'))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages(FileSyncMessage(command=constants.STAT, data=b"/data")), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - self.assertEqual((1, 2, 3), self.device.stat('/data')) + self.assertEqual((1, 2, 3), self.device.stat("/data")) self.assertEqual(expected_bulk_write, self.transport.bulk_write_data) def test_stat_empty_path(self): @@ -1075,30 +1330,37 @@ def test_stat_empty_path(self): with self.assertRaises(exceptions.DevicePathInvalidError): self.device.stat(b"") with self.assertRaises(exceptions.DevicePathInvalidError): - self.device.stat(u"") + self.device.stat("") with self.assertRaises(exceptions.DevicePathInvalidError): self.device.stat(None) # Clear the `_bulk_read` buffer so that `self.tearDown()` passes - self.transport.bulk_read_data = b'' + self.transport.bulk_read_data = b"" def test_stat_issue155(self): self.assertTrue(self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = b"".join([b'CLSE\n\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba', - b'OKAY\x0b\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6', - b'OKAY\x0b\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6', - b'WRTE\x0b\x00\x00\x00\x01\x00\x00\x00\x10\x00\x00\x00\x96\x04\x00\x00\xa8\xad\xab\xba', - b'STAT\xedA\x00\x00\x00\x10\x00\x00\xf0\x88[I', - b'CLSE\x0b\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba']) + self.transport.bulk_read_data = b"".join( + [ + b"CLSE\n\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", + b"OKAY\x0b\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6", + b"OKAY\x0b\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6", + b"WRTE\x0b\x00\x00\x00\x01\x00\x00\x00\x10\x00\x00\x00\x96\x04\x00\x00\xa8\xad\xab\xba", + b"STAT\xedA\x00\x00\x00\x10\x00\x00\xf0\x88[I", + b"CLSE\x0b\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", + ] + ) # This is where the expected values come from mode = 16877 size = 4096 mtime = 1230735600 - self.assertEqual(FileSyncStatMessage(constants.STAT, mode, size, mtime).pack(), b'STAT\xedA\x00\x00\x00\x10\x00\x00\xf0\x88[I') + self.assertEqual( + FileSyncStatMessage(constants.STAT, mode, size, mtime).pack(), + b"STAT\xedA\x00\x00\x00\x10\x00\x00\xf0\x88[I", + ) - self.assertEqual((mode, size, mtime), self.device.stat('/')) + self.assertEqual((mode, size, mtime), self.device.stat("/")) # ======================================================================= # # # @@ -1107,26 +1369,42 @@ def test_stat_issue155(self): # ======================================================================= # def test_filesync_read_adb_command_failure_exceptions(self): self.assertTrue(self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncStatMessage(constants.FAIL, 1, 2, 3), - FileSyncStatMessage(constants.DONE, 0, 0, 0)))) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncStatMessage(constants.FAIL, 1, 2, 3), FileSyncStatMessage(constants.DONE, 0, 0, 0) + ), + ), + ) with self.assertRaises(exceptions.AdbCommandFailureException): - self.device.stat('/data') + self.device.stat("/data") def test_filesync_read_invalid_response_error(self): self.assertTrue(self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncStatMessage(constants.DENT, 1, 2, 3), - FileSyncStatMessage(constants.DONE, 0, 0, 0)))) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncStatMessage(constants.DENT, 1, 2, 3), FileSyncStatMessage(constants.DONE, 0, 0, 0) + ), + ), + ) with self.assertRaises(exceptions.InvalidResponseError): - self.device.stat('/data') + self.device.stat("/data") diff --git a/tests/test_adb_device_async.py b/tests/test_adb_device_async.py index f6479b26..4abae0ce 100644 --- a/tests/test_adb_device_async.py +++ b/tests/test_adb_device_async.py @@ -20,7 +20,7 @@ # https://stackoverflow.com/a/7483862 -_LOGGER = logging.getLogger('adb_shell.adb_device_async') +_LOGGER = logging.getLogger("adb_shell.adb_device_async") _LOGGER.setLevel(logging.DEBUG) _LOGGER.addHandler(logging.StreamHandler(sys.stdout)) @@ -28,12 +28,13 @@ def to_int(cmd): return sum(c << (i * 8) for i, c in enumerate(bytearray(cmd))) + def join_messages(*messages): - return b''.join([message.pack() + message.data for message in messages]) + return b"".join([message.pack() + message.data for message in messages]) class AdbMessageForTesting(AdbMessage): - def __init__(self, command, arg0=None, arg1=None, data=b''): + def __init__(self, command, arg0=None, arg1=None, data=b""): self.command = to_int(command) self.magic = self.command ^ 0xFFFFFFFF self.arg0 = arg0 @@ -44,9 +45,9 @@ def __init__(self, command, arg0=None, arg1=None, data=b''): @patchers.ASYNC_SKIPPER class TestAdbDeviceAsync(unittest.TestCase): def setUp(self): - self.transport = FakeTcpTransportAsync('host', 5555) + self.transport = FakeTcpTransportAsync("host", 5555) self.device = AdbDeviceAsync(self.transport) - self.transport.bulk_read_data = b''.join(patchers.BULK_READ_LIST) + self.transport.bulk_read_data = b"".join(patchers.BULK_READ_LIST) self.progress_callback_count = 0 async def _progress_callback(device_path, current, total_bytes): @@ -70,21 +71,21 @@ def test_no_sync_references(self): self.assertTrue("BaseTransport." not in adb_device_async_source) self.assertTrue("adb_device." not in adb_device_async_source) self.assertTrue("AdbDevice." not in adb_device_async_source) - self.transport.bulk_read_data = b'' + self.transport.bulk_read_data = b"" @awaiter async def test_adb_connection_error(self): with self.assertRaises(exceptions.AdbConnectionError): - await self.device.exec_out('FAIL') + await self.device.exec_out("FAIL") with self.assertRaises(exceptions.AdbConnectionError): await self.device.root() with self.assertRaises(exceptions.AdbConnectionError): - await self.device.shell('FAIL') + await self.device.shell("FAIL") with self.assertRaises(exceptions.AdbConnectionError): - async_generator = self.device.streaming_shell('FAIL') + async_generator = self.device.streaming_shell("FAIL") await async_generator.__anext__() with self.assertRaises(exceptions.AdbConnectionError): @@ -94,23 +95,23 @@ async def test_adb_connection_error(self): await self.device.root() with self.assertRaises(exceptions.AdbConnectionError): - await self.device.list('FAIL') + await self.device.list("FAIL") with self.assertRaises(exceptions.AdbConnectionError): - await self.device.push('FAIL', 'FAIL') + await self.device.push("FAIL", "FAIL") with self.assertRaises(exceptions.AdbConnectionError): - await self.device.pull('FAIL', 'FAIL') + await self.device.pull("FAIL", "FAIL") with self.assertRaises(exceptions.AdbConnectionError): - await self.device.stat('FAIL') + await self.device.stat("FAIL") - self.transport.bulk_read_data = b'' + self.transport.bulk_read_data = b"" @awaiter async def test_init_tcp(self): with PATCH_TCP_TRANSPORT_ASYNC: - tcp_device = AdbDeviceTcpAsync('host') + tcp_device = AdbDeviceTcpAsync("host") tcp_device._io_manager._transport.bulk_read_data = self.transport.bulk_read_data # Make sure that the `connect()` method works @@ -118,24 +119,25 @@ async def test_init_tcp(self): self.assertTrue(tcp_device.available) # Clear the `_bulk_read` buffer so that `self.tearDown()` passes - self.transport.bulk_read_data = b'' - + self.transport.bulk_read_data = b"" @awaiter async def test_init_banner(self): - device_with_banner = AdbDeviceAsync(transport=FakeTcpTransportAsync('host', 5555), banner='banner') - self.assertEqual(device_with_banner._banner, b'banner') + device_with_banner = AdbDeviceAsync(transport=FakeTcpTransportAsync("host", 5555), banner="banner") + self.assertEqual(device_with_banner._banner, b"banner") - device_with_banner2 = AdbDeviceAsync(transport=FakeTcpTransportAsync('host', 5555), banner=bytearray('banner2', 'utf-8')) - self.assertEqual(device_with_banner2._banner, b'banner2') + device_with_banner2 = AdbDeviceAsync( + transport=FakeTcpTransportAsync("host", 5555), banner=bytearray("banner2", "utf-8") + ) + self.assertEqual(device_with_banner2._banner, b"banner2") - device_with_banner3 = AdbDeviceAsync(transport=FakeTcpTransportAsync('host', 5555), banner=u'banner3') - self.assertEqual(device_with_banner3._banner, b'banner3') + device_with_banner3 = AdbDeviceAsync(transport=FakeTcpTransportAsync("host", 5555), banner="banner3") + self.assertEqual(device_with_banner3._banner, b"banner3") - with patch('socket.gethostname', side_effect=Exception): + with patch("socket.gethostname", side_effect=Exception): device_banner_unknown = AdbDeviceAsync(self.transport) self.assertTrue(await device_banner_unknown.connect()) - self.assertEqual(device_banner_unknown._banner, b'unknown') + self.assertEqual(device_banner_unknown._banner, b"unknown") @awaiter async def test_init_invalid_transport(self): @@ -143,14 +145,14 @@ async def test_init_invalid_transport(self): device = AdbDeviceAsync(transport=123) # Clear the `_bulk_read` buffer so that `self.tearDown()` passes - self.transport.bulk_read_data = b'' + self.transport.bulk_read_data = b"" @awaiter async def test_available(self): self.assertFalse(self.device.available) # Clear the `_bulk_read` buffer so that `self.tearDown()` passes - self.transport.bulk_read_data = b'' + self.transport.bulk_read_data = b"" @awaiter async def test_close(self): @@ -158,7 +160,7 @@ async def test_close(self): self.assertFalse(self.device.available) # Clear the `_bulk_read` buffer so that `self.tearDown()` passes - self.transport.bulk_read_data = b'' + self.transport.bulk_read_data = b"" # ======================================================================= # # # @@ -172,7 +174,7 @@ async def test_connect(self): @awaiter async def test_connect_no_keys(self): - self.transport.bulk_read_data = b''.join(patchers.BULK_READ_LIST_WITH_AUTH[:2]) + self.transport.bulk_read_data = b"".join(patchers.BULK_READ_LIST_WITH_AUTH[:2]) with self.assertRaises(exceptions.DeviceAuthError): await self.device.connect() @@ -180,11 +182,13 @@ async def test_connect_no_keys(self): @awaiter async def test_connect_with_key_invalid_response(self): - with patch('adb_shell.auth.sign_pythonrsa.open', open_priv_pub), patch('adb_shell.auth.keygen.open', open_priv_pub): - keygen('tests/adbkey') - signer = PythonRSASigner.FromRSAKeyPath('tests/adbkey') + with patch("adb_shell.auth.sign_pythonrsa.open", open_priv_pub), patch( + "adb_shell.auth.keygen.open", open_priv_pub + ): + keygen("tests/adbkey") + signer = PythonRSASigner.FromRSAKeyPath("tests/adbkey") - self.transport.bulk_read_data = b''.join(patchers.BULK_READ_LIST_WITH_AUTH_INVALID) + self.transport.bulk_read_data = b"".join(patchers.BULK_READ_LIST_WITH_AUTH_INVALID) with self.assertRaises(exceptions.InvalidResponseError): await self.device.connect([signer]) @@ -193,37 +197,44 @@ async def test_connect_with_key_invalid_response(self): @awaiter async def test_connect_with_key(self): - with patch('adb_shell.auth.sign_pythonrsa.open', open_priv_pub), patch('adb_shell.auth.keygen.open', open_priv_pub): - keygen('tests/adbkey') - signer = PythonRSASigner.FromRSAKeyPath('tests/adbkey') + with patch("adb_shell.auth.sign_pythonrsa.open", open_priv_pub), patch( + "adb_shell.auth.keygen.open", open_priv_pub + ): + keygen("tests/adbkey") + signer = PythonRSASigner.FromRSAKeyPath("tests/adbkey") - self.transport.bulk_read_data = b''.join(patchers.BULK_READ_LIST_WITH_AUTH) + self.transport.bulk_read_data = b"".join(patchers.BULK_READ_LIST_WITH_AUTH) self.assertTrue(await self.device.connect([signer])) @awaiter async def test_connect_with_new_key(self): - with patch('adb_shell.auth.sign_pythonrsa.open', open_priv_pub), patch('adb_shell.auth.keygen.open', open_priv_pub): - keygen('tests/adbkey') - signer = PythonRSASigner.FromRSAKeyPath('tests/adbkey') - signer.pub_key = u'' + with patch("adb_shell.auth.sign_pythonrsa.open", open_priv_pub), patch( + "adb_shell.auth.keygen.open", open_priv_pub + ): + keygen("tests/adbkey") + signer = PythonRSASigner.FromRSAKeyPath("tests/adbkey") + signer.pub_key = "" - self.transport.bulk_read_data = b''.join(patchers.BULK_READ_LIST_WITH_AUTH_NEW_KEY) + self.transport.bulk_read_data = b"".join(patchers.BULK_READ_LIST_WITH_AUTH_NEW_KEY) self.assertTrue(await self.device.connect([signer])) @awaiter async def test_connect_with_new_key_and_callback(self): - with patch('adb_shell.auth.sign_pythonrsa.open', open_priv_pub), patch('adb_shell.auth.keygen.open', open_priv_pub): - keygen('tests/adbkey') - signer = PythonRSASigner.FromRSAKeyPath('tests/adbkey') - signer.pub_key = u'' + with patch("adb_shell.auth.sign_pythonrsa.open", open_priv_pub), patch( + "adb_shell.auth.keygen.open", open_priv_pub + ): + keygen("tests/adbkey") + signer = PythonRSASigner.FromRSAKeyPath("tests/adbkey") + signer.pub_key = "" self._callback_invoked = False + def auth_callback(device): self._callback_invoked = True - self.transport.bulk_read_data = b''.join(patchers.BULK_READ_LIST_WITH_AUTH_NEW_KEY) + self.transport.bulk_read_data = b"".join(patchers.BULK_READ_LIST_WITH_AUTH_NEW_KEY) self.assertTrue(await self.device.connect([signer], auth_callback=auth_callback)) self.assertTrue(self._callback_invoked) @@ -246,85 +257,99 @@ async def test_shell_no_return(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - self.assertEqual(await self.device.shell('TEST'), '') + self.assertEqual(await self.device.shell("TEST"), "") @awaiter async def test_shell_return_pass(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'PA'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'SS'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"PA"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"SS"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - self.assertEqual(await self.device.shell('TEST'), 'PASS') + self.assertEqual(await self.device.shell("TEST"), "PASS") @awaiter async def test_shell_local_id_wraparound(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=2**32 - 1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=2**32 - 1, data=b'PASS1'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=2**32 - 1, data=b''), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'PASS2'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=2**32 - 1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=2**32 - 1, data=b"PASS1"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=2**32 - 1, data=b""), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"PASS2"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) self.device._local_id = 2**32 - 2 - self.assertEqual(await self.device.shell('TEST'), 'PASS1') - self.assertEqual(await self.device.shell('TEST'), 'PASS2') + self.assertEqual(await self.device.shell("TEST"), "PASS1") + self.assertEqual(await self.device.shell("TEST"), "PASS2") @awaiter async def test_shell_return_pass_with_unexpected_packet(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'PA'), - AdbMessage(command=constants.AUTH, arg0=1, arg1=1, data=b'UNEXPECTED'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'SS'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"PA"), + AdbMessage(command=constants.AUTH, arg0=1, arg1=1, data=b"UNEXPECTED"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"SS"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - self.assertEqual(await self.device.shell('TEST'), 'PASS') + self.assertEqual(await self.device.shell("TEST"), "PASS") @awaiter async def test_shell_dont_decode(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'PA'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'SS'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"PA"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"SS"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - self.assertEqual(await self.device.shell('TEST', decode=False), b'PASS') + self.assertEqual(await self.device.shell("TEST", decode=False), b"PASS") @awaiter async def test_shell_avoid_decode_error(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'\x80abc'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"\x80abc"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - self.assertEqual(await self.device.shell('TEST'), '\\x80abc') + self.assertEqual(await self.device.shell("TEST"), "\\x80abc") @awaiter async def test_shell_data_length_exceeds_max(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'0'*(self.device.max_chunk_size+1)), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"0" * (self.device.max_chunk_size + 1)), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - await self.device.shell('TEST') + await self.device.shell("TEST") self.assertTrue(True) @awaiter @@ -332,23 +357,29 @@ async def test_shell_multibytes_sequence_exceeds_max(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'0'*(self.device.max_chunk_size-1) + b'\xe3\x81\x82'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage( + command=constants.WRTE, arg0=1, arg1=1, data=b"0" * (self.device.max_chunk_size - 1) + b"\xe3\x81\x82" + ), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - self.assertEqual(await self.device.shell('TEST'), u'0'*(self.device.max_chunk_size-1) + u'\u3042') + self.assertEqual(await self.device.shell("TEST"), "0" * (self.device.max_chunk_size - 1) + "\u3042") @awaiter async def test_shell_with_multibytes_sequence_over_two_messages(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'\xe3'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'\x81\x82'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"\xe3"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"\x81\x82"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - self.assertEqual(await self.device.shell('TEST'), u'\u3042') + self.assertEqual(await self.device.shell("TEST"), "\u3042") @awaiter async def test_shell_multiple_clse(self): @@ -356,40 +387,48 @@ async def test_shell_multiple_clse(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - msg1 = AdbMessage(command=constants.OKAY, arg0=2, arg1=2, data=b'') - msg2 = AdbMessage(command=constants.WRTE, arg0=2, arg1=2, data=b'PASS') - msg3 = AdbMessage(command=constants.CLSE, arg0=2, arg1=2, data=b'') - self.transport.bulk_read_data = b''.join([b'OKAY\xd9R\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6', - b'WRTE\xd9R\x00\x00\x01\x00\x00\x00\x01\x00\x00\x002\x00\x00\x00\xa8\xad\xab\xba', - b'2', - b'WRTE\xd9R\x00\x00\x01\x00\x00\x00\x0c\x02\x00\x00\xc0\x92\x00\x00\xa8\xad\xab\xba', - b'Wake Locks: size=2\ncom.google.android.tvlauncher\n\n- STREAM_MUSIC:\n Muted: true\n Min: 0\n Max: 15\n Current: 2 (speaker): 15, 4 (headset): 10, 8 (headphone): 10, 80 (bt_a2dp): 10, 1000 (digital_dock): 10, 4000000 (usb_headset): 3, 40000000 (default): 15\n Devices: speaker\n- STREAM_ALARM:\n Muted: true\n Min: 1\n Max: 7\n Current: 2 (speaker): 7, 4 (headset): 5, 8 (headphone): 5, 80 (bt_a2dp): 5, 1000 (digital_dock): 5, 4000000 (usb_headset): 1, 40000000 (default): 7\n Devices: speaker\n- STREAM_NOTIFICATION:\n', - b'CLSE\xd9R\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba', - msg1.pack(), - b'CLSE\xdaR\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba', - msg2.pack(), - msg2.data, - msg3.pack()]) - - await self.device.shell("dumpsys power | grep 'Display Power' | grep -q 'state=ON' && echo -e '1\\c' && dumpsys power | grep mWakefulness | grep -q Awake && echo -e '1\\c' && dumpsys audio | grep paused | grep -qv 'Buffer Queue' && echo -e '1\\c' || (dumpsys audio | grep started | grep -qv 'Buffer Queue' && echo '2\\c' || echo '0\\c') && dumpsys power | grep Locks | grep 'size=' && CURRENT_APP=$(dumpsys window windows | grep mCurrentFocus) && CURRENT_APP=${CURRENT_APP#*{* * } && CURRENT_APP=${CURRENT_APP%%/*} && echo $CURRENT_APP && (dumpsys media_session | grep -A 100 'Sessions Stack' | grep -A 100 $CURRENT_APP | grep -m 1 'state=PlaybackState {' || echo) && dumpsys audio | grep '\\- STREAM_MUSIC:' -A 12") - self.assertEqual(await self.device.shell('TEST'), 'PASS') + msg1 = AdbMessage(command=constants.OKAY, arg0=2, arg1=2, data=b"") + msg2 = AdbMessage(command=constants.WRTE, arg0=2, arg1=2, data=b"PASS") + msg3 = AdbMessage(command=constants.CLSE, arg0=2, arg1=2, data=b"") + self.transport.bulk_read_data = b"".join( + [ + b"OKAY\xd9R\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6", + b"WRTE\xd9R\x00\x00\x01\x00\x00\x00\x01\x00\x00\x002\x00\x00\x00\xa8\xad\xab\xba", + b"2", + b"WRTE\xd9R\x00\x00\x01\x00\x00\x00\x0c\x02\x00\x00\xc0\x92\x00\x00\xa8\xad\xab\xba", + b"Wake Locks: size=2\ncom.google.android.tvlauncher\n\n- STREAM_MUSIC:\n Muted: true\n Min: 0\n Max: 15\n Current: 2 (speaker): 15, 4 (headset): 10, 8 (headphone): 10, 80 (bt_a2dp): 10, 1000 (digital_dock): 10, 4000000 (usb_headset): 3, 40000000 (default): 15\n Devices: speaker\n- STREAM_ALARM:\n Muted: true\n Min: 1\n Max: 7\n Current: 2 (speaker): 7, 4 (headset): 5, 8 (headphone): 5, 80 (bt_a2dp): 5, 1000 (digital_dock): 5, 4000000 (usb_headset): 1, 40000000 (default): 7\n Devices: speaker\n- STREAM_NOTIFICATION:\n", + b"CLSE\xd9R\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", + msg1.pack(), + b"CLSE\xdaR\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", + msg2.pack(), + msg2.data, + msg3.pack(), + ] + ) + + await self.device.shell( + "dumpsys power | grep 'Display Power' | grep -q 'state=ON' && echo -e '1\\c' && dumpsys power | grep mWakefulness | grep -q Awake && echo -e '1\\c' && dumpsys audio | grep paused | grep -qv 'Buffer Queue' && echo -e '1\\c' || (dumpsys audio | grep started | grep -qv 'Buffer Queue' && echo '2\\c' || echo '0\\c') && dumpsys power | grep Locks | grep 'size=' && CURRENT_APP=$(dumpsys window windows | grep mCurrentFocus) && CURRENT_APP=${CURRENT_APP#*{* * } && CURRENT_APP=${CURRENT_APP%%/*} && echo $CURRENT_APP && (dumpsys media_session | grep -A 100 'Sessions Stack' | grep -A 100 $CURRENT_APP | grep -m 1 'state=PlaybackState {' || echo) && dumpsys audio | grep '\\- STREAM_MUSIC:' -A 12" + ) + self.assertEqual(await self.device.shell("TEST"), "PASS") @awaiter async def test_shell_multiple_streams(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=2, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=2, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=2, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=2, data=b'PASS2'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'PASS1'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.CLSE, arg0=1, arg1=2, data=b'')) - - self.assertEqual(await self.device.shell('TEST1'), 'PASS1') - self.assertEqual(await self.device.shell('TEST2'), 'PASS2') + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=2, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=2, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=2, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=2, data=b"PASS2"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"PASS1"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.CLSE, arg0=1, arg1=2, data=b""), + ) + + self.assertEqual(await self.device.shell("TEST1"), "PASS1") + self.assertEqual(await self.device.shell("TEST2"), "PASS2") @awaiter async def test_shell_multiple_streams2(self): @@ -397,11 +436,11 @@ async def test_shell_multiple_streams2(self): async def fake_read_packet_from_device(*args, **kwargs): # Mimic the scenario that this stream's packets get read by another stream after the first attempt to read the packet from the device - self.device._io_manager._packet_store.put(arg0=1, arg1=1, cmd=constants.WRTE, data=b'\x00') - self.device._io_manager._packet_store.put(arg0=1, arg1=1, cmd=constants.OKAY, data=b'\x00') - self.device._io_manager._packet_store.put(arg0=2, arg1=2, cmd=constants.OKAY, data=b'\x00') - self.device._io_manager._packet_store.put(arg0=1, arg1=1, cmd=constants.OKAY, data=b'\x00') - self.device._io_manager._packet_store.put(arg0=2, arg1=2, cmd=constants.WRTE, data=b'PASS2') + self.device._io_manager._packet_store.put(arg0=1, arg1=1, cmd=constants.WRTE, data=b"\x00") + self.device._io_manager._packet_store.put(arg0=1, arg1=1, cmd=constants.OKAY, data=b"\x00") + self.device._io_manager._packet_store.put(arg0=2, arg1=2, cmd=constants.OKAY, data=b"\x00") + self.device._io_manager._packet_store.put(arg0=1, arg1=1, cmd=constants.OKAY, data=b"\x00") + self.device._io_manager._packet_store.put(arg0=2, arg1=2, cmd=constants.WRTE, data=b"PASS2") self.device._io_manager._packet_store.put(arg0=1, arg1=1, cmd=constants.WRTE, data=b"PASS1") self.device._io_manager._packet_store.put(arg0=1, arg1=1, cmd=constants.CLSE, data=b"") self.device._io_manager._packet_store.put(arg0=2, arg1=2, cmd=constants.CLSE, data=b"") @@ -410,39 +449,42 @@ async def fake_read_packet_from_device(*args, **kwargs): with patch.object(self.device._io_manager, "_read_packet_from_device", fake_read_packet_from_device): # The patch function will only be called once, all subsequent packets will be retrieved from the store - self.assertEqual(await self.device.shell('TEST1'), 'PASS1') - self.assertEqual(await self.device.shell('TEST2'), 'PASS2') + self.assertEqual(await self.device.shell("TEST1"), "PASS1") + self.assertEqual(await self.device.shell("TEST2"), "PASS2") @awaiter async def test_shell_local_id2(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=2, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=2, data=b'PASS2'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'PASS1'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.CLSE, arg0=1, arg1=2, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=2, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=2, data=b"PASS2"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"PASS1"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.CLSE, arg0=1, arg1=2, data=b""), + ) - self.assertEqual(await self.device.shell('TEST1'), 'PASS1') - self.assertEqual(await self.device.shell('TEST2'), 'PASS2') + self.assertEqual(await self.device.shell("TEST1"), "PASS1") + self.assertEqual(await self.device.shell("TEST2"), "PASS2") @awaiter async def test_shell_remote_id2(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=2, arg1=2, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=2, arg1=2, data=b'PASS2'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'PASS1'), - AdbMessage(command=constants.CLSE, arg0=2, arg1=2, data=b''), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) - - self.assertEqual(await self.device.shell('TEST1'), 'PASS1') - self.assertEqual(await self.device.shell('TEST2'), 'PASS2') + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=2, arg1=2, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=2, arg1=2, data=b"PASS2"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"PASS1"), + AdbMessage(command=constants.CLSE, arg0=2, arg1=2, data=b""), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) + self.assertEqual(await self.device.shell("TEST1"), "PASS1") + self.assertEqual(await self.device.shell("TEST2"), "PASS2") # ======================================================================= # # # @@ -454,11 +496,13 @@ async def test_shell_error_local_id_timeout(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1234, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1234, data=b'\x00')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1234, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1234, data=b"\x00"), + ) with self.assertRaises(exceptions.AdbTimeoutError): - await self.device.shell('TEST', read_timeout_s=1) + await self.device.shell("TEST", read_timeout_s=1) # Close the connection so that the packet store gets cleared await self.device.close() @@ -468,142 +512,154 @@ async def test_shell_error_unknown_command(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessageForTesting(command=constants.FAIL, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessageForTesting(command=constants.FAIL, arg0=1, arg1=1, data=b"") + ) with self.assertRaises(exceptions.InvalidCommandError): - self.assertEqual(await self.device.shell('TEST'), '') + self.assertEqual(await self.device.shell("TEST"), "") @awaiter async def test_shell_error_transport_timeout(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"")) with self.assertRaises(exceptions.AdbTimeoutError): - await self.device.shell('TEST', read_timeout_s=-1) + await self.device.shell("TEST", read_timeout_s=-1) @awaiter async def test_shell_error_read_timeout_multiple_clse(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.CLSE, arg0=2, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.CLSE, arg0=2, arg1=1, data=b""), + ) with self.assertRaises(exceptions.AdbTimeoutError): - await self.device.shell('TEST', read_timeout_s=-1) + await self.device.shell("TEST", read_timeout_s=-1) @awaiter async def test_shell_error_timeout(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'PA'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'SS'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"PA"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"SS"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) async def fake_read_until(*args, **kwargs): await asyncio.sleep(0.2) - return b'WRTE', b'PA' + return b"WRTE", b"PA" - with patch('adb_shell.adb_device_async.AdbDeviceAsync._read_until', fake_read_until): + with patch("adb_shell.adb_device_async.AdbDeviceAsync._read_until", fake_read_until): with self.assertRaises(exceptions.AdbTimeoutError): - await self.device.shell('TEST', timeout_s=0.5) + await self.device.shell("TEST", timeout_s=0.5) # Clear the `_bulk_read` buffer so that `self.tearDown()` passes - self.transport.bulk_read_data = b'' + self.transport.bulk_read_data = b"" @awaiter async def test_shell_error_checksum(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - msg1 = AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00') - msg2 = AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'PASS') - self.transport.bulk_read_data = b''.join([msg1.pack(), msg1.data, msg2.pack(), msg2.data[:-1] + b'0']) + msg1 = AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00") + msg2 = AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"PASS") + self.transport.bulk_read_data = b"".join([msg1.pack(), msg1.data, msg2.pack(), msg2.data[:-1] + b"0"]) with self.assertRaises(exceptions.InvalidChecksumError): - await self.device.shell('TEST') + await self.device.shell("TEST") @awaiter async def test_issue29(self): # https://github.com/JeffLIrion/adb_shell/issues/29 - with patch('adb_shell.auth.sign_pythonrsa.open', open_priv_pub), patch('adb_shell.auth.keygen.open', open_priv_pub): - keygen('tests/adbkey') - signer = PythonRSASigner.FromRSAKeyPath('tests/adbkey') - - okay3 = AdbMessage(command=constants.OKAY, arg0=1, arg1=3, data=b'\x00') - clse3 = AdbMessage(command=constants.CLSE, arg0=1, arg1=3, data=b'') - okay5 = AdbMessage(command=constants.OKAY, arg0=1, arg1=5, data=b'\x00') - clse5 = AdbMessage(command=constants.CLSE, arg0=1, arg1=5, data=b'') - okay7 = AdbMessage(command=constants.OKAY, arg0=1, arg1=7, data=b'\x00') - clse7 = AdbMessage(command=constants.CLSE, arg0=1, arg1=7, data=b'') - - self.transport.bulk_read_data = b''.join([b'AUTH\x01\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\xc5\n\x00\x00\xbe\xaa\xab\xb7', # Line 22 - b"\x17\xbf\xbf\xff\xc7\xa2eo'Sh\xdf\x8e\xf5\xff\xe0\tJ6H", # Line 23 - b"CNXN\x00\x00\x00\x01\x00\x10\x00\x00i\x00\x00\x00.'\x00\x00\xbc\xb1\xa7\xb1", # Line 26 - b'device::ro.product.name=once;ro.product.model=MIBOX3;ro.product.device=once;features=stat_v2,cmd,shell_v2', # Line 27 - b'OKAY\x99\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6', # Line 290 (modified --> Line 30) - b'CLSE\xa2\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba', # Line 291 - b'CLSE\xa2\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba', # Line 292 - b'WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x001\x00\x00\x00\xa8\xad\xab\xba', # Line 31 - b'1', # Line 32 - b'WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x001\x00\x00\x00\xa8\xad\xab\xba', # Line 35 - b'1', # Line 36 - b'WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x000\x00\x00\x00\xa8\xad\xab\xba', # Line 39 - b'0', # Line 40 - b'WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x13\x00\x00\x000\x06\x00\x00\xa8\xad\xab\xba', # Line 43 - b'Wake Locks: size=0\n', # Line 44 - b'WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x1e\x00\x00\x00V\x0b\x00\x00\xa8\xad\xab\xba', # Line 47 - b'com.google.android.youtube.tv\n', # Line 48 - b'WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x98\x00\x00\x00\xa13\x00\x00\xa8\xad\xab\xba', # Line 51 - b' state=PlaybackState {state=0, position=0, buffered position=0, speed=0.0, updated=0, actions=0, custom actions=[], active item id=-1, error=null}\n', # Line 52 - b'WRTE\x99\x00\x00\x00\x01\x00\x00\x00.\x01\x00\x00\xceP\x00\x00\xa8\xad\xab\xba', # Line 55 - b'- STREAM_MUSIC:\n Muted: false\n Min: 0\n Max: 15\n Current: 2 (speaker): 11, 4 (headset): 10, 8 (headphone): 10, 400 (hdmi): 6, 40000000 (default): 11\n Devices: hdmi\n- STREAM_ALARM:\n Muted: false\n Min: 0\n Max: 7\n Current: 40000000 (default): 6\n Devices: speaker\n- STREAM_NOTIFICATION:\n', # Line 56 - b'CLSE\x99\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba', # Line 59 - b'AUTH\x01\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x94\t\x00\x00\xbe\xaa\xab\xb7', # Line 297 - b'P\xa5\x86\x97\xe8\x01\xb09\x8c>F\x9d\xc6\xbd\xc0J\x80!\xbb\x1a', # Line 298 - b"CNXN\x00\x00\x00\x01\x00\x10\x00\x00i\x00\x00\x00.'\x00\x00\xbc\xb1\xa7\xb1", # Line 301 - b'device::ro.product.name=once;ro.product.model=MIBOX3;ro.product.device=once;features=stat_v2,cmd,shell_v2', # Line 302 - b'OKAY\xa5\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6', # Line 305 - b'CLSE\xa5\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba', # Line 306 - okay3.pack(), - okay3.data, - clse3.pack(), - b'AUTH\x01\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00e\x0c\x00\x00\xbe\xaa\xab\xb7', # Line 315 - b'\xd3\xef\x7f_\xa6\xc0`b\x19\\z\xe4\xf3\xe2\xed\x8d\xe1W\xfbH', # Line 316 - b"CNXN\x00\x00\x00\x01\x00\x10\x00\x00i\x00\x00\x00.'\x00\x00\xbc\xb1\xa7\xb1", # Line 319 - b'device::ro.product.name=once;ro.product.model=MIBOX3;ro.product.device=once;features=stat_v2,cmd,shell_v2', # Line 320 - b'OKAY\xa7\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6', # Line 323 - b'CLSE\xa7\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba', # Line 324 - okay5.pack(), - okay5.data, - clse5.pack(), - b'AUTH\x01\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x93\x08\x00\x00\xbe\xaa\xab\xb7', # Line 333 - b's\xd4_e\xa4s\x02\x95\x0f\x1e\xec\n\x95Y9[`\x8e\xe1f', # Line 334 - b"CNXN\x00\x00\x00\x01\x00\x10\x00\x00i\x00\x00\x00.'\x00\x00\xbc\xb1\xa7\xb1", # Line 337 - b'device::ro.product.name=once;ro.product.model=MIBOX3;ro.product.device=once;features=stat_v2,cmd,shell_v2', # Line 338 - b'OKAY\xa9\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6', # Line 341 - b'CLSE\xa9\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba', # Line 342 - okay7.pack(), - okay7.data, - clse7.pack()]) + with patch("adb_shell.auth.sign_pythonrsa.open", open_priv_pub), patch( + "adb_shell.auth.keygen.open", open_priv_pub + ): + keygen("tests/adbkey") + signer = PythonRSASigner.FromRSAKeyPath("tests/adbkey") + + okay3 = AdbMessage(command=constants.OKAY, arg0=1, arg1=3, data=b"\x00") + clse3 = AdbMessage(command=constants.CLSE, arg0=1, arg1=3, data=b"") + okay5 = AdbMessage(command=constants.OKAY, arg0=1, arg1=5, data=b"\x00") + clse5 = AdbMessage(command=constants.CLSE, arg0=1, arg1=5, data=b"") + okay7 = AdbMessage(command=constants.OKAY, arg0=1, arg1=7, data=b"\x00") + clse7 = AdbMessage(command=constants.CLSE, arg0=1, arg1=7, data=b"") + + self.transport.bulk_read_data = b"".join( + [ + b"AUTH\x01\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\xc5\n\x00\x00\xbe\xaa\xab\xb7", # Line 22 + b"\x17\xbf\xbf\xff\xc7\xa2eo'Sh\xdf\x8e\xf5\xff\xe0\tJ6H", # Line 23 + b"CNXN\x00\x00\x00\x01\x00\x10\x00\x00i\x00\x00\x00.'\x00\x00\xbc\xb1\xa7\xb1", # Line 26 + b"device::ro.product.name=once;ro.product.model=MIBOX3;ro.product.device=once;features=stat_v2,cmd,shell_v2", # Line 27 + b"OKAY\x99\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6", # Line 290 (modified --> Line 30) + b"CLSE\xa2\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", # Line 291 + b"CLSE\xa2\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", # Line 292 + b"WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x001\x00\x00\x00\xa8\xad\xab\xba", # Line 31 + b"1", # Line 32 + b"WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x001\x00\x00\x00\xa8\xad\xab\xba", # Line 35 + b"1", # Line 36 + b"WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x000\x00\x00\x00\xa8\xad\xab\xba", # Line 39 + b"0", # Line 40 + b"WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x13\x00\x00\x000\x06\x00\x00\xa8\xad\xab\xba", # Line 43 + b"Wake Locks: size=0\n", # Line 44 + b"WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x1e\x00\x00\x00V\x0b\x00\x00\xa8\xad\xab\xba", # Line 47 + b"com.google.android.youtube.tv\n", # Line 48 + b"WRTE\x99\x00\x00\x00\x01\x00\x00\x00\x98\x00\x00\x00\xa13\x00\x00\xa8\xad\xab\xba", # Line 51 + b" state=PlaybackState {state=0, position=0, buffered position=0, speed=0.0, updated=0, actions=0, custom actions=[], active item id=-1, error=null}\n", # Line 52 + b"WRTE\x99\x00\x00\x00\x01\x00\x00\x00.\x01\x00\x00\xceP\x00\x00\xa8\xad\xab\xba", # Line 55 + b"- STREAM_MUSIC:\n Muted: false\n Min: 0\n Max: 15\n Current: 2 (speaker): 11, 4 (headset): 10, 8 (headphone): 10, 400 (hdmi): 6, 40000000 (default): 11\n Devices: hdmi\n- STREAM_ALARM:\n Muted: false\n Min: 0\n Max: 7\n Current: 40000000 (default): 6\n Devices: speaker\n- STREAM_NOTIFICATION:\n", # Line 56 + b"CLSE\x99\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", # Line 59 + b"AUTH\x01\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x94\t\x00\x00\xbe\xaa\xab\xb7", # Line 297 + b"P\xa5\x86\x97\xe8\x01\xb09\x8c>F\x9d\xc6\xbd\xc0J\x80!\xbb\x1a", # Line 298 + b"CNXN\x00\x00\x00\x01\x00\x10\x00\x00i\x00\x00\x00.'\x00\x00\xbc\xb1\xa7\xb1", # Line 301 + b"device::ro.product.name=once;ro.product.model=MIBOX3;ro.product.device=once;features=stat_v2,cmd,shell_v2", # Line 302 + b"OKAY\xa5\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6", # Line 305 + b"CLSE\xa5\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", # Line 306 + okay3.pack(), + okay3.data, + clse3.pack(), + b"AUTH\x01\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00e\x0c\x00\x00\xbe\xaa\xab\xb7", # Line 315 + b"\xd3\xef\x7f_\xa6\xc0`b\x19\\z\xe4\xf3\xe2\xed\x8d\xe1W\xfbH", # Line 316 + b"CNXN\x00\x00\x00\x01\x00\x10\x00\x00i\x00\x00\x00.'\x00\x00\xbc\xb1\xa7\xb1", # Line 319 + b"device::ro.product.name=once;ro.product.model=MIBOX3;ro.product.device=once;features=stat_v2,cmd,shell_v2", # Line 320 + b"OKAY\xa7\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6", # Line 323 + b"CLSE\xa7\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", # Line 324 + okay5.pack(), + okay5.data, + clse5.pack(), + b"AUTH\x01\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x93\x08\x00\x00\xbe\xaa\xab\xb7", # Line 333 + b"s\xd4_e\xa4s\x02\x95\x0f\x1e\xec\n\x95Y9[`\x8e\xe1f", # Line 334 + b"CNXN\x00\x00\x00\x01\x00\x10\x00\x00i\x00\x00\x00.'\x00\x00\xbc\xb1\xa7\xb1", # Line 337 + b"device::ro.product.name=once;ro.product.model=MIBOX3;ro.product.device=once;features=stat_v2,cmd,shell_v2", # Line 338 + b"OKAY\xa9\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6", # Line 341 + b"CLSE\xa9\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", # Line 342 + okay7.pack(), + okay7.data, + clse7.pack(), + ] + ) self.assertTrue(await self.device.connect([signer])) - await self.device.shell('Android TV update command') + await self.device.shell("Android TV update command") self.assertTrue(await self.device.connect([signer])) - await self.device.shell('Android TV update command') - await self.device.shell('Android TV update command') + await self.device.shell("Android TV update command") + await self.device.shell("Android TV update command") self.assertTrue(await self.device.connect([signer])) - await self.device.shell('Android TV update command') - await self.device.shell('Android TV update command') + await self.device.shell("Android TV update command") + await self.device.shell("Android TV update command") self.assertTrue(await self.device.connect([signer])) - await self.device.shell('Android TV update command') - await self.device.shell('Android TV update command') + await self.device.shell("Android TV update command") + await self.device.shell("Android TV update command") # ======================================================================= # # # @@ -616,14 +672,14 @@ async def test_streaming_shell_decode(self): # Provide the `bulk_read` return values self.transport.bulk_read_data = join_messages( - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'ABC'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'123'), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"ABC"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"123"), ) - async_generator = self.device.streaming_shell('TEST', decode=True) - self.assertEqual(await async_generator.__anext__(), 'ABC') - self.assertEqual(await async_generator.__anext__(), '123') + async_generator = self.device.streaming_shell("TEST", decode=True) + self.assertEqual(await async_generator.__anext__(), "ABC") + self.assertEqual(await async_generator.__anext__(), "123") @awaiter async def test_streaming_shell_dont_decode(self): @@ -631,15 +687,14 @@ async def test_streaming_shell_dont_decode(self): # Provide the `bulk_read` return values self.transport.bulk_read_data = join_messages( - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'ABC'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'123'), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"ABC"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"123"), ) - async_generator = self.device.streaming_shell('TEST', decode=False) - self.assertEqual(await async_generator.__anext__(), b'ABC') - self.assertEqual(await async_generator.__anext__(), b'123') - + async_generator = self.device.streaming_shell("TEST", decode=False) + self.assertEqual(await async_generator.__anext__(), b"ABC") + self.assertEqual(await async_generator.__anext__(), b"123") # ======================================================================= # # # @@ -650,11 +705,10 @@ async def test_streaming_shell_dont_decode(self): async def test_reboot(self): self.assertTrue(await self.device.connect()) - with async_patch('adb_shell.adb_device_async.AdbDeviceAsync._open') as patch_open: + with async_patch("adb_shell.adb_device_async.AdbDeviceAsync._open") as patch_open: await self.device.reboot() patch_open.assert_called_once() - # ======================================================================= # # # # `root` test # @@ -664,11 +718,10 @@ async def test_reboot(self): async def test_root(self): self.assertTrue(await self.device.connect()) - with async_patch('adb_shell.adb_device_async.AdbDeviceAsync._service') as patch_service: + with async_patch("adb_shell.adb_device_async.AdbDeviceAsync._service") as patch_service: await self.device.root() patch_service.assert_called_once() - # ======================================================================= # # # # `exec_out` test # @@ -679,15 +732,18 @@ async def test_exec_out(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = b''.join([b'OKAY\x14\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6', - b'WRTE\x14\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00J\x01\x00\x00\xa8\xad\xab\xba', - b'TEST\n', - b'', - b'CLSE\x14\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba']) + self.transport.bulk_read_data = b"".join( + [ + b"OKAY\x14\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6", + b"WRTE\x14\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00J\x01\x00\x00\xa8\xad\xab\xba", + b"TEST\n", + b"", + b"CLSE\x14\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", + ] + ) self.assertEqual(await self.device.exec_out("echo 'TEST'"), "TEST\n") - # ======================================================================= # # # # `filesync` tests # @@ -696,26 +752,44 @@ async def test_exec_out(self): @awaiter async def test_list(self): self.assertTrue(await self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncListMessage(constants.DENT, 1, 2, 3, data=b'file1'), - FileSyncListMessage(constants.DENT, 4, 5, 6, data=b'file2'), - FileSyncListMessage(constants.DONE, 0, 0, 0))), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncListMessage(constants.DENT, 1, 2, 3, data=b"file1"), + FileSyncListMessage(constants.DENT, 4, 5, 6, data=b"file2"), + FileSyncListMessage(constants.DONE, 0, 0, 0), + ), + ), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.LIST, data=b'/dir'))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages(FileSyncMessage(command=constants.LIST, data=b"/dir")), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - expected_result = [DeviceFile(filename=bytearray(b'file1'), mode=1, size=2, mtime=3), - DeviceFile(filename=bytearray(b'file2'), mode=4, size=5, mtime=6)] + expected_result = [ + DeviceFile(filename=bytearray(b"file1"), mode=1, size=2, mtime=3), + DeviceFile(filename=bytearray(b"file2"), mode=4, size=5, mtime=6), + ] - self.assertEqual(await self.device.list('/dir'), expected_result) + self.assertEqual(await self.device.list("/dir"), expected_result) self.assertEqual(self.transport.bulk_write_data, expected_bulk_write) @awaiter @@ -725,56 +799,71 @@ async def test_list_empty_path(self): with self.assertRaises(exceptions.DevicePathInvalidError): await self.device.list(b"") with self.assertRaises(exceptions.DevicePathInvalidError): - await self.device.list(u"") + await self.device.list("") with self.assertRaises(exceptions.DevicePathInvalidError): await self.device.list(None) # Clear the `_bulk_read` buffer so that `self.tearDown()` passes - self.transport.bulk_read_data = b'' + self.transport.bulk_read_data = b"" @patchers.ASYNC_SKIPPER @awaiter async def test_push_fail(self): self.assertTrue(await self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" mtime = 100 - filedata = b'Ohayou sekai.\nGood morning world!' + filedata = b"Ohayou sekai.\nGood morning world!" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(constants.FAIL, data=b'')))) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage( + command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(constants.FAIL, data=b"")) + ), + ) - with self.assertRaises(exceptions.PushFailedError), patch('aiofiles.open', async_mock_open(read_data=filedata)): - await self.device.push('TEST_FILE', '/data', mtime=mtime) + with self.assertRaises(exceptions.PushFailedError), patch("aiofiles.open", async_mock_open(read_data=filedata)): + await self.device.push("TEST_FILE", "/data", mtime=mtime) @patchers.ASYNC_SKIPPER @awaiter async def test_push_file(self): self.assertTrue(await self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" mtime = 100 - filedata = b'Ohayou sekai.\nGood morning world!' + filedata = b"Ohayou sekai.\nGood morning world!" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=FileSyncMessage(constants.OKAY).pack()), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=FileSyncMessage(constants.OKAY).pack()), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.SEND, data=b'/data,33272'), - FileSyncMessage(command=constants.DATA, data=filedata), - FileSyncMessage(command=constants.DONE, arg0=mtime, data=b''))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) - - with patch('aiofiles.open', async_mock_open(read_data=filedata)): + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncMessage(command=constants.SEND, data=b"/data,33272"), + FileSyncMessage(command=constants.DATA, data=filedata), + FileSyncMessage(command=constants.DONE, arg0=mtime, data=b""), + ), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) + + with patch("aiofiles.open", async_mock_open(read_data=filedata)): self.assertEqual(self.progress_callback_count, 0) with patch("adb_shell.adb_device_async.os.fstat", return_value=patchers.StSize(12345)): - await self.device.push('TEST_FILE', '/data', mtime=mtime, progress_callback=self.progress_callback) + await self.device.push("TEST_FILE", "/data", mtime=mtime, progress_callback=self.progress_callback) self.assertEqual(self.progress_callback_count, 1) self.assertEqual(self.transport.bulk_write_data, expected_bulk_write) @@ -782,57 +871,79 @@ async def test_push_file(self): @awaiter async def test_push_bytesio(self): self.assertTrue(await self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" mtime = 100 - filedata = b'Ohayou sekai.\nGood morning world!' + filedata = b"Ohayou sekai.\nGood morning world!" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=FileSyncMessage(constants.OKAY).pack()), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=FileSyncMessage(constants.OKAY).pack()), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.SEND, data=b'/data,33272'), - FileSyncMessage(command=constants.DATA, data=filedata), - FileSyncMessage(command=constants.DONE, arg0=mtime, data=b''))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncMessage(command=constants.SEND, data=b"/data,33272"), + FileSyncMessage(command=constants.DATA, data=filedata), + FileSyncMessage(command=constants.DONE, arg0=mtime, data=b""), + ), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) stream = BytesIO(filedata) - await self.device.push(stream, '/data', mtime=mtime) + await self.device.push(stream, "/data", mtime=mtime) self.assertEqual(self.transport.bulk_write_data, expected_bulk_write) @patchers.ASYNC_SKIPPER @awaiter async def test_push_file_exception(self): self.assertTrue(await self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" mtime = 100 - filedata = b'Ohayou sekai.\nGood morning world!' + filedata = b"Ohayou sekai.\nGood morning world!" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=FileSyncMessage(constants.OKAY).pack()), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=FileSyncMessage(constants.OKAY).pack()), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.SEND, data=b'/data,33272'), - FileSyncMessage(command=constants.DATA, data=filedata), - FileSyncMessage(command=constants.DONE, arg0=mtime, data=b''))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) - - with patch('aiofiles.open', async_mock_open(read_data=filedata)): + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncMessage(command=constants.SEND, data=b"/data,33272"), + FileSyncMessage(command=constants.DATA, data=filedata), + FileSyncMessage(command=constants.DONE, arg0=mtime, data=b""), + ), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) + + with patch("aiofiles.open", async_mock_open(read_data=filedata)): # Set self.progress_callback_count to None so that an exception occurs when self.progress_callback tries to increment it self.progress_callback_count = None with patch("adb_shell.adb_device_async.os.fstat", return_value=patchers.StSize(12345)): - await self.device.push('TEST_FILE', '/data', mtime=mtime, progress_callback=self.progress_callback) + await self.device.push("TEST_FILE", "/data", mtime=mtime, progress_callback=self.progress_callback) self.assertIsNone(self.progress_callback_count) self.assertEqual(self.transport.bulk_write_data, expected_bulk_write) @@ -841,65 +952,103 @@ async def test_push_file_exception(self): @awaiter async def test_push_file_mtime0(self): self.assertTrue(await self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" mtime = 0 - filedata = b'Ohayou sekai.\nGood morning world!' + filedata = b"Ohayou sekai.\nGood morning world!" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(constants.OKAY, data=b''))), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage( + command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(constants.OKAY, data=b"")) + ), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.SEND, data=b'/data,33272'), - FileSyncMessage(command=constants.DATA, data=filedata), - FileSyncMessage(command=constants.DONE, arg0=mtime))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) - - with patch('aiofiles.open', async_mock_open(read_data=filedata)), patch('time.time', return_value=mtime): - await self.device.push('TEST_FILE', '/data', mtime=mtime) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncMessage(command=constants.SEND, data=b"/data,33272"), + FileSyncMessage(command=constants.DATA, data=filedata), + FileSyncMessage(command=constants.DONE, arg0=mtime), + ), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) + + with patch("aiofiles.open", async_mock_open(read_data=filedata)), patch("time.time", return_value=mtime): + await self.device.push("TEST_FILE", "/data", mtime=mtime) self.assertEqual(self.transport.bulk_write_data, expected_bulk_write) @patchers.ASYNC_SKIPPER @awaiter async def test_push_big_file(self): self.assertTrue(await self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" mtime = 100 - filedata = b'0' * int(3.5 * self.device.max_chunk_size) + filedata = b"0" * int(3.5 * self.device.max_chunk_size) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(constants.OKAY))), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(constants.OKAY))), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - mcs0, mcs1, mcs2, mcs3 = 0, self.device.max_chunk_size, 2*self.device.max_chunk_size, 3*self.device.max_chunk_size - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages( - FileSyncMessage(command=constants.SEND, data=b'/data,33272'), - FileSyncMessage(command=constants.DATA, data=filedata[mcs0:mcs1]))), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages( - FileSyncMessage(command=constants.DATA, data=filedata[mcs1:mcs2]))), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages( - FileSyncMessage(command=constants.DATA, data=filedata[mcs2:mcs3]), - FileSyncMessage(command=constants.DATA, data=filedata[mcs3:]), - FileSyncMessage(command=constants.DONE, arg0=mtime))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) - - with patch('aiofiles.open', async_mock_open(read_data=filedata)): + mcs0, mcs1, mcs2, mcs3 = ( + 0, + self.device.max_chunk_size, + 2 * self.device.max_chunk_size, + 3 * self.device.max_chunk_size, + ) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncMessage(command=constants.SEND, data=b"/data,33272"), + FileSyncMessage(command=constants.DATA, data=filedata[mcs0:mcs1]), + ), + ), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages(FileSyncMessage(command=constants.DATA, data=filedata[mcs1:mcs2])), + ), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncMessage(command=constants.DATA, data=filedata[mcs2:mcs3]), + FileSyncMessage(command=constants.DATA, data=filedata[mcs3:]), + FileSyncMessage(command=constants.DONE, arg0=mtime), + ), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) + + with patch("aiofiles.open", async_mock_open(read_data=filedata)): self.assertEqual(self.progress_callback_count, 0) with patch("adb_shell.adb_device_async.os.fstat", return_value=patchers.StSize(12345)): - await self.device.push('TEST_FILE', '/data', mtime=mtime, progress_callback=self.progress_callback) + await self.device.push("TEST_FILE", "/data", mtime=mtime, progress_callback=self.progress_callback) self.assertEqual(self.progress_callback_count, 4) self.assertEqual(self.transport.bulk_write_data, expected_bulk_write) @@ -909,25 +1058,29 @@ async def test_push_dir(self): self.assertTrue(await self.device.connect()) mtime = 100 - filedata = b'Ohayou sekai.\nGood morning world!' + filedata = b"Ohayou sekai.\nGood morning world!" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.OKAY, arg0=2, arg1=2, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=2, arg1=2, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=2, arg1=2, data=join_messages(FileSyncMessage(constants.OKAY))), - AdbMessage(command=constants.CLSE, arg0=2, arg1=2, data=b''), - AdbMessage(command=constants.OKAY, arg0=3, arg1=3, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=3, arg1=3, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=3, arg1=3, data=join_messages(FileSyncMessage(constants.OKAY))), - AdbMessage(command=constants.CLSE, arg0=3, arg1=3, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.OKAY, arg0=2, arg1=2, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=2, arg1=2, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=2, arg1=2, data=join_messages(FileSyncMessage(constants.OKAY))), + AdbMessage(command=constants.CLSE, arg0=2, arg1=2, data=b""), + AdbMessage(command=constants.OKAY, arg0=3, arg1=3, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=3, arg1=3, data=b"\x00"), + AdbMessage(command=constants.WRTE, arg0=3, arg1=3, data=join_messages(FileSyncMessage(constants.OKAY))), + AdbMessage(command=constants.CLSE, arg0=3, arg1=3, data=b""), + ) # Expected `bulk_write` values - #TODO + # TODO - with patch('aiofiles.open', async_mock_open(read_data=filedata)), patch('os.path.isdir', lambda x: x == 'TEST_DIR/'), patch('os.listdir', return_value=['TEST_FILE1', 'TEST_FILE2']): - await self.device.push('TEST_DIR/', '/data', mtime=mtime) + with patch("aiofiles.open", async_mock_open(read_data=filedata)), patch( + "os.path.isdir", lambda x: x == "TEST_DIR/" + ), patch("os.listdir", return_value=["TEST_FILE1", "TEST_FILE2"]): + await self.device.push("TEST_DIR/", "/data", mtime=mtime) @awaiter async def test_push_empty_path(self): @@ -936,37 +1089,52 @@ async def test_push_empty_path(self): with self.assertRaises(exceptions.DevicePathInvalidError): await self.device.push("NOTHING", b"") with self.assertRaises(exceptions.DevicePathInvalidError): - await self.device.push("NOTHING", u"") + await self.device.push("NOTHING", "") with self.assertRaises(exceptions.DevicePathInvalidError): await self.device.push("NOTHING", None) # Clear the `_bulk_read` buffer so that `self.tearDown()` passes - self.transport.bulk_read_data = b'' + self.transport.bulk_read_data = b"" @patchers.ASYNC_SKIPPER @awaiter async def test_pull_file(self): self.assertTrue(await self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" - filedata = b'Ohayou sekai.\nGood morning world!' + filedata = b"Ohayou sekai.\nGood morning world!" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.DATA, data=filedata), - FileSyncMessage(command=constants.DONE))), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncMessage(command=constants.DATA, data=filedata), FileSyncMessage(command=constants.DONE) + ), + ), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.RECV, data=b'/data'))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages(FileSyncMessage(command=constants.RECV, data=b"/data")), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - with patch('aiofiles.open', async_mock_open()) as m: + with patch("aiofiles.open", async_mock_open()) as m: self.assertEqual(self.progress_callback_count, 0) - with patch('adb_shell.adb_device_async.AdbDeviceAsync.stat', self.fake_stat): - await self.device.pull('/data', 'TEST_FILE', progress_callback=self.progress_callback) + with patch("adb_shell.adb_device_async.AdbDeviceAsync.stat", self.fake_stat): + await self.device.pull("/data", "TEST_FILE", progress_callback=self.progress_callback) self.assertEqual(self.progress_callback_count, 1) self.assertEqual(m.written, filedata) @@ -976,55 +1144,85 @@ async def test_pull_file(self): @awaiter async def test_pull_bytesio(self): self.assertTrue(await self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" - filedata = b'Ohayou sekai.\nGood morning world!' + filedata = b"Ohayou sekai.\nGood morning world!" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.DATA, data=filedata), - FileSyncMessage(command=constants.DONE))), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncMessage(command=constants.DATA, data=filedata), FileSyncMessage(command=constants.DONE) + ), + ), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.RECV, data=b'/data'))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages(FileSyncMessage(command=constants.RECV, data=b"/data")), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) stream = BytesIO() - await self.device.pull('/data', stream) + await self.device.pull("/data", stream) self.assertEqual(self.transport.bulk_write_data, expected_bulk_write) - self.assertEqual(stream.getvalue(), filedata) + self.assertEqual(stream.getvalue(), filedata) @patchers.ASYNC_SKIPPER @awaiter async def test_pull_file_exception(self): self.assertTrue(await self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" - filedata = b'Ohayou sekai.\nGood morning world!' + filedata = b"Ohayou sekai.\nGood morning world!" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.DATA, data=filedata), - FileSyncMessage(command=constants.DONE))), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncMessage(command=constants.DATA, data=filedata), FileSyncMessage(command=constants.DONE) + ), + ), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.RECV, data=b'/data'))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages(FileSyncMessage(command=constants.RECV, data=b"/data")), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - with patch('aiofiles.open', async_mock_open()) as m: + with patch("aiofiles.open", async_mock_open()) as m: # Set self.progress_callback_count to None so that an exception occurs when self.progress_callback tries to increment it self.progress_callback_count = None - with patch('adb_shell.adb_device_async.AdbDeviceAsync.stat', self.fake_stat): - await self.device.pull('/data', 'TEST_FILE', progress_callback=self.progress_callback) + with patch("adb_shell.adb_device_async.AdbDeviceAsync.stat", self.fake_stat): + await self.device.pull("/data", "TEST_FILE", progress_callback=self.progress_callback) self.assertIsNone(self.progress_callback_count) self.assertEqual(m.written, filedata) @@ -1034,27 +1232,42 @@ async def test_pull_file_exception(self): @awaiter async def test_pull_big_file(self): self.assertTrue(await self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" - filedata = b'0' * int(1.5 * constants.MAX_ADB_DATA) + filedata = b"0" * int(1.5 * constants.MAX_ADB_DATA) # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.DATA, data=filedata), - FileSyncMessage(command=constants.DONE))), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncMessage(command=constants.DATA, data=filedata), FileSyncMessage(command=constants.DONE) + ), + ), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.RECV, data=b'/data'))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages(FileSyncMessage(command=constants.RECV, data=b"/data")), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - with patch('aiofiles.open', async_mock_open()) as m: + with patch("aiofiles.open", async_mock_open()) as m: self.assertEqual(self.progress_callback_count, 0) - with patch('adb_shell.adb_device_async.AdbDeviceAsync.stat', self.fake_stat): - await self.device.pull('/data', 'TEST_FILE', progress_callback=self.progress_callback) + with patch("adb_shell.adb_device_async.AdbDeviceAsync.stat", self.fake_stat): + await self.device.pull("/data", "TEST_FILE", progress_callback=self.progress_callback) self.assertEqual(self.progress_callback_count, 1) self.assertEqual(m.written, filedata) @@ -1067,30 +1280,39 @@ async def test_pull_empty_path(self): with self.assertRaises(exceptions.DevicePathInvalidError): await self.device.pull(b"", "NOWHERE") with self.assertRaises(exceptions.DevicePathInvalidError): - await self.device.pull(u"", "NOWHERE") + await self.device.pull("", "NOWHERE") with self.assertRaises(exceptions.DevicePathInvalidError): await self.device.pull(None, "NOWHERE") # Clear the `_bulk_read` buffer so that `self.tearDown()` passes - self.transport.bulk_read_data = b'' + self.transport.bulk_read_data = b"" @awaiter async def test_pull_non_existant_path(self): self.assertTrue(await self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'FAIL&\x00\x00\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'open failed: No such file or directory'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"FAIL&\x00\x00\x00"), + AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b"open failed: No such file or directory"), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.RECV, data=b'/does/not/exist'))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages(FileSyncMessage(command=constants.RECV, data=b"/does/not/exist")), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) with self.assertRaises(exceptions.AdbCommandFailureException): await self.device.pull("/does/not/exist", "NOWHERE") self.assertEqual(expected_bulk_write, self.transport.bulk_write_data) @@ -1098,19 +1320,30 @@ async def test_pull_non_existant_path(self): @awaiter async def test_pull_non_existant_path_2(self): self.assertTrue(await self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=b'FAIL&\x00\x00\x00open failed: No such file or directory'), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage( + command=constants.WRTE, arg0=1, arg1=1, data=b"FAIL&\x00\x00\x00open failed: No such file or directory" + ), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.RECV, data=b'/does/not/exist'))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages(FileSyncMessage(command=constants.RECV, data=b"/does/not/exist")), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) with self.assertRaises(exceptions.AdbCommandFailureException): await self.device.pull("/does/not/exist", "NOWHERE") self.assertEqual(expected_bulk_write, self.transport.bulk_write_data) @@ -1118,22 +1351,37 @@ async def test_pull_non_existant_path_2(self): @awaiter async def test_stat(self): self.assertTrue(await self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncStatMessage(constants.STAT, 1, 2, 3), - FileSyncStatMessage(constants.DONE, 0, 0, 0))), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncStatMessage(constants.STAT, 1, 2, 3), FileSyncStatMessage(constants.DONE, 0, 0, 0) + ), + ), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) # Expected `bulk_write` values - expected_bulk_write = join_messages(AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b'sync:\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncMessage(command=constants.STAT, data=b'/data'))), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b''), - AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b'')) + expected_bulk_write = join_messages( + AdbMessage(command=constants.OPEN, arg0=1, arg1=0, data=b"sync:\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages(FileSyncMessage(command=constants.STAT, data=b"/data")), + ), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b""), + AdbMessage(command=constants.CLSE, arg0=1, arg1=1, data=b""), + ) - self.assertEqual(await self.device.stat('/data'), (1, 2, 3)) + self.assertEqual(await self.device.stat("/data"), (1, 2, 3)) self.assertEqual(self.transport.bulk_write_data, expected_bulk_write) @awaiter @@ -1143,31 +1391,38 @@ async def test_stat_empty_path(self): with self.assertRaises(exceptions.DevicePathInvalidError): await self.device.stat(b"") with self.assertRaises(exceptions.DevicePathInvalidError): - await self.device.stat(u"") + await self.device.stat("") with self.assertRaises(exceptions.DevicePathInvalidError): await self.device.stat(None) # Clear the `_bulk_read` buffer so that `self.tearDown()` passes - self.transport.bulk_read_data = b'' + self.transport.bulk_read_data = b"" @awaiter async def test_stat_issue155(self): self.assertTrue(await self.device.connect()) # Provide the `bulk_read` return values - self.transport.bulk_read_data = b"".join([b'CLSE\n\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba', - b'OKAY\x0b\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6', - b'OKAY\x0b\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6', - b'WRTE\x0b\x00\x00\x00\x01\x00\x00\x00\x10\x00\x00\x00\x96\x04\x00\x00\xa8\xad\xab\xba', - b'STAT\xedA\x00\x00\x00\x10\x00\x00\xf0\x88[I', - b'CLSE\x0b\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba']) + self.transport.bulk_read_data = b"".join( + [ + b"CLSE\n\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", + b"OKAY\x0b\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6", + b"OKAY\x0b\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6", + b"WRTE\x0b\x00\x00\x00\x01\x00\x00\x00\x10\x00\x00\x00\x96\x04\x00\x00\xa8\xad\xab\xba", + b"STAT\xedA\x00\x00\x00\x10\x00\x00\xf0\x88[I", + b"CLSE\x0b\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba", + ] + ) # This is where the expected values come from mode = 16877 size = 4096 mtime = 1230735600 - self.assertEqual(FileSyncStatMessage(constants.STAT, mode, size, mtime).pack(), b'STAT\xedA\x00\x00\x00\x10\x00\x00\xf0\x88[I') + self.assertEqual( + FileSyncStatMessage(constants.STAT, mode, size, mtime).pack(), + b"STAT\xedA\x00\x00\x00\x10\x00\x00\xf0\x88[I", + ) - self.assertEqual((mode, size, mtime), await self.device.stat('/')) + self.assertEqual((mode, size, mtime), await self.device.stat("/")) # ======================================================================= # # # @@ -1177,27 +1432,43 @@ async def test_stat_issue155(self): @awaiter async def test_filesync_read_adb_command_failure_exceptions(self): self.assertTrue(await self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncStatMessage(constants.FAIL, 1, 2, 3), - FileSyncStatMessage(constants.DONE, 0, 0, 0)))) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncStatMessage(constants.FAIL, 1, 2, 3), FileSyncStatMessage(constants.DONE, 0, 0, 0) + ), + ), + ) with self.assertRaises(exceptions.AdbCommandFailureException): - await self.device.stat('/data') + await self.device.stat("/data") @awaiter async def test_filesync_read_invalid_response_error(self): self.assertTrue(await self.device.connect()) - self.transport.bulk_write_data = b'' + self.transport.bulk_write_data = b"" # Provide the `bulk_read` return values - self.transport.bulk_read_data = join_messages(AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b'\x00'), - AdbMessage(command=constants.WRTE, arg0=1, arg1=1, data=join_messages(FileSyncStatMessage(constants.DENT, 1, 2, 3), - FileSyncStatMessage(constants.DONE, 0, 0, 0)))) + self.transport.bulk_read_data = join_messages( + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage(command=constants.OKAY, arg0=1, arg1=1, data=b"\x00"), + AdbMessage( + command=constants.WRTE, + arg0=1, + arg1=1, + data=join_messages( + FileSyncStatMessage(constants.DENT, 1, 2, 3), FileSyncStatMessage(constants.DONE, 0, 0, 0) + ), + ), + ) with self.assertRaises(exceptions.InvalidResponseError): - await self.device.stat('/data') + await self.device.stat("/data") diff --git a/tests/test_adb_message.py b/tests/test_adb_message.py index 9e7d6670..b7b708ad 100644 --- a/tests/test_adb_message.py +++ b/tests/test_adb_message.py @@ -13,20 +13,20 @@ class TestAdbMessage(unittest.TestCase): def test_checksum_bytearray(self): - cs = checksum(bytearray('TEST', 'utf-8')) + cs = checksum(bytearray("TEST", "utf-8")) self.assertEqual(cs, 320) def test_checksum_bytes(self): - cs = checksum(b'TEST') + cs = checksum(b"TEST") self.assertEqual(cs, 320) def test_checksum_unicode(self): - cs = checksum(u'TEST') + cs = checksum("TEST") self.assertEqual(cs, 320) def test_unpack_error(self): with self.assertRaises(ValueError): - unpack(b'TEST') + unpack(b"TEST") def test_constants(self): for key, val in constants.ID_TO_WIRE.items(): diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py index d8e41e22..35898d19 100644 --- a/tests/test_exceptions.py +++ b/tests/test_exceptions.py @@ -3,6 +3,7 @@ import pickle import re import unittest + try: from unittest import mock except ImportError: @@ -31,7 +32,7 @@ def __test_serialize_one_exc_cls(exc_cls): # wasn't overridden by the exception subclass - use 0 arity. exc_required_arity = 0 # Don't try to provide `self` - we assume strings will be fine here - fake_args = ("foo", ) * (exc_required_arity - 1) + fake_args = ("foo",) * (exc_required_arity - 1) # Instantiate the exception object and then attempt a serializion cycle # using `pickle` - we mainly care about whether this blows up or not exc_obj = exc_cls(*fake_args) @@ -40,9 +41,7 @@ def __test_serialize_one_exc_cls(exc_cls): for __obj in adb_shell.exceptions.__dict__.values(): if isinstance(__obj, type) and issubclass(__obj, BaseException): - __test_method = functools.partial( - __test_serialize_one_exc_cls, __obj - ) + __test_method = functools.partial(__test_serialize_one_exc_cls, __obj) __test_name = "test_serialize_{}".format(__obj.__name__) locals()[__test_name] = __test_method @@ -58,7 +57,5 @@ def test_usbreadfailederror_as_str(self): def test_usbreadfailederror_as_repr(self): exc_args = (mock.sentinel.error_msg, mock.sentinel.usb1_exc_obj) exc_obj = adb_shell.exceptions.UsbReadFailedError(*exc_args) - expected_repr = "{}{!r}".format( - adb_shell.exceptions.UsbReadFailedError.__name__, exc_args - ) + expected_repr = "{}{!r}".format(adb_shell.exceptions.UsbReadFailedError.__name__, exc_args) _assertRegex(self, repr(exc_obj), re.escape(expected_repr)) diff --git a/tests/test_hidden_helpers.py b/tests/test_hidden_helpers.py index 53fe6a01..1d582303 100644 --- a/tests/test_hidden_helpers.py +++ b/tests/test_hidden_helpers.py @@ -44,7 +44,7 @@ def test_put(self): self.packet_store.put(arg0=5, arg1=5, cmd=constants.CLSE, data=b"data5") self.assertEqual(len(self.packet_store), 3) self.assertFalse((5, 5) in self.packet_store) - + self.packet_store.put(arg0=5, arg1=1, cmd=constants.CLSE, data=b"data5") self.assertEqual(len(self.packet_store), 3) self.assertFalse((5, 1) in self.packet_store) @@ -112,7 +112,7 @@ def test_get(self): self.assertEqual(len(self.packet_store._dict[0]), 1) self.assertEqual(len(self.packet_store._dict[3]), 1) self.assertEqual(len(self.packet_store._dict[5]), 1) - + def test_get_clse(self): self.packet_store.put(arg0=0, arg1=1, cmd=b"cmd1", data=b"data1") self.packet_store.put(arg0=0, arg1=1, cmd=constants.CLSE, data=b"data2") @@ -170,7 +170,6 @@ def test_find_allow_zeros(self): class TestAdbTransactionInfo(unittest.TestCase): - def test_args_match(self): adb_info_1_None = _AdbTransactionInfo(1, None, 123, 456, 789) adb_info_1_2 = _AdbTransactionInfo(1, 2, 123, 456, 789) diff --git a/tests/test_keygen.py b/tests/test_keygen.py index d5f190c5..9cc9f4c1 100644 --- a/tests/test_keygen.py +++ b/tests/test_keygen.py @@ -10,10 +10,14 @@ class TestKeygen(unittest.TestCase): def test_get_user_info(self): - with patch('adb_shell.auth.keygen.os.getlogin', side_effect=OSError), patch('adb_shell.auth.keygen.socket.gethostname', return_value=''): + with patch("adb_shell.auth.keygen.os.getlogin", side_effect=OSError), patch( + "adb_shell.auth.keygen.socket.gethostname", return_value="" + ): user_host = get_user_info() - self.assertEqual(user_host, ' unknown@unknown') + self.assertEqual(user_host, " unknown@unknown") - with patch('adb_shell.auth.keygen.os.getlogin', return_value=''), patch('adb_shell.auth.keygen.socket.gethostname', return_value=''): + with patch("adb_shell.auth.keygen.os.getlogin", return_value=""), patch( + "adb_shell.auth.keygen.socket.gethostname", return_value="" + ): user_host = get_user_info() - self.assertEqual(user_host, ' unknown@unknown') + self.assertEqual(user_host, " unknown@unknown") diff --git a/tests/test_sign_cryptography.py b/tests/test_sign_cryptography.py index 080fbfdf..01efe843 100644 --- a/tests/test_sign_cryptography.py +++ b/tests/test_sign_cryptography.py @@ -17,15 +17,17 @@ class TestCryptographySigner(unittest.TestCase): def setUp(self): - with patch('adb_shell.auth.sign_cryptography.open', open_priv_pub), patch('adb_shell.auth.keygen.open', open_priv_pub): - keygen('tests/adbkey') - self.signer = CryptographySigner('tests/adbkey') + with patch("adb_shell.auth.sign_cryptography.open", open_priv_pub), patch( + "adb_shell.auth.keygen.open", open_priv_pub + ): + keygen("tests/adbkey") + self.signer = CryptographySigner("tests/adbkey") def test_sign(self): """Test that the ``Sign`` method does not raise an exception.""" # https://www.programcreek.com/python/example/107988/cryptography.hazmat.primitives.hashes.Hash hash_ctx = hashes.Hash(hashes.SHA1(), default_backend()) - hash_ctx.update(b'notadb') + hash_ctx.update(b"notadb") data = hash_ctx.finalize() # For reference: # data = b'(\x8b\x9e\x88|JY\xb5\x18\x13b_\xe0\xc4\xfb\xa5\x83\xbdx\xfc' @@ -35,8 +37,8 @@ def test_sign(self): def test_get_public_key(self): """Test that the ``GetPublicKey`` method works correctly.""" - with patch('{}.open'.format(__name__), open_priv_pub): - with open('tests/adbkey.pub', 'rb') as f: + with patch("{}.open".format(__name__), open_priv_pub): + with open("tests/adbkey.pub", "rb") as f: pub = f.read() self.assertEqual(pub, self.signer.GetPublicKey()) diff --git a/tests/test_sign_pycryptodome.py b/tests/test_sign_pycryptodome.py index 84e29575..ecfd349a 100644 --- a/tests/test_sign_pycryptodome.py +++ b/tests/test_sign_pycryptodome.py @@ -14,19 +14,21 @@ class TestPycryptodomeAuthSigner(unittest.TestCase): def setUp(self): - with patch('adb_shell.auth.sign_pycryptodome.open', open_priv_pub), patch('adb_shell.auth.keygen.open', open_priv_pub): - keygen('tests/adbkey') - self.signer = PycryptodomeAuthSigner('tests/adbkey') + with patch("adb_shell.auth.sign_pycryptodome.open", open_priv_pub), patch( + "adb_shell.auth.keygen.open", open_priv_pub + ): + keygen("tests/adbkey") + self.signer = PycryptodomeAuthSigner("tests/adbkey") def test_sign(self): """Test that the ``Sign`` method does not raise an exception.""" - self.signer.Sign(b'notadb') + self.signer.Sign(b"notadb") self.assertTrue(True) def test_get_public_key(self): """Test that the ``GetPublicKey`` method works correctly.""" - with patch('{}.open'.format(__name__), open_priv_pub): - with open('tests/adbkey.pub', 'rb') as f: + with patch("{}.open".format(__name__), open_priv_pub): + with open("tests/adbkey.pub", "rb") as f: pub = f.read() self.assertEqual(pub, self.signer.GetPublicKey()) diff --git a/tests/test_sign_pythonrsa.py b/tests/test_sign_pythonrsa.py index 058f8e99..2e3fd2b2 100644 --- a/tests/test_sign_pythonrsa.py +++ b/tests/test_sign_pythonrsa.py @@ -14,19 +14,21 @@ class TestPythonRSASigner(unittest.TestCase): def setUp(self): - with patch('adb_shell.auth.sign_pythonrsa.open', open_priv_pub), patch('adb_shell.auth.keygen.open', open_priv_pub): - keygen('tests/adbkey') - self.signer = PythonRSASigner.FromRSAKeyPath('tests/adbkey') + with patch("adb_shell.auth.sign_pythonrsa.open", open_priv_pub), patch( + "adb_shell.auth.keygen.open", open_priv_pub + ): + keygen("tests/adbkey") + self.signer = PythonRSASigner.FromRSAKeyPath("tests/adbkey") def test_sign(self): """Test that the ``Sign`` method does not raise an exception.""" - self.signer.Sign(b'notadb') + self.signer.Sign(b"notadb") self.assertTrue(True) def test_get_public_key(self): """Test that the ``GetPublicKey`` method works correctly.""" - with patch('{}.open'.format(__name__), open_priv_pub): - with open('tests/adbkey.pub') as f: + with patch("{}.open".format(__name__), open_priv_pub): + with open("tests/adbkey.pub") as f: pub = f.read() self.assertEqual(pub, self.signer.GetPublicKey()) @@ -34,16 +36,19 @@ def test_get_public_key(self): class TestPythonRSASignerExceptions(unittest.TestCase): def test_value_error(self): - with patch('adb_shell.auth.sign_pythonrsa.open', open_priv_pub), patch('adb_shell.auth.keygen.open', open_priv_pub): - with patch('adb_shell.auth.sign_pythonrsa.decoder.decode', return_value=([None, [None]], None)): + with patch("adb_shell.auth.sign_pythonrsa.open", open_priv_pub), patch( + "adb_shell.auth.keygen.open", open_priv_pub + ): + with patch("adb_shell.auth.sign_pythonrsa.decoder.decode", return_value=([None, [None]], None)): with self.assertRaises(ValueError): - keygen('tests/adbkey') - self.signer = PythonRSASigner.FromRSAKeyPath('tests/adbkey') + keygen("tests/adbkey") + self.signer = PythonRSASigner.FromRSAKeyPath("tests/adbkey") def test_index_error(self): - with patch('adb_shell.auth.sign_pythonrsa.open', open_priv_pub), patch('adb_shell.auth.keygen.open', open_priv_pub): - with patch('adb_shell.auth.sign_pythonrsa.decoder.decode', side_effect=IndexError): + with patch("adb_shell.auth.sign_pythonrsa.open", open_priv_pub), patch( + "adb_shell.auth.keygen.open", open_priv_pub + ): + with patch("adb_shell.auth.sign_pythonrsa.decoder.decode", side_effect=IndexError): with self.assertRaises(ValueError): - keygen('tests/adbkey') - self.signer = PythonRSASigner.FromRSAKeyPath('tests/adbkey') - + keygen("tests/adbkey") + self.signer = PythonRSASigner.FromRSAKeyPath("tests/adbkey") diff --git a/tests/test_tcp_transport.py b/tests/test_tcp_transport.py index b0b3ea61..57d93da7 100644 --- a/tests/test_tcp_transport.py +++ b/tests/test_tcp_transport.py @@ -13,10 +13,8 @@ class TestTcpTransport(unittest.TestCase): def setUp(self): - """Create a ``TcpTransport`` and connect to a TCP service. - - """ - self.transport = TcpTransport('host', 5555) + """Create a ``TcpTransport`` and connect to a TCP service.""" + self.transport = TcpTransport("host", 5555) with patchers.PATCH_CREATE_CONNECTION: self.transport.connect(transport_timeout_s=1) @@ -25,43 +23,35 @@ def tearDown(self): self.transport.close() def test_connect_with_timeout(self): - """TODO - - """ + """TODO""" self.transport.close() with patchers.PATCH_CREATE_CONNECTION: self.transport.connect(transport_timeout_s=1) self.assertTrue(True) def test_bulk_read(self): - """TODO - - """ + """TODO""" # Provide the `recv` return values - self.transport._connection._recv = b'TEST1TEST2' + self.transport._connection._recv = b"TEST1TEST2" with patchers.PATCH_SELECT_SUCCESS: - self.assertEqual(self.transport.bulk_read(5, transport_timeout_s=1), b'TEST1') - self.assertEqual(self.transport.bulk_read(5, transport_timeout_s=1), b'TEST2') + self.assertEqual(self.transport.bulk_read(5, transport_timeout_s=1), b"TEST1") + self.assertEqual(self.transport.bulk_read(5, transport_timeout_s=1), b"TEST2") with patchers.PATCH_SELECT_FAIL: with self.assertRaises(TcpTimeoutException): self.transport.bulk_read(4, transport_timeout_s=1) def test_close_oserror(self): - """Test that an `OSError` exception is handled when closing the socket. - - """ - with patch('{}.patchers.FakeSocket.shutdown'.format(__name__), side_effect=OSError): + """Test that an `OSError` exception is handled when closing the socket.""" + with patch("{}.patchers.FakeSocket.shutdown".format(__name__), side_effect=OSError): self.transport.close() def test_bulk_write(self): - """TODO - - """ + """TODO""" with patchers.PATCH_SELECT_SUCCESS: - self.transport.bulk_write(b'TEST', transport_timeout_s=1) + self.transport.bulk_write(b"TEST", transport_timeout_s=1) with patchers.PATCH_SELECT_FAIL: with self.assertRaises(TcpTimeoutException): - self.transport.bulk_write(b'FAIL', transport_timeout_s=1) + self.transport.bulk_write(b"FAIL", transport_timeout_s=1) diff --git a/tests/test_tcp_transport_async.py b/tests/test_tcp_transport_async.py index 98ce8dd2..ac6ae916 100644 --- a/tests/test_tcp_transport_async.py +++ b/tests/test_tcp_transport_async.py @@ -13,10 +13,8 @@ @patchers.ASYNC_SKIPPER class TestTcpTransportAsync(unittest.TestCase): def setUp(self): - """Create a ``TcpTransportAsync`` and connect to a TCP service. - - """ - self.transport = TcpTransportAsync('host', 5555) + """Create a ``TcpTransportAsync`` and connect to a TCP service.""" + self.transport = TcpTransportAsync("host", 5555) @awaiter async def test_close(self): @@ -28,12 +26,12 @@ async def test_close2(self): @awaiter async def test_connect(self): - with async_patch('asyncio.open_connection', return_value=(True, True)): + with async_patch("asyncio.open_connection", return_value=(True, True)): await self.transport.connect(transport_timeout_s=1) @awaiter async def test_connect_close(self): - with async_patch('asyncio.open_connection', return_value=(FakeStreamReader(), FakeStreamWriter())): + with async_patch("asyncio.open_connection", return_value=(FakeStreamReader(), FakeStreamWriter())): await self.transport.connect(transport_timeout_s=1) self.assertIsNotNone(self.transport._writer) @@ -43,11 +41,11 @@ async def test_connect_close(self): @awaiter async def test_connect_close_catch_oserror(self): - with async_patch('asyncio.open_connection', return_value=(FakeStreamReader(), FakeStreamWriter())): + with async_patch("asyncio.open_connection", return_value=(FakeStreamReader(), FakeStreamWriter())): await self.transport.connect(transport_timeout_s=1) self.assertIsNotNone(self.transport._writer) - with patch('{}.FakeStreamWriter.close'.format(__name__), side_effect=OSError): + with patch("{}.FakeStreamWriter.close".format(__name__), side_effect=OSError): await self.transport.close() self.assertIsNone(self.transport._reader) self.assertIsNone(self.transport._writer) @@ -55,27 +53,27 @@ async def test_connect_close_catch_oserror(self): @awaiter async def test_connect_with_timeout(self): with self.assertRaises(TcpTimeoutException): - with async_patch('asyncio.open_connection', side_effect=asyncio.TimeoutError): + with async_patch("asyncio.open_connection", side_effect=asyncio.TimeoutError): await self.transport.connect(transport_timeout_s=1) @awaiter async def test_bulk_read(self): - with async_patch('asyncio.open_connection', return_value=(FakeStreamReader(), FakeStreamWriter())): + with async_patch("asyncio.open_connection", return_value=(FakeStreamReader(), FakeStreamWriter())): await self.transport.connect(transport_timeout_s=1) - self.assertEqual(await self.transport.bulk_read(4, transport_timeout_s=1), b'TEST') + self.assertEqual(await self.transport.bulk_read(4, transport_timeout_s=1), b"TEST") with self.assertRaises(TcpTimeoutException): - with patch('{}.FakeStreamReader.read'.format(__name__), side_effect=asyncio.TimeoutError): + with patch("{}.FakeStreamReader.read".format(__name__), side_effect=asyncio.TimeoutError): await self.transport.bulk_read(4, transport_timeout_s=1) @awaiter async def test_bulk_write(self): - with async_patch('asyncio.open_connection', return_value=(FakeStreamReader(), FakeStreamWriter())): + with async_patch("asyncio.open_connection", return_value=(FakeStreamReader(), FakeStreamWriter())): await self.transport.connect(transport_timeout_s=1) - self.assertEqual(await self.transport.bulk_write(b'TEST', transport_timeout_s=1), 4) + self.assertEqual(await self.transport.bulk_write(b"TEST", transport_timeout_s=1), 4) with self.assertRaises(TcpTimeoutException): - with patch('{}.FakeStreamWriter.write'.format(__name__), side_effect=asyncio.TimeoutError): - await self.transport.bulk_write(b'TEST', transport_timeout_s=1) + with patch("{}.FakeStreamWriter.write".format(__name__), side_effect=asyncio.TimeoutError): + await self.transport.bulk_write(b"TEST", transport_timeout_s=1) diff --git a/tests/test_usb_importerror.py b/tests/test_usb_importerror.py index 122b78a8..4fdadf88 100644 --- a/tests/test_usb_importerror.py +++ b/tests/test_usb_importerror.py @@ -23,7 +23,7 @@ def test_import_error(self): # In lieu of a real `ImportError`, I'll just set this to None with patch("adb_shell.adb_device.UsbTransport", None): with self.assertRaises(InvalidTransportError): - adb_device.AdbDeviceUsb('serial') + adb_device.AdbDeviceUsb("serial") def test_import_successful(self): from adb_shell import adb_device diff --git a/tests/test_usb_transport.py b/tests/test_usb_transport.py index 40d942a7..c1c9a64f 100644 --- a/tests/test_usb_transport.py +++ b/tests/test_usb_transport.py @@ -16,10 +16,8 @@ @unittest.skipIf(UsbTransport is None, "UsbTransport could not be imported") class TestUsbTransport(unittest.TestCase): def setUp(self): - """Create a ``UsbTransport`` and do something... - - """ - self.transport = UsbTransport('TODO', 'TODO') + """Create a ``UsbTransport`` and do something...""" + self.transport = UsbTransport("TODO", "TODO") if True: return @@ -32,9 +30,7 @@ def tearDown(self): self.transport.close() def test_connect_with_timeout(self): - """TODO - - """ + """TODO""" if True: return @@ -44,33 +40,29 @@ def test_connect_with_timeout(self): self.assertTrue(True) def test_bulk_read(self): - """TODO - - """ + """TODO""" if True: return # Provide the `recv` return values - self.transport._connection._recv = b'TEST1TEST2' + self.transport._connection._recv = b"TEST1TEST2" with patchers.PATCH_SELECT_SUCCESS: - self.assertEqual(self.transport.bulk_read(5), b'TEST1') - self.assertEqual(self.transport.bulk_read(5), b'TEST2') + self.assertEqual(self.transport.bulk_read(5), b"TEST1") + self.assertEqual(self.transport.bulk_read(5), b"TEST2") with patchers.PATCH_SELECT_FAIL: with self.assertRaises(TcpTimeoutException): self.transport.bulk_read(4) def test_bulk_write(self): - """TODO - - """ + """TODO""" if True: return with patchers.PATCH_SELECT_SUCCESS: - self.transport.bulk_write(b'TEST') + self.transport.bulk_write(b"TEST") with patchers.PATCH_SELECT_FAIL: with self.assertRaises(TcpTimeoutException): - self.transport.bulk_write(b'FAIL') + self.transport.bulk_write(b"FAIL") From af06aad3f7eda1a94377a4f47fc6ccb593eb8c08 Mon Sep 17 00:00:00 2001 From: Jeff Irion Date: Tue, 17 Oct 2023 20:52:15 -0700 Subject: [PATCH 2/2] Linting --- adb_shell/adb_device.py | 2 +- adb_shell/adb_device_async.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/adb_shell/adb_device.py b/adb_shell/adb_device.py index 8a23dd9b..c2950287 100644 --- a/adb_shell/adb_device.py +++ b/adb_shell/adb_device.py @@ -1590,7 +1590,7 @@ def _filesync_send(self, command_id, adb_info, filesync_info, data=b"", size=Non self._filesync_flush(adb_info, filesync_info) buf = struct.pack(b"<2I", constants.FILESYNC_ID_TO_WIRE[command_id], size) + data - filesync_info.send_buffer[filesync_info.send_idx : filesync_info.send_idx + len(buf)] = buf + filesync_info.send_buffer[filesync_info.send_idx : filesync_info.send_idx + len(buf)] = buf # noqa filesync_info.send_idx += len(buf) diff --git a/adb_shell/adb_device_async.py b/adb_shell/adb_device_async.py index 9f55e609..c44987b7 100644 --- a/adb_shell/adb_device_async.py +++ b/adb_shell/adb_device_async.py @@ -1650,7 +1650,7 @@ async def _filesync_send(self, command_id, adb_info, filesync_info, data=b"", si await self._filesync_flush(adb_info, filesync_info) buf = struct.pack(b"<2I", constants.FILESYNC_ID_TO_WIRE[command_id], size) + data - filesync_info.send_buffer[filesync_info.send_idx : filesync_info.send_idx + len(buf)] = buf + filesync_info.send_buffer[filesync_info.send_idx : filesync_info.send_idx + len(buf)] = buf # noqa filesync_info.send_idx += len(buf)