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

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, 3 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
13 14
14 class Forwarder(object): 15 class Forwarder(object):
15 """Class to manage port forwards from the device to the host.""" 16 """Class to manage port forwards from the device to the host."""
16 17
17 _FORWARDER_PATH = constants.TEST_EXECUTABLE_DIR + '/forwarder' 18 _DEVICE_FORWARDER_PATH = constants.TEST_EXECUTABLE_DIR + '/device_forwarder'
19
20 # Unix Abstract socket path:
21 _DEVICE_ADB_CONTROL_PORT = 'chrome_device_forwarder'
18 _TIMEOUT_SECS = 30 22 _TIMEOUT_SECS = 30
19 23
20 def __init__(self, adb, port_pairs, tool, host_name, build_type): 24 def __init__(self, adb, port_pairs, tool, host_name, build_type):
21 """Forwards TCP ports on the device back to the host. 25 """Forwards TCP ports on the device back to the host.
22 26
23 Works like adb forward, but in reverse. 27 Works like adb forward, but in reverse.
24 28
25 Args: 29 Args:
26 adb: Instance of AndroidCommands for talking to the device. 30 adb: Instance of AndroidCommands for talking to the device.
27 port_pairs: A list of tuples (device_port, host_port) to forward. Note 31 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 32 that you can specify 0 as a device_port, in which case a
29 port will by dynamically assigned on the device. You can 33 port will by dynamically assigned on the device. You can
30 get the number of the assigned port using the 34 get the number of the assigned port using the
31 DevicePortForHostPort method. 35 DevicePortForHostPort method.
32 tool: Tool class to use to get wrapper, if necessary, for executing the 36 tool: Tool class to use to get wrapper, if necessary, for executing the
33 forwarder (see valgrind_tools.py). 37 forwarder (see valgrind_tools.py).
34 host_name: Address to forward to, must be addressable from the 38 host_name: Address to forward to, must be addressable from the
35 host machine. Usually use loopback '127.0.0.1'. 39 host machine. Usually use loopback '127.0.0.1'.
36 build_type: 'Release' or 'Debug'. 40 build_type: 'Release' or 'Debug'.
37 41
38 Raises: 42 Raises:
39 Exception on failure to forward the port. 43 Exception on failure to forward the port.
40 """ 44 """
41 self._adb = adb 45 self._adb = adb
42 self._host_to_device_port_map = dict() 46 self._host_to_device_port_map = dict()
43 self._process = None 47 self._host_process = None
48 self._device_process = None
49 self._adb_forward_process = None
50
51 self._host_adb_control_port = ports.AllocateTestServerPort()
52
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))
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
79 self._device_process = pexpect.spawn(
80 'adb', ['-s',
81 adb._adb.GetSerialNumber(),
82 'shell',
83 '%s %s -D --adb_sock=%s' % (
84 tool.GetUtilWrapper(),
85 Forwarder._DEVICE_FORWARDER_PATH,
86 Forwarder._DEVICE_ADB_CONTROL_PORT)])
87
88 device_success_re = re.compile('Device Forwarder Ready.')
89 device_failure_re = re.compile('.*:ERROR:(.*)')
90 index = self._device_process.expect([device_success_re,
91 device_failure_re,
92 pexpect.EOF,
93 pexpect.TIMEOUT],
94 Forwarder._TIMEOUT_SECS)
95 if index == 1:
96 # Failure
97 error_msg = str(self._device_process.match.group(1))
98 logging.error(self._device_process.before)
99 self._CloseProcess()
100 raise Exception('Failed to start Device Forwarder with Error: %s' % (
101 error_msg))
102 elif index == 2:
103 logging.error(self._device_process.before)
104 self._CloseProcess()
105 raise Exception('Unexpected EOF while trying to start Device Forwarder.')
106 elif index == 3:
107 logging.error(self._device_process.before)
108 self._CloseProcess()
109 raise Exception('Timeout while trying start Device Forwarder')
110
111 # TODO(felipeg): Should I use tool.GetUtilWrapper() here ? bulach must know it.
bulach 2012/09/24 10:40:49 this is on the host, right? the tool.GetUtilWrappe
felipeg 2012/09/25 03:27:21 Yes, here is on the host only.
112 self._host_process = pexpect.spawn(self._host_forwarder_path,
113 ['--adb_port=%s' % (
114 self._host_adb_control_port),
115 ' '.join(forward_string)])
62 116
63 # Read the output of the command to determine which device ports where 117 # Read the output of the command to determine which device ports where
64 # forwarded to which host ports (necessary if 118 # forwarded to which host ports (necessary if
65 success_re = re.compile('Forwarding device port (\d+) to host (\d+):') 119 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: ' 120 host_failure_re = re.compile('Couldn\'t start forwarder server for port '
67 '(\d+):(\d+)') 121 'spec: (\d+):(\d+)')
68 for pair in port_pairs: 122 for pair in port_pairs:
69 index = process.expect([success_re, failure_re, pexpect.EOF, 123 index = self._host_process.expect([host_success_re,
70 pexpect.TIMEOUT], 124 host_failure_re,
71 Forwarder._TIMEOUT_SECS) 125 pexpect.EOF,
126 pexpect.TIMEOUT],
127 Forwarder._TIMEOUT_SECS)
72 if index == 0: 128 if index == 0:
73 # Success 129 # Success
74 device_port = int(process.match.group(1)) 130 device_port = int(self._host_process.match.group(1))
75 host_port = int(process.match.group(2)) 131 host_port = int(self._host_process.match.group(2))
76 self._host_to_device_port_map[host_port] = device_port 132 self._host_to_device_port_map[host_port] = device_port
77 logging.info("Forwarding device port: %d to host port: %d." % 133 logging.info("Forwarding device port: %d to host port: %d." %
78 (device_port, host_port)) 134 (device_port, host_port))
79 elif index == 1: 135 elif index == 1:
80 # Failure 136 # Failure
81 device_port = int(process.match.group(1)) 137 device_port = int(self._host_process.match.group(1))
82 host_port = int(process.match.group(2)) 138 host_port = int(self._host_process.match.group(2))
83 process.close() 139 self._CloseProcess()
84 raise Exception('Failed to forward port %d to %d' % (device_port, 140 raise Exception('Failed to forward port %d to %d' % (device_port,
85 host_port)) 141 host_port))
86 elif index == 2: 142 elif index == 2:
87 logging.error(process.before) 143 logging.error(self._host_process.before)
88 process.close() 144 self._CloseProcess()
89 raise Exception('Unexpected EOF while trying to forward ports %s' % 145 raise Exception('Unexpected EOF while trying to forward ports %s' %
90 port_pairs) 146 port_pairs)
91 elif index == 3: 147 elif index == 3:
92 logging.error(process.before) 148 logging.error(self._host_process.before)
93 process.close() 149 self._CloseProcess()
94 raise Exception('Timeout while trying to forward ports %s' % port_pairs) 150 raise Exception('Timeout while trying to forward ports %s' % port_pairs)
95 151
96 self._process = process 152 def _CloseProcess(self):
153 if self._host_process:
154 self._host_process.close()
155 if self._device_process:
156 self._device_process.close()
157 if self._adb_forward_process:
158 self._adb_forward_process.close()
159 self._host_process = None
160 self._device_process = None
161 self._adb_forward_process = None
97 162
98 def _KillForwardersUsingDevicePort(self, device_port): 163 def _KillForwardersUsingDevicePort(self, device_port):
99 """Check if the device port is in use and if it is try to terminate the 164 """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""" 165 forwarder process (if any) that may already be forwarding it"""
101 processes = self._adb.ProcessesUsingDevicePort(device_port) 166 processes = self._adb.ProcessesUsingDevicePort(device_port)
102 for pid, name in processes: 167 for pid, name in processes:
103 if name == 'forwarder': 168 if name == 'forwarder':
104 logging.warning( 169 logging.warning(
105 'Killing forwarder process with pid %d using device_port %d' % ( 170 'Killing forwarder process with pid %d using device_port %d' % (
106 pid, device_port)) 171 pid, device_port))
107 self._adb.RunShellCommand('kill %d' % pid) 172 self._adb.RunShellCommand('kill %d' % pid)
108 else: 173 else:
109 logging.error( 174 logging.error(
110 'Not killing process with pid %d (%s) using device_port %d' % ( 175 'Not killing process with pid %d (%s) using device_port %d' % (
111 pid, name, device_port)) 176 pid, name, device_port))
112 177
113 def DevicePortForHostPort(self, host_port): 178 def DevicePortForHostPort(self, host_port):
114 """Get the device port that corresponds to a given host port.""" 179 """Get the device port that corresponds to a given host port."""
115 return self._host_to_device_port_map.get(host_port) 180 return self._host_to_device_port_map.get(host_port)
116 181
117 def Close(self): 182 def Close(self):
118 """Terminate the forwarder process.""" 183 """Terminate the forwarder process."""
119 if self._process: 184 self._CloseProcess()
120 self._process.close()
121 self._process = None
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698