Title: [120846] trunk/Tools
Revision
120846
Author
[email protected]
Date
2012-06-20 12:00:48 -0700 (Wed, 20 Jun 2012)

Log Message

new-run-webkit-tests should spin-up enough httpd processes to avoid timeouts
https://bugs.webkit.org/show_bug.cgi?id=88134

Reviewed by Tony Chang.

Change NRWT to spin up 2*min(child_processes, locked_shards)
http servers by default so that we are less likely to get a
bunch of http timeouts at the beginning of a test run.

Note that I had to tweak executive_mock to support mocked stderr
because the apache_http_server code reads stderr when starting a
process to ensure it started okay.

* Scripts/webkitpy/common/system/executive_mock.py:
(MockProcess.__init__):
* Scripts/webkitpy/common/system/outputcapture.py:
* Scripts/webkitpy/layout_tests/controllers/manager.py:
(Manager._run_tests):
(Manager.start_servers_with_lock):
* Scripts/webkitpy/layout_tests/port/base.py:
(Port.to.start_http_server):
* Scripts/webkitpy/layout_tests/port/test.py:
(TestPort.start_http_server):
(TestPort._path_to_apache):
(TestPort):
(TestPort._path_to_apache_config_file):
* Scripts/webkitpy/layout_tests/servers/apache_http_server.py:
(LayoutTestApacheHttpd.__init__):
* Scripts/webkitpy/layout_tests/servers/apache_http_server_unittest.py: Added
(LayoutTestApacheHttpd.__init__):
* Scripts/webkitpy/layout_tests/servers/http_server.py:
(Lighttpd.__init__):
* Scripts/webkitpy/layout_tests/servers/http_server_base.py:
(HttpServerBase.__init__):

Modified Paths

Added Paths

Diff

Modified: trunk/Tools/ChangeLog (120845 => 120846)


--- trunk/Tools/ChangeLog	2012-06-20 18:42:51 UTC (rev 120845)
+++ trunk/Tools/ChangeLog	2012-06-20 19:00:48 UTC (rev 120846)
@@ -1,3 +1,40 @@
+2012-06-18  Dirk Pranke  <[email protected]>
+
+        new-run-webkit-tests should spin-up enough httpd processes to avoid timeouts
+        https://bugs.webkit.org/show_bug.cgi?id=88134
+
+        Reviewed by Tony Chang.
+
+        Change NRWT to spin up 2*min(child_processes, locked_shards)
+        http servers by default so that we are less likely to get a
+        bunch of http timeouts at the beginning of a test run.
+
+        Note that I had to tweak executive_mock to support mocked stderr
+        because the apache_http_server code reads stderr when starting a
+        process to ensure it started okay.
+
+        * Scripts/webkitpy/common/system/executive_mock.py:
+        (MockProcess.__init__):
+        * Scripts/webkitpy/common/system/outputcapture.py:
+        * Scripts/webkitpy/layout_tests/controllers/manager.py:
+        (Manager._run_tests):
+        (Manager.start_servers_with_lock):
+        * Scripts/webkitpy/layout_tests/port/base.py:
+        (Port.to.start_http_server):
+        * Scripts/webkitpy/layout_tests/port/test.py:
+        (TestPort.start_http_server):
+        (TestPort._path_to_apache):
+        (TestPort):
+        (TestPort._path_to_apache_config_file):
+        * Scripts/webkitpy/layout_tests/servers/apache_http_server.py:
+        (LayoutTestApacheHttpd.__init__):
+        * Scripts/webkitpy/layout_tests/servers/apache_http_server_unittest.py: Added
+        (LayoutTestApacheHttpd.__init__):
+        * Scripts/webkitpy/layout_tests/servers/http_server.py:
+        (Lighttpd.__init__):
+        * Scripts/webkitpy/layout_tests/servers/http_server_base.py:
+        (HttpServerBase.__init__):
+
 2012-06-20  Tom Zakrajsek  <[email protected]>
 
         Unreviewed: Back out accidentally checked in debug print which broke a test

Modified: trunk/Tools/Scripts/webkitpy/common/system/executive_mock.py (120845 => 120846)


