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

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

Issue 11038005: Enable forwarder2 for all our tests. (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()
53 if not self._host_adb_control_port:
54 raise Exception('Failed to allocate a TCP port in the host machine.')
44 adb.PushIfNeeded( 55 adb.PushIfNeeded(
45 os.path.join(constants.CHROME_DIR, 'out', build_type, 'forwarder'), 56 os.path.join(constants.CHROME_DIR, 'out', build_type,
46 Forwarder._FORWARDER_PATH) 57 'device_forwarder'),
58 Forwarder._DEVICE_FORWARDER_PATH)
59 self._host_forwarder_path = os.path.join(constants.CHROME_DIR,
60 'out',
61 build_type,
62 'host_forwarder')
47 forward_string = ['%d:%d:%s' % 63 forward_string = ['%d:%d:%s' %
48 (device, host, host_name) for device, host in port_pairs] 64 (device, host, host_name) for device, host in port_pairs]
49 65 logging.info('Forwarding ports: %s', forward_string)
50 # Kill off any existing forwarders on conflicting non-dynamically allocated 66 # Kill off any existing device forwarders on conflicting non-dynamically
51 # ports. 67 # allocated ports.
52 for device_port, _ in port_pairs: 68 for device_port, _ in port_pairs:
53 if device_port != 0: 69 if device_port != 0:
54 self._KillForwardersUsingDevicePort(device_port) 70 self._KillForwardersUsingDevicePort(device_port)
55 71
56 logging.info('Forwarding ports: %s' % (forward_string)) 72 self._adb_forward_process = pexpect.spawn(
57 process = pexpect.spawn( 73 'adb', ['-s',
58 'adb', ['-s', adb._adb.GetSerialNumber(), 74 adb._adb.GetSerialNumber(),
59 'shell', '%s %s -D %s' % ( 75 'forward',
60 tool.GetUtilWrapper(), Forwarder._FORWARDER_PATH, 76 'tcp:%s' % self._host_adb_control_port,
61 ' '.join(forward_string))]) 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)
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 # Kill any existing host forwarders using the same forward_string.
111 cmd_helper.RunCmd(['pkill', '-f',
112 'host_forwarder.*' + ' '.join(forward_string)])
113
114 self._host_process = pexpect.spawn(self._host_forwarder_path,
115 ['--adb_port=%s' % (
116 self._host_adb_control_port),
117 ' '.join(forward_string)])
62 118
63 # Read the output of the command to determine which device ports where 119 # Read the output of the command to determine which device ports where
64 # forwarded to which host ports (necessary if 120 # forwarded to which host ports (necessary if
65 success_re = re.compile('Forwarding device port (\d+) to host (\d+):') 121 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: ' 122 host_failure_re = re.compile('Couldn\'t start forwarder server for port '
67 '(\d+):(\d+)') 123 'spec: (\d+):(\d+)')
68 for pair in port_pairs: 124 for pair in port_pairs:
69 index = process.expect([success_re, failure_re, pexpect.EOF, 125 index = self._host_process.expect([host_success_re,
70 pexpect.TIMEOUT], 126 host_failure_re,
71 Forwarder._TIMEOUT_SECS) 127 pexpect.EOF,
128 pexpect.TIMEOUT],
129 Forwarder._TIMEOUT_SECS)
72 if index == 0: 130 if index == 0:
73 # Success 131 # Success
74 device_port = int(process.match.group(1)) 132 device_port = int(self._host_process.match.group(1))
75 host_port = int(process.match.group(2)) 133 host_port = int(self._host_process.match.group(2))
76 self._host_to_device_port_map[host_port] = device_port 134 self._host_to_device_port_map[host_port] = device_port
77 logging.info("Forwarding device port: %d to host port: %d." % 135 logging.info("Forwarding device port: %d to host port: %d." %
78 (device_port, host_port)) 136 (device_port, host_port))
79 elif index == 1: 137 elif index == 1:
80 # Failure 138 # Failure
81 device_port = int(process.match.group(1)) 139 device_port = int(self._host_process.match.group(1))
82 host_port = int(process.match.group(2)) 140 host_port = int(self._host_process.match.group(2))
83 process.close() 141 self._CloseProcess()
84 raise Exception('Failed to forward port %d to %d' % (device_port, 142 raise Exception('Failed to forward port %d to %d' % (device_port,
85 host_port)) 143 host_port))
86 elif index == 2: 144 elif index == 2:
87 logging.error(process.before) 145 logging.error(self._host_process.before)
88 process.close() 146 self._CloseProcess()
89 raise Exception('Unexpected EOF while trying to forward ports %s' % 147 raise Exception('Unexpected EOF while trying to forward ports %s' %
90 port_pairs) 148 port_pairs)
91 elif index == 3: 149 elif index == 3:
92 logging.error(process.before) 150 logging.error(self._host_process.before)
93 process.close() 151 self._CloseProcess()
94 raise Exception('Timeout while trying to forward ports %s' % port_pairs) 152 raise Exception('Timeout while trying to forward ports %s' % port_pairs)
95 153
96 self._process = process 154 def _CloseProcess(self):
155 if self._host_process:
156 self._host_process.close()
157 if self._device_process:
Yaron 2012/10/01 22:28:43 Missed this downstream.. as the device is a client
felipeg 2012/10/01 22:35:26 As we chatted in person: The current C++ code is r
158 self._device_process.close()
159 if self._adb_forward_process:
160 self._adb_forward_process.close()
161 self._host_process = None
162 self._device_process = None
163 self._adb_forward_process = None
97 164
98 def _KillForwardersUsingDevicePort(self, device_port): 165 def _KillForwardersUsingDevicePort(self, device_port):
99 """Check if the device port is in use and if it is try to terminate the 166 """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""" 167 forwarder process (if any) that may already be forwarding it"""
101 processes = self._adb.ProcessesUsingDevicePort(device_port) 168 processes = self._adb.ProcessesUsingDevicePort(device_port)
102 for pid, name in processes: 169 for pid, name in processes:
103 if name == 'forwarder': 170 if name == 'device_forwarder':
104 logging.warning( 171 logging.warning(
105 'Killing forwarder process with pid %d using device_port %d' % ( 172 'Killing forwarder process with pid %d using device_port %d' % (
106 pid, device_port)) 173 pid, device_port))
107 self._adb.RunShellCommand('kill %d' % pid) 174 self._adb.RunShellCommand('kill %d' % pid)
108 else: 175 else:
109 logging.error( 176 logging.error(
110 'Not killing process with pid %d (%s) using device_port %d' % ( 177 'Not killing process with pid %d (%s) using device_port %d' % (
111 pid, name, device_port)) 178 pid, name, device_port))
112 179
113 def DevicePortForHostPort(self, host_port): 180 def DevicePortForHostPort(self, host_port):
114 """Get the device port that corresponds to a given host port.""" 181 """Get the device port that corresponds to a given host port."""
115 return self._host_to_device_port_map.get(host_port) 182 return self._host_to_device_port_map.get(host_port)
116 183
117 def Close(self): 184 def Close(self):
118 """Terminate the forwarder process.""" 185 """Terminate the forwarder process."""
119 if self._process: 186 self._CloseProcess()
120 self._process.close()
121 self._process = None
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698