forked from mirrors/gecko-dev
Bug 1484238 - Add an 'adb_reverse' command to mozdevice.ADBAndroid r=gbrown,bc
Differential Revision: https://phabricator.services.mozilla.com/D4775 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
8d537bb798
commit
1a098a6537
2 changed files with 94 additions and 25 deletions
|
|
@ -529,6 +529,9 @@ class ADBDevice(ADBCommand):
|
||||||
"""
|
"""
|
||||||
__metaclass__ = ABCMeta
|
__metaclass__ = ABCMeta
|
||||||
|
|
||||||
|
SOCKET_DIRECTON_REVERSE = "reverse"
|
||||||
|
SOCKET_DIRECTON_FORWARD = "forward"
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
device=None,
|
device=None,
|
||||||
adb='adb',
|
adb='adb',
|
||||||
|
|
@ -962,7 +965,7 @@ class ADBDevice(ADBCommand):
|
||||||
device_serial=self._device_serial,
|
device_serial=self._device_serial,
|
||||||
timeout=timeout)
|
timeout=timeout)
|
||||||
|
|
||||||
# Port forwarding methods
|
# Networking methods
|
||||||
|
|
||||||
def _validate_port(self, port, is_local=True):
|
def _validate_port(self, port, is_local=True):
|
||||||
"""Validate a port forwarding specifier. Raises ValueError on failure.
|
"""Validate a port forwarding specifier. Raises ValueError on failure.
|
||||||
|
|
@ -977,22 +980,24 @@ class ADBDevice(ADBCommand):
|
||||||
|
|
||||||
parts = port.split(":", 1)
|
parts = port.split(":", 1)
|
||||||
if len(parts) != 2 or parts[0] not in prefixes:
|
if len(parts) != 2 or parts[0] not in prefixes:
|
||||||
raise ValueError("Invalid forward specifier %s" % port)
|
raise ValueError("Invalid port specifier %s" % port)
|
||||||
|
|
||||||
def forward(self, local, remote, allow_rebind=True, timeout=None):
|
def _validate_direction(self, direction):
|
||||||
"""Forward a local port to a specific port on the device.
|
"""Validate direction of the socket connection. Raises ValueError on failure.
|
||||||
|
|
||||||
Ports are specified in the form:
|
:param str direction: The socket direction specifier to validate
|
||||||
tcp:<port>
|
:raises: * ValueError
|
||||||
localabstract:<unix domain socket name>
|
"""
|
||||||
localreserved:<unix domain socket name>
|
if direction not in [self.SOCKET_DIRECTON_FORWARD, self.SOCKET_DIRECTON_REVERSE]:
|
||||||
localfilesystem:<unix domain socket name>
|
raise ValueError('Invalid direction specifier {}'.format(direction))
|
||||||
dev:<character device name>
|
|
||||||
jdwp:<process pid> (remote only)
|
|
||||||
|
|
||||||
:param str local: Local port to forward
|
def create_socket_connection(self, direction, local, remote, allow_rebind=True, timeout=None):
|
||||||
:param str remote: Remote port to which to forward
|
"""Sets up a socket connection in the specified direction.
|
||||||
:param bool allow_rebind: Don't error if the local port is already forwarded
|
|
||||||
|
:param str direction: Direction of the socket connection
|
||||||
|
:param str local: Local port
|
||||||
|
:param str remote: Remote port
|
||||||
|
:param bool allow_rebind: Do not fail if port is already bound
|
||||||
:param timeout: The maximum time in seconds
|
:param timeout: The maximum time in seconds
|
||||||
for any spawned adb process to complete before throwing
|
for any spawned adb process to complete before throwing
|
||||||
an ADBTimeoutError. If it is not specified, the value
|
an ADBTimeoutError. If it is not specified, the value
|
||||||
|
|
@ -1002,34 +1007,46 @@ class ADBDevice(ADBCommand):
|
||||||
* ADBTimeoutError
|
* ADBTimeoutError
|
||||||
* ADBError
|
* ADBError
|
||||||
"""
|
"""
|
||||||
|
# validate socket direction, and local and remote port formatting.
|
||||||
|
self._validate_direction(direction)
|
||||||
for port, is_local in [(local, True), (remote, False)]:
|
for port, is_local in [(local, True), (remote, False)]:
|
||||||
self._validate_port(port, is_local=is_local)
|
self._validate_port(port, is_local=is_local)
|
||||||
|
|
||||||
cmd = ["forward", local, remote]
|
cmd = [direction, local, remote]
|
||||||
|
|
||||||
if not allow_rebind:
|
if not allow_rebind:
|
||||||
cmd.insert(1, "--no-rebind")
|
cmd.insert(1, "--no-rebind")
|
||||||
|
|
||||||
|
# execute commands to establish socket connection.
|
||||||
self.command_output(cmd, timeout=timeout)
|
self.command_output(cmd, timeout=timeout)
|
||||||
|
|
||||||
def list_forwards(self, timeout=None):
|
def list_socket_connections(self, direction, timeout=None):
|
||||||
"""Return a list of tuples specifying active forwards
|
"""Return a list of tuples specifying active socket connectionss.
|
||||||
|
|
||||||
Return values are of the form (device, local, remote).
|
Return values are of the form (device, local, remote).
|
||||||
|
|
||||||
|
:param str direction: 'forward' to list forward socket connections
|
||||||
|
'reverse' to list reverse socket connections
|
||||||
:param timeout: The maximum time in seconds
|
:param timeout: The maximum time in seconds
|
||||||
for any spawned adb process to complete before throwing
|
for any spawned adb process to complete before throwing
|
||||||
an ADBTimeoutError. If it is not specified, the value
|
an ADBTimeoutError. If it is not specified, the value
|
||||||
set in the ADBDevice constructor is used.
|
set in the ADBDevice constructor is used.
|
||||||
:type timeout: integer or None
|
:type timeout: integer or None
|
||||||
:raises: * ADBTimeoutError
|
:raises: * ValueError
|
||||||
|
* ADBTimeoutError
|
||||||
* ADBError
|
* ADBError
|
||||||
"""
|
"""
|
||||||
forwards = self.command_output(["forward", "--list"], timeout=timeout)
|
self._validate_direction(direction)
|
||||||
return [tuple(line.split(" ")) for line in forwards.splitlines() if line.strip()]
|
|
||||||
|
|
||||||
def remove_forwards(self, local=None, timeout=None):
|
cmd = [direction, "--list"]
|
||||||
"""Remove existing port forwards.
|
output = self.command_output(cmd, timeout=timeout)
|
||||||
|
return [tuple(line.split(" ")) for line in output.splitlines() if line.strip()]
|
||||||
|
|
||||||
|
def remove_socket_connections(self, direction, local=None, timeout=None):
|
||||||
|
"""Remove existing socket connections for a given direction.
|
||||||
|
|
||||||
|
:param str direction: 'forward' to remove forward socket connection
|
||||||
|
'reverse' to remove reverse socket connection
|
||||||
:param local: local port specifier as for ADBDevice.forward. If local
|
:param local: local port specifier as for ADBDevice.forward. If local
|
||||||
is not specified removes all forwards.
|
is not specified removes all forwards.
|
||||||
:type local: str or None
|
:type local: str or None
|
||||||
|
|
@ -1042,7 +1059,10 @@ class ADBDevice(ADBCommand):
|
||||||
* ADBTimeoutError
|
* ADBTimeoutError
|
||||||
* ADBError
|
* ADBError
|
||||||
"""
|
"""
|
||||||
cmd = ["forward"]
|
self._validate_direction(direction)
|
||||||
|
|
||||||
|
cmd = [direction]
|
||||||
|
|
||||||
if local is None:
|
if local is None:
|
||||||
cmd.extend(["--remove-all"])
|
cmd.extend(["--remove-all"])
|
||||||
else:
|
else:
|
||||||
|
|
@ -1051,6 +1071,55 @@ class ADBDevice(ADBCommand):
|
||||||
|
|
||||||
self.command_output(cmd, timeout=timeout)
|
self.command_output(cmd, timeout=timeout)
|
||||||
|
|
||||||
|
# Legacy port forward methods
|
||||||
|
|
||||||
|
def forward(self, local, remote, allow_rebind=True, timeout=None):
|
||||||
|
"""Forward a local port to a specific port on the device.
|
||||||
|
|
||||||
|
See `ADBDevice.create_socket_connection`.
|
||||||
|
"""
|
||||||
|
self.create_socket_connection(self.SOCKET_DIRECTON_FORWARD,
|
||||||
|
local, remote, allow_rebind, timeout)
|
||||||
|
|
||||||
|
def list_forwards(self, timeout=None):
|
||||||
|
"""Return a list of tuples specifying active forwards.
|
||||||
|
|
||||||
|
See `ADBDevice.list_socket_connection`.
|
||||||
|
"""
|
||||||
|
return self.list_socket_connections(self.SOCKET_DIRECTON_FORWARD, timeout)
|
||||||
|
|
||||||
|
def remove_forwards(self, local=None, timeout=None):
|
||||||
|
"""Remove existing port forwards.
|
||||||
|
|
||||||
|
See `ADBDevice.remove_socket_connection`.
|
||||||
|
"""
|
||||||
|
self.remove_socket_connections(self.SOCKET_DIRECTON_FORWARD, local, timeout)
|
||||||
|
|
||||||
|
# Legacy port reverse methods
|
||||||
|
|
||||||
|
def reverse(self, local, remote, allow_rebind=True, timeout=None):
|
||||||
|
"""Sets up a reverse socket connection from device to host.
|
||||||
|
|
||||||
|
See `ADBDevice.create_socket_connection`.
|
||||||
|
"""
|
||||||
|
self.create_socket_connection(self.SOCKET_DIRECTON_REVERSE,
|
||||||
|
local, remote, allow_rebind, timeout)
|
||||||
|
|
||||||
|
def list_reverses(self, timeout=None):
|
||||||
|
"""Returns a list of tuples showing active reverse socket connections.
|
||||||
|
|
||||||
|
See `ADBDevice.list_socket_connection`.
|
||||||
|
"""
|
||||||
|
return self.list_socket_connections(self.SOCKET_DIRECTON_REVERSE, timeout)
|
||||||
|
|
||||||
|
def remove_reverses(self, local=None, timeout=None):
|
||||||
|
"""Remove existing reverse socket connections.
|
||||||
|
|
||||||
|
See `ADBDevice.remove_socket_connection`.
|
||||||
|
"""
|
||||||
|
self.remove_socket_connections(self.SOCKET_DIRECTON_REVERSE,
|
||||||
|
local, timeout)
|
||||||
|
|
||||||
# Device Shell methods
|
# Device Shell methods
|
||||||
|
|
||||||
def shell(self, cmd, env=None, cwd=None, timeout=None, root=False,
|
def shell(self, cmd, env=None, cwd=None, timeout=None, root=False,
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ from __future__ import absolute_import
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
|
|
||||||
PACKAGE_NAME = 'mozdevice'
|
PACKAGE_NAME = 'mozdevice'
|
||||||
PACKAGE_VERSION = '1.1.0'
|
PACKAGE_VERSION = '1.1.1'
|
||||||
|
|
||||||
deps = ['mozfile >= 1.0',
|
deps = ['mozfile >= 1.0',
|
||||||
'mozlog >= 3.0',
|
'mozlog >= 3.0',
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue