Commit d9e49db7 authored by Robert Ma's avatar Robert Ma Committed by Commit Bot

Make /gen/ available in wptserve

/gen/ is already available in both file tests (via blink_test_runner.cc)
and http tests (via Apache 'Alias' directives). This CL makes /gen/ also
available to wptserve in Blink (both run_web_tests and
run_blink_wptserve).

Besides, this CL adds configuration options (release, debug, etc.) to
run_blink_wptserve so that users can control which out/*/gen is served.

Also fix a leaking file descriptor in filesystem.open_text_tempfile.

Bug: 821496
Change-Id: I60ae0657df470dd319d002bc1c20476d33d9c05e
Reviewed-on: https://chromium-review.googlesource.com/1140908
Commit-Queue: Robert Ma <robertma@chromium.org>
Reviewed-by: default avatarQuinten Yearsley <qyearsley@chromium.org>
Reviewed-by: default avatarPhilip Jägenstedt <foolip@chromium.org>
Cr-Commit-Position: refs/heads/master@{#576210}
parent 160ec668
...@@ -257,7 +257,10 @@ class FileSystem(object): ...@@ -257,7 +257,10 @@ class FileSystem(object):
Returns a tuple of the file and the name. Returns a tuple of the file and the name.
""" """
_, temp_name = tempfile.mkstemp(suffix) temp_fd, temp_name = tempfile.mkstemp(suffix)
# Close the OS fd opened by mkstemp as we will reopen the file with an
# explict encoding.
os.close(temp_fd)
f = codecs.open(temp_name, 'w', 'utf8') f = codecs.open(temp_name, 'w', 'utf8')
return f, temp_name return f, temp_name
......
...@@ -32,35 +32,43 @@ Scripts in tools/ can use this module to start servers that are normally used ...@@ -32,35 +32,43 @@ Scripts in tools/ can use this module to start servers that are normally used
for layout tests, outside of the layout test runner. for layout tests, outside of the layout test runner.
""" """
import argparse
import logging import logging
import optparse
from blinkpy.common.host import Host from blinkpy.common.host import Host
from blinkpy.web_tests.port.factory import configuration_options
class RawTextHelpFormatter(optparse.IndentedHelpFormatter):
def format_description(self, description):
return description
def main(server_constructor, input_fn=None, argv=None, description=None, **kwargs): def main(server_constructor, input_fn=None, argv=None, description=None, **kwargs):
input_fn = input_fn or raw_input input_fn = input_fn or raw_input
parser = argparse.ArgumentParser(description=description, formatter_class=argparse.RawTextHelpFormatter) parser = optparse.OptionParser(description=description, formatter=RawTextHelpFormatter())
parser.add_argument('--output-dir', type=str, default=None, parser.add_option('--output-dir', type=str, default=None,
help='output directory, for log files etc.') help='output directory, for log files etc.')
parser.add_argument('-v', '--verbose', action='store_true', parser.add_option('-v', '--verbose', action='store_true',
help='print more information, including port numbers') help='print more information, including port numbers')
args = parser.parse_args(argv) for opt in configuration_options():
parser.add_option(opt)
options, _ = parser.parse_args(argv)
logging.basicConfig() logging.basicConfig()
logger = logging.getLogger() logger = logging.getLogger()
logger.setLevel(logging.DEBUG if args.verbose else logging.INFO) logger.setLevel(logging.DEBUG if options.verbose else logging.INFO)
host = Host() host = Host()
port_obj = host.port_factory.get() port_obj = host.port_factory.get(options=options)
if not args.output_dir: if not options.output_dir:
args.output_dir = port_obj.default_results_directory() options.output_dir = port_obj.default_results_directory()
# Create the output directory if it doesn't already exist. # Create the output directory if it doesn't already exist.
port_obj.host.filesystem.maybe_make_directory(args.output_dir) port_obj.host.filesystem.maybe_make_directory(options.output_dir)
server = server_constructor(port_obj, args.output_dir, **kwargs) server = server_constructor(port_obj, options.output_dir, **kwargs)
server.start() server.start()
try: try:
_ = input_fn('Hit any key to stop the server and exit.') _ = input_fn('Hit any key to stop the server and exit.')
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
"""Start and stop the WPTserve servers as they're used by the layout tests.""" """Start and stop the WPTserve servers as they're used by the layout tests."""
import datetime import datetime
import json
import logging import logging
from blinkpy.common.path_finder import PathFinder from blinkpy.common.path_finder import PathFinder
...@@ -37,13 +38,13 @@ class WPTServe(server_base.ServerBase): ...@@ -37,13 +38,13 @@ class WPTServe(server_base.ServerBase):
path_to_pywebsocket = finder.path_from_chromium_base('third_party', 'pywebsocket', 'src') path_to_pywebsocket = finder.path_from_chromium_base('third_party', 'pywebsocket', 'src')
path_to_wpt_support = finder.path_from_blink_tools('blinkpy', 'third_party', 'wpt') path_to_wpt_support = finder.path_from_blink_tools('blinkpy', 'third_party', 'wpt')
path_to_wpt_root = fs.join(path_to_wpt_support, 'wpt') path_to_wpt_root = fs.join(path_to_wpt_support, 'wpt')
path_to_wpt_config = fs.join(path_to_wpt_support, 'wpt.config.json')
path_to_wpt_tests = fs.abspath(fs.join(self._port_obj.layout_tests_dir(), 'external', 'wpt')) path_to_wpt_tests = fs.abspath(fs.join(self._port_obj.layout_tests_dir(), 'external', 'wpt'))
path_to_ws_handlers = fs.join(path_to_wpt_tests, 'websockets', 'handlers') path_to_ws_handlers = fs.join(path_to_wpt_tests, 'websockets', 'handlers')
self._config_file = self._prepare_wptserve_config(path_to_wpt_support)
wpt_script = fs.join(path_to_wpt_root, 'wpt') wpt_script = fs.join(path_to_wpt_root, 'wpt')
start_cmd = [self._port_obj.host.executable, start_cmd = [self._port_obj.host.executable,
'-u', wpt_script, 'serve', '-u', wpt_script, 'serve',
'--config', path_to_wpt_config, '--config', self._config_file,
'--doc_root', path_to_wpt_tests] '--doc_root', path_to_wpt_tests]
# TODO(burnik): Merge with default start_cmd once we roll in websockets. # TODO(burnik): Merge with default start_cmd once we roll in websockets.
...@@ -59,15 +60,31 @@ class WPTServe(server_base.ServerBase): ...@@ -59,15 +60,31 @@ class WPTServe(server_base.ServerBase):
expiration_date = datetime.date(2025, 1, 4) expiration_date = datetime.date(2025, 1, 4)
if datetime.date.today() > expiration_date - datetime.timedelta(30): if datetime.date.today() > expiration_date - datetime.timedelta(30):
logging.getLogger(__name__).error( _log.error(
'Pre-generated keys and certificates are going to be expired at %s.' 'Pre-generated keys and certificates are going to be expired at %s.'
' Please re-generate them by following steps in %s/README.chromium.' ' Please re-generate them by following steps in %s/README.chromium.',
% (expiration_date.strftime('%b %d %Y'), path_to_wpt_support)) expiration_date.strftime('%b %d %Y'), path_to_wpt_support)
def _prepare_wptserve_config(self, path_to_wpt_support):
fs = self._filesystem
template_path = fs.join(path_to_wpt_support, 'wpt.config.json')
config = json.loads(fs.read_text_file(template_path))
config['aliases'].append({
'url-path': '/gen/',
'local-dir': self._port_obj.generated_sources_directory()
})
f, temp_file = fs.open_text_tempfile('.json')
json.dump(config, f)
f.close()
return temp_file
def _stop_running_server(self): def _stop_running_server(self):
self._wait_for_action(self._check_and_kill_wptserve) self._wait_for_action(self._check_and_kill_wptserve)
if self._filesystem.exists(self._pid_file): if self._filesystem.exists(self._pid_file):
self._filesystem.remove(self._pid_file) self._filesystem.remove(self._pid_file)
if self._filesystem.exists(self._config_file):
self._filesystem.remove(self._config_file)
def _check_and_kill_wptserve(self): def _check_and_kill_wptserve(self):
"""Tries to kill wptserve. """Tries to kill wptserve.
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
import json
import logging import logging
from blinkpy.common.system.log_testing import LoggingTestCase from blinkpy.common.system.log_testing import LoggingTestCase
...@@ -12,11 +13,19 @@ from blinkpy.web_tests.servers.wptserve import WPTServe ...@@ -12,11 +13,19 @@ from blinkpy.web_tests.servers.wptserve import WPTServe
class TestWPTServe(LoggingTestCase): class TestWPTServe(LoggingTestCase):
def setUp(self):
super(TestWPTServe, self).setUp()
self.host = MockHost()
self.port = test.TestPort(self.host)
self.host.filesystem.write_text_file(
'/mock-checkout/third_party/blink/tools/blinkpy/third_party/wpt/wpt.config.json',
'{"ports": {}, "aliases": []}'
)
# pylint: disable=protected-access # pylint: disable=protected-access
def test_init_start_cmd(self): def test_init_start_cmd(self):
test_port = test.TestPort(MockHost()) server = WPTServe(self.port, '/foo')
server = WPTServe(test_port, '/foo')
self.assertEqual( self.assertEqual(
server._start_cmd, # pylint: disable=protected-access server._start_cmd, # pylint: disable=protected-access
[ [
...@@ -25,14 +34,22 @@ class TestWPTServe(LoggingTestCase): ...@@ -25,14 +34,22 @@ class TestWPTServe(LoggingTestCase):
'/mock-checkout/third_party/blink/tools/blinkpy/third_party/wpt/wpt/wpt', '/mock-checkout/third_party/blink/tools/blinkpy/third_party/wpt/wpt/wpt',
'serve', 'serve',
'--config', '--config',
'/mock-checkout/third_party/blink/tools/blinkpy/third_party/wpt/wpt.config.json', server._config_file,
'--doc_root', '--doc_root',
'/test.checkout/LayoutTests/external/wpt' '/test.checkout/LayoutTests/external/wpt'
]) ])
def test_init_gen_config(self):
server = WPTServe(self.port, '/foo')
config = json.loads(self.port._filesystem.read_text_file(server._config_file))
self.assertEqual(len(config['aliases']), 1)
self.assertDictEqual(
config['aliases'][0],
{'url-path': '/gen/', 'local-dir': '/mock-checkout/out/Release/gen'}
)
def test_init_env(self): def test_init_env(self):
test_port = test.TestPort(MockHost()) server = WPTServe(self.port, '/foo')
server = WPTServe(test_port, '/foo')
self.assertEqual( self.assertEqual(
server._env, # pylint: disable=protected-access server._env, # pylint: disable=protected-access
{ {
...@@ -45,23 +62,21 @@ class TestWPTServe(LoggingTestCase): ...@@ -45,23 +62,21 @@ class TestWPTServe(LoggingTestCase):
# Allow asserting about debug logs. # Allow asserting about debug logs.
self.set_logging_level(logging.DEBUG) self.set_logging_level(logging.DEBUG)
host = MockHost() self.host.filesystem.write_text_file('/log_file_dir/access_log', 'foo')
test_port = test.TestPort(host) self.host.filesystem.write_text_file('/log_file_dir/error_log', 'foo')
host.filesystem.write_text_file('/log_file_dir/access_log', 'foo') self.host.filesystem.write_text_file('/tmp/pidfile', '7')
host.filesystem.write_text_file('/log_file_dir/error_log', 'foo')
host.filesystem.write_text_file('/tmp/pidfile', '7')
server = WPTServe(test_port, '/log_file_dir') server = WPTServe(self.port, '/log_file_dir')
server._pid_file = '/tmp/pidfile' server._pid_file = '/tmp/pidfile'
server._spawn_process = lambda: 4 server._spawn_process = lambda: 4
server._is_server_running_on_all_ports = lambda: True server._is_server_running_on_all_ports = lambda: True
# Simulate a process that never gets killed. # Simulate a process that never gets killed.
host.executive.check_running_pid = lambda _: True self.host.executive.check_running_pid = lambda _: True
server.start() server.start()
self.assertEqual(server._pid, 4) self.assertEqual(server._pid, 4)
self.assertIsNone(host.filesystem.files[server._pid_file]) self.assertIsNone(self.host.filesystem.files[server._pid_file])
# In this case, we'll try to kill the process repeatedly, # In this case, we'll try to kill the process repeatedly,
# then give up and just try to start a new process anyway. # then give up and just try to start a new process anyway.
...@@ -79,3 +94,9 @@ class TestWPTServe(LoggingTestCase): ...@@ -79,3 +94,9 @@ class TestWPTServe(LoggingTestCase):
'DEBUG: all ports are available\n', 'DEBUG: all ports are available\n',
'DEBUG: wptserve successfully started (pid = 4)\n' 'DEBUG: wptserve successfully started (pid = 4)\n'
]) ])
def test_stop_running_server_removes_temp_files(self):
server = WPTServe(self.port, '/foo')
server._stop_running_server()
self.assertFalse(self.host.filesystem.exists(server._pid_file))
self.assertFalse(self.host.filesystem.exists(server._config_file))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment