diff options
Diffstat (limited to 'WebKitTools/Scripts/webkitpy/layout_tests/port')
41 files changed, 0 insertions, 7074 deletions
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/__init__.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/__init__.py deleted file mode 100644 index e3ad6f4..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/__init__.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""Port-specific entrypoints for the layout tests test infrastructure.""" - -from factory import get diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/apache_http_server.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/apache_http_server.py deleted file mode 100644 index 46617f6..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/apache_http_server.py +++ /dev/null @@ -1,230 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""A class to start/stop the apache http server used by layout tests.""" - - -from __future__ import with_statement - -import codecs -import logging -import optparse -import os -import re -import subprocess -import sys - -import http_server_base - -_log = logging.getLogger("webkitpy.layout_tests.port.apache_http_server") - - -class LayoutTestApacheHttpd(http_server_base.HttpServerBase): - - def __init__(self, port_obj, output_dir): - """Args: - port_obj: handle to the platform-specific routines - output_dir: the absolute path to the layout test result directory - """ - http_server_base.HttpServerBase.__init__(self, port_obj) - self._output_dir = output_dir - self._httpd_proc = None - port_obj.maybe_make_directory(output_dir) - - self.mappings = [{'port': 8000}, - {'port': 8080}, - {'port': 8081}, - {'port': 8443, 'sslcert': True}] - - # The upstream .conf file assumed the existence of /tmp/WebKit for - # placing apache files like the lock file there. - self._runtime_path = os.path.join("/tmp", "WebKit") - port_obj.maybe_make_directory(self._runtime_path) - - # The PID returned when Apache is started goes away (due to dropping - # privileges?). The proper controlling PID is written to a file in the - # apache runtime directory. - self._pid_file = os.path.join(self._runtime_path, 'httpd.pid') - - test_dir = self._port_obj.layout_tests_dir() - js_test_resources_dir = self._cygwin_safe_join(test_dir, "fast", "js", - "resources") - mime_types_path = self._cygwin_safe_join(test_dir, "http", "conf", - "mime.types") - cert_file = self._cygwin_safe_join(test_dir, "http", "conf", - "webkit-httpd.pem") - access_log = self._cygwin_safe_join(output_dir, "access_log.txt") - error_log = self._cygwin_safe_join(output_dir, "error_log.txt") - document_root = self._cygwin_safe_join(test_dir, "http", "tests") - - # FIXME: We shouldn't be calling a protected method of _port_obj! - executable = self._port_obj._path_to_apache() - if self._is_cygwin(): - executable = self._get_cygwin_path(executable) - - cmd = [executable, - '-f', "\"%s\"" % self._get_apache_config_file_path(test_dir, output_dir), - '-C', "\'DocumentRoot \"%s\"\'" % document_root, - '-c', "\'Alias /js-test-resources \"%s\"'" % js_test_resources_dir, - '-C', "\'Listen %s\'" % "127.0.0.1:8000", - '-C', "\'Listen %s\'" % "127.0.0.1:8081", - '-c', "\'TypesConfig \"%s\"\'" % mime_types_path, - '-c', "\'CustomLog \"%s\" common\'" % access_log, - '-c', "\'ErrorLog \"%s\"\'" % error_log, - '-C', "\'User \"%s\"\'" % os.environ.get("USERNAME", - os.environ.get("USER", ""))] - - if self._is_cygwin(): - cygbin = self._port_obj._path_from_base('third_party', 'cygwin', - 'bin') - # Not entirely sure why, but from cygwin we need to run the - # httpd command through bash. - self._start_cmd = [ - os.path.join(cygbin, 'bash.exe'), - '-c', - 'PATH=%s %s' % (self._get_cygwin_path(cygbin), " ".join(cmd)), - ] - else: - # TODO(ojan): When we get cygwin using Apache 2, use set the - # cert file for cygwin as well. - cmd.extend(['-c', "\'SSLCertificateFile %s\'" % cert_file]) - # Join the string here so that Cygwin/Windows and Mac/Linux - # can use the same code. Otherwise, we could remove the single - # quotes above and keep cmd as a sequence. - self._start_cmd = " ".join(cmd) - - def _is_cygwin(self): - return sys.platform in ("win32", "cygwin") - - def _cygwin_safe_join(self, *parts): - """Returns a platform appropriate path.""" - path = os.path.join(*parts) - if self._is_cygwin(): - return self._get_cygwin_path(path) - return path - - def _get_cygwin_path(self, path): - """Convert a Windows path to a cygwin path. - - The cygpath utility insists on converting paths that it thinks are - Cygwin root paths to what it thinks the correct roots are. So paths - such as "C:\b\slave\webkit-release\build\third_party\cygwin\bin" - are converted to plain "/usr/bin". To avoid this, we - do the conversion manually. - - The path is expected to be an absolute path, on any drive. - """ - drive_regexp = re.compile(r'([a-z]):[/\\]', re.IGNORECASE) - - def lower_drive(matchobj): - return '/cygdrive/%s/' % matchobj.group(1).lower() - path = drive_regexp.sub(lower_drive, path) - return path.replace('\\', '/') - - def _get_apache_config_file_path(self, test_dir, output_dir): - """Returns the path to the apache config file to use. - Args: - test_dir: absolute path to the LayoutTests directory. - output_dir: absolute path to the layout test results directory. - """ - httpd_config = self._port_obj._path_to_apache_config_file() - httpd_config_copy = os.path.join(output_dir, "httpd.conf") - # httpd.conf is always utf-8 according to http://archive.apache.org/gnats/10125 - with codecs.open(httpd_config, "r", "utf-8") as httpd_config_file: - httpd_conf = httpd_config_file.read() - if self._is_cygwin(): - # This is a gross hack, but it lets us use the upstream .conf file - # and our checked in cygwin. This tells the server the root - # directory to look in for .so modules. It will use this path - # plus the relative paths to the .so files listed in the .conf - # file. We have apache/cygwin checked into our tree so - # people don't have to install it into their cygwin. - cygusr = self._port_obj._path_from_base('third_party', 'cygwin', - 'usr') - httpd_conf = httpd_conf.replace('ServerRoot "/usr"', - 'ServerRoot "%s"' % self._get_cygwin_path(cygusr)) - - with codecs.open(httpd_config_copy, "w", "utf-8") as file: - file.write(httpd_conf) - - if self._is_cygwin(): - return self._get_cygwin_path(httpd_config_copy) - return httpd_config_copy - - def _get_virtual_host_config(self, document_root, port, ssl=False): - """Returns a <VirtualHost> directive block for an httpd.conf file. - It will listen to 127.0.0.1 on each of the given port. - """ - return '\n'.join(('<VirtualHost 127.0.0.1:%s>' % port, - 'DocumentRoot "%s"' % document_root, - ssl and 'SSLEngine On' or '', - '</VirtualHost>', '')) - - def _start_httpd_process(self): - """Starts the httpd process and returns whether there were errors.""" - # Use shell=True because we join the arguments into a string for - # the sake of Window/Cygwin and it needs quoting that breaks - # shell=False. - # FIXME: We should not need to be joining shell arguments into strings. - # shell=True is a trail of tears. - # Note: Not thread safe: http://bugs.python.org/issue2320 - self._httpd_proc = subprocess.Popen(self._start_cmd, - stderr=subprocess.PIPE, - shell=True) - err = self._httpd_proc.stderr.read() - if len(err): - _log.debug(err) - return False - return True - - def start(self): - """Starts the apache http server.""" - # Stop any currently running servers. - self.stop() - - _log.debug("Starting apache http server") - server_started = self.wait_for_action(self._start_httpd_process) - if server_started: - _log.debug("Apache started. Testing ports") - server_started = self.wait_for_action( - self.is_server_running_on_all_ports) - - if server_started: - _log.debug("Server successfully started") - else: - raise Exception('Failed to start http server') - - def stop(self): - """Stops the apache http server.""" - _log.debug("Shutting down any running http servers") - httpd_pid = None - if os.path.exists(self._pid_file): - httpd_pid = int(open(self._pid_file).readline()) - # FIXME: We shouldn't be calling a protected method of _port_obj! - self._port_obj._shut_down_http_server(httpd_pid) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py deleted file mode 100644 index 757318d..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py +++ /dev/null @@ -1,861 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the Google name 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""Abstract base class of Port-specific entrypoints for the layout tests -test infrastructure (the Port and Driver classes).""" - -import cgi -import difflib -import errno -import os -import shlex -import sys -import time - -import apache_http_server -import config as port_config -import http_lock -import http_server -import test_files -import websocket_server - -from webkitpy.common import system -from webkitpy.common.system import filesystem -from webkitpy.common.system import logutils -from webkitpy.common.system import path -from webkitpy.common.system.executive import Executive, ScriptError -from webkitpy.common.system.user import User - - -_log = logutils.get_logger(__file__) - - -class DummyOptions(object): - """Fake implementation of optparse.Values. Cloned from - webkitpy.tool.mocktool.MockOptions. - - """ - - def __init__(self, **kwargs): - # The caller can set option values using keyword arguments. We don't - # set any values by default because we don't know how this - # object will be used. Generally speaking unit tests should - # subclass this or provider wrapper functions that set a common - # set of options. - for key, value in kwargs.items(): - self.__dict__[key] = value - - -# FIXME: This class should merge with webkitpy.webkit_port at some point. -class Port(object): - """Abstract class for Port-specific hooks for the layout_test package.""" - - def __init__(self, port_name=None, options=None, - executive=None, - user=None, - filesystem=None, - config=None, - **kwargs): - self._name = port_name - self._options = options - if self._options is None: - # FIXME: Ideally we'd have a package-wide way to get a - # well-formed options object that had all of the necessary - # options defined on it. - self._options = DummyOptions() - self._executive = executive or Executive() - self._user = user or User() - self._filesystem = filesystem or system.filesystem.FileSystem() - self._config = config or port_config.Config(self._executive, - self._filesystem) - self._helper = None - self._http_server = None - self._webkit_base_dir = None - self._websocket_server = None - self._http_lock = None - - # Python's Popen has a bug that causes any pipes opened to a - # process that can't be executed to be leaked. Since this - # code is specifically designed to tolerate exec failures - # to gracefully handle cases where wdiff is not installed, - # the bug results in a massive file descriptor leak. As a - # workaround, if an exec failure is ever experienced for - # wdiff, assume it's not available. This will leak one - # file descriptor but that's better than leaking each time - # wdiff would be run. - # - # http://mail.python.org/pipermail/python-list/ - # 2008-August/505753.html - # http://bugs.python.org/issue3210 - self._wdiff_available = True - - self._pretty_patch_path = self.path_from_webkit_base("BugsSite", - "PrettyPatch", "prettify.rb") - self._pretty_patch_available = True - self.set_option_default('configuration', None) - if self._options.configuration is None: - self._options.configuration = self.default_configuration() - - def default_child_processes(self): - """Return the number of DumpRenderTree instances to use for this - port.""" - return self._executive.cpu_count() - - def baseline_path(self): - """Return the absolute path to the directory to store new baselines - in for this port.""" - raise NotImplementedError('Port.baseline_path') - - def baseline_search_path(self): - """Return a list of absolute paths to directories to search under for - baselines. The directories are searched in order.""" - raise NotImplementedError('Port.baseline_search_path') - - def check_build(self, needs_http): - """This routine is used to ensure that the build is up to date - and all the needed binaries are present.""" - raise NotImplementedError('Port.check_build') - - def check_sys_deps(self, needs_http): - """If the port needs to do some runtime checks to ensure that the - tests can be run successfully, it should override this routine. - This step can be skipped with --nocheck-sys-deps. - - Returns whether the system is properly configured.""" - return True - - def check_image_diff(self, override_step=None, logging=True): - """This routine is used to check whether image_diff binary exists.""" - raise NotImplementedError('Port.check_image_diff') - - def check_pretty_patch(self): - """Checks whether we can use the PrettyPatch ruby script.""" - - # check if Ruby is installed - try: - result = self._executive.run_command(['ruby', '--version']) - except OSError, e: - if e.errno in [errno.ENOENT, errno.EACCES, errno.ECHILD]: - _log.error("Ruby is not installed; " - "can't generate pretty patches.") - _log.error('') - return False - - if not self.path_exists(self._pretty_patch_path): - _log.error('Unable to find %s .' % self._pretty_patch_path) - _log.error("Can't generate pretty patches.") - _log.error('') - return False - - return True - - def compare_text(self, expected_text, actual_text): - """Return whether or not the two strings are *not* equal. This - routine is used to diff text output. - - While this is a generic routine, we include it in the Port - interface so that it can be overriden for testing purposes.""" - return expected_text != actual_text - - def diff_image(self, expected_contents, actual_contents, - diff_filename=None, tolerance=0): - """Compare two images and produce a delta image file. - - Return True if the two images are different, False if they are the same. - Also produce a delta image of the two images and write that into - |diff_filename| if it is not None. - - |tolerance| should be a percentage value (0.0 - 100.0). - If it is omitted, the port default tolerance value is used. - - """ - raise NotImplementedError('Port.diff_image') - - - def diff_text(self, expected_text, actual_text, - expected_filename, actual_filename): - """Returns a string containing the diff of the two text strings - in 'unified diff' format. - - While this is a generic routine, we include it in the Port - interface so that it can be overriden for testing purposes.""" - - # The filenames show up in the diff output, make sure they're - # raw bytes and not unicode, so that they don't trigger join() - # trying to decode the input. - def to_raw_bytes(str): - if isinstance(str, unicode): - return str.encode('utf-8') - return str - expected_filename = to_raw_bytes(expected_filename) - actual_filename = to_raw_bytes(actual_filename) - diff = difflib.unified_diff(expected_text.splitlines(True), - actual_text.splitlines(True), - expected_filename, - actual_filename) - return ''.join(diff) - - def driver_name(self): - """Returns the name of the actual binary that is performing the test, - so that it can be referred to in log messages. In most cases this - will be DumpRenderTree, but if a port uses a binary with a different - name, it can be overridden here.""" - return "DumpRenderTree" - - def expected_baselines(self, filename, suffix, all_baselines=False): - """Given a test name, finds where the baseline results are located. - - Args: - filename: absolute filename to test file - suffix: file suffix of the expected results, including dot; e.g. - '.txt' or '.png'. This should not be None, but may be an empty - string. - all_baselines: If True, return an ordered list of all baseline paths - for the given platform. If False, return only the first one. - Returns - a list of ( platform_dir, results_filename ), where - platform_dir - abs path to the top of the results tree (or test - tree) - results_filename - relative path from top of tree to the results - file - (os.path.join of the two gives you the full path to the file, - unless None was returned.) - Return values will be in the format appropriate for the current - platform (e.g., "\\" for path separators on Windows). If the results - file is not found, then None will be returned for the directory, - but the expected relative pathname will still be returned. - - This routine is generic but lives here since it is used in - conjunction with the other baseline and filename routines that are - platform specific. - """ - testname = os.path.splitext(self.relative_test_filename(filename))[0] - - baseline_filename = testname + '-expected' + suffix - - baseline_search_path = self.baseline_search_path() - - baselines = [] - for platform_dir in baseline_search_path: - if self.path_exists(self._filesystem.join(platform_dir, - baseline_filename)): - baselines.append((platform_dir, baseline_filename)) - - if not all_baselines and baselines: - return baselines - - # If it wasn't found in a platform directory, return the expected - # result in the test directory, even if no such file actually exists. - platform_dir = self.layout_tests_dir() - if self.path_exists(self._filesystem.join(platform_dir, - baseline_filename)): - baselines.append((platform_dir, baseline_filename)) - - if baselines: - return baselines - - return [(None, baseline_filename)] - - def expected_filename(self, filename, suffix): - """Given a test name, returns an absolute path to its expected results. - - If no expected results are found in any of the searched directories, - the directory in which the test itself is located will be returned. - The return value is in the format appropriate for the platform - (e.g., "\\" for path separators on windows). - - Args: - filename: absolute filename to test file - suffix: file suffix of the expected results, including dot; e.g. '.txt' - or '.png'. This should not be None, but may be an empty string. - platform: the most-specific directory name to use to build the - search list of directories, e.g., 'chromium-win', or - 'chromium-mac-leopard' (we follow the WebKit format) - - This routine is generic but is implemented here to live alongside - the other baseline and filename manipulation routines. - """ - platform_dir, baseline_filename = self.expected_baselines( - filename, suffix)[0] - if platform_dir: - return self._filesystem.join(platform_dir, baseline_filename) - return self._filesystem.join(self.layout_tests_dir(), baseline_filename) - - def expected_checksum(self, test): - """Returns the checksum of the image we expect the test to produce, or None if it is a text-only test.""" - path = self.expected_filename(test, '.checksum') - if not self.path_exists(path): - return None - return self._filesystem.read_text_file(path) - - def expected_image(self, test): - """Returns the image we expect the test to produce.""" - path = self.expected_filename(test, '.png') - if not self.path_exists(path): - return None - return self._filesystem.read_binary_file(path) - - def expected_text(self, test): - """Returns the text output we expect the test to produce.""" - # FIXME: DRT output is actually utf-8, but since we don't decode the - # output from DRT (instead treating it as a binary string), we read the - # baselines as a binary string, too. - path = self.expected_filename(test, '.txt') - if not self.path_exists(path): - return '' - text = self._filesystem.read_binary_file(path) - return text.strip("\r\n").replace("\r\n", "\n") + "\n" - - def filename_to_uri(self, filename): - """Convert a test file (which is an absolute path) to a URI.""" - LAYOUTTEST_HTTP_DIR = "http/tests/" - LAYOUTTEST_WEBSOCKET_DIR = "http/tests/websocket/tests/" - - relative_path = self.relative_test_filename(filename) - port = None - use_ssl = False - - if (relative_path.startswith(LAYOUTTEST_WEBSOCKET_DIR) - or relative_path.startswith(LAYOUTTEST_HTTP_DIR)): - relative_path = relative_path[len(LAYOUTTEST_HTTP_DIR):] - port = 8000 - - # Make http/tests/local run as local files. This is to mimic the - # logic in run-webkit-tests. - # - # TODO(dpranke): remove the media reference and the SSL reference? - if (port and not relative_path.startswith("local/") and - not relative_path.startswith("media/")): - if relative_path.startswith("ssl/"): - port += 443 - protocol = "https" - else: - protocol = "http" - return "%s://127.0.0.1:%u/%s" % (protocol, port, relative_path) - - return path.abspath_to_uri(os.path.abspath(filename)) - - def tests(self, paths): - """Return the list of tests found (relative to layout_tests_dir().""" - return test_files.find(self, paths) - - def test_dirs(self): - """Returns the list of top-level test directories. - - Used by --clobber-old-results.""" - layout_tests_dir = self.layout_tests_dir() - return filter(lambda x: self._filesystem.isdir(self._filesystem.join(layout_tests_dir, x)), - self._filesystem.listdir(layout_tests_dir)) - - def path_isdir(self, path): - """Return True if the path refers to a directory of tests.""" - # Used by test_expectations.py to apply rules to whole directories. - return self._filesystem.isdir(path) - - def path_exists(self, path): - """Return True if the path refers to an existing test or baseline.""" - # Used by test_expectations.py to determine if an entry refers to a - # valid test and by printing.py to determine if baselines exist. - return self._filesystem.exists(path) - - def driver_cmd_line(self): - """Prints the DRT command line that will be used.""" - driver = self.create_driver(0) - return driver.cmd_line() - - def update_baseline(self, path, data, encoding): - """Updates the baseline for a test. - - Args: - path: the actual path to use for baseline, not the path to - the test. This function is used to update either generic or - platform-specific baselines, but we can't infer which here. - data: contents of the baseline. - encoding: file encoding to use for the baseline. - """ - # FIXME: remove the encoding parameter in favor of text/binary - # functions. - if encoding is None: - self._filesystem.write_binary_file(path, data) - else: - self._filesystem.write_text_file(path, data) - - def uri_to_test_name(self, uri): - """Return the base layout test name for a given URI. - - This returns the test name for a given URI, e.g., if you passed in - "file:///src/LayoutTests/fast/html/keygen.html" it would return - "fast/html/keygen.html". - - """ - test = uri - if uri.startswith("file:///"): - prefix = path.abspath_to_uri(self.layout_tests_dir()) + "/" - return test[len(prefix):] - - if uri.startswith("http://127.0.0.1:8880/"): - # websocket tests - return test.replace('http://127.0.0.1:8880/', '') - - if uri.startswith("http://"): - # regular HTTP test - return test.replace('http://127.0.0.1:8000/', 'http/tests/') - - if uri.startswith("https://"): - return test.replace('https://127.0.0.1:8443/', 'http/tests/') - - raise NotImplementedError('unknown url type: %s' % uri) - - def layout_tests_dir(self): - """Return the absolute path to the top of the LayoutTests directory.""" - return self.path_from_webkit_base('LayoutTests') - - def skips_layout_test(self, test_name): - """Figures out if the givent test is being skipped or not. - - Test categories are handled as well.""" - for test_or_category in self.skipped_layout_tests(): - if test_or_category == test_name: - return True - category = self._filesystem.join(self.layout_tests_dir(), - test_or_category) - if (self._filesystem.isdir(category) and - test_name.startswith(test_or_category)): - return True - return False - - def maybe_make_directory(self, *path): - """Creates the specified directory if it doesn't already exist.""" - self._filesystem.maybe_make_directory(*path) - - def name(self): - """Return the name of the port (e.g., 'mac', 'chromium-win-xp'). - - Note that this is different from the test_platform_name(), which - may be different (e.g., 'win-xp' instead of 'chromium-win-xp'.""" - return self._name - - def get_option(self, name, default_value=None): - # FIXME: Eventually we should not have to do a test for - # hasattr(), and we should be able to just do - # self.options.value. See additional FIXME in the constructor. - if hasattr(self._options, name): - return getattr(self._options, name) - return default_value - - def set_option_default(self, name, default_value): - if not hasattr(self._options, name): - return setattr(self._options, name, default_value) - - def path_from_webkit_base(self, *comps): - """Returns the full path to path made by joining the top of the - WebKit source tree and the list of path components in |*comps|.""" - return self._config.path_from_webkit_base(*comps) - - def script_path(self, script_name): - return self._config.script_path(script_name) - - def path_to_test_expectations_file(self): - """Update the test expectations to the passed-in string. - - This is used by the rebaselining tool. Raises NotImplementedError - if the port does not use expectations files.""" - raise NotImplementedError('Port.path_to_test_expectations_file') - - def relative_test_filename(self, filename): - """Relative unix-style path for a filename under the LayoutTests - directory. Filenames outside the LayoutTests directory should raise - an error.""" - #assert(filename.startswith(self.layout_tests_dir())) - return filename[len(self.layout_tests_dir()) + 1:] - - def results_directory(self): - """Absolute path to the place to store the test results.""" - raise NotImplementedError('Port.results_directory') - - def setup_test_run(self): - """Perform port-specific work at the beginning of a test run.""" - pass - - def setup_environ_for_server(self): - """Perform port-specific work at the beginning of a server launch. - - Returns: - Operating-system's environment. - """ - return os.environ.copy() - - def show_results_html_file(self, results_filename): - """This routine should display the HTML file pointed at by - results_filename in a users' browser.""" - return self._user.open_url(results_filename) - - def create_driver(self, worker_number): - """Return a newly created base.Driver subclass for starting/stopping - the test driver.""" - raise NotImplementedError('Port.create_driver') - - def start_helper(self): - """If a port needs to reconfigure graphics settings or do other - things to ensure a known test configuration, it should override this - method.""" - pass - - def start_http_server(self): - """Start a web server if it is available. Do nothing if - it isn't. This routine is allowed to (and may) fail if a server - is already running.""" - if self.get_option('use_apache'): - self._http_server = apache_http_server.LayoutTestApacheHttpd(self, - self.get_option('results_directory')) - else: - self._http_server = http_server.Lighttpd(self, - self.get_option('results_directory')) - self._http_server.start() - - def start_websocket_server(self): - """Start a websocket server if it is available. Do nothing if - it isn't. This routine is allowed to (and may) fail if a server - is already running.""" - self._websocket_server = websocket_server.PyWebSocket(self, - self.get_option('results_directory')) - self._websocket_server.start() - - def acquire_http_lock(self): - self._http_lock = http_lock.HttpLock(None) - self._http_lock.wait_for_httpd_lock() - - def stop_helper(self): - """Shut down the test helper if it is running. Do nothing if - it isn't, or it isn't available. If a port overrides start_helper() - it must override this routine as well.""" - pass - - def stop_http_server(self): - """Shut down the http server if it is running. Do nothing if - it isn't, or it isn't available.""" - if self._http_server: - self._http_server.stop() - - def stop_websocket_server(self): - """Shut down the websocket server if it is running. Do nothing if - it isn't, or it isn't available.""" - if self._websocket_server: - self._websocket_server.stop() - - def release_http_lock(self): - if self._http_lock: - self._http_lock.cleanup_http_lock() - - def test_expectations(self): - """Returns the test expectations for this port. - - Basically this string should contain the equivalent of a - test_expectations file. See test_expectations.py for more details.""" - raise NotImplementedError('Port.test_expectations') - - def test_expectations_overrides(self): - """Returns an optional set of overrides for the test_expectations. - - This is used by ports that have code in two repositories, and where - it is possible that you might need "downstream" expectations that - temporarily override the "upstream" expectations until the port can - sync up the two repos.""" - return None - - def test_base_platform_names(self): - """Return a list of the 'base' platforms on your port. The base - platforms represent different architectures, operating systems, - or implementations (as opposed to different versions of a single - platform). For example, 'mac' and 'win' might be different base - platforms, wherease 'mac-tiger' and 'mac-leopard' might be - different platforms. This routine is used by the rebaselining tool - and the dashboards, and the strings correspond to the identifiers - in your test expectations (*not* necessarily the platform names - themselves).""" - raise NotImplementedError('Port.base_test_platforms') - - def test_platform_name(self): - """Returns the string that corresponds to the given platform name - in the test expectations. This may be the same as name(), or it - may be different. For example, chromium returns 'mac' for - 'chromium-mac'.""" - raise NotImplementedError('Port.test_platform_name') - - def test_platforms(self): - """Returns the list of test platform identifiers as used in the - test_expectations and on dashboards, the rebaselining tool, etc. - - Note that this is not necessarily the same as the list of ports, - which must be globally unique (e.g., both 'chromium-mac' and 'mac' - might return 'mac' as a test_platform name'.""" - raise NotImplementedError('Port.platforms') - - def test_platform_name_to_name(self, test_platform_name): - """Returns the Port platform name that corresponds to the name as - referenced in the expectations file. E.g., "mac" returns - "chromium-mac" on the Chromium ports.""" - raise NotImplementedError('Port.test_platform_name_to_name') - - def version(self): - """Returns a string indicating the version of a given platform, e.g. - '-leopard' or '-xp'. - - This is used to help identify the exact port when parsing test - expectations, determining search paths, and logging information.""" - raise NotImplementedError('Port.version') - - def test_repository_paths(self): - """Returns a list of (repository_name, repository_path) tuples - of its depending code base. By default it returns a list that only - contains a ('webkit', <webkitRepossitoryPath>) tuple. - """ - return [('webkit', self.layout_tests_dir())] - - - _WDIFF_DEL = '##WDIFF_DEL##' - _WDIFF_ADD = '##WDIFF_ADD##' - _WDIFF_END = '##WDIFF_END##' - - def _format_wdiff_output_as_html(self, wdiff): - wdiff = cgi.escape(wdiff) - wdiff = wdiff.replace(self._WDIFF_DEL, "<span class=del>") - wdiff = wdiff.replace(self._WDIFF_ADD, "<span class=add>") - wdiff = wdiff.replace(self._WDIFF_END, "</span>") - html = "<head><style>.del { background: #faa; } " - html += ".add { background: #afa; }</style></head>" - html += "<pre>%s</pre>" % wdiff - return html - - def _wdiff_command(self, actual_filename, expected_filename): - executable = self._path_to_wdiff() - return [executable, - "--start-delete=%s" % self._WDIFF_DEL, - "--end-delete=%s" % self._WDIFF_END, - "--start-insert=%s" % self._WDIFF_ADD, - "--end-insert=%s" % self._WDIFF_END, - actual_filename, - expected_filename] - - @staticmethod - def _handle_wdiff_error(script_error): - # Exit 1 means the files differed, any other exit code is an error. - if script_error.exit_code != 1: - raise script_error - - def _run_wdiff(self, actual_filename, expected_filename): - """Runs wdiff and may throw exceptions. - This is mostly a hook for unit testing.""" - # Diffs are treated as binary as they may include multiple files - # with conflicting encodings. Thus we do not decode the output. - command = self._wdiff_command(actual_filename, expected_filename) - wdiff = self._executive.run_command(command, decode_output=False, - error_handler=self._handle_wdiff_error) - return self._format_wdiff_output_as_html(wdiff) - - def wdiff_text(self, actual_filename, expected_filename): - """Returns a string of HTML indicating the word-level diff of the - contents of the two filenames. Returns an empty string if word-level - diffing isn't available.""" - if not self._wdiff_available: - return "" - try: - # It's possible to raise a ScriptError we pass wdiff invalid paths. - return self._run_wdiff(actual_filename, expected_filename) - except OSError, e: - if e.errno in [errno.ENOENT, errno.EACCES, errno.ECHILD]: - # Silently ignore cases where wdiff is missing. - self._wdiff_available = False - return "" - raise - - # This is a class variable so we can test error output easily. - _pretty_patch_error_html = "Failed to run PrettyPatch, see error log." - - def pretty_patch_text(self, diff_path): - if not self._pretty_patch_available: - return self._pretty_patch_error_html - command = ("ruby", "-I", os.path.dirname(self._pretty_patch_path), - self._pretty_patch_path, diff_path) - try: - # Diffs are treated as binary (we pass decode_output=False) as they - # may contain multiple files of conflicting encodings. - return self._executive.run_command(command, decode_output=False) - except OSError, e: - # If the system is missing ruby log the error and stop trying. - self._pretty_patch_available = False - _log.error("Failed to run PrettyPatch (%s): %s" % (command, e)) - return self._pretty_patch_error_html - except ScriptError, e: - # If ruby failed to run for some reason, log the command - # output and stop trying. - self._pretty_patch_available = False - _log.error("Failed to run PrettyPatch (%s):\n%s" % (command, - e.message_with_output())) - return self._pretty_patch_error_html - - def default_configuration(self): - return self._config.default_configuration() - - # - # PROTECTED ROUTINES - # - # The routines below should only be called by routines in this class - # or any of its subclasses. - # - def _webkit_build_directory(self, args): - return self._config.build_directory(args[0]) - - def _path_to_apache(self): - """Returns the full path to the apache binary. - - This is needed only by ports that use the apache_http_server module.""" - raise NotImplementedError('Port.path_to_apache') - - def _path_to_apache_config_file(self): - """Returns the full path to the apache binary. - - This is needed only by ports that use the apache_http_server module.""" - raise NotImplementedError('Port.path_to_apache_config_file') - - def _path_to_driver(self, configuration=None): - """Returns the full path to the test driver (DumpRenderTree).""" - raise NotImplementedError('Port._path_to_driver') - - def _path_to_webcore_library(self): - """Returns the full path to a built copy of WebCore.""" - raise NotImplementedError('Port.path_to_webcore_library') - - def _path_to_helper(self): - """Returns the full path to the layout_test_helper binary, which - is used to help configure the system for the test run, or None - if no helper is needed. - - This is likely only used by start/stop_helper().""" - raise NotImplementedError('Port._path_to_helper') - - def _path_to_image_diff(self): - """Returns the full path to the image_diff binary, or None if it - is not available. - - This is likely used only by diff_image()""" - raise NotImplementedError('Port.path_to_image_diff') - - def _path_to_lighttpd(self): - """Returns the path to the LigHTTPd binary. - - This is needed only by ports that use the http_server.py module.""" - raise NotImplementedError('Port._path_to_lighttpd') - - def _path_to_lighttpd_modules(self): - """Returns the path to the LigHTTPd modules directory. - - This is needed only by ports that use the http_server.py module.""" - raise NotImplementedError('Port._path_to_lighttpd_modules') - - def _path_to_lighttpd_php(self): - """Returns the path to the LigHTTPd PHP executable. - - This is needed only by ports that use the http_server.py module.""" - raise NotImplementedError('Port._path_to_lighttpd_php') - - def _path_to_wdiff(self): - """Returns the full path to the wdiff binary, or None if it is - not available. - - This is likely used only by wdiff_text()""" - raise NotImplementedError('Port._path_to_wdiff') - - def _shut_down_http_server(self, pid): - """Forcefully and synchronously kills the web server. - - This routine should only be called from http_server.py or its - subclasses.""" - raise NotImplementedError('Port._shut_down_http_server') - - def _webkit_baseline_path(self, platform): - """Return the full path to the top of the baseline tree for a - given platform.""" - return self._filesystem.join(self.layout_tests_dir(), 'platform', - platform) - - -class Driver: - """Abstract interface for the DumpRenderTree interface.""" - - def __init__(self, port, worker_number): - """Initialize a Driver to subsequently run tests. - - Typically this routine will spawn DumpRenderTree in a config - ready for subsequent input. - - port - reference back to the port object. - worker_number - identifier for a particular worker/driver instance - """ - raise NotImplementedError('Driver.__init__') - - def run_test(self, test_input): - """Run a single test and return the results. - - Note that it is okay if a test times out or crashes and leaves - the driver in an indeterminate state. The upper layers of the program - are responsible for cleaning up and ensuring things are okay. - - Args: - test_input: a TestInput object - - Returns a TestOutput object. - """ - raise NotImplementedError('Driver.run_test') - - # FIXME: This is static so we can test it w/o creating a Base instance. - @classmethod - def _command_wrapper(cls, wrapper_option): - # Hook for injecting valgrind or other runtime instrumentation, - # used by e.g. tools/valgrind/valgrind_tests.py. - wrapper = [] - browser_wrapper = os.environ.get("BROWSER_WRAPPER", None) - if browser_wrapper: - # FIXME: There seems to be no reason to use BROWSER_WRAPPER over --wrapper. - # Remove this code any time after the date listed below. - _log.error("BROWSER_WRAPPER is deprecated, please use --wrapper instead.") - _log.error("BROWSER_WRAPPER will be removed any time after June 1st 2010 and your scripts will break.") - wrapper += [browser_wrapper] - - if wrapper_option: - wrapper += shlex.split(wrapper_option) - return wrapper - - def poll(self): - """Returns None if the Driver is still running. Returns the returncode - if it has exited.""" - raise NotImplementedError('Driver.poll') - - def stop(self): - raise NotImplementedError('Driver.stop') diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/base_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/base_unittest.py deleted file mode 100644 index 8d586e3..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/base_unittest.py +++ /dev/null @@ -1,315 +0,0 @@ -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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 os -import sys -import tempfile -import unittest - -from webkitpy.common.system.executive import Executive, ScriptError -from webkitpy.common.system import executive_mock -from webkitpy.common.system import filesystem -from webkitpy.common.system import outputcapture -from webkitpy.common.system.path import abspath_to_uri -from webkitpy.thirdparty.mock import Mock -from webkitpy.tool import mocktool - -import base -import config -import config_mock - - -class PortTest(unittest.TestCase): - def test_format_wdiff_output_as_html(self): - output = "OUTPUT %s %s %s" % (base.Port._WDIFF_DEL, base.Port._WDIFF_ADD, base.Port._WDIFF_END) - html = base.Port()._format_wdiff_output_as_html(output) - expected_html = "<head><style>.del { background: #faa; } .add { background: #afa; }</style></head><pre>OUTPUT <span class=del> <span class=add> </span></pre>" - self.assertEqual(html, expected_html) - - def test_wdiff_command(self): - port = base.Port() - port._path_to_wdiff = lambda: "/path/to/wdiff" - command = port._wdiff_command("/actual/path", "/expected/path") - expected_command = [ - "/path/to/wdiff", - "--start-delete=##WDIFF_DEL##", - "--end-delete=##WDIFF_END##", - "--start-insert=##WDIFF_ADD##", - "--end-insert=##WDIFF_END##", - "/actual/path", - "/expected/path", - ] - self.assertEqual(command, expected_command) - - def _file_with_contents(self, contents, encoding="utf-8"): - new_file = tempfile.NamedTemporaryFile() - new_file.write(contents.encode(encoding)) - new_file.flush() - return new_file - - def test_pretty_patch_os_error(self): - port = base.Port(executive=executive_mock.MockExecutive2(exception=OSError)) - oc = outputcapture.OutputCapture() - oc.capture_output() - self.assertEqual(port.pretty_patch_text("patch.txt"), - port._pretty_patch_error_html) - - # This tests repeated calls to make sure we cache the result. - self.assertEqual(port.pretty_patch_text("patch.txt"), - port._pretty_patch_error_html) - oc.restore_output() - - def test_pretty_patch_script_error(self): - # FIXME: This is some ugly white-box test hacking ... - base._pretty_patch_available = True - port = base.Port(executive=executive_mock.MockExecutive2(exception=ScriptError)) - self.assertEqual(port.pretty_patch_text("patch.txt"), - port._pretty_patch_error_html) - - # This tests repeated calls to make sure we cache the result. - self.assertEqual(port.pretty_patch_text("patch.txt"), - port._pretty_patch_error_html) - - def test_run_wdiff(self): - executive = Executive() - # This may fail on some systems. We could ask the port - # object for the wdiff path, but since we don't know what - # port object to use, this is sufficient for now. - try: - wdiff_path = executive.run_command(["which", "wdiff"]).rstrip() - except Exception, e: - wdiff_path = None - - port = base.Port() - port._path_to_wdiff = lambda: wdiff_path - - if wdiff_path: - # "with tempfile.NamedTemporaryFile() as actual" does not seem to work in Python 2.5 - actual = self._file_with_contents(u"foo") - expected = self._file_with_contents(u"bar") - wdiff = port._run_wdiff(actual.name, expected.name) - expected_wdiff = "<head><style>.del { background: #faa; } .add { background: #afa; }</style></head><pre><span class=del>foo</span><span class=add>bar</span></pre>" - self.assertEqual(wdiff, expected_wdiff) - # Running the full wdiff_text method should give the same result. - port._wdiff_available = True # In case it's somehow already disabled. - wdiff = port.wdiff_text(actual.name, expected.name) - self.assertEqual(wdiff, expected_wdiff) - # wdiff should still be available after running wdiff_text with a valid diff. - self.assertTrue(port._wdiff_available) - actual.close() - expected.close() - - # Bogus paths should raise a script error. - self.assertRaises(ScriptError, port._run_wdiff, "/does/not/exist", "/does/not/exist2") - self.assertRaises(ScriptError, port.wdiff_text, "/does/not/exist", "/does/not/exist2") - # wdiff will still be available after running wdiff_text with invalid paths. - self.assertTrue(port._wdiff_available) - base._wdiff_available = True - - # If wdiff does not exist _run_wdiff should throw an OSError. - port._path_to_wdiff = lambda: "/invalid/path/to/wdiff" - self.assertRaises(OSError, port._run_wdiff, "foo", "bar") - - # wdiff_text should not throw an error if wdiff does not exist. - self.assertEqual(port.wdiff_text("foo", "bar"), "") - # However wdiff should not be available after running wdiff_text if wdiff is missing. - self.assertFalse(port._wdiff_available) - - def test_diff_text(self): - port = base.Port() - # Make sure that we don't run into decoding exceptions when the - # filenames are unicode, with regular or malformed input (expected or - # actual input is always raw bytes, not unicode). - port.diff_text('exp', 'act', 'exp.txt', 'act.txt') - port.diff_text('exp', 'act', u'exp.txt', 'act.txt') - port.diff_text('exp', 'act', u'a\xac\u1234\u20ac\U00008000', 'act.txt') - - port.diff_text('exp' + chr(255), 'act', 'exp.txt', 'act.txt') - port.diff_text('exp' + chr(255), 'act', u'exp.txt', 'act.txt') - - # Though expected and actual files should always be read in with no - # encoding (and be stored as str objects), test unicode inputs just to - # be safe. - port.diff_text(u'exp', 'act', 'exp.txt', 'act.txt') - port.diff_text( - u'a\xac\u1234\u20ac\U00008000', 'act', 'exp.txt', 'act.txt') - - # And make sure we actually get diff output. - diff = port.diff_text('foo', 'bar', 'exp.txt', 'act.txt') - self.assertTrue('foo' in diff) - self.assertTrue('bar' in diff) - self.assertTrue('exp.txt' in diff) - self.assertTrue('act.txt' in diff) - self.assertFalse('nosuchthing' in diff) - - def test_default_configuration_notfound(self): - # Test that we delegate to the config object properly. - port = base.Port(config=config_mock.MockConfig(default_configuration='default')) - self.assertEqual(port.default_configuration(), 'default') - - def test_layout_tests_skipping(self): - port = base.Port() - port.skipped_layout_tests = lambda: ['foo/bar.html', 'media'] - self.assertTrue(port.skips_layout_test('foo/bar.html')) - self.assertTrue(port.skips_layout_test('media/video-zoom.html')) - self.assertFalse(port.skips_layout_test('foo/foo.html')) - - def test_setup_test_run(self): - port = base.Port() - # This routine is a no-op. We just test it for coverage. - port.setup_test_run() - - def test_test_dirs(self): - port = base.Port() - dirs = port.test_dirs() - self.assertTrue('canvas' in dirs) - self.assertTrue('css2.1' in dirs) - - def test_filename_to_uri(self): - port = base.Port() - layout_test_dir = port.layout_tests_dir() - test_file = os.path.join(layout_test_dir, "foo", "bar.html") - - # On Windows, absolute paths are of the form "c:\foo.txt". However, - # all current browsers (except for Opera) normalize file URLs by - # prepending an additional "/" as if the absolute path was - # "/c:/foo.txt". This means that all file URLs end up with "file:///" - # at the beginning. - if sys.platform == 'win32': - prefix = "file:///" - path = test_file.replace("\\", "/") - else: - prefix = "file://" - path = test_file - - self.assertEqual(port.filename_to_uri(test_file), - abspath_to_uri(test_file)) - - def test_get_option__set(self): - options, args = optparse.OptionParser().parse_args([]) - options.foo = 'bar' - port = base.Port(options=options) - self.assertEqual(port.get_option('foo'), 'bar') - - def test_get_option__unset(self): - port = base.Port() - self.assertEqual(port.get_option('foo'), None) - - def test_get_option__default(self): - port = base.Port() - self.assertEqual(port.get_option('foo', 'bar'), 'bar') - - def test_set_option_default__unset(self): - port = base.Port() - port.set_option_default('foo', 'bar') - self.assertEqual(port.get_option('foo'), 'bar') - - def test_set_option_default__set(self): - options, args = optparse.OptionParser().parse_args([]) - options.foo = 'bar' - port = base.Port(options=options) - # This call should have no effect. - port.set_option_default('foo', 'new_bar') - self.assertEqual(port.get_option('foo'), 'bar') - - def test_name__unset(self): - port = base.Port() - self.assertEqual(port.name(), None) - - def test_name__set(self): - port = base.Port(port_name='foo') - self.assertEqual(port.name(), 'foo') - - -class VirtualTest(unittest.TestCase): - """Tests that various methods expected to be virtual are.""" - def assertVirtual(self, method, *args, **kwargs): - self.assertRaises(NotImplementedError, method, *args, **kwargs) - - def test_virtual_methods(self): - port = base.Port() - self.assertVirtual(port.baseline_path) - self.assertVirtual(port.baseline_search_path) - self.assertVirtual(port.check_build, None) - self.assertVirtual(port.check_image_diff) - self.assertVirtual(port.create_driver, 0) - self.assertVirtual(port.diff_image, None, None) - self.assertVirtual(port.path_to_test_expectations_file) - self.assertVirtual(port.test_platform_name) - self.assertVirtual(port.results_directory) - self.assertVirtual(port.test_expectations) - self.assertVirtual(port.test_base_platform_names) - self.assertVirtual(port.test_platform_name) - self.assertVirtual(port.test_platforms) - self.assertVirtual(port.test_platform_name_to_name, None) - self.assertVirtual(port.version) - self.assertVirtual(port._path_to_apache) - self.assertVirtual(port._path_to_apache_config_file) - self.assertVirtual(port._path_to_driver) - self.assertVirtual(port._path_to_helper) - self.assertVirtual(port._path_to_image_diff) - self.assertVirtual(port._path_to_lighttpd) - self.assertVirtual(port._path_to_lighttpd_modules) - self.assertVirtual(port._path_to_lighttpd_php) - self.assertVirtual(port._path_to_wdiff) - self.assertVirtual(port._shut_down_http_server, None) - - def test_virtual_driver_method(self): - self.assertRaises(NotImplementedError, base.Driver, base.Port(), - 0) - - def test_virtual_driver_methods(self): - class VirtualDriver(base.Driver): - def __init__(self): - pass - - driver = VirtualDriver() - self.assertVirtual(driver.run_test, None) - self.assertVirtual(driver.poll) - self.assertVirtual(driver.stop) - - -class DriverTest(unittest.TestCase): - - def _assert_wrapper(self, wrapper_string, expected_wrapper): - wrapper = base.Driver._command_wrapper(wrapper_string) - self.assertEqual(wrapper, expected_wrapper) - - def test_command_wrapper(self): - self._assert_wrapper(None, []) - self._assert_wrapper("valgrind", ["valgrind"]) - - # Validate that shlex works as expected. - command_with_spaces = "valgrind --smc-check=\"check with spaces!\" --foo" - expected_parse = ["valgrind", "--smc-check=check with spaces!", "--foo"] - self._assert_wrapper(command_with_spaces, expected_parse) - - -if __name__ == '__main__': - unittest.main() diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py deleted file mode 100644 index 8fe685a..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py +++ /dev/null @@ -1,555 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""Chromium implementations of the Port interface.""" - -from __future__ import with_statement - -import codecs -import errno -import logging -import os -import re -import shutil -import signal -import subprocess -import sys -import tempfile -import time -import webbrowser - -from webkitpy.common.system.path import cygpath -from webkitpy.layout_tests.layout_package import test_expectations -from webkitpy.layout_tests.layout_package import test_output - -import base -import http_server - -# Chromium DRT on OSX uses WebKitDriver. -if sys.platform == 'darwin': - import webkit - -import websocket_server - -_log = logging.getLogger("webkitpy.layout_tests.port.chromium") - - -# FIXME: This function doesn't belong in this package. -def check_file_exists(path_to_file, file_description, override_step=None, - logging=True): - """Verify the file is present where expected or log an error. - - Args: - file_name: The (human friendly) name or description of the file - you're looking for (e.g., "HTTP Server"). Used for error logging. - override_step: An optional string to be logged if the check fails. - logging: Whether or not log the error messages.""" - if not os.path.exists(path_to_file): - if logging: - _log.error('Unable to find %s' % file_description) - _log.error(' at %s' % path_to_file) - if override_step: - _log.error(' %s' % override_step) - _log.error('') - return False - return True - - -class ChromiumPort(base.Port): - """Abstract base class for Chromium implementations of the Port class.""" - - def __init__(self, **kwargs): - base.Port.__init__(self, **kwargs) - self._chromium_base_dir = None - - def baseline_path(self): - return self._webkit_baseline_path(self._name) - - def check_build(self, needs_http): - result = True - - dump_render_tree_binary_path = self._path_to_driver() - result = check_file_exists(dump_render_tree_binary_path, - 'test driver') and result - if result and self.get_option('build'): - result = self._check_driver_build_up_to_date( - self.get_option('configuration')) - else: - _log.error('') - - helper_path = self._path_to_helper() - if helper_path: - result = check_file_exists(helper_path, - 'layout test helper') and result - - if self.get_option('pixel_tests'): - result = self.check_image_diff( - 'To override, invoke with --no-pixel-tests') and result - - # It's okay if pretty patch isn't available, but we will at - # least log a message. - self.check_pretty_patch() - - return result - - def check_sys_deps(self, needs_http): - cmd = [self._path_to_driver(), '--check-layout-test-sys-deps'] - if self._executive.run_command(cmd, return_exit_code=True): - _log.error('System dependencies check failed.') - _log.error('To override, invoke with --nocheck-sys-deps') - _log.error('') - return False - return True - - def check_image_diff(self, override_step=None, logging=True): - image_diff_path = self._path_to_image_diff() - return check_file_exists(image_diff_path, 'image diff exe', - override_step, logging) - - def diff_image(self, expected_contents, actual_contents, - diff_filename=None): - executable = self._path_to_image_diff() - - tempdir = tempfile.mkdtemp() - expected_filename = os.path.join(tempdir, "expected.png") - with open(expected_filename, 'w+b') as file: - file.write(expected_contents) - actual_filename = os.path.join(tempdir, "actual.png") - with open(actual_filename, 'w+b') as file: - file.write(actual_contents) - - if diff_filename: - cmd = [executable, '--diff', expected_filename, - actual_filename, diff_filename] - else: - cmd = [executable, expected_filename, actual_filename] - - result = True - try: - exit_code = self._executive.run_command(cmd, return_exit_code=True) - if exit_code == 0: - # The images are the same. - result = False - elif exit_code != 1: - _log.error("image diff returned an exit code of " - + str(exit_code)) - # Returning False here causes the script to think that we - # successfully created the diff even though we didn't. If - # we return True, we think that the images match but the hashes - # don't match. - # FIXME: Figure out why image_diff returns other values. - result = False - except OSError, e: - if e.errno == errno.ENOENT or e.errno == errno.EACCES: - _compare_available = False - else: - raise e - finally: - shutil.rmtree(tempdir, ignore_errors=True) - return result - - def driver_name(self): - if self._options.use_drt: - return "DumpRenderTree" - return "test_shell" - - def path_from_chromium_base(self, *comps): - """Returns the full path to path made by joining the top of the - Chromium source tree and the list of path components in |*comps|.""" - if not self._chromium_base_dir: - abspath = os.path.abspath(__file__) - offset = abspath.find('third_party') - if offset == -1: - self._chromium_base_dir = os.path.join( - abspath[0:abspath.find('WebKitTools')], - 'WebKit', 'chromium') - else: - self._chromium_base_dir = abspath[0:offset] - return os.path.join(self._chromium_base_dir, *comps) - - def path_to_test_expectations_file(self): - return self.path_from_webkit_base('LayoutTests', 'platform', - 'chromium', 'test_expectations.txt') - - def results_directory(self): - try: - return self.path_from_chromium_base('webkit', - self.get_option('configuration'), - self.get_option('results_directory')) - except AssertionError: - return self._build_path(self.get_option('configuration'), - self.get_option('results_directory')) - - def setup_test_run(self): - # Delete the disk cache if any to ensure a clean test run. - dump_render_tree_binary_path = self._path_to_driver() - cachedir = os.path.split(dump_render_tree_binary_path)[0] - cachedir = os.path.join(cachedir, "cache") - if os.path.exists(cachedir): - shutil.rmtree(cachedir) - - def create_driver(self, worker_number): - """Starts a new Driver and returns a handle to it.""" - if self.get_option('use_drt') and sys.platform == 'darwin': - return webkit.WebKitDriver(self, worker_number) - return ChromiumDriver(self, worker_number) - - def start_helper(self): - helper_path = self._path_to_helper() - if helper_path: - _log.debug("Starting layout helper %s" % helper_path) - # Note: Not thread safe: http://bugs.python.org/issue2320 - self._helper = subprocess.Popen([helper_path], - stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=None) - is_ready = self._helper.stdout.readline() - if not is_ready.startswith('ready'): - _log.error("layout_test_helper failed to be ready") - - def stop_helper(self): - if self._helper: - _log.debug("Stopping layout test helper") - self._helper.stdin.write("x\n") - self._helper.stdin.close() - # wait() is not threadsafe and can throw OSError due to: - # http://bugs.python.org/issue1731717 - self._helper.wait() - - def test_base_platform_names(self): - return ('linux', 'mac', 'win') - - def test_expectations(self): - """Returns the test expectations for this port. - - Basically this string should contain the equivalent of a - test_expectations file. See test_expectations.py for more details.""" - expectations_path = self.path_to_test_expectations_file() - with codecs.open(expectations_path, "r", "utf-8") as file: - return file.read() - - def test_expectations_overrides(self): - # FIXME: This drt_overrides handling should be removed when we switch - # from tes_shell to DRT. - drt_overrides = '' - if self.get_option('use_drt'): - drt_overrides_path = self.path_from_webkit_base('LayoutTests', - 'platform', 'chromium', 'drt_expectations.txt') - if os.path.exists(drt_overrides_path): - with codecs.open(drt_overrides_path, "r", "utf-8") as file: - drt_overrides = file.read() - - try: - overrides_path = self.path_from_chromium_base('webkit', 'tools', - 'layout_tests', 'test_expectations.txt') - except AssertionError: - return None - if not os.path.exists(overrides_path): - return None - with codecs.open(overrides_path, "r", "utf-8") as file: - return file.read() + drt_overrides - - def skipped_layout_tests(self, extra_test_files=None): - expectations_str = self.test_expectations() - overrides_str = self.test_expectations_overrides() - test_platform_name = self.test_platform_name() - is_debug_mode = False - - all_test_files = self.tests([]) - if extra_test_files: - all_test_files.update(extra_test_files) - - expectations = test_expectations.TestExpectations( - self, all_test_files, expectations_str, test_platform_name, - is_debug_mode, is_lint_mode=True, overrides=overrides_str) - tests_dir = self.layout_tests_dir() - return [self.relative_test_filename(test) - for test in expectations.get_tests_with_result_type(test_expectations.SKIP)] - - def test_platform_names(self): - return self.test_base_platform_names() + ('win-xp', - 'win-vista', 'win-7') - - def test_platform_name_to_name(self, test_platform_name): - if test_platform_name in self.test_platform_names(): - return 'chromium-' + test_platform_name - raise ValueError('Unsupported test_platform_name: %s' % - test_platform_name) - - def test_repository_paths(self): - # Note: for JSON file's backward-compatibility we use 'chrome' rather - # than 'chromium' here. - repos = super(ChromiumPort, self).test_repository_paths() - repos.append(('chrome', self.path_from_chromium_base())) - return repos - - # - # PROTECTED METHODS - # - # These routines should only be called by other methods in this file - # or any subclasses. - # - - def _check_driver_build_up_to_date(self, configuration): - if configuration in ('Debug', 'Release'): - try: - debug_path = self._path_to_driver('Debug') - release_path = self._path_to_driver('Release') - - debug_mtime = os.stat(debug_path).st_mtime - release_mtime = os.stat(release_path).st_mtime - - if (debug_mtime > release_mtime and configuration == 'Release' or - release_mtime > debug_mtime and configuration == 'Debug'): - _log.warning('You are not running the most ' - 'recent DumpRenderTree binary. You need to ' - 'pass --debug or not to select between ' - 'Debug and Release.') - _log.warning('') - # This will fail if we don't have both a debug and release binary. - # That's fine because, in this case, we must already be running the - # most up-to-date one. - except OSError: - pass - return True - - def _chromium_baseline_path(self, platform): - if platform is None: - platform = self.name() - return self.path_from_webkit_base('LayoutTests', 'platform', platform) - - def _convert_path(self, path): - """Handles filename conversion for subprocess command line args.""" - # See note above in diff_image() for why we need this. - if sys.platform == 'cygwin': - return cygpath(path) - return path - - def _path_to_image_diff(self): - binary_name = 'image_diff' - if self.get_option('use_drt'): - binary_name = 'ImageDiff' - return self._build_path(self.get_option('configuration'), binary_name) - - -class ChromiumDriver(base.Driver): - """Abstract interface for test_shell.""" - - def __init__(self, port, worker_number): - self._port = port - self._worker_number = worker_number - self._image_path = None - if self._port.get_option('pixel_tests'): - self._image_path = os.path.join( - self._port.get_option('results_directory'), - 'png_result%s.png' % self._worker_number) - - def cmd_line(self): - cmd = self._command_wrapper(self._port.get_option('wrapper')) - cmd.append(self._port._path_to_driver()) - if self._port.get_option('pixel_tests'): - # See note above in diff_image() for why we need _convert_path(). - cmd.append("--pixel-tests=" + - self._port._convert_path(self._image_path)) - - if self._port.get_option('use_drt'): - cmd.append('--test-shell') - else: - cmd.append('--layout-tests') - - if self._port.get_option('startup_dialog'): - cmd.append('--testshell-startup-dialog') - - if self._port.get_option('gp_fault_error_box'): - cmd.append('--gp-fault-error-box') - - if self._port.get_option('js_flags') is not None: - cmd.append('--js-flags="' + self._port.get_option('js_flags') + '"') - - if self._port.get_option('multiple_loads') > 0: - cmd.append('--multiple-loads=' + str(self._port.get_option('multiple_loads'))) - - if self._port.get_option('accelerated_compositing'): - cmd.append('--enable-accelerated-compositing') - - if self._port.get_option('accelerated_2d_canvas'): - cmd.append('--enable-accelerated-2d-canvas') - return cmd - - def start(self): - # FIXME: Should be an error to call this method twice. - cmd = self.cmd_line() - - # We need to pass close_fds=True to work around Python bug #2320 - # (otherwise we can hang when we kill DumpRenderTree when we are running - # multiple threads). See http://bugs.python.org/issue2320 . - # Note that close_fds isn't supported on Windows, but this bug only - # shows up on Mac and Linux. - close_flag = sys.platform not in ('win32', 'cygwin') - self._proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - close_fds=close_flag) - - def poll(self): - # poll() is not threadsafe and can throw OSError due to: - # http://bugs.python.org/issue1731717 - return self._proc.poll() - - def _write_command_and_read_line(self, input=None): - """Returns a tuple: (line, did_crash)""" - try: - if input: - if isinstance(input, unicode): - # TestShell expects utf-8 - input = input.encode("utf-8") - self._proc.stdin.write(input) - # DumpRenderTree text output is always UTF-8. However some tests - # (e.g. webarchive) may spit out binary data instead of text so we - # don't bother to decode the output (for either DRT or test_shell). - line = self._proc.stdout.readline() - # We could assert() here that line correctly decodes as UTF-8. - return (line, False) - except IOError, e: - _log.error("IOError communicating w/ test_shell: " + str(e)) - return (None, True) - - def _test_shell_command(self, uri, timeoutms, checksum): - cmd = uri - if timeoutms: - cmd += ' ' + str(timeoutms) - if checksum: - cmd += ' ' + checksum - cmd += "\n" - return cmd - - def _output_image(self): - """Returns the image output which driver generated.""" - png_path = self._image_path - if png_path and os.path.isfile(png_path): - with open(png_path, 'rb') as image_file: - return image_file.read() - else: - return None - - def _output_image_with_retry(self): - # Retry a few more times because open() sometimes fails on Windows, - # raising "IOError: [Errno 13] Permission denied:" - retry_num = 50 - timeout_seconds = 5.0 - for i in range(retry_num): - try: - return self._output_image() - except IOError, e: - if e.errno == errno.EACCES: - time.sleep(timeout_seconds / retry_num) - else: - raise e - return self._output_image() - - def run_test(self, test_input): - output = [] - error = [] - crash = False - timeout = False - actual_uri = None - actual_checksum = None - - start_time = time.time() - - uri = self._port.filename_to_uri(test_input.filename) - cmd = self._test_shell_command(uri, test_input.timeout, - test_input.image_hash) - (line, crash) = self._write_command_and_read_line(input=cmd) - - while not crash and line.rstrip() != "#EOF": - # Make sure we haven't crashed. - if line == '' and self.poll() is not None: - # This is hex code 0xc000001d, which is used for abrupt - # termination. This happens if we hit ctrl+c from the prompt - # and we happen to be waiting on test_shell. - # sdoyon: Not sure for which OS and in what circumstances the - # above code is valid. What works for me under Linux to detect - # ctrl+c is for the subprocess returncode to be negative - # SIGINT. And that agrees with the subprocess documentation. - if (-1073741510 == self._proc.returncode or - - signal.SIGINT == self._proc.returncode): - raise KeyboardInterrupt - crash = True - break - - # Don't include #URL lines in our output - if line.startswith("#URL:"): - actual_uri = line.rstrip()[5:] - if uri != actual_uri: - # GURL capitalizes the drive letter of a file URL. - if (not re.search("^file:///[a-z]:", uri) or - uri.lower() != actual_uri.lower()): - _log.fatal("Test got out of sync:\n|%s|\n|%s|" % - (uri, actual_uri)) - raise AssertionError("test out of sync") - elif line.startswith("#MD5:"): - actual_checksum = line.rstrip()[5:] - elif line.startswith("#TEST_TIMED_OUT"): - timeout = True - # Test timed out, but we still need to read until #EOF. - elif actual_uri: - output.append(line) - else: - error.append(line) - - (line, crash) = self._write_command_and_read_line(input=None) - - run_time = time.time() - start_time - return test_output.TestOutput( - ''.join(output), self._output_image_with_retry(), actual_checksum, - crash, run_time, timeout, ''.join(error)) - - def stop(self): - if self._proc: - self._proc.stdin.close() - self._proc.stdout.close() - if self._proc.stderr: - self._proc.stderr.close() - if sys.platform not in ('win32', 'cygwin'): - # Closing stdin/stdout/stderr hangs sometimes on OS X, - # (see __init__(), above), and anyway we don't want to hang - # the harness if test_shell is buggy, so we wait a couple - # seconds to give test_shell a chance to clean up, but then - # force-kill the process if necessary. - KILL_TIMEOUT = 3.0 - timeout = time.time() + KILL_TIMEOUT - # poll() is not threadsafe and can throw OSError due to: - # http://bugs.python.org/issue1731717 - while self._proc.poll() is None and time.time() < timeout: - time.sleep(0.1) - # poll() is not threadsafe and can throw OSError due to: - # http://bugs.python.org/issue1731717 - if self._proc.poll() is None: - _log.warning('stopping test driver timed out, ' - 'killing it') - self._port._executive.kill_process(self._proc.pid) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu.py deleted file mode 100644 index 54a0fee..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu.py +++ /dev/null @@ -1,154 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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 HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -from __future__ import with_statement - -import codecs -import os -import sys - -import chromium_linux -import chromium_mac -import chromium_win - - -def get(**kwargs): - """Some tests have slightly different results when run while using - hardware acceleration. In those cases, we prepend an additional directory - to the baseline paths.""" - port_name = kwargs.get('port_name', None) - if port_name == 'chromium-gpu': - if sys.platform in ('cygwin', 'win32'): - port_name = 'chromium-gpu-win' - elif sys.platform == 'linux2': - port_name = 'chromium-gpu-linux' - elif sys.platform == 'darwin': - port_name = 'chromium-gpu-mac' - else: - raise NotImplementedError('unsupported platform: %s' % - sys.platform) - - if port_name == 'chromium-gpu-linux': - return ChromiumGpuLinuxPort(**kwargs) - - if port_name.startswith('chromium-gpu-mac'): - return ChromiumGpuMacPort(**kwargs) - - if port_name.startswith('chromium-gpu-win'): - return ChromiumGpuWinPort(**kwargs) - - raise NotImplementedError('unsupported port: %s' % port_name) - - -def _set_gpu_options(options): - if options: - if options.accelerated_compositing is None: - options.accelerated_compositing = True - if options.accelerated_2d_canvas is None: - options.accelerated_2d_canvas = True - if options.use_drt is None: - options.use_drt = True - - # FIXME: Remove this after http://codereview.chromium.org/5133001/ is enabled - # on the bots. - if options.builder_name is not None and not ' - GPU' in options.builder_name: - options.builder_name = options.builder_name + ' - GPU' - - -def _gpu_overrides(port): - try: - overrides_path = port.path_from_chromium_base('webkit', 'tools', - 'layout_tests', 'test_expectations_gpu.txt') - except AssertionError: - return None - if not os.path.exists(overrides_path): - return None - with codecs.open(overrides_path, "r", "utf-8") as file: - return file.read() - - -class ChromiumGpuLinuxPort(chromium_linux.ChromiumLinuxPort): - def __init__(self, **kwargs): - kwargs.setdefault('port_name', 'chromium-gpu-linux') - _set_gpu_options(kwargs.get('options')) - chromium_linux.ChromiumLinuxPort.__init__(self, **kwargs) - - def baseline_search_path(self): - # Mimic the Linux -> Win expectations fallback in the ordinary Chromium port. - return (map(self._webkit_baseline_path, ['chromium-gpu-linux', 'chromium-gpu-win', 'chromium-gpu']) + - chromium_linux.ChromiumLinuxPort.baseline_search_path(self)) - - def default_child_processes(self): - return 1 - - def path_to_test_expectations_file(self): - return self.path_from_webkit_base('LayoutTests', 'platform', - 'chromium-gpu', 'test_expectations.txt') - - def test_expectations_overrides(self): - return _gpu_overrides(self) - - -class ChromiumGpuMacPort(chromium_mac.ChromiumMacPort): - def __init__(self, **kwargs): - kwargs.setdefault('port_name', 'chromium-gpu-mac') - _set_gpu_options(kwargs.get('options')) - chromium_mac.ChromiumMacPort.__init__(self, **kwargs) - - def baseline_search_path(self): - return (map(self._webkit_baseline_path, ['chromium-gpu-mac', 'chromium-gpu']) + - chromium_mac.ChromiumMacPort.baseline_search_path(self)) - - def default_child_processes(self): - return 1 - - def path_to_test_expectations_file(self): - return self.path_from_webkit_base('LayoutTests', 'platform', - 'chromium-gpu', 'test_expectations.txt') - - def test_expectations_overrides(self): - return _gpu_overrides(self) - - -class ChromiumGpuWinPort(chromium_win.ChromiumWinPort): - def __init__(self, **kwargs): - kwargs.setdefault('port_name', 'chromium-gpu-win' + self.version()) - _set_gpu_options(kwargs.get('options')) - chromium_win.ChromiumWinPort.__init__(self, **kwargs) - - def baseline_search_path(self): - return (map(self._webkit_baseline_path, ['chromium-gpu-win', 'chromium-gpu']) + - chromium_win.ChromiumWinPort.baseline_search_path(self)) - - def default_child_processes(self): - return 1 - - def path_to_test_expectations_file(self): - return self.path_from_webkit_base('LayoutTests', 'platform', - 'chromium-gpu', 'test_expectations.txt') - - def test_expectations_overrides(self): - return _gpu_overrides(self) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py deleted file mode 100644 index 03bc98a..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_gpu_unittest.py +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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 HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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 os -import unittest - -from webkitpy.tool import mocktool -import chromium_gpu - - -class ChromiumGpuTest(unittest.TestCase): - def test_get_chromium_gpu_linux(self): - self.assertOverridesWorked('chromium-gpu-linux') - - def test_get_chromium_gpu_mac(self): - self.assertOverridesWorked('chromium-gpu-mac') - - def test_get_chromium_gpu_win(self): - self.assertOverridesWorked('chromium-gpu-win') - - def assertOverridesWorked(self, port_name): - # test that we got the right port - mock_options = mocktool.MockOptions(accelerated_compositing=None, - accelerated_2d_canvas=None, - builder_name='foo', - use_drt=None, - child_processes=None) - port = chromium_gpu.get(port_name=port_name, options=mock_options) - self.assertTrue(port._options.accelerated_compositing) - self.assertTrue(port._options.accelerated_2d_canvas) - self.assertTrue(port._options.use_drt) - self.assertEqual(port.default_child_processes(), 1) - self.assertEqual(port._options.builder_name, 'foo - GPU') - - # we use startswith() instead of Equal to gloss over platform versions. - self.assertTrue(port.name().startswith(port_name)) - - # test that it has the right directories in front of the search path. - paths = port.baseline_search_path() - self.assertEqual(port._webkit_baseline_path(port_name), paths[0]) - if port_name == 'chromium-gpu-linux': - self.assertEqual(port._webkit_baseline_path('chromium-gpu-win'), paths[1]) - self.assertEqual(port._webkit_baseline_path('chromium-gpu'), paths[2]) - else: - self.assertEqual(port._webkit_baseline_path('chromium-gpu'), paths[1]) - - # Test that we have the right expectations file. - self.assertTrue('chromium-gpu' in - port.path_to_test_expectations_file()) - -if __name__ == '__main__': - unittest.main() diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_linux.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_linux.py deleted file mode 100644 index b26a6b5..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_linux.py +++ /dev/null @@ -1,190 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""Chromium Linux implementation of the Port interface.""" - -import logging -import os -import signal - -import chromium - -_log = logging.getLogger("webkitpy.layout_tests.port.chromium_linux") - - -class ChromiumLinuxPort(chromium.ChromiumPort): - """Chromium Linux implementation of the Port class.""" - - def __init__(self, **kwargs): - kwargs.setdefault('port_name', 'chromium-linux') - chromium.ChromiumPort.__init__(self, **kwargs) - - def baseline_search_path(self): - port_names = ["chromium-linux", "chromium-win", "chromium", "win", "mac"] - return map(self._webkit_baseline_path, port_names) - - def check_build(self, needs_http): - result = chromium.ChromiumPort.check_build(self, needs_http) - if needs_http: - if self.get_option('use_apache'): - result = self._check_apache_install() and result - else: - result = self._check_lighttpd_install() and result - result = self._check_wdiff_install() and result - - if not result: - _log.error('For complete Linux build requirements, please see:') - _log.error('') - _log.error(' http://code.google.com/p/chromium/wiki/' - 'LinuxBuildInstructions') - return result - - def test_platform_name(self): - # We use 'linux' instead of 'chromium-linux' in test_expectations.txt. - return 'linux' - - def version(self): - # We don't have different versions on linux. - return '' - - # - # PROTECTED METHODS - # - - def _build_path(self, *comps): - base = self.path_from_chromium_base() - if os.path.exists(os.path.join(base, 'sconsbuild')): - return os.path.join(base, 'sconsbuild', *comps) - if os.path.exists(os.path.join(base, 'out', *comps)) or not self.get_option('use_drt'): - return os.path.join(base, 'out', *comps) - base = self.path_from_webkit_base() - if os.path.exists(os.path.join(base, 'sconsbuild')): - return os.path.join(base, 'sconsbuild', *comps) - return os.path.join(base, 'out', *comps) - - def _check_apache_install(self): - result = chromium.check_file_exists(self._path_to_apache(), - "apache2") - result = chromium.check_file_exists(self._path_to_apache_config_file(), - "apache2 config file") and result - if not result: - _log.error(' Please install using: "sudo apt-get install ' - 'apache2 libapache2-mod-php5"') - _log.error('') - return result - - def _check_lighttpd_install(self): - result = chromium.check_file_exists( - self._path_to_lighttpd(), "LigHTTPd executable") - result = chromium.check_file_exists(self._path_to_lighttpd_php(), - "PHP CGI executable") and result - result = chromium.check_file_exists(self._path_to_lighttpd_modules(), - "LigHTTPd modules") and result - if not result: - _log.error(' Please install using: "sudo apt-get install ' - 'lighttpd php5-cgi"') - _log.error('') - return result - - def _check_wdiff_install(self): - result = chromium.check_file_exists(self._path_to_wdiff(), 'wdiff') - if not result: - _log.error(' Please install using: "sudo apt-get install ' - 'wdiff"') - _log.error('') - # FIXME: The ChromiumMac port always returns True. - return result - - def _path_to_apache(self): - if self._is_redhat_based(): - return '/usr/sbin/httpd' - else: - return '/usr/sbin/apache2' - - def _path_to_apache_config_file(self): - if self._is_redhat_based(): - config_name = 'fedora-httpd.conf' - else: - config_name = 'apache2-debian-httpd.conf' - - return os.path.join(self.layout_tests_dir(), 'http', 'conf', - config_name) - - def _path_to_lighttpd(self): - return "/usr/sbin/lighttpd" - - def _path_to_lighttpd_modules(self): - return "/usr/lib/lighttpd" - - def _path_to_lighttpd_php(self): - return "/usr/bin/php-cgi" - - def _path_to_driver(self, configuration=None): - if not configuration: - configuration = self.get_option('configuration') - binary_name = 'test_shell' - if self.get_option('use_drt'): - binary_name = 'DumpRenderTree' - return self._build_path(configuration, binary_name) - - def _path_to_helper(self): - return None - - def _path_to_wdiff(self): - if self._is_redhat_based(): - return '/usr/bin/dwdiff' - else: - return '/usr/bin/wdiff' - - def _is_redhat_based(self): - return os.path.exists(os.path.join('/etc', 'redhat-release')) - - def _shut_down_http_server(self, server_pid): - """Shut down the lighttpd web server. Blocks until it's fully - shut down. - - Args: - server_pid: The process ID of the running server. - """ - # server_pid is not set when "http_server.py stop" is run manually. - if server_pid is None: - # TODO(mmoss) This isn't ideal, since it could conflict with - # lighttpd processes not started by http_server.py, - # but good enough for now. - self._executive.kill_all("lighttpd") - self._executive.kill_all("apache2") - else: - try: - os.kill(server_pid, signal.SIGTERM) - # TODO(mmoss) Maybe throw in a SIGKILL just to be sure? - except OSError: - # Sometimes we get a bad PID (e.g. from a stale httpd.pid - # file), so if kill fails on the given PID, just try to - # 'killall' web servers. - self._shut_down_http_server(None) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac.py deleted file mode 100644 index d1c383c..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac.py +++ /dev/null @@ -1,176 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""Chromium Mac implementation of the Port interface.""" - -import logging -import os -import platform -import signal - -import chromium - -from webkitpy.common.system.executive import Executive - -_log = logging.getLogger("webkitpy.layout_tests.port.chromium_mac") - - -class ChromiumMacPort(chromium.ChromiumPort): - """Chromium Mac implementation of the Port class.""" - - def __init__(self, **kwargs): - kwargs.setdefault('port_name', 'chromium-mac') - chromium.ChromiumPort.__init__(self, **kwargs) - - def baseline_search_path(self): - port_names = ["chromium-mac", "chromium", "mac" + self.version(), "mac"] - return map(self._webkit_baseline_path, port_names) - - def check_build(self, needs_http): - result = chromium.ChromiumPort.check_build(self, needs_http) - result = self._check_wdiff_install() and result - if not result: - _log.error('For complete Mac build requirements, please see:') - _log.error('') - _log.error(' http://code.google.com/p/chromium/wiki/' - 'MacBuildInstructions') - return result - - def default_child_processes(self): - # FIXME: we need to run single-threaded for now. See - # https://bugs.webkit.org/show_bug.cgi?id=38553. Unfortunately this - # routine is called right before the logger is configured, so if we - # try to _log.warning(), it gets thrown away. - import sys - sys.stderr.write("Defaulting to one child - see https://bugs.webkit.org/show_bug.cgi?id=38553\n") - return 1 - - def driver_name(self): - """name for this port's equivalent of DumpRenderTree.""" - if self.get_option('use_drt'): - return "DumpRenderTree" - return "TestShell" - - def test_platform_name(self): - # We use 'mac' instead of 'chromium-mac' - return 'mac' - - def version(self): - # FIXME: It's strange that this string is -version, not just version. - os_version_string = platform.mac_ver()[0] # e.g. "10.5.6" - if not os_version_string: - return '-leopard' - release_version = int(os_version_string.split('.')[1]) - # we don't support 'tiger' or earlier releases - if release_version == 5: - return '-leopard' - elif release_version == 6: - return '-snowleopard' - return '' - - # - # PROTECTED METHODS - # - - def _build_path(self, *comps): - path = self.path_from_chromium_base('xcodebuild', *comps) - if os.path.exists(path) or not self.get_option('use_drt'): - return path - return self.path_from_webkit_base('WebKit', 'chromium', 'xcodebuild', - *comps) - - def _check_wdiff_install(self): - try: - # We're ignoring the return and always returning True - self._executive.run_command([self._path_to_wdiff()], error_handler=Executive.ignore_error) - except OSError: - _log.warning('wdiff not found. Install using MacPorts or some ' - 'other means') - return True - - def _lighttpd_path(self, *comps): - return self.path_from_chromium_base('third_party', 'lighttpd', - 'mac', *comps) - - def _path_to_apache(self): - return '/usr/sbin/httpd' - - def _path_to_apache_config_file(self): - return os.path.join(self.layout_tests_dir(), 'http', 'conf', - 'apache2-httpd.conf') - - def _path_to_lighttpd(self): - return self._lighttpd_path('bin', 'lighttpd') - - def _path_to_lighttpd_modules(self): - return self._lighttpd_path('lib') - - def _path_to_lighttpd_php(self): - return self._lighttpd_path('bin', 'php-cgi') - - def _path_to_driver(self, configuration=None): - # FIXME: make |configuration| happy with case-sensitive file - # systems. - if not configuration: - configuration = self.get_option('configuration') - return self._build_path(configuration, self.driver_name() + '.app', - 'Contents', 'MacOS', self.driver_name()) - - def _path_to_helper(self): - binary_name = 'layout_test_helper' - if self.get_option('use_drt'): - binary_name = 'LayoutTestHelper' - return self._build_path(self.get_option('configuration'), binary_name) - - def _path_to_wdiff(self): - return 'wdiff' - - def _shut_down_http_server(self, server_pid): - """Shut down the lighttpd web server. Blocks until it's fully - shut down. - - Args: - server_pid: The process ID of the running server. - """ - # server_pid is not set when "http_server.py stop" is run manually. - if server_pid is None: - # TODO(mmoss) This isn't ideal, since it could conflict with - # lighttpd processes not started by http_server.py, - # but good enough for now. - self._executive.kill_all('lighttpd') - self._executive.kill_all('httpd') - else: - try: - os.kill(server_pid, signal.SIGTERM) - # TODO(mmoss) Maybe throw in a SIGKILL just to be sure? - except OSError: - # Sometimes we get a bad PID (e.g. from a stale httpd.pid - # file), so if kill fails on the given PID, just try to - # 'killall' web servers. - self._shut_down_http_server(None) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac_unittest.py deleted file mode 100644 index d63faa0..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac_unittest.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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 chromium_mac -import unittest - -from webkitpy.thirdparty.mock import Mock - - -class ChromiumMacPortTest(unittest.TestCase): - - def test_check_wdiff_install(self): - port = chromium_mac.ChromiumMacPort() - # Currently is always true, just logs if missing. - self.assertTrue(port._check_wdiff_install()) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py deleted file mode 100644 index 5396522..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py +++ /dev/null @@ -1,186 +0,0 @@ -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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 os -import unittest -import StringIO - -from webkitpy.tool import mocktool -from webkitpy.thirdparty.mock import Mock - -import chromium -import chromium_linux -import chromium_mac -import chromium_win - -class ChromiumDriverTest(unittest.TestCase): - - def setUp(self): - mock_port = Mock() - mock_port.get_option = lambda option_name: '' - self.driver = chromium.ChromiumDriver(mock_port, worker_number=0) - - def test_test_shell_command(self): - expected_command = "test.html 2 checksum\n" - self.assertEqual(self.driver._test_shell_command("test.html", 2, "checksum"), expected_command) - - def _assert_write_command_and_read_line(self, input=None, expected_line=None, expected_stdin=None, expected_crash=False): - if not expected_stdin: - if input: - expected_stdin = input - else: - # We reset stdin, so we should expect stdin.getValue = "" - expected_stdin = "" - self.driver._proc.stdin = StringIO.StringIO() - line, did_crash = self.driver._write_command_and_read_line(input) - self.assertEqual(self.driver._proc.stdin.getvalue(), expected_stdin) - self.assertEqual(line, expected_line) - self.assertEqual(did_crash, expected_crash) - - def test_write_command_and_read_line(self): - self.driver._proc = Mock() - # Set up to read 3 lines before we get an IOError - self.driver._proc.stdout = StringIO.StringIO("first\nsecond\nthird\n") - - unicode_input = u"I \u2661 Unicode" - utf8_input = unicode_input.encode("utf-8") - # Test unicode input conversion to utf-8 - self._assert_write_command_and_read_line(input=unicode_input, expected_stdin=utf8_input, expected_line="first\n") - # Test str() input. - self._assert_write_command_and_read_line(input="foo", expected_line="second\n") - # Test input=None - self._assert_write_command_and_read_line(expected_line="third\n") - # Test reading from a closed/empty stream. - # reading from a StringIO does not raise IOError like a real file would, so raise IOError manually. - def mock_readline(): - raise IOError - self.driver._proc.stdout.readline = mock_readline - self._assert_write_command_and_read_line(expected_crash=True) - - -class ChromiumPortTest(unittest.TestCase): - class TestMacPort(chromium_mac.ChromiumMacPort): - def __init__(self, options): - chromium_mac.ChromiumMacPort.__init__(self, - port_name='test-port', - options=options) - - def default_configuration(self): - self.default_configuration_called = True - return 'default' - - class TestLinuxPort(chromium_linux.ChromiumLinuxPort): - def __init__(self, options): - chromium_linux.ChromiumLinuxPort.__init__(self, - port_name='test-port', - options=options) - - def default_configuration(self): - self.default_configuration_called = True - return 'default' - - def test_path_to_image_diff(self): - mock_options = mocktool.MockOptions(use_drt=True) - port = ChromiumPortTest.TestLinuxPort(options=mock_options) - self.assertTrue(port._path_to_image_diff().endswith( - '/out/default/ImageDiff'), msg=port._path_to_image_diff()) - port = ChromiumPortTest.TestMacPort(options=mock_options) - self.assertTrue(port._path_to_image_diff().endswith( - '/xcodebuild/default/ImageDiff')) - # FIXME: Figure out how this is going to work on Windows. - #port = chromium_win.ChromiumWinPort('test-port', options=MockOptions()) - - def test_skipped_layout_tests(self): - mock_options = mocktool.MockOptions(use_drt=True) - port = ChromiumPortTest.TestLinuxPort(options=mock_options) - - fake_test = os.path.join(port.layout_tests_dir(), "fast/js/not-good.js") - - port.test_expectations = lambda: """BUG_TEST SKIP : fast/js/not-good.js = TEXT -LINUX WIN : fast/js/very-good.js = TIMEOUT PASS""" - port.test_expectations_overrides = lambda: '' - port.tests = lambda paths: set() - port.path_exists = lambda test: True - - skipped_tests = port.skipped_layout_tests(extra_test_files=[fake_test, ]) - self.assertTrue("fast/js/not-good.js" in skipped_tests) - - def test_default_configuration(self): - mock_options = mocktool.MockOptions() - port = ChromiumPortTest.TestLinuxPort(options=mock_options) - self.assertEquals(mock_options.configuration, 'default') - self.assertTrue(port.default_configuration_called) - - mock_options = mocktool.MockOptions(configuration=None) - port = ChromiumPortTest.TestLinuxPort(mock_options) - self.assertEquals(mock_options.configuration, 'default') - self.assertTrue(port.default_configuration_called) - - def test_diff_image(self): - class TestPort(ChromiumPortTest.TestLinuxPort): - def _path_to_image_diff(self): - return "/path/to/image_diff" - - class MockExecute: - def __init__(self, result): - self._result = result - - def run_command(self, - args, - cwd=None, - input=None, - error_handler=None, - return_exit_code=False, - return_stderr=True, - decode_output=False): - if return_exit_code: - return self._result - return '' - - mock_options = mocktool.MockOptions(use_drt=False) - port = ChromiumPortTest.TestLinuxPort(mock_options) - - # Images are different. - port._executive = MockExecute(0) - self.assertEquals(False, port.diff_image("EXPECTED", "ACTUAL")) - - # Images are the same. - port._executive = MockExecute(1) - self.assertEquals(True, port.diff_image("EXPECTED", "ACTUAL")) - - # There was some error running image_diff. - port._executive = MockExecute(2) - exception_raised = False - try: - port.diff_image("EXPECTED", "ACTUAL") - except ValueError, e: - exception_raised = True - self.assertFalse(exception_raised) - -if __name__ == '__main__': - unittest.main() diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py deleted file mode 100644 index 69b529a..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""Chromium Win implementation of the Port interface.""" - -import logging -import os -import sys - -import chromium - -_log = logging.getLogger("webkitpy.layout_tests.port.chromium_win") - - -class ChromiumWinPort(chromium.ChromiumPort): - """Chromium Win implementation of the Port class.""" - - def __init__(self, **kwargs): - kwargs.setdefault('port_name', 'chromium-win' + self.version()) - chromium.ChromiumPort.__init__(self, **kwargs) - - def setup_environ_for_server(self): - env = chromium.ChromiumPort.setup_environ_for_server(self) - # Put the cygwin directory first in the path to find cygwin1.dll. - env["PATH"] = "%s;%s" % ( - self.path_from_chromium_base("third_party", "cygwin", "bin"), - env["PATH"]) - # Configure the cygwin directory so that pywebsocket finds proper - # python executable to run cgi program. - env["CYGWIN_PATH"] = self.path_from_chromium_base( - "third_party", "cygwin", "bin") - if (sys.platform == "win32" and self.get_option('register_cygwin')): - setup_mount = self.path_from_chromium_base("third_party", - "cygwin", - "setup_mount.bat") - self._executive.run_command([setup_mount]) - return env - - def baseline_search_path(self): - port_names = [] - if self._name.endswith('-win-xp'): - port_names.append("chromium-win-xp") - if self._name.endswith('-win-xp') or self._name.endswith('-win-vista'): - port_names.append("chromium-win-vista") - # FIXME: This may need to include mac-snowleopard like win.py. - port_names.extend(["chromium-win", "chromium", "win", "mac"]) - return map(self._webkit_baseline_path, port_names) - - def check_build(self, needs_http): - result = chromium.ChromiumPort.check_build(self, needs_http) - if not result: - _log.error('For complete Windows build requirements, please ' - 'see:') - _log.error('') - _log.error(' http://dev.chromium.org/developers/how-tos/' - 'build-instructions-windows') - return result - - def relative_test_filename(self, filename): - path = filename[len(self.layout_tests_dir()) + 1:] - return path.replace('\\', '/') - - def test_platform_name(self): - # We return 'win-xp', not 'chromium-win-xp' here, for convenience. - return 'win' + self.version() - - def version(self): - if not hasattr(sys, 'getwindowsversion'): - return '' - winver = sys.getwindowsversion() - if winver[0] == 6 and (winver[1] == 1): - return '-7' - if winver[0] == 6 and (winver[1] == 0): - return '-vista' - if winver[0] == 5 and (winver[1] == 1 or winver[1] == 2): - return '-xp' - return '' - - # - # PROTECTED ROUTINES - # - - def _build_path(self, *comps): - p = self.path_from_chromium_base('webkit', *comps) - if os.path.exists(p): - return p - p = self.path_from_chromium_base('chrome', *comps) - if os.path.exists(p) or not self.get_option('use_drt'): - return p - return os.path.join(self.path_from_webkit_base(), 'WebKit', 'chromium', - *comps) - - def _lighttpd_path(self, *comps): - return self.path_from_chromium_base('third_party', 'lighttpd', 'win', - *comps) - - def _path_to_apache(self): - return self.path_from_chromium_base('third_party', 'cygwin', 'usr', - 'sbin', 'httpd') - - def _path_to_apache_config_file(self): - return os.path.join(self.layout_tests_dir(), 'http', 'conf', - 'cygwin-httpd.conf') - - def _path_to_lighttpd(self): - return self._lighttpd_path('LightTPD.exe') - - def _path_to_lighttpd_modules(self): - return self._lighttpd_path('lib') - - def _path_to_lighttpd_php(self): - return self._lighttpd_path('php5', 'php-cgi.exe') - - def _path_to_driver(self, configuration=None): - if not configuration: - configuration = self.get_option('configuration') - binary_name = 'test_shell.exe' - if self.get_option('use_drt'): - binary_name = 'DumpRenderTree.exe' - return self._build_path(configuration, binary_name) - - def _path_to_helper(self): - binary_name = 'layout_test_helper.exe' - if self.get_option('use_drt'): - binary_name = 'LayoutTestHelper.exe' - return self._build_path(self.get_option('configuration'), binary_name) - - def _path_to_image_diff(self): - binary_name = 'image_diff.exe' - if self.get_option('use_drt'): - binary_name = 'ImageDiff.exe' - return self._build_path(self.get_option('configuration'), binary_name) - - def _path_to_wdiff(self): - return self.path_from_chromium_base('third_party', 'cygwin', 'bin', - 'wdiff.exe') - - def _shut_down_http_server(self, server_pid): - """Shut down the lighttpd web server. Blocks until it's fully - shut down. - - Args: - server_pid: The process ID of the running server. - """ - # FIXME: Why are we ignoring server_pid and calling - # _kill_all instead of Executive.kill_process(pid)? - self._executive.kill_all("LightTPD.exe") - self._executive.kill_all("httpd.exe") diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win_unittest.py deleted file mode 100644 index 36f3c6b..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win_unittest.py +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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 os -import sys -import unittest -import chromium_win -from webkitpy.common.system import outputcapture -from webkitpy.tool import mocktool - - -class ChromiumWinTest(unittest.TestCase): - - class RegisterCygwinOption(object): - def __init__(self): - self.register_cygwin = True - - def setUp(self): - self.orig_platform = sys.platform - - def tearDown(self): - sys.platform = self.orig_platform - - def _mock_path_from_chromium_base(self, *comps): - return os.path.join("/chromium/src", *comps) - - def test_setup_environ_for_server(self): - port = chromium_win.ChromiumWinPort() - port._executive = mocktool.MockExecutive(should_log=True) - port.path_from_chromium_base = self._mock_path_from_chromium_base - output = outputcapture.OutputCapture() - orig_environ = os.environ.copy() - env = output.assert_outputs(self, port.setup_environ_for_server) - self.assertEqual(orig_environ["PATH"], os.environ["PATH"]) - self.assertNotEqual(env["PATH"], os.environ["PATH"]) - - def test_setup_environ_for_server_register_cygwin(self): - sys.platform = "win32" - port = chromium_win.ChromiumWinPort( - options=ChromiumWinTest.RegisterCygwinOption()) - port._executive = mocktool.MockExecutive(should_log=True) - port.path_from_chromium_base = self._mock_path_from_chromium_base - setup_mount = self._mock_path_from_chromium_base("third_party", - "cygwin", - "setup_mount.bat") - expected_stderr = "MOCK run_command: %s\n" % [setup_mount] - output = outputcapture.OutputCapture() - output.assert_outputs(self, port.setup_environ_for_server, - expected_stderr=expected_stderr) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/config.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/config.py deleted file mode 100644 index 9aec637..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/config.py +++ /dev/null @@ -1,169 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""Wrapper objects for WebKit-specific utility routines.""" - -# FIXME: This file needs to be unified with common/checkout/scm.py and -# common/config/ports.py . - -import os - -from webkitpy.common.system import logutils -from webkitpy.common.system import executive - - -_log = logutils.get_logger(__file__) - -# -# FIXME: This is used to record if we've already hit the filesystem to look -# for a default configuration. We cache this to speed up the unit tests, -# but this can be reset with clear_cached_configuration(). This should be -# replaced with us consistently using MockConfigs() for tests that don't -# hit the filesystem at all and provide a reliable value. -# -_have_determined_configuration = False -_configuration = "Release" - - -def clear_cached_configuration(): - global _have_determined_configuration, _configuration - _have_determined_configuration = False - _configuration = "Release" - - -class Config(object): - _FLAGS_FROM_CONFIGURATIONS = { - "Debug": "--debug", - "Release": "--release", - } - - def __init__(self, executive, filesystem): - self._executive = executive - self._filesystem = filesystem - self._webkit_base_dir = None - self._default_configuration = None - self._build_directories = {} - - def build_directory(self, configuration): - """Returns the path to the build directory for the configuration.""" - if configuration: - flags = ["--configuration", - self._FLAGS_FROM_CONFIGURATIONS[configuration]] - else: - configuration = "" - flags = ["--top-level"] - - if not self._build_directories.get(configuration): - args = ["perl", self._script_path("webkit-build-directory")] + flags - self._build_directories[configuration] = ( - self._executive.run_command(args).rstrip()) - - return self._build_directories[configuration] - - def build_dumprendertree(self, configuration): - """Builds DRT in the given configuration. - - Returns True if the build was successful and up-to-date.""" - flag = self._FLAGS_FROM_CONFIGURATIONS[configuration] - exit_code = self._executive.run_command([ - self._script_path("build-dumprendertree"), flag], - return_exit_code=True) - if exit_code != 0: - _log.error("Failed to build DumpRenderTree") - return False - return True - - def default_configuration(self): - """Returns the default configuration for the user. - - Returns the value set by 'set-webkit-configuration', or "Release" - if that has not been set. This mirrors the logic in webkitdirs.pm.""" - if not self._default_configuration: - self._default_configuration = self._determine_configuration() - if not self._default_configuration: - self._default_configuration = 'Release' - if self._default_configuration not in self._FLAGS_FROM_CONFIGURATIONS: - _log.warn("Configuration \"%s\" is not a recognized value.\n" % - self._default_configuration) - _log.warn("Scripts may fail. " - "See 'set-webkit-configuration --help'.") - return self._default_configuration - - def path_from_webkit_base(self, *comps): - return self._filesystem.join(self.webkit_base_dir(), *comps) - - def webkit_base_dir(self): - """Returns the absolute path to the top of the WebKit tree. - - Raises an AssertionError if the top dir can't be determined.""" - # Note: this code somewhat duplicates the code in - # scm.find_checkout_root(). However, that code only works if the top - # of the SCM repository also matches the top of the WebKit tree. The - # Chromium ports, for example, only check out subdirectories like - # WebKitTools/Scripts, and so we still have to do additional work - # to find the top of the tree. - # - # This code will also work if there is no SCM system at all. - if not self._webkit_base_dir: - abspath = os.path.abspath(__file__) - self._webkit_base_dir = abspath[0:abspath.find('WebKitTools')] - return self._webkit_base_dir - - def _script_path(self, script_name): - return self._filesystem.join(self.webkit_base_dir(), "WebKitTools", - "Scripts", script_name) - - def _determine_configuration(self): - # This mirrors the logic in webkitdirs.pm:determineConfiguration(). - # - # FIXME: See the comment at the top of the file regarding unit tests - # and our use of global mutable static variables. - global _have_determined_configuration, _configuration - if not _have_determined_configuration: - contents = self._read_configuration() - if not contents: - contents = "Release" - if contents == "Deployment": - contents = "Release" - if contents == "Development": - contents = "Debug" - _configuration = contents - _have_determined_configuration = True - return _configuration - - def _read_configuration(self): - try: - configuration_path = self._filesystem.join(self.build_directory(None), - "Configuration") - if not self._filesystem.exists(configuration_path): - return None - except (OSError, executive.ScriptError): - return None - - return self._filesystem.read_text_file(configuration_path).rstrip() diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/config_mock.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/config_mock.py deleted file mode 100644 index af71fa3..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/config_mock.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""Wrapper objects for WebKit-specific utility routines.""" - - -class MockConfig(object): - def __init__(self, default_configuration='Release'): - self._default_configuration = default_configuration - - def build_directory(self, configuration): - return "/build" - - def build_dumprendertree(self, configuration): - return True - - def default_configuration(self): - return self._default_configuration - - def path_from_webkit_base(self, *comps): - return "/" + "/".join(list(comps)) - - def webkit_base_dir(self): - return "/" diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/config_standalone.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/config_standalone.py deleted file mode 100644 index 3dec3b9..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/config_standalone.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""FIXME: This script is used by -config_unittest.test_default_configuration__standalone() to read the -default configuration to work around any possible caching / reset bugs. See -https://bugs.webkit.org/show_bug?id=49360 for the motivation. We can remove -this test when we remove the global configuration cache in config.py.""" - -import os -import unittest -import sys - - -# Ensure that webkitpy is in PYTHONPATH. -this_dir = os.path.abspath(sys.path[0]) -up = os.path.dirname -script_dir = up(up(up(this_dir))) -if script_dir not in sys.path: - sys.path.append(script_dir) - -from webkitpy.common.system import executive -from webkitpy.common.system import executive_mock -from webkitpy.common.system import filesystem -from webkitpy.common.system import filesystem_mock - -import config - - -def main(argv=None): - if not argv: - argv = sys.argv - - if len(argv) == 3 and argv[1] == '--mock': - e = executive_mock.MockExecutive2(output='foo') - fs = filesystem_mock.MockFileSystem({'foo/Configuration': argv[2]}) - else: - e = executive.Executive() - fs = filesystem.FileSystem() - - c = config.Config(e, fs) - print c.default_configuration() - -if __name__ == '__main__': - main() diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/config_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/config_unittest.py deleted file mode 100644 index 2d23691..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/config_unittest.py +++ /dev/null @@ -1,201 +0,0 @@ -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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 os -import sys -import unittest - -from webkitpy.common.system import executive -from webkitpy.common.system import executive_mock -from webkitpy.common.system import filesystem -from webkitpy.common.system import filesystem_mock -from webkitpy.common.system import outputcapture - -import config - - -def mock_run_command(arg_list): - # Set this to True to test actual output (where possible). - integration_test = False - if integration_test: - return executive.Executive().run_command(arg_list) - - if 'webkit-build-directory' in arg_list[1]: - return mock_webkit_build_directory(arg_list[2:]) - return 'Error' - - -def mock_webkit_build_directory(arg_list): - if arg_list == ['--top-level']: - return '/WebKitBuild' - elif arg_list == ['--configuration', '--debug']: - return '/WebKitBuild/Debug' - elif arg_list == ['--configuration', '--release']: - return '/WebKitBuild/Release' - return 'Error' - - -class ConfigTest(unittest.TestCase): - def tearDown(self): - config.clear_cached_configuration() - - def make_config(self, output='', files={}, exit_code=0, exception=None, - run_command_fn=None): - e = executive_mock.MockExecutive2(output=output, exit_code=exit_code, - exception=exception, - run_command_fn=run_command_fn) - fs = filesystem_mock.MockFileSystem(files) - return config.Config(e, fs) - - def assert_configuration(self, contents, expected): - # This tests that a configuration file containing - # _contents_ ends up being interpreted as _expected_. - c = self.make_config('foo', {'foo/Configuration': contents}) - self.assertEqual(c.default_configuration(), expected) - - def test_build_directory(self): - # --top-level - c = self.make_config(run_command_fn=mock_run_command) - self.assertTrue(c.build_directory(None).endswith('WebKitBuild')) - - # Test again to check caching - self.assertTrue(c.build_directory(None).endswith('WebKitBuild')) - - # Test other values - self.assertTrue(c.build_directory('Release').endswith('/Release')) - self.assertTrue(c.build_directory('Debug').endswith('/Debug')) - self.assertRaises(KeyError, c.build_directory, 'Unknown') - - def test_build_dumprendertree__success(self): - c = self.make_config(exit_code=0) - self.assertTrue(c.build_dumprendertree("Debug")) - self.assertTrue(c.build_dumprendertree("Release")) - self.assertRaises(KeyError, c.build_dumprendertree, "Unknown") - - def test_build_dumprendertree__failure(self): - c = self.make_config(exit_code=-1) - - # FIXME: Build failures should log errors. However, the message we - # get depends on how we're being called; as a standalone test, - # we'll get the "no handlers found" message. As part of - # test-webkitpy, we get the actual message. Really, we need - # outputcapture to install its own handler. - oc = outputcapture.OutputCapture() - oc.capture_output() - self.assertFalse(c.build_dumprendertree('Debug')) - oc.restore_output() - - oc.capture_output() - self.assertFalse(c.build_dumprendertree('Release')) - oc.restore_output() - - def test_default_configuration__release(self): - self.assert_configuration('Release', 'Release') - - def test_default_configuration__debug(self): - self.assert_configuration('Debug', 'Debug') - - def test_default_configuration__deployment(self): - self.assert_configuration('Deployment', 'Release') - - def test_default_configuration__development(self): - self.assert_configuration('Development', 'Debug') - - def test_default_configuration__notfound(self): - # This tests what happens if the default configuration file - # doesn't exist. - c = self.make_config(output='foo', files={'foo/Configuration': None}) - self.assertEqual(c.default_configuration(), "Release") - - def test_default_configuration__unknown(self): - # Ignore the warning about an unknown configuration value. - oc = outputcapture.OutputCapture() - oc.capture_output() - self.assert_configuration('Unknown', 'Unknown') - oc.restore_output() - - def test_default_configuration__standalone(self): - # FIXME: This test runs a standalone python script to test - # reading the default configuration to work around any possible - # caching / reset bugs. See https://bugs.webkit.org/show_bug?id=49360 - # for the motivation. We can remove this test when we remove the - # global configuration cache in config.py. - e = executive.Executive() - fs = filesystem.FileSystem() - c = config.Config(e, fs) - script = c.path_from_webkit_base('WebKitTools', 'Scripts', - 'webkitpy', 'layout_tests', 'port', 'config_standalone.py') - - # Note: don't use 'Release' here, since that's the normal default. - expected = 'Debug' - - args = [sys.executable, script, '--mock', expected] - actual = e.run_command(args).rstrip() - self.assertEqual(actual, expected) - - def test_default_configuration__no_perl(self): - # We need perl to run webkit-build-directory to find out where the - # default configuration file is. See what happens if perl isn't - # installed. (We should get the default value, 'Release'). - c = self.make_config(exception=OSError) - actual = c.default_configuration() - self.assertEqual(actual, 'Release') - - def test_default_configuration__scripterror(self): - # We run webkit-build-directory to find out where the default - # configuration file is. See what happens if that script fails. - # (We should get the default value, 'Release'). - c = self.make_config(exception=executive.ScriptError()) - actual = c.default_configuration() - self.assertEqual(actual, 'Release') - - def test_path_from_webkit_base(self): - # FIXME: We use a real filesystem here. Should this move to a - # mocked one? - c = config.Config(executive.Executive(), filesystem.FileSystem()) - self.assertTrue(c.path_from_webkit_base('foo')) - - def test_webkit_base_dir(self): - # FIXME: We use a real filesystem here. Should this move to a - # mocked one? - c = config.Config(executive.Executive(), filesystem.FileSystem()) - base_dir = c.webkit_base_dir() - self.assertTrue(base_dir) - - orig_cwd = os.getcwd() - os.chdir(os.environ['HOME']) - c = config.Config(executive.Executive(), filesystem.FileSystem()) - try: - base_dir_2 = c.webkit_base_dir() - self.assertEqual(base_dir, base_dir_2) - finally: - os.chdir(orig_cwd) - - -if __name__ == '__main__': - unittest.main() diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/dryrun.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/dryrun.py deleted file mode 100644 index 4ed34e6..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/dryrun.py +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the Google name 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""This is a test implementation of the Port interface that generates the - correct output for every test. It can be used for perf testing, because - it is pretty much a lower limit on how fast a port can possibly run. - - This implementation acts as a wrapper around a real port (the real port - is held as a delegate object). To specify which port, use the port name - 'dryrun-XXX' (e.g., 'dryrun-chromium-mac-leopard'). If you use just - 'dryrun', it uses the default port. - - Note that because this is really acting as a wrapper around the underlying - port, you must be able to run the underlying port as well - (check_build() and check_sys_deps() must pass and auxiliary binaries - like layout_test_helper and httpd must work). - - This implementation also modifies the test expectations so that all - tests are either SKIPPED or expected to PASS.""" - -from __future__ import with_statement - -import os -import sys -import time - -from webkitpy.layout_tests.layout_package import test_output - -import base -import factory - - -class DryRunPort(object): - """DryRun implementation of the Port interface.""" - - def __init__(self, **kwargs): - pfx = 'dryrun-' - if 'port_name' in kwargs: - if kwargs['port_name'].startswith(pfx): - kwargs['port_name'] = kwargs['port_name'][len(pfx):] - else: - kwargs['port_name'] = None - self.__delegate = factory.get(**kwargs) - - def __getattr__(self, name): - return getattr(self.__delegate, name) - - def check_build(self, needs_http): - return True - - def check_sys_deps(self, needs_http): - return True - - def start_helper(self): - pass - - def start_http_server(self): - pass - - def start_websocket_server(self): - pass - - def stop_helper(self): - pass - - def stop_http_server(self): - pass - - def stop_websocket_server(self): - pass - - def create_driver(self, worker_number): - return DryrunDriver(self, worker_number) - - -class DryrunDriver(base.Driver): - """Dryrun implementation of the DumpRenderTree / Driver interface.""" - - def __init__(self, port, worker_number): - self._port = port - self._worker_number = worker_number - - def cmd_line(self): - return ['None'] - - def poll(self): - return None - - def run_test(self, test_input): - start_time = time.time() - text_output = self._port.expected_text(test_input.filename) - - if test_input.image_hash is not None: - image = self._port.expected_image(test_input.filename) - hash = self._port.expected_checksum(test_input.filename) - else: - image = None - hash = None - return test_output.TestOutput(text_output, image, hash, False, - time.time() - start_time, False, None) - - def start(self): - pass - - def stop(self): - pass diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/factory.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/factory.py deleted file mode 100644 index 6935744..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/factory.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""Factory method to retrieve the appropriate port implementation.""" - - -import sys - -ALL_PORT_NAMES = ['test', 'dryrun', 'mac', 'win', 'gtk', 'qt', 'chromium-mac', - 'chromium-linux', 'chromium-win', 'google-chrome-win', - 'google-chrome-mac', 'google-chrome-linux32', 'google-chrome-linux64'] - - -def get(port_name=None, options=None, **kwargs): - """Returns an object implementing the Port interface. If - port_name is None, this routine attempts to guess at the most - appropriate port on this platform.""" - # Wrapped for backwards-compatibility - if port_name: - kwargs['port_name'] = port_name - if options: - kwargs['options'] = options - return _get_kwargs(**kwargs) - - -def _get_kwargs(**kwargs): - port_to_use = kwargs.get('port_name', None) - options = kwargs.get('options', None) - if port_to_use is None: - if sys.platform == 'win32' or sys.platform == 'cygwin': - if options and hasattr(options, 'chromium') and options.chromium: - port_to_use = 'chromium-win' - else: - port_to_use = 'win' - elif sys.platform == 'linux2': - port_to_use = 'chromium-linux' - elif sys.platform == 'darwin': - if options and hasattr(options, 'chromium') and options.chromium: - port_to_use = 'chromium-mac' - else: - port_to_use = 'mac' - - if port_to_use is None: - raise NotImplementedError('unknown port; sys.platform = "%s"' % - sys.platform) - - if port_to_use == 'test': - import test - maker = test.TestPort - elif port_to_use.startswith('dryrun'): - import dryrun - maker = dryrun.DryRunPort - elif port_to_use.startswith('mac'): - import mac - maker = mac.MacPort - elif port_to_use.startswith('win'): - import win - maker = win.WinPort - elif port_to_use.startswith('gtk'): - import gtk - maker = gtk.GtkPort - elif port_to_use.startswith('qt'): - import qt - maker = qt.QtPort - elif port_to_use.startswith('chromium-gpu'): - import chromium_gpu - maker = chromium_gpu.get - elif port_to_use.startswith('chromium-mac'): - import chromium_mac - maker = chromium_mac.ChromiumMacPort - elif port_to_use.startswith('chromium-linux'): - import chromium_linux - maker = chromium_linux.ChromiumLinuxPort - elif port_to_use.startswith('chromium-win'): - import chromium_win - maker = chromium_win.ChromiumWinPort - elif port_to_use.startswith('google-chrome'): - import google_chrome - maker = google_chrome.GetGoogleChromePort - else: - raise NotImplementedError('unsupported port: %s' % port_to_use) - return maker(**kwargs) - -def get_all(options=None): - """Returns all the objects implementing the Port interface.""" - return dict([(port_name, get(port_name, options=options)) - for port_name in ALL_PORT_NAMES]) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/factory_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/factory_unittest.py deleted file mode 100644 index 978a557..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/factory_unittest.py +++ /dev/null @@ -1,188 +0,0 @@ -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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 sys -import unittest - -from webkitpy.tool import mocktool - -import chromium_gpu -import chromium_linux -import chromium_mac -import chromium_win -import dryrun -import factory -import google_chrome -import gtk -import mac -import qt -import test -import win - - -class FactoryTest(unittest.TestCase): - """Test factory creates proper port object for the target. - - Target is specified by port_name, sys.platform and options. - - """ - # FIXME: The ports themselves should expose what options they require, - # instead of passing generic "options". - - def setUp(self): - self.real_sys_platform = sys.platform - self.webkit_options = mocktool.MockOptions(pixel_tests=False) - self.chromium_options = mocktool.MockOptions(pixel_tests=False, - chromium=True) - - def tearDown(self): - sys.platform = self.real_sys_platform - - def assert_port(self, port_name, expected_port, port_obj=None): - """Helper assert for port_name. - - Args: - port_name: port name to get port object. - expected_port: class of expected port object. - port_obj: optional port object - """ - port_obj = port_obj or factory.get(port_name=port_name) - self.assertTrue(isinstance(port_obj, expected_port)) - - def assert_platform_port(self, platform, options, expected_port): - """Helper assert for platform and options. - - Args: - platform: sys.platform. - options: options to get port object. - expected_port: class of expected port object. - - """ - orig_platform = sys.platform - sys.platform = platform - self.assertTrue(isinstance(factory.get(options=options), - expected_port)) - sys.platform = orig_platform - - def test_test(self): - self.assert_port("test", test.TestPort) - - def test_dryrun(self): - self.assert_port("dryrun-test", dryrun.DryRunPort) - self.assert_port("dryrun-mac", dryrun.DryRunPort) - - def test_mac(self): - self.assert_port("mac", mac.MacPort) - self.assert_platform_port("darwin", None, mac.MacPort) - self.assert_platform_port("darwin", self.webkit_options, mac.MacPort) - - def test_win(self): - self.assert_port("win", win.WinPort) - self.assert_platform_port("win32", None, win.WinPort) - self.assert_platform_port("win32", self.webkit_options, win.WinPort) - self.assert_platform_port("cygwin", None, win.WinPort) - self.assert_platform_port("cygwin", self.webkit_options, win.WinPort) - - def test_google_chrome(self): - # The actual Chrome class names aren't available so we test that the - # objects we get are at least subclasses of the Chromium versions. - self.assert_port("google-chrome-linux32", - chromium_linux.ChromiumLinuxPort) - self.assert_port("google-chrome-linux64", - chromium_linux.ChromiumLinuxPort) - self.assert_port("google-chrome-win", - chromium_win.ChromiumWinPort) - self.assert_port("google-chrome-mac", - chromium_mac.ChromiumMacPort) - - def test_gtk(self): - self.assert_port("gtk", gtk.GtkPort) - - def test_qt(self): - self.assert_port("qt", qt.QtPort) - - def test_chromium_gpu_linux(self): - self.assert_port("chromium-gpu-linux", chromium_gpu.ChromiumGpuLinuxPort) - - def test_chromium_gpu_mac(self): - self.assert_port("chromium-gpu-mac", chromium_gpu.ChromiumGpuMacPort) - - def test_chromium_gpu_win(self): - self.assert_port("chromium-gpu-win", chromium_gpu.ChromiumGpuWinPort) - - def test_chromium_mac(self): - self.assert_port("chromium-mac", chromium_mac.ChromiumMacPort) - self.assert_platform_port("darwin", self.chromium_options, - chromium_mac.ChromiumMacPort) - - def test_chromium_linux(self): - self.assert_port("chromium-linux", chromium_linux.ChromiumLinuxPort) - self.assert_platform_port("linux2", self.chromium_options, - chromium_linux.ChromiumLinuxPort) - - def test_chromium_win(self): - self.assert_port("chromium-win", chromium_win.ChromiumWinPort) - self.assert_platform_port("win32", self.chromium_options, - chromium_win.ChromiumWinPort) - self.assert_platform_port("cygwin", self.chromium_options, - chromium_win.ChromiumWinPort) - - def test_get_all_ports(self): - ports = factory.get_all() - for name in factory.ALL_PORT_NAMES: - self.assertTrue(name in ports.keys()) - self.assert_port("test", test.TestPort, ports["test"]) - self.assert_port("dryrun-test", dryrun.DryRunPort, ports["dryrun"]) - self.assert_port("dryrun-mac", dryrun.DryRunPort, ports["dryrun"]) - self.assert_port("mac", mac.MacPort, ports["mac"]) - self.assert_port("win", win.WinPort, ports["win"]) - self.assert_port("gtk", gtk.GtkPort, ports["gtk"]) - self.assert_port("qt", qt.QtPort, ports["qt"]) - self.assert_port("chromium-mac", chromium_mac.ChromiumMacPort, - ports["chromium-mac"]) - self.assert_port("chromium-linux", chromium_linux.ChromiumLinuxPort, - ports["chromium-linux"]) - self.assert_port("chromium-win", chromium_win.ChromiumWinPort, - ports["chromium-win"]) - - def test_unknown_specified(self): - # Test what happens when you specify an unknown port. - orig_platform = sys.platform - self.assertRaises(NotImplementedError, factory.get, - port_name='unknown') - - def test_unknown_default(self): - # Test what happens when you're running on an unknown platform. - orig_platform = sys.platform - sys.platform = 'unknown' - self.assertRaises(NotImplementedError, factory.get) - sys.platform = orig_platform - - -if __name__ == '__main__': - unittest.main() diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome.py deleted file mode 100644 index 8d94bb5..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome.py +++ /dev/null @@ -1,122 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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 HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -from __future__ import with_statement - -import codecs -import os - - -def _test_expectations_overrides(port, super): - # The chrome ports use the regular overrides plus anything in the - # official test_expectations as well. Hopefully we don't get collisions. - chromium_overrides = super.test_expectations_overrides(port) - - # FIXME: It used to be that AssertionError would get raised by - # path_from_chromium_base() if we weren't in a Chromium checkout, but - # this changed in r60427. This should probably be changed back. - overrides_path = port.path_from_chromium_base('webkit', 'tools', - 'layout_tests', 'test_expectations_chrome.txt') - if not os.path.exists(overrides_path): - return chromium_overrides - - with codecs.open(overrides_path, "r", "utf-8") as file: - if chromium_overrides: - return chromium_overrides + file.read() - else: - return file.read() - -def GetGoogleChromePort(**kwargs): - """Some tests have slightly different results when compiled as Google - Chrome vs Chromium. In those cases, we prepend an additional directory to - to the baseline paths.""" - port_name = kwargs['port_name'] - del kwargs['port_name'] - if port_name == 'google-chrome-linux32': - import chromium_linux - - class GoogleChromeLinux32Port(chromium_linux.ChromiumLinuxPort): - def baseline_search_path(self): - paths = chromium_linux.ChromiumLinuxPort.baseline_search_path( - self) - paths.insert(0, self._webkit_baseline_path( - 'google-chrome-linux32')) - return paths - - def test_expectations_overrides(self): - return _test_expectations_overrides(self, - chromium_linux.ChromiumLinuxPort) - - return GoogleChromeLinux32Port(**kwargs) - elif port_name == 'google-chrome-linux64': - import chromium_linux - - class GoogleChromeLinux64Port(chromium_linux.ChromiumLinuxPort): - def baseline_search_path(self): - paths = chromium_linux.ChromiumLinuxPort.baseline_search_path( - self) - paths.insert(0, self._webkit_baseline_path( - 'google-chrome-linux64')) - return paths - - def test_expectations_overrides(self): - return _test_expectations_overrides(self, - chromium_linux.ChromiumLinuxPort) - - return GoogleChromeLinux64Port(**kwargs) - elif port_name.startswith('google-chrome-mac'): - import chromium_mac - - class GoogleChromeMacPort(chromium_mac.ChromiumMacPort): - def baseline_search_path(self): - paths = chromium_mac.ChromiumMacPort.baseline_search_path( - self) - paths.insert(0, self._webkit_baseline_path( - 'google-chrome-mac')) - return paths - - def test_expectations_overrides(self): - return _test_expectations_overrides(self, - chromium_mac.ChromiumMacPort) - - return GoogleChromeMacPort(**kwargs) - elif port_name.startswith('google-chrome-win'): - import chromium_win - - class GoogleChromeWinPort(chromium_win.ChromiumWinPort): - def baseline_search_path(self): - paths = chromium_win.ChromiumWinPort.baseline_search_path( - self) - paths.insert(0, self._webkit_baseline_path( - 'google-chrome-win')) - return paths - - def test_expectations_overrides(self): - return _test_expectations_overrides(self, - chromium_win.ChromiumWinPort) - - return GoogleChromeWinPort(**kwargs) - raise NotImplementedError('unsupported port: %s' % port_name) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome_unittest.py deleted file mode 100644 index e60c274..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/google_chrome_unittest.py +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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 HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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 codecs -import os -import unittest - -from webkitpy.common import newstringio - -import factory -import google_chrome - - -class GetGoogleChromePortTest(unittest.TestCase): - def test_get_google_chrome_port(self): - test_ports = ('google-chrome-linux32', 'google-chrome-linux64', - 'google-chrome-mac', 'google-chrome-win') - for port in test_ports: - self._verify_baseline_path(port, port) - self._verify_expectations_overrides(port) - - self._verify_baseline_path('google-chrome-mac', 'google-chrome-mac-leopard') - self._verify_baseline_path('google-chrome-win', 'google-chrome-win-xp') - self._verify_baseline_path('google-chrome-win', 'google-chrome-win-vista') - - def _verify_baseline_path(self, expected_path, port_name): - port = google_chrome.GetGoogleChromePort(port_name=port_name, - options=None) - path = port.baseline_search_path()[0] - self.assertEqual(expected_path, os.path.split(path)[1]) - - def _verify_expectations_overrides(self, port_name): - # FIXME: make this more robust when we have the Tree() abstraction. - # we should be able to test for the files existing or not, and - # be able to control the contents better. - - chromium_port = factory.get("chromium-mac") - chromium_overrides = chromium_port.test_expectations_overrides() - port = google_chrome.GetGoogleChromePort(port_name=port_name, - options=None) - - orig_exists = os.path.exists - orig_open = codecs.open - expected_string = "// hello, world\n" - - def mock_exists_chrome_not_found(path): - if 'test_expectations_chrome.txt' in path: - return False - return orig_exists(path) - - def mock_exists_chrome_found(path): - if 'test_expectations_chrome.txt' in path: - return True - return orig_exists(path) - - def mock_open(path, mode, encoding): - if 'test_expectations_chrome.txt' in path: - return newstringio.StringIO(expected_string) - return orig_open(path, mode, encoding) - - try: - os.path.exists = mock_exists_chrome_not_found - chrome_overrides = port.test_expectations_overrides() - self.assertEqual(chromium_overrides, chrome_overrides) - - os.path.exists = mock_exists_chrome_found - codecs.open = mock_open - chrome_overrides = port.test_expectations_overrides() - if chromium_overrides: - self.assertEqual(chrome_overrides, - chromium_overrides + expected_string) - else: - self.assertEqual(chrome_overrides, expected_string) - finally: - os.path.exists = orig_exists - codecs.open = orig_open - - -if __name__ == '__main__': - unittest.main() diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/gtk.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/gtk.py deleted file mode 100644 index c60909e..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/gtk.py +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the Google name 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""WebKit Gtk implementation of the Port interface.""" - -import logging -import os - -from webkitpy.layout_tests.port.webkit import WebKitPort - -_log = logging.getLogger("webkitpy.layout_tests.port.gtk") - - -class GtkPort(WebKitPort): - """WebKit Gtk implementation of the Port class.""" - - def __init__(self, **kwargs): - kwargs.setdefault('port_name', 'gtk') - WebKitPort.__init__(self, **kwargs) - - def _tests_for_other_platforms(self): - # FIXME: This list could be dynamic based on platform name and - # pushed into base.Port. - # This really need to be automated. - return [ - "platform/chromium", - "platform/win", - "platform/qt", - "platform/mac", - ] - - def _path_to_apache_config_file(self): - # FIXME: This needs to detect the distribution and change config files. - return os.path.join(self.layout_tests_dir(), 'http', 'conf', - 'apache2-debian-httpd.conf') - - def _shut_down_http_server(self, server_pid): - """Shut down the httpd web server. Blocks until it's fully - shut down. - - Args: - server_pid: The process ID of the running server. - """ - # server_pid is not set when "http_server.py stop" is run manually. - if server_pid is None: - # FIXME: This isn't ideal, since it could conflict with - # lighttpd processes not started by http_server.py, - # but good enough for now. - self._executive.kill_all('apache2') - else: - try: - os.kill(server_pid, signal.SIGTERM) - # TODO(mmoss) Maybe throw in a SIGKILL just to be sure? - except OSError: - # Sometimes we get a bad PID (e.g. from a stale httpd.pid - # file), so if kill fails on the given PID, just try to - # 'killall' web servers. - self._shut_down_http_server(None) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock.py deleted file mode 100644 index 8995b21..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock.py +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Gabor Rapcsanyi (rgabor@inf.u-szeged.hu), University of Szeged -# Copyright (C) 2010 Andras Becsi (abecsi@inf.u-szeged.hu), University of Szeged -# -# 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 UNIVERSITY OF SZEGED ``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 UNIVERSITY OF SZEGED OR -# 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. - -"""This class helps to block NRWT threads when more NRWTs run -http and websocket tests in a same time.""" - -import glob -import logging -import os -import sys -import tempfile -import time - -from webkitpy.common.system.executive import Executive -from webkitpy.common.system.file_lock import FileLock - - -_log = logging.getLogger("webkitpy.layout_tests.port.http_lock") - - -class HttpLock(object): - - def __init__(self, lock_path, lock_file_prefix="WebKitHttpd.lock.", - guard_lock="WebKit.lock"): - self._lock_path = lock_path - if not self._lock_path: - self._lock_path = tempfile.gettempdir() - self._lock_file_prefix = lock_file_prefix - self._lock_file_path_prefix = os.path.join(self._lock_path, - self._lock_file_prefix) - self._guard_lock_file = os.path.join(self._lock_path, guard_lock) - self._guard_lock = FileLock(self._guard_lock_file) - self._process_lock_file_name = "" - self._executive = Executive() - - def cleanup_http_lock(self): - """Delete the lock file if exists.""" - if os.path.exists(self._process_lock_file_name): - _log.debug("Removing lock file: %s" % self._process_lock_file_name) - os.unlink(self._process_lock_file_name) - - def _extract_lock_number(self, lock_file_name): - """Return the lock number from lock file.""" - prefix_length = len(self._lock_file_path_prefix) - return int(lock_file_name[prefix_length:]) - - def _lock_file_list(self): - """Return the list of lock files sequentially.""" - lock_list = glob.glob(self._lock_file_path_prefix + '*') - lock_list.sort(key=self._extract_lock_number) - return lock_list - - def _next_lock_number(self): - """Return the next available lock number.""" - lock_list = self._lock_file_list() - if not lock_list: - return 0 - return self._extract_lock_number(lock_list[-1]) + 1 - - def _curent_lock_pid(self): - """Return with the current lock pid. If the lock is not valid - it deletes the lock file.""" - lock_list = self._lock_file_list() - if not lock_list: - return - try: - current_lock_file = open(lock_list[0], 'r') - current_pid = current_lock_file.readline() - current_lock_file.close() - if not (current_pid and self._executive.check_running_pid(int(current_pid))): - _log.debug("Removing stuck lock file: %s" % lock_list[0]) - os.unlink(lock_list[0]) - return - except (IOError, OSError): - return - return int(current_pid) - - def _create_lock_file(self): - """The lock files are used to schedule the running test sessions in first - come first served order. The guard lock ensures that the lock numbers are - sequential.""" - if not os.path.exists(self._lock_path): - _log.debug("Lock directory does not exist: %s" % self._lock_path) - return False - - if not self._guard_lock.acquire_lock(): - _log.debug("Guard lock timed out!") - return False - - self._process_lock_file_name = (self._lock_file_path_prefix + - str(self._next_lock_number())) - _log.debug("Creating lock file: %s" % self._process_lock_file_name) - lock_file = open(self._process_lock_file_name, 'w') - lock_file.write(str(os.getpid())) - lock_file.close() - self._guard_lock.release_lock() - return True - - - def wait_for_httpd_lock(self): - """Create a lock file and wait until it's turn comes. If something goes wrong - it wont do any locking.""" - if not self._create_lock_file(): - _log.debug("Warning, http locking failed!") - return - - while self._curent_lock_pid() != os.getpid(): - time.sleep(1) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock_unittest.py deleted file mode 100644 index 85c760a..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock_unittest.py +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Gabor Rapcsanyi (rgabor@inf.u-szeged.hu), University of Szeged -# -# 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 UNIVERSITY OF SZEGED ``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 UNIVERSITY OF SZEGED OR -# 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 glob -import http_lock -import os -import unittest - - -class HttpLockTest(unittest.TestCase): - - def __init__(self, testFunc): - self.http_lock_obj = http_lock.HttpLock(None, "WebKitTestHttpd.lock.", "WebKitTest.lock") - self.lock_file_path_prefix = os.path.join(self.http_lock_obj._lock_path, - self.http_lock_obj._lock_file_prefix) - self.lock_file_name = self.lock_file_path_prefix + "0" - self.guard_lock_file = self.http_lock_obj._guard_lock_file - self.clean_all_lockfile() - unittest.TestCase.__init__(self, testFunc) - - def clean_all_lockfile(self): - if os.path.exists(self.guard_lock_file): - os.unlink(self.guard_lock_file) - lock_list = glob.glob(self.lock_file_path_prefix + '*') - for file_name in lock_list: - os.unlink(file_name) - - def assertEqual(self, first, second): - if first != second: - self.clean_all_lockfile() - unittest.TestCase.assertEqual(self, first, second) - - def _check_lock_file(self): - if os.path.exists(self.lock_file_name): - pid = os.getpid() - lock_file = open(self.lock_file_name, 'r') - lock_file_pid = lock_file.readline() - lock_file.close() - self.assertEqual(pid, int(lock_file_pid)) - return True - return False - - def test_lock_lifecycle(self): - self.http_lock_obj._create_lock_file() - - self.assertEqual(True, self._check_lock_file()) - self.assertEqual(1, self.http_lock_obj._next_lock_number()) - - self.http_lock_obj.cleanup_http_lock() - - self.assertEqual(False, self._check_lock_file()) - self.assertEqual(0, self.http_lock_obj._next_lock_number()) - - def test_extract_lock_number(self,): - lock_file_list = ( - self.lock_file_path_prefix + "00", - self.lock_file_path_prefix + "9", - self.lock_file_path_prefix + "001", - self.lock_file_path_prefix + "021", - ) - - expected_number_list = (0, 9, 1, 21) - - for lock_file, expected in zip(lock_file_list, expected_number_list): - self.assertEqual(self.http_lock_obj._extract_lock_number(lock_file), expected) - - def test_lock_file_list(self): - lock_file_list = [ - self.lock_file_path_prefix + "6", - self.lock_file_path_prefix + "1", - self.lock_file_path_prefix + "4", - self.lock_file_path_prefix + "3", - ] - - expected_file_list = [ - self.lock_file_path_prefix + "1", - self.lock_file_path_prefix + "3", - self.lock_file_path_prefix + "4", - self.lock_file_path_prefix + "6", - ] - - for file_name in lock_file_list: - open(file_name, 'w') - - self.assertEqual(self.http_lock_obj._lock_file_list(), expected_file_list) - - for file_name in lock_file_list: - os.unlink(file_name) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/http_server.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/http_server.py deleted file mode 100755 index 0f8a21e..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/http_server.py +++ /dev/null @@ -1,233 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""A class to help start/stop the lighttpd server used by layout tests.""" - -from __future__ import with_statement - -import codecs -import logging -import optparse -import os -import shutil -import subprocess -import sys -import tempfile -import time -import urllib - -import factory -import http_server_base - -_log = logging.getLogger("webkitpy.layout_tests.port.http_server") - - -class HttpdNotStarted(Exception): - pass - - -class Lighttpd(http_server_base.HttpServerBase): - - def __init__(self, port_obj, output_dir, background=False, port=None, - root=None, run_background=None): - """Args: - output_dir: the absolute path to the layout test result directory - """ - # Webkit tests - http_server_base.HttpServerBase.__init__(self, port_obj) - self._output_dir = output_dir - self._process = None - self._port = port - self._root = root - self._run_background = run_background - if self._port: - self._port = int(self._port) - - try: - self._webkit_tests = os.path.join( - self._port_obj.layout_tests_dir(), 'http', 'tests') - self._js_test_resource = os.path.join( - self._port_obj.layout_tests_dir(), 'fast', 'js', 'resources') - except: - self._webkit_tests = None - self._js_test_resource = None - - # Self generated certificate for SSL server (for client cert get - # <base-path>\chrome\test\data\ssl\certs\root_ca_cert.crt) - self._pem_file = os.path.join( - os.path.dirname(os.path.abspath(__file__)), 'httpd2.pem') - - # One mapping where we can get to everything - self.VIRTUALCONFIG = [] - - if self._webkit_tests: - self.VIRTUALCONFIG.extend( - # Three mappings (one with SSL) for LayoutTests http tests - [{'port': 8000, 'docroot': self._webkit_tests}, - {'port': 8080, 'docroot': self._webkit_tests}, - {'port': 8443, 'docroot': self._webkit_tests, - 'sslcert': self._pem_file}]) - - def is_running(self): - return self._process != None - - def start(self): - if self.is_running(): - raise 'Lighttpd already running' - - base_conf_file = self._port_obj.path_from_webkit_base('WebKitTools', - 'Scripts', 'webkitpy', 'layout_tests', 'port', 'lighttpd.conf') - out_conf_file = os.path.join(self._output_dir, 'lighttpd.conf') - time_str = time.strftime("%d%b%Y-%H%M%S") - access_file_name = "access.log-" + time_str + ".txt" - access_log = os.path.join(self._output_dir, access_file_name) - log_file_name = "error.log-" + time_str + ".txt" - error_log = os.path.join(self._output_dir, log_file_name) - - # Remove old log files. We only need to keep the last ones. - self.remove_log_files(self._output_dir, "access.log-") - self.remove_log_files(self._output_dir, "error.log-") - - # Write out the config - with codecs.open(base_conf_file, "r", "utf-8") as file: - base_conf = file.read() - - # FIXME: This should be re-worked so that this block can - # use with open() instead of a manual file.close() call. - # lighttpd.conf files seem to be UTF-8 without BOM: - # http://redmine.lighttpd.net/issues/992 - f = codecs.open(out_conf_file, "w", "utf-8") - f.write(base_conf) - - # Write out our cgi handlers. Run perl through env so that it - # processes the #! line and runs perl with the proper command - # line arguments. Emulate apache's mod_asis with a cat cgi handler. - f.write(('cgi.assign = ( ".cgi" => "/usr/bin/env",\n' - ' ".pl" => "/usr/bin/env",\n' - ' ".asis" => "/bin/cat",\n' - ' ".php" => "%s" )\n\n') % - self._port_obj._path_to_lighttpd_php()) - - # Setup log files - f.write(('server.errorlog = "%s"\n' - 'accesslog.filename = "%s"\n\n') % (error_log, access_log)) - - # Setup upload folders. Upload folder is to hold temporary upload files - # and also POST data. This is used to support XHR layout tests that - # does POST. - f.write(('server.upload-dirs = ( "%s" )\n\n') % (self._output_dir)) - - # Setup a link to where the js test templates are stored - f.write(('alias.url = ( "/js-test-resources" => "%s" )\n\n') % - (self._js_test_resource)) - - # dump out of virtual host config at the bottom. - if self._root: - if self._port: - # Have both port and root dir. - mappings = [{'port': self._port, 'docroot': self._root}] - else: - # Have only a root dir - set the ports as for LayoutTests. - # This is used in ui_tests to run http tests against a browser. - - # default set of ports as for LayoutTests but with a - # specified root. - mappings = [{'port': 8000, 'docroot': self._root}, - {'port': 8080, 'docroot': self._root}, - {'port': 8443, 'docroot': self._root, - 'sslcert': self._pem_file}] - else: - mappings = self.VIRTUALCONFIG - for mapping in mappings: - ssl_setup = '' - if 'sslcert' in mapping: - ssl_setup = (' ssl.engine = "enable"\n' - ' ssl.pemfile = "%s"\n' % mapping['sslcert']) - - f.write(('$SERVER["socket"] == "127.0.0.1:%d" {\n' - ' server.document-root = "%s"\n' + - ssl_setup + - '}\n\n') % (mapping['port'], mapping['docroot'])) - f.close() - - executable = self._port_obj._path_to_lighttpd() - module_path = self._port_obj._path_to_lighttpd_modules() - start_cmd = [executable, - # Newly written config file - '-f', os.path.join(self._output_dir, 'lighttpd.conf'), - # Where it can find its module dynamic libraries - '-m', module_path] - - if not self._run_background: - start_cmd.append(# Don't background - '-D') - - # Copy liblightcomp.dylib to /tmp/lighttpd/lib to work around the - # bug that mod_alias.so loads it from the hard coded path. - if sys.platform == 'darwin': - tmp_module_path = '/tmp/lighttpd/lib' - if not os.path.exists(tmp_module_path): - os.makedirs(tmp_module_path) - lib_file = 'liblightcomp.dylib' - shutil.copyfile(os.path.join(module_path, lib_file), - os.path.join(tmp_module_path, lib_file)) - - env = self._port_obj.setup_environ_for_server() - _log.debug('Starting http server') - # FIXME: Should use Executive.run_command - self._process = subprocess.Popen(start_cmd, env=env) - - # Wait for server to start. - self.mappings = mappings - server_started = self.wait_for_action( - self.is_server_running_on_all_ports) - - # Our process terminated already - if not server_started or self._process.returncode != None: - raise google.httpd_utils.HttpdNotStarted('Failed to start httpd.') - - _log.debug("Server successfully started") - - # TODO(deanm): Find a nicer way to shutdown cleanly. Our log files are - # probably not being flushed, etc... why doesn't our python have os.kill ? - - def stop(self, force=False): - if not force and not self.is_running(): - return - - httpd_pid = None - if self._process: - httpd_pid = self._process.pid - self._port_obj._shut_down_http_server(httpd_pid) - - if self._process: - # wait() is not threadsafe and can throw OSError due to: - # http://bugs.python.org/issue1731717 - self._process.wait() - self._process = None diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/http_server_base.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/http_server_base.py deleted file mode 100644 index 2745cce..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/http_server_base.py +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""Base class with common routines between the Apache and Lighttpd servers.""" - -import logging -import os -import time -import urllib - -_log = logging.getLogger("webkitpy.layout_tests.port.http_server_base") - - -class HttpServerBase(object): - - def __init__(self, port_obj): - self._port_obj = port_obj - - def wait_for_action(self, action): - """Repeat the action for 20 seconds or until it succeeds. Returns - whether it succeeded.""" - start_time = time.time() - while time.time() - start_time < 20: - if action(): - return True - _log.debug("Waiting for action: %s" % action) - time.sleep(1) - - return False - - def is_server_running_on_all_ports(self): - """Returns whether the server is running on all the desired ports.""" - for mapping in self.mappings: - if 'sslcert' in mapping: - http_suffix = 's' - else: - http_suffix = '' - - url = 'http%s://127.0.0.1:%d/' % (http_suffix, mapping['port']) - - try: - response = urllib.urlopen(url) - _log.debug("Server running at %s" % url) - except IOError, e: - _log.debug("Server NOT running at %s: %s" % (url, e)) - return False - - return True - - def remove_log_files(self, folder, starts_with): - files = os.listdir(folder) - for file in files: - if file.startswith(starts_with): - full_path = os.path.join(folder, file) - os.remove(full_path) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/httpd2.pem b/WebKitTools/Scripts/webkitpy/layout_tests/port/httpd2.pem deleted file mode 100644 index 6349b78..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/httpd2.pem +++ /dev/null @@ -1,41 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEZDCCAkygAwIBAgIBATANBgkqhkiG9w0BAQUFADBgMRAwDgYDVQQDEwdUZXN0 -IENBMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMN -TW91bnRhaW4gVmlldzESMBAGA1UEChMJQ2VydCBUZXN0MB4XDTA4MDcyODIyMzIy -OFoXDTEzMDcyNzIyMzIyOFowSjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlm -b3JuaWExEjAQBgNVBAoTCUNlcnQgVGVzdDESMBAGA1UEAxMJMTI3LjAuMC4xMIGf -MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQj2tPWPUgbuI4H3/3dnttqVbndwU3 -3BdRCd67DFM44GRrsjDSH4bY/EbFyX9D52d/iy6ZaAmDePcCz5k/fgP3DMujykYG -qgNiV2ywxTlMj7NlN2C7SRt68fQMZr5iI7rypdxuaZt9lSMD3ENBffYtuLTyZd9a -3JPJe1TaIab5GwIDAQABo4HCMIG/MAkGA1UdEwQCMAAwHQYDVR0OBBYEFCYLBv5K -x5sLNVlpLh5FwTwhdDl7MIGSBgNVHSMEgYowgYeAFF3Of5nj1BlBMU/Gz7El9Vqv -45cxoWSkYjBgMRAwDgYDVQQDEwdUZXN0IENBMQswCQYDVQQGEwJVUzETMBEGA1UE -CBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzESMBAGA1UEChMJ -Q2VydCBUZXN0ggkA1FGT1D/e2U4wDQYJKoZIhvcNAQEFBQADggIBAEtkVmLObUgk -b2cIA2S+QDtifq1UgVfBbytvR2lFmnADOR55mo0gHQG3HHqq4g034LmoVXDHhUk8 -Gb6aFiv4QubmVhLXcUelTRXwiNvGzkW7pC6Jrq105hdPjzXMKTcmiLaopm5Fqfc7 -hj5Cn1Sjspc8pdeQjrbeMdvca7KlFrGP8YkwCU2xOOX9PiN9G0966BWfjnr/fZZp -+OQVuUFHdiAZwthEMuDpAAXHqYXIsermgdOpgJaA53cf8NqBV2QGhtFgtsJCRoiu -7DKqhyRWBGyz19VIH2b7y+6qvQVxuHk19kKRM0nftw/yNcJnm7gtttespMUPsOMa -a2SD1G0hm0TND6vxaBhgR3cVqpl/qIpAdFi00Tm7hTyYE7I43zPW03t+/DpCt3Um -EMRZsQ90co5q+bcx/vQ7YAtwUh30uMb0wpibeyCwDp8cqNmSiRkEuc/FjTYes5t8 -5gR//WX1l0+qjrjusO9NmoLnq2Yk6UcioX+z+q6Z/dudGfqhLfeWD2Q0LWYA242C -d7km5Y3KAt1PJdVsof/aiVhVdddY/OIEKTRQhWEdDbosy2eh16BCKXT2FFvhNDg1 -AYFvn6I8nj9IldMJiIc3DdhacEAEzRMeRgPdzAa1griKUGknxsyTyRii8ru0WS6w -DCNrlDOVXdzYGEZooBI76BDVY0W0akjV ------END CERTIFICATE----- ------BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQDQj2tPWPUgbuI4H3/3dnttqVbndwU33BdRCd67DFM44GRrsjDS -H4bY/EbFyX9D52d/iy6ZaAmDePcCz5k/fgP3DMujykYGqgNiV2ywxTlMj7NlN2C7 -SRt68fQMZr5iI7rypdxuaZt9lSMD3ENBffYtuLTyZd9a3JPJe1TaIab5GwIDAQAB -AoGANHXu8z2YIzlhE+bwhGm8MGBpKL3qhRuKjeriqMA36tWezOw8lY4ymEAU+Ulv -BsCdaxqydQoTYou57m4TyUHEcxq9pq3H0zB0qL709DdHi/t4zbV9XIoAzC5v0/hG -9+Ca29TwC02FCw+qLkNrtwCpwOcQmc+bPxqvFu1iMiahURECQQD2I/Hi2413CMZz -TBjl8fMiVO9GhA2J0sc8Qi+YcgJakaLD9xcbaiLkTzPZDlA389C1b6Ia+poAr4YA -Ve0FFbxpAkEA2OobayyHE/QtPEqoy6NLR57jirmVBNmSWWd4lAyL5UIHIYVttJZg -8CLvbzaU/iDGwR+wKsM664rKPHEmtlyo4wJBAMeSqYO5ZOCJGu9NWjrHjM3fdAsG -8zs2zhiLya+fcU0iHIksBW5TBmt71Jw/wMc9R5J1K0kYvFml98653O5si1ECQBCk -RV4/mE1rmlzZzYFyEcB47DQkcM5ictvxGEsje0gnfKyRtAz6zI0f4QbDRUMJ+LWw -XK+rMsYHa+SfOb0b9skCQQCLdeonsIpFDv/Uv+flHISy0WA+AFkLXrRkBKh6G/OD -dMHaNevkJgUnpceVEnkrdenp5CcEoFTI17pd+nBgDm/B ------END RSA PRIVATE KEY----- diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/lighttpd.conf b/WebKitTools/Scripts/webkitpy/layout_tests/port/lighttpd.conf deleted file mode 100644 index 26ca22f..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/lighttpd.conf +++ /dev/null @@ -1,90 +0,0 @@ -server.tag = "LightTPD/1.4.19 (Win32)" -server.modules = ( "mod_accesslog", - "mod_alias", - "mod_cgi", - "mod_rewrite" ) - -# default document root required -server.document-root = "." - -# files to check for if .../ is requested -index-file.names = ( "index.php", "index.pl", "index.cgi", - "index.html", "index.htm", "default.htm" ) -# mimetype mapping -mimetype.assign = ( - ".gif" => "image/gif", - ".jpg" => "image/jpeg", - ".jpeg" => "image/jpeg", - ".png" => "image/png", - ".svg" => "image/svg+xml", - ".css" => "text/css", - ".html" => "text/html", - ".htm" => "text/html", - ".xhtml" => "application/xhtml+xml", - ".xhtmlmp" => "application/vnd.wap.xhtml+xml", - ".js" => "application/x-javascript", - ".log" => "text/plain", - ".conf" => "text/plain", - ".text" => "text/plain", - ".txt" => "text/plain", - ".dtd" => "text/xml", - ".xml" => "text/xml", - ".manifest" => "text/cache-manifest", - ) - -# Use the "Content-Type" extended attribute to obtain mime type if possible -mimetype.use-xattr = "enable" - -## -# which extensions should not be handle via static-file transfer -# -# .php, .pl, .fcgi are most often handled by mod_fastcgi or mod_cgi -static-file.exclude-extensions = ( ".php", ".pl", ".cgi" ) - -server.bind = "localhost" -server.port = 8001 - -## virtual directory listings -dir-listing.activate = "enable" -#dir-listing.encoding = "iso-8859-2" -#dir-listing.external-css = "style/oldstyle.css" - -## enable debugging -#debug.log-request-header = "enable" -#debug.log-response-header = "enable" -#debug.log-request-handling = "enable" -#debug.log-file-not-found = "enable" - -#### SSL engine -#ssl.engine = "enable" -#ssl.pemfile = "server.pem" - -# Rewrite rule for utf-8 path test (LayoutTests/http/tests/uri/utf8-path.html) -# See the apache rewrite rule at LayoutTests/http/tests/uri/intercept/.htaccess -# Rewrite rule for LayoutTests/http/tests/appcache/cyrillic-uri.html. -# See the apache rewrite rule at -# LayoutTests/http/tests/appcache/resources/intercept/.htaccess -url.rewrite-once = ( - "^/uri/intercept/(.*)" => "/uri/resources/print-uri.php", - "^/appcache/resources/intercept/(.*)" => "/appcache/resources/print-uri.php" -) - -# LayoutTests/http/tests/xmlhttprequest/response-encoding.html uses an htaccess -# to override charset for reply2.txt, reply2.xml, and reply4.txt. -$HTTP["url"] =~ "^/xmlhttprequest/resources/reply2.(txt|xml)" { - mimetype.assign = ( - ".txt" => "text/plain; charset=windows-1251", - ".xml" => "text/xml; charset=windows-1251" - ) -} -$HTTP["url"] =~ "^/xmlhttprequest/resources/reply4.txt" { - mimetype.assign = ( ".txt" => "text/plain; charset=koi8-r" ) -} - -# LayoutTests/http/tests/appcache/wrong-content-type.html uses an htaccess -# to override mime type for wrong-content-type.manifest. -$HTTP["url"] =~ "^/appcache/resources/wrong-content-type.manifest" { - mimetype.assign = ( ".manifest" => "text/plain" ) -} - -# Autogenerated test-specific config follows. diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/mac.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/mac.py deleted file mode 100644 index 696e339..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/mac.py +++ /dev/null @@ -1,152 +0,0 @@ -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the Google name 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""WebKit Mac implementation of the Port interface.""" - -import logging -import os -import platform -import signal - -import webkitpy.common.system.ospath as ospath -import webkitpy.layout_tests.port.server_process as server_process -from webkitpy.layout_tests.port.webkit import WebKitPort, WebKitDriver - -_log = logging.getLogger("webkitpy.layout_tests.port.mac") - - -class MacPort(WebKitPort): - """WebKit Mac implementation of the Port class.""" - - def __init__(self, **kwargs): - kwargs.setdefault('port_name', 'mac' + self.version()) - WebKitPort.__init__(self, **kwargs) - - def default_child_processes(self): - # FIXME: new-run-webkit-tests is unstable on Mac running more than - # four threads in parallel. - # See https://bugs.webkit.org/show_bug.cgi?id=36622 - child_processes = WebKitPort.default_child_processes(self) - if child_processes > 4: - return 4 - return child_processes - - def baseline_search_path(self): - port_names = [] - if self._name == 'mac-tiger': - port_names.append("mac-tiger") - if self._name in ('mac-tiger', 'mac-leopard'): - port_names.append("mac-leopard") - if self._name in ('mac-tiger', 'mac-leopard', 'mac-snowleopard'): - port_names.append("mac-snowleopard") - port_names.append("mac") - return map(self._webkit_baseline_path, port_names) - - def path_to_test_expectations_file(self): - return self.path_from_webkit_base('LayoutTests', 'platform', - 'mac', 'test_expectations.txt') - - def _skipped_file_paths(self): - # FIXME: This method will need to be made work for non-mac - # platforms and moved into base.Port. - skipped_files = [] - if self._name in ('mac-tiger', 'mac-leopard', 'mac-snowleopard'): - skipped_files.append(os.path.join( - self._webkit_baseline_path(self._name), 'Skipped')) - skipped_files.append(os.path.join(self._webkit_baseline_path('mac'), - 'Skipped')) - return skipped_files - - def test_platform_name(self): - return 'mac' + self.version() - - def version(self): - os_version_string = platform.mac_ver()[0] # e.g. "10.5.6" - if not os_version_string: - return '-leopard' - release_version = int(os_version_string.split('.')[1]) - if release_version == 4: - return '-tiger' - elif release_version == 5: - return '-leopard' - elif release_version == 6: - return '-snowleopard' - return '' - - def _build_java_test_support(self): - java_tests_path = os.path.join(self.layout_tests_dir(), "java") - build_java = ["/usr/bin/make", "-C", java_tests_path] - if self._executive.run_command(build_java, return_exit_code=True): - _log.error("Failed to build Java support files: %s" % build_java) - return False - return True - - def _check_port_build(self): - return self._build_java_test_support() - - def _tests_for_other_platforms(self): - # The original run-webkit-tests builds up a "whitelist" of tests to - # run, and passes that to DumpRenderTree. new-run-webkit-tests assumes - # we run *all* tests and test_expectations.txt functions as a - # blacklist. - # FIXME: This list could be dynamic based on platform name and - # pushed into base.Port. - return [ - "platform/chromium", - "platform/gtk", - "platform/qt", - "platform/win", - ] - - def _path_to_apache_config_file(self): - return os.path.join(self.layout_tests_dir(), 'http', 'conf', - 'apache2-httpd.conf') - - # FIXME: This doesn't have anything to do with WebKit. - def _shut_down_http_server(self, server_pid): - """Shut down the lighttpd web server. Blocks until it's fully - shut down. - - Args: - server_pid: The process ID of the running server. - """ - # server_pid is not set when "http_server.py stop" is run manually. - if server_pid is None: - # FIXME: This isn't ideal, since it could conflict with - # lighttpd processes not started by http_server.py, - # but good enough for now. - self._executive.kill_all('httpd') - else: - try: - os.kill(server_pid, signal.SIGTERM) - # FIXME: Maybe throw in a SIGKILL just to be sure? - except OSError: - # Sometimes we get a bad PID (e.g. from a stale httpd.pid - # file), so if kill fails on the given PID, just try to - # 'killall' web servers. - self._shut_down_http_server(None) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/mac_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/mac_unittest.py deleted file mode 100644 index d383a4c..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/mac_unittest.py +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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 StringIO -import sys -import unittest - -import mac -import port_testcase - - -class MacTest(port_testcase.PortTestCase): - def make_port(self, options=port_testcase.mock_options): - if sys.platform != 'darwin': - return None - port_obj = mac.MacPort(options=options) - port_obj._options.results_directory = port_obj.results_directory() - port_obj._options.configuration = 'Release' - return port_obj - - def test_skipped_file_paths(self): - port = self.make_port() - if not port: - return - skipped_paths = port._skipped_file_paths() - # FIXME: _skipped_file_paths should return WebKit-relative paths. - # So to make it unit testable, we strip the WebKit directory from the path. - relative_paths = [path[len(port.path_from_webkit_base()):] for path in skipped_paths] - self.assertEqual(relative_paths, ['LayoutTests/platform/mac-leopard/Skipped', 'LayoutTests/platform/mac/Skipped']) - - example_skipped_file = u""" -# <rdar://problem/5647952> fast/events/mouseout-on-window.html needs mac DRT to issue mouse out events -fast/events/mouseout-on-window.html - -# <rdar://problem/5643675> window.scrollTo scrolls a window with no scrollbars -fast/events/attempt-scroll-with-no-scrollbars.html - -# see bug <rdar://problem/5646437> REGRESSION (r28015): svg/batik/text/smallFonts fails -svg/batik/text/smallFonts.svg -""" - example_skipped_tests = [ - "fast/events/mouseout-on-window.html", - "fast/events/attempt-scroll-with-no-scrollbars.html", - "svg/batik/text/smallFonts.svg", - ] - - def test_skipped_file_paths(self): - port = self.make_port() - if not port: - return - skipped_file = StringIO.StringIO(self.example_skipped_file) - self.assertEqual(port._tests_from_skipped_file(skipped_file), self.example_skipped_tests) - - -if __name__ == '__main__': - unittest.main() diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/port_testcase.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/port_testcase.py deleted file mode 100644 index c4b36ac..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/port_testcase.py +++ /dev/null @@ -1,97 +0,0 @@ -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""Unit testing base class for Port implementations.""" - -import os -import tempfile -import unittest - -from webkitpy.tool import mocktool -mock_options = mocktool.MockOptions(results_directory='layout-test-results', - use_apache=True, - configuration='Release') - -# FIXME: This should be used for all ports, not just WebKit Mac. See -# https://bugs.webkit.org/show_bug.cgi?id=50043 . - -class PortTestCase(unittest.TestCase): - """Tests the WebKit port implementation.""" - def make_port(self, options=mock_options): - """Override in subclass.""" - raise NotImplementedError() - - def test_driver_cmd_line(self): - port = self.make_port() - if not port: - return - self.assertTrue(len(port.driver_cmd_line())) - - def test_http_server(self): - port = self.make_port() - if not port: - return - port.start_http_server() - port.stop_http_server() - - def test_image_diff(self): - port = self.make_port() - if not port: - return - - # FIXME: not sure why this shouldn't always be True - #self.assertTrue(port.check_image_diff()) - if not port.check_image_diff(): - return - - dir = port.layout_tests_dir() - file1 = os.path.join(dir, 'fast', 'css', 'button_center.png') - fh1 = file(file1) - contents1 = fh1.read() - file2 = os.path.join(dir, 'fast', 'css', - 'remove-shorthand-expected.png') - fh2 = file(file2) - contents2 = fh2.read() - tmpfile = tempfile.mktemp() - - self.assertFalse(port.diff_image(contents1, contents1)) - self.assertTrue(port.diff_image(contents1, contents2)) - - self.assertTrue(port.diff_image(contents1, contents2, tmpfile)) - fh1.close() - fh2.close() - # FIXME: this may not be being written? - # self.assertTrue(os.path.exists(tmpfile)) - # os.remove(tmpfile) - - def test_websocket_server(self): - port = self.make_port() - if not port: - return - port.start_websocket_server() - port.stop_websocket_server() diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/qt.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/qt.py deleted file mode 100644 index af94acc..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/qt.py +++ /dev/null @@ -1,119 +0,0 @@ -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the Google name 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""QtWebKit implementation of the Port interface.""" - -import logging -import os -import signal -import sys - -import webkit - -from webkitpy.layout_tests.port.webkit import WebKitPort - -_log = logging.getLogger("webkitpy.layout_tests.port.qt") - - -class QtPort(WebKitPort): - """QtWebKit implementation of the Port class.""" - - def __init__(self, **kwargs): - kwargs.setdefault('port_name', 'qt') - WebKitPort.__init__(self, **kwargs) - - def baseline_search_path(self): - port_names = [] - if sys.platform == 'linux2': - port_names.append("qt-linux") - elif sys.platform in ('win32', 'cygwin'): - port_names.append("qt-win") - elif sys.platform == 'darwin': - port_names.append("qt-mac") - port_names.append("qt") - return map(self._webkit_baseline_path, port_names) - - def _tests_for_other_platforms(self): - # FIXME: This list could be dynamic based on platform name and - # pushed into base.Port. - # This really need to be automated. - return [ - "platform/chromium", - "platform/win", - "platform/gtk", - "platform/mac", - ] - - def _path_to_apache_config_file(self): - # FIXME: This needs to detect the distribution and change config files. - return os.path.join(self.layout_tests_dir(), 'http', 'conf', - 'apache2-debian-httpd.conf') - - def _shut_down_http_server(self, server_pid): - """Shut down the httpd web server. Blocks until it's fully - shut down. - - Args: - server_pid: The process ID of the running server. - """ - # server_pid is not set when "http_server.py stop" is run manually. - if server_pid is None: - # FIXME: This isn't ideal, since it could conflict with - # lighttpd processes not started by http_server.py, - # but good enough for now. - self._executive.kill_all('apache2') - else: - try: - os.kill(server_pid, signal.SIGTERM) - # TODO(mmoss) Maybe throw in a SIGKILL just to be sure? - except OSError: - # Sometimes we get a bad PID (e.g. from a stale httpd.pid - # file), so if kill fails on the given PID, just try to - # 'killall' web servers. - self._shut_down_http_server(None) - - def _build_driver(self): - # The Qt port builds DRT as part of the main build step - return True - - def _path_to_driver(self): - return self._build_path('bin/DumpRenderTree') - - def _path_to_image_diff(self): - return self._build_path('bin/ImageDiff') - - def _path_to_webcore_library(self): - return self._build_path('lib/libQtWebKit.so') - - def _runtime_feature_list(self): - return None - - def setup_environ_for_server(self): - env = webkit.WebKitPort.setup_environ_for_server(self) - env['QTWEBKIT_PLUGIN_PATH'] = self._build_path('lib/plugins') - return env diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/server_process.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/server_process.py deleted file mode 100644 index 5a0a40c..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/server_process.py +++ /dev/null @@ -1,225 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the Google name 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""Package that implements the ServerProcess wrapper class""" - -import logging -import os -import select -import signal -import subprocess -import sys -import time -if sys.platform != 'win32': - import fcntl - -from webkitpy.common.system.executive import Executive - -_log = logging.getLogger("webkitpy.layout_tests.port.server_process") - - -class ServerProcess: - """This class provides a wrapper around a subprocess that - implements a simple request/response usage model. The primary benefit - is that reading responses takes a timeout, so that we don't ever block - indefinitely. The class also handles transparently restarting processes - as necessary to keep issuing commands.""" - - def __init__(self, port_obj, name, cmd, env=None, executive=Executive()): - self._port = port_obj - self._name = name - self._cmd = cmd - self._env = env - self._reset() - self._executive = executive - - def _reset(self): - self._proc = None - self._output = '' - self.crashed = False - self.timed_out = False - self.error = '' - - def _start(self): - if self._proc: - raise ValueError("%s already running" % self._name) - self._reset() - # close_fds is a workaround for http://bugs.python.org/issue2320 - close_fds = sys.platform not in ('win32', 'cygwin') - self._proc = subprocess.Popen(self._cmd, stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - close_fds=close_fds, - env=self._env) - fd = self._proc.stdout.fileno() - fl = fcntl.fcntl(fd, fcntl.F_GETFL) - fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) - fd = self._proc.stderr.fileno() - fl = fcntl.fcntl(fd, fcntl.F_GETFL) - fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) - - def handle_interrupt(self): - """This routine checks to see if the process crashed or exited - because of a keyboard interrupt and raises KeyboardInterrupt - accordingly.""" - if self.crashed: - # This is hex code 0xc000001d, which is used for abrupt - # termination. This happens if we hit ctrl+c from the prompt - # and we happen to be waiting on the DumpRenderTree. - # sdoyon: Not sure for which OS and in what circumstances the - # above code is valid. What works for me under Linux to detect - # ctrl+c is for the subprocess returncode to be negative - # SIGINT. And that agrees with the subprocess documentation. - if (-1073741510 == self._proc.returncode or - - signal.SIGINT == self._proc.returncode): - raise KeyboardInterrupt - return - - def poll(self): - """Check to see if the underlying process is running; returns None - if it still is (wrapper around subprocess.poll).""" - if self._proc: - # poll() is not threadsafe and can throw OSError due to: - # http://bugs.python.org/issue1731717 - return self._proc.poll() - return None - - def write(self, input): - """Write a request to the subprocess. The subprocess is (re-)start()'ed - if is not already running.""" - if not self._proc: - self._start() - self._proc.stdin.write(input) - - def read_line(self, timeout): - """Read a single line from the subprocess, waiting until the deadline. - If the deadline passes, the call times out. Note that even if the - subprocess has crashed or the deadline has passed, if there is output - pending, it will be returned. - - Args: - timeout: floating-point number of seconds the call is allowed - to block for. A zero or negative number will attempt to read - any existing data, but will not block. There is no way to - block indefinitely. - Returns: - output: data returned, if any. If no data is available and the - call times out or crashes, an empty string is returned. Note - that the returned string includes the newline ('\n').""" - return self._read(timeout, size=0) - - def read(self, timeout, size): - """Attempts to read size characters from the subprocess, waiting until - the deadline passes. If the deadline passes, any available data will be - returned. Note that even if the deadline has passed or if the - subprocess has crashed, any available data will still be returned. - - Args: - timeout: floating-point number of seconds the call is allowed - to block for. A zero or negative number will attempt to read - any existing data, but will not block. There is no way to - block indefinitely. - size: amount of data to read. Must be a postive integer. - Returns: - output: data returned, if any. If no data is available, an empty - string is returned. - """ - if size <= 0: - raise ValueError('ServerProcess.read() called with a ' - 'non-positive size: %d ' % size) - return self._read(timeout, size) - - def _read(self, timeout, size): - """Internal routine that actually does the read.""" - index = -1 - out_fd = self._proc.stdout.fileno() - err_fd = self._proc.stderr.fileno() - select_fds = (out_fd, err_fd) - deadline = time.time() + timeout - while not self.timed_out and not self.crashed: - # poll() is not threadsafe and can throw OSError due to: - # http://bugs.python.org/issue1731717 - if self._proc.poll() != None: - self.crashed = True - self.handle_interrupt() - - now = time.time() - if now > deadline: - self.timed_out = True - - # Check to see if we have any output we can return. - if size and len(self._output) >= size: - index = size - elif size == 0: - index = self._output.find('\n') + 1 - - if index > 0 or self.crashed or self.timed_out: - output = self._output[0:index] - self._output = self._output[index:] - return output - - # Nope - wait for more data. - (read_fds, write_fds, err_fds) = select.select(select_fds, [], - select_fds, - deadline - now) - try: - if out_fd in read_fds: - self._output += self._proc.stdout.read() - if err_fd in read_fds: - self.error += self._proc.stderr.read() - except IOError, e: - pass - - def stop(self): - """Stop (shut down) the subprocess), if it is running.""" - pid = self._proc.pid - self._proc.stdin.close() - self._proc.stdout.close() - if self._proc.stderr: - self._proc.stderr.close() - if sys.platform not in ('win32', 'cygwin'): - # Closing stdin/stdout/stderr hangs sometimes on OS X, - # (see restart(), above), and anyway we don't want to hang - # the harness if DumpRenderTree is buggy, so we wait a couple - # seconds to give DumpRenderTree a chance to clean up, but then - # force-kill the process if necessary. - KILL_TIMEOUT = 3.0 - timeout = time.time() + KILL_TIMEOUT - # poll() is not threadsafe and can throw OSError due to: - # http://bugs.python.org/issue1731717 - while self._proc.poll() is None and time.time() < timeout: - time.sleep(0.1) - # poll() is not threadsafe and can throw OSError due to: - # http://bugs.python.org/issue1731717 - if self._proc.poll() is None: - _log.warning('stopping %s timed out, killing it' % - self._name) - self._executive.kill_process(self._proc.pid) - _log.warning('killed') - self._reset() diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py deleted file mode 100644 index 8e27f35..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py +++ /dev/null @@ -1,312 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the Google name 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""Dummy Port implementation used for testing.""" -from __future__ import with_statement - -import codecs -import fnmatch -import os -import sys -import time - -from webkitpy.layout_tests.layout_package import test_output - -import base - - -# This sets basic expectations for a test. Each individual expectation -# can be overridden by a keyword argument in TestList.add(). -class TestInstance: - def __init__(self, name): - self.name = name - self.base = name[(name.rfind("/") + 1):name.rfind(".html")] - self.crash = False - self.exception = False - self.hang = False - self.keyboard = False - self.error = '' - self.timeout = False - self.actual_text = self.base + '-txt\n' - self.actual_checksum = self.base + '-checksum\n' - self.actual_image = self.base + '-png\n' - self.expected_text = self.actual_text - self.expected_checksum = self.actual_checksum - self.expected_image = self.actual_image - - -# This is an in-memory list of tests, what we want them to produce, and -# what we want to claim are the expected results. -class TestList: - def __init__(self, port): - self.port = port - self.tests = {} - - def add(self, name, **kwargs): - test = TestInstance(name) - for key, value in kwargs.items(): - test.__dict__[key] = value - self.tests[name] = test - - def keys(self): - return self.tests.keys() - - def __contains__(self, item): - return item in self.tests - - def __getitem__(self, item): - return self.tests[item] - - -class TestPort(base.Port): - """Test implementation of the Port interface.""" - - def __init__(self, **kwargs): - base.Port.__init__(self, **kwargs) - tests = TestList(self) - tests.add('passes/image.html') - tests.add('passes/text.html') - tests.add('failures/expected/checksum.html', - actual_checksum='checksum_fail-checksum') - tests.add('failures/expected/crash.html', crash=True) - tests.add('failures/expected/exception.html', exception=True) - tests.add('failures/expected/timeout.html', timeout=True) - tests.add('failures/expected/hang.html', hang=True) - tests.add('failures/expected/missing_text.html', - expected_text=None) - tests.add('failures/expected/image.html', - actual_image='image_fail-png', - expected_image='image-png') - tests.add('failures/expected/image_checksum.html', - actual_checksum='image_checksum_fail-checksum', - actual_image='image_checksum_fail-png') - tests.add('failures/expected/keyboard.html', - keyboard=True) - tests.add('failures/expected/missing_check.html', - expected_checksum=None) - tests.add('failures/expected/missing_image.html', - expected_image=None) - tests.add('failures/expected/missing_text.html', - expected_text=None) - tests.add('failures/expected/text.html', - actual_text='text_fail-png') - tests.add('failures/unexpected/text-image-checksum.html', - actual_text='text-image-checksum_fail-txt', - actual_checksum='text-image-checksum_fail-checksum') - tests.add('http/tests/passes/text.html') - tests.add('http/tests/ssl/text.html') - tests.add('passes/error.html', error='stuff going to stderr') - tests.add('passes/image.html') - tests.add('passes/platform_image.html') - tests.add('passes/text.html') - tests.add('websocket/tests/passes/text.html') - self._tests = tests - - def baseline_path(self): - return os.path.join(self.layout_tests_dir(), 'platform', - self.name() + self.version()) - - def baseline_search_path(self): - return [self.baseline_path()] - - def check_build(self, needs_http): - return True - - def diff_image(self, expected_contents, actual_contents, - diff_filename=None): - diffed = actual_contents != expected_contents - if diffed and diff_filename: - with codecs.open(diff_filename, "w", "utf-8") as diff_fh: - diff_fh.write("< %s\n---\n> %s\n" % - (expected_contents, actual_contents)) - return diffed - - def expected_checksum(self, test): - test = self.relative_test_filename(test) - return self._tests[test].expected_checksum - - def expected_image(self, test): - test = self.relative_test_filename(test) - return self._tests[test].expected_image - - def expected_text(self, test): - test = self.relative_test_filename(test) - text = self._tests[test].expected_text - if not text: - text = '' - return text - - def tests(self, paths): - # Test the idea of port-specific overrides for test lists. Also - # keep in memory to speed up the test harness. - if not paths: - paths = ['*'] - - matched_tests = [] - for p in paths: - if self.path_isdir(p): - matched_tests.extend(fnmatch.filter(self._tests.keys(), p + '*')) - else: - matched_tests.extend(fnmatch.filter(self._tests.keys(), p)) - layout_tests_dir = self.layout_tests_dir() - return set([os.path.join(layout_tests_dir, p) for p in matched_tests]) - - def path_exists(self, path): - # used by test_expectations.py and printing.py - rpath = self.relative_test_filename(path) - if rpath in self._tests: - return True - if self.path_isdir(rpath): - return True - if rpath.endswith('-expected.txt'): - test = rpath.replace('-expected.txt', '.html') - return (test in self._tests and - self._tests[test].expected_text) - if rpath.endswith('-expected.checksum'): - test = rpath.replace('-expected.checksum', '.html') - return (test in self._tests and - self._tests[test].expected_checksum) - if rpath.endswith('-expected.png'): - test = rpath.replace('-expected.png', '.html') - return (test in self._tests and - self._tests[test].expected_image) - return False - - def layout_tests_dir(self): - return self.path_from_webkit_base('WebKitTools', 'Scripts', - 'webkitpy', 'layout_tests', 'data') - - def path_isdir(self, path): - # Used by test_expectations.py - # - # We assume that a path is a directory if we have any tests that - # whose prefix matches the path plus a directory modifier. - if path[-1] != '/': - path += '/' - return any([t.startswith(path) for t in self._tests.keys()]) - - def test_dirs(self): - return ['passes', 'failures'] - - def name(self): - return self._name - - def _path_to_wdiff(self): - return None - - def results_directory(self): - return '/tmp/' + self.get_option('results_directory') - - def setup_test_run(self): - pass - - def create_driver(self, worker_number): - return TestDriver(self, worker_number) - - def start_http_server(self): - pass - - def start_websocket_server(self): - pass - - def stop_http_server(self): - pass - - def stop_websocket_server(self): - pass - - def test_expectations(self): - """Returns the test expectations for this port. - - Basically this string should contain the equivalent of a - test_expectations file. See test_expectations.py for more details.""" - return """ -WONTFIX : failures/expected/checksum.html = IMAGE -WONTFIX : failures/expected/crash.html = CRASH -// This one actually passes because the checksums will match. -WONTFIX : failures/expected/image.html = PASS -WONTFIX : failures/expected/image_checksum.html = IMAGE -WONTFIX : failures/expected/missing_check.html = MISSING PASS -WONTFIX : failures/expected/missing_image.html = MISSING PASS -WONTFIX : failures/expected/missing_text.html = MISSING PASS -WONTFIX : failures/expected/text.html = TEXT -WONTFIX : failures/expected/timeout.html = TIMEOUT -WONTFIX SKIP : failures/expected/hang.html = TIMEOUT -WONTFIX SKIP : failures/expected/keyboard.html = CRASH -WONTFIX SKIP : failures/expected/exception.html = CRASH -""" - - def test_base_platform_names(self): - return ('mac', 'win') - - def test_platform_name(self): - return 'mac' - - def test_platform_names(self): - return self.test_base_platform_names() - - def test_platform_name_to_name(self, test_platform_name): - return test_platform_name - - def version(self): - return '' - - -class TestDriver(base.Driver): - """Test/Dummy implementation of the DumpRenderTree interface.""" - - def __init__(self, port, worker_number): - self._port = port - - def cmd_line(self): - return ['None'] - - def poll(self): - return True - - def run_test(self, test_input): - start_time = time.time() - test_name = self._port.relative_test_filename(test_input.filename) - test = self._port._tests[test_name] - if test.keyboard: - raise KeyboardInterrupt - if test.exception: - raise ValueError('exception from ' + test_name) - if test.hang: - time.sleep((float(test_input.timeout) * 4) / 1000.0) - return test_output.TestOutput(test.actual_text, test.actual_image, - test.actual_checksum, test.crash, - time.time() - start_time, test.timeout, - test.error) - - def start(self): - pass - - def stop(self): - pass diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/test_files.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/test_files.py deleted file mode 100644 index 2c0a7b6..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/test_files.py +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""This module is used to find all of the layout test files used by -run-webkit-tests. It exposes one public function - find() - -which takes an optional list of paths. If a list is passed in, the returned -list of test files is constrained to those found under the paths passed in, -i.e. calling find(["LayoutTests/fast"]) will only return files -under that directory.""" - -import glob -import os -import time - -from webkitpy.common.system import logutils - - -_log = logutils.get_logger(__file__) - - -# When collecting test cases, we include any file with these extensions. -_supported_file_extensions = set(['.html', '.shtml', '.xml', '.xhtml', '.xhtmlmp', '.pl', - '.php', '.svg']) -# When collecting test cases, skip these directories -_skipped_directories = set(['.svn', '_svn', 'resources', 'script-tests']) - - -def find(port, paths): - """Finds the set of tests under port.layout_tests_dir(). - - Args: - paths: a list of command line paths relative to the layout_tests_dir() - to limit the search to. glob patterns are ok. - """ - gather_start_time = time.time() - paths_to_walk = set() - # if paths is empty, provide a pre-defined list. - if paths: - _log.debug("Gathering tests from: %s relative to %s" % (paths, port.layout_tests_dir())) - for path in paths: - # If there's an * in the name, assume it's a glob pattern. - path = os.path.join(port.layout_tests_dir(), path) - if path.find('*') > -1: - filenames = glob.glob(path) - paths_to_walk.update(filenames) - else: - paths_to_walk.add(path) - else: - _log.debug("Gathering tests from: %s" % port.layout_tests_dir()) - paths_to_walk.add(port.layout_tests_dir()) - - # Now walk all the paths passed in on the command line and get filenames - test_files = set() - for path in paths_to_walk: - if os.path.isfile(path) and _is_test_file(path): - test_files.add(os.path.normpath(path)) - continue - - for root, dirs, files in os.walk(path): - # Don't walk skipped directories or their sub-directories. - if os.path.basename(root) in _skipped_directories: - del dirs[:] - continue - # This copy and for-in is slightly inefficient, but - # the extra walk avoidance consistently shaves .5 seconds - # off of total walk() time on my MacBook Pro. - for directory in dirs[:]: - if directory in _skipped_directories: - dirs.remove(directory) - - for filename in files: - if _is_test_file(filename): - filename = os.path.join(root, filename) - filename = os.path.normpath(filename) - test_files.add(filename) - - gather_time = time.time() - gather_start_time - _log.debug("Test gathering took %f seconds" % gather_time) - - return test_files - - -def _has_supported_extension(filename): - """Return true if filename is one of the file extensions we want to run a - test on.""" - extension = os.path.splitext(filename)[1] - return extension in _supported_file_extensions - - -def _is_reference_html_file(filename): - """Return true if the filename points to a reference HTML file.""" - if (filename.endswith('-expected.html') or - filename.endswith('-expected-mismatch.html')): - _log.warn("Reftests are not supported - ignoring %s" % filename) - return True - return False - - -def _is_test_file(filename): - """Return true if the filename points to a test file.""" - return (_has_supported_extension(filename) and - not _is_reference_html_file(filename)) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/test_files_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/test_files_unittest.py deleted file mode 100644 index 83525c8..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/test_files_unittest.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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 os -import unittest - -import base -import test_files - - -class TestFilesTest(unittest.TestCase): - def test_find_no_paths_specified(self): - port = base.Port() - layout_tests_dir = port.layout_tests_dir() - port.layout_tests_dir = lambda: os.path.join(layout_tests_dir, - 'fast', 'html') - tests = test_files.find(port, []) - self.assertNotEqual(tests, 0) - - def test_find_one_test(self): - port = base.Port() - # This is just a test picked at random but known to exist. - tests = test_files.find(port, ['fast/html/keygen.html']) - self.assertEqual(len(tests), 1) - - def test_find_glob(self): - port = base.Port() - tests = test_files.find(port, ['fast/html/key*']) - self.assertEqual(len(tests), 1) - - def test_find_with_skipped_directories(self): - port = base.Port() - tests = port.tests('userscripts') - self.assertTrue('userscripts/resources/frame1.html' not in tests) - - def test_find_with_skipped_directories_2(self): - port = base.Port() - tests = test_files.find(port, ['userscripts/resources']) - self.assertEqual(tests, set([])) - - def test_is_test_file(self): - self.assertTrue(test_files._is_test_file('foo.html')) - self.assertTrue(test_files._is_test_file('foo.shtml')) - self.assertFalse(test_files._is_test_file('foo.png')) - self.assertFalse(test_files._is_test_file('foo-expected.html')) - self.assertFalse(test_files._is_test_file('foo-expected-mismatch.html')) - - -if __name__ == '__main__': - unittest.main() diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py deleted file mode 100644 index 09be833..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py +++ /dev/null @@ -1,504 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# Copyright (C) 2010 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu>, University of Szeged -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the Google name 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""WebKit implementations of the Port interface.""" - - -from __future__ import with_statement - -import codecs -import logging -import os -import re -import shutil -import signal -import sys -import time -import webbrowser -import operator -import tempfile -import shutil - -import webkitpy.common.system.ospath as ospath -import webkitpy.layout_tests.layout_package.test_output as test_output -import webkitpy.layout_tests.port.base as base -import webkitpy.layout_tests.port.server_process as server_process - -_log = logging.getLogger("webkitpy.layout_tests.port.webkit") - - -class WebKitPort(base.Port): - """WebKit implementation of the Port class.""" - - def __init__(self, **kwargs): - base.Port.__init__(self, **kwargs) - self._cached_apache_path = None - - # FIXME: disable pixel tests until they are run by default on the - # build machines. - self.set_option_default('pixel_tests', False) - - def baseline_path(self): - return self._webkit_baseline_path(self._name) - - def baseline_search_path(self): - return [self._webkit_baseline_path(self._name)] - - def path_to_test_expectations_file(self): - return os.path.join(self._webkit_baseline_path(self._name), - 'test_expectations.txt') - - # Only needed by ports which maintain versioned test expectations (like mac-tiger vs. mac-leopard) - def version(self): - return '' - - def _build_driver(self): - configuration = self.get_option('configuration') - return self._config.build_dumprendertree(configuration) - - def _check_driver(self): - driver_path = self._path_to_driver() - if not os.path.exists(driver_path): - _log.error("DumpRenderTree was not found at %s" % driver_path) - return False - return True - - def check_build(self, needs_http): - if self.get_option('build') and not self._build_driver(): - return False - if not self._check_driver(): - return False - if self.get_option('pixel_tests'): - if not self.check_image_diff(): - return False - if not self._check_port_build(): - return False - return True - - def _check_port_build(self): - # Ports can override this method to do additional checks. - return True - - def check_image_diff(self, override_step=None, logging=True): - image_diff_path = self._path_to_image_diff() - if not os.path.exists(image_diff_path): - _log.error("ImageDiff was not found at %s" % image_diff_path) - return False - return True - - def diff_image(self, expected_contents, actual_contents, - diff_filename=None): - """Return True if the two files are different. Also write a delta - image of the two images into |diff_filename| if it is not None.""" - - # Handle the case where the test didn't actually generate an image. - if not actual_contents: - return True - - sp = self._diff_image_request(expected_contents, actual_contents) - return self._diff_image_reply(sp, diff_filename) - - def _diff_image_request(self, expected_contents, actual_contents): - # FIXME: use self.get_option('tolerance') and - # self.set_option_default('tolerance', 0.1) once that behaves correctly - # with default values. - if self.get_option('tolerance') is not None: - tolerance = self.get_option('tolerance') - else: - tolerance = 0.1 - command = [self._path_to_image_diff(), '--tolerance', str(tolerance)] - sp = server_process.ServerProcess(self, 'ImageDiff', command) - - sp.write('Content-Length: %d\n%sContent-Length: %d\n%s' % - (len(actual_contents), actual_contents, - len(expected_contents), expected_contents)) - - return sp - - def _diff_image_reply(self, sp, diff_filename): - timeout = 2.0 - deadline = time.time() + timeout - output = sp.read_line(timeout) - while not sp.timed_out and not sp.crashed and output: - if output.startswith('Content-Length'): - m = re.match('Content-Length: (\d+)', output) - content_length = int(m.group(1)) - timeout = deadline - time.time() - output = sp.read(timeout, content_length) - break - elif output.startswith('diff'): - break - else: - timeout = deadline - time.time() - output = sp.read_line(deadline) - - result = True - if output.startswith('diff'): - m = re.match('diff: (.+)% (passed|failed)', output) - if m.group(2) == 'passed': - result = False - elif output and diff_filename: - with open(diff_filename, 'w') as file: - file.write(output) - elif sp.timed_out: - _log.error("ImageDiff timed out") - elif sp.crashed: - _log.error("ImageDiff crashed") - sp.stop() - return result - - def results_directory(self): - # Results are store relative to the built products to make it easy - # to have multiple copies of webkit checked out and built. - return self._build_path(self.get_option('results_directory')) - - def setup_test_run(self): - # This port doesn't require any specific configuration. - pass - - def create_driver(self, worker_number): - return WebKitDriver(self, worker_number) - - def test_base_platform_names(self): - # At the moment we don't use test platform names, but we have - # to return something. - return ('mac', 'win') - - def _tests_for_other_platforms(self): - raise NotImplementedError('WebKitPort._tests_for_other_platforms') - # The original run-webkit-tests builds up a "whitelist" of tests to - # run, and passes that to DumpRenderTree. new-run-webkit-tests assumes - # we run *all* tests and test_expectations.txt functions as a - # blacklist. - # FIXME: This list could be dynamic based on platform name and - # pushed into base.Port. - return [ - "platform/chromium", - "platform/gtk", - "platform/qt", - "platform/win", - ] - - def _runtime_feature_list(self): - """Return the supported features of DRT. If a port doesn't support - this DRT switch, it has to override this method to return None""" - driver_path = self._path_to_driver() - feature_list = ' '.join(os.popen(driver_path + " --print-supported-features 2>&1").readlines()) - if "SupportedFeatures:" in feature_list: - return feature_list - return None - - def _supported_symbol_list(self): - """Return the supported symbols of WebCore.""" - webcore_library_path = self._path_to_webcore_library() - if not webcore_library_path: - return None - symbol_list = ' '.join(os.popen("nm " + webcore_library_path).readlines()) - return symbol_list - - def _directories_for_features(self): - """Return the supported feature dictionary. The keys are the - features and the values are the directories in lists.""" - directories_for_features = { - "Accelerated Compositing": ["compositing"], - "3D Rendering": ["animations/3d", "transforms/3d"], - } - return directories_for_features - - def _directories_for_symbols(self): - """Return the supported feature dictionary. The keys are the - symbols and the values are the directories in lists.""" - directories_for_symbol = { - "MathMLElement": ["mathml"], - "GraphicsLayer": ["compositing"], - "WebCoreHas3DRendering": ["animations/3d", "transforms/3d"], - "WebGLShader": ["fast/canvas/webgl", "compositing/webgl", "http/tests/canvas/webgl"], - "WMLElement": ["http/tests/wml", "fast/wml", "wml"], - "parseWCSSInputProperty": ["fast/wcss"], - "isXHTMLMPDocument": ["fast/xhtmlmp"], - } - return directories_for_symbol - - def _skipped_tests_for_unsupported_features(self): - """Return the directories of unsupported tests. Search for the - symbols in the symbol_list, if found add the corresponding - directories to the skipped directory list.""" - feature_list = self._runtime_feature_list() - directories = self._directories_for_features() - - # if DRT feature detection not supported - if not feature_list: - feature_list = self._supported_symbol_list() - directories = self._directories_for_symbols() - - if not feature_list: - return [] - - skipped_directories = [directories[feature] - for feature in directories.keys() - if feature not in feature_list] - return reduce(operator.add, skipped_directories) - - def _tests_for_disabled_features(self): - # FIXME: This should use the feature detection from - # webkitperl/features.pm to match run-webkit-tests. - # For now we hard-code a list of features known to be disabled on - # the Mac platform. - disabled_feature_tests = [ - "fast/xhtmlmp", - "http/tests/wml", - "mathml", - "wml", - ] - # FIXME: webarchive tests expect to read-write from - # -expected.webarchive files instead of .txt files. - # This script doesn't know how to do that yet, so pretend they're - # just "disabled". - webarchive_tests = [ - "webarchive", - "svg/webarchive", - "http/tests/webarchive", - "svg/custom/image-with-prefix-in-webarchive.svg", - ] - unsupported_feature_tests = self._skipped_tests_for_unsupported_features() - return disabled_feature_tests + webarchive_tests + unsupported_feature_tests - - def _tests_from_skipped_file(self, skipped_file): - tests_to_skip = [] - for line in skipped_file.readlines(): - line = line.strip() - if line.startswith('#') or not len(line): - continue - tests_to_skip.append(line) - return tests_to_skip - - def _skipped_file_paths(self): - return [os.path.join(self._webkit_baseline_path(self._name), - 'Skipped')] - - def _expectations_from_skipped_files(self): - tests_to_skip = [] - for filename in self._skipped_file_paths(): - if not os.path.exists(filename): - _log.warn("Failed to open Skipped file: %s" % filename) - continue - with codecs.open(filename, "r", "utf-8") as skipped_file: - tests_to_skip.extend(self._tests_from_skipped_file(skipped_file)) - return tests_to_skip - - def test_expectations(self): - # The WebKit mac port uses a combination of a test_expectations file - # and 'Skipped' files. - expectations_path = self.path_to_test_expectations_file() - with codecs.open(expectations_path, "r", "utf-8") as file: - return file.read() + self._skips() - - def _skips(self): - # Each Skipped file contains a list of files - # or directories to be skipped during the test run. The total list - # of tests to skipped is given by the contents of the generic - # Skipped file found in platform/X plus a version-specific file - # found in platform/X-version. Duplicate entries are allowed. - # This routine reads those files and turns contents into the - # format expected by test_expectations. - - tests_to_skip = self.skipped_layout_tests() - skip_lines = map(lambda test_path: "BUG_SKIPPED SKIP : %s = FAIL" % - test_path, tests_to_skip) - return "\n".join(skip_lines) - - def skipped_layout_tests(self): - # Use a set to allow duplicates - tests_to_skip = set(self._expectations_from_skipped_files()) - tests_to_skip.update(self._tests_for_other_platforms()) - tests_to_skip.update(self._tests_for_disabled_features()) - return tests_to_skip - - def test_platform_name(self): - return self._name + self.version() - - def test_platform_names(self): - return self.test_base_platform_names() + ( - 'mac-tiger', 'mac-leopard', 'mac-snowleopard') - - def _build_path(self, *comps): - return self._filesystem.join(self._config.build_directory( - self.get_option('configuration')), *comps) - - def _path_to_driver(self): - return self._build_path('DumpRenderTree') - - def _path_to_webcore_library(self): - return None - - def _path_to_helper(self): - return None - - def _path_to_image_diff(self): - return self._build_path('ImageDiff') - - def _path_to_wdiff(self): - # FIXME: This does not exist on a default Mac OS X Leopard install. - return 'wdiff' - - def _path_to_apache(self): - if not self._cached_apache_path: - # The Apache binary path can vary depending on OS and distribution - # See http://wiki.apache.org/httpd/DistrosDefaultLayout - for path in ["/usr/sbin/httpd", "/usr/sbin/apache2"]: - if os.path.exists(path): - self._cached_apache_path = path - break - - if not self._cached_apache_path: - _log.error("Could not find apache. Not installed or unknown path.") - - return self._cached_apache_path - - -class WebKitDriver(base.Driver): - """WebKit implementation of the DumpRenderTree interface.""" - - def __init__(self, port, worker_number): - self._worker_number = worker_number - self._port = port - self._driver_tempdir = tempfile.mkdtemp(prefix='DumpRenderTree-') - - def __del__(self): - shutil.rmtree(self._driver_tempdir) - - def cmd_line(self): - cmd = self._command_wrapper(self._port.get_option('wrapper')) - cmd += [self._port._path_to_driver(), '-'] - - if self._port.get_option('pixel_tests'): - cmd.append('--pixel-tests') - - if self._port.get_option('use_drt'): - if self._port.get_option('accelerated_compositing'): - cmd.append('--enable-accelerated-compositing') - - if self._port.get_option('accelerated_2d_canvas'): - cmd.append('--enable-accelerated-2d-canvas') - - return cmd - - def start(self): - environment = self._port.setup_environ_for_server() - environment['DYLD_FRAMEWORK_PATH'] = self._port._build_path() - environment['DUMPRENDERTREE_TEMP'] = self._driver_tempdir - self._server_process = server_process.ServerProcess(self._port, - "DumpRenderTree", self.cmd_line(), environment) - - def poll(self): - return self._server_process.poll() - - def restart(self): - self._server_process.stop() - self._server_process.start() - return - - # FIXME: This function is huge. - def run_test(self, test_input): - uri = self._port.filename_to_uri(test_input.filename) - if uri.startswith("file:///"): - command = uri[7:] - else: - command = uri - - if test_input.image_hash: - command += "'" + test_input.image_hash - command += "\n" - - start_time = time.time() - self._server_process.write(command) - - have_seen_content_type = False - actual_image_hash = None - output = str() # Use a byte array for output, even though it should be UTF-8. - image = str() - - timeout = int(test_input.timeout) / 1000.0 - deadline = time.time() + timeout - line = self._server_process.read_line(timeout) - while (not self._server_process.timed_out - and not self._server_process.crashed - and line.rstrip() != "#EOF"): - if (line.startswith('Content-Type:') and not - have_seen_content_type): - have_seen_content_type = True - else: - # Note: Text output from DumpRenderTree is always UTF-8. - # However, some tests (e.g. webarchives) spit out binary - # data instead of text. So to make things simple, we - # always treat the output as binary. - output += line - line = self._server_process.read_line(timeout) - timeout = deadline - time.time() - - # Now read a second block of text for the optional image data - remaining_length = -1 - HASH_HEADER = 'ActualHash: ' - LENGTH_HEADER = 'Content-Length: ' - line = self._server_process.read_line(timeout) - while (not self._server_process.timed_out - and not self._server_process.crashed - and line.rstrip() != "#EOF"): - if line.startswith(HASH_HEADER): - actual_image_hash = line[len(HASH_HEADER):].strip() - elif line.startswith('Content-Type:'): - pass - elif line.startswith(LENGTH_HEADER): - timeout = deadline - time.time() - content_length = int(line[len(LENGTH_HEADER):]) - image = self._server_process.read(timeout, content_length) - timeout = deadline - time.time() - line = self._server_process.read_line(timeout) - - error_lines = self._server_process.error.splitlines() - # FIXME: This is a hack. It is unclear why sometimes - # we do not get any error lines from the server_process - # probably we are not flushing stderr. - if error_lines and error_lines[-1] == "#EOF": - error_lines.pop() # Remove the expected "#EOF" - error = "\n".join(error_lines) - # FIXME: This seems like the wrong section of code to be doing - # this reset in. - self._server_process.error = "" - return test_output.TestOutput(output, image, actual_image_hash, - self._server_process.crashed, - time.time() - start_time, - self._server_process.timed_out, - error) - - def stop(self): - if self._server_process: - self._server_process.stop() - self._server_process = None diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py deleted file mode 100644 index 7b68310..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu>, University of Szeged -# -# 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 UNIVERSITY OF SZEGED ``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 UNIVERSITY OF SZEGED OR -# 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 unittest - -from webkitpy.layout_tests.port.webkit import WebKitPort - - -class TestWebKitPort(WebKitPort): - def __init__(self, symbol_list=None, feature_list=None): - self.symbol_list = symbol_list - self.feature_list = feature_list - - def _runtime_feature_list(self): - return self.feature_list - - def _supported_symbol_list(self): - return self.symbol_list - - def _tests_for_other_platforms(self): - return ["media", ] - - def _tests_for_disabled_features(self): - return ["accessibility", ] - - def _skipped_file_paths(self): - return [] - -class WebKitPortTest(unittest.TestCase): - - def test_skipped_directories_for_symbols(self): - supported_symbols = ["GraphicsLayer", "WebCoreHas3DRendering", "isXHTMLMPDocument", "fooSymbol"] - expected_directories = set(["mathml", "fast/canvas/webgl", "compositing/webgl", "http/tests/canvas/webgl", "http/tests/wml", "fast/wml", "wml", "fast/wcss"]) - result_directories = set(TestWebKitPort(supported_symbols, None)._skipped_tests_for_unsupported_features()) - self.assertEqual(result_directories, expected_directories) - - def test_skipped_directories_for_features(self): - supported_features = ["Accelerated Compositing", "Foo Feature"] - expected_directories = set(["animations/3d", "transforms/3d"]) - result_directories = set(TestWebKitPort(None, supported_features)._skipped_tests_for_unsupported_features()) - self.assertEqual(result_directories, expected_directories) - - def test_skipped_layout_tests(self): - self.assertEqual(TestWebKitPort(None, None).skipped_layout_tests(), - set(["media", "accessibility"])) diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/websocket_server.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/websocket_server.py deleted file mode 100644 index 926bc04..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/websocket_server.py +++ /dev/null @@ -1,257 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""A class to help start/stop the PyWebSocket server used by layout tests.""" - - -from __future__ import with_statement - -import codecs -import logging -import optparse -import os -import subprocess -import sys -import tempfile -import time -import urllib - -import factory -import http_server - -from webkitpy.common.system.executive import Executive -from webkitpy.thirdparty.autoinstalled.pywebsocket import mod_pywebsocket - - -_log = logging.getLogger("webkitpy.layout_tests.port.websocket_server") - -_WS_LOG_PREFIX = 'pywebsocket.ws.log-' -_WSS_LOG_PREFIX = 'pywebsocket.wss.log-' - -_DEFAULT_WS_PORT = 8880 -_DEFAULT_WSS_PORT = 9323 - - -def url_is_alive(url): - """Checks to see if we get an http response from |url|. - We poll the url 20 times with a 0.5 second delay. If we don't - get a reply in that time, we give up and assume the httpd - didn't start properly. - - Args: - url: The URL to check. - Return: - True if the url is alive. - """ - sleep_time = 0.5 - wait_time = 10 - while wait_time > 0: - try: - response = urllib.urlopen(url) - # Server is up and responding. - return True - except IOError: - pass - # Wait for sleep_time before trying again. - wait_time -= sleep_time - time.sleep(sleep_time) - - return False - - -class PyWebSocketNotStarted(Exception): - pass - - -class PyWebSocketNotFound(Exception): - pass - - -class PyWebSocket(http_server.Lighttpd): - - def __init__(self, port_obj, output_dir, port=_DEFAULT_WS_PORT, - root=None, use_tls=False, - pidfile=None): - """Args: - output_dir: the absolute path to the layout test result directory - """ - http_server.Lighttpd.__init__(self, port_obj, output_dir, - port=_DEFAULT_WS_PORT, - root=root) - self._output_dir = output_dir - self._process = None - self._port = port - self._root = root - self._use_tls = use_tls - self._private_key = self._pem_file - self._certificate = self._pem_file - if self._port: - self._port = int(self._port) - if self._use_tls: - self._server_name = 'PyWebSocket(Secure)' - else: - self._server_name = 'PyWebSocket' - self._pidfile = pidfile - self._wsout = None - - # Webkit tests - if self._root: - self._layout_tests = os.path.abspath(self._root) - self._web_socket_tests = os.path.abspath( - os.path.join(self._root, 'http', 'tests', - 'websocket', 'tests')) - else: - try: - self._layout_tests = self._port_obj.layout_tests_dir() - self._web_socket_tests = os.path.join(self._layout_tests, - 'http', 'tests', 'websocket', 'tests') - except: - self._web_socket_tests = None - - def start(self): - if not self._web_socket_tests: - _log.info('No need to start %s server.' % self._server_name) - return - if self.is_running(): - raise PyWebSocketNotStarted('%s is already running.' % - self._server_name) - - time_str = time.strftime('%d%b%Y-%H%M%S') - if self._use_tls: - log_prefix = _WSS_LOG_PREFIX - else: - log_prefix = _WS_LOG_PREFIX - log_file_name = log_prefix + time_str - - # Remove old log files. We only need to keep the last ones. - self.remove_log_files(self._output_dir, log_prefix) - - error_log = os.path.join(self._output_dir, log_file_name + "-err.txt") - - output_log = os.path.join(self._output_dir, log_file_name + "-out.txt") - self._wsout = codecs.open(output_log, "w", "utf-8") - - python_interp = sys.executable - pywebsocket_base = os.path.join( - os.path.dirname(os.path.dirname(os.path.dirname( - os.path.abspath(__file__)))), 'thirdparty', - 'autoinstalled', 'pywebsocket') - pywebsocket_script = os.path.join(pywebsocket_base, 'mod_pywebsocket', - 'standalone.py') - start_cmd = [ - python_interp, '-u', pywebsocket_script, - '--server-host', '127.0.0.1', - '--port', str(self._port), - '--document-root', os.path.join(self._layout_tests, 'http', 'tests'), - '--scan-dir', self._web_socket_tests, - '--cgi-paths', '/websocket/tests', - '--log-file', error_log, - ] - - handler_map_file = os.path.join(self._web_socket_tests, - 'handler_map.txt') - if os.path.exists(handler_map_file): - _log.debug('Using handler_map_file: %s' % handler_map_file) - start_cmd.append('--websock-handlers-map-file') - start_cmd.append(handler_map_file) - else: - _log.warning('No handler_map_file found') - - if self._use_tls: - start_cmd.extend(['-t', '-k', self._private_key, - '-c', self._certificate]) - - env = self._port_obj.setup_environ_for_server() - env['PYTHONPATH'] = (pywebsocket_base + os.path.pathsep + - env.get('PYTHONPATH', '')) - - _log.debug('Starting %s server on %d.' % ( - self._server_name, self._port)) - _log.debug('cmdline: %s' % ' '.join(start_cmd)) - # FIXME: We should direct this call through Executive for testing. - # Note: Not thread safe: http://bugs.python.org/issue2320 - self._process = subprocess.Popen(start_cmd, - stdin=open(os.devnull, 'r'), - stdout=self._wsout, - stderr=subprocess.STDOUT, - env=env) - - if self._use_tls: - url = 'https' - else: - url = 'http' - url = url + '://127.0.0.1:%d/' % self._port - if not url_is_alive(url): - if self._process.returncode == None: - # FIXME: We should use a non-static Executive for easier - # testing. - Executive().kill_process(self._process.pid) - with codecs.open(output_log, "r", "utf-8") as fp: - for line in fp: - _log.error(line) - raise PyWebSocketNotStarted( - 'Failed to start %s server on port %s.' % - (self._server_name, self._port)) - - # Our process terminated already - if self._process.returncode != None: - raise PyWebSocketNotStarted( - 'Failed to start %s server.' % self._server_name) - if self._pidfile: - with codecs.open(self._pidfile, "w", "ascii") as file: - file.write("%d" % self._process.pid) - - def stop(self, force=False): - if not force and not self.is_running(): - return - - pid = None - if self._process: - pid = self._process.pid - elif self._pidfile: - with codecs.open(self._pidfile, "r", "ascii") as file: - pid = int(file.read().strip()) - - if not pid: - raise PyWebSocketNotFound( - 'Failed to find %s server pid.' % self._server_name) - - _log.debug('Shutting down %s server %d.' % (self._server_name, pid)) - # FIXME: We should use a non-static Executive for easier testing. - Executive().kill_process(pid) - - if self._process: - # wait() is not threadsafe and can throw OSError due to: - # http://bugs.python.org/issue1731717 - self._process.wait() - self._process = None - - if self._wsout: - self._wsout.close() - self._wsout = None diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/win.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/win.py deleted file mode 100644 index 9e30155..0000000 --- a/WebKitTools/Scripts/webkitpy/layout_tests/port/win.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright (C) 2010 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * 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. -# * Neither the Google name 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -# OWNER OR 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. - -"""WebKit Win implementation of the Port interface.""" - -import logging -import os - -from webkitpy.layout_tests.port.webkit import WebKitPort - -_log = logging.getLogger("webkitpy.layout_tests.port.win") - - -class WinPort(WebKitPort): - """WebKit Win implementation of the Port class.""" - - def __init__(self, **kwargs): - kwargs.setdefault('port_name', 'win') - WebKitPort.__init__(self, **kwargs) - - def baseline_search_path(self): - # Based on code from old-run-webkit-tests expectedDirectoryForTest() - port_names = ["win", "mac-snowleopard", "mac"] - return map(self._webkit_baseline_path, port_names) - - def _tests_for_other_platforms(self): - # FIXME: This list could be dynamic based on platform name and - # pushed into base.Port. - # This really need to be automated. - return [ - "platform/chromium", - "platform/gtk", - "platform/qt", - "platform/mac", - ] - - def _path_to_apache_config_file(self): - return os.path.join(self.layout_tests_dir(), 'http', 'conf', - 'cygwin-httpd.conf') - - def _shut_down_http_server(self, server_pid): - """Shut down the httpd web server. Blocks until it's fully - shut down. - - Args: - server_pid: The process ID of the running server. - """ - # Looks like we ignore server_pid. - # Copy/pasted from chromium-win. - self._executive.kill_all("httpd.exe") |