2010-04-28 Eric Seidel <eric@webkit.org>
[WebKit-https.git] / WebKitTools / Scripts / webkitpy / layout_tests / port / http_server.py
index b24b9c0..fbe47e3 100755 (executable)
@@ -29,7 +29,9 @@
 
 """A class to help start/stop the lighttpd server used by layout tests."""
 
+from __future__ import with_statement
 
+import codecs
 import logging
 import optparse
 import os
@@ -40,8 +42,11 @@ import tempfile
 import time
 import urllib
 
+import factory
 import http_server_base
 
+_log = logging.getLogger("webkitpy.layout_tests.port.http_server")
+
 
 class HttpdNotStarted(Exception):
     pass
@@ -66,13 +71,13 @@ class Lighttpd(http_server_base.HttpServerBase):
             self._port = int(self._port)
 
         try:
-            _webkit_tests = os.path.join(self._port_obj.layout_tests_dir(),
-                 'http', 'tests')
-            _webkit_tests = os.path.join(self._port_obj.layout_tests_dir(),
-                 'fast', 'js', 'resources')
+            self._webkit_tests = os.path.join(
+                self._port_obj.layout_tests_dir(), 'http', 'tests')
+            self._js_test_resource = os.path.join(
+                self._port_obj.layout_tests_dir(), 'fast', 'js', 'resources')
         except:
-            _webkit_tests = None
-            _js_test_resource = None
+            self._webkit_tests = None
+            self._js_test_resource = None
 
         # Self generated certificate for SSL server (for client cert get
         # <base-path>\chrome\test\data\ssl\certs\root_ca_cert.crt)
@@ -80,14 +85,14 @@ class Lighttpd(http_server_base.HttpServerBase):
             os.path.dirname(os.path.abspath(__file__)), 'httpd2.pem')
 
         # One mapping where we can get to everything
-        VIRTUALCONFIG = []
+        self.VIRTUALCONFIG = []
 
-        if _webkit_tests:
-            VIRTUALCONFIG.extend(
+        if self._webkit_tests:
+            self.VIRTUALCONFIG.extend(
                # Three mappings (one with SSL) for LayoutTests http tests
-               [{'port': 8000, 'docroot': _webkit_tests},
-                {'port': 8080, 'docroot': _webkit_tests},
-                {'port': 8443, 'docroot': _webkit_tests,
+               [{'port': 8000, 'docroot': self._webkit_tests},
+                {'port': 8080, 'docroot': self._webkit_tests},
+                {'port': 8443, 'docroot': self._webkit_tests,
                  'sslcert': self._pem_file}])
 
     def is_running(self):
@@ -97,9 +102,8 @@ class Lighttpd(http_server_base.HttpServerBase):
         if self.is_running():
             raise 'Lighttpd already running'
 
-        base_conf_file = self._port_obj.path_from_base('third_party',
-            'WebKitTools', 'Scripts', 'webkitpy', 'layout_tests',
-            'port', 'lighttpd.conf')
+        base_conf_file = self._port_obj.path_from_webkit_base('WebKitTools',
+            'Scripts', 'webkitpy', 'layout_tests', 'port', 'lighttpd.conf')
         out_conf_file = os.path.join(self._output_dir, 'lighttpd.conf')
         time_str = time.strftime("%d%b%Y-%H%M%S")
         access_file_name = "access.log-" + time_str + ".txt"
@@ -112,11 +116,14 @@ class Lighttpd(http_server_base.HttpServerBase):
         self.remove_log_files(self._output_dir, "error.log-")
 
         # Write out the config
-        f = file(base_conf_file, 'rb')
-        base_conf = f.read()
-        f.close()
-
-        f = file(out_conf_file, 'wb')
+        with codecs.open(base_conf_file, "r", "utf-8") as file:
+            base_conf = file.read()
+
+        # FIXME: This should be re-worked so that this block can
+        # use with open() instead of a manual file.close() call.
+        # lighttpd.conf files seem to be UTF-8 without BOM:
+        # http://redmine.lighttpd.net/issues/992
+        f = codecs.open(out_conf_file, "w", "utf-8")
         f.write(base_conf)
 
         # Write out our cgi handlers.  Run perl through env so that it
@@ -174,8 +181,7 @@ class Lighttpd(http_server_base.HttpServerBase):
         module_path = self._port_obj._path_to_lighttpd_modules()
         start_cmd = [executable,
                      # Newly written config file
-                     '-f', self._port_obj._path_from_base(self._output_dir,
-                                                         'lighttpd.conf'),
+                     '-f', os.path.join(self._output_dir, 'lighttpd.conf'),
                      # Where it can find its module dynamic libraries
                      '-m', module_path]
 
@@ -197,15 +203,18 @@ class Lighttpd(http_server_base.HttpServerBase):
         env = os.environ
         if sys.platform in ('cygwin', 'win32'):
             env['PATH'] = '%s;%s' % (
-                port.path_from_base('third_party', 'cygwin', 'bin'),
+                self._port_obj.path_from_chromium_base('third_party',
+                                                       'cygwin', 'bin'),
                 env['PATH'])
 
         if sys.platform == 'win32' and self._register_cygwin:
-            setup_mount = port.path_from_base('third_party', 'cygwin',
-                                                    'setup_mount.bat')
+            setup_mount = self._port_obj.path_from_chromium_base('third_party',
+                'cygwin', 'setup_mount.bat')
+            # FIXME: Should use Executive.run_command
             subprocess.Popen(setup_mount).wait()
 
-        logging.debug('Starting http server')
+        _log.debug('Starting http server')
+        # FIXME: Should use Executive.run_command
         self._process = subprocess.Popen(start_cmd, env=env)
 
         # Wait for server to start.
@@ -217,7 +226,7 @@ class Lighttpd(http_server_base.HttpServerBase):
         if not server_started or self._process.returncode != None:
             raise google.httpd_utils.HttpdNotStarted('Failed to start httpd.')
 
-        logging.debug("Server successfully started")
+        _log.debug("Server successfully started")
 
     # TODO(deanm): Find a nicer way to shutdown cleanly.  Our log files are
     # probably not being flushed, etc... why doesn't our python have os.kill ?
@@ -229,45 +238,10 @@ class Lighttpd(http_server_base.HttpServerBase):
         httpd_pid = None
         if self._process:
             httpd_pid = self._process.pid
-        port._shut_down_http_server(httpd_pid)
+        self._port_obj._shut_down_http_server(httpd_pid)
 
         if self._process:
+            # wait() is not threadsafe and can throw OSError due to:
+            # http://bugs.python.org/issue1731717
             self._process.wait()
             self._process = None
-
-if '__main__' == __name__:
-    # Provide some command line params for starting/stopping the http server
-    # manually. Also used in ui_tests to run http layout tests in a browser.
-    option_parser = optparse.OptionParser()
-    option_parser.add_option('-k', '--server',
-        help='Server action (start|stop)')
-    option_parser.add_option('-p', '--port',
-        help='Port to listen on (overrides layout test ports)')
-    option_parser.add_option('-r', '--root',
-        help='Absolute path to DocumentRoot (overrides layout test roots)')
-    option_parser.add_option('--register_cygwin', action="store_true",
-        dest="register_cygwin", help='Register Cygwin paths (on Win try bots)')
-    option_parser.add_option('--run_background', action="store_true",
-        dest="run_background",
-        help='Run on background (for running as UI test)')
-    options, args = option_parser.parse_args()
-
-    if not options.server:
-        print ('Usage: %s --server {start|stop} [--root=root_dir]'
-               ' [--port=port_number]' % sys.argv[0])
-    else:
-        if (options.root is None) and (options.port is not None):
-            # specifying root but not port means we want httpd on default
-            # set of ports that LayoutTest use, but pointing to a different
-            # source of tests. Specifying port but no root does not seem
-            # meaningful.
-            raise 'Specifying port requires also a root.'
-        httpd = Lighttpd(tempfile.gettempdir(),
-                         port=options.port,
-                         root=options.root,
-                         register_cygwin=options.register_cygwin,
-                         run_background=options.run_background)
-        if 'start' == options.server:
-            httpd.start()
-        else:
-            httpd.stop(force=True)