--- trunk/Tools/Scripts/webkitpy/common/system/executive_mock.py	2012-06-20 18:42:51 UTC (rev 120845)
+++ trunk/Tools/Scripts/webkitpy/common/system/executive_mock.py	2012-06-20 19:00:48 UTC (rev 120846)
@@ -34,10 +34,12 @@
 
 
 class MockProcess(object):
-    def __init__(self, stdout='MOCK STDOUT\n'):
+    def __init__(self, stdout='MOCK STDOUT\n', stderr=''):
         self.pid = 42
         self.stdout = StringIO.StringIO(stdout)
+        self.stderr = StringIO.StringIO(stderr)
         self.stdin = StringIO.StringIO()
+        self.returncode = 0
 
     def wait(self):
         return

Modified: trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py (120845 => 120846)


--- trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py	2012-06-20 18:42:51 UTC (rev 120845)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py	2012-06-20 19:00:48 UTC (rev 120846)
@@ -765,8 +765,8 @@
 
         all_shards = locked_shards + unlocked_shards
         self._remaining_locked_shards = locked_shards
-        if self._options.http and (self._http_tests() or self._websocket_tests()):
-            self.start_servers_with_lock()
+        if locked_shards and self._options.http:
+            self.start_servers_with_lock(2 * min(num_workers, len(locked_shards)))
 
         num_workers = min(num_workers, len(all_shards))
         self._log_num_workers(num_workers, len(all_shards), len(locked_shards))
@@ -969,12 +969,12 @@
 
         return self._port.exit_code_from_summarized_results(unexpected_results)
 
-    def start_servers_with_lock(self):
+    def start_servers_with_lock(self, number_of_servers):
         self._printer.print_update('Acquiring http lock ...')
         self._port.acquire_http_lock()
         if self._http_tests():
             self._printer.print_update('Starting HTTP server ...')
-            self._port.start_http_server()
+            self._port.start_http_server(number_of_servers=number_of_servers)
         if self._websocket_tests():
             self._printer.print_update('Starting WebSocket server ...')
             self._port.start_websocket_server()

Modified: trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py (120845 => 120846)


--- trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py	2012-06-20 18:42:51 UTC (rev 120845)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py	2012-06-20 19:00:48 UTC (rev 120846)
@@ -344,7 +344,7 @@
 
     def test_servers_started(self):
 
-        def start_http_server():
+        def start_http_server(number_of_servers=None):
             self.http_started = True
 
         def start_websocket_server():
@@ -366,7 +366,7 @@
         self.http_started = self.http_stopped = self.websocket_started = self.websocket_stopped = False
         manager = Manager(port=port, options=MockOptions(http=True), printer=Mock())
         manager._test_files = ['http/tests/pass.txt']
-        manager.start_servers_with_lock()
+        manager.start_servers_with_lock(number_of_servers=4)
         self.assertEquals(self.http_started, True)
         self.assertEquals(self.websocket_started, False)
         manager.stop_servers_with_lock()
@@ -376,7 +376,7 @@
         self.http_started = self.http_stopped = self.websocket_started = self.websocket_stopped = False
         manager = Manager(port=port, options=MockOptions(http=True), printer=Mock())
         manager._test_files = ['websocket/pass.txt']
-        manager.start_servers_with_lock()
+        manager.start_servers_with_lock(number_of_servers=4)
         self.assertEquals(self.http_started, True)
         self.assertEquals(self.websocket_started, True)
         manager.stop_servers_with_lock()
@@ -386,7 +386,7 @@
         self.http_started = self.http_stopped = self.websocket_started = self.websocket_stopped = False
         manager = Manager(port=port, options=MockOptions(http=True), printer=Mock())
         manager._test_files = ['perf/foo/test.html']
-        manager.start_servers_with_lock()
+        manager.start_servers_with_lock(number_of_servers=4)
         self.assertEquals(self.http_started, False)
         self.assertEquals(self.websocket_started, False)
         manager.stop_servers_with_lock()

Modified: trunk/Tools/Scripts/webkitpy/layout_tests/port/base.py (120845 => 120846)


--- trunk/Tools/Scripts/webkitpy/layout_tests/port/base.py	2012-06-20 18:42:51 UTC (rev 120845)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/port/base.py	2012-06-20 19:00:48 UTC (rev 120846)
@@ -786,16 +786,16 @@
         method."""
         pass
 
-    def start_http_server(self, additional_dirs=None):
+    def start_http_server(self, additional_dirs=None, number_of_servers=None):
         """Start a web server. Raise an error if it can't start or is already running.
 
         Ports can stub this out if they don't need a web server to be running."""
         assert not self._http_server, 'Already running an http server.'
 
         if self._uses_apache():
-            server = apache_http_server.LayoutTestApacheHttpd(self, self.results_directory(), additional_dirs=additional_dirs)
+            server = apache_http_server.LayoutTestApacheHttpd(self, self.results_directory(), additional_dirs=additional_dirs, number_of_servers=number_of_servers)
         else:
-            server = http_server.Lighttpd(self, self.results_directory(), additional_dirs=additional_dirs)
+            server = http_server.Lighttpd(self, self.results_directory(), additional_dirs=additional_dirs, num_servers=num_servers)
 
         server.start()
         self._http_server = server

Modified: trunk/Tools/Scripts/webkitpy/layout_tests/port/test.py (120845 => 120846)


--- trunk/Tools/Scripts/webkitpy/layout_tests/port/test.py	2012-06-20 18:42:51 UTC (rev 120845)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/port/test.py	2012-06-20 19:00:48 UTC (rev 120846)
@@ -428,7 +428,7 @@
     def _driver_class(self):
         return TestDriver
 
-    def start_http_server(self):
+    def start_http_server(self, additional_dirs=None, number_of_servers=None):
         pass
 
     def start_websocket_server(self):
@@ -455,6 +455,12 @@
     def _path_to_lighttpd_php(self):
         return "/usr/bin/php-cgi"
 
+    def _path_to_apache(self):
+        return "/usr/sbin/httpd"
+
+    def _path_to_apache_config_file(self):
+        return self._filesystem.join(self.layout_tests_dir(), 'http', 'conf', 'httpd.conf')
+
     def path_to_test_expectations_file(self):
         return self._expectations_path
 

Modified: trunk/Tools/Scripts/webkitpy/layout_tests/servers/apache_http_server.py (120845 => 120846)


--- trunk/Tools/Scripts/webkitpy/layout_tests/servers/apache_http_server.py	2012-06-20 18:42:51 UTC (rev 120845)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/servers/apache_http_server.py	2012-06-20 19:00:48 UTC (rev 120846)
@@ -43,12 +43,12 @@
 
 class LayoutTestApacheHttpd(http_server_base.HttpServerBase):
 
-    def __init__(self, port_obj, output_dir, additional_dirs=None):
+    def __init__(self, port_obj, output_dir, additional_dirs=None, number_of_servers=None):
         """Args:
           port_obj: handle to the platform-specific routines
           output_dir: the absolute path to the layout test result directory
         """
-        http_server_base.HttpServerBase.__init__(self, port_obj)
+        http_server_base.HttpServerBase.__init__(self, port_obj, number_of_servers)
         # We use the name "httpd" instead of "apache" to make our paths (e.g. the pid file: /tmp/WebKit/httpd.pid)
         # match old-run-webkit-tests: https://bugs.webkit.org/show_bug.cgi?id=63956
         self._name = 'httpd'
@@ -95,6 +95,12 @@
                         '-c', "\'RemoveHandler .cgi .pl\'",
                         '-c', "\'</Location>\'"]
 
