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