[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.20-204-g221d8e8
dpranke at chromium.org
dpranke at chromium.org
Wed Feb 10 22:12:10 UTC 2010
The following commit has been merged in the webkit-1.1 branch:
commit ac2c69988b550294aa6966c7afd3f4955cf668f2
Author: dpranke at chromium.org <dpranke at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Thu Feb 4 07:51:49 2010 +0000
2010-02-03 Dirk Pranke <dpranke at chromium.org>
Rubber-stamped by Eric Siedel.
Rename files as part of refactoring the layout_tests package. All
the platform_utils* module, the path_utils.py module, and
the http server and web socket server modules are moved into a new
port/ package.
https://bugs.webkit.org/show_bug.cgi?id=34511
* Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py:
* Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py:
* Scripts/webkitpy/layout_tests/layout_package/test_expectations.py:
* Scripts/webkitpy/layout_tests/layout_package/test_files.py:
* Scripts/webkitpy/layout_tests/layout_package/test_shell_thread.py:
* Scripts/webkitpy/layout_tests/port/__init__.py: Renamed from WebKitTools/Scripts/webkitpy/layout_tests/layout_package/platform_utils.py.
* Scripts/webkitpy/layout_tests/port/apache_http_server.py: Renamed from WebKitTools/Scripts/webkitpy/layout_tests/layout_package/apache_http_server.py.
* Scripts/webkitpy/layout_tests/port/chromium_linux.py: Renamed from WebKitTools/Scripts/webkitpy/layout_tests/layout_package/platform_utils_linux.py.
* Scripts/webkitpy/layout_tests/port/chromium_mac.py: Renamed from WebKitTools/Scripts/webkitpy/layout_tests/layout_package/platform_utils_mac.py.
* Scripts/webkitpy/layout_tests/port/chromium_win.py: Renamed from WebKitTools/Scripts/webkitpy/layout_tests/layout_package/platform_utils_win.py.
* Scripts/webkitpy/layout_tests/port/http_server.py: Renamed from WebKitTools/Scripts/webkitpy/layout_tests/layout_package/http_server.py.
* Scripts/webkitpy/layout_tests/port/http_server_base.py: Renamed from WebKitTools/Scripts/webkitpy/layout_tests/layout_package/http_server_base.py.
* Scripts/webkitpy/layout_tests/port/httpd2.pem: Renamed from WebKitTools/Scripts/webkitpy/layout_tests/layout_package/httpd2.pem.
* Scripts/webkitpy/layout_tests/port/lighttpd.conf: Renamed from WebKitTools/Scripts/webkitpy/layout_tests/layout_package/lighttpd.conf.
* Scripts/webkitpy/layout_tests/port/path_utils.py: Renamed from WebKitTools/Scripts/webkitpy/layout_tests/layout_package/path_utils.py.
* Scripts/webkitpy/layout_tests/port/websocket_server.py: Renamed from WebKitTools/Scripts/webkitpy/layout_tests/layout_package/websocket_server.py.
* Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py:
* Scripts/webkitpy/layout_tests/run_chromium_webkit_tests.py:
* Scripts/webkitpy/layout_tests/test_types/fuzzy_image_diff.py:
* Scripts/webkitpy/layout_tests/test_types/image_diff.py:
* Scripts/webkitpy/layout_tests/test_types/test_type_base.py:
* Scripts/webkitpy/layout_tests/test_types/text_diff.py:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@54327 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index fb86419..918bcd4 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,49 @@
+2010-02-03 Dirk Pranke <dpranke at chromium.org>
+
+ Rubber-stamped by Eric Seidel.
+
+ Rename files as part of refactoring the layout_tests package. All
+ the platform_utils* module, the path_utils.py module, and
+ the http server and web socket server modules are moved into a new
+ port/ package.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34511
+
+ * Scripts/webkitpy/layout_tests/layout_package/apache_http_server.py: Removed.
+ * Scripts/webkitpy/layout_tests/layout_package/http_server.py: Removed.
+ * Scripts/webkitpy/layout_tests/layout_package/http_server_base.py: Removed.
+ * Scripts/webkitpy/layout_tests/layout_package/httpd2.pem: Removed.
+ * Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py:
+ * Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py:
+ * Scripts/webkitpy/layout_tests/layout_package/lighttpd.conf: Removed.
+ * Scripts/webkitpy/layout_tests/layout_package/path_utils.py: Removed.
+ * Scripts/webkitpy/layout_tests/layout_package/platform_utils.py: Removed.
+ * Scripts/webkitpy/layout_tests/layout_package/platform_utils_linux.py: Removed.
+ * Scripts/webkitpy/layout_tests/layout_package/platform_utils_mac.py: Removed.
+ * Scripts/webkitpy/layout_tests/layout_package/platform_utils_win.py: Removed.
+ * Scripts/webkitpy/layout_tests/layout_package/test_expectations.py:
+ * Scripts/webkitpy/layout_tests/layout_package/test_files.py:
+ * Scripts/webkitpy/layout_tests/layout_package/test_shell_thread.py:
+ * Scripts/webkitpy/layout_tests/layout_package/websocket_server.py: Removed.
+ * Scripts/webkitpy/layout_tests/port: Added.
+ * Scripts/webkitpy/layout_tests/port/__init__.py: Copied from Scripts/webkitpy/layout_tests/layout_package/platform_utils.py.
+ * Scripts/webkitpy/layout_tests/port/apache_http_server.py: Copied from Scripts/webkitpy/layout_tests/layout_package/apache_http_server.py.
+ * Scripts/webkitpy/layout_tests/port/chromium_linux.py: Copied from Scripts/webkitpy/layout_tests/layout_package/platform_utils_linux.py.
+ * Scripts/webkitpy/layout_tests/port/chromium_mac.py: Copied from Scripts/webkitpy/layout_tests/layout_package/platform_utils_mac.py.
+ * Scripts/webkitpy/layout_tests/port/chromium_win.py: Copied from Scripts/webkitpy/layout_tests/layout_package/platform_utils_win.py.
+ * Scripts/webkitpy/layout_tests/port/http_server.py: Copied from Scripts/webkitpy/layout_tests/layout_package/http_server.py.
+ * Scripts/webkitpy/layout_tests/port/http_server_base.py: Copied from Scripts/webkitpy/layout_tests/layout_package/http_server_base.py.
+ * Scripts/webkitpy/layout_tests/port/httpd2.pem: Copied from Scripts/webkitpy/layout_tests/layout_package/httpd2.pem.
+ * Scripts/webkitpy/layout_tests/port/lighttpd.conf: Copied from Scripts/webkitpy/layout_tests/layout_package/lighttpd.conf.
+ * Scripts/webkitpy/layout_tests/port/path_utils.py: Copied from Scripts/webkitpy/layout_tests/layout_package/path_utils.py.
+ * Scripts/webkitpy/layout_tests/port/websocket_server.py: Copied from Scripts/webkitpy/layout_tests/layout_package/websocket_server.py.
+ * Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py:
+ * Scripts/webkitpy/layout_tests/run_chromium_webkit_tests.py:
+ * Scripts/webkitpy/layout_tests/test_types/fuzzy_image_diff.py:
+ * Scripts/webkitpy/layout_tests/test_types/image_diff.py:
+ * Scripts/webkitpy/layout_tests/test_types/test_type_base.py:
+ * Scripts/webkitpy/layout_tests/test_types/text_diff.py:
+
2010-02-03 Csaba Osztrogonác <ossy at webkit.org>
Rubber-stamped by Eric Seidel.
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/apache_http_server.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/apache_http_server.py
deleted file mode 100644
index 307a335..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/apache_http_server.py
+++ /dev/null
@@ -1,229 +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 Chromium 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.
-
-"""A class to start/stop the apache http server used by layout tests."""
-
-import logging
-import optparse
-import os
-import re
-import subprocess
-import sys
-
-import http_server_base
-import path_utils
-import platform_utils
-
-
-class LayoutTestApacheHttpd(http_server_base.HttpServerBase):
-
- def __init__(self, output_dir):
- """Args:
- output_dir: the absolute path to the layout test result directory
- """
- self._output_dir = output_dir
- self._httpd_proc = None
- path_utils.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")
- path_utils.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 = path_utils.path_from_base('third_party', 'WebKit',
- 'LayoutTests')
- 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")
-
- executable = platform_utils.apache_executable_path()
- if self._is_cygwin():
- executable = self._get_cygwin_path(executable)
-
- cmd = [executable,
- '-f', 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 = path_utils.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 = platform_utils.apache_config_file_path()
- httpd_config_copy = os.path.join(output_dir, "httpd.conf")
- httpd_conf = open(httpd_config).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 = path_utils.path_from_base('third_party', 'cygwin', 'usr')
- httpd_conf = httpd_conf.replace('ServerRoot "/usr"',
- 'ServerRoot "%s"' % self._get_cygwin_path(cygusr))
-
- # TODO(ojan): Instead of writing an extra file, checkin a conf file
- # upstream. Or, even better, upstream/delete all our chrome http
- # tests so we don't need this special-cased DocumentRoot and then
- # just use the upstream
- # conf file.
- chrome_document_root = path_utils.path_from_base('webkit', 'data',
- 'layout_tests')
- if self._is_cygwin():
- chrome_document_root = self._get_cygwin_path(chrome_document_root)
- httpd_conf = (httpd_conf +
- self._get_virtual_host_config(chrome_document_root, 8081))
-
- f = open(httpd_config_copy, 'wb')
- f.write(httpd_conf)
- f.close()
-
- 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.
- self._httpd_proc = subprocess.Popen(self._start_cmd,
- stderr=subprocess.PIPE,
- shell=True)
- err = self._httpd_proc.stderr.read()
- if len(err):
- logging.debug(err)
- return False
- return True
-
- def start(self):
- """Starts the apache http server."""
- # Stop any currently running servers.
- self.stop()
-
- logging.debug("Starting apache http server")
- server_started = self.wait_for_action(self._start_httpd_process)
- if server_started:
- logging.debug("Apache started. Testing ports")
- server_started = self.wait_for_action(
- self.is_server_running_on_all_ports)
-
- if server_started:
- logging.debug("Server successfully started")
- else:
- raise Exception('Failed to start http server')
-
- def stop(self):
- """Stops the apache http server."""
- logging.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())
- path_utils.shut_down_http_server(httpd_pid)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py
index 271ff6c..5d90d13 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py
@@ -31,7 +31,7 @@ import logging
import os
from layout_package import json_results_generator
-from layout_package import path_utils
+from port import path_utils
from layout_package import test_expectations
from layout_package import test_failures
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py
index 0540194..bce6d13 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py
@@ -35,7 +35,7 @@ import time
import urllib2
import xml.dom.minidom
-from layout_package import path_utils
+from port import path_utils
from layout_package import test_expectations
sys.path.append(path_utils.path_from_base('third_party', 'WebKit',
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/path_utils.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/path_utils.py
deleted file mode 100644
index 48b7611..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/path_utils.py
+++ /dev/null
@@ -1,395 +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 Chromium 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 package contains utility methods for manipulating paths and
-filenames for test results and baselines. It also contains wrappers
-of a few routines in platform_utils.py so that platform_utils.py can
-be considered a 'protected' package - i.e., this file should be
-the only file that ever includes platform_utils. This leads to
-us including a few things that don't really have anything to do
- with paths, unfortunately."""
-
-import errno
-import os
-import stat
-import sys
-
-import platform_utils
-import platform_utils_win
-import platform_utils_mac
-import platform_utils_linux
-
-# Cache some values so we don't have to recalculate them. _basedir is
-# used by PathFromBase() and caches the full (native) path to the top
-# of the source tree (/src). _baseline_search_path is used by
-# ExpectedBaselines() and caches the list of native paths to search
-# for baseline results.
-_basedir = None
-_baseline_search_path = None
-
-
-class PathNotFound(Exception):
- pass
-
-
-def layout_tests_dir():
- """Returns the fully-qualified path to the directory containing the input
- data for the specified layout test."""
- return path_from_base('third_party', 'WebKit', 'LayoutTests')
-
-
-def chromium_baseline_path(platform=None):
- """Returns the full path to the directory containing expected
- baseline results from chromium ports. If |platform| is None, the
- currently executing platform is used.
-
- Note: although directly referencing individual platform_utils_* files is
- usually discouraged, we allow it here so that the rebaselining tool can
- pull baselines for platforms other than the host platform."""
-
- # Normalize the platform string.
- platform = platform_name(platform)
- if platform.startswith('chromium-mac'):
- return platform_utils_mac.baseline_path(platform)
- elif platform.startswith('chromium-win'):
- return platform_utils_win.baseline_path(platform)
- elif platform.startswith('chromium-linux'):
- return platform_utils_linux.baseline_path(platform)
-
- return platform_utils.baseline_path()
-
-
-def webkit_baseline_path(platform):
- """Returns the full path to the directory containing expected
- baseline results from WebKit ports."""
- return path_from_base('third_party', 'WebKit', 'LayoutTests',
- 'platform', platform)
-
-
-def baseline_search_path(platform=None):
- """Returns the list of directories to search for baselines/results for a
- given platform, in order of preference. Paths are relative to the top of
- the source tree. If parameter platform is None, returns the list for the
- current platform that the script is running on.
-
- Note: although directly referencing individual platform_utils_* files is
- usually discouraged, we allow it here so that the rebaselining tool can
- pull baselines for platforms other than the host platform."""
-
- # Normalize the platform name.
- platform = platform_name(platform)
- if platform.startswith('chromium-mac'):
- return platform_utils_mac.baseline_search_path(platform)
- elif platform.startswith('chromium-win'):
- return platform_utils_win.baseline_search_path(platform)
- elif platform.startswith('chromium-linux'):
- return platform_utils_linux.baseline_search_path(platform)
- return platform_utils.baseline_search_path()
-
-
-def expected_baselines(filename, suffix, platform=None, 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.
- platform: layout test platform: 'win', 'linux' or 'mac'. Defaults to
- the current platform.
- 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.
- """
- global _baseline_search_path
- global _search_path_platform
- testname = os.path.splitext(relative_test_filename(filename))[0]
-
- baseline_filename = testname + '-expected' + suffix
-
- if (_baseline_search_path is None) or (_search_path_platform != platform):
- _baseline_search_path = baseline_search_path(platform)
- _search_path_platform = platform
-
- baselines = []
- for platform_dir in _baseline_search_path:
- if os.path.exists(os.path.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 = layout_tests_dir()
- if os.path.exists(os.path.join(platform_dir, baseline_filename)):
- baselines.append((platform_dir, baseline_filename))
-
- if baselines:
- return baselines
-
- return [(None, baseline_filename)]
-
-
-def expected_filename(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)
- """
- platform_dir, baseline_filename = expected_baselines(filename, suffix)[0]
- if platform_dir:
- return os.path.join(platform_dir, baseline_filename)
- return os.path.join(layout_tests_dir(), baseline_filename)
-
-
-def relative_test_filename(filename):
- """Provide the filename of the test relative to the layout tests
- directory as a unix style path (a/b/c)."""
- return _win_path_to_unix(filename[len(layout_tests_dir()) + 1:])
-
-
-def _win_path_to_unix(path):
- """Convert a windows path to use unix-style path separators (a/b/c)."""
- return path.replace('\\', '/')
-
-#
-# Routines that are arguably platform-specific but have been made
-# generic for now (they used to be in platform_utils_*)
-#
-
-
-def filename_to_uri(full_path):
- """Convert a test file to a URI."""
- LAYOUTTEST_HTTP_DIR = "http/tests/"
- LAYOUTTEST_WEBSOCKET_DIR = "websocket/tests/"
-
- relative_path = _win_path_to_unix(relative_test_filename(full_path))
- port = None
- use_ssl = False
-
- if relative_path.startswith(LAYOUTTEST_HTTP_DIR):
- # http/tests/ run off port 8000 and ssl/ off 8443
- relative_path = relative_path[len(LAYOUTTEST_HTTP_DIR):]
- port = 8000
- elif relative_path.startswith(LAYOUTTEST_WEBSOCKET_DIR):
- # websocket/tests/ run off port 8880 and 9323
- # Note: the root is /, not websocket/tests/
- port = 8880
-
- # Make http/tests/local run as local files. This is to mimic the
- # logic in run-webkit-tests.
- # TODO(jianli): Consider extending this to "media/".
- if port and not relative_path.startswith("local/"):
- if relative_path.startswith("ssl/"):
- port += 443
- protocol = "https"
- else:
- protocol = "http"
- return "%s://127.0.0.1:%u/%s" % (protocol, port, relative_path)
-
- if sys.platform in ('cygwin', 'win32'):
- return "file:///" + get_absolute_path(full_path)
- return "file://" + get_absolute_path(full_path)
-
-
-def get_absolute_path(path):
- """Returns an absolute UNIX path."""
- return _win_path_to_unix(os.path.abspath(path))
-
-
-def maybe_make_directory(*path):
- """Creates the specified directory if it doesn't already exist."""
- try:
- os.makedirs(os.path.join(*path))
- except OSError, e:
- if e.errno != errno.EEXIST:
- raise
-
-
-def path_from_base(*comps):
- """Returns an absolute filename from a set of components specified
- relative to the top of the source tree. If the path does not exist,
- the exception PathNotFound is raised."""
- global _basedir
- if _basedir == None:
- # We compute the top of the source tree by finding the absolute
- # path of this source file, and then climbing up three directories
- # as given in subpath. If we move this file, subpath needs to be
- # updated.
- path = os.path.abspath(__file__)
- subpath = os.path.join('third_party', 'WebKit')
- _basedir = path[:path.index(subpath)]
- path = os.path.join(_basedir, *comps)
- if not os.path.exists(path):
- raise PathNotFound('could not find %s' % (path))
- return path
-
-
-def remove_directory(*path):
- """Recursively removes a directory, even if it's marked read-only.
-
- Remove the directory located at *path, if it exists.
-
- shutil.rmtree() doesn't work on Windows if any of the files or directories
- are read-only, which svn repositories and some .svn files are. We need to
- be able to force the files to be writable (i.e., deletable) as we traverse
- the tree.
-
- Even with all this, Windows still sometimes fails to delete a file, citing
- a permission error (maybe something to do with antivirus scans or disk
- indexing). The best suggestion any of the user forums had was to wait a
- bit and try again, so we do that too. It's hand-waving, but sometimes it
- works. :/
- """
- file_path = os.path.join(*path)
- if not os.path.exists(file_path):
- return
-
- win32 = False
- if sys.platform == 'win32':
- win32 = True
- # Some people don't have the APIs installed. In that case we'll do
- # without.
- try:
- win32api = __import__('win32api')
- win32con = __import__('win32con')
- except ImportError:
- win32 = False
-
- def remove_with_retry(rmfunc, path):
- os.chmod(path, stat.S_IWRITE)
- if win32:
- win32api.SetFileAttributes(path,
- win32con.FILE_ATTRIBUTE_NORMAL)
- try:
- return rmfunc(path)
- except EnvironmentError, e:
- if e.errno != errno.EACCES:
- raise
- print 'Failed to delete %s: trying again' % repr(path)
- time.sleep(0.1)
- return rmfunc(path)
- else:
-
- def remove_with_retry(rmfunc, path):
- if os.path.islink(path):
- return os.remove(path)
- else:
- return rmfunc(path)
-
- for root, dirs, files in os.walk(file_path, topdown=False):
- # For POSIX: making the directory writable guarantees removability.
- # Windows will ignore the non-read-only bits in the chmod value.
- os.chmod(root, 0770)
- for name in files:
- remove_with_retry(os.remove, os.path.join(root, name))
- for name in dirs:
- remove_with_retry(os.rmdir, os.path.join(root, name))
-
- remove_with_retry(os.rmdir, file_path)
-
-#
-# Wrappers around platform_utils
-#
-
-
-def platform_name(platform=None):
- """Returns the appropriate chromium platform name for |platform|. If
- |platform| is None, returns the name of the chromium platform on the
- currently running system. If |platform| is of the form 'chromium-*',
- it is returned unchanged, otherwise 'chromium-' is prepended."""
- if platform == None:
- return platform_utils.platform_name()
- if not platform.startswith('chromium-'):
- platform = "chromium-" + platform
- return platform
-
-
-def platform_version():
- return platform_utils.platform_version()
-
-
-def lighttpd_executable_path():
- return platform_utils.lighttpd_executable_path()
-
-
-def lighttpd_module_path():
- return platform_utils.lighttpd_module_path()
-
-
-def lighttpd_php_path():
- return platform_utils.lighttpd_php_path()
-
-
-def wdiff_path():
- return platform_utils.wdiff_path()
-
-
-def test_shell_path(target):
- return platform_utils.test_shell_path(target)
-
-
-def image_diff_path(target):
- return platform_utils.image_diff_path(target)
-
-
-def layout_test_helper_path(target):
- return platform_utils.layout_test_helper_path(target)
-
-
-def fuzzy_match_path():
- return platform_utils.fuzzy_match_path()
-
-
-def shut_down_http_server(server_pid):
- return platform_utils.shut_down_http_server(server_pid)
-
-
-def kill_all_test_shells():
- platform_utils.kill_all_test_shells()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/platform_utils.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/platform_utils.py
deleted file mode 100644
index c6a801c..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/platform_utils.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 Chromium 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.
-
-"""Platform-specific utilities and pseudo-constants
-
-Any functions whose implementations or values differ from one platform to
-another should be defined in their respective platform_utils_<platform>.py
-modules. The appropriate one of those will be imported into this module to
-provide callers with a common, platform-independent interface.
-
-This file should only ever be imported by layout_package.path_utils.
-"""
-
-import sys
-
-# We may not support the version of Python that a user has installed (Cygwin
-# especially has had problems), but we'll allow the platform utils to be
-# included in any case so we don't get an import error.
-if sys.platform in ('cygwin', 'win32'):
- from platform_utils_win import *
-elif sys.platform == 'darwin':
- from platform_utils_mac import *
-elif sys.platform in ('linux', 'linux2', 'freebsd7', 'openbsd4'):
- from platform_utils_linux import *
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/platform_utils_linux.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/platform_utils_linux.py
deleted file mode 100644
index bb1c5da..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/platform_utils_linux.py
+++ /dev/null
@@ -1,248 +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 Chromium 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 the Linux implementation of the layout_package.platform_utils
- package. This file should only be imported by that package."""
-
-import os
-import signal
-import subprocess
-import sys
-import logging
-
-import path_utils
-import platform_utils_win
-
-
-def platform_name():
- """Returns the name of the platform we're currently running on."""
- return 'chromium-linux' + platform_version()
-
-
-def platform_version():
- """Returns the version string for the platform, e.g. '-vista' or
- '-snowleopard'. If the platform does not distinguish between
- minor versions, it returns ''."""
- return ''
-
-
-def get_num_cores():
- """Returns the number of cores on the machine. For hyperthreaded machines,
- this will be double the number of actual processors."""
- num_cores = os.sysconf("SC_NPROCESSORS_ONLN")
- if isinstance(num_cores, int) and num_cores > 0:
- return num_cores
- return 1
-
-
-def baseline_path(platform=None):
- """Returns the path relative to the top of the source tree for the
- baselines for the specified platform version. If |platform| is None,
- then the version currently in use is used."""
- if platform is None:
- platform = platform_name()
- return path_utils.path_from_base('webkit', 'data', 'layout_tests',
- 'platform', platform, 'LayoutTests')
-
-
-def baseline_search_path(platform=None):
- """Returns the list of directories to search for baselines/results, in
- order of preference. Paths are relative to the top of the source tree."""
- return [baseline_path(platform),
- platform_utils_win.baseline_path('chromium-win'),
- path_utils.webkit_baseline_path('win'),
- path_utils.webkit_baseline_path('mac')]
-
-
-def apache_executable_path():
- """Returns the executable path to start Apache"""
- path = os.path.join("/usr", "sbin", "apache2")
- if os.path.exists(path):
- return path
- print "Unable to fine Apache executable %s" % path
- _missing_apache()
-
-
-def apache_config_file_path():
- """Returns the path to Apache config file"""
- return path_utils.path_from_base("third_party", "WebKit", "LayoutTests",
- "http", "conf", "apache2-debian-httpd.conf")
-
-
-def lighttpd_executable_path():
- """Returns the executable path to start LigHTTPd"""
- binpath = "/usr/sbin/lighttpd"
- if os.path.exists(binpath):
- return binpath
- print "Unable to find LigHTTPd executable %s" % binpath
- _missing_lighttpd()
-
-
-def lighttpd_module_path():
- """Returns the library module path for LigHTTPd"""
- modpath = "/usr/lib/lighttpd"
- if os.path.exists(modpath):
- return modpath
- print "Unable to find LigHTTPd modules %s" % modpath
- _missing_lighttpd()
-
-
-def lighttpd_php_path():
- """Returns the PHP executable path for LigHTTPd"""
- binpath = "/usr/bin/php-cgi"
- if os.path.exists(binpath):
- return binpath
- print "Unable to find PHP CGI executable %s" % binpath
- _missing_lighttpd()
-
-
-def wdiff_path():
- """Path to the WDiff executable, which we assume is already installed and
- in the user's $PATH."""
- return 'wdiff'
-
-
-def image_diff_path(target):
- """Path to the image_diff binary.
-
- Args:
- target: Build target mode (debug or release)"""
- return _path_from_build_results(target, 'image_diff')
-
-
-def layout_test_helper_path(target):
- """Path to the layout_test helper binary, if needed, empty otherwise"""
- return ''
-
-
-def test_shell_path(target):
- """Return the platform-specific binary path for our TestShell.
-
- Args:
- target: Build target mode (debug or release) """
- if target in ('Debug', 'Release'):
- try:
- debug_path = _path_from_build_results('Debug', 'test_shell')
- release_path = _path_from_build_results('Release', 'test_shell')
-
- debug_mtime = os.stat(debug_path).st_mtime
- release_mtime = os.stat(release_path).st_mtime
-
- if debug_mtime > release_mtime and target == 'Release' or \
- release_mtime > debug_mtime and target == 'Debug':
- logging.info('\x1b[31mWarning: you are not running the most '
- 'recent test_shell binary. You need to pass '
- '--debug or not to select between Debug and '
- 'Release.\x1b[0m')
- # 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 path_utils.PathNotFound:
- pass
-
- return _path_from_build_results(target, 'test_shell')
-
-
-def fuzzy_match_path():
- """Return the path to the fuzzy matcher binary."""
- return path_utils.path_from_base('third_party', 'fuzzymatch', 'fuzzymatch')
-
-
-def shut_down_http_server(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:
- # This isn't ideal, since it could conflict with web server processes
- # not started by http_server.py, but good enough for now.
- kill_all_process('lighttpd')
- kill_all_process('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.
- shut_down_http_server(None)
-
-
-def kill_process(pid):
- """Forcefully kill the process.
-
- Args:
- pid: The id of the process to be killed.
- """
- os.kill(pid, signal.SIGKILL)
-
-
-def kill_all_process(process_name):
- null = open(os.devnull)
- subprocess.call(['killall', '-TERM', '-u', os.getenv('USER'),
- process_name], stderr=null)
- null.close()
-
-
-def kill_all_test_shells():
- """Kills all instances of the test_shell binary currently running."""
- kill_all_process('test_shell')
-
-#
-# Private helper functions
-#
-
-
-def _missing_lighttpd():
- print 'Please install using: "sudo apt-get install lighttpd php5-cgi"'
- print 'For complete Linux build requirements, please see:'
- print 'http://code.google.com/p/chromium/wiki/LinuxBuildInstructions'
- sys.exit(1)
-
-
-def _missing_apache():
- print ('Please install using: "sudo apt-get install apache2 '
- 'libapache2-mod-php5"')
- print 'For complete Linux build requirements, please see:'
- print 'http://code.google.com/p/chromium/wiki/LinuxBuildInstructions'
- sys.exit(1)
-
-
-def _path_from_build_results(*pathies):
- # FIXME(dkegel): use latest or warn if more than one found?
- for dir in ["sconsbuild", "out", "xcodebuild"]:
- try:
- return path_utils.path_from_base(dir, *pathies)
- except:
- pass
- raise path_utils.PathNotFound("Unable to find %s in build tree" %
- (os.path.join(*pathies)))
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/platform_utils_mac.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/platform_utils_mac.py
deleted file mode 100644
index 38c221e..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/platform_utils_mac.py
+++ /dev/null
@@ -1,201 +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 Chromium 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 the Mac implementation of the layout_package.platform_utils
- package. This file should only be imported by that package."""
-
-import os
-import platform
-import signal
-import subprocess
-
-import path_utils
-
-
-def platform_name():
- """Returns the name of the platform we're currently running on."""
- # At the moment all chromium mac results are version-independent. At some
- # point we may need to return 'chromium-mac' + PlatformVersion()
- return 'chromium-mac'
-
-
-def platform_version():
- """Returns the version string for the platform, e.g. '-vista' or
- '-snowleopard'. If the platform does not distinguish between
- minor versions, it returns ''."""
- 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 ''
-
-
-def get_num_cores():
- """Returns the number of cores on the machine. For hyperthreaded machines,
- this will be double the number of actual processors."""
- return int(os.popen2("sysctl -n hw.ncpu")[1].read())
-
-
-def baseline_path(platform=None):
- """Returns the path relative to the top of the source tree for the
- baselines for the specified platform version. If |platform| is None,
- then the version currently in use is used."""
- if platform is None:
- platform = platform_name()
- return path_utils.path_from_base('webkit', 'data', 'layout_tests',
- 'platform', platform, 'LayoutTests')
-
-# TODO: We should add leopard and snowleopard to the list of paths to check
-# once we start running the tests from snowleopard.
-
-
-def baseline_search_path(platform=None):
- """Returns the list of directories to search for baselines/results, in
- order of preference. Paths are relative to the top of the source tree."""
- return [baseline_path(platform),
- path_utils.webkit_baseline_path('mac' + platform_version()),
- path_utils.webkit_baseline_path('mac')]
-
-
-def wdiff_path():
- """Path to the WDiff executable, which we assume is already installed and
- in the user's $PATH."""
- return 'wdiff'
-
-
-def image_diff_path(target):
- """Path to the image_diff executable
-
- Args:
- target: build type - 'Debug','Release',etc."""
- return path_utils.path_from_base('xcodebuild', target, 'image_diff')
-
-
-def layout_test_helper_path(target):
- """Path to the layout_test_helper executable, if needed, empty otherwise
-
- Args:
- target: build type - 'Debug','Release',etc."""
- return path_utils.path_from_base('xcodebuild', target,
- 'layout_test_helper')
-
-
-def test_shell_path(target):
- """Path to the test_shell executable.
-
- Args:
- target: build type - 'Debug','Release',etc."""
- # TODO(pinkerton): make |target| happy with case-sensitive file systems.
- return path_utils.path_from_base('xcodebuild', target, 'TestShell.app',
- 'Contents', 'MacOS', 'TestShell')
-
-
-def apache_executable_path():
- """Returns the executable path to start Apache"""
- return os.path.join("/usr", "sbin", "httpd")
-
-
-def apache_config_file_path():
- """Returns the path to Apache config file"""
- return path_utils.path_from_base("third_party", "WebKit", "LayoutTests",
- "http", "conf", "apache2-httpd.conf")
-
-
-def lighttpd_executable_path():
- """Returns the executable path to start LigHTTPd"""
- return path_utils.path_from_base('third_party', 'lighttpd', 'mac',
- 'bin', 'lighttpd')
-
-
-def lighttpd_module_path():
- """Returns the library module path for LigHTTPd"""
- return path_utils.path_from_base('third_party', 'lighttpd', 'mac', 'lib')
-
-
-def lighttpd_php_path():
- """Returns the PHP executable path for LigHTTPd"""
- return path_utils.path_from_base('third_party', 'lighttpd', 'mac', 'bin',
- 'php-cgi')
-
-
-def shut_down_http_server(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.
- kill_all_process('lighttpd')
- kill_all_process('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.
- shut_down_http_server(None)
-
-
-def kill_process(pid):
- """Forcefully kill the process.
-
- Args:
- pid: The id of the process to be killed.
- """
- os.kill(pid, signal.SIGKILL)
-
-
-def kill_all_process(process_name):
- # On Mac OS X 10.6, killall has a new constraint: -SIGNALNAME or
- # -SIGNALNUMBER must come first. Example problem:
- # $ killall -u $USER -TERM lighttpd
- # killall: illegal option -- T
- # Use of the earlier -TERM placement is just fine on 10.5.
- null = open(os.devnull)
- subprocess.call(['killall', '-TERM', '-u', os.getenv('USER'),
- process_name], stderr=null)
- null.close()
-
-
-def kill_all_test_shells():
- """Kills all instances of the test_shell binary currently running."""
- kill_all_process('TestShell')
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/platform_utils_win.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/platform_utils_win.py
deleted file mode 100644
index 3e64d78..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/platform_utils_win.py
+++ /dev/null
@@ -1,210 +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 Chromium 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 the Linux implementation of the layout_package.platform_utils
- package. This file should only be imported by that package."""
-
-import os
-import path_utils
-import subprocess
-import sys
-
-
-def platform_name():
- """Returns the name of the platform we're currently running on."""
- # We're not ready for version-specific results yet. When we uncomment
- # this, we also need to add it to the BaselineSearchPath()
- return 'chromium-win' + platform_version()
-
-
-def platform_version():
- """Returns the version string for the platform, e.g. '-vista' or
- '-snowleopard'. If the platform does not distinguish between
- minor versions, it returns ''."""
- 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 ''
-
-
-def get_num_cores():
- """Returns the number of cores on the machine. For hyperthreaded machines,
- this will be double the number of actual processors."""
- return int(os.environ.get('NUMBER_OF_PROCESSORS', 1))
-
-
-def baseline_path(platform=None):
- """Returns the path relative to the top of the source tree for the
- baselines for the specified platform version. If |platform| is None,
- then the version currently in use is used."""
- if platform is None:
- platform = platform_name()
- return path_utils.path_from_base('webkit', 'data', 'layout_tests',
- 'platform', platform, 'LayoutTests')
-
-
-def baseline_search_path(platform=None):
- """Returns the list of directories to search for baselines/results, in
- order of preference. Paths are relative to the top of the source tree."""
- dirs = []
- if platform is None:
- platform = platform_name()
-
- if platform == 'chromium-win-xp':
- dirs.append(baseline_path(platform))
- if platform in ('chromium-win-xp', 'chromium-win-vista'):
- dirs.append(baseline_path('chromium-win-vista'))
- dirs.append(baseline_path('chromium-win'))
- dirs.append(path_utils.webkit_baseline_path('win'))
- dirs.append(path_utils.webkit_baseline_path('mac'))
- return dirs
-
-
-def wdiff_path():
- """Path to the WDiff executable, whose binary is checked in on Win"""
- return path_utils.path_from_base('third_party', 'cygwin', 'bin',
- 'wdiff.exe')
-
-
-def image_diff_path(target):
- """Return the platform-specific binary path for the image compare util.
- We use this if we can't find the binary in the default location
- in path_utils.
-
- Args:
- target: Build target mode (debug or release)
- """
- return _find_binary(target, 'image_diff.exe')
-
-
-def layout_test_helper_path(target):
- """Return the platform-specific binary path for the layout test helper.
- We use this if we can't find the binary in the default location
- in path_utils.
-
- Args:
- target: Build target mode (debug or release)
- """
- return _find_binary(target, 'layout_test_helper.exe')
-
-
-def test_shell_path(target):
- """Return the platform-specific binary path for our TestShell.
- We use this if we can't find the binary in the default location
- in path_utils.
-
- Args:
- target: Build target mode (debug or release)
- """
- return _find_binary(target, 'test_shell.exe')
-
-
-def apache_executable_path():
- """Returns the executable path to start Apache"""
- path = path_utils.path_from_base('third_party', 'cygwin', "usr", "sbin")
- # Don't return httpd.exe since we want to use this from cygwin.
- return os.path.join(path, "httpd")
-
-
-def apache_config_file_path():
- """Returns the path to Apache config file"""
- return path_utils.path_from_base("third_party", "WebKit", "LayoutTests",
- "http", "conf", "cygwin-httpd.conf")
-
-
-def lighttpd_executable_path():
- """Returns the executable path to start LigHTTPd"""
- return path_utils.path_from_base('third_party', 'lighttpd', 'win',
- 'LightTPD.exe')
-
-
-def lighttpd_module_path():
- """Returns the library module path for LigHTTPd"""
- return path_utils.path_from_base('third_party', 'lighttpd', 'win', 'lib')
-
-
-def lighttpd_php_path():
- """Returns the PHP executable path for LigHTTPd"""
- return path_utils.path_from_base('third_party', 'lighttpd', 'win', 'php5',
- 'php-cgi.exe')
-
-
-def shut_down_http_server(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.
- Unused in this implementation of the method.
- """
- subprocess.Popen(('taskkill.exe', '/f', '/im', 'LightTPD.exe'),
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE).wait()
- subprocess.Popen(('taskkill.exe', '/f', '/im', 'httpd.exe'),
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE).wait()
-
-
-def kill_process(pid):
- """Forcefully kill the process.
-
- Args:
- pid: The id of the process to be killed.
- """
- subprocess.call(('taskkill.exe', '/f', '/pid', str(pid)),
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
-
-
-def kill_all_test_shells(self):
- """Kills all instances of the test_shell binary currently running."""
- subprocess.Popen(('taskkill.exe', '/f', '/im', 'test_shell.exe'),
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE).wait()
-
-#
-# Private helper functions.
-#
-
-
-def _find_binary(target, binary):
- """On Windows, we look for binaries that we compile in potentially
- two places: src/webkit/$target (preferably, which we get if we
- built using webkit_glue.gyp), or src/chrome/$target (if compiled some
- other way)."""
- try:
- return path_utils.path_from_base('webkit', target, binary)
- except path_utils.PathNotFound:
- try:
- return path_utils.path_from_base('chrome', target, binary)
- except path_utils.PathNotFound:
- return path_utils.path_from_base('build', target, binary)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py
index a3be8f4..141aae7 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py
@@ -36,7 +36,7 @@ import os
import re
import sys
import time
-import path_utils
+from port import path_utils
sys.path.append(path_utils.path_from_base('third_party', 'WebKit',
'WebKitTools'))
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_files.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_files.py
index 0227e7b..581f914 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_files.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_files.py
@@ -36,7 +36,7 @@ under that directory."""
import glob
import os
-import path_utils
+from port import path_utils
# When collecting test cases, we include any file with these extensions.
_supported_file_extensions = set(['.html', '.shtml', '.xml', '.xhtml', '.pl',
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_shell_thread.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_shell_thread.py
index f9a00c1..b357620 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_shell_thread.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_shell_thread.py
@@ -46,7 +46,7 @@ import thread
import threading
import time
-import path_utils
+from port import path_utils
import test_failures
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/websocket_server.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/websocket_server.py
deleted file mode 100644
index 91e0ba9..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/websocket_server.py
+++ /dev/null
@@ -1,316 +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 Chromium 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.
-
-"""A class to help start/stop the PyWebSocket server used by layout tests."""
-
-
-import logging
-import optparse
-import os
-import subprocess
-import sys
-import tempfile
-import time
-import urllib
-
-import path_utils
-import platform_utils
-import http_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 5 times with a 1 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.
- """
- wait_time = 5
- while wait_time > 0:
- try:
- response = urllib.urlopen(url)
- # Server is up and responding.
- return True
- except IOError:
- pass
- wait_time -= 1
- # Wait a second and try again.
- time.sleep(1)
-
- return False
-
-
-def remove_log_files(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)
-
-
-class PyWebSocketNotStarted(Exception):
- pass
-
-
-class PyWebSocketNotFound(Exception):
- pass
-
-
-class PyWebSocket(http_server.Lighttpd):
-
- def __init__(self, output_dir, port=_DEFAULT_WS_PORT,
- root=None,
- use_tls=False,
- private_key=http_server.Lighttpd._pem_file,
- certificate=http_server.Lighttpd._pem_file,
- register_cygwin=None,
- pidfile=None):
- """Args:
- output_dir: the absolute path to the layout test result directory
- """
- http_server.Lighttpd.__init__(self, output_dir,
- port=port,
- root=root,
- register_cygwin=register_cygwin)
- self._output_dir = output_dir
- self._process = None
- self._port = port
- self._root = root
- self._use_tls = use_tls
- self._private_key = private_key
- self._certificate = certificate
- 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, 'websocket', 'tests'))
- else:
- try:
- self._web_socket_tests = path_utils.path_from_base(
- 'third_party', 'WebKit', 'LayoutTests', 'websocket',
- 'tests')
- self._layout_tests = path_utils.path_from_base(
- 'third_party', 'WebKit', 'LayoutTests')
- except path_utils.PathNotFound:
- self._web_socket_tests = None
-
- def start(self):
- if not self._web_socket_tests:
- logging.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.
- 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 = open(output_log, "w")
-
- python_interp = sys.executable
- pywebsocket_base = path_utils.path_from_base(
- 'third_party', 'WebKit', 'WebKitTools', 'pywebsocket')
- pywebsocket_script = path_utils.path_from_base(
- 'third_party', 'WebKit', 'WebKitTools', 'pywebsocket',
- 'mod_pywebsocket', 'standalone.py')
- start_cmd = [
- python_interp, pywebsocket_script,
- '-p', str(self._port),
- '-d', self._layout_tests,
- '-s', self._web_socket_tests,
- '-l', error_log,
- ]
-
- handler_map_file = os.path.join(self._web_socket_tests,
- 'handler_map.txt')
- if os.path.exists(handler_map_file):
- logging.debug('Using handler_map_file: %s' % handler_map_file)
- start_cmd.append('-m')
- start_cmd.append(handler_map_file)
- else:
- logging.warning('No handler_map_file found')
-
- if self._use_tls:
- start_cmd.extend(['-t', '-k', self._private_key,
- '-c', self._certificate])
-
- # Put the cygwin directory first in the path to find cygwin1.dll
- env = os.environ
- if sys.platform in ('cygwin', 'win32'):
- env['PATH'] = '%s;%s' % (
- path_utils.path_from_base('third_party', 'cygwin', 'bin'),
- env['PATH'])
-
- if sys.platform == 'win32' and self._register_cygwin:
- setup_mount = path_utils.path_from_base('third_party', 'cygwin',
- 'setup_mount.bat')
- subprocess.Popen(setup_mount).wait()
-
- env['PYTHONPATH'] = (pywebsocket_base + os.path.pathsep +
- env.get('PYTHONPATH', ''))
-
- logging.debug('Starting %s server on %d.' % (
- self._server_name, self._port))
- logging.debug('cmdline: %s' % ' '.join(start_cmd))
- self._process = subprocess.Popen(start_cmd, stdout=self._wsout,
- stderr=subprocess.STDOUT,
- env=env)
-
- # Wait a bit before checking the liveness of the server.
- time.sleep(0.5)
-
- if self._use_tls:
- url = 'https'
- else:
- url = 'http'
- url = url + '://127.0.0.1:%d/' % self._port
- if not url_is_alive(url):
- fp = open(output_log)
- try:
- for line in fp:
- logging.error(line)
- finally:
- fp.close()
- 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:
- f = open(self._pidfile, 'w')
- f.write("%d" % self._process.pid)
- f.close()
-
- def stop(self, force=False):
- if not force and not self.is_running():
- return
-
- if self._process:
- pid = self._process.pid
- elif self._pidfile:
- f = open(self._pidfile)
- pid = int(f.read().strip())
- f.close()
-
- if not pid:
- raise PyWebSocketNotFound(
- 'Failed to find %s server pid.' % self._server_name)
-
- logging.debug('Shutting down %s server %d.' % (self._server_name, pid))
- platform_utils.kill_process(pid)
-
- if self._process:
- self._process.wait()
- self._process = None
-
- if self._wsout:
- self._wsout.close()
- self._wsout = None
-
-
-if '__main__' == __name__:
- # Provide some command line params for starting the PyWebSocket server
- # manually.
- option_parser = optparse.OptionParser()
- option_parser.add_option('--server', type='choice',
- choices=['start', 'stop'], default='start',
- help='Server action (start|stop)')
- option_parser.add_option('-p', '--port', dest='port',
- default=None, help='Port to listen on')
- option_parser.add_option('-r', '--root',
- help='Absolute path to DocumentRoot '
- '(overrides layout test roots)')
- option_parser.add_option('-t', '--tls', dest='use_tls',
- action='store_true',
- default=False, help='use TLS (wss://)')
- option_parser.add_option('-k', '--private_key', dest='private_key',
- default='', help='TLS private key file.')
- option_parser.add_option('-c', '--certificate', dest='certificate',
- default='', help='TLS certificate file.')
- option_parser.add_option('--register_cygwin', action="store_true",
- dest="register_cygwin",
- help='Register Cygwin paths (on Win try bots)')
- option_parser.add_option('--pidfile', help='path to pid file.')
- options, args = option_parser.parse_args()
-
- if not options.port:
- if options.use_tls:
- options.port = _DEFAULT_WSS_PORT
- else:
- options.port = _DEFAULT_WS_PORT
-
- kwds = {'port': options.port, 'use_tls': options.use_tls}
- if options.root:
- kwds['root'] = options.root
- if options.private_key:
- kwds['private_key'] = options.private_key
- if options.certificate:
- kwds['certificate'] = options.certificate
- kwds['register_cygwin'] = options.register_cygwin
- if options.pidfile:
- kwds['pidfile'] = options.pidfile
-
- pywebsocket = PyWebSocket(tempfile.gettempdir(), **kwds)
-
- if 'start' == options.server:
- pywebsocket.start()
- else:
- pywebsocket.stop(force=True)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/__init__.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/__init__.py
new file mode 100644
index 0000000..7294f24
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/__init__.py
@@ -0,0 +1,50 @@
+#!/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 Chromium 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.
+
+"""Platform-specific utilities and pseudo-constants
+
+Any functions whose implementations or values differ from one platform to
+another should be defined in their respective <platform>.py
+modules. The appropriate one of those will be imported into this module to
+provide callers with a common, platform-independent interface.
+
+This file should only ever be imported by layout_package.path_utils.
+"""
+
+import sys
+
+# We may not support the version of Python that a user has installed (Cygwin
+# especially has had problems), but we'll allow the platform utils to be
+# included in any case so we don't get an import error.
+if sys.platform in ('cygwin', 'win32'):
+ from chromium_win import *
+elif sys.platform == 'darwin':
+ from chromium_mac import *
+elif sys.platform in ('linux', 'linux2', 'freebsd7', 'openbsd4'):
+ from chromium_linux import *
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/apache_http_server.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/apache_http_server.py
new file mode 100644
index 0000000..2b33f8e
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/apache_http_server.py
@@ -0,0 +1,229 @@
+#!/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 Chromium 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.
+
+"""A class to start/stop the apache http server used by layout tests."""
+
+import logging
+import optparse
+import os
+import re
+import subprocess
+import sys
+
+import http_server_base
+import path_utils
+import port
+
+
+class LayoutTestApacheHttpd(http_server_base.HttpServerBase):
+
+ def __init__(self, output_dir):
+ """Args:
+ output_dir: the absolute path to the layout test result directory
+ """
+ self._output_dir = output_dir
+ self._httpd_proc = None
+ path_utils.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")
+ path_utils.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 = path_utils.path_from_base('third_party', 'WebKit',
+ 'LayoutTests')
+ 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")
+
+ executable = port.apache_executable_path()
+ if self._is_cygwin():
+ executable = self._get_cygwin_path(executable)
+
+ cmd = [executable,
+ '-f', 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 = path_utils.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 = port.apache_config_file_path()
+ httpd_config_copy = os.path.join(output_dir, "httpd.conf")
+ httpd_conf = open(httpd_config).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 = path_utils.path_from_base('third_party', 'cygwin', 'usr')
+ httpd_conf = httpd_conf.replace('ServerRoot "/usr"',
+ 'ServerRoot "%s"' % self._get_cygwin_path(cygusr))
+
+ # TODO(ojan): Instead of writing an extra file, checkin a conf file
+ # upstream. Or, even better, upstream/delete all our chrome http
+ # tests so we don't need this special-cased DocumentRoot and then
+ # just use the upstream
+ # conf file.
+ chrome_document_root = path_utils.path_from_base('webkit', 'data',
+ 'layout_tests')
+ if self._is_cygwin():
+ chrome_document_root = self._get_cygwin_path(chrome_document_root)
+ httpd_conf = (httpd_conf +
+ self._get_virtual_host_config(chrome_document_root, 8081))
+
+ f = open(httpd_config_copy, 'wb')
+ f.write(httpd_conf)
+ f.close()
+
+ 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.
+ self._httpd_proc = subprocess.Popen(self._start_cmd,
+ stderr=subprocess.PIPE,
+ shell=True)
+ err = self._httpd_proc.stderr.read()
+ if len(err):
+ logging.debug(err)
+ return False
+ return True
+
+ def start(self):
+ """Starts the apache http server."""
+ # Stop any currently running servers.
+ self.stop()
+
+ logging.debug("Starting apache http server")
+ server_started = self.wait_for_action(self._start_httpd_process)
+ if server_started:
+ logging.debug("Apache started. Testing ports")
+ server_started = self.wait_for_action(
+ self.is_server_running_on_all_ports)
+
+ if server_started:
+ logging.debug("Server successfully started")
+ else:
+ raise Exception('Failed to start http server')
+
+ def stop(self):
+ """Stops the apache http server."""
+ logging.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())
+ path_utils.shut_down_http_server(httpd_pid)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_linux.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_linux.py
new file mode 100644
index 0000000..44caf94
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_linux.py
@@ -0,0 +1,248 @@
+#!/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 Chromium 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 the Linux implementation of the port
+ package. This file should only be imported by that package."""
+
+import os
+import signal
+import subprocess
+import sys
+import logging
+
+import chromium_win
+import path_utils
+
+
+def platform_name():
+ """Returns the name of the platform we're currently running on."""
+ return 'chromium-linux' + platform_version()
+
+
+def platform_version():
+ """Returns the version string for the platform, e.g. '-vista' or
+ '-snowleopard'. If the platform does not distinguish between
+ minor versions, it returns ''."""
+ return ''
+
+
+def get_num_cores():
+ """Returns the number of cores on the machine. For hyperthreaded machines,
+ this will be double the number of actual processors."""
+ num_cores = os.sysconf("SC_NPROCESSORS_ONLN")
+ if isinstance(num_cores, int) and num_cores > 0:
+ return num_cores
+ return 1
+
+
+def baseline_path(platform=None):
+ """Returns the path relative to the top of the source tree for the
+ baselines for the specified platform version. If |platform| is None,
+ then the version currently in use is used."""
+ if platform is None:
+ platform = platform_name()
+ return path_utils.path_from_base('webkit', 'data', 'layout_tests',
+ 'platform', platform, 'LayoutTests')
+
+
+def baseline_search_path(platform=None):
+ """Returns the list of directories to search for baselines/results, in
+ order of preference. Paths are relative to the top of the source tree."""
+ return [baseline_path(platform),
+ chromium_win.baseline_path('chromium-win'),
+ path_utils.webkit_baseline_path('win'),
+ path_utils.webkit_baseline_path('mac')]
+
+
+def apache_executable_path():
+ """Returns the executable path to start Apache"""
+ path = os.path.join("/usr", "sbin", "apache2")
+ if os.path.exists(path):
+ return path
+ print "Unable to fine Apache executable %s" % path
+ _missing_apache()
+
+
+def apache_config_file_path():
+ """Returns the path to Apache config file"""
+ return path_utils.path_from_base("third_party", "WebKit", "LayoutTests",
+ "http", "conf", "apache2-debian-httpd.conf")
+
+
+def lighttpd_executable_path():
+ """Returns the executable path to start LigHTTPd"""
+ binpath = "/usr/sbin/lighttpd"
+ if os.path.exists(binpath):
+ return binpath
+ print "Unable to find LigHTTPd executable %s" % binpath
+ _missing_lighttpd()
+
+
+def lighttpd_module_path():
+ """Returns the library module path for LigHTTPd"""
+ modpath = "/usr/lib/lighttpd"
+ if os.path.exists(modpath):
+ return modpath
+ print "Unable to find LigHTTPd modules %s" % modpath
+ _missing_lighttpd()
+
+
+def lighttpd_php_path():
+ """Returns the PHP executable path for LigHTTPd"""
+ binpath = "/usr/bin/php-cgi"
+ if os.path.exists(binpath):
+ return binpath
+ print "Unable to find PHP CGI executable %s" % binpath
+ _missing_lighttpd()
+
+
+def wdiff_path():
+ """Path to the WDiff executable, which we assume is already installed and
+ in the user's $PATH."""
+ return 'wdiff'
+
+
+def image_diff_path(target):
+ """Path to the image_diff binary.
+
+ Args:
+ target: Build target mode (debug or release)"""
+ return _path_from_build_results(target, 'image_diff')
+
+
+def layout_test_helper_path(target):
+ """Path to the layout_test helper binary, if needed, empty otherwise"""
+ return ''
+
+
+def test_shell_path(target):
+ """Return the platform-specific binary path for our TestShell.
+
+ Args:
+ target: Build target mode (debug or release) """
+ if target in ('Debug', 'Release'):
+ try:
+ debug_path = _path_from_build_results('Debug', 'test_shell')
+ release_path = _path_from_build_results('Release', 'test_shell')
+
+ debug_mtime = os.stat(debug_path).st_mtime
+ release_mtime = os.stat(release_path).st_mtime
+
+ if debug_mtime > release_mtime and target == 'Release' or \
+ release_mtime > debug_mtime and target == 'Debug':
+ logging.info('\x1b[31mWarning: you are not running the most '
+ 'recent test_shell binary. You need to pass '
+ '--debug or not to select between Debug and '
+ 'Release.\x1b[0m')
+ # 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 path_utils.PathNotFound:
+ pass
+
+ return _path_from_build_results(target, 'test_shell')
+
+
+def fuzzy_match_path():
+ """Return the path to the fuzzy matcher binary."""
+ return path_utils.path_from_base('third_party', 'fuzzymatch', 'fuzzymatch')
+
+
+def shut_down_http_server(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:
+ # This isn't ideal, since it could conflict with web server processes
+ # not started by http_server.py, but good enough for now.
+ kill_all_process('lighttpd')
+ kill_all_process('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.
+ shut_down_http_server(None)
+
+
+def kill_process(pid):
+ """Forcefully kill the process.
+
+ Args:
+ pid: The id of the process to be killed.
+ """
+ os.kill(pid, signal.SIGKILL)
+
+
+def kill_all_process(process_name):
+ null = open(os.devnull)
+ subprocess.call(['killall', '-TERM', '-u', os.getenv('USER'),
+ process_name], stderr=null)
+ null.close()
+
+
+def kill_all_test_shells():
+ """Kills all instances of the test_shell binary currently running."""
+ kill_all_process('test_shell')
+
+#
+# Private helper functions
+#
+
+
+def _missing_lighttpd():
+ print 'Please install using: "sudo apt-get install lighttpd php5-cgi"'
+ print 'For complete Linux build requirements, please see:'
+ print 'http://code.google.com/p/chromium/wiki/LinuxBuildInstructions'
+ sys.exit(1)
+
+
+def _missing_apache():
+ print ('Please install using: "sudo apt-get install apache2 '
+ 'libapache2-mod-php5"')
+ print 'For complete Linux build requirements, please see:'
+ print 'http://code.google.com/p/chromium/wiki/LinuxBuildInstructions'
+ sys.exit(1)
+
+
+def _path_from_build_results(*pathies):
+ # FIXME(dkegel): use latest or warn if more than one found?
+ for dir in ["sconsbuild", "out", "xcodebuild"]:
+ try:
+ return path_utils.path_from_base(dir, *pathies)
+ except:
+ pass
+ raise path_utils.PathNotFound("Unable to find %s in build tree" %
+ (os.path.join(*pathies)))
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac.py
new file mode 100644
index 0000000..827efd8
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac.py
@@ -0,0 +1,201 @@
+#!/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 Chromium 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 the Mac implementation of the port interface
+ package. This file should only be imported by that package."""
+
+import os
+import platform
+import signal
+import subprocess
+
+import path_utils
+
+
+def platform_name():
+ """Returns the name of the platform we're currently running on."""
+ # At the moment all chromium mac results are version-independent. At some
+ # point we may need to return 'chromium-mac' + PlatformVersion()
+ return 'chromium-mac'
+
+
+def platform_version():
+ """Returns the version string for the platform, e.g. '-vista' or
+ '-snowleopard'. If the platform does not distinguish between
+ minor versions, it returns ''."""
+ 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 ''
+
+
+def get_num_cores():
+ """Returns the number of cores on the machine. For hyperthreaded machines,
+ this will be double the number of actual processors."""
+ return int(os.popen2("sysctl -n hw.ncpu")[1].read())
+
+
+def baseline_path(platform=None):
+ """Returns the path relative to the top of the source tree for the
+ baselines for the specified platform version. If |platform| is None,
+ then the version currently in use is used."""
+ if platform is None:
+ platform = platform_name()
+ return path_utils.path_from_base('webkit', 'data', 'layout_tests',
+ 'platform', platform, 'LayoutTests')
+
+# TODO: We should add leopard and snowleopard to the list of paths to check
+# once we start running the tests from snowleopard.
+
+
+def baseline_search_path(platform=None):
+ """Returns the list of directories to search for baselines/results, in
+ order of preference. Paths are relative to the top of the source tree."""
+ return [baseline_path(platform),
+ path_utils.webkit_baseline_path('mac' + platform_version()),
+ path_utils.webkit_baseline_path('mac')]
+
+
+def wdiff_path():
+ """Path to the WDiff executable, which we assume is already installed and
+ in the user's $PATH."""
+ return 'wdiff'
+
+
+def image_diff_path(target):
+ """Path to the image_diff executable
+
+ Args:
+ target: build type - 'Debug','Release',etc."""
+ return path_utils.path_from_base('xcodebuild', target, 'image_diff')
+
+
+def layout_test_helper_path(target):
+ """Path to the layout_test_helper executable, if needed, empty otherwise
+
+ Args:
+ target: build type - 'Debug','Release',etc."""
+ return path_utils.path_from_base('xcodebuild', target,
+ 'layout_test_helper')
+
+
+def test_shell_path(target):
+ """Path to the test_shell executable.
+
+ Args:
+ target: build type - 'Debug','Release',etc."""
+ # TODO(pinkerton): make |target| happy with case-sensitive file systems.
+ return path_utils.path_from_base('xcodebuild', target, 'TestShell.app',
+ 'Contents', 'MacOS', 'TestShell')
+
+
+def apache_executable_path():
+ """Returns the executable path to start Apache"""
+ return os.path.join("/usr", "sbin", "httpd")
+
+
+def apache_config_file_path():
+ """Returns the path to Apache config file"""
+ return path_utils.path_from_base("third_party", "WebKit", "LayoutTests",
+ "http", "conf", "apache2-httpd.conf")
+
+
+def lighttpd_executable_path():
+ """Returns the executable path to start LigHTTPd"""
+ return path_utils.path_from_base('third_party', 'lighttpd', 'mac',
+ 'bin', 'lighttpd')
+
+
+def lighttpd_module_path():
+ """Returns the library module path for LigHTTPd"""
+ return path_utils.path_from_base('third_party', 'lighttpd', 'mac', 'lib')
+
+
+def lighttpd_php_path():
+ """Returns the PHP executable path for LigHTTPd"""
+ return path_utils.path_from_base('third_party', 'lighttpd', 'mac', 'bin',
+ 'php-cgi')
+
+
+def shut_down_http_server(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.
+ kill_all_process('lighttpd')
+ kill_all_process('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.
+ shut_down_http_server(None)
+
+
+def kill_process(pid):
+ """Forcefully kill the process.
+
+ Args:
+ pid: The id of the process to be killed.
+ """
+ os.kill(pid, signal.SIGKILL)
+
+
+def kill_all_process(process_name):
+ # On Mac OS X 10.6, killall has a new constraint: -SIGNALNAME or
+ # -SIGNALNUMBER must come first. Example problem:
+ # $ killall -u $USER -TERM lighttpd
+ # killall: illegal option -- T
+ # Use of the earlier -TERM placement is just fine on 10.5.
+ null = open(os.devnull)
+ subprocess.call(['killall', '-TERM', '-u', os.getenv('USER'),
+ process_name], stderr=null)
+ null.close()
+
+
+def kill_all_test_shells():
+ """Kills all instances of the test_shell binary currently running."""
+ kill_all_process('TestShell')
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py
new file mode 100644
index 0000000..a1a1548
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py
@@ -0,0 +1,210 @@
+#!/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 Chromium 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 the Linux implementation of the port
+ package. This file should only be imported by that package."""
+
+import os
+import subprocess
+import sys
+
+import path_utils
+
+def platform_name():
+ """Returns the name of the platform we're currently running on."""
+ # We're not ready for version-specific results yet. When we uncomment
+ # this, we also need to add it to the BaselineSearchPath()
+ return 'chromium-win' + platform_version()
+
+
+def platform_version():
+ """Returns the version string for the platform, e.g. '-vista' or
+ '-snowleopard'. If the platform does not distinguish between
+ minor versions, it returns ''."""
+ 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 ''
+
+
+def get_num_cores():
+ """Returns the number of cores on the machine. For hyperthreaded machines,
+ this will be double the number of actual processors."""
+ return int(os.environ.get('NUMBER_OF_PROCESSORS', 1))
+
+
+def baseline_path(platform=None):
+ """Returns the path relative to the top of the source tree for the
+ baselines for the specified platform version. If |platform| is None,
+ then the version currently in use is used."""
+ if platform is None:
+ platform = platform_name()
+ return path_utils.path_from_base('webkit', 'data', 'layout_tests',
+ 'platform', platform, 'LayoutTests')
+
+
+def baseline_search_path(platform=None):
+ """Returns the list of directories to search for baselines/results, in
+ order of preference. Paths are relative to the top of the source tree."""
+ dirs = []
+ if platform is None:
+ platform = platform_name()
+
+ if platform == 'chromium-win-xp':
+ dirs.append(baseline_path(platform))
+ if platform in ('chromium-win-xp', 'chromium-win-vista'):
+ dirs.append(baseline_path('chromium-win-vista'))
+ dirs.append(baseline_path('chromium-win'))
+ dirs.append(path_utils.webkit_baseline_path('win'))
+ dirs.append(path_utils.webkit_baseline_path('mac'))
+ return dirs
+
+
+def wdiff_path():
+ """Path to the WDiff executable, whose binary is checked in on Win"""
+ return path_utils.path_from_base('third_party', 'cygwin', 'bin',
+ 'wdiff.exe')
+
+
+def image_diff_path(target):
+ """Return the platform-specific binary path for the image compare util.
+ We use this if we can't find the binary in the default location
+ in path_utils.
+
+ Args:
+ target: Build target mode (debug or release)
+ """
+ return _find_binary(target, 'image_diff.exe')
+
+
+def layout_test_helper_path(target):
+ """Return the platform-specific binary path for the layout test helper.
+ We use this if we can't find the binary in the default location
+ in path_utils.
+
+ Args:
+ target: Build target mode (debug or release)
+ """
+ return _find_binary(target, 'layout_test_helper.exe')
+
+
+def test_shell_path(target):
+ """Return the platform-specific binary path for our TestShell.
+ We use this if we can't find the binary in the default location
+ in path_utils.
+
+ Args:
+ target: Build target mode (debug or release)
+ """
+ return _find_binary(target, 'test_shell.exe')
+
+
+def apache_executable_path():
+ """Returns the executable path to start Apache"""
+ path = path_utils.path_from_base('third_party', 'cygwin', "usr", "sbin")
+ # Don't return httpd.exe since we want to use this from cygwin.
+ return os.path.join(path, "httpd")
+
+
+def apache_config_file_path():
+ """Returns the path to Apache config file"""
+ return path_utils.path_from_base("third_party", "WebKit", "LayoutTests",
+ "http", "conf", "cygwin-httpd.conf")
+
+
+def lighttpd_executable_path():
+ """Returns the executable path to start LigHTTPd"""
+ return path_utils.path_from_base('third_party', 'lighttpd', 'win',
+ 'LightTPD.exe')
+
+
+def lighttpd_module_path():
+ """Returns the library module path for LigHTTPd"""
+ return path_utils.path_from_base('third_party', 'lighttpd', 'win', 'lib')
+
+
+def lighttpd_php_path():
+ """Returns the PHP executable path for LigHTTPd"""
+ return path_utils.path_from_base('third_party', 'lighttpd', 'win', 'php5',
+ 'php-cgi.exe')
+
+
+def shut_down_http_server(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.
+ Unused in this implementation of the method.
+ """
+ subprocess.Popen(('taskkill.exe', '/f', '/im', 'LightTPD.exe'),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE).wait()
+ subprocess.Popen(('taskkill.exe', '/f', '/im', 'httpd.exe'),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE).wait()
+
+
+def kill_process(pid):
+ """Forcefully kill the process.
+
+ Args:
+ pid: The id of the process to be killed.
+ """
+ subprocess.call(('taskkill.exe', '/f', '/pid', str(pid)),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+
+
+def kill_all_test_shells(self):
+ """Kills all instances of the test_shell binary currently running."""
+ subprocess.Popen(('taskkill.exe', '/f', '/im', 'test_shell.exe'),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE).wait()
+
+#
+# Private helper functions.
+#
+
+
+def _find_binary(target, binary):
+ """On Windows, we look for binaries that we compile in potentially
+ two places: src/webkit/$target (preferably, which we get if we
+ built using webkit_glue.gyp), or src/chrome/$target (if compiled some
+ other way)."""
+ try:
+ return path_utils.path_from_base('webkit', target, binary)
+ except path_utils.PathNotFound:
+ try:
+ return path_utils.path_from_base('chrome', target, binary)
+ except path_utils.PathNotFound:
+ return path_utils.path_from_base('build', target, binary)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/http_server.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/http_server.py
similarity index 100%
rename from WebKitTools/Scripts/webkitpy/layout_tests/layout_package/http_server.py
rename to WebKitTools/Scripts/webkitpy/layout_tests/port/http_server.py
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/http_server_base.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/http_server_base.py
similarity index 100%
rename from WebKitTools/Scripts/webkitpy/layout_tests/layout_package/http_server_base.py
rename to WebKitTools/Scripts/webkitpy/layout_tests/port/http_server_base.py
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/httpd2.pem b/WebKitTools/Scripts/webkitpy/layout_tests/port/httpd2.pem
similarity index 100%
rename from WebKitTools/Scripts/webkitpy/layout_tests/layout_package/httpd2.pem
rename to WebKitTools/Scripts/webkitpy/layout_tests/port/httpd2.pem
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/lighttpd.conf b/WebKitTools/Scripts/webkitpy/layout_tests/port/lighttpd.conf
similarity index 100%
rename from WebKitTools/Scripts/webkitpy/layout_tests/layout_package/lighttpd.conf
rename to WebKitTools/Scripts/webkitpy/layout_tests/port/lighttpd.conf
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/path_utils.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/path_utils.py
new file mode 100644
index 0000000..91b1b62
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/path_utils.py
@@ -0,0 +1,395 @@
+#!/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 Chromium 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 package contains utility methods for manipulating paths and
+filenames for test results and baselines. It also contains wrappers
+of a few routines in port/ so that the port package can
+be considered a 'protected' package - i.e., this file should be
+the only file that ever includes port. This leads to
+us including a few things that don't really have anything to do
+ with paths, unfortunately."""
+
+import errno
+import os
+import stat
+import sys
+
+import port
+import chromium_win
+import chromium_mac
+import chromium_linux
+
+# Cache some values so we don't have to recalculate them. _basedir is
+# used by PathFromBase() and caches the full (native) path to the top
+# of the source tree (/src). _baseline_search_path is used by
+# ExpectedBaselines() and caches the list of native paths to search
+# for baseline results.
+_basedir = None
+_baseline_search_path = None
+
+
+class PathNotFound(Exception):
+ pass
+
+
+def layout_tests_dir():
+ """Returns the fully-qualified path to the directory containing the input
+ data for the specified layout test."""
+ return path_from_base('third_party', 'WebKit', 'LayoutTests')
+
+
+def chromium_baseline_path(platform=None):
+ """Returns the full path to the directory containing expected
+ baseline results from chromium ports. If |platform| is None, the
+ currently executing platform is used.
+
+ Note: although directly referencing individual port/* files is
+ usually discouraged, we allow it here so that the rebaselining tool can
+ pull baselines for platforms other than the host platform."""
+
+ # Normalize the platform string.
+ platform = platform_name(platform)
+ if platform.startswith('chromium-mac'):
+ return chromium_mac.baseline_path(platform)
+ elif platform.startswith('chromium-win'):
+ return chromium_win.baseline_path(platform)
+ elif platform.startswith('chromium-linux'):
+ return chromium_linux.baseline_path(platform)
+
+ return port.baseline_path()
+
+
+def webkit_baseline_path(platform):
+ """Returns the full path to the directory containing expected
+ baseline results from WebKit ports."""
+ return path_from_base('third_party', 'WebKit', 'LayoutTests',
+ 'platform', platform)
+
+
+def baseline_search_path(platform=None):
+ """Returns the list of directories to search for baselines/results for a
+ given platform, in order of preference. Paths are relative to the top of
+ the source tree. If parameter platform is None, returns the list for the
+ current platform that the script is running on.
+
+ Note: although directly referencing individual port/* files is
+ usually discouraged, we allow it here so that the rebaselining tool can
+ pull baselines for platforms other than the host platform."""
+
+ # Normalize the platform name.
+ platform = platform_name(platform)
+ if platform.startswith('chromium-mac'):
+ return chromium_mac.baseline_search_path(platform)
+ elif platform.startswith('chromium-win'):
+ return chromium_win.baseline_search_path(platform)
+ elif platform.startswith('chromium-linux'):
+ return chromium_linux.baseline_search_path(platform)
+ return port.baseline_search_path()
+
+
+def expected_baselines(filename, suffix, platform=None, 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.
+ platform: layout test platform: 'win', 'linux' or 'mac'. Defaults to
+ the current platform.
+ 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.
+ """
+ global _baseline_search_path
+ global _search_path_platform
+ testname = os.path.splitext(relative_test_filename(filename))[0]
+
+ baseline_filename = testname + '-expected' + suffix
+
+ if (_baseline_search_path is None) or (_search_path_platform != platform):
+ _baseline_search_path = baseline_search_path(platform)
+ _search_path_platform = platform
+
+ baselines = []
+ for platform_dir in _baseline_search_path:
+ if os.path.exists(os.path.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 = layout_tests_dir()
+ if os.path.exists(os.path.join(platform_dir, baseline_filename)):
+ baselines.append((platform_dir, baseline_filename))
+
+ if baselines:
+ return baselines
+
+ return [(None, baseline_filename)]
+
+
+def expected_filename(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)
+ """
+ platform_dir, baseline_filename = expected_baselines(filename, suffix)[0]
+ if platform_dir:
+ return os.path.join(platform_dir, baseline_filename)
+ return os.path.join(layout_tests_dir(), baseline_filename)
+
+
+def relative_test_filename(filename):
+ """Provide the filename of the test relative to the layout tests
+ directory as a unix style path (a/b/c)."""
+ return _win_path_to_unix(filename[len(layout_tests_dir()) + 1:])
+
+
+def _win_path_to_unix(path):
+ """Convert a windows path to use unix-style path separators (a/b/c)."""
+ return path.replace('\\', '/')
+
+#
+# Routines that are arguably platform-specific but have been made
+# generic for now
+#
+
+
+def filename_to_uri(full_path):
+ """Convert a test file to a URI."""
+ LAYOUTTEST_HTTP_DIR = "http/tests/"
+ LAYOUTTEST_WEBSOCKET_DIR = "websocket/tests/"
+
+ relative_path = _win_path_to_unix(relative_test_filename(full_path))
+ port = None
+ use_ssl = False
+
+ if relative_path.startswith(LAYOUTTEST_HTTP_DIR):
+ # http/tests/ run off port 8000 and ssl/ off 8443
+ relative_path = relative_path[len(LAYOUTTEST_HTTP_DIR):]
+ port = 8000
+ elif relative_path.startswith(LAYOUTTEST_WEBSOCKET_DIR):
+ # websocket/tests/ run off port 8880 and 9323
+ # Note: the root is /, not websocket/tests/
+ port = 8880
+
+ # Make http/tests/local run as local files. This is to mimic the
+ # logic in run-webkit-tests.
+ # TODO(jianli): Consider extending this to "media/".
+ if port and not relative_path.startswith("local/"):
+ if relative_path.startswith("ssl/"):
+ port += 443
+ protocol = "https"
+ else:
+ protocol = "http"
+ return "%s://127.0.0.1:%u/%s" % (protocol, port, relative_path)
+
+ if sys.platform in ('cygwin', 'win32'):
+ return "file:///" + get_absolute_path(full_path)
+ return "file://" + get_absolute_path(full_path)
+
+
+def get_absolute_path(path):
+ """Returns an absolute UNIX path."""
+ return _win_path_to_unix(os.path.abspath(path))
+
+
+def maybe_make_directory(*path):
+ """Creates the specified directory if it doesn't already exist."""
+ try:
+ os.makedirs(os.path.join(*path))
+ except OSError, e:
+ if e.errno != errno.EEXIST:
+ raise
+
+
+def path_from_base(*comps):
+ """Returns an absolute filename from a set of components specified
+ relative to the top of the source tree. If the path does not exist,
+ the exception PathNotFound is raised."""
+ global _basedir
+ if _basedir == None:
+ # We compute the top of the source tree by finding the absolute
+ # path of this source file, and then climbing up three directories
+ # as given in subpath. If we move this file, subpath needs to be
+ # updated.
+ path = os.path.abspath(__file__)
+ subpath = os.path.join('third_party', 'WebKit')
+ _basedir = path[:path.index(subpath)]
+ path = os.path.join(_basedir, *comps)
+ if not os.path.exists(path):
+ raise PathNotFound('could not find %s' % (path))
+ return path
+
+
+def remove_directory(*path):
+ """Recursively removes a directory, even if it's marked read-only.
+
+ Remove the directory located at *path, if it exists.
+
+ shutil.rmtree() doesn't work on Windows if any of the files or directories
+ are read-only, which svn repositories and some .svn files are. We need to
+ be able to force the files to be writable (i.e., deletable) as we traverse
+ the tree.
+
+ Even with all this, Windows still sometimes fails to delete a file, citing
+ a permission error (maybe something to do with antivirus scans or disk
+ indexing). The best suggestion any of the user forums had was to wait a
+ bit and try again, so we do that too. It's hand-waving, but sometimes it
+ works. :/
+ """
+ file_path = os.path.join(*path)
+ if not os.path.exists(file_path):
+ return
+
+ win32 = False
+ if sys.platform == 'win32':
+ win32 = True
+ # Some people don't have the APIs installed. In that case we'll do
+ # without.
+ try:
+ win32api = __import__('win32api')
+ win32con = __import__('win32con')
+ except ImportError:
+ win32 = False
+
+ def remove_with_retry(rmfunc, path):
+ os.chmod(path, stat.S_IWRITE)
+ if win32:
+ win32api.SetFileAttributes(path,
+ win32con.FILE_ATTRIBUTE_NORMAL)
+ try:
+ return rmfunc(path)
+ except EnvironmentError, e:
+ if e.errno != errno.EACCES:
+ raise
+ print 'Failed to delete %s: trying again' % repr(path)
+ time.sleep(0.1)
+ return rmfunc(path)
+ else:
+
+ def remove_with_retry(rmfunc, path):
+ if os.path.islink(path):
+ return os.remove(path)
+ else:
+ return rmfunc(path)
+
+ for root, dirs, files in os.walk(file_path, topdown=False):
+ # For POSIX: making the directory writable guarantees removability.
+ # Windows will ignore the non-read-only bits in the chmod value.
+ os.chmod(root, 0770)
+ for name in files:
+ remove_with_retry(os.remove, os.path.join(root, name))
+ for name in dirs:
+ remove_with_retry(os.rmdir, os.path.join(root, name))
+
+ remove_with_retry(os.rmdir, file_path)
+
+#
+# Wrappers around port/
+#
+
+
+def platform_name(platform=None):
+ """Returns the appropriate chromium platform name for |platform|. If
+ |platform| is None, returns the name of the chromium platform on the
+ currently running system. If |platform| is of the form 'chromium-*',
+ it is returned unchanged, otherwise 'chromium-' is prepended."""
+ if platform == None:
+ return port.platform_name()
+ if not platform.startswith('chromium-'):
+ platform = "chromium-" + platform
+ return platform
+
+
+def platform_version():
+ return port.platform_version()
+
+
+def lighttpd_executable_path():
+ return port.lighttpd_executable_path()
+
+
+def lighttpd_module_path():
+ return port.lighttpd_module_path()
+
+
+def lighttpd_php_path():
+ return port.lighttpd_php_path()
+
+
+def wdiff_path():
+ return port.wdiff_path()
+
+
+def test_shell_path(target):
+ return port.test_shell_path(target)
+
+
+def image_diff_path(target):
+ return port.image_diff_path(target)
+
+
+def layout_test_helper_path(target):
+ return port.layout_test_helper_path(target)
+
+
+def fuzzy_match_path():
+ return port.fuzzy_match_path()
+
+
+def shut_down_http_server(server_pid):
+ return port.shut_down_http_server(server_pid)
+
+
+def kill_all_test_shells():
+ port.kill_all_test_shells()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/websocket_server.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/websocket_server.py
new file mode 100644
index 0000000..5fc7e6f
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/websocket_server.py
@@ -0,0 +1,316 @@
+#!/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 Chromium 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.
+
+"""A class to help start/stop the PyWebSocket server used by layout tests."""
+
+
+import logging
+import optparse
+import os
+import subprocess
+import sys
+import tempfile
+import time
+import urllib
+
+import path_utils
+import port
+import http_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 5 times with a 1 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.
+ """
+ wait_time = 5
+ while wait_time > 0:
+ try:
+ response = urllib.urlopen(url)
+ # Server is up and responding.
+ return True
+ except IOError:
+ pass
+ wait_time -= 1
+ # Wait a second and try again.
+ time.sleep(1)
+
+ return False
+
+
+def remove_log_files(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)
+
+
+class PyWebSocketNotStarted(Exception):
+ pass
+
+
+class PyWebSocketNotFound(Exception):
+ pass
+
+
+class PyWebSocket(http_server.Lighttpd):
+
+ def __init__(self, output_dir, port=_DEFAULT_WS_PORT,
+ root=None,
+ use_tls=False,
+ private_key=http_server.Lighttpd._pem_file,
+ certificate=http_server.Lighttpd._pem_file,
+ register_cygwin=None,
+ pidfile=None):
+ """Args:
+ output_dir: the absolute path to the layout test result directory
+ """
+ http_server.Lighttpd.__init__(self, output_dir,
+ port=port,
+ root=root,
+ register_cygwin=register_cygwin)
+ self._output_dir = output_dir
+ self._process = None
+ self._port = port
+ self._root = root
+ self._use_tls = use_tls
+ self._private_key = private_key
+ self._certificate = certificate
+ 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, 'websocket', 'tests'))
+ else:
+ try:
+ self._web_socket_tests = path_utils.path_from_base(
+ 'third_party', 'WebKit', 'LayoutTests', 'websocket',
+ 'tests')
+ self._layout_tests = path_utils.path_from_base(
+ 'third_party', 'WebKit', 'LayoutTests')
+ except path_utils.PathNotFound:
+ self._web_socket_tests = None
+
+ def start(self):
+ if not self._web_socket_tests:
+ logging.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.
+ 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 = open(output_log, "w")
+
+ python_interp = sys.executable
+ pywebsocket_base = path_utils.path_from_base(
+ 'third_party', 'WebKit', 'WebKitTools', 'pywebsocket')
+ pywebsocket_script = path_utils.path_from_base(
+ 'third_party', 'WebKit', 'WebKitTools', 'pywebsocket',
+ 'mod_pywebsocket', 'standalone.py')
+ start_cmd = [
+ python_interp, pywebsocket_script,
+ '-p', str(self._port),
+ '-d', self._layout_tests,
+ '-s', self._web_socket_tests,
+ '-l', error_log,
+ ]
+
+ handler_map_file = os.path.join(self._web_socket_tests,
+ 'handler_map.txt')
+ if os.path.exists(handler_map_file):
+ logging.debug('Using handler_map_file: %s' % handler_map_file)
+ start_cmd.append('-m')
+ start_cmd.append(handler_map_file)
+ else:
+ logging.warning('No handler_map_file found')
+
+ if self._use_tls:
+ start_cmd.extend(['-t', '-k', self._private_key,
+ '-c', self._certificate])
+
+ # Put the cygwin directory first in the path to find cygwin1.dll
+ env = os.environ
+ if sys.platform in ('cygwin', 'win32'):
+ env['PATH'] = '%s;%s' % (
+ path_utils.path_from_base('third_party', 'cygwin', 'bin'),
+ env['PATH'])
+
+ if sys.platform == 'win32' and self._register_cygwin:
+ setup_mount = path_utils.path_from_base('third_party', 'cygwin',
+ 'setup_mount.bat')
+ subprocess.Popen(setup_mount).wait()
+
+ env['PYTHONPATH'] = (pywebsocket_base + os.path.pathsep +
+ env.get('PYTHONPATH', ''))
+
+ logging.debug('Starting %s server on %d.' % (
+ self._server_name, self._port))
+ logging.debug('cmdline: %s' % ' '.join(start_cmd))
+ self._process = subprocess.Popen(start_cmd, stdout=self._wsout,
+ stderr=subprocess.STDOUT,
+ env=env)
+
+ # Wait a bit before checking the liveness of the server.
+ time.sleep(0.5)
+
+ if self._use_tls:
+ url = 'https'
+ else:
+ url = 'http'
+ url = url + '://127.0.0.1:%d/' % self._port
+ if not url_is_alive(url):
+ fp = open(output_log)
+ try:
+ for line in fp:
+ logging.error(line)
+ finally:
+ fp.close()
+ 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:
+ f = open(self._pidfile, 'w')
+ f.write("%d" % self._process.pid)
+ f.close()
+
+ def stop(self, force=False):
+ if not force and not self.is_running():
+ return
+
+ if self._process:
+ pid = self._process.pid
+ elif self._pidfile:
+ f = open(self._pidfile)
+ pid = int(f.read().strip())
+ f.close()
+
+ if not pid:
+ raise PyWebSocketNotFound(
+ 'Failed to find %s server pid.' % self._server_name)
+
+ logging.debug('Shutting down %s server %d.' % (self._server_name, pid))
+ port.kill_process(pid)
+
+ if self._process:
+ self._process.wait()
+ self._process = None
+
+ if self._wsout:
+ self._wsout.close()
+ self._wsout = None
+
+
+if '__main__' == __name__:
+ # Provide some command line params for starting the PyWebSocket server
+ # manually.
+ option_parser = optparse.OptionParser()
+ option_parser.add_option('--server', type='choice',
+ choices=['start', 'stop'], default='start',
+ help='Server action (start|stop)')
+ option_parser.add_option('-p', '--port', dest='port',
+ default=None, help='Port to listen on')
+ option_parser.add_option('-r', '--root',
+ help='Absolute path to DocumentRoot '
+ '(overrides layout test roots)')
+ option_parser.add_option('-t', '--tls', dest='use_tls',
+ action='store_true',
+ default=False, help='use TLS (wss://)')
+ option_parser.add_option('-k', '--private_key', dest='private_key',
+ default='', help='TLS private key file.')
+ option_parser.add_option('-c', '--certificate', dest='certificate',
+ default='', help='TLS certificate file.')
+ option_parser.add_option('--register_cygwin', action="store_true",
+ dest="register_cygwin",
+ help='Register Cygwin paths (on Win try bots)')
+ option_parser.add_option('--pidfile', help='path to pid file.')
+ options, args = option_parser.parse_args()
+
+ if not options.port:
+ if options.use_tls:
+ options.port = _DEFAULT_WSS_PORT
+ else:
+ options.port = _DEFAULT_WS_PORT
+
+ kwds = {'port': options.port, 'use_tls': options.use_tls}
+ if options.root:
+ kwds['root'] = options.root
+ if options.private_key:
+ kwds['private_key'] = options.private_key
+ if options.certificate:
+ kwds['certificate'] = options.certificate
+ kwds['register_cygwin'] = options.register_cygwin
+ if options.pidfile:
+ kwds['pidfile'] = options.pidfile
+
+ pywebsocket = PyWebSocket(tempfile.gettempdir(), **kwds)
+
+ if 'start' == options.server:
+ pywebsocket.start()
+ else:
+ pywebsocket.stop(force=True)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py b/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py
index 5b9f1e8..95303c8 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py
@@ -54,7 +54,7 @@ import urllib
import webbrowser
import zipfile
-from layout_package import path_utils
+from port import path_utils
from layout_package import test_expectations
from test_types import image_diff
from test_types import text_diff
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/run_chromium_webkit_tests.py b/WebKitTools/Scripts/webkitpy/layout_tests/run_chromium_webkit_tests.py
index 4173191..58037fb 100755
--- a/WebKitTools/Scripts/webkitpy/layout_tests/run_chromium_webkit_tests.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/run_chromium_webkit_tests.py
@@ -59,17 +59,19 @@ import sys
import time
import traceback
-from layout_package import apache_http_server
from layout_package import test_expectations
-from layout_package import http_server
from layout_package import json_layout_results_generator
from layout_package import metered_stream
-from layout_package import path_utils
-from layout_package import platform_utils
from layout_package import test_failures
from layout_package import test_shell_thread
from layout_package import test_files
-from layout_package import websocket_server
+
+import port
+from port import apache_http_server
+from port import http_server
+from port import path_utils
+from port import websocket_server
+
from test_types import fuzzy_image_diff
from test_types import image_diff
from test_types import test_type_base
@@ -1469,7 +1471,7 @@ def main(options, args):
if not options.num_test_shells:
# TODO(ojan): Investigate perf/flakiness impact of using numcores + 1.
- options.num_test_shells = platform_utils.get_num_cores()
+ options.num_test_shells = port.get_num_cores()
write = create_logging_writer(options, 'config')
write("Running %s test_shells in parallel" % options.num_test_shells)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/fuzzy_image_diff.py b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/fuzzy_image_diff.py
index 938366d..77ce01d 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/fuzzy_image_diff.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/fuzzy_image_diff.py
@@ -37,7 +37,7 @@ import os
import shutil
import subprocess
-from layout_package import path_utils
+from port import path_utils
from layout_package import test_failures
from test_types import test_type_base
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py
index 2576f7a..1b44b40 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py
@@ -40,7 +40,7 @@ import os
import shutil
import subprocess
-from layout_package import path_utils
+from port import path_utils
from layout_package import test_failures
from test_types import test_type_base
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py
index 2aa8a2d..d412a0b 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py
@@ -39,7 +39,7 @@ import logging
import os.path
import subprocess
-from layout_package import path_utils
+from port import path_utils
class TestArguments(object):
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py
index 1aa4253..8ef7745 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py
@@ -37,7 +37,7 @@ import errno
import logging
import os.path
-from layout_package import path_utils
+from port import path_utils
from layout_package import test_failures
from test_types import test_type_base
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list