+        if self._number_of_servers:
+            start_cmd += ['-c', "\'StartServers %d\'" % self._number_of_servers,
+                          '-c', "\'MinSpareServers %d\'" % self._number_of_servers,
+                          '-c', "\'MaxSpareServers %d\'" % self._number_of_servers]
+
+
         stop_cmd = [executable,
             '-f', "\"%s\"" % self._get_apache_config_file_path(test_dir, output_dir),
             '-c', "\'PidFile %s'" % self._pid_file,

Added: trunk/Tools/Scripts/webkitpy/layout_tests/servers/apache_http_server_unittest.py (0 => 120846)


--- trunk/Tools/Scripts/webkitpy/layout_tests/servers/apache_http_server_unittest.py	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/servers/apache_http_server_unittest.py	2012-06-20 19:00:48 UTC (rev 120846)
@@ -0,0 +1,70 @@
+# Copyright (C) 2012 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import unittest
+import re
+import sys
+
+from webkitpy.common.system.executive_mock import MockExecutive
+from webkitpy.common.system.outputcapture import OutputCapture
+from webkitpy.common.host_mock import MockHost
+from webkitpy.layout_tests.port import test
+from webkitpy.layout_tests.servers.apache_http_server import LayoutTestApacheHttpd
+from webkitpy.layout_tests.servers.http_server_base import ServerError
+
+
+class TestLayoutTestApacheHttpd(unittest.TestCase):
+    def test_start_cmd(self):
+        # Fails on win - see https://bugs.webkit.org/show_bug.cgi?id=84726
+        if sys.platform in ('cygwin', 'win32'):
+            return
+
+        def fake_pid(_):
+            host.filesystem.write_text_file('/tmp/WebKit/httpd.pid', '42')
+            return True
+
+        host = MockHost()
+        host.executive = MockExecutive(should_log=True)
+        test_port = test.TestPort(host)
+        host.filesystem.write_text_file(test_port._path_to_apache_config_file(), '')
+
+        server = LayoutTestApacheHttpd(test_port, "/mock/output_dir", number_of_servers=4)
+        server._check_that_all_ports_are_available = lambda: True
+        server._is_server_running_on_all_ports = lambda: True
+        server._wait_for_action = fake_pid
+        oc = OutputCapture()
+        try:
+            oc.capture_output()
+            server.start()
+            server.stop()
+        finally:
+            out, err, logs = oc.restore_output()
+        self.assertTrue("StartServers 4" in err)
+        self.assertTrue("MinSpareServers 4" in err)
+        self.assertTrue("MaxSpareServers 4" in err)
+        self.assertTrue(host.filesystem.exists("/mock/output_dir/httpd.conf"))

Modified: trunk/Tools/Scripts/webkitpy/layout_tests/servers/http_server.py (120845 => 120846)


--- trunk/Tools/Scripts/webkitpy/layout_tests/servers/http_server.py	2012-06-20 18:42:51 UTC (rev 120845)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/servers/http_server.py	2012-06-20 19:00:48 UTC (rev 120846)
@@ -43,12 +43,12 @@
 
     def __init__(self, port_obj, output_dir, background="" port=None,
                  root=None, run_background=None, additional_dirs=None,
-                 layout_tests_dir=None):
+                 layout_tests_dir=None, num_servers=None):
         """Args:
           output_dir: the absolute path to the layout test result directory
         """
         # Webkit tests
-        http_server_base.HttpServerBase.__init__(self, port_obj)
+        http_server_base.HttpServerBase.__init__(self, port_obj, num_servers)
         self._name = 'lighttpd'
         self._output_dir = output_dir
         self._port = port

Modified: trunk/Tools/Scripts/webkitpy/layout_tests/servers/http_server_base.py (120845 => 120846)


--- trunk/Tools/Scripts/webkitpy/layout_tests/servers/http_server_base.py	2012-06-20 18:42:51 UTC (rev 120845)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/servers/http_server_base.py	2012-06-20 19:00:48 UTC (rev 120846)
@@ -47,7 +47,7 @@
 class HttpServerBase(object):
     """A skeleton class for starting and stopping servers used by the layout tests."""
 
-    def __init__(self, port_obj):
+    def __init__(self, port_obj, number_of_servers=None):
         self._executive = port_obj._executive
         self._filesystem = port_obj._filesystem
         self._name = '<virtual>'
@@ -55,6 +55,7 @@
         self._pid = None
         self._pid_file = None
         self._port_obj = port_obj
+        self._number_of_servers = number_of_servers
 
         # We need a non-checkout-dependent place to put lock files, etc. We
         # don't use the Python default on the Mac because it defaults to a
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to