1d0825bca7fe65beaee391d30da42e937db621564Steve Block#!/usr/bin/env python
25e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block# Copyright (C) 2010 Google Inc. All rights reserved.
3d0825bca7fe65beaee391d30da42e937db621564Steve Block#
4d0825bca7fe65beaee391d30da42e937db621564Steve Block# Redistribution and use in source and binary forms, with or without
5d0825bca7fe65beaee391d30da42e937db621564Steve Block# modification, are permitted provided that the following conditions are
6d0825bca7fe65beaee391d30da42e937db621564Steve Block# met:
7d0825bca7fe65beaee391d30da42e937db621564Steve Block#
8d0825bca7fe65beaee391d30da42e937db621564Steve Block#     * Redistributions of source code must retain the above copyright
9d0825bca7fe65beaee391d30da42e937db621564Steve Block# notice, this list of conditions and the following disclaimer.
10d0825bca7fe65beaee391d30da42e937db621564Steve Block#     * Redistributions in binary form must reproduce the above
11d0825bca7fe65beaee391d30da42e937db621564Steve Block# copyright notice, this list of conditions and the following disclaimer
12d0825bca7fe65beaee391d30da42e937db621564Steve Block# in the documentation and/or other materials provided with the
13d0825bca7fe65beaee391d30da42e937db621564Steve Block# distribution.
145e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block#     * Neither the name of Google Inc. nor the names of its
15d0825bca7fe65beaee391d30da42e937db621564Steve Block# contributors may be used to endorse or promote products derived from
16d0825bca7fe65beaee391d30da42e937db621564Steve Block# this software without specific prior written permission.
17d0825bca7fe65beaee391d30da42e937db621564Steve Block#
18d0825bca7fe65beaee391d30da42e937db621564Steve Block# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19d0825bca7fe65beaee391d30da42e937db621564Steve Block# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20d0825bca7fe65beaee391d30da42e937db621564Steve Block# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21d0825bca7fe65beaee391d30da42e937db621564Steve Block# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22d0825bca7fe65beaee391d30da42e937db621564Steve Block# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23d0825bca7fe65beaee391d30da42e937db621564Steve Block# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24d0825bca7fe65beaee391d30da42e937db621564Steve Block# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25d0825bca7fe65beaee391d30da42e937db621564Steve Block# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26d0825bca7fe65beaee391d30da42e937db621564Steve Block# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27d0825bca7fe65beaee391d30da42e937db621564Steve Block# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28d0825bca7fe65beaee391d30da42e937db621564Steve Block# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29d0825bca7fe65beaee391d30da42e937db621564Steve Block
308a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block"""Chromium Win implementation of the Port interface."""
31d0825bca7fe65beaee391d30da42e937db621564Steve Block
32dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockimport logging
33d0825bca7fe65beaee391d30da42e937db621564Steve Blockimport sys
34d0825bca7fe65beaee391d30da42e937db621564Steve Block
358a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockimport chromium
36d0825bca7fe65beaee391d30da42e937db621564Steve Block
37dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block_log = logging.getLogger("webkitpy.layout_tests.port.chromium_win")
38dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
39d0825bca7fe65beaee391d30da42e937db621564Steve Block
4081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochdef os_version(windows_version=None):
4181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if not windows_version:
4281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if hasattr(sys, 'getwindowsversion'):
4381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            windows_version = tuple(sys.getwindowsversion()[:2])
4481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        else:
4581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            # Make up something for testing.
4681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            windows_version = (5, 1)
4781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
4881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    version_strings = {
4981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        (6, 1): 'win7',
5081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        (6, 0): 'vista',
5181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        (5, 1): 'xp',
5281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
5381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return version_strings[windows_version]
5481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
5581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
568a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockclass ChromiumWinPort(chromium.ChromiumPort):
578a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    """Chromium Win implementation of the Port class."""
5881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    # FIXME: Figure out how to unify this with base.TestConfiguration.all_systems()?
5981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    SUPPORTED_VERSIONS = ('xp', 'vista', 'win7')
6081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
6181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    # FIXME: Do we need mac-snowleopard here, like the base win port?
6281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FALLBACK_PATHS = {
6381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        'xp': ['chromium-win-xp', 'chromium-win-vista', 'chromium-win', 'chromium', 'win', 'mac'],
6481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        'vista': ['chromium-win-vista', 'chromium-win', 'chromium', 'win', 'mac'],
6581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        'win7': ['chromium-win', 'chromium', 'win', 'mac'],
6681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
678a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    def __init__(self, port_name=None, windows_version=None, **kwargs):
6981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        # We're a little generic here because this code is reused by the
7081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        # 'google-chrome' port as well as the 'mock-' and 'dryrun-' ports.
7181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        port_name = port_name or 'chromium-win'
722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        chromium.ChromiumPort.__init__(self, port_name=port_name, **kwargs)
7381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if port_name.endswith('-win'):
742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            self._version = os_version(windows_version)
752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            self._name = port_name + '-' + self._version
7681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        else:
7781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            self._version = port_name[port_name.index('-win-') + 5:]
7881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            assert self._version in self.SUPPORTED_VERSIONS
7981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        self._operating_system = 'win'
818a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
826c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    def setup_environ_for_server(self):
836c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        env = chromium.ChromiumPort.setup_environ_for_server(self)
846c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        # Put the cygwin directory first in the path to find cygwin1.dll.
856c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        env["PATH"] = "%s;%s" % (
866c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            self.path_from_chromium_base("third_party", "cygwin", "bin"),
876c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            env["PATH"])
886c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        # Configure the cygwin directory so that pywebsocket finds proper
896c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        # python executable to run cgi program.
906c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        env["CYGWIN_PATH"] = self.path_from_chromium_base(
916c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            "third_party", "cygwin", "bin")
9281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (sys.platform in ("cygwin", "win32") and self.get_option('register_cygwin')):
936c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            setup_mount = self.path_from_chromium_base("third_party",
946c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen                                                       "cygwin",
956c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen                                                       "setup_mount.bat")
96e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            self._executive.run_command([setup_mount])
976c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        return env
986c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
9981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    def baseline_path(self):
10081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if self.version() == 'win7':
10181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            # Win 7 is the newest version of windows, so it gets the base dir.
10281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return self._webkit_baseline_path('chromium-win')
10381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return self._webkit_baseline_path(self.name())
10481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
1058a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    def baseline_search_path(self):
10681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        port_names = self.FALLBACK_PATHS[self.version()]
1076c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        return map(self._webkit_baseline_path, port_names)
1088a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
109dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def check_build(self, needs_http):
110dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        result = chromium.ChromiumPort.check_build(self, needs_http)
111dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if not result:
112dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            _log.error('For complete Windows build requirements, please '
113dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                       'see:')
114dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            _log.error('')
115dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            _log.error('    http://dev.chromium.org/developers/how-tos/'
116dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                       'build-instructions-windows')
117dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return result
1188a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1198a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    def relative_test_filename(self, filename):
1208a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        path = filename[len(self.layout_tests_dir()) + 1:]
1218a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        return path.replace('\\', '/')
1228a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1238a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    #
1248a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    # PROTECTED ROUTINES
1258a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    #
1268a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    def _build_path(self, *comps):
127ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        if self.get_option('build_directory'):
128ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch            return self._filesystem.join(self.get_option('build_directory'),
129ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch                                         *comps)
130ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
131dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        p = self.path_from_chromium_base('webkit', *comps)
132ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        if self._filesystem.exists(p):
133dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return p
134545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        p = self.path_from_chromium_base('chrome', *comps)
1352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if self._filesystem.exists(p):
136545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            return p
1372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return self._filesystem.join(self.path_from_webkit_base(), 'Source', 'WebKit', 'chromium', *comps)
1388a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1398a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    def _lighttpd_path(self, *comps):
1408a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        return self.path_from_chromium_base('third_party', 'lighttpd', 'win',
1418a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block                                            *comps)
1428a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1438a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    def _path_to_apache(self):
1448a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        return self.path_from_chromium_base('third_party', 'cygwin', 'usr',
1458a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block                                            'sbin', 'httpd')
1468a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1478a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    def _path_to_apache_config_file(self):
148ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        return self._filesystem.join(self.layout_tests_dir(), 'http', 'conf', 'cygwin-httpd.conf')
1498a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1508a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    def _path_to_lighttpd(self):
1518a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        return self._lighttpd_path('LightTPD.exe')
1528a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1538a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    def _path_to_lighttpd_modules(self):
1548a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        return self._lighttpd_path('lib')
1558a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1568a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    def _path_to_lighttpd_php(self):
1578a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        return self._lighttpd_path('php5', 'php-cgi.exe')
1588a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
159dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def _path_to_driver(self, configuration=None):
160dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if not configuration:
161a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            configuration = self.get_option('configuration')
162f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        binary_name = 'DumpRenderTree.exe'
1635af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return self._build_path(configuration, binary_name)
1648a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1658a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    def _path_to_helper(self):
166f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        binary_name = 'LayoutTestHelper.exe'
167a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return self._build_path(self.get_option('configuration'), binary_name)
1688a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1698a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    def _path_to_image_diff(self):
170f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        binary_name = 'ImageDiff.exe'
171a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return self._build_path(self.get_option('configuration'), binary_name)
1728a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1738a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    def _path_to_wdiff(self):
1748a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        return self.path_from_chromium_base('third_party', 'cygwin', 'bin',
1758a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block                                            'wdiff.exe')
1768a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1778a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    def _shut_down_http_server(self, server_pid):
1788a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        """Shut down the lighttpd web server. Blocks until it's fully
1798a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        shut down.
1808a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1818a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        Args:
1828a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            server_pid: The process ID of the running server.
1838a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        """
18421939df44de1705786c545cd1bf519d47250322dBen Murdoch        # FIXME: Why are we ignoring server_pid and calling
18521939df44de1705786c545cd1bf519d47250322dBen Murdoch        # _kill_all instead of Executive.kill_process(pid)?
18621939df44de1705786c545cd1bf519d47250322dBen Murdoch        self._executive.kill_all("LightTPD.exe")
18721939df44de1705786c545cd1bf519d47250322dBen Murdoch        self._executive.kill_all("httpd.exe")
188