OLD | NEW |
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 deal 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 socket | 13 import socket |
13 import traceback | 14 import traceback |
14 | 15 |
15 import cmd_helper | 16 import cmd_helper |
16 import constants | 17 import constants |
17 | 18 |
18 | 19 |
19 # 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 |
20 # types of test servers. Because some net-related tests can be run on shards at | 21 # types of test servers. Because some net-related tests can be run on shards at |
21 # same time, it's important to have a mechanism to allocate the port | 22 # same time, it's important to have a mechanism to allocate the port |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 logging.info('Allocate port %d for test server.', port) | 76 logging.info('Allocate port %d for test server.', port) |
76 else: | 77 else: |
77 logging.error('Could not allocate port for test server. ' | 78 logging.error('Could not allocate port for test server. ' |
78 'List of ports tried: %s', str(ports_tried)) | 79 'List of ports tried: %s', str(ports_tried)) |
79 return port | 80 return port |
80 | 81 |
81 | 82 |
82 def IsHostPortUsed(host_port): | 83 def IsHostPortUsed(host_port): |
83 """Checks whether the specified host port is used or not. | 84 """Checks whether the specified host port is used or not. |
84 | 85 |
| 86 Uses -n -P to inhibit the conversion of host/port numbers to host/port names. |
| 87 |
85 Args: | 88 Args: |
86 host_port: Port on host we want to check. | 89 host_port: Port on host we want to check. |
87 | 90 |
88 Returns: | 91 Returns: |
89 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. |
90 """ | 93 """ |
91 try: | 94 port_info = '(\*)|(127\.0\.0\.1)|(localhost):%d' % host_port |
92 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | 95 # TODO(jnd): Find a better way to filter the port. Note that connecting to the |
93 sock.connect(('127.0.0.1', host_port)) | 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. |
| 98 re_port = re.compile(port_info, re.MULTILINE) |
| 99 if re_port.search(cmd_helper.GetCmdOutput(['lsof', '-nPi:%d' % host_port])): |
94 return True | 100 return True |
95 except socket.error as error: | 101 return False |
96 return False | |
97 finally: | |
98 sock.close() | |
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. |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 client_error = ('Bad response: %s %s version %s\n ' % | 167 client_error = ('Bad response: %s %s version %s\n ' % |
165 (r.status, r.reason, r.version) + | 168 (r.status, r.reason, r.version) + |
166 '\n '.join([': '.join(h) for h in r.getheaders()])) | 169 '\n '.join([': '.join(h) for h in r.getheaders()])) |
167 except (httplib.HTTPException, socket.error) as e: | 170 except (httplib.HTTPException, socket.error) as e: |
168 # Probably too quick connecting: try again. | 171 # Probably too quick connecting: try again. |
169 exception_error_msgs = traceback.format_exception_only(type(e), e) | 172 exception_error_msgs = traceback.format_exception_only(type(e), e) |
170 if exception_error_msgs: | 173 if exception_error_msgs: |
171 client_error = ''.join(exception_error_msgs) | 174 client_error = ''.join(exception_error_msgs) |
172 # Only returns last client_error. | 175 # Only returns last client_error. |
173 return (False, client_error or 'Timeout') | 176 return (False, client_error or 'Timeout') |
OLD | NEW |