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

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

Issue 14767023: Speedup net_unittests on Android by 30%. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: s/range/xrange Created 7 years, 7 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
11 import BaseHTTPServer 11 import BaseHTTPServer
12 import json 12 import json
13 import logging 13 import logging
14 import os 14 import os
15 import select 15 import select
16 import struct 16 import struct
17 import subprocess 17 import subprocess
18 import sys
18 import threading 19 import threading
19 import time 20 import time
20 import urlparse 21 import urlparse
21 22
22 import constants 23 import constants
23 from forwarder import Forwarder 24 from forwarder import Forwarder
24 import ports 25 import ports
25 26
26 27
27 # Path that are needed to import necessary modules when launching a testserver. 28 # Path that are needed to import necessary modules when launching a testserver.
(...skipping 10 matching lines...) Expand all
38 'ftp': '-f', 39 'ftp': '-f',
39 'sync': '', # Sync uses its own script, and doesn't take a server type arg. 40 'sync': '', # Sync uses its own script, and doesn't take a server type arg.
40 'tcpecho': '--tcp-echo', 41 'tcpecho': '--tcp-echo',
41 'udpecho': '--udp-echo', 42 'udpecho': '--udp-echo',
42 } 43 }
43 44
44 45
45 # The timeout (in seconds) of starting up the Python test server. 46 # The timeout (in seconds) of starting up the Python test server.
46 TEST_SERVER_STARTUP_TIMEOUT = 10 47 TEST_SERVER_STARTUP_TIMEOUT = 10
47 48
49 def _WaitUntil(predicate, max_attempts=5):
50 """Blocks until the provided predicate (function) is true.
51
52 Returns:
53 Whether the provided predicate was satisfied once (before the timeout).
54 """
55 sleep_time_sec = 0.025
56 for attempt in xrange(1, max_attempts):
57 if predicate():
58 return True
59 time.sleep(sleep_time_sec)
60 sleep_time_sec = min(1, sleep_time_sec * 2) # Don't wait more than 1 sec.
61 return False
62
48 63
49 def _CheckPortStatus(port, expected_status): 64 def _CheckPortStatus(port, expected_status):
50 """Returns True if port has expected_status. 65 """Returns True if port has expected_status.
51 66
52 Args: 67 Args:
53 port: the port number. 68 port: the port number.
54 expected_status: boolean of expected status. 69 expected_status: boolean of expected status.
55 70
56 Returns: 71 Returns:
57 Returns True if the status is expected. Otherwise returns False. 72 Returns True if the status is expected. Otherwise returns False.
58 """ 73 """
59 for timeout in range(1, 5): 74 return _WaitUntil(lambda: ports.IsHostPortUsed(port) == expected_status)
60 if ports.IsHostPortUsed(port) == expected_status: 75
61 return True 76
62 time.sleep(timeout) 77 def _CheckDevicePortStatus(adb, port):
63 return False 78 """Returns whether the provided port is used."""
79 return _WaitUntil(lambda: ports.IsDevicePortUsed(adb, port))
64 80
65 81
66 def _GetServerTypeCommandLine(server_type): 82 def _GetServerTypeCommandLine(server_type):
67 """Returns the command-line by the given server type. 83 """Returns the command-line by the given server type.
68 84
69 Args: 85 Args:
70 server_type: the server type to be used (e.g. 'http'). 86 server_type: the server type to be used (e.g. 'http').
71 87
72 Returns: 88 Returns:
73 A string containing the command-line argument. 89 A string containing the command-line argument.
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 else: 239 else:
224 self.is_ready = _CheckPortStatus(self.host_port, True) 240 self.is_ready = _CheckPortStatus(self.host_port, True)
225 if self.is_ready: 241 if self.is_ready:
226 self._test_server_forwarder = Forwarder(self.adb, self.build_type) 242 self._test_server_forwarder = Forwarder(self.adb, self.build_type)
227 self._test_server_forwarder.Run( 243 self._test_server_forwarder.Run(
228 [(0, self.host_port)], self.tool, '127.0.0.1') 244 [(0, self.host_port)], self.tool, '127.0.0.1')
229 # Check whether the forwarder is ready on the device. 245 # Check whether the forwarder is ready on the device.
230 self.is_ready = False 246 self.is_ready = False
231 device_port = self._test_server_forwarder.DevicePortForHostPort( 247 device_port = self._test_server_forwarder.DevicePortForHostPort(
232 self.host_port) 248 self.host_port)
233 if device_port: 249 if device_port and _CheckDevicePortStatus(self.adb, device_port):
234 for timeout in range(1, 5): 250 self.is_ready = True
235 if ports.IsDevicePortUsed(self.adb, device_port, 'LISTEN'): 251 self.forwarder_device_port = device_port
236 self.is_ready = True
237 self.forwarder_device_port = device_port
238 break
239 time.sleep(timeout)
240 # Wake up the request handler thread. 252 # Wake up the request handler thread.
241 self.ready_event.set() 253 self.ready_event.set()
242 # Keep thread running until Stop() gets called. 254 # Keep thread running until Stop() gets called.
243 while not self.stop_flag: 255 _WaitUntil(lambda: self.stop_flag, max_attempts=sys.maxint)
244 time.sleep(1)
245 if self.process.poll() is None: 256 if self.process.poll() is None:
246 self.process.kill() 257 self.process.kill()
247 if self._test_server_forwarder: 258 if self._test_server_forwarder:
248 self._test_server_forwarder.Close() 259 self._test_server_forwarder.Close()
249 self.process = None 260 self.process = None
250 self.is_ready = False 261 self.is_ready = False
251 if self.pipe_out: 262 if self.pipe_out:
252 os.close(self.pipe_in) 263 os.close(self.pipe_in)
253 os.close(self.pipe_out) 264 os.close(self.pipe_out)
254 self.pipe_in = None 265 self.pipe_in = None
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 405
395 def _Listen(self): 406 def _Listen(self):
396 logging.info('Starting test server spawner') 407 logging.info('Starting test server spawner')
397 self.server.serve_forever() 408 self.server.serve_forever()
398 409
399 def Start(self): 410 def Start(self):
400 """Starts the test server spawner.""" 411 """Starts the test server spawner."""
401 listener_thread = threading.Thread(target=self._Listen) 412 listener_thread = threading.Thread(target=self._Listen)
402 listener_thread.setDaemon(True) 413 listener_thread.setDaemon(True)
403 listener_thread.start() 414 listener_thread.start()
404 time.sleep(1)
405 415
406 def Stop(self): 416 def Stop(self):
407 """Stops the test server spawner. 417 """Stops the test server spawner.
408 418
409 Also cleans the server state. 419 Also cleans the server state.
410 """ 420 """
411 self.CleanupState() 421 self.CleanupState()
412 self.server.shutdown() 422 self.server.shutdown()
413 423
414 def CleanupState(self): 424 def CleanupState(self):
415 """Cleans up the spawning server state. 425 """Cleans up the spawning server state.
416 426
417 This should be called if the test server spawner is reused, 427 This should be called if the test server spawner is reused,
418 to avoid sharing the test server instance. 428 to avoid sharing the test server instance.
419 """ 429 """
420 if self.server.test_server_instance: 430 if self.server.test_server_instance:
421 self.server.test_server_instance.Stop() 431 self.server.test_server_instance.Stop()
422 self.server.test_server_instance = None 432 self.server.test_server_instance = None
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698