• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (C) 2010 Google Inc. All rights reserved.
2#
3# Redistribution and use in source and binary forms, with or without
4# modification, are permitted provided that the following conditions are
5# met:
6#
7#     * Redistributions of source code must retain the above copyright
8# notice, this list of conditions and the following disclaimer.
9#     * Redistributions in binary form must reproduce the above
10# copyright notice, this list of conditions and the following disclaimer
11# in the documentation and/or other materials provided with the
12# distribution.
13#     * Neither the Google name nor the names of its
14# contributors may be used to endorse or promote products derived from
15# this software without specific prior written permission.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29"""WebKit Mac implementation of the Port interface."""
30
31import logging
32import os
33import platform
34import signal
35
36from webkitpy.layout_tests.port.webkit import WebKitPort
37
38_log = logging.getLogger("webkitpy.layout_tests.port.mac")
39
40
41def os_version(os_version_string=None, supported_versions=None):
42    if not os_version_string:
43        if hasattr(platform, 'mac_ver') and platform.mac_ver()[0]:
44            os_version_string = platform.mac_ver()[0]
45        else:
46            # Make up something for testing.
47            os_version_string = "10.5.6"
48    release_version = int(os_version_string.split('.')[1])
49    version_strings = {
50        4: 'tiger',
51        5: 'leopard',
52        6: 'snowleopard',
53    }
54    assert release_version >= min(version_strings.keys())
55    version_string = version_strings.get(release_version, 'future')
56    if supported_versions:
57        assert version_string in supported_versions
58    return version_string
59
60
61class MacPort(WebKitPort):
62    """WebKit Mac implementation of the Port class."""
63    # FIXME: 'wk2' probably shouldn't be a version, it should probably be
64    # a modifier, like 'chromium-gpu' is to 'chromium'.
65    SUPPORTED_VERSIONS = ('tiger', 'leopard', 'snowleopard', 'future', 'wk2')
66
67    FALLBACK_PATHS = {
68        'tiger': ['mac-tiger', 'mac-leopard', 'mac-snowleopard', 'mac'],
69        'leopard': ['mac-leopard', 'mac-snowleopard', 'mac'],
70        'snowleopard': ['mac-snowleopard', 'mac'],
71        'future': ['mac'],
72        'wk2': ['mac-wk2', 'mac'],
73    }
74
75    def __init__(self, port_name=None, os_version_string=None, **kwargs):
76        port_name = port_name or 'mac'
77        WebKitPort.__init__(self, port_name=port_name, **kwargs)
78        if port_name == 'mac':
79            self._version = os_version(os_version_string)
80            self._name = port_name + '-' + self._version
81        else:
82            self._version = port_name[4:]
83            assert self._version in self.SUPPORTED_VERSIONS
84        self._operating_system = 'mac'
85        if not hasattr(self._options, 'time-out-ms') or self._options.time_out_ms is None:
86            self._options.time_out_ms = 35000
87
88    def default_child_processes(self):
89        # FIXME: new-run-webkit-tests is unstable on Mac running more than
90        # four threads in parallel.
91        # See https://bugs.webkit.org/show_bug.cgi?id=36622
92        child_processes = WebKitPort.default_child_processes(self)
93        if not self._multiprocessing_is_available and child_processes > 4:
94            return 4
95        return child_processes
96
97    def baseline_path(self):
98        if self.version() != 'future':
99            return WebKitPort.baseline_path(self)
100
101        assert(self._name[-7:] == '-future')
102        return self._webkit_baseline_path(self._name[:-7])
103
104    def baseline_search_path(self):
105        return map(self._webkit_baseline_path, self.FALLBACK_PATHS[self._version])
106
107    def path_to_test_expectations_file(self):
108        return self.path_from_webkit_base('LayoutTests', 'platform',
109           'mac', 'test_expectations.txt')
110
111    def _skipped_file_paths(self):
112        # FIXME: This method will need to be made work for non-mac
113        # platforms and moved into base.Port.
114        skipped_files = []
115        if self._name in ('mac-leopard', 'mac-snowleopard'):
116            skipped_files.append(self._filesystem.join(
117                self._webkit_baseline_path(self._name), 'Skipped'))
118        skipped_files.append(self._filesystem.join(self._webkit_baseline_path('mac'),
119                                          'Skipped'))
120        return skipped_files
121
122    def _build_java_test_support(self):
123        java_tests_path = self._filesystem.join(self.layout_tests_dir(), "java")
124        build_java = ["/usr/bin/make", "-C", java_tests_path]
125        if self._executive.run_command(build_java, return_exit_code=True):
126            _log.error("Failed to build Java support files: %s" % build_java)
127            return False
128        return True
129
130    def _check_port_build(self):
131        return self._build_java_test_support()
132
133    def _path_to_apache_config_file(self):
134        return self._filesystem.join(self.layout_tests_dir(), 'http', 'conf',
135                                     'apache2-httpd.conf')
136
137    def _path_to_webcore_library(self):
138        return self._build_path('WebCore.framework/Versions/A/WebCore')
139
140    # FIXME: This doesn't have anything to do with WebKit.
141    def _shut_down_http_server(self, server_pid):
142        """Shut down the lighttpd web server. Blocks until it's fully
143        shut down.
144
145        Args:
146            server_pid: The process ID of the running server.
147        """
148        # server_pid is not set when "http_server.py stop" is run manually.
149        if server_pid is None:
150            # FIXME: This isn't ideal, since it could conflict with
151            # lighttpd processes not started by http_server.py,
152            # but good enough for now.
153            self._executive.kill_all('httpd')
154        else:
155            try:
156                os.kill(server_pid, signal.SIGTERM)
157                # FIXME: Maybe throw in a SIGKILL just to be sure?
158            except OSError:
159                # Sometimes we get a bad PID (e.g. from a stale httpd.pid
160                # file), so if kill fails on the given PID, just try to
161                # 'killall' web servers.
162                self._shut_down_http_server(None)
163