2 # Copyright (C) 2010 Google Inc. All rights reserved.
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above
11 # copyright notice, this list of conditions and the following disclaimer
12 # in the documentation and/or other materials provided with the
14 # * Neither the Google name nor the names of its
15 # contributors may be used to endorse or promote products derived from
16 # this software without specific prior written permission.
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 """Dummy Port implementation used for testing."""
31 from __future__ import with_statement
40 class TestPort(base.Port):
41 """Test implementation of the Port interface."""
43 def __init__(self, port_name=None, options=None):
44 base.Port.__init__(self, port_name, options)
46 def baseline_path(self):
47 return os.path.join(self.layout_tests_dir(), 'platform',
48 self.name() + self.version())
50 def baseline_search_path(self):
51 return [self.baseline_path()]
53 def check_build(self, needs_http):
56 def diff_image(self, expected_filename, actual_filename,
57 diff_filename=None, tolerance=0):
58 with codecs.open(actual_filename, "r", "utf-8") as actual_fh:
59 actual_contents = actual_fh.read()
60 with codecs.open(expected_filename, "r", "utf-8") as expected_fh:
61 expected_contents = expected_fh.read()
62 diffed = actual_contents != expected_contents
63 if diffed and diff_filename:
64 with codecs.open(diff_filename, "w", "utf-8") as diff_fh:
65 diff_fh.write("< %s\n---\n> %s\n" %
66 (expected_contents, actual_contents))
69 def layout_tests_dir(self):
70 return self.path_from_webkit_base('WebKitTools', 'Scripts',
71 'webkitpy', 'layout_tests', 'data')
79 def path_to_test_expectations_file(self):
80 return self.path_from_webkit_base('WebKitTools', 'Scripts',
81 'webkitpy', 'layout_tests', 'data', 'platform', 'test',
82 'test_expectations.txt')
84 def _path_to_wdiff(self):
87 def results_directory(self):
88 return '/tmp/' + self._options.results_directory
90 def setup_test_run(self):
93 def show_results_html_file(self, filename):
96 def create_driver(self, image_path, options):
97 return TestDriver(image_path, options, self)
99 def start_http_server(self):
102 def start_websocket_server(self):
105 def stop_http_server(self):
108 def stop_websocket_server(self):
111 def test_expectations(self):
112 """Returns the test expectations for this port.
114 Basically this string should contain the equivalent of a
115 test_expectations file. See test_expectations.py for more details."""
116 expectations_path = self.path_to_test_expectations_file()
117 with codecs.open(expectations_path, "r", "utf-8") as file:
120 def test_base_platform_names(self):
123 def test_platform_name(self):
126 def test_platform_names(self):
127 return self.test_base_platform_names()
129 def test_platform_name_to_name(self, test_platform_name):
130 return test_platform_name
136 class TestDriver(base.Driver):
137 """Test/Dummy implementation of the DumpRenderTree interface."""
139 def __init__(self, image_path, test_driver_options, port):
140 self._driver_options = test_driver_options
141 self._image_path = image_path
143 self._image_written = False
148 def returncode(self):
151 def run_test(self, uri, timeoutms, image_hash):
152 basename = uri[(uri.rfind("/") + 1):uri.rfind(".html")]
156 # There are four currently supported types of tests: text, image,
157 # image hash (checksum), and stderr output. The fake output
158 # is the basename of the file + "-" plus the type of test output
159 # (or a blank string for stderr).
161 # If 'image' or 'check' appears in the basename, we assume this is
162 # simulating a pixel test.
164 # If 'failures' appears in the URI, then we assume this test should
165 # fail. Which type of failures are determined by which strings appear
166 # in the basename of the test. For failures that produce outputs,
167 # we change the fake output to basename + "_failed-".
169 # The fact that each test produces (more or less) unique output data
170 # will allow us to see if any results get crossed by the rest of the
172 if 'failures' in uri:
173 crash = 'crash' in basename
174 timeout = 'timeout' in basename
175 if 'error' in basename:
176 error = basename + "_error\n"
177 if 'text' in basename:
178 output = basename + '_failed-txt\n'
180 output = basename + '-txt\n'
181 if self._port.options().pixel_tests:
182 if ('image' in basename or 'check' in basename):
183 checksum = basename + "-checksum\n"
185 if 'image' in basename:
186 with open(self._image_path, "w") as f:
187 f.write(basename + "_failed-png\n")
188 elif 'check' in basename:
189 with open(self._image_path, "w") as f:
190 f.write(basename + "-png\n")
191 if 'checksum' in basename:
192 checksum = basename + "_failed-checksum\n"
196 output = basename + '-txt\n'
197 if self._port.options().pixel_tests and (
198 'image' in basename or 'check' in basename):
199 checksum = basename + '-checksum\n'
200 with open(self._image_path, "w") as f:
201 f.write(basename + "-png")
203 return (crash, timeout, checksum, output, error)