Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(861)

Side by Side Diff: build/android/pylib/forwarder.py

Issue 10957052: Adapt python scripts to use the new Forwarder2 (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import logging 5 import logging
6 import os 6 import os
7 import pexpect 7 import pexpect
8 import re 8 import re
9 import sys 9 import sys
10 10
11 import android_commands 11 import android_commands
12 import cmd_helper
12 import constants 13 import constants
14 import ports
13 15
14 class Forwarder(object): 16 class Forwarder(object):
15 """Class to manage port forwards from the device to the host.""" 17 """Class to manage port forwards from the device to the host."""
16 18
17 _FORWARDER_PATH = constants.TEST_EXECUTABLE_DIR + '/forwarder' 19 _DEVICE_FORWARDER_PATH = constants.TEST_EXECUTABLE_DIR + '/device_forwarder'
20
21 # Unix Abstract socket path:
22 _DEVICE_ADB_CONTROL_PORT = 'chrome_device_forwarder'
18 _TIMEOUT_SECS = 30 23 _TIMEOUT_SECS = 30
19 24
20 def __init__(self, adb, port_pairs, tool, host_name, build_type): 25 def __init__(self, adb, port_pairs, tool, host_name, build_type):
21 """Forwards TCP ports on the device back to the host. 26 """Forwards TCP ports on the device back to the host.
22 27
23 Works like adb forward, but in reverse. 28 Works like adb forward, but in reverse.
24 29
25 Args: 30 Args:
26 adb: Instance of AndroidCommands for talking to the device. 31 adb: Instance of AndroidCommands for talking to the device.
27 port_pairs: A list of tuples (device_port, host_port) to forward. Note 32 port_pairs: A list of tuples (device_port, host_port) to forward. Note
28 that you can specify 0 as a device_port, in which case a 33 that you can specify 0 as a device_port, in which case a
29 port will by dynamically assigned on the device. You can 34 port will by dynamically assigned on the device. You can
30 get the number of the assigned port using the 35 get the number of the assigned port using the
31 DevicePortForHostPort method. 36 DevicePortForHostPort method.
32 tool: Tool class to use to get wrapper, if necessary, for executing the 37 tool: Tool class to use to get wrapper, if necessary, for executing the
33 forwarder (see valgrind_tools.py). 38 forwarder (see valgrind_tools.py).
34 host_name: Address to forward to, must be addressable from the 39 host_name: Address to forward to, must be addressable from the
35 host machine. Usually use loopback '127.0.0.1'. 40 host machine. Usually use loopback '127.0.0.1'.
36 build_type: 'Release' or 'Debug'. 41 build_type: 'Release' or 'Debug'.
37 42
38 Raises: 43 Raises:
39 Exception on failure to forward the port. 44 Exception on failure to forward the port.
40 """ 45 """
41 self._adb = adb 46 self._adb = adb
42 self._host_to_device_port_map = dict() 47 self._host_to_device_port_map = dict()
43 self._process = None 48 self._host_process = None
49 self._device_process = None
50 self._adb_forward_process = None
51
52 self._host_adb_control_port = ports.AllocateTestServerPort()
44 adb.PushIfNeeded( 53 adb.PushIfNeeded(
45 os.path.join(constants.CHROME_DIR, 'out', build_type, 'forwarder'), 54 os.path.join(constants.CHROME_DIR, 'out', build_type,
46 Forwarder._FORWARDER_PATH) 55 'device_forwarder'),
56 Forwarder._DEVICE_FORWARDER_PATH)
57 self._host_forwarder_path = os.path.join(constants.CHROME_DIR,
58 'out',
59 build_type,
60 'host_forwarder')
47 forward_string = ['%d:%d:%s' % 61 forward_string = ['%d:%d:%s' %
48 (device, host, host_name) for device, host in port_pairs] 62 (device, host, host_name) for device, host in port_pairs]
49 63 logging.info('Forwarding ports: %s' % (forward_string))
bulach 2012/09/26 15:13:11 logging takes a format and vararg as well, so this
felipeg 2012/09/26 18:06:03 Done.
50 # Kill off any existing forwarders on conflicting non-dynamically allocated 64 # Kill off any existing device forwarders on conflicting non-dynamically
51 # ports. 65 # allocated ports.
52 for device_port, _ in port_pairs: 66 for device_port, _ in port_pairs:
53 if device_port != 0: 67 if device_port != 0:
54 self._KillForwardersUsingDevicePort(device_port) 68 self._KillForwardersUsingDevicePort(device_port)
55 69
56 logging.info('Forwarding ports: %s' % (forward_string)) 70 # Kill any existing host forwarders.
57 process = pexpect.spawn( 71 cmd_helper.RunCmd(['killall', 'host_forwarder'])
58 'adb', ['-s', adb._adb.GetSerialNumber(), 72 self._adb_forward_process = pexpect.spawn(
59 'shell', '%s %s -D %s' % ( 73 'adb', ['-s',
60 tool.GetUtilWrapper(), Forwarder._FORWARDER_PATH, 74 adb._adb.GetSerialNumber(),
61 ' '.join(forward_string))]) 75 'forward',
76 'tcp:%s' % self._host_adb_control_port,
77 'localabstract:%s' % Forwarder._DEVICE_ADB_CONTROL_PORT])
78 self._device_process = pexpect.spawn(
79 'adb', ['-s',
80 adb._adb.GetSerialNumber(),
81 'shell',
82 '%s %s -D --adb_sock=%s' % (
83 tool.GetUtilWrapper(),
84 Forwarder._DEVICE_FORWARDER_PATH,
85 Forwarder._DEVICE_ADB_CONTROL_PORT)])
86
87 device_success_re = re.compile('Starting Device Forwarder.')
88 device_failure_re = re.compile('.*:ERROR:(.*)')
89 index = self._device_process.expect([device_success_re,
90 device_failure_re,
91 pexpect.EOF,
92 pexpect.TIMEOUT],
93 Forwarder._TIMEOUT_SECS)
94 if index == 1:
95 # Failure
96 error_msg = str(self._device_process.match.group(1))
97 logging.error(self._device_process.before)
98 self._CloseProcess()
99 raise Exception('Failed to start Device Forwarder with Error: %s' % (
100 error_msg))
bulach 2012/09/26 15:13:11 nit: no need for the extra parens around error_msg
felipeg 2012/09/26 18:06:03 Done.
101 elif index == 2:
102 logging.error(self._device_process.before)
103 self._CloseProcess()
104 raise Exception('Unexpected EOF while trying to start Device Forwarder.')
105 elif index == 3:
106 logging.error(self._device_process.before)
107 self._CloseProcess()
108 raise Exception('Timeout while trying start Device Forwarder')
109
110 self._host_process = pexpect.spawn(self._host_forwarder_path,
111 ['--adb_port=%s' % (
112 self._host_adb_control_port),
113 ' '.join(forward_string)])
62 114
63 # Read the output of the command to determine which device ports where 115 # Read the output of the command to determine which device ports where
64 # forwarded to which host ports (necessary if 116 # forwarded to which host ports (necessary if
65 success_re = re.compile('Forwarding device port (\d+) to host (\d+):') 117 host_success_re = re.compile('Forwarding device port (\d+) to host (\d+):')
66 failure_re = re.compile('Couldn\'t start forwarder server for port spec: ' 118 host_failure_re = re.compile('Couldn\'t start forwarder server for port '
67 '(\d+):(\d+)') 119 'spec: (\d+):(\d+)')
68 for pair in port_pairs: 120 for pair in port_pairs:
69 index = process.expect([success_re, failure_re, pexpect.EOF, 121 index = self._host_process.expect([host_success_re,
70 pexpect.TIMEOUT], 122 host_failure_re,
71 Forwarder._TIMEOUT_SECS) 123 pexpect.EOF,
124 pexpect.TIMEOUT],
125 Forwarder._TIMEOUT_SECS)
72 if index == 0: 126 if index == 0:
73 # Success 127 # Success
74 device_port = int(process.match.group(1)) 128 device_port = int(self._host_process.match.group(1))
75 host_port = int(process.match.group(2)) 129 host_port = int(self._host_process.match.group(2))
76 self._host_to_device_port_map[host_port] = device_port 130 self._host_to_device_port_map[host_port] = device_port
77 logging.info("Forwarding device port: %d to host port: %d." % 131 logging.info("Forwarding device port: %d to host port: %d." %
78 (device_port, host_port)) 132 (device_port, host_port))
79 elif index == 1: 133 elif index == 1:
80 # Failure 134 # Failure
81 device_port = int(process.match.group(1)) 135 device_port = int(self._host_process.match.group(1))
82 host_port = int(process.match.group(2)) 136 host_port = int(self._host_process.match.group(2))
83 process.close() 137 self._CloseProcess()
84 raise Exception('Failed to forward port %d to %d' % (device_port, 138 raise Exception('Failed to forward port %d to %d' % (device_port,
85 host_port)) 139 host_port))
86 elif index == 2: 140 elif index == 2:
87 logging.error(process.before) 141 logging.error(self._host_process.before)
88 process.close() 142 self._CloseProcess()
89 raise Exception('Unexpected EOF while trying to forward ports %s' % 143 raise Exception('Unexpected EOF while trying to forward ports %s' %
90 port_pairs) 144 port_pairs)
91 elif index == 3: 145 elif index == 3:
92 logging.error(process.before) 146 logging.error(self._host_process.before)
93 process.close() 147 self._CloseProcess()
94 raise Exception('Timeout while trying to forward ports %s' % port_pairs) 148 raise Exception('Timeout while trying to forward ports %s' % port_pairs)
95 149
96 self._process = process 150 def _CloseProcess(self):
151 if self._host_process:
152 self._host_process.close()
153 if self._device_process:
154 self._device_process.close()
155 if self._adb_forward_process:
156 self._adb_forward_process.close()
157 self._host_process = None
158 self._device_process = None
159 self._adb_forward_process = None
97 160
98 def _KillForwardersUsingDevicePort(self, device_port): 161 def _KillForwardersUsingDevicePort(self, device_port):
99 """Check if the device port is in use and if it is try to terminate the 162 """Check if the device port is in use and if it is try to terminate the
100 forwarder process (if any) that may already be forwarding it""" 163 forwarder process (if any) that may already be forwarding it"""
101 processes = self._adb.ProcessesUsingDevicePort(device_port) 164 processes = self._adb.ProcessesUsingDevicePort(device_port)
102 for pid, name in processes: 165 for pid, name in processes:
103 if name == 'forwarder': 166 if name == 'device_forwarder':
104 logging.warning( 167 logging.warning(
105 'Killing forwarder process with pid %d using device_port %d' % ( 168 'Killing forwarder process with pid %d using device_port %d' % (
106 pid, device_port)) 169 pid, device_port))
107 self._adb.RunShellCommand('kill %d' % pid) 170 self._adb.RunShellCommand('kill %d' % pid)
108 else: 171 else:
109 logging.error( 172 logging.error(
110 'Not killing process with pid %d (%s) using device_port %d' % ( 173 'Not killing process with pid %d (%s) using device_port %d' % (
111 pid, name, device_port)) 174 pid, name, device_port))
112 175
113 def DevicePortForHostPort(self, host_port): 176 def DevicePortForHostPort(self, host_port):
114 """Get the device port that corresponds to a given host port.""" 177 """Get the device port that corresponds to a given host port."""
115 return self._host_to_device_port_map.get(host_port) 178 return self._host_to_device_port_map.get(host_port)
116 179
117 def Close(self): 180 def Close(self):
118 """Terminate the forwarder process.""" 181 """Terminate the forwarder process."""
119 if self._process: 182 self._CloseProcess()
120 self._process.close()
121 self._process = None
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698