Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 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 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 38 'ftp': '-f', | 38 'ftp': '-f', |
| 39 'sync': '', # Sync uses its own script, and doesn't take a server type arg. | 39 'sync': '', # Sync uses its own script, and doesn't take a server type arg. |
| 40 'tcpecho': '--tcp-echo', | 40 'tcpecho': '--tcp-echo', |
| 41 'udpecho': '--udp-echo', | 41 'udpecho': '--udp-echo', |
| 42 } | 42 } |
| 43 | 43 |
| 44 | 44 |
| 45 # The timeout (in seconds) of starting up the Python test server. | 45 # The timeout (in seconds) of starting up the Python test server. |
| 46 TEST_SERVER_STARTUP_TIMEOUT = 10 | 46 TEST_SERVER_STARTUP_TIMEOUT = 10 |
| 47 | 47 |
| 48 INITIAL_SLEEP_TIMEOUT_SEC = 0.025 | |
| 48 | 49 |
| 49 def _CheckPortStatus(port, expected_status): | 50 def _CheckPortStatus(port, expected_status): |
| 50 """Returns True if port has expected_status. | 51 """Returns True if port has expected_status. |
| 51 | 52 |
| 52 Args: | 53 Args: |
| 53 port: the port number. | 54 port: the port number. |
| 54 expected_status: boolean of expected status. | 55 expected_status: boolean of expected status. |
| 55 | 56 |
| 56 Returns: | 57 Returns: |
| 57 Returns True if the status is expected. Otherwise returns False. | 58 Returns True if the status is expected. Otherwise returns False. |
| 58 """ | 59 """ |
| 59 for timeout in range(1, 5): | 60 sleep_time_sec = INITIAL_SLEEP_TIMEOUT_SEC |
| 61 for attempt in range(1, 5): | |
| 60 if ports.IsHostPortUsed(port) == expected_status: | 62 if ports.IsHostPortUsed(port) == expected_status: |
| 61 return True | 63 return True |
| 62 time.sleep(timeout) | 64 time.sleep(sleep_time_sec) |
| 65 sleep_time_sec *= 2 | |
| 63 return False | 66 return False |
| 64 | 67 |
| 65 | 68 |
| 66 def _GetServerTypeCommandLine(server_type): | 69 def _GetServerTypeCommandLine(server_type): |
| 67 """Returns the command-line by the given server type. | 70 """Returns the command-line by the given server type. |
| 68 | 71 |
| 69 Args: | 72 Args: |
| 70 server_type: the server type to be used (e.g. 'http'). | 73 server_type: the server type to be used (e.g. 'http'). |
| 71 | 74 |
| 72 Returns: | 75 Returns: |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 224 self.is_ready = _CheckPortStatus(self.host_port, True) | 227 self.is_ready = _CheckPortStatus(self.host_port, True) |
| 225 if self.is_ready: | 228 if self.is_ready: |
| 226 self._test_server_forwarder = Forwarder(self.adb, self.build_type) | 229 self._test_server_forwarder = Forwarder(self.adb, self.build_type) |
| 227 self._test_server_forwarder.Run( | 230 self._test_server_forwarder.Run( |
| 228 [(0, self.host_port)], self.tool, '127.0.0.1') | 231 [(0, self.host_port)], self.tool, '127.0.0.1') |
| 229 # Check whether the forwarder is ready on the device. | 232 # Check whether the forwarder is ready on the device. |
| 230 self.is_ready = False | 233 self.is_ready = False |
| 231 device_port = self._test_server_forwarder.DevicePortForHostPort( | 234 device_port = self._test_server_forwarder.DevicePortForHostPort( |
| 232 self.host_port) | 235 self.host_port) |
| 233 if device_port: | 236 if device_port: |
| 234 for timeout in range(1, 5): | 237 sleep_time_sec = INITIAL_SLEEP_TIMEOUT_SEC |
| 238 for attempt in range(1, 5): | |
| 235 if ports.IsDevicePortUsed(self.adb, device_port, 'LISTEN'): | 239 if ports.IsDevicePortUsed(self.adb, device_port, 'LISTEN'): |
| 236 self.is_ready = True | 240 self.is_ready = True |
| 237 self.forwarder_device_port = device_port | 241 self.forwarder_device_port = device_port |
| 238 break | 242 break |
| 239 time.sleep(timeout) | 243 time.sleep(sleep_time_sec) |
| 244 sleep_time_sec *= 2 | |
|
bulach
2013/05/07 15:09:28
perhaps move this out into a "_CheckDevicePortStat
Philippe
2013/05/07 15:47:41
Good idea. I would not encourage people to use thi
| |
| 240 # Wake up the request handler thread. | 245 # Wake up the request handler thread. |
| 241 self.ready_event.set() | 246 self.ready_event.set() |
| 242 # Keep thread running until Stop() gets called. | 247 # Keep thread running until Stop() gets called. |
| 248 sleep_time_sec = INITIAL_SLEEP_TIMEOUT_SEC | |
| 243 while not self.stop_flag: | 249 while not self.stop_flag: |
| 244 time.sleep(1) | 250 time.sleep(sleep_time_sec) |
| 251 sleep_time_sec *= 2 | |
|
bulach
2013/05/07 15:09:28
should we limit this somehow up to say, 1 or two s
Philippe
2013/05/07 15:47:41
Yeah good point.
| |
| 245 if self.process.poll() is None: | 252 if self.process.poll() is None: |
| 246 self.process.kill() | 253 self.process.kill() |
| 247 if self._test_server_forwarder: | 254 if self._test_server_forwarder: |
| 248 self._test_server_forwarder.Close() | 255 self._test_server_forwarder.Close() |
| 249 self.process = None | 256 self.process = None |
| 250 self.is_ready = False | 257 self.is_ready = False |
| 251 if self.pipe_out: | 258 if self.pipe_out: |
| 252 os.close(self.pipe_in) | 259 os.close(self.pipe_in) |
| 253 os.close(self.pipe_out) | 260 os.close(self.pipe_out) |
| 254 self.pipe_in = None | 261 self.pipe_in = None |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 394 | 401 |
| 395 def _Listen(self): | 402 def _Listen(self): |
| 396 logging.info('Starting test server spawner') | 403 logging.info('Starting test server spawner') |
| 397 self.server.serve_forever() | 404 self.server.serve_forever() |
| 398 | 405 |
| 399 def Start(self): | 406 def Start(self): |
| 400 """Starts the test server spawner.""" | 407 """Starts the test server spawner.""" |
| 401 listener_thread = threading.Thread(target=self._Listen) | 408 listener_thread = threading.Thread(target=self._Listen) |
| 402 listener_thread.setDaemon(True) | 409 listener_thread.setDaemon(True) |
| 403 listener_thread.start() | 410 listener_thread.start() |
| 404 time.sleep(1) | |
| 405 | 411 |
| 406 def Stop(self): | 412 def Stop(self): |
| 407 """Stops the test server spawner. | 413 """Stops the test server spawner. |
| 408 | 414 |
| 409 Also cleans the server state. | 415 Also cleans the server state. |
| 410 """ | 416 """ |
| 411 self.CleanupState() | 417 self.CleanupState() |
| 412 self.server.shutdown() | 418 self.server.shutdown() |
| 413 | 419 |
| 414 def CleanupState(self): | 420 def CleanupState(self): |
| 415 """Cleans up the spawning server state. | 421 """Cleans up the spawning server state. |
| 416 | 422 |
| 417 This should be called if the test server spawner is reused, | 423 This should be called if the test server spawner is reused, |
| 418 to avoid sharing the test server instance. | 424 to avoid sharing the test server instance. |
| 419 """ | 425 """ |
| 420 if self.server.test_server_instance: | 426 if self.server.test_server_instance: |
| 421 self.server.test_server_instance.Stop() | 427 self.server.test_server_instance.Stop() |
| 422 self.server.test_server_instance = None | 428 self.server.test_server_instance = None |
| OLD | NEW |