summaryrefslogtreecommitdiffstats
path: root/Tools/Scripts/webkitpy/layout_tests/port/base.py
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/Scripts/webkitpy/layout_tests/port/base.py')
-rw-r--r--Tools/Scripts/webkitpy/layout_tests/port/base.py175
1 files changed, 148 insertions, 27 deletions
diff --git a/Tools/Scripts/webkitpy/layout_tests/port/base.py b/Tools/Scripts/webkitpy/layout_tests/port/base.py
index 6e5fabc..5ff4bff 100644
--- a/Tools/Scripts/webkitpy/layout_tests/port/base.py
+++ b/Tools/Scripts/webkitpy/layout_tests/port/base.py
@@ -121,15 +121,18 @@ class Port(object):
# certainly won't be available, so it's a good test to keep us
# from erroring out later.
self._pretty_patch_available = self._filesystem.exists(self._pretty_patch_path)
- self.set_option_default('configuration', None)
- if self._options.configuration is None:
+ if not hasattr(self._options, 'configuration') or self._options.configuration is None:
self._options.configuration = self.default_configuration()
+ self._test_configuration = None
def default_child_processes(self):
"""Return the number of DumpRenderTree instances to use for this
port."""
return self._executive.cpu_count()
+ def default_worker_model(self):
+ return 'old-threads'
+
def baseline_path(self):
"""Return the absolute path to the directory to store new baselines
in for this port."""
@@ -315,7 +318,7 @@ class Port(object):
path = self.expected_filename(test, '.checksum')
if not self.path_exists(path):
return None
- return self._filesystem.read_text_file(path)
+ return self._filesystem.read_binary_file(path)
def expected_image(self, test):
"""Returns the image we expect the test to produce."""
@@ -393,7 +396,7 @@ class Port(object):
driver = self.create_driver(0)
return driver.cmd_line()
- def update_baseline(self, path, data, encoding):
+ def update_baseline(self, path, data):
"""Updates the baseline for a test.
Args:
@@ -401,14 +404,8 @@ class Port(object):
the test. This function is used to update either generic or
platform-specific baselines, but we can't infer which here.
data: contents of the baseline.
- encoding: file encoding to use for the baseline.
"""
- # FIXME: remove the encoding parameter in favor of text/binary
- # functions.
- if encoding is None:
- self._filesystem.write_binary_file(path, data)
- else:
- self._filesystem.write_text_file(path, data)
+ self._filesystem.write_binary_file(path, data)
def uri_to_test_name(self, uri):
"""Return the base layout test name for a given URI.
@@ -465,6 +462,15 @@ class Port(object):
may be different (e.g., 'win-xp' instead of 'chromium-win-xp'."""
return self._name
+ def graphics_type(self):
+ """Returns whether the port uses accelerated graphics ('gpu') or not
+ ('cpu')."""
+ return 'cpu'
+
+ def real_name(self):
+ """Returns the actual name of the port, not the delegate's."""
+ return self.name()
+
def get_option(self, name, default_value=None):
# FIXME: Eventually we should not have to do a test for
# hasattr(), and we should be able to just do
@@ -496,9 +502,16 @@ class Port(object):
"""Relative unix-style path for a filename under the LayoutTests
directory. Filenames outside the LayoutTests directory should raise
an error."""
+ # FIXME: On Windows, does this return test_names with forward slashes,
+ # or windows-style relative paths?
assert filename.startswith(self.layout_tests_dir()), "%s did not start with %s" % (filename, self.layout_tests_dir())
return filename[len(self.layout_tests_dir()) + 1:]
+ def abspath_for_test(self, test_name):
+ """Returns the full path to the file for a given test name. This is the
+ inverse of relative_test_filename()."""
+ return self._filesystem.normpath(self._filesystem.join(self.layout_tests_dir(), test_name))
+
def results_directory(self):
"""Absolute path to the place to store the test results."""
raise NotImplementedError('Port.results_directory')
@@ -577,12 +590,25 @@ class Port(object):
if self._http_lock:
self._http_lock.cleanup_http_lock()
+ #
+ # TEST EXPECTATION-RELATED METHODS
+ #
+
+ def test_configuration(self):
+ """Returns the current TestConfiguration for the port."""
+ if not self._test_configuration:
+ self._test_configuration = TestConfiguration(self)
+ return self._test_configuration
+
+ def all_test_configurations(self):
+ return self.test_configuration().all_test_configurations()
+
def test_expectations(self):
"""Returns the test expectations for this port.
Basically this string should contain the equivalent of a
test_expectations file. See test_expectations.py for more details."""
- raise NotImplementedError('Port.test_expectations')
+ return self._filesystem.read_text_file(self.path_to_test_expectations_file())
def test_expectations_overrides(self):
"""Returns an optional set of overrides for the test_expectations.
@@ -593,18 +619,6 @@ class Port(object):
sync up the two repos."""
return None
- def test_base_platform_names(self):
- """Return a list of the 'base' platforms on your port. The base
- platforms represent different architectures, operating systems,
- or implementations (as opposed to different versions of a single
- platform). For example, 'mac' and 'win' might be different base
- platforms, wherease 'mac-tiger' and 'mac-leopard' might be
- different platforms. This routine is used by the rebaselining tool
- and the dashboards, and the strings correspond to the identifiers
- in your test expectations (*not* necessarily the platform names
- themselves)."""
- raise NotImplementedError('Port.base_test_platforms')
-
def test_platform_name(self):
"""Returns the string that corresponds to the given platform name
in the test expectations. This may be the same as name(), or it
@@ -810,6 +824,48 @@ class Port(object):
platform)
+class DriverInput(object):
+ """Holds the input parameters for a driver."""
+
+ def __init__(self, filename, timeout, image_hash):
+ """Initializes a DriverInput object.
+
+ Args:
+ filename: Full path to the test.
+ timeout: Timeout in msecs the driver should use while running the test
+ image_hash: A image checksum which is used to avoid doing an image dump if
+ the checksums match.
+ """
+ self.filename = filename
+ self.timeout = timeout
+ self.image_hash = image_hash
+
+
+class DriverOutput(object):
+ """Groups information about a output from driver for easy passing of data."""
+
+ def __init__(self, text, image, image_hash,
+ crash=False, test_time=None, timeout=False, error=''):
+ """Initializes a TestOutput object.
+
+ Args:
+ text: a text output
+ image: an image output
+ image_hash: a string containing the checksum of the image
+ crash: a boolean indicating whether the driver crashed on the test
+ test_time: a time which the test has taken
+ timeout: a boolean indicating whehter the test timed out
+ error: any unexpected or additional (or error) text output
+ """
+ self.text = text
+ self.image = image
+ self.image_hash = image_hash
+ self.crash = crash
+ self.test_time = test_time
+ self.timeout = timeout
+ self.error = error
+
+
class Driver:
"""Abstract interface for the DumpRenderTree interface."""
@@ -824,7 +880,7 @@ class Driver:
"""
raise NotImplementedError('Driver.__init__')
- def run_test(self, test_input):
+ def run_test(self, driver_input):
"""Run a single test and return the results.
Note that it is okay if a test times out or crashes and leaves
@@ -832,9 +888,9 @@ class Driver:
are responsible for cleaning up and ensuring things are okay.
Args:
- test_input: a TestInput object
+ driver_input: a DriverInput object
- Returns a TestOutput object.
+ Returns a DriverOutput object.
"""
raise NotImplementedError('Driver.run_test')
@@ -863,3 +919,68 @@ class Driver:
def stop(self):
raise NotImplementedError('Driver.stop')
+
+
+class TestConfiguration(object):
+ def __init__(self, port=None, os=None, version=None, architecture=None,
+ build_type=None, graphics_type=None):
+
+ # FIXME: We can get the O/S and version from test_platform_name()
+ # and version() for now, but those should go away and be cleaned up
+ # with more generic methods like operation_system() and os_version()
+ # or something. Note that we need to strip the leading '-' off the
+ # version string if it is present.
+ if port:
+ port_version = port.version()
+ self.os = os or port.test_platform_name().replace(port_version, '')
+ self.version = version or port_version[1:]
+ self.architecture = architecture or 'x86'
+ self.build_type = build_type or port._options.configuration.lower()
+ self.graphics_type = graphics_type or port.graphics_type()
+
+ def items(self):
+ return self.__dict__.items()
+
+ def keys(self):
+ return self.__dict__.keys()
+
+ def __str__(self):
+ return ("<%(os)s, %(version)s, %(build_type)s, %(graphics_type)s>" %
+ self.__dict__)
+
+ def __repr__(self):
+ return "TestConfig(os='%(os)s', version='%(version)s', architecture='%(architecture)s', build_type='%(build_type)s', graphics_type='%(graphics_type)s')" % self.__dict__
+
+ def values(self):
+ """Returns the configuration values of this instance as a tuple."""
+ return self.__dict__.values()
+
+ def all_test_configurations(self):
+ """Returns a sequence of the TestConfigurations the port supports."""
+ # By default, we assume we want to test every graphics type in
+ # every configuration on every system.
+ test_configurations = []
+ for system in self.all_systems():
+ for build_type in self.all_build_types():
+ for graphics_type in self.all_graphics_types():
+ test_configurations.append(TestConfiguration(
+ os=system[0],
+ version=system[1],
+ architecture=system[2],
+ build_type=build_type,
+ graphics_type=graphics_type))
+ return test_configurations
+
+ def all_systems(self):
+ return (('mac', 'leopard', 'x86'),
+ ('mac', 'snowleopard', 'x86'),
+ ('win', 'xp', 'x86'),
+ ('win', 'vista', 'x86'),
+ ('win', 'win7', 'x86'),
+ ('linux', 'hardy', 'x86'))
+
+ def all_build_types(self):
+ return ('debug', 'release')
+
+ def all_graphics_types(self):
+ return ('cpu', 'gpu')