Index: webkit/tools/layout_tests/layout_package/apache_http_server.py |
=================================================================== |
--- webkit/tools/layout_tests/layout_package/apache_http_server.py (revision 0) |
+++ webkit/tools/layout_tests/layout_package/apache_http_server.py (revision 0) |
@@ -0,0 +1,143 @@ |
+# Copyright (c) 2009 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+"""A class to start/stop the apache http server used by layout tests.""" |
+ |
+import logging |
+import optparse |
+import os |
+import subprocess |
+import sys |
+import time |
+ |
+import google.httpd_utils |
+ |
+import path_utils |
+import platform_utils |
+ |
+class LayoutTestApacheHttpd(object): |
+ _PORTS = [ |
+ {'port': 8000}, |
+ {'port': 8080}, |
+ {'port': 8443, 'is_ssl': True} |
+ ] |
+ |
+ def __init__(self, output_dir): |
+ """Args: |
+ output_dir: the absolute path to the layout test result directory |
+ """ |
+ self._output_dir = output_dir |
+ self._httpd_proc = None |
+ path_utils.MaybeMakeDirectory(output_dir) |
+ |
+ # The upstream .conf file assumed the existence of /tmp/WebKit for placing |
+ # apache files like the lock file there. |
+ path_utils.MaybeMakeDirectory(os.path.join("/tmp", "WebKit")) |
+ |
+ test_dir = path_utils.PathFromBase('third_party', 'WebKit', |
+ 'LayoutTests') |
+ js_test_resources_dir = os.path.join(test_dir, "fast", "js", "resources") |
+ mime_types_path = os.path.join(test_dir, "http", "conf", "mime.types") |
+ cert_file = os.path.join(test_dir, "http", "conf", "webkit-httpd.pem") |
+ |
+ cmd = [os.path.join("/usr", "sbin", "httpd"), |
+ '-f', self._GetApacheConfigFilePath(test_dir, output_dir), |
+ '-C', "DocumentRoot %s" % os.path.join(test_dir, "http", "tests"), |
+ '-c', "Alias /js-test-resources %s" % js_test_resources_dir, |
+ '-C', "Listen %s" % "127.0.0.1:8000", |
+ '-C', "Listen %s" % "127.0.0.1:8081", |
+ '-c', "TypesConfig \"%s\"" % mime_types_path, |
+ '-c', "CustomLog \"%s/access_log.txt\" common" % output_dir, |
+ '-c', "ErrorLog \"%s/error_log.txt\"" % output_dir, |
+ '-C', "User \"%s\"" % os.environ.get("USERNAME", |
+ os.environ.get("USER", "")), |
+ '-c', "SSLCertificateFile %s" % cert_file, |
+ ] |
+ |
+ self._start_cmd = cmd |
+ |
+ def _GetApacheConfigFilePath(self, test_dir, output_dir): |
+ """Returns the path to the apache config file to use. |
+ Args: |
+ test_dir: absolute path to the LayoutTests directory. |
+ output_dir: absolute path to the layout test results directory. |
+ """ |
+ conf_file_name = "apache2-httpd.conf" |
+ httpd_config = os.path.join(test_dir, "http", "conf", conf_file_name) |
+ httpd_config_copy = os.path.join(output_dir, conf_file_name) |
+ main_document_root = os.path.join(path_utils.LayoutTestsDir(), |
+ "LayoutTests", "http", "tests") |
+ chrome_document_root = path_utils.PathFromBase('webkit', 'data', |
+ 'layout_tests') |
+ httpd_conf = open(httpd_config).read() |
+ # TODO(ojan): Instead of writing an extra file, checkin a conf file |
+ # upstream. Or, even better, upstream/delete all our chrome http tests so we |
+ # don't need this special-cased DocumentRoot and then just use the upstream |
+ # conf file. |
+ httpd_conf = (httpd_conf + |
+ self._GetVirtualHostConfig(chrome_document_root, 8081)) |
+ |
+ f = open(httpd_config_copy, 'wb') |
+ f.write(httpd_conf) |
+ f.close() |
+ |
+ return httpd_config_copy |
+ |
+ def _GetVirtualHostConfig(self, document_root, port, ssl=False): |
+ """Returns a <VirtualHost> directive block for an httpd.conf file. It will |
+ listen to 127.0.0.1 on each of the given port. |
+ """ |
+ return '\n'.join(('<VirtualHost 127.0.0.1:%s>' % port, |
+ 'DocumentRoot %s' % document_root, |
+ ssl and 'SSLEngine On' or '', |
+ '</VirtualHost>', '')) |
+ |
+ def _IsServerRunningOnAllPorts(self): |
+ """Returns whether the server is running on all the desired ports.""" |
+ for mapping in self._PORTS: |
+ url = 'http%s://127.0.0.1:%d/' % ('is_ssl' in mapping and 's' or '', |
+ mapping['port']) |
+ if not google.httpd_utils.UrlIsAlive(url): |
+ return False |
+ |
+ return True |
+ |
+ def _StartHttpdProcess(self): |
+ """Starts the httpd process and returns whether there were errors.""" |
+ self._httpd_proc = subprocess.Popen(self._start_cmd, stderr=subprocess.PIPE) |
+ if len(self._httpd_proc.stderr.read()): |
+ return False |
+ return True |
+ |
+ def _WaitForAction(self, action): |
+ """Repeat the action for 20 seconds or until it succeeds. Returns whether |
+ it succeeded.""" |
+ succeeded = False |
+ |
+ start_time = time.time() |
+ # Give apache up to 20 seconds to start up. |
+ while time.time() - start_time < 20 and not succeeded: |
+ succeeded = action() |
tony
2009/11/25 21:45:30
Nit: There should still probably be some sleep her
|
+ |
+ return succeeded |
+ |
+ def Start(self): |
+ """Starts the apache http server.""" |
+ # Stop any currently running servers. |
+ self.Stop() |
+ |
+ logging.debug("Starting apache http server") |
+ server_started = self._WaitForAction(self._StartHttpdProcess) |
+ if server_started: |
+ server_started = self._WaitForAction(self._IsServerRunningOnAllPorts) |
+ |
+ if server_started: |
+ logging.debug("Server successfully started") |
+ else: |
+ raise google.httpd_utils.HttpdNotStarted('Failed to start httpd') |
+ |
+ def Stop(self): |
+ """Stops the apache http server.""" |
+ logging.debug("Shutting down any running http servers") |
+ path_utils.ShutDownHTTPServer(self._httpd_proc) |
Property changes on: webkit/tools/layout_tests/layout_package/apache_http_server.py |
___________________________________________________________________ |
Name: svn:eol-style |
+ LF |