<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[217276] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/217276">217276</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2017-05-23 08:56:12 -0700 (Tue, 23 May 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>There should be an easy way to run HTTP/WPT served tests on a browser
https://bugs.webkit.org/show_bug.cgi?id=172068

Patch by youenn fablet <youenn@apple.com> on 2017-05-23
Reviewed by Sam Weinig.

Tools:

Adding a new script open-layout-test to open a layout-test in a
browser and making sure it is served as done through run-webkit-tests.
In case tests should be run using a server, detecting whether the
server are running. If not, calling run-webkit-httpd to run the
servers and open the URL in a browser.
Otherwise, open directly the URL.

Adding an option in run-webkit-httpd to open an URL after having
started the servers.

Adding the --no-http-servers option in run-webkit-tests to not start any HTTP server.
This allows running run-webkit-httpd once and not having to restart
servers everytime a test should be served.

Moving most of run-webkit-httpd logic in its own python file to reuse
it in open-layout-test script.

Adding routines to check whether HTTP and WPT servers are running.

* Scripts/open-layout-test: Added.
(parse_args):
(main):
* Scripts/run-webkit-httpd:
(main):
* Scripts/webkitpy/layout_tests/controllers/layout_test_finder.py:
(LayoutTestFinder.find_tests):
* Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py:
(LayoutTestRunner.run_tests):
* Scripts/webkitpy/layout_tests/run_webkit_tests.py:
(parse_args):
* Scripts/webkitpy/layout_tests/servers/http_server_base.py:
(HttpServerBase._is_server_running_on_all_ports):
(HttpServerBase):
(HttpServerBase._is_running_on_port):
(HttpServerBase._check_that_all_ports_are_available):
(is_http_server_running):
* Scripts/webkitpy/layout_tests/servers/run_webkit_httpd.py: Copied from Tools/Scripts/run-webkit-httpd.
(parse_args):
(main):
(run_server):
* Scripts/webkitpy/layout_tests/servers/web_platform_test_server.py:
(is_wpt_server_running):
* Scripts/webkitpy/port/base.py:
(Port.to.is_http_server_running):
(Port.to):
(Port.to.is_wpt_server_running):
(Port.to.start_web_platform_test_server):
* Scripts/webkitpy/port/driver.py:
(DriverProxy.is_web_platform_test):
(DriverProxy):
(DriverProxy.is_webkit_specific_web_platform_test):

LayoutTests:

