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 name of Google Inc. 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 """Unit tests for rebaseline_chromium_webkit_tests.py."""
34 from webkitpy.tool import mocktool
35 from webkitpy.common.system import urlfetcher_mock
36 from webkitpy.common.system import filesystem_mock
37 from webkitpy.common.system import zipfileset_mock
38 from webkitpy.common.system import outputcapture
39 from webkitpy.common.system.executive import Executive, ScriptError
41 from webkitpy.layout_tests import port
42 from webkitpy.layout_tests import rebaseline_chromium_webkit_tests
45 class MockPort(object):
46 def __init__(self, image_diff_exists):
47 self.image_diff_exists = image_diff_exists
49 def check_image_diff(self, override_step, logging):
50 return self.image_diff_exists
53 def get_mock_get(config_expectations):
54 def mock_get(port_name, options):
55 return MockPort(config_expectations[options.configuration])
59 ARCHIVE_URL = 'http://localhost/layout_test_results'
63 return mocktool.MockOptions(configuration=None,
65 html_directory='/tmp',
66 archive_url=ARCHIVE_URL,
67 force_archive_url=None,
73 def test_host_port_and_filesystem(options, expectations):
74 filesystem = port.unit_test_filesystem()
75 host_port_obj = port.get('test', options, filesystem=filesystem,
76 user=mocktool.MockUser())
78 expectations_path = host_port_obj.path_to_test_expectations_file()
79 filesystem.write_text_file(expectations_path, expectations)
80 return (host_port_obj, filesystem)
83 def test_url_fetcher(filesystem):
85 ARCHIVE_URL + '/Webkit_Mac10_6/': '<a href="4/">',
86 ARCHIVE_URL + '/Webkit_Mac10_5/': '<a href="1/"><a href="2/">',
87 ARCHIVE_URL + '/Webkit_Win7/': '<a href="1/">',
88 ARCHIVE_URL + '/Webkit_Vista/': '<a href="1/">',
89 ARCHIVE_URL + '/Webkit_Win/': '<a href="1/">',
90 ARCHIVE_URL + '/Webkit_Linux/': '<a href="1/">',
92 return urlfetcher_mock.make_fetcher_cls(urls)(filesystem)
95 def test_zip_factory():
97 ARCHIVE_URL + '/Webkit_Mac10_5/2/layout-test-results.zip': {
98 'layout-test-results/failures/expected/image-actual.txt': 'new-image-txt',
99 'layout-test-results/failures/expected/image-actual.checksum': 'new-image-checksum',
100 'layout-test-results/failures/expected/image-actual.png': 'new-image-png',
101 'layout-test-results/failures/expected/image_checksum-actual.txt': 'png-comment-txt',
102 'layout-test-results/failures/expected/image_checksum-actual.checksum': '0123456789',
103 'layout-test-results/failures/expected/image_checksum-actual.png': 'tEXtchecksum\x000123456789',
105 ARCHIVE_URL + '/Webkit_Mac10_6/4/layout-test-results.zip': {
106 'layout-test-results/failures/expected/image-actual.txt': 'new-image-txt',
107 'layout-test-results/failures/expected/image-actual.checksum': 'new-image-checksum',
108 'layout-test-results/failures/expected/image-actual.png': 'new-image-png',
110 ARCHIVE_URL + '/Webkit_Vista/1/layout-test-results.zip': {
111 'layout-test-results/failures/expected/image-actual.txt': 'win-image-txt',
112 'layout-test-results/failures/expected/image-actual.checksum': 'win-image-checksum',
113 'layout-test-results/failures/expected/image-actual.png': 'win-image-png',
115 ARCHIVE_URL + '/Webkit_Win7/1/layout-test-results.zip': {
116 'layout-test-results/failures/expected/image-actual.txt': 'win-image-txt',
117 'layout-test-results/failures/expected/image-actual.checksum': 'win-image-checksum',
118 'layout-test-results/failures/expected/image-actual.png': 'win-image-png',
120 ARCHIVE_URL + '/Webkit_Win/1/layout-test-results.zip': {
121 'layout-test-results/failures/expected/image-actual.txt': 'win-image-txt',
122 'layout-test-results/failures/expected/image-actual.checksum': 'win-image-checksum',
123 'layout-test-results/failures/expected/image-actual.png': 'win-image-png',
125 ARCHIVE_URL + '/Webkit_Linux/1/layout-test-results.zip': {
126 'layout-test-results/failures/expected/image-actual.txt': 'win-image-txt',
127 'layout-test-results/failures/expected/image-actual.checksum': 'win-image-checksum',
128 'layout-test-results/failures/expected/image-actual.png': 'win-image-png',
131 return zipfileset_mock.make_factory(ziphashes)
134 def test_archive(orig_archive_dict):
135 new_archive_dict = {}
136 for platform, dirname in orig_archive_dict.iteritems():
137 platform = platform.replace('chromium', 'test')
138 new_archive_dict[platform] = dirname
139 return new_archive_dict
142 class TestGetHostPortObject(unittest.TestCase):
143 def assert_result(self, release_present, debug_present, valid_port_obj):
144 # Tests whether we get a valid port object returned when we claim
145 # that Image diff is (or isn't) present in the two configs.
146 port.get = get_mock_get({'Release': release_present,
147 'Debug': debug_present})
148 options = mocktool.MockOptions(configuration=None,
149 html_directory='/tmp')
150 port_obj = rebaseline_chromium_webkit_tests.get_host_port_object(options)
152 self.assertNotEqual(port_obj, None)
154 self.assertEqual(port_obj, None)
156 def test_get_host_port_object(self):
157 # Save the normal port.get() function for future testing.
160 # Test whether we get a valid port object back for the four
161 # possible cases of having ImageDiffs built. It should work when
162 # there is at least one binary present.
163 self.assert_result(False, False, False)
164 self.assert_result(True, False, True)
165 self.assert_result(False, True, True)
166 self.assert_result(True, True, True)
168 # Restore the normal port.get() function.
172 class TestOptions(unittest.TestCase):
173 def test_parse_options(self):
174 (options, target_options) = rebaseline_chromium_webkit_tests.parse_options([])
175 self.assertTrue(target_options.chromium)
176 self.assertEqual(options.tolerance, 0)
178 (options, target_options) = rebaseline_chromium_webkit_tests.parse_options(['--target-platform', 'qt'])
179 self.assertFalse(hasattr(target_options, 'chromium'))
180 self.assertEqual(options.tolerance, 0)
183 class TestRebaseliner(unittest.TestCase):
185 if not hasattr(self, '_orig_archive'):
186 self._orig_archive = rebaseline_chromium_webkit_tests.ARCHIVE_DIR_NAME_DICT
187 rebaseline_chromium_webkit_tests.ARCHIVE_DIR_NAME_DICT = test_archive(self._orig_archive)
190 rebaseline_chromium_webkit_tests.ARCHIVE_DIR_NAME_DICT = self._orig_archive
192 def make_rebaseliner(self, expectations):
193 options = test_options()
194 host_port_obj, filesystem = test_host_port_and_filesystem(options, expectations)
196 target_options = options
197 target_port_obj = port.get('test', target_options,
198 filesystem=filesystem)
199 target_port_obj._expectations = expectations
200 platform = target_port_obj.name()
202 url_fetcher = test_url_fetcher(filesystem)
203 zip_factory = test_zip_factory()
204 mock_scm = mocktool.MockSCM(filesystem)
205 rebaseliner = rebaseline_chromium_webkit_tests.Rebaseliner(host_port_obj,
206 target_port_obj, platform, options, url_fetcher, zip_factory, mock_scm)
207 return rebaseliner, filesystem
210 # this method tests that was can at least instantiate an object, even
211 # if there is nothing to do.
212 rebaseliner, filesystem = self.make_rebaseliner("")
214 self.assertEqual(len(filesystem.written_files), 1)
216 def test_rebaselining_tests(self):
217 rebaseliner, filesystem = self.make_rebaseliner(
218 "BUGX REBASELINE MAC : failures/expected/image.html = IMAGE")
219 compile_success = rebaseliner._compile_rebaselining_tests()
220 self.assertTrue(compile_success)
221 self.assertEqual(set(['failures/expected/image.html']), rebaseliner._rebaselining_tests)
223 def test_rebaselining_tests_should_ignore_reftests(self):
224 rebaseliner, filesystem = self.make_rebaseliner(
225 "BUGX REBASELINE : failures/expected/reftest.html = IMAGE")
226 compile_success = rebaseliner._compile_rebaselining_tests()
227 self.assertFalse(compile_success)
228 self.assertFalse(rebaseliner._rebaselining_tests)
230 def test_one_platform(self):
231 rebaseliner, filesystem = self.make_rebaseliner(
232 "BUGX REBASELINE MAC : failures/expected/image.html = IMAGE")
234 # We expect to have written 12 files over the course of this rebaseline:
235 # *) 3 files in /__im_tmp for the extracted archive members
236 # *) 3 new baselines under '/test.checkout/LayoutTests'
237 # *) 4 files in /tmp for the new and old baselines in the result file
238 # (-{old,new}.{txt,png}
239 # *) 1 text diff in /tmp for the result file (-diff.txt). We don't
240 # create image diffs (FIXME?) and don't display the checksums.
241 # *) 1 updated test_expectations file
242 self.assertEqual(len(filesystem.written_files), 12)
243 self.assertEqual(filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image-expected.checksum'], 'new-image-checksum')
244 self.assertEqual(filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image-expected.png'], 'new-image-png')
245 self.assertEqual(filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image-expected.txt'], 'new-image-txt')
247 def test_all_platforms(self):
248 rebaseliner, filesystem = self.make_rebaseliner(
249 "BUGX REBASELINE : failures/expected/image.html = IMAGE")
251 # See comment in test_one_platform for an explanation of the 12 written tests.
252 # Note that even though the rebaseline is marked for all platforms, each
253 # rebaseliner only ever does one.
254 self.assertEqual(len(filesystem.written_files), 12)
255 self.assertEqual(filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image-expected.checksum'], 'new-image-checksum')
256 self.assertEqual(filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image-expected.png'], 'new-image-png')
257 self.assertEqual(filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image-expected.txt'], 'new-image-txt')
259 def test_png_file_with_comment(self):
260 rebaseliner, filesystem = self.make_rebaseliner(
261 "BUGX REBASELINE MAC : failures/expected/image_checksum.html = IMAGE")
262 compile_success = rebaseliner._compile_rebaselining_tests()
263 self.assertTrue(compile_success)
264 self.assertEqual(set(['failures/expected/image_checksum.html']), rebaseliner._rebaselining_tests)
266 # There is one less file written than |test_one_platform| because we only
267 # write 2 expectations (the png and the txt file).
268 self.assertEqual(len(filesystem.written_files), 11)
269 self.assertEqual(filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.png'], 'tEXtchecksum\x000123456789')
270 self.assertEqual(filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.txt'], 'png-comment-txt')
271 self.assertFalse(filesystem.files.get('/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.checksum', None))
273 def test_png_file_with_comment_remove_old_checksum(self):
274 rebaseliner, filesystem = self.make_rebaseliner(
275 "BUGX REBASELINE MAC : failures/expected/image_checksum.html = IMAGE")
276 filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.png'] = 'old'
277 filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.checksum'] = 'old'
278 filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.txt'] = 'old'
280 compile_success = rebaseliner._compile_rebaselining_tests()
281 self.assertTrue(compile_success)
282 self.assertEqual(set(['failures/expected/image_checksum.html']), rebaseliner._rebaselining_tests)
284 # There is one more file written than |test_png_file_with_comment_remove_old_checksum|
285 # because we also delete the old checksum.
286 self.assertEqual(len(filesystem.written_files), 12)
287 self.assertEqual(filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.png'], 'tEXtchecksum\x000123456789')
288 self.assertEqual(filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.txt'], 'png-comment-txt')
289 self.assertEqual(filesystem.files.get('/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.checksum', None), None)
291 def test_png_file_with_comment_as_duplicate(self):
292 rebaseliner, filesystem = self.make_rebaseliner(
293 "BUGX REBASELINE MAC : failures/expected/image_checksum.html = IMAGE")
294 filesystem.files['/test.checkout/LayoutTests/platform/test-mac-snowleopard/failures/expected/image_checksum-expected.png'] = 'tEXtchecksum\x000123456789'
295 filesystem.files['/test.checkout/LayoutTests/platform/test-mac-snowleopard/failures/expected/image_checksum-expected.txt'] = 'png-comment-txt'
297 compile_success = rebaseliner._compile_rebaselining_tests()
298 self.assertTrue(compile_success)
299 self.assertEqual(set(['failures/expected/image_checksum.html']), rebaseliner._rebaselining_tests)
301 self.assertEqual(filesystem.files.get('/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.png', None), None)
302 self.assertEqual(filesystem.files.get('/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.txt', None), None)
303 self.assertEqual(filesystem.files.get('/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.checksum', None), None)
305 def test_diff_baselines_txt(self):
306 rebaseliner, filesystem = self.make_rebaseliner("")
307 port = rebaseliner._port
308 output = port.expected_text(
309 port._filesystem.join(port.layout_tests_dir(), 'passes/text.html'))
310 self.assertFalse(rebaseliner._diff_baselines(output, output,
313 def test_diff_baselines_png(self):
314 rebaseliner, filesystem = self.make_rebaseliner('')
315 port = rebaseliner._port
316 image = port.expected_image(
317 port._filesystem.join(port.layout_tests_dir(), 'passes/image.html'))
318 self.assertFalse(rebaseliner._diff_baselines(image, image,
322 class TestRealMain(unittest.TestCase):
324 if not hasattr(self, '_orig_archive'):
325 self._orig_archive = rebaseline_chromium_webkit_tests.ARCHIVE_DIR_NAME_DICT
326 rebaseline_chromium_webkit_tests.ARCHIVE_DIR_NAME_DICT = test_archive(self._orig_archive)
329 rebaseline_chromium_webkit_tests.ARCHIVE_DIR_NAME_DICT = self._orig_archive
331 def test_all_platforms(self):
332 expectations = "BUGX REBASELINE : failures/expected/image.html = IMAGE"
334 options = test_options()
335 host_port_obj, filesystem = test_host_port_and_filesystem(options, expectations)
336 url_fetcher = test_url_fetcher(filesystem)
337 zip_factory = test_zip_factory()
338 mock_scm = mocktool.MockSCM()
339 oc = outputcapture.OutputCapture()
341 res = rebaseline_chromium_webkit_tests.real_main(options, options,
342 host_port_obj, host_port_obj, url_fetcher, zip_factory, mock_scm)
345 # We expect to have written 36 files over the course of this rebaseline:
346 # *) 6*3 files in /__im_tmp/ for the archived members of the 6 ports
347 # *) 2*3 files in /test.checkout for actually differing baselines
348 # *) 1 file in /test.checkout for the updated test_expectations file
349 # *) 2*4 files in /tmp for the old/new baselines for the two actual ports
350 # *) 2 files in /tmp for the text diffs for the two ports
351 # *) 1 file in /tmp for the rebaseline results html file
352 self.assertEqual(res, 0)
353 self.assertEqual(len(filesystem.written_files), 36)
356 class TestHtmlGenerator(unittest.TestCase):
357 def make_generator(self, files, tests):
358 options = mocktool.MockOptions(configuration=None, html_directory='/tmp')
359 host_port = port.get('test', options, filesystem=port.unit_test_filesystem(files))
360 generator = rebaseline_chromium_webkit_tests.HtmlGenerator(host_port,
361 target_port=None, options=options, platforms=['test-mac-leopard'], rebaselining_tests=tests)
362 return generator, host_port
364 def test_generate_baseline_links(self):
366 "/tmp/foo-expected-mac-old.txt": "",
367 "/tmp/foo-expected-mac-new.txt": "",
368 "/tmp/foo-expected-mac-diff.txt": "",
371 generator, host_port = self.make_generator(files, tests)
372 links = generator._generate_baseline_links("foo", ".txt", "mac")
373 expected_links = '<td align=center><a href="file:///tmp/foo-expected-mac-old.txt">foo-expected.txt</a></td><td align=center><a href="file:///tmp/foo-expected-mac-new.txt">foo-expected.txt</a></td><td align=center><a href="file:///tmp/foo-expected-mac-diff.txt">Diff</a></td>'
374 self.assertEqual(links, expected_links)
377 if __name__ == '__main__':