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

Side by Side Diff: build/android/lighttpd_server.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/enable_asserts.py ('k') | build/android/pylib/android_commands.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 #
3 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 5 # found in the LICENSE file.
5 6
6 """Provides a convenient wrapper for spawning a test lighttpd instance. 7 """Provides a convenient wrapper for spawning a test lighttpd instance.
7 8
8 Usage: 9 Usage:
9 lighttpd_server PATH_TO_DOC_ROOT 10 lighttpd_server PATH_TO_DOC_ROOT
10 """ 11 """
11 12
12 import codecs 13 import codecs
13 import contextlib 14 import contextlib
14 import httplib 15 import httplib
15 import os 16 import os
16 import pexpect 17 import pexpect
17 import random 18 import random
18 import shutil 19 import shutil
19 import socket 20 import socket
21 import subprocess
20 import sys 22 import sys
21 import tempfile 23 import tempfile
24 import time
25
26 from pylib import constants
22 27
23 28
24 class LighttpdServer(object): 29 class LighttpdServer(object):
25 """Wraps lighttpd server, providing robust startup. 30 """Wraps lighttpd server, providing robust startup.
26 31
27 Args: 32 Args:
28 document_root: Path to root of this server's hosted files. 33 document_root: Path to root of this server's hosted files.
29 port: TCP port on the _host_ machine that the server will listen on. If 34 port: TCP port on the _host_ machine that the server will listen on. If
30 ommitted it will attempt to use 9000, or if unavailable it will find 35 ommitted it will attempt to use 9000, or if unavailable it will find
31 a free port from 8001 - 8999. 36 a free port from 8001 - 8999.
32 lighttpd_path, lighttpd_module_path: Optional paths to lighttpd binaries. 37 lighttpd_path, lighttpd_module_path: Optional paths to lighttpd binaries.
33 base_config_path: If supplied this file will replace the built-in default 38 base_config_path: If supplied this file will replace the built-in default
34 lighttpd config file. 39 lighttpd config file.
35 extra_config_contents: If specified, this string will be appended to the 40 extra_config_contents: If specified, this string will be appended to the
36 base config (default built-in, or from base_config_path). 41 base config (default built-in, or from base_config_path).
37 config_path, error_log, access_log: Optional paths where the class should 42 config_path, error_log, access_log: Optional paths where the class should
38 place temprary files for this session. 43 place temprary files for this session.
39 """ 44 """
40 45
41 def __init__(self, document_root, port=None, 46 def __init__(self, document_root, port=None,
42 lighttpd_path=None, lighttpd_module_path=None, 47 lighttpd_path=None, lighttpd_module_path=None,
43 base_config_path=None, extra_config_contents=None, 48 base_config_path=None, extra_config_contents=None,
44 config_path=None, error_log=None, access_log=None): 49 config_path=None, error_log=None, access_log=None):
45 self.temp_dir = tempfile.mkdtemp(prefix='lighttpd_for_chrome_android') 50 self.temp_dir = tempfile.mkdtemp(prefix='lighttpd_for_chrome_android')
46 self.document_root = os.path.abspath(document_root) 51 self.document_root = os.path.abspath(document_root)
47 self.fixed_port = port 52 self.fixed_port = port
48 self.port = port or 9000 53 self.port = port or constants.LIGHTTPD_DEFAULT_PORT
49 self.server_tag = 'LightTPD ' + str(random.randint(111111, 999999)) 54 self.server_tag = 'LightTPD ' + str(random.randint(111111, 999999))
50 self.lighttpd_path = lighttpd_path or '/usr/sbin/lighttpd' 55 self.lighttpd_path = lighttpd_path or '/usr/sbin/lighttpd'
51 self.lighttpd_module_path = lighttpd_module_path or '/usr/lib/lighttpd' 56 self.lighttpd_module_path = lighttpd_module_path or '/usr/lib/lighttpd'
52 self.base_config_path = base_config_path 57 self.base_config_path = base_config_path
53 self.extra_config_contents = extra_config_contents 58 self.extra_config_contents = extra_config_contents
54 self.config_path = config_path or self._Mktmp('config') 59 self.config_path = config_path or self._Mktmp('config')
55 self.error_log = error_log or self._Mktmp('error_log') 60 self.error_log = error_log or self._Mktmp('error_log')
56 self.access_log = access_log or self._Mktmp('access_log') 61 self.access_log = access_log or self._Mktmp('access_log')
57 self.pid_file = self._Mktmp('pid_file') 62 self.pid_file = self._Mktmp('pid_file')
58 self.process = None 63 self.process = None
59 64
60 def _Mktmp(self, name): 65 def _Mktmp(self, name):
61 return os.path.join(self.temp_dir, name) 66 return os.path.join(self.temp_dir, name)
62 67
63 def _GetRandomPort(self): 68 def _GetRandomPort(self):
64 # Ports 8001-8004 are reserved for other test servers. Ensure we don't 69 # The ports of test server is arranged in constants.py.
65 # collide with them. 70 return random.randint(constants.LIGHTTPD_RANDOM_PORT_FIRST,
66 return random.randint(8005, 8999) 71 constants.LIGHTTPD_RANDOM_PORT_LAST)
67 72
68 def StartupHttpServer(self): 73 def StartupHttpServer(self):
69 """Starts up a http server with specified document root and port.""" 74 """Starts up a http server with specified document root and port."""
70 # Currently we use lighttpd as http sever in test. 75 # If we want a specific port, make sure no one else is listening on it.
76 if self.fixed_port:
77 self._KillProcessListeningOnPort(self.fixed_port)
71 while True: 78 while True:
72 if self.base_config_path: 79 if self.base_config_path:
73 # Read the config 80 # Read the config
74 with codecs.open(self.base_config_path, 'r', 'utf-8') as f: 81 with codecs.open(self.base_config_path, 'r', 'utf-8') as f:
75 config_contents = f.read() 82 config_contents = f.read()
76 else: 83 else:
77 config_contents = self._GetDefaultBaseConfig() 84 config_contents = self._GetDefaultBaseConfig()
78 if self.extra_config_contents: 85 if self.extra_config_contents:
79 config_contents += self.extra_config_contents 86 config_contents += self.extra_config_contents
80 # Write out the config, filling in placeholders from the members of |self| 87 # Write out the config, filling in placeholders from the members of |self|
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 # Check for server startup error messages 139 # Check for server startup error messages
133 ix = self.process.expect([pexpect.TIMEOUT, pexpect.EOF, '.+'], 140 ix = self.process.expect([pexpect.TIMEOUT, pexpect.EOF, '.+'],
134 timeout=timeout) 141 timeout=timeout)
135 if ix == 2: # stdout spew from the server 142 if ix == 2: # stdout spew from the server
136 server_msg += self.process.match.group(0) 143 server_msg += self.process.match.group(0)
137 elif ix == 1: # EOF -- server has quit so giveup. 144 elif ix == 1: # EOF -- server has quit so giveup.
138 client_error = client_error or 'Server exited' 145 client_error = client_error or 'Server exited'
139 break 146 break
140 return (client_error or 'Timeout', server_msg) 147 return (client_error or 'Timeout', server_msg)
141 148
149 def _KillProcessListeningOnPort(self, port):
150 """Checks if there is a process listening on port number |port| and
151 terminates it if found.
152
153 Args:
154 port: Port number to check.
155 """
156 if subprocess.call(['fuser', '-kv', '%d/tcp' % port]) == 0:
157 # Give the process some time to terminate and check that it is gone.
158 time.sleep(2)
159 assert subprocess.call(['fuser', '-v', '%d/tcp' % port]) != 0, \
160 'Unable to kill process listening on port %d.' % port
161
142 def _GetDefaultBaseConfig(self): 162 def _GetDefaultBaseConfig(self):
143 return """server.tag = "%(server_tag)s" 163 return """server.tag = "%(server_tag)s"
144 server.modules = ( "mod_access", 164 server.modules = ( "mod_access",
145 "mod_accesslog", 165 "mod_accesslog",
146 "mod_alias", 166 "mod_alias",
147 "mod_cgi", 167 "mod_cgi",
148 "mod_rewrite" ) 168 "mod_rewrite" )
149 169
150 # default document root required 170 # default document root required
151 #server.document-root = "." 171 #server.document-root = "."
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 raw_input('Server running at http://127.0.0.1:%s -' 245 raw_input('Server running at http://127.0.0.1:%s -'
226 ' press Enter to exit it.' % server.port) 246 ' press Enter to exit it.' % server.port)
227 else: 247 else:
228 print 'Server exit code:', server.process.exitstatus 248 print 'Server exit code:', server.process.exitstatus
229 finally: 249 finally:
230 server.ShutdownHttpServer() 250 server.ShutdownHttpServer()
231 251
232 252
233 if __name__ == '__main__': 253 if __name__ == '__main__':
234 sys.exit(main(sys.argv)) 254 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « build/android/enable_asserts.py ('k') | build/android/pylib/android_commands.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698