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

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

Issue 10689132: [android] Upstream / sync most of build/android and build/android/pylib. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « build/android/pylib/perf_tests_helper.py ('k') | build/android/pylib/run_tests_helper.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 # found in the LICENSE file.
4
5 """Functions that deals with local and device ports."""
6
7 import contextlib
8 import fcntl
9 import httplib
10 import logging
11 import os
12 import re
13 import socket
14 import traceback
15
16 import cmd_helper
17 import constants
18
19
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
22 # at same time, it's important to have a mechanism to allocate the port process
23 # safe. In here, we implement the safe port allocation by leveraging flock.
24 def ResetTestServerPortAllocation():
25 """Reset the port allocation to start from TEST_SERVER_PORT_FIRST.
26
27 Returns:
28 Returns True if reset successes. Otherwise returns False.
29 """
30 try:
31 with open(constants.TEST_SERVER_PORT_FILE, 'w') as fp:
32 fp.write('%d' % constants.TEST_SERVER_PORT_FIRST)
33 if os.path.exists(constants.TEST_SERVER_PORT_LOCKFILE):
34 os.unlink(constants.TEST_SERVER_PORT_LOCKFILE)
35 return True
36 except Exception as e:
37 logging.error(e)
38 return False
39
40
41 def AllocateTestServerPort():
42 """Allocate a port incrementally.
43
44 Returns:
45 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 """
48 port = 0
49 try:
50 fp_lock = open(constants.TEST_SERVER_PORT_LOCKFILE, 'w')
51 fcntl.flock(fp_lock, fcntl.LOCK_EX)
52 # Get current valid port and calculate next valid port.
53 assert os.path.exists(constants.TEST_SERVER_PORT_FILE)
54 with open(constants.TEST_SERVER_PORT_FILE, 'r+') as fp:
55 port = int(fp.read())
56 while IsHostPortUsed(port):
57 port += 1
58 if (port > constants.TEST_SERVER_PORT_LAST or
59 port < constants.TEST_SERVER_PORT_FIRST):
60 port = 0
61 else:
62 fp.seek(0, os.SEEK_SET)
63 fp.write('%d' % (port + 1))
64 except Exception as e:
65 logging.info(e)
66 finally:
67 if fp_lock:
68 fcntl.flock(fp_lock, fcntl.LOCK_UN)
69 fp_lock.close()
70 logging.info('Allocate port %d for test server.', port)
71 return port
72
73
74 def IsHostPortUsed(host_port):
75 """Checks whether the specified host port is used or not.
76
77 Uses -n -P to inhibit the conversion of host/port numbers to host/port names.
78
79 Args:
80 host_port: Port on host we want to check.
81
82 Returns:
83 True if the port on host is already used, otherwise returns False.
84 """
85 port_info = '(127\.0\.0\.1)|(localhost)\:%d' % host_port
86 # TODO(jnd): Find a better way to filter the port.
87 re_port = re.compile(port_info, re.MULTILINE)
88 if re_port.findall(cmd_helper.GetCmdOutput(['lsof', '-nPi:%d' % host_port])):
89 return True
90 return False
91
92
93 def IsDevicePortUsed(adb, device_port, state=''):
94 """Checks whether the specified device port is used or not.
95
96 Args:
97 adb: Instance of AndroidCommands for talking to the device.
98 device_port: Port on device we want to check.
99 state: String of the specified state. Default is empty string, which
100 means any state.
101
102 Returns:
103 True if the port on device is already used, otherwise returns False.
104 """
105 base_url = '127.0.0.1:%d' % device_port
106 netstat_results = adb.RunShellCommand('netstat', log_result=False)
107 for single_connect in netstat_results:
108 # Column 3 is the local address which we want to check with.
109 connect_results = single_connect.split()
110 is_state_match = connect_results[5] == state if state else True
111 if connect_results[3] == base_url and is_state_match:
112 return True
113 return False
114
115
116 def IsHttpServerConnectable(host, port, tries=3, command='GET', path='/',
117 expected_read='', timeout=2):
118 """Checks whether the specified http server is ready to serve request or not.
119
120 Args:
121 host: Host name of the HTTP server.
122 port: Port number of the HTTP server.
123 tries: How many times we want to test the connection. The default value is
124 3.
125 command: The http command we use to connect to HTTP server. The default
126 command is 'GET'.
127 path: The path we use when connecting to HTTP server. The default path is
128 '/'.
129 expected_read: The content we expect to read from the response. The default
130 value is ''.
131 timeout: Timeout (in seconds) for each http connection. The default is 2s.
132
133 Returns:
134 Tuple of (connect status, client error). connect status is a boolean value
135 to indicate whether the server is connectable. client_error is the error
136 message the server returns when connect status is false.
137 """
138 assert tries >= 1
139 for i in xrange(0, tries):
140 client_error = None
141 try:
142 with contextlib.closing(httplib.HTTPConnection(
143 host, port, timeout=timeout)) as http:
144 # Output some debug information when we have tried more than 2 times.
145 http.set_debuglevel(i >= 2)
146 http.request(command, path)
147 r = http.getresponse()
148 content = r.read()
149 if r.status == 200 and r.reason == 'OK' and content == expected_read:
150 return (True, '')
151 client_error = ('Bad response: %s %s version %s\n ' %
152 (r.status, r.reason, r.version) +
153 '\n '.join([': '.join(h) for h in r.getheaders()]))
154 except (httplib.HTTPException, socket.error) as e:
155 # Probably too quick connecting: try again.
156 exception_error_msgs = traceback.format_exception_only(type(e), e)
157 if exception_error_msgs:
158 client_error = ''.join(exception_error_msgs)
159 # Only returns last client_error.
160 return (False, client_error or 'Timeout')
OLDNEW
« no previous file with comments | « build/android/pylib/perf_tests_helper.py ('k') | build/android/pylib/run_tests_helper.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698