* fast/harness/results.html: In case results.html is opened locallly,
open HTTP/WPT urls as served by their related servers.
Adding a check that the servers are running before opening the related test.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsfastharnessresultshtml">trunk/LayoutTests/fast/harness/results.html</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsScriptsrunwebkithttpd">trunk/Tools/Scripts/run-webkit-httpd</a></li>
<li><a href="#trunkToolsScriptswebkitpylayout_testscontrollerslayout_test_finderpy">trunk/Tools/Scripts/webkitpy/layout_tests/controllers/layout_test_finder.py</a></li>
<li><a href="#trunkToolsScriptswebkitpylayout_testscontrollerslayout_test_runnerpy">trunk/Tools/Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py</a></li>
<li><a href="#trunkToolsScriptswebkitpylayout_testsrun_webkit_testspy">trunk/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py</a></li>
<li><a href="#trunkToolsScriptswebkitpylayout_testsservershttp_server_basepy">trunk/Tools/Scripts/webkitpy/layout_tests/servers/http_server_base.py</a></li>
<li><a href="#trunkToolsScriptswebkitpylayout_testsserversweb_platform_test_serverpy">trunk/Tools/Scripts/webkitpy/layout_tests/servers/web_platform_test_server.py</a></li>
<li><a href="#trunkToolsScriptswebkitpyportbasepy">trunk/Tools/Scripts/webkitpy/port/base.py</a></li>
<li><a href="#trunkToolsScriptswebkitpyportdriverpy">trunk/Tools/Scripts/webkitpy/port/driver.py</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkToolsScriptsopenlayouttest">trunk/Tools/Scripts/open-layout-test</a></li>
<li><a href="#trunkToolsScriptswebkitpylayout_testsserversrun_webkit_httpdpy">trunk/Tools/Scripts/webkitpy/layout_tests/servers/run_webkit_httpd.py</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (217275 => 217276)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2017-05-23 14:18:55 UTC (rev 217275)
+++ trunk/LayoutTests/ChangeLog 2017-05-23 15:56:12 UTC (rev 217276)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2017-05-23  youenn fablet  <youenn@apple.com>
+
+        There should be an easy way to run HTTP/WPT served tests on a browser
+        https://bugs.webkit.org/show_bug.cgi?id=172068
+
+        Reviewed by Sam Weinig.
+
+        * fast/harness/results.html: In case results.html is opened locallly,
+        open HTTP/WPT urls as served by their related servers.
+        Adding a check that the servers are running before opening the related test.
+
</ins><span class="cx"> 2017-05-23  Antoine Quint  <graouts@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [Modern Media Controls] Turn off all tests
</span></span></pre></div>
<a id="trunkLayoutTestsfastharnessresultshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/harness/results.html (217275 => 217276)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/harness/results.html      2017-05-23 14:18:55 UTC (rev 217275)
+++ trunk/LayoutTests/fast/harness/results.html 2017-05-23 15:56:12 UTC (rev 217276)
</span><span class="lines">@@ -482,9 +482,50 @@
</span><span class="cx">     return basePath;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+var mappings = {
+    "http/tests/ssl/": "https://127.0.0.1:8443/ssl/",
+    "http/tests/": "http://127.0.0.1:8000/",
+    "http/wpt/": "http://localhost:8800/WebKit/",
+    "imported/w3c/web-platform-tests/": "http://localhost:8800/"
+}
+
+function testToURL(test, layoutTestsPath)
+{
+    for (let key in mappings) {
+        if (test.startsWith(key))
+            return mappings[key] + test.substring(key.length);
+
+    }
+    return "file://" + layoutTestsPath + "/" + test
+}
+
+function layoutTestURL(test)
+{
+    if (shouldUseTracLinks())
+        return layoutTestsBasePath() + test;
+    return testToURL(test, layoutTestsBasePath());
+}
+
+function checkServerIsRunning(event)
+{
+    if (shouldUseTracLinks())
+        return;
+
+    var url = event.target.href;
+    if (url.startsWith("file://"))
+        return;
+
+    event.preventDefault();
+    fetch(url, {mode: "no-cors"}).then(() => {
+        window.location = url;
+    }, () => {
+        alert("HTTP server does not seem to be running, please use the run-webkit-httpd script");
+    });
+}
+
</ins><span class="cx"> function testLink(test)
</span><span class="cx"> {
</span><del>-    return '<a class=test-link href="' + layoutTestsBasePath() + test + '">' + test + '</a><span class=flag onclick="unflag(this)"> \u2691</span>';
</del><ins>+    return '<a class=test-link onclick="checkServerIsRunning(event)" href="' + layoutTestURL(test) + '">' + test + '</a><span class=flag onclick="unflag(this)"> \u2691</span>';
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function unflag(flag)
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (217275 => 217276)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog    2017-05-23 14:18:55 UTC (rev 217275)
+++ trunk/Tools/ChangeLog       2017-05-23 15:56:12 UTC (rev 217276)
</span><span class="lines">@@ -1,3 +1,62 @@
</span><ins>+2017-05-23  youenn fablet  <youenn@apple.com>
+
+        There should be an easy way to run HTTP/WPT served tests on a browser
+        https://bugs.webkit.org/show_bug.cgi?id=172068
+
+        Reviewed by Sam Weinig.
+
+        Adding a new script open-layout-test to open a layout-test in a
+        browser and making sure it is served as done through run-webkit-tests.
+        In case tests should be run using a server, detecting whether the
+        server are running. If not, calling run-webkit-httpd to run the
+        servers and open the URL in a browser.
+        Otherwise, open directly the URL.
+
+        Adding an option in run-webkit-httpd to open an URL after having
+        started the servers.
+
+        Adding the --no-http-servers option in run-webkit-tests to not start any HTTP server.
+        This allows running run-webkit-httpd once and not having to restart
+        servers everytime a test should be served.
+
+        Moving most of run-webkit-httpd logic in its own python file to reuse
+        it in open-layout-test script.
+
+        Adding routines to check whether HTTP and WPT servers are running.
+
+        * Scripts/open-layout-test: Added.
+        (parse_args):
+        (main):
+        * Scripts/run-webkit-httpd:
+        (main):
+        * Scripts/webkitpy/layout_tests/controllers/layout_test_finder.py:
+        (LayoutTestFinder.find_tests):
+        * Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py:
+        (LayoutTestRunner.run_tests):
+        * Scripts/webkitpy/layout_tests/run_webkit_tests.py:
+        (parse_args):
+        * Scripts/webkitpy/layout_tests/servers/http_server_base.py:
+        (HttpServerBase._is_server_running_on_all_ports):
+        (HttpServerBase):
+        (HttpServerBase._is_running_on_port):
+        (HttpServerBase._check_that_all_ports_are_available):
+        (is_http_server_running):
+        * Scripts/webkitpy/layout_tests/servers/run_webkit_httpd.py: Copied from Tools/Scripts/run-webkit-httpd.
+        (parse_args):
+        (main):
+        (run_server):
+        * Scripts/webkitpy/layout_tests/servers/web_platform_test_server.py:
+        (is_wpt_server_running):
+        * Scripts/webkitpy/port/base.py:
+        (Port.to.is_http_server_running):
+        (Port.to):
+        (Port.to.is_wpt_server_running):
+        (Port.to.start_web_platform_test_server):
+        * Scripts/webkitpy/port/driver.py:
+        (DriverProxy.is_web_platform_test):
+        (DriverProxy):
+        (DriverProxy.is_webkit_specific_web_platform_test):
+
</ins><span class="cx"> 2017-05-23  Emilio Cobos Álvarez  <ecobos@igalia.com>
</span><span class="cx"> 
</span><span class="cx">         Add a RuntimeEnabledFeature for display: contents, defaulted to false.
</span></span></pre></div>
<a id="trunkToolsScriptsopenlayouttest"></a>
<div class="addfile"><h4>Added: trunk/Tools/Scripts/open-layout-test (0 => 217276)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/open-layout-test                             (rev 0)
+++ trunk/Tools/Scripts/open-layout-test        2017-05-23 15:56:12 UTC (rev 217276)
</span><span class="lines">@@ -0,0 +1,77 @@
</span><ins>+#!/usr/bin/env python
+
+# Copyright (C) 2017 Apple Incorporated. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above
+#    copyright notice, this list of conditions and the following
+#    disclaimer.
+# 2. 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "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 HOLDER 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 argparse
+import subprocess
+import sys
+
+from webkitpy.common.host import Host
+from webkitpy.layout_tests.controllers.layout_test_finder import LayoutTestFinder
+from webkitpy.layout_tests.servers.run_webkit_httpd import run_server as run_webkit_httpd
+from webkitpy.layout_tests.servers.run_webkit_httpd import parse_args as parse_httpd_args
+
+def parse_args(args):
+    description = """Open a layout test using the default browser. Script will make sure to start a server if test needs it."""
+    parser = argparse.ArgumentParser(prog='open-layout-test', description=description, formatter_class=argparse.RawDescriptionHelpFormatter)
+    parser.add_argument('test_name', nargs=1, help='test to open')
+
+    options, args = parser.parse_known_args(args)
+    return options, args
+
+
+def main(argv, stdout, stderr):
+    options, args  = parse_args(argv)
+    test_name = options.test_name[0]
+
+    host = Host()
+    port = host.port_factory.get(None, {})
+    driver = port.create_driver(0)
+    finder = LayoutTestFinder(port, {})
+
+    paths, test_files = finder.find_tests(None, [test_name])
+    test_name = paths[0]
+
+    needs_server = False
+    if driver.is_http_test(test_name) and not port.is_http_server_running():
+        needs_server = not port.is_http_server_running()
+    elif driver.is_web_platform_test(test_name) or driver.is_webkit_specific_web_platform_test(test_name):
+        needs_server = not port.is_wpt_server_running()
+
+    test_url = driver.test_to_uri(test_name)
+    if not needs_server:
+        print "Opening %s" % test_url
+        subprocess.Popen(['open', test_url])
+        return
+
+    httpd_options, httpd_args = parse_httpd_args(['-u', test_url])
+    run_webkit_httpd(httpd_options, httpd_args, stdout, stderr)
+
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv[1:], sys.stdout, sys.stderr))
</ins><span class="cx">Property changes on: trunk/Tools/Scripts/open-layout-test
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<ins>+*
</ins><span class="cx">\ No newline at end of property
</span><a id="trunkToolsScriptsrunwebkithttpd"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/run-webkit-httpd (217275 => 217276)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/run-webkit-httpd     2017-05-23 14:18:55 UTC (rev 217275)
+++ trunk/Tools/Scripts/run-webkit-httpd        2017-05-23 15:56:12 UTC (rev 217276)
</span><span class="lines">@@ -9,13 +9,13 @@
</span><span class="cx"> # are met:
</span><span class="cx"> #
</span><span class="cx"> # 1.  Redistributions of source code must retain the above copyright
</span><del>-#     notice, this list of conditions and the following disclaimer. 
</del><ins>+#     notice, this list of conditions and the following disclaimer.
</ins><span class="cx"> # 2.  Redistributions in binary form must reproduce the above copyright
</span><span class="cx"> #     notice, this list of conditions and the following disclaimer in the
</span><del>-#     documentation and/or other materials provided with the distribution. 
</del><ins>+#     documentation and/or other materials provided with the distribution.
</ins><span class="cx"> # 3.  Neither the name of Apple Inc. ("Apple") nor the names of
</span><span class="cx"> #     its contributors may be used to endorse or promote products derived
</span><del>-#     from this software without specific prior written permission. 
</del><ins>+#     from this software without specific prior written permission.
</ins><span class="cx"> #
</span><span class="cx"> # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
</span><span class="cx"> # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
</span><span class="lines">@@ -28,67 +28,15 @@
</span><span class="cx"> # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
</span><span class="cx"> # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx"> 
</span><del>-import optparse
-import subprocess
</del><span class="cx"> import sys
</span><del>-import tempfile
-import time
</del><span class="cx"> 
</span><del>-from webkitpy.common.host import Host
-from webkitpy.layout_tests.servers import web_platform_test_server
-from webkitpy.port import platform_options
</del><ins>+from webkitpy.layout_tests.servers.run_webkit_httpd import parse_args, run_server
</ins><span class="cx"> 
</span><del>-def parse_args(args):
-    parser = optparse.OptionParser()
-    parser.add_option("-a", "--all-interfaces", help="Bind to all interfaces", action="store_true", dest="http_all_interfaces")
-    parser.add_option("-p", "--port", help="Bind to port NNNN", action="store", type="int", dest="http_port")
-    parser.add_option("--no-httpd", help="Do not start httpd server", action="store_false", default=True, dest="httpd_server")
-    parser.add_option("--no-wpt", help="Do not start web-platform-tests server", action="store_false", default=True, dest="web_platform_test_server")
-    parser.add_option("-D", "--additional-dir", help="Additional directory and alias", action="append", default=[], type="string", nargs=2, dest="additional_dirs")
-    return parser.parse_args(args)
</del><span class="cx"> 
</span><span class="cx"> def main(argv, stdout, stderr):
</span><span class="cx">     options, args = parse_args(argv)
</span><del>-    host = Host()
</del><ins>+    run_server(options, args, stdout, stderr)
</ins><span class="cx"> 
</span><del>-    log_file = tempfile.NamedTemporaryFile()
-    options.http_access_log = log_file.name
-    options.http_error_log = log_file.name
-    options.platform = None
</del><span class="cx"> 
</span><del>-    try:
-        port = host.port_factory.get(options.platform, options)
-    except NotImplementedError, e:
-        print >> stderr, str(e)
-        return EXCEPTIONAL_EXIT_STATUS
-
-    if options.web_platform_test_server:
-        print "Starting web-platform-tests server on <%s>" % web_platform_test_server.base_url(port)
-        port.start_web_platform_test_server()
-
-    if options.httpd_server:
-        # FIXME(154294): somehow retrieve the actual ports and interfaces bound by the httpd server
-        http_port = options.http_port if options.http_port is not None else "8000"
-        if options.http_all_interfaces is not None:
-            print "Starting httpd on port %s (all interfaces)" % http_port
-        else:
-            print "Starting httpd on <http://127.0.0.1:%s>" % http_port
-
-        additionalDirs = {additional_dir[0]: additional_dir[1] for additional_dir in options.additional_dirs}
-        port.start_http_server(additionalDirs)
-        port.start_websocket_server()
-
-    try:
-        tail = subprocess.Popen(['tail', '-F', log_file.name], stdout=subprocess.PIPE)
-        while True:
-            sys.stdout.write(tail.stdout.readline())
-    except KeyboardInterrupt:
-        if options.web_platform_test_server:
-            port.stop_web_platform_test_server()
-        if options.httpd_server:
-            port.stop_websocket_server()
-            port.stop_http_server()
-
-
</del><span class="cx"> if __name__ == '__main__':
</span><span class="cx">     sys.exit(main(sys.argv[1:], sys.stdout, sys.stderr))
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpylayout_testscontrollerslayout_test_finderpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/layout_tests/controllers/layout_test_finder.py (217275 => 217276)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/layout_tests/controllers/layout_test_finder.py      2017-05-23 14:18:55 UTC (rev 217275)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/controllers/layout_test_finder.py 2017-05-23 15:56:12 UTC (rev 217276)
</span><span class="lines">@@ -45,7 +45,7 @@
</span><span class="cx"> 
</span><span class="cx">     def find_tests(self, options, args):
</span><span class="cx">         paths = self._strip_test_dir_prefixes(args)
</span><del>-        if options.test_list:
</del><ins>+        if options and options.test_list:
</ins><span class="cx">             paths += self._strip_test_dir_prefixes(self._read_test_names_from_file(options.test_list, self._port.TEST_PATH_SEPARATOR))
</span><span class="cx">         test_files = self._port.tests(paths)
</span><span class="cx">         return (paths, test_files)
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpylayout_testscontrollerslayout_test_runnerpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py (217275 => 217276)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py      2017-05-23 14:18:55 UTC (rev 217275)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py 2017-05-23 15:56:12 UTC (rev 217276)
</span><span class="lines">@@ -108,7 +108,8 @@
</span><span class="cx">         all_shards = self._sharder.shard_tests(test_inputs, int(self._options.child_processes), self._options.fully_parallel)
</span><span class="cx"> 
</span><span class="cx">         if (self._needs_http and self._options.http) or self._needs_web_platform_test_server:
</span><del>-            self.start_servers()
</del><ins>+            if self._port.get_option("start_http_servers_if_needed"):
+                self.start_servers()
</ins><span class="cx"> 
</span><span class="cx">         self._printer.print_workers_and_shards(num_workers, len(all_shards))
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpylayout_testsrun_webkit_testspy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py (217275 => 217276)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py    2017-05-23 14:18:55 UTC (rev 217275)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py       2017-05-23 15:56:12 UTC (rev 217276)
</span><span class="lines">@@ -199,6 +199,8 @@
</span><span class="cx">             default=True, help="Run HTTP and WebSocket tests (default)"),
</span><span class="cx">         optparse.make_option("--no-http", action="store_false", dest="http",
</span><span class="cx">             help="Don't run HTTP and WebSocket tests"),
</span><ins>+        optparse.make_option("--no-http-servers", action="store_false", dest="start_http_servers_if_needed",
+            default=True, help="Don't start HTTP servers"),
</ins><span class="cx">         optparse.make_option("--ignore-metrics", action="store_true", dest="ignore_metrics",
</span><span class="cx">             default=False, help="Ignore rendering metrics related information from test "
</span><span class="cx">             "output, only compare the structure of the rendertree."),
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpylayout_testsservershttp_server_basepy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/layout_tests/servers/http_server_base.py (217275 => 217276)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/layout_tests/servers/http_server_base.py    2017-05-23 14:18:55 UTC (rev 217275)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/servers/http_server_base.py       2017-05-23 15:56:12 UTC (rev 217276)
</span><span class="lines">@@ -200,20 +200,25 @@
</span><span class="cx">             raise ServerError("Server exited")
</span><span class="cx"> 
</span><span class="cx">         for mapping in self._mappings:
</span><del>-            s = socket.socket()
-            port = mapping['port']
-            try:
-                s.connect(('localhost', port))
-                _log.debug("Server running on %d" % port)
-            except IOError, e:
-                if e.errno not in (errno.ECONNREFUSED, errno.ECONNRESET):
-                    raise
-                _log.debug("Server NOT running on %d: %s" % (port, e))
</del><ins>+            if not self._is_running_on_port(mapping['port']):
</ins><span class="cx">                 return False
</span><del>-            finally:
-                s.close()
</del><span class="cx">         return True
</span><span class="cx"> 
</span><ins>+    @classmethod
+    def _is_running_on_port(cls, port):
+        s = socket.socket()
+        try:
+            s.connect(('localhost', port))
+            _log.debug("Server running on %d" % port)
+        except IOError, e:
+            if e.errno not in (errno.ECONNREFUSED, errno.ECONNRESET):
+                raise
+            _log.debug("Server NOT running on %d: %s" % (port, e))
+            return False
+        finally:
+            s.close()
+        return True
+
</ins><span class="cx">     def _check_that_all_ports_are_available(self):
</span><span class="cx">         for mapping in self._mappings:
</span><span class="cx">             s = socket.socket()
</span><span class="lines">@@ -230,3 +235,7 @@
</span><span class="cx">                     raise
</span><span class="cx">             finally:
</span><span class="cx">                 s.close()
</span><ins>+
+
+def is_http_server_running():
+    return HttpServerBase._is_running_on_port(HttpServerBase.HTTP_SERVER_PORT)
</ins></span></pre></div>
<a id="trunkToolsScriptswebkitpylayout_testsserversrun_webkit_httpdpyfromrev217275trunkToolsScriptsrunwebkithttpd"></a>
<div class="copfile"><h4>Copied: trunk/Tools/Scripts/webkitpy/layout_tests/servers/run_webkit_httpd.py (from rev 217275, trunk/Tools/Scripts/run-webkit-httpd) (0 => 217276)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/layout_tests/servers/run_webkit_httpd.py                            (rev 0)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/servers/run_webkit_httpd.py       2017-05-23 15:56:12 UTC (rev 217276)
</span><span class="lines">@@ -0,0 +1,103 @@
</span><ins>+#!/usr/bin/python
+
+# Copyright (C) 2005, 2006, 2007, 2015 Apple Inc.  All rights reserved.
+# Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+# Copyright (C) 2011 Research In Motion Limited. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  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.
+# 3.  Neither the name of Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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 optparse
+import subprocess
+import sys
+import tempfile
+
+from webkitpy.common.host import Host
+from webkitpy.layout_tests.servers import web_platform_test_server
+from webkitpy.layout_tests.run_webkit_tests import EXCEPTIONAL_EXIT_STATUS
+
+
+def parse_args(args):
+    parser = optparse.OptionParser()
+    parser.add_option("-a", "--all-interfaces", help="Bind to all interfaces", action="store_true", dest="http_all_interfaces")
+    parser.add_option("-p", "--port", help="Bind to port NNNN", action="store", type="int", dest="http_port")
+    parser.add_option("--no-httpd", help="Do not start httpd server", action="store_false", default=True, dest="httpd_server")
+    parser.add_option("--no-wpt", help="Do not start web-platform-tests server", action="store_false", default=True, dest="web_platform_test_server")
+    parser.add_option("-D", "--additional-dir", help="Additional directory and alias", action="append", default=[], type="string", nargs=2, dest="additional_dirs")
+    parser.add_option("-u", "--open-url", help="Open an URL", action="store", default=[], type="string", dest="url")
+    return parser.parse_args(args)
+
+
+def main(argv, stdout, stderr):
+    options, args = parse_args(argv)
+    run_server(options, args, stdout, stderr)
+
+
+def run_server(options, args, stdout, stderr):
+    host = Host()
+    log_file = tempfile.NamedTemporaryFile()
+    options.http_access_log = log_file.name
+    options.http_error_log = log_file.name
+    options.platform = None
+
+    try:
+        port = host.port_factory.get(options.platform, options)
+    except NotImplementedError, e:
+        print >> stderr, str(e)
+        return EXCEPTIONAL_EXIT_STATUS
+
+    if options.web_platform_test_server:
+        print "Starting web-platform-tests server on <%s>" % web_platform_test_server.base_url(port)
+        port.start_web_platform_test_server()
+
+    if options.httpd_server:
+        # FIXME(154294): somehow retrieve the actual ports and interfaces bound by the httpd server
+        http_port = options.http_port if options.http_port is not None else "8000"
+        if options.http_all_interfaces is not None:
+            print "Starting httpd on port %s (all interfaces)" % http_port
+        else:
+            print "Starting httpd on <http://127.0.0.1:%s>" % http_port
+
+        additionalDirs = {additional_dir[0]: additional_dir[1] for additional_dir in options.additional_dirs}
+        port.start_http_server(additionalDirs)
+        port.start_websocket_server()
+
+    if options.url:
+        print "Opening %s" % options.url
+        subprocess.Popen(['open', options.url], stdout=subprocess.PIPE)
+
+    try:
+        tail = subprocess.Popen(['tail', '-F', log_file.name], stdout=subprocess.PIPE)
+        while True:
+            sys.stdout.write(tail.stdout.readline())
+    except KeyboardInterrupt:
+        if options.web_platform_test_server:
+            port.stop_web_platform_test_server()
+        if options.httpd_server:
+            port.stop_http_server()
+            port.stop_websocket_server()
+
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv[1:], sys.stdout, sys.stderr))
</ins></span></pre></div>
<a id="trunkToolsScriptswebkitpylayout_testsserversweb_platform_test_serverpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/layout_tests/servers/web_platform_test_server.py (217275 => 217276)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/layout_tests/servers/web_platform_test_server.py    2017-05-23 14:18:55 UTC (rev 217275)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/servers/web_platform_test_server.py       2017-05-23 15:56:12 UTC (rev 217276)
</span><span class="lines">@@ -55,6 +55,11 @@
</span><span class="cx">     return "http://" + config["host"] + ":" + str(ports["http"][0]) + "/"
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+def is_wpt_server_running(port_obj):
+    config = wpt_config_json(port_obj)
+    return http_server_base.HttpServerBase._is_running_on_port(config["ports"]["http"][0])
+
+
</ins><span class="cx"> class WebPlatformTestServer(http_server_base.HttpServerBase):
</span><span class="cx">     def __init__(self, port_obj, name, pidfile=None):
</span><span class="cx">         http_server_base.HttpServerBase.__init__(self, port_obj)
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpyportbasepy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/port/base.py (217275 => 217276)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/port/base.py        2017-05-23 14:18:55 UTC (rev 217275)
+++ trunk/Tools/Scripts/webkitpy/port/base.py   2017-05-23 15:56:12 UTC (rev 217276)
</span><span class="lines">@@ -57,7 +57,7 @@
</span><span class="cx"> from webkitpy.port import image_diff
</span><span class="cx"> from webkitpy.port import server_process
</span><span class="cx"> from webkitpy.port.factory import PortFactory
</span><del>-from webkitpy.layout_tests.servers import apache_http_server, http_server
</del><ins>+from webkitpy.layout_tests.servers import apache_http_server, http_server, http_server_base
</ins><span class="cx"> from webkitpy.layout_tests.servers import web_platform_test_server
</span><span class="cx"> from webkitpy.layout_tests.servers import websocket_server
</span><span class="cx"> 
</span><span class="lines">@@ -970,6 +970,12 @@
</span><span class="cx">         server.start()
</span><span class="cx">         self._http_server = server
</span><span class="cx"> 
</span><ins>+    def is_http_server_running(self):
+        return http_server_base.is_http_server_running()
+
+    def is_wpt_server_running(self):
+        return web_platform_test_server.is_wpt_server_running(self)
+
</ins><span class="cx">     def _extract_certificate_from_pem(self, pem_file, destination_certificate_file):
</span><span class="cx">         return self._executive.run_command(['openssl', 'x509', '-outform', 'pem', '-in', pem_file, '-out', destination_certificate_file], return_exit_code=True) == 0
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpyportdriverpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/port/driver.py (217275 => 217276)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/port/driver.py      2017-05-23 14:18:55 UTC (rev 217275)
+++ trunk/Tools/Scripts/webkitpy/port/driver.py 2017-05-23 15:56:12 UTC (rev 217276)
</span><span class="lines">@@ -661,6 +661,12 @@
</span><span class="cx">     def is_http_test(self, test_name):
</span><span class="cx">         return self._driver.is_http_test(test_name)
</span><span class="cx"> 
</span><ins>+    def is_web_platform_test(self, test_name):
+        return self._driver.is_web_platform_test(test_name)
+
+    def is_webkit_specific_web_platform_test(self, test_name):
+        return self._driver.is_webkit_specific_web_platform_test(test_name)
+
</ins><span class="cx">     # FIXME: this should be a @classmethod (or implemented on Port instead).
</span><span class="cx">     def test_to_uri(self, test_name):
</span><span class="cx">         return self._driver.test_to_uri(test_name)
</span></span></pre>
</div>
</div>

</body>
</html>