Remove default copy of wpt testharness.js when launching wpt server
[WebKit-https.git] / Tools / Scripts / webkitpy / layout_tests / servers / web_platform_test_server.py
1 #  Copyright (c) 2014, Canon Inc. All rights reserved.
2 #  Redistribution and use in source and binary forms, with or without
3 #  modification, are permitted provided that the following conditions
4 #  are met:
5 #  1.  Redistributions of source code must retain the above copyright
6 #      notice, this list of conditions and the following disclaimer.
7 #  2.  Redistributions in binary form must reproduce the above copyright
8 #      notice, this list of conditions and the following disclaimer in the
9 #      documentation and/or other materials provided with the distribution.
10 #  3.  Neither the name of Canon Inc. nor the names of
11 #      its contributors may be used to endorse or promote products derived
12 #      from this software without specific prior written permission.
13 #  THIS SOFTWARE IS PROVIDED BY CANON INC. AND ITS CONTRIBUTORS "AS IS" AND ANY
14 #  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 #  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 #  DISCLAIMED. IN NO EVENT SHALL CANON INC. AND ITS CONTRIBUTORS BE LIABLE FOR
17 #  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 #  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 #  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20 #  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21 #  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22 #  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
24 import json
25 import logging
26 import sys
27 import time
28
29 from webkitpy.common.system.autoinstall import AutoInstaller
30 from webkitpy.layout_tests.servers import http_server_base
31
32 _log = logging.getLogger(__name__)
33
34
35 def doc_root(port_obj):
36     doc_root = port_obj.get_option("wptserver_doc_root")
37     if doc_root is None:
38         return port_obj.host.filesystem.join("imported", "w3c", "web-platform-tests")
39     return doc_root
40
41
42 def base_url(port_obj):
43     config_wk_filepath = port_obj._filesystem.join(port_obj.layout_tests_dir(), "imported", "w3c", "resources", "config.json")
44     if not port_obj.host.filesystem.isfile(config_wk_filepath):
45         # This should only be hit by webkitpy unit tests
46         _log.debug("No WPT config file found")
47         return "http://localhost:8800/"
48     json_data = port_obj._filesystem.read_text_file(config_wk_filepath)
49     config = json.loads(json_data)
50     ports = config["ports"]
51     return "http://" + config["host"] + ":" + str(ports["http"][0]) + "/"
52
53
54 class WebPlatformTestServer(http_server_base.HttpServerBase):
55     def __init__(self, port_obj, name, pidfile=None):
56         http_server_base.HttpServerBase.__init__(self, port_obj)
57         self._output_dir = port_obj.results_directory()
58
59         self._name = name
60         self._log_file_name = '%s_process_log.out.txt' % (self._name)
61
62         self._wsout = None
63         self._process = None
64         self._pid_file = pidfile
65         if not self._pid_file:
66             self._pid_file = self._filesystem.join(self._runtime_path, '%s.pid' % self._name)
67         self._servers_file = self._filesystem.join(self._runtime_path, '%s_servers.json' % (self._name))
68
69         self._stdout_data = None
70         self._stderr_data = None
71         self._filesystem = port_obj.host.filesystem
72         self._layout_root = port_obj.layout_tests_dir()
73         self._doc_root = self._filesystem.join(self._layout_root, doc_root(port_obj))
74
75         self._resources_files_to_copy = ['testharness.css', 'testharnessreport.js']
76
77         current_dir_path = self._filesystem.abspath(self._filesystem.split(__file__)[0])
78         self._start_cmd = ["python", self._filesystem.join(current_dir_path, "web_platform_test_launcher.py"), self._servers_file]
79         self._doc_root_path = self._filesystem.join(self._layout_root, self._doc_root)
80
81     def _install_modules(self):
82         modules_file_path = self._filesystem.join(self._doc_root_path, "..", "resources", "web-platform-tests-modules.json")
83         if not self._filesystem.isfile(modules_file_path):
84             _log.warning("Cannot read " + modules_file_path)
85             return
86         modules = json.loads(self._filesystem.read_text_file(modules_file_path))
87         for module in modules:
88             AutoInstaller(target_dir=self._filesystem.join(self._doc_root, self._filesystem.sep.join(module["path"]))).install(url=module["url"], url_subpath=module["url_subpath"], target_name=module["name"])
89
90     def _copy_webkit_test_files(self):
91         _log.debug('Copying WebKit resources files')
92         for f in self._resources_files_to_copy:
93             webkit_filename = self._filesystem.join(self._layout_root, "resources", f)
94             if self._filesystem.isfile(webkit_filename):
95                 self._filesystem.copyfile(webkit_filename, self._filesystem.join(self._doc_root, "resources", f))
96         _log.debug('Copying WebKit web platform server config.json')
97         config_wk_filename = self._filesystem.join(self._layout_root, "imported", "w3c", "resources", "config.json")
98         if self._filesystem.isfile(config_wk_filename):
99             config_json = self._filesystem.read_text_file(config_wk_filename).replace("%CERTS_DIR%", self._filesystem.join(self._output_dir, "_wpt_certs"))
100             self._filesystem.write_text_file(self._filesystem.join(self._doc_root, "config.json"), config_json)
101
102         wpt_testharnessjs_file = self._filesystem.join(self._doc_root, "resources", "testharness.js")
103         layout_tests_testharnessjs_file = self._filesystem.join(self._layout_root, "resources", "testharness.js")
104         if (not self._filesystem.compare(wpt_testharnessjs_file, layout_tests_testharnessjs_file)):
105             _log.warning("\n//////////\nWPT tests are not using the same testharness.js file as other WebKit Layout tests.\nWebKit testharness.js might need to be updated according WPT testharness.js.\n//////////\n")
106
107     def _clean_webkit_test_files(self):
108         _log.debug('Cleaning WPT resources files')
109         for f in self._resources_files_to_copy:
110             wpt_filename = self._filesystem.join(self._doc_root, "resources", f)
111             if self._filesystem.isfile(wpt_filename):
112                 self._filesystem.remove(wpt_filename)
113         _log.debug('Cleaning WPT web platform server config.json')
114         config_wpt_filename = self._filesystem.join(self._doc_root, "config.json")
115         if self._filesystem.isfile(config_wpt_filename):
116             self._filesystem.remove(config_wpt_filename)
117
118     def _prepare_config(self):
119         if self._filesystem.exists(self._output_dir):
120             output_log = self._filesystem.join(self._output_dir, self._log_file_name)
121             self._wsout = self._filesystem.open_text_file_for_writing(output_log)
122         self._install_modules()
123         self._copy_webkit_test_files()
124
125     def _spawn_process(self):
126         self._stdout_data = None
127         self._stderr_data = None
128         if self._wsout:
129             self._process = self._executive.popen(self._start_cmd, cwd=self._doc_root_path, shell=False, stdin=self._executive.PIPE, stdout=self._wsout, stderr=self._wsout)
130         else:
131             self._process = self._executive.popen(self._start_cmd, cwd=self._doc_root_path, shell=False, stdin=self._executive.PIPE, stdout=self._executive.PIPE, stderr=self._executive.STDOUT)
132         self._filesystem.write_text_file(self._pid_file, str(self._process.pid))
133
134         # Wait a second for the server to actually start so that tests do not start until server is running.
135         time.sleep(1)
136
137         return self._process.pid
138
139     def _stop_running_subservers(self):
140         if self._filesystem.exists(self._servers_file):
141             try:
142                 json_data = self._filesystem.read_text_file(self._servers_file)
143                 started_servers = json.loads(json_data)
144                 for server in started_servers:
145                     if self._executive.check_running_pid(server['pid']):
146                         _log.warning('Killing server process (protocol: %s , port: %d, pid: %d).' % (server['protocol'], server['port'], server['pid']))
147                         self._executive.kill_process(server['pid'])
148             finally:
149                 self._filesystem.remove(self._servers_file)
150
151     def stop(self):
152         super(WebPlatformTestServer, self).stop()
153         # In case of orphaned pid, kill the running subservers if any still alive.
154         self._stop_running_subservers()
155
156     def _stop_running_server(self):
157         _log.debug('Stopping %s server' % (self._name))
158         self._clean_webkit_test_files()
159
160         if self._process:
161             (self._stdout_data, self._stderr_data) = self._process.communicate(input='\n')
162         if self._wsout:
163             self._wsout.close()
164             self._wsout = None
165
166         if self._pid and self._executive.check_running_pid(self._pid):
167             _log.warning('Cannot stop %s server normally.' % (self._name))
168             _log.warning('Killing server launcher process (pid: %d).' % (self._pid))
169             self._executive.kill_process(self._pid)
170
171         self._remove_pid_file()
172         self._stop_running_subservers()