Chromium Code Reviews| 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 """A "Test Server Spawner" that handles killing/stopping per-test test servers. | 5 """A "Test Server Spawner" that handles killing/stopping per-test test servers. |
| 6 | 6 |
| 7 It's used to accept requests from the device to spawn and kill instances of the | 7 It's used to accept requests from the device to spawn and kill instances of the |
| 8 chrome test server on the host. | 8 chrome test server on the host. |
| 9 """ | 9 """ |
| 10 | 10 |
| 11 import BaseHTTPServer | 11 import BaseHTTPServer |
| 12 import logging | 12 import logging |
| 13 import json | |
|
bulach
2012/08/29 09:22:54
nit: before logging
Philippe
2012/08/29 11:29:05
Done.
| |
| 13 import os | 14 import os |
| 15 import select | |
| 16 import struct | |
| 17 import subprocess | |
| 14 import sys | 18 import sys |
| 15 import threading | 19 import threading |
| 16 import time | 20 import time |
| 17 import urlparse | 21 import urlparse |
| 18 | 22 |
| 19 # Path that are needed to import testserver | 23 import constants |
| 20 cr_src = os.path.join(os.path.abspath(os.path.dirname(__file__)), | 24 from forwarder import Forwarder |
| 21 '..', '..', '..') | 25 import ports |
| 22 sys.path.append(os.path.join(cr_src, 'third_party')) | 26 |
|
bulach
2012/08/29 09:22:54
nit: need another \n
Philippe
2012/08/29 11:29:05
Done.
| |
| 23 sys.path.append(os.path.join(cr_src, 'third_party', 'tlslite')) | 27 # Path that are needed to import necessary modules when running testserver.py. |
| 24 sys.path.append(os.path.join(cr_src, 'third_party', 'pyftpdlib', 'src')) | 28 os.environ['PYTHONPATH'] += ':%s:%s:%s:%s' % ( |
| 25 sys.path.append(os.path.join(cr_src, 'net', 'tools', 'testserver')) | 29 os.path.join(constants.CHROME_DIR, 'third_party'), |
| 26 import testserver | 30 os.path.join(constants.CHROME_DIR, 'third_party', 'tlslite'), |
| 27 | 31 os.path.join(constants.CHROME_DIR, 'third_party', 'pyftpdlib', 'src'), |
| 28 _test_servers = [] | 32 os.path.join(constants.CHROME_DIR, 'net', 'tools', 'testserver')) |
| 33 | |
|
Philippe
2012/08/29 11:29:05
Do we need another \n here? I'm adding it to be co
| |
| 34 SERVER_TYPES = { | |
| 35 'http': '', | |
|
bulach
2012/08/29 09:22:54
nit: 35-39 needs indent by 4
Philippe
2012/08/29 11:29:05
Done.
| |
| 36 'ftp': '-f', | |
| 37 'sync': '--sync', | |
| 38 'tcpecho': '--tcp-echo', | |
| 39 'udpecho': '--udp-echo', | |
| 40 } | |
| 41 | |
|
bulach
2012/08/29 09:22:54
nit: need another \n
Philippe
2012/08/29 11:29:05
Done.
| |
| 42 # The timeout (in seconds) of starting up the Python test server. | |
| 43 TEST_SERVER_STARTUP_TIMEOUT = 10 | |
| 44 | |
| 45 | |
| 46 def CheckPortStatus(port, expected_status): | |
|
bulach
2012/08/29 09:22:54
nit: it seems that this function, and most of the
Philippe
2012/08/29 11:29:05
Sounds good. Done.
| |
| 47 """Returns True if port has expected_status. | |
| 48 | |
| 49 Args: | |
| 50 port: the port number. | |
| 51 expected_status: boolean of expected status. | |
| 52 Returns: | |
| 53 Returns True if the status is expected. Otherwise returns False. | |
| 54 """ | |
| 55 for timeout in range(1, 5): | |
| 56 if ports.IsHostPortUsed(port) == expected_status: | |
| 57 return True | |
| 58 time.sleep(timeout) | |
| 59 return False | |
| 60 | |
| 61 | |
| 62 def GetServerTypeCommandLine(server_type_string): | |
| 63 """Returns the command-line by the given server type. | |
| 64 | |
| 65 This function translates the server type string into the appropriate | |
| 66 command-line argument by following the option definitions in testserver.py. | |
|
bulach
2012/08/29 09:22:54
nit: need "Args:" and "Returns:"..
also, it'd be n
Philippe
2012/08/29 11:29:05
Done.
| |
| 67 """ | |
| 68 if server_type_string not in SERVER_TYPES: | |
| 69 raise NotImplementedError('Unknown server type: %s' % server_type) | |
|
bulach
2012/08/29 09:22:54
nit: server_type is undefined, needs to be "server
Philippe
2012/08/29 11:29:05
Done.
| |
| 70 if server_type_string == 'udpecho': | |
| 71 raise Exception('Please do not run UDP echo tests because we do not have ' | |
| 72 'a UDP forwarder tool.') | |
| 73 return SERVER_TYPES[server_type_string] | |
| 74 | |
| 75 | |
| 76 class TestServerThread(threading.Thread): | |
| 77 """The class to run a test server in a separate process in a thread. | |
|
bulach
2012/08/29 09:22:54
nit: needs to be one line, probably something like
Philippe
2012/08/29 11:29:05
Done.
| |
| 78 """ | |
| 79 | |
| 80 def __init__(self, ready_event, arguments, adb, tool, build_type): | |
| 81 """Initialize TestServerThread with the following argument. | |
| 82 | |
| 83 Args: | |
| 84 ready_event: event which will be set when the test server is ready. | |
| 85 arguments: dictionary of arguments to run the test server. | |
| 86 adb: instance of AndroidCommands. | |
| 87 tool: instance of runtime error detection tool. | |
| 88 build_type: 'Release' or 'Debug'. | |
| 89 """ | |
| 90 threading.Thread.__init__(self) | |
| 91 self.wait_event = threading.Event() | |
| 92 self.stop_flag = False | |
| 93 self.ready_event = ready_event | |
| 94 self.ready_event.clear() | |
| 95 self.arguments = arguments | |
| 96 self.adb = adb | |
| 97 self.tool = tool | |
| 98 self.test_server_process = None | |
| 99 self.is_ready = False | |
| 100 self.host_port = self.arguments['port'] | |
| 101 assert isinstance(self.host_port, int) | |
| 102 self._test_server_forwarder = None | |
| 103 # The forwarder device port now is dynamically allocated. | |
| 104 self.forwarder_device_port = 0; | |
|
bulach
2012/08/29 09:22:54
nit: remove ;
Philippe
2012/08/29 11:29:05
Done.
| |
| 105 # Anonymous pipe in order to get port info from test server. | |
| 106 self.pipe_in = None | |
| 107 self.pipe_out = None | |
| 108 self.command_line = [] | |
| 109 self.build_type = build_type | |
| 110 | |
| 111 def WaitToStartAndGetPortFromTestServer(self): | |
| 112 """Waits for the Python test server to start and get port it is using. The | |
|
bulach
2012/08/29 09:22:54
nit: needs a one line docstring.
Philippe
2012/08/29 11:29:05
Done.
| |
| 113 port information is passed by the Python test server with a pipe given by | |
| 114 self.pipe_out. | |
| 115 | |
| 116 Return: | |
|
bulach
2012/08/29 09:22:54
nit: Returns:
Philippe
2012/08/29 11:29:05
Done.
| |
| 117 True if successfully gets port used by the Python test server. | |
| 118 """ | |
| 119 assert self.host_port == 0 and self.pipe_out and self.pipe_in | |
| 120 (in_fds, out_fds, err_fds) = select.select([self.pipe_in,],[],[], | |
|
bulach
2012/08/29 09:22:54
nit: out_fds and err_fds seem unused, maybe replac
Philippe
2012/08/29 11:29:05
Done.
| |
| 121 TEST_SERVER_STARTUP_TIMEOUT) | |
| 122 if len(in_fds) == 0: | |
| 123 logging.error('Failed to wait to the Python test server to be started.') | |
| 124 return False | |
| 125 # First read the data length as an unsigned 4-byte value. This | |
| 126 # is _not_ using network byte ordering since the Python test server packs | |
| 127 # size as native byte order and all Chromium platforms so far are | |
| 128 # configured to use little-endian. | |
| 129 # TODO(jnd): Change the Python test server and local_test_server_*.cc to | |
| 130 # use a unified byte order (either big-endian or little-endian). | |
| 131 data_length = os.read(self.pipe_in, struct.calcsize('=L')) | |
| 132 if data_length: | |
| 133 (data_length, ) = struct.unpack('=L', data_length) | |
|
bulach
2012/08/29 09:22:54
nit: no space after ,
Philippe
2012/08/29 11:29:05
Done.
| |
| 134 assert data_length | |
| 135 if not data_length: | |
| 136 logging.error('Failed to get length of server data.') | |
| 137 return False | |
| 138 port_json = os.read(self.pipe_in, data_length) | |
| 139 if not port_json: | |
| 140 logging.error('Failed to get server data.') | |
| 141 return False | |
| 142 logging.info('Got port json data: %s' % port_json) | |
|
bulach
2012/08/29 09:22:54
nit: logging can do the formatting itself, so use
Philippe
2012/08/29 11:29:05
Done.
| |
| 143 port_json = json.loads(port_json) | |
| 144 if port_json.has_key('port') and isinstance(port_json['port'], int): | |
| 145 self.host_port = port_json['port'] | |
| 146 return CheckPortStatus(self.host_port, True) | |
| 147 logging.error('Failed to get port information from the server data.') | |
| 148 return False | |
| 149 | |
| 150 def GenerateCommandLineArguments(self): | |
| 151 """Generate the command lines based on the input arguments to run | |
|
bulach
2012/08/29 09:22:54
nit: one line docstring
Philippe
2012/08/29 11:29:05
Done.
| |
| 152 the test server. All options are processed by following the definitions | |
| 153 in testserver.py""" | |
| 154 if self.command_line: | |
| 155 return | |
| 156 # The following arguments must exist. | |
| 157 type_cmd = GetServerTypeCommandLine(self.arguments['server-type']) | |
| 158 if type_cmd: | |
| 159 self.command_line.append(type_cmd) | |
| 160 self.command_line.append('--port=%d' % self.host_port) | |
| 161 # Use a pipe to get the port given by the instance of Python test server | |
| 162 # if the test does not specify the port. | |
| 163 if self.host_port == 0: | |
| 164 (self.pipe_in, self.pipe_out) = os.pipe() | |
| 165 self.command_line.append('--startup-pipe=%d' % self.pipe_out) | |
| 166 self.command_line.append('--host=%s' % self.arguments['host']) | |
| 167 data_dir = self.arguments['data-dir'] or 'chrome/test/data' | |
| 168 if not os.path.isabs(data_dir): | |
| 169 data_dir = os.path.join(constants.CHROME_DIR, data_dir) | |
| 170 self.command_line.append('--data-dir=%s' % data_dir) | |
| 171 # The following arguments are optional depending on the individual test. | |
| 172 if self.arguments.has_key('log-to-console'): | |
| 173 self.command_line.append('--log-to-console') | |
| 174 if self.arguments.has_key('auth-token'): | |
| 175 self.command_line.append('--auth-token=%s' % self.arguments['auth-token']) | |
| 176 if self.arguments.has_key('https'): | |
| 177 self.command_line.append('--https') | |
| 178 if self.arguments.has_key('cert-and-key-file'): | |
| 179 self.command_line.append('--cert-and-key-file=%s' % os.path.join( | |
| 180 constants.CHROME_DIR, self.arguments['cert-and-key-file'])) | |
| 181 if self.arguments.has_key('ocsp'): | |
| 182 self.command_line.append('--ocsp=%s' % self.arguments['ocsp']) | |
| 183 if self.arguments.has_key('https-record-resume'): | |
| 184 self.command_line.append('--https-record-resume') | |
| 185 if self.arguments.has_key('ssl-client-auth'): | |
| 186 self.command_line.append('--ssl-client-auth') | |
| 187 if self.arguments.has_key('tls-intolerant'): | |
| 188 self.command_line.append('--tls-intolerant') | |
| 189 if self.arguments.has_key('ssl-client-ca'): | |
| 190 for ca in self.arguments['ssl-client-ca']: | |
| 191 self.command_line.append('--ssl-client-ca=%s' % | |
| 192 os.path.join(constants.CHROME_DIR, ca)) | |
| 193 if self.arguments.has_key('ssl-bulk-cipher'): | |
| 194 for bulk_cipher in self.arguments['ssl-bulk-cipher']: | |
| 195 self.command_line.append('--ssl-bulk-cipher=%s' % bulk_cipher) | |
| 196 | |
| 197 def run(self): | |
| 198 logging.info('Start running the thread!') | |
| 199 self.wait_event.clear() | |
| 200 self.GenerateCommandLineArguments() | |
| 201 command = '%s %s' % ( | |
| 202 os.path.join(constants.CHROME_DIR, 'net', 'tools', 'testserver', | |
| 203 'testserver.py'), | |
| 204 ' '.join(self.command_line)) | |
| 205 logging.info(command) | |
| 206 self.process = subprocess.Popen(command, shell=True) | |
| 207 if self.process: | |
| 208 if self.pipe_out: | |
| 209 self.is_ready = self.WaitToStartAndGetPortFromTestServer() | |
| 210 else: | |
| 211 self.is_ready = CheckPortStatus(self.host_port, True) | |
| 212 if self.is_ready: | |
| 213 self._test_server_forwarder = Forwarder( | |
| 214 self.adb, [(0, self.host_port)], self.tool, '127.0.0.1', | |
| 215 self.build_type) | |
| 216 # Check whether the forwarder is ready on the device. | |
| 217 self.is_ready = False | |
| 218 device_port = self._test_server_forwarder.DevicePortForHostPort( | |
| 219 self.host_port) | |
| 220 if device_port: | |
| 221 for timeout in range(1, 5): | |
| 222 if ports.IsDevicePortUsed(self.adb, device_port, 'LISTEN'): | |
| 223 self.is_ready = True | |
| 224 self.forwarder_device_port = device_port | |
| 225 break | |
| 226 time.sleep(timeout) | |
| 227 # Wake up the request handler thread. | |
| 228 self.ready_event.set() | |
| 229 # Keep thread running until Stop() gets called. | |
| 230 while not self.stop_flag: | |
| 231 time.sleep(1) | |
| 232 if self.process.poll() == None: | |
|
bulach
2012/08/29 09:22:54
nit: "is None"
Philippe
2012/08/29 11:29:05
Done.
| |
| 233 self.process.kill() | |
| 234 if self._test_server_forwarder: | |
| 235 self._test_server_forwarder.Close() | |
| 236 self.process = None | |
| 237 self.is_ready = False | |
| 238 if self.pipe_out: | |
| 239 os.close(self.pipe_in) | |
| 240 os.close(self.pipe_out) | |
| 241 self.pipe_in = None | |
| 242 self.pipe_out = None | |
| 243 logging.info('Test-server has died.') | |
| 244 self.wait_event.set() | |
| 245 | |
| 246 def Stop(self): | |
| 247 """Blocks until the loop has finished. This must be called in another | |
|
bulach
2012/08/29 09:22:54
nit: one line
Philippe
2012/08/29 11:29:05
Done.
| |
| 248 thread. | |
| 249 """ | |
| 250 if not self.process: | |
| 251 return | |
| 252 self.stop_flag = True | |
| 253 self.wait_event.wait() | |
| 254 | |
| 29 | 255 |
| 30 class SpawningServerRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): | 256 class SpawningServerRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
| 31 """A handler used to process http GET request. | 257 """A handler used to process http GET/POST request. |
|
bulach
2012/08/29 09:22:54
nit: one line
Philippe
2012/08/29 11:29:05
Done.
| |
| 32 """ | 258 """ |
| 33 | 259 |
| 34 def GetServerType(self, server_type): | 260 def SendResponse(self, response_code, response_reason, additional_headers, |
| 35 """Returns the server type to use when starting the test server. | 261 contents): |
| 36 | 262 """Generate response according to specified parameters and send it back |
| 37 This function translate the command-line argument into the appropriate | 263 to client. |
|
bulach
2012/08/29 09:22:54
nit: one line
Philippe
2012/08/29 11:29:05
Done.
| |
| 38 numerical constant. | 264 |
| 39 # TODO(yfriedman): Do that translation! | 265 Args: |
| 266 response_code: number of the response status. | |
| 267 response_reason: string of reason description of the response. | |
| 268 additional_headers: dict of additional headers. Each key is the name of | |
| 269 the header, each value is the content of the header. | |
| 270 contents: string of the contents we want to send to client. | |
| 40 """ | 271 """ |
| 41 if server_type: | 272 self.send_response(response_code, response_reason) |
| 42 pass | 273 self.send_header('Content-Type', 'text/html') |
| 43 return 0 | 274 # Specify the content-length as without it the http(s) response will not |
| 275 # be completed properly (and the browser keeps expecting data). | |
| 276 self.send_header('Content-Length', len(contents)) | |
| 277 for header_name in additional_headers: | |
| 278 self.send_header(header_name, additional_headers[header_name]) | |
| 279 self.end_headers() | |
| 280 self.wfile.write(contents) | |
| 281 self.wfile.flush() | |
| 282 | |
| 283 def StartTestServer(self): | |
|
bulach
2012/08/29 09:22:54
nit: needs docstring
Philippe
2012/08/29 11:29:05
Done.
| |
| 284 logging.info('Handling request to spawn a test server.') | |
| 285 content_type = self.headers.getheader('content-type') | |
| 286 if content_type != 'application/json': | |
| 287 raise Exception('Bad content-type for start request.') | |
| 288 content_length = self.headers.getheader('content-length') | |
| 289 if not content_length: | |
| 290 content_length = 0 | |
| 291 try: | |
| 292 content_length = int(content_length) | |
| 293 except: | |
| 294 raise Exception('Bad content-length for start request.') | |
| 295 logging.info(content_length) | |
| 296 test_server_argument_json = self.rfile.read(content_length) | |
| 297 logging.info(test_server_argument_json) | |
| 298 assert not self.server.test_server_instance | |
| 299 ready_event = threading.Event() | |
| 300 self.server.test_server_instance = TestServerThread( | |
| 301 ready_event, | |
| 302 json.loads(test_server_argument_json), | |
| 303 self.server.adb, | |
| 304 self.server.tool, | |
| 305 self.server.build_type) | |
| 306 self.server.test_server_instance.setDaemon(True) | |
| 307 self.server.test_server_instance.start() | |
| 308 ready_event.wait() | |
| 309 if self.server.test_server_instance.is_ready: | |
| 310 self.SendResponse(200, 'OK', {}, json.dumps( | |
| 311 {'port': self.server.test_server_instance.forwarder_device_port, | |
| 312 'message': 'started'})) | |
| 313 logging.info('Test server is running on port: %d.' % | |
|
bulach
2012/08/29 09:22:54
nit: as above, s/%/,/
Philippe
2012/08/29 11:29:05
Done.
| |
| 314 self.server.test_server_instance.host_port) | |
| 315 else: | |
| 316 self.server.test_server_instance.Stop() | |
| 317 self.server.test_server_instance = None | |
| 318 self.SendResponse(500, 'Test Server Error.', {}, '') | |
| 319 logging.info('Encounter problem during starting a test server.') | |
| 320 | |
| 321 def KillTestServer(self): | |
|
bulach
2012/08/29 09:22:54
nit: need docstring
Philippe
2012/08/29 11:29:05
Done.
| |
| 322 # There should only ever be one test server at a time. This may do the | |
| 323 # wrong thing if we try and start multiple test servers. | |
| 324 if not self.server.test_server_instance: | |
| 325 return | |
| 326 port = self.server.test_server_instance.host_port | |
| 327 logging.info('Handling request to kill a test server on port: %d.' % port) | |
| 328 self.server.test_server_instance.Stop() | |
| 329 # Make sure the status of test server is correct before sending response. | |
| 330 if CheckPortStatus(port, False): | |
| 331 self.SendResponse(200, 'OK', {}, 'killed') | |
| 332 logging.info('Test server on port %d is killed' % port) | |
|
bulach
2012/08/29 09:22:54
nit: s/%/,/
Philippe
2012/08/29 11:29:05
Done.
| |
| 333 else: | |
| 334 self.SendResponse(500, 'Test Server Error.', {}, '') | |
| 335 logging.info('Encounter problem during killing a test server.') | |
| 336 self.server.test_server_instance = None | |
| 337 | |
| 338 def do_POST(self): | |
| 339 parsed_path = urlparse.urlparse(self.path) | |
| 340 action = parsed_path.path | |
| 341 logging.info('Action for POST method is: %s.' % action) | |
|
bulach
2012/08/29 09:22:54
nit: s/%/,/
Philippe
2012/08/29 11:29:05
Done.
| |
| 342 if action == '/start': | |
| 343 self.StartTestServer() | |
| 344 else: | |
| 345 self.SendResponse(400, 'Unknown request.', {}, '') | |
| 346 logging.info('Encounter unknown request: %s.' % action) | |
|
bulach
2012/08/29 09:22:54
nit: s/%/,/
Philippe
2012/08/29 11:29:05
Done.
| |
| 44 | 347 |
| 45 def do_GET(self): | 348 def do_GET(self): |
| 46 parsed_path = urlparse.urlparse(self.path) | 349 parsed_path = urlparse.urlparse(self.path) |
| 47 action = parsed_path.path | 350 action = parsed_path.path |
| 48 params = urlparse.parse_qs(parsed_path.query, keep_blank_values=1) | 351 params = urlparse.parse_qs(parsed_path.query, keep_blank_values=1) |
| 49 logging.info('Action is: %s' % action) | 352 logging.info('Action for GET method is: %s.' % action) |
|
bulach
2012/08/29 09:22:54
nit: s/%/,/
Philippe
2012/08/29 11:29:05
Done.
| |
| 50 if action == '/killserver': | 353 for param in params: |
| 51 # There should only ever be one test server at a time. This may do the | 354 logging.info('%s=%s' % (param, params[param][0])) |
|
bulach
2012/08/29 09:22:54
nit: s/%/,/
Philippe
2012/08/29 11:29:05
Done.
| |
| 52 # wrong thing if we try and start multiple test servers. | 355 expect_exist = False |
|
bulach
2012/08/29 09:22:54
nit: unused..
Philippe
2012/08/29 11:29:05
Done.
| |
| 53 _test_servers.pop().Stop() | 356 if action == '/kill': |
| 54 elif action == '/start': | 357 self.KillTestServer() |
| 55 logging.info('Handling request to spawn a test webserver') | 358 elif action == '/ping': |
| 56 for param in params: | 359 # The ping handler is used to check whether the spawner server is ready |
| 57 logging.info('%s=%s' % (param, params[param][0])) | 360 # to serve the requests. We don't need to test the status of the test |
| 58 s_type = 0 | 361 # server when handling ping request. |
| 59 doc_root = None | 362 self.SendResponse(200, 'OK', {}, 'ready') |
| 60 if 'server_type' in params: | 363 logging.info('Handled ping request and sent response.') |
| 61 s_type = self.GetServerType(params['server_type'][0]) | 364 else: |
| 62 if 'doc_root' in params: | 365 self.SendResponse(400, 'Unknown request', {}, '') |
| 63 doc_root = params['doc_root'][0] | 366 logging.info('Encounter unknown request: %s.' % action) |
|
bulach
2012/08/29 09:22:54
nit: s/%/,/
Philippe
2012/08/29 11:29:05
Done.
| |
| 64 self.webserver_thread = threading.Thread( | |
| 65 target=self.SpawnTestWebServer, args=(s_type, doc_root)) | |
| 66 self.webserver_thread.setDaemon(True) | |
| 67 self.webserver_thread.start() | |
| 68 self.send_response(200, 'OK') | |
| 69 self.send_header('Content-type', 'text/html') | |
| 70 self.end_headers() | |
| 71 self.wfile.write('<html><head><title>started</title></head></html>') | |
| 72 logging.info('Returned OK!!!') | |
| 73 | |
| 74 def SpawnTestWebServer(self, s_type, doc_root): | |
| 75 class Options(object): | |
| 76 log_to_console = True | |
| 77 server_type = s_type | |
| 78 port = self.server.test_server_port | |
| 79 data_dir = doc_root or 'chrome/test/data' | |
| 80 file_root_url = '/files/' | |
| 81 cert = False | |
| 82 policy_keys = None | |
| 83 policy_user = None | |
| 84 startup_pipe = None | |
| 85 options = Options() | |
| 86 logging.info('Listening on %d, type %d, data_dir %s' % (options.port, | |
| 87 options.server_type, options.data_dir)) | |
| 88 testserver.main(options, None, server_list=_test_servers) | |
| 89 logging.info('Test-server has died.') | |
| 90 | 367 |
| 91 | 368 |
| 92 class SpawningServer(object): | 369 class SpawningServer(object): |
| 93 """The class used to start/stop a http server. | 370 """The class used to start/stop a http server. |
|
bulach
2012/08/29 09:22:54
nit: one line
Philippe
2012/08/29 11:29:05
Done.
| |
| 94 """ | 371 """ |
| 95 | 372 |
| 96 def __init__(self, test_server_spawner_port, test_server_port): | 373 def __init__(self, test_server_spawner_port, adb, tool, build_type): |
| 97 logging.info('Creating new spawner %d', test_server_spawner_port) | 374 logging.info('Creating new spawner on port: %d.', test_server_spawner_port) |
| 98 self.server = testserver.StoppableHTTPServer(('', test_server_spawner_port), | 375 self.server = BaseHTTPServer.HTTPServer(('', test_server_spawner_port), |
| 99 SpawningServerRequestHandler) | 376 SpawningServerRequestHandler) |
| 100 self.port = test_server_spawner_port | 377 self.port = test_server_spawner_port |
| 101 self.server.test_server_port = test_server_port | 378 self.server.adb = adb |
| 379 self.server.tool = tool | |
| 380 self.server.test_server_instance = None | |
| 381 self.server.build_type = build_type | |
| 102 | 382 |
| 103 def Listen(self): | 383 def Listen(self): |
| 104 logging.info('Starting test server spawner') | 384 logging.info('Starting test server spawner') |
| 105 self.server.serve_forever() | 385 self.server.serve_forever() |
| 106 | 386 |
| 107 def Start(self): | 387 def Start(self): |
| 108 listener_thread = threading.Thread(target=self.Listen) | 388 listener_thread = threading.Thread(target=self.Listen) |
| 109 listener_thread.setDaemon(True) | 389 listener_thread.setDaemon(True) |
| 110 listener_thread.start() | 390 listener_thread.start() |
| 111 time.sleep(1) | 391 time.sleep(1) |
| 112 | 392 |
| 113 def Stop(self): | 393 def Stop(self): |
| 114 self.server.Stop() | 394 if self.server.test_server_instance: |
| 395 self.server.test_server_instance.Stop() | |
| 396 self.server.shutdown() | |
| OLD | NEW |