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

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

Issue 11269036: Support HTTP test-server based net unit tests on Android. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix Clang build + sync Created 8 years, 1 month 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 | Annotate | Revision Log
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 """Functions that deals with local and device ports.""" 5 """Functions that deal with local and device ports."""
6 6
7 import contextlib 7 import contextlib
8 import fcntl 8 import fcntl
9 import httplib 9 import httplib
10 import logging 10 import logging
11 import os 11 import os
12 import re 12 import re
13 import socket 13 import socket
14 import traceback 14 import traceback
15 15
16 import cmd_helper 16 import cmd_helper
17 import constants 17 import constants
18 18
19 19
20 #The following two methods are used to allocate the port source for various 20 # The following two methods are used to allocate the port source for various
21 # types of test servers. Because some net relates tests can be run on shards 21 # types of test servers. Because some net-related tests can be run on shards at
22 # at same time, it's important to have a mechanism to allocate the port process 22 # same time, it's important to have a mechanism to allocate the port
23 # safe. In here, we implement the safe port allocation by leveraging flock. 23 # process-safe. In here, we implement the safe port allocation by leveraging
24 # flock.
24 def ResetTestServerPortAllocation(): 25 def ResetTestServerPortAllocation():
25 """Reset the port allocation to start from TEST_SERVER_PORT_FIRST. 26 """Resets the port allocation to start from TEST_SERVER_PORT_FIRST.
26 27
27 Returns: 28 Returns:
28 Returns True if reset successes. Otherwise returns False. 29 Returns True if reset successes. Otherwise returns False.
29 """ 30 """
30 try: 31 try:
31 with open(constants.TEST_SERVER_PORT_FILE, 'w') as fp: 32 with open(constants.TEST_SERVER_PORT_FILE, 'w') as fp:
32 fp.write('%d' % constants.TEST_SERVER_PORT_FIRST) 33 fp.write('%d' % constants.TEST_SERVER_PORT_FIRST)
33 if os.path.exists(constants.TEST_SERVER_PORT_LOCKFILE): 34 if os.path.exists(constants.TEST_SERVER_PORT_LOCKFILE):
34 os.unlink(constants.TEST_SERVER_PORT_LOCKFILE) 35 os.unlink(constants.TEST_SERVER_PORT_LOCKFILE)
35 return True 36 return True
36 except Exception as e: 37 except Exception as e:
37 logging.error(e) 38 logging.error(e)
38 return False 39 return False
39 40
40 41
41 def AllocateTestServerPort(): 42 def AllocateTestServerPort():
42 """Allocate a port incrementally. 43 """Allocates a port incrementally.
43 44
44 Returns: 45 Returns:
45 Returns a valid port which should be in between TEST_SERVER_PORT_FIRST and 46 Returns a valid port which should be in between TEST_SERVER_PORT_FIRST and
46 TEST_SERVER_PORT_LAST. Returning 0 means no more valid port can be used. 47 TEST_SERVER_PORT_LAST. Returning 0 means no more valid port can be used.
47 """ 48 """
48 port = 0 49 port = 0
49 ports_tried = [] 50 ports_tried = []
50 try: 51 try:
51 fp_lock = open(constants.TEST_SERVER_PORT_LOCKFILE, 'w') 52 fp_lock = open(constants.TEST_SERVER_PORT_LOCKFILE, 'w')
52 fcntl.flock(fp_lock, fcntl.LOCK_EX) 53 fcntl.flock(fp_lock, fcntl.LOCK_EX)
(...skipping 30 matching lines...) Expand all
83 """Checks whether the specified host port is used or not. 84 """Checks whether the specified host port is used or not.
84 85
85 Uses -n -P to inhibit the conversion of host/port numbers to host/port names. 86 Uses -n -P to inhibit the conversion of host/port numbers to host/port names.
86 87
87 Args: 88 Args:
88 host_port: Port on host we want to check. 89 host_port: Port on host we want to check.
89 90
90 Returns: 91 Returns:
91 True if the port on host is already used, otherwise returns False. 92 True if the port on host is already used, otherwise returns False.
92 """ 93 """
93 port_info = '(127\.0\.0\.1)|(localhost)\:%d' % host_port 94 port_info = '(\*)|(127\.0\.0\.1)|(localhost):%d' % host_port
94 # TODO(jnd): Find a better way to filter the port. 95 # TODO(jnd): Find a better way to filter the port. Note that connecting to the
96 # socket and closing it would leave it in the TIME_WAIT state. Setting
97 # SO_LINGER on it and then closing it makes the Python HTTP server crash.
95 re_port = re.compile(port_info, re.MULTILINE) 98 re_port = re.compile(port_info, re.MULTILINE)
96 if re_port.findall(cmd_helper.GetCmdOutput(['lsof', '-nPi:%d' % host_port])): 99 if re_port.search(cmd_helper.GetCmdOutput(['lsof', '-nPi:%d' % host_port])):
97 return True 100 return True
98 return False 101 return False
99 102
100 103
101 def IsDevicePortUsed(adb, device_port, state=''): 104 def IsDevicePortUsed(adb, device_port, state=''):
102 """Checks whether the specified device port is used or not. 105 """Checks whether the specified device port is used or not.
103 106
104 Args: 107 Args:
105 adb: Instance of AndroidCommands for talking to the device. 108 adb: Instance of AndroidCommands for talking to the device.
106 device_port: Port on device we want to check. 109 device_port: Port on device we want to check.
107 state: String of the specified state. Default is empty string, which 110 state: String of the specified state. Default is empty string, which
108 means any state. 111 means any state.
109 112
110 Returns: 113 Returns:
111 True if the port on device is already used, otherwise returns False. 114 True if the port on device is already used, otherwise returns False.
112 """ 115 """
113 base_url = '127.0.0.1:%d' % device_port 116 base_url = '127.0.0.1:%d' % device_port
114 netstat_results = adb.RunShellCommand('netstat', log_result=False) 117 netstat_results = adb.RunShellCommand('netstat', log_result=False)
115 for single_connect in netstat_results: 118 for single_connect in netstat_results:
116 # Column 3 is the local address which we want to check with. 119 # Column 3 is the local address which we want to check with.
117 connect_results = single_connect.split() 120 connect_results = single_connect.split()
121 if connect_results[0] != 'tcp':
122 continue
123 if len(connect_results) < 6:
124 raise Exception('Unexpected format while parsing netstat line: ' +
125 single_connect)
118 is_state_match = connect_results[5] == state if state else True 126 is_state_match = connect_results[5] == state if state else True
119 if connect_results[3] == base_url and is_state_match: 127 if connect_results[3] == base_url and is_state_match:
120 return True 128 return True
121 return False 129 return False
122 130
123 131
124 def IsHttpServerConnectable(host, port, tries=3, command='GET', path='/', 132 def IsHttpServerConnectable(host, port, tries=3, command='GET', path='/',
125 expected_read='', timeout=2): 133 expected_read='', timeout=2):
126 """Checks whether the specified http server is ready to serve request or not. 134 """Checks whether the specified http server is ready to serve request or not.
127 135
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 client_error = ('Bad response: %s %s version %s\n ' % 167 client_error = ('Bad response: %s %s version %s\n ' %
160 (r.status, r.reason, r.version) + 168 (r.status, r.reason, r.version) +
161 '\n '.join([': '.join(h) for h in r.getheaders()])) 169 '\n '.join([': '.join(h) for h in r.getheaders()]))
162 except (httplib.HTTPException, socket.error) as e: 170 except (httplib.HTTPException, socket.error) as e:
163 # Probably too quick connecting: try again. 171 # Probably too quick connecting: try again.
164 exception_error_msgs = traceback.format_exception_only(type(e), e) 172 exception_error_msgs = traceback.format_exception_only(type(e), e)
165 if exception_error_msgs: 173 if exception_error_msgs:
166 client_error = ''.join(exception_error_msgs) 174 client_error = ''.join(exception_error_msgs)
167 # Only returns last client_error. 175 # Only returns last client_error.
168 return (False, client_error or 'Timeout') 176 return (False, client_error or 'Timeout')
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698