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

Side by Side Diff: build/android/lighttpd_server.py

Issue 8364020: Upstream: Test scripts for Android (phase 2) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sync again Created 9 years, 2 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
OLDNEW
(Empty)
1 #!/usr/bin/python
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 """Provides a convenient wrapper for spawning a test lighttpd instance.
7
8 Usage:
9 lighttpd_server PATH_TO_DOC_ROOT
10 """
11
12 import codecs
13 import contextlib
14 import httplib
15 import os
16 import pexpect
17 import random
18 import shutil
19 import socket
20 import sys
21 import tempfile
22
23
24 class LighttpdServer(object):
25 """Wraps lighttpd server, providing robust startup.
26
27 Args:
28 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
30 ommitted it will attempt to use 9000, or if unavailable it will find
31 a free port from 8001 - 8999.
32 lighttpd_path, lighttpd_module_path: Optional paths to lighttpd binaries.
33 base_config_path: If supplied this file will replace the built-in default
34 lighttpd config file.
35 extra_config_contents: If specified, this string will be appended to the
36 base config (default built-in, or from base_config_path).
37 config_path, error_log, access_log: Optional paths where the class should
38 place temprary files for this session.
39 """
40
41 def __init__(self, document_root, port=None,
42 lighttpd_path=None, lighttpd_module_path=None,
43 base_config_path=None, extra_config_contents=None,
44 config_path=None, error_log=None, access_log=None):
45 self.temp_dir = tempfile.mkdtemp(prefix='lighttpd_for_chrome_android')
46 self.document_root = os.path.abspath(document_root)
47 self.fixed_port = port
48 self.port = port or 9000
49 self.server_tag = 'LightTPD ' + str(random.randint(111111, 999999))
50 self.lighttpd_path = lighttpd_path or '/usr/sbin/lighttpd'
51 self.lighttpd_module_path = lighttpd_module_path or '/usr/lib/lighttpd'
52 self.base_config_path = base_config_path
53 self.extra_config_contents = extra_config_contents
54 self.config_path = config_path or self._Mktmp('config')
55 self.error_log = error_log or self._Mktmp('error_log')
56 self.access_log = access_log or self._Mktmp('access_log')
57 self.pid_file = self._Mktmp('pid_file')
58 self.process = None
59
60 def _Mktmp(self, name):
61 return os.path.join(self.temp_dir, name)
62
63 def _GetRandomPort(self):
64 # Ports 8001-8004 are reserved for other test servers. Ensure we don't
65 # collide with them.
66 return random.randint(8005, 8999)
67
68 def StartupHttpServer(self):
69 """Starts up a http server with specified document root and port."""
70 # Currently we use lighttpd as http sever in test.
71 while True:
72 if self.base_config_path:
73 # Read the config
74 with codecs.open(self.base_config_path, 'r', 'utf-8') as f:
75 config_contents = f.read()
76 else:
77 config_contents = self._GetDefaultBaseConfig()
78 if self.extra_config_contents:
79 config_contents += self.extra_config_contents
80 # Write out the config, filling in placeholders from the members of |self|
81 with codecs.open(self.config_path, 'w', 'utf-8') as f:
82 f.write(config_contents % self.__dict__)
83 if (not os.path.exists(self.lighttpd_path) or
84 not os.access(self.lighttpd_path, os.X_OK)):
85 raise EnvironmentError(
86 'Could not find lighttpd at %s.\n'
87 'It may need to be installed (e.g. sudo apt-get install lighttpd)'
88 % self.lighttpd_path)
89 self.process = pexpect.spawn(self.lighttpd_path,
90 ['-D', '-f', self.config_path,
91 '-m', self.lighttpd_module_path],
92 cwd=self.temp_dir)
93 client_error, server_error = self._TestServerConnection()
94 if not client_error:
95 assert int(open(self.pid_file, 'r').read()) == self.process.pid
96 break
97 self.process.close()
98
99 if self.fixed_port or not 'in use' in server_error:
100 print 'Client error:', client_error
101 print 'Server error:', server_error
102 return False
103 self.port = self._GetRandomPort()
104 return True
105
106 def ShutdownHttpServer(self):
107 """Shuts down our lighttpd processes."""
108 if self.process:
109 self.process.terminate()
110 shutil.rmtree(self.temp_dir, ignore_errors=True)
111
112 def _TestServerConnection(self):
113 # Wait for server to start
114 server_msg = ''
115 for timeout in xrange(1, 5):
116 client_error = None
117 try:
118 with contextlib.closing(httplib.HTTPConnection(
119 '127.0.0.1', self.port, timeout=timeout)) as http:
120 http.set_debuglevel(timeout > 3)
121 http.request('HEAD', '/')
122 r = http.getresponse()
123 r.read()
124 if (r.status == 200 and r.reason == 'OK' and
125 r.getheader('Server') == self.server_tag):
126 return (None, server_msg)
127 client_error = ('Bad response: %s %s version %s\n ' %
128 (r.status, r.reason, r.version) +
129 '\n '.join([': '.join(h) for h in r.getheaders()]))
130 except (httplib.HTTPException, socket.error) as client_error:
131 pass # Probably too quick connecting: try again
132 # Check for server startup error messages
133 ix = self.process.expect([pexpect.TIMEOUT, pexpect.EOF, '.+'],
134 timeout=timeout)
135 if ix == 2: # stdout spew from the server
136 server_msg += self.process.match.group(0)
137 elif ix == 1: # EOF -- server has quit so giveup.
138 client_error = client_error or 'Server exited'
139 break
140 return (client_error or 'Timeout', server_msg)
141
142 def _GetDefaultBaseConfig(self):
143 return """server.tag = "%(server_tag)s"
144 server.modules = ( "mod_access",
145 "mod_accesslog",
146 "mod_alias",
147 "mod_cgi",
148 "mod_rewrite" )
149
150 # default document root required
151 #server.document-root = "."
152
153 # files to check for if .../ is requested
154 index-file.names = ( "index.php", "index.pl", "index.cgi",
155 "index.html", "index.htm", "default.htm" )
156 # mimetype mapping
157 mimetype.assign = (
158 ".gif" => "image/gif",
159 ".jpg" => "image/jpeg",
160 ".jpeg" => "image/jpeg",
161 ".png" => "image/png",
162 ".svg" => "image/svg+xml",
163 ".css" => "text/css",
164 ".html" => "text/html",
165 ".htm" => "text/html",
166 ".xhtml" => "application/xhtml+xml",
167 ".xhtmlmp" => "application/vnd.wap.xhtml+xml",
168 ".js" => "application/x-javascript",
169 ".log" => "text/plain",
170 ".conf" => "text/plain",
171 ".text" => "text/plain",
172 ".txt" => "text/plain",
173 ".dtd" => "text/xml",
174 ".xml" => "text/xml",
175 ".manifest" => "text/cache-manifest",
176 )
177
178 # Use the "Content-Type" extended attribute to obtain mime type if possible
179 mimetype.use-xattr = "enable"
180
181 ##
182 # which extensions should not be handle via static-file transfer
183 #
184 # .php, .pl, .fcgi are most often handled by mod_fastcgi or mod_cgi
185 static-file.exclude-extensions = ( ".php", ".pl", ".cgi" )
186
187 server.bind = "127.0.0.1"
188 server.port = %(port)s
189
190 ## virtual directory listings
191 dir-listing.activate = "enable"
192 #dir-listing.encoding = "iso-8859-2"
193 #dir-listing.external-css = "style/oldstyle.css"
194
195 ## enable debugging
196 #debug.log-request-header = "enable"
197 #debug.log-response-header = "enable"
198 #debug.log-request-handling = "enable"
199 #debug.log-file-not-found = "enable"
200
201 #### SSL engine
202 #ssl.engine = "enable"
203 #ssl.pemfile = "server.pem"
204
205 # Autogenerated test-specific config follows.
206
207 cgi.assign = ( ".cgi" => "/usr/bin/env",
208 ".pl" => "/usr/bin/env",
209 ".asis" => "/bin/cat",
210 ".php" => "/usr/bin/php-cgi" )
211
212 server.errorlog = "%(error_log)s"
213 accesslog.filename = "%(access_log)s"
214 server.upload-dirs = ( "/tmp" )
215 server.pid-file = "%(pid_file)s"
216 server.document-root = "%(document_root)s"
217
218 """
219
220
221 def main(argv):
222 server = LighttpdServer(*argv[1:])
223 try:
224 if server.StartupHttpServer():
225 raw_input('Server running at http://127.0.0.1:%s -'
226 ' press Enter to exit it.' % server.port)
227 else:
228 print 'Server exit code:', server.process.exitstatus
229 finally:
230 server.ShutdownHttpServer()
231
232
233 if __name__ == '__main__':
234 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « build/android/gtest_filter/base_unittests_emulator_additional_disabled ('k') | build/android/run_tests.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698