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

Side by Side Diff: webkit/tools/layout_tests/layout_package/apache_http_server.py

Issue 545145: Move the layout test scripts into a 'webkitpy' subdirectory in preparation... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: try to de-confuse svn and the try bots Created 10 years, 11 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 # Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 """A class to start/stop the apache http server used by layout tests."""
6
7 import logging
8 import optparse
9 import os
10 import re
11 import subprocess
12 import sys
13
14 import http_server_base
15 import path_utils
16 import platform_utils
17
18
19 class LayoutTestApacheHttpd(http_server_base.HttpServerBase):
20
21 def __init__(self, output_dir):
22 """Args:
23 output_dir: the absolute path to the layout test result directory
24 """
25 self._output_dir = output_dir
26 self._httpd_proc = None
27 path_utils.MaybeMakeDirectory(output_dir)
28
29 self.mappings = [{'port': 8000},
30 {'port': 8080},
31 {'port': 8081},
32 {'port': 8443, 'sslcert': True}]
33
34 # The upstream .conf file assumed the existence of /tmp/WebKit for
35 # placing apache files like the lock file there.
36 self._runtime_path = os.path.join("/tmp", "WebKit")
37 path_utils.MaybeMakeDirectory(self._runtime_path)
38
39 # The PID returned when Apache is started goes away (due to dropping
40 # privileges?). The proper controlling PID is written to a file in the
41 # apache runtime directory.
42 self._pid_file = os.path.join(self._runtime_path, 'httpd.pid')
43
44 test_dir = path_utils.PathFromBase('third_party', 'WebKit',
45 'LayoutTests')
46 js_test_resources_dir = self._CygwinSafeJoin(test_dir, "fast", "js",
47 "resources")
48 mime_types_path = self._CygwinSafeJoin(test_dir, "http", "conf",
49 "mime.types")
50 cert_file = self._CygwinSafeJoin(test_dir, "http", "conf",
51 "webkit-httpd.pem")
52 access_log = self._CygwinSafeJoin(output_dir, "access_log.txt")
53 error_log = self._CygwinSafeJoin(output_dir, "error_log.txt")
54 document_root = self._CygwinSafeJoin(test_dir, "http", "tests")
55
56 executable = platform_utils.ApacheExecutablePath()
57 if self._IsCygwin():
58 executable = self._GetCygwinPath(executable)
59
60 cmd = [executable,
61 '-f', self._GetApacheConfigFilePath(test_dir, output_dir),
62 '-C', "\'DocumentRoot %s\'" % document_root,
63 '-c', "\'Alias /js-test-resources %s\'" % js_test_resources_dir,
64 '-C', "\'Listen %s\'" % "127.0.0.1:8000",
65 '-C', "\'Listen %s\'" % "127.0.0.1:8081",
66 '-c', "\'TypesConfig \"%s\"\'" % mime_types_path,
67 '-c', "\'CustomLog \"%s\" common\'" % access_log,
68 '-c', "\'ErrorLog \"%s\"\'" % error_log,
69 '-C', "\'User \"%s\"\'" % os.environ.get("USERNAME",
70 os.environ.get("USER", ""))]
71
72 if self._IsCygwin():
73 cygbin = path_utils.PathFromBase('third_party', 'cygwin', 'bin')
74 # Not entirely sure why, but from cygwin we need to run the
75 # httpd command through bash.
76 self._start_cmd = [
77 os.path.join(cygbin, 'bash.exe'),
78 '-c',
79 'PATH=%s %s' % (self._GetCygwinPath(cygbin), " ".join(cmd)),
80 ]
81 else:
82 # TODO(ojan): When we get cygwin using Apache 2, use set the
83 # cert file for cygwin as well.
84 cmd.extend(['-c', "\'SSLCertificateFile %s\'" % cert_file])
85 # Join the string here so that Cygwin/Windows and Mac/Linux
86 # can use the same code. Otherwise, we could remove the single
87 # quotes above and keep cmd as a sequence.
88 self._start_cmd = " ".join(cmd)
89
90 def _IsCygwin(self):
91 return sys.platform in ("win32", "cygwin")
92
93 def _CygwinSafeJoin(self, *parts):
94 """Returns a platform appropriate path."""
95 path = os.path.join(*parts)
96 if self._IsCygwin():
97 return self._GetCygwinPath(path)
98 return path
99
100 def _GetCygwinPath(self, path):
101 """Convert a Windows path to a cygwin path.
102
103 The cygpath utility insists on converting paths that it thinks are
104 Cygwin root paths to what it thinks the correct roots are. So paths
105 such as "C:\b\slave\webkit-release\build\third_party\cygwin\bin"
106 are converted to plain "/usr/bin". To avoid this, we
107 do the conversion manually.
108
109 The path is expected to be an absolute path, on any drive.
110 """
111 drive_regexp = re.compile(r'([a-z]):[/\\]', re.IGNORECASE)
112
113 def LowerDrive(matchobj):
114 return '/cygdrive/%s/' % matchobj.group(1).lower()
115 path = drive_regexp.sub(LowerDrive, path)
116 return path.replace('\\', '/')
117
118 def _GetApacheConfigFilePath(self, test_dir, output_dir):
119 """Returns the path to the apache config file to use.
120 Args:
121 test_dir: absolute path to the LayoutTests directory.
122 output_dir: absolute path to the layout test results directory.
123 """
124 httpd_config = platform_utils.ApacheConfigFilePath()
125 httpd_config_copy = os.path.join(output_dir, "httpd.conf")
126 httpd_conf = open(httpd_config).read()
127 if self._IsCygwin():
128 # This is a gross hack, but it lets us use the upstream .conf file
129 # and our checked in cygwin. This tells the server the root
130 # directory to look in for .so modules. It will use this path
131 # plus the relative paths to the .so files listed in the .conf
132 # file. We have apache/cygwin checked into our tree so
133 # people don't have to install it into their cygwin.
134 cygusr = path_utils.PathFromBase('third_party', 'cygwin', 'usr')
135 httpd_conf = httpd_conf.replace('ServerRoot "/usr"',
136 'ServerRoot "%s"' % self._GetCygwinPath(cygusr))
137
138 # TODO(ojan): Instead of writing an extra file, checkin a conf file
139 # upstream. Or, even better, upstream/delete all our chrome http
140 # tests so we don't need this special-cased DocumentRoot and then
141 # just use the upstream
142 # conf file.
143 chrome_document_root = path_utils.PathFromBase('webkit', 'data',
144 'layout_tests')
145 if self._IsCygwin():
146 chrome_document_root = self._GetCygwinPath(chrome_document_root)
147 httpd_conf = (httpd_conf +
148 self._GetVirtualHostConfig(chrome_document_root, 8081))
149
150 f = open(httpd_config_copy, 'wb')
151 f.write(httpd_conf)
152 f.close()
153
154 if self._IsCygwin():
155 return self._GetCygwinPath(httpd_config_copy)
156 return httpd_config_copy
157
158 def _GetVirtualHostConfig(self, document_root, port, ssl=False):
159 """Returns a <VirtualHost> directive block for an httpd.conf file.
160 It will listen to 127.0.0.1 on each of the given port.
161 """
162 return '\n'.join(('<VirtualHost 127.0.0.1:%s>' % port,
163 'DocumentRoot %s' % document_root,
164 ssl and 'SSLEngine On' or '',
165 '</VirtualHost>', ''))
166
167 def _StartHttpdProcess(self):
168 """Starts the httpd process and returns whether there were errors."""
169 # Use shell=True because we join the arguments into a string for
170 # the sake of Window/Cygwin and it needs quoting that breaks
171 # shell=False.
172 self._httpd_proc = subprocess.Popen(self._start_cmd,
173 stderr=subprocess.PIPE,
174 shell=True)
175 err = self._httpd_proc.stderr.read()
176 if len(err):
177 logging.debug(err)
178 return False
179 return True
180
181 def Start(self):
182 """Starts the apache http server."""
183 # Stop any currently running servers.
184 self.Stop()
185
186 logging.debug("Starting apache http server")
187 server_started = self.WaitForAction(self._StartHttpdProcess)
188 if server_started:
189 logging.debug("Apache started. Testing ports")
190 server_started = self.WaitForAction(self.IsServerRunningOnAllPorts)
191
192 if server_started:
193 logging.debug("Server successfully started")
194 else:
195 raise Exception('Failed to start http server')
196
197 def Stop(self):
198 """Stops the apache http server."""
199 logging.debug("Shutting down any running http servers")
200 httpd_pid = None
201 if os.path.exists(self._pid_file):
202 httpd_pid = int(open(self._pid_file).readline())
203 path_utils.ShutDownHTTPServer(httpd_pid)
OLDNEW
« no previous file with comments | « webkit/tools/layout_tests/dedup-tests.py ('k') | webkit/tools/layout_tests/layout_package/failure.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698