blob: 73bc1a78c962396021b4128c44b9abcd87459898 [file] [log] [blame]
#!/usr/bin/python
# Copyright (C) 2010 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Unit tests for rebaseline_chromium_webkit_tests.py."""
import unittest
from webkitpy.tool import mocktool
from webkitpy.common.system import urlfetcher_mock
from webkitpy.common.system import filesystem_mock
from webkitpy.common.system import zipfileset_mock
from webkitpy.common.system import outputcapture
from webkitpy.common.system.executive import Executive, ScriptError
from webkitpy.layout_tests import port
from webkitpy.layout_tests import rebaseline_chromium_webkit_tests
class MockPort(object):
def __init__(self, image_diff_exists):
self.image_diff_exists = image_diff_exists
def check_image_diff(self, override_step, logging):
return self.image_diff_exists
def get_mock_get(config_expectations):
def mock_get(port_name, options):
return MockPort(config_expectations[options.configuration])
return mock_get
ARCHIVE_URL = 'http://localhost/layout_test_results'
def test_options():
return mocktool.MockOptions(configuration=None,
backup=False,
html_directory='/tmp',
archive_url=ARCHIVE_URL,
force_archive_url=None,
verbose=False,
quiet=False,
platforms=None)
def test_host_port_and_filesystem(options, expectations):
filesystem = port.unit_test_filesystem()
host_port_obj = port.get('test', options, filesystem=filesystem,
user=mocktool.MockUser())
expectations_path = host_port_obj.path_to_test_expectations_file()
filesystem.write_text_file(expectations_path, expectations)
return (host_port_obj, filesystem)
def test_url_fetcher(filesystem):
urls = {
ARCHIVE_URL + '/Webkit_Mac10_6/': '<a href="4/">',
ARCHIVE_URL + '/Webkit_Mac10_5/': '<a href="1/"><a href="2/">',
ARCHIVE_URL + '/Webkit_Win7/': '<a href="1/">',
ARCHIVE_URL + '/Webkit_Vista/': '<a href="1/">',
ARCHIVE_URL + '/Webkit_Win/': '<a href="1/">',
ARCHIVE_URL + '/Webkit_Linux/': '<a href="1/">',
}
return urlfetcher_mock.make_fetcher_cls(urls)(filesystem)
def test_zip_factory():
ziphashes = {
ARCHIVE_URL + '/Webkit_Mac10_5/2/layout-test-results.zip': {
'layout-test-results/failures/expected/image-actual.txt': 'new-image-txt',
'layout-test-results/failures/expected/image-actual.checksum': 'new-image-checksum',
'layout-test-results/failures/expected/image-actual.png': 'new-image-png',
'layout-test-results/failures/expected/image_checksum-actual.txt': 'png-comment-txt',
'layout-test-results/failures/expected/image_checksum-actual.checksum': '0123456789',
'layout-test-results/failures/expected/image_checksum-actual.png': 'tEXtchecksum\x000123456789',
},
ARCHIVE_URL + '/Webkit_Mac10_6/4/layout-test-results.zip': {
'layout-test-results/failures/expected/image-actual.txt': 'new-image-txt',
'layout-test-results/failures/expected/image-actual.checksum': 'new-image-checksum',
'layout-test-results/failures/expected/image-actual.png': 'new-image-png',
},
ARCHIVE_URL + '/Webkit_Vista/1/layout-test-results.zip': {
'layout-test-results/failures/expected/image-actual.txt': 'win-image-txt',
'layout-test-results/failures/expected/image-actual.checksum': 'win-image-checksum',
'layout-test-results/failures/expected/image-actual.png': 'win-image-png',
},
ARCHIVE_URL + '/Webkit_Win7/1/layout-test-results.zip': {
'layout-test-results/failures/expected/image-actual.txt': 'win-image-txt',
'layout-test-results/failures/expected/image-actual.checksum': 'win-image-checksum',
'layout-test-results/failures/expected/image-actual.png': 'win-image-png',
},
ARCHIVE_URL + '/Webkit_Win/1/layout-test-results.zip': {
'layout-test-results/failures/expected/image-actual.txt': 'win-image-txt',
'layout-test-results/failures/expected/image-actual.checksum': 'win-image-checksum',
'layout-test-results/failures/expected/image-actual.png': 'win-image-png',
},
ARCHIVE_URL + '/Webkit_Linux/1/layout-test-results.zip': {
'layout-test-results/failures/expected/image-actual.txt': 'win-image-txt',
'layout-test-results/failures/expected/image-actual.checksum': 'win-image-checksum',
'layout-test-results/failures/expected/image-actual.png': 'win-image-png',
},
}
return zipfileset_mock.make_factory(ziphashes)
def test_archive(orig_archive_dict):
new_archive_dict = {}
for platform, dirname in orig_archive_dict.iteritems():
platform = platform.replace('chromium', 'test')
new_archive_dict[platform] = dirname
return new_archive_dict
class TestGetHostPortObject(unittest.TestCase):
def assert_result(self, release_present, debug_present, valid_port_obj):
# Tests whether we get a valid port object returned when we claim
# that Image diff is (or isn't) present in the two configs.
port.get = get_mock_get({'Release': release_present,
'Debug': debug_present})
options = mocktool.MockOptions(configuration=None,
html_directory='/tmp')
port_obj = rebaseline_chromium_webkit_tests.get_host_port_object(options)
if valid_port_obj:
self.assertNotEqual(port_obj, None)
else:
self.assertEqual(port_obj, None)
def test_get_host_port_object(self):
# Save the normal port.get() function for future testing.
old_get = port.get
# Test whether we get a valid port object back for the four
# possible cases of having ImageDiffs built. It should work when
# there is at least one binary present.
self.assert_result(False, False, False)
self.assert_result(True, False, True)
self.assert_result(False, True, True)
self.assert_result(True, True, True)
# Restore the normal port.get() function.
port.get = old_get
class TestOptions(unittest.TestCase):
def test_parse_options(self):
(options, target_options) = rebaseline_chromium_webkit_tests.parse_options([])
self.assertTrue(target_options.chromium)
self.assertEqual(options.tolerance, 0)
(options, target_options) = rebaseline_chromium_webkit_tests.parse_options(['--target-platform', 'qt'])
self.assertFalse(hasattr(target_options, 'chromium'))
self.assertEqual(options.tolerance, 0)
class TestRebaseliner(unittest.TestCase):
def setUp(self):
if not hasattr(self, '_orig_archive'):
self._orig_archive = rebaseline_chromium_webkit_tests.ARCHIVE_DIR_NAME_DICT
rebaseline_chromium_webkit_tests.ARCHIVE_DIR_NAME_DICT = test_archive(self._orig_archive)
def tearDown(self):
rebaseline_chromium_webkit_tests.ARCHIVE_DIR_NAME_DICT = self._orig_archive
def make_rebaseliner(self, expectations):
options = test_options()
host_port_obj, filesystem = test_host_port_and_filesystem(options, expectations)
target_options = options
target_port_obj = port.get('test', target_options,
filesystem=filesystem)
target_port_obj._expectations = expectations
platform = target_port_obj.name()
url_fetcher = test_url_fetcher(filesystem)
zip_factory = test_zip_factory()
mock_scm = mocktool.MockSCM(filesystem)
rebaseliner = rebaseline_chromium_webkit_tests.Rebaseliner(host_port_obj,
target_port_obj, platform, options, url_fetcher, zip_factory, mock_scm)
return rebaseliner, filesystem
def test_noop(self):
# this method tests that was can at least instantiate an object, even
# if there is nothing to do.
rebaseliner, filesystem = self.make_rebaseliner("")
rebaseliner.run()
self.assertEqual(len(filesystem.written_files), 1)
def test_rebaselining_tests(self):
rebaseliner, filesystem = self.make_rebaseliner(
"BUGX REBASELINE MAC : failures/expected/image.html = IMAGE")
compile_success = rebaseliner._compile_rebaselining_tests()
self.assertTrue(compile_success)
self.assertEqual(set(['failures/expected/image.html']), rebaseliner._rebaselining_tests)
def test_rebaselining_tests_should_ignore_reftests(self):
rebaseliner, filesystem = self.make_rebaseliner(
"BUGX REBASELINE : failures/expected/reftest.html = IMAGE")
compile_success = rebaseliner._compile_rebaselining_tests()
self.assertFalse(compile_success)
self.assertFalse(rebaseliner._rebaselining_tests)
def test_one_platform(self):
rebaseliner, filesystem = self.make_rebaseliner(
"BUGX REBASELINE MAC : failures/expected/image.html = IMAGE")
rebaseliner.run()
# We expect to have written 12 files over the course of this rebaseline:
# *) 3 files in /__im_tmp for the extracted archive members
# *) 3 new baselines under '/test.checkout/LayoutTests'
# *) 4 files in /tmp for the new and old baselines in the result file
# (-{old,new}.{txt,png}
# *) 1 text diff in /tmp for the result file (-diff.txt). We don't
# create image diffs (FIXME?) and don't display the checksums.
# *) 1 updated test_expectations file
self.assertEqual(len(filesystem.written_files), 12)
self.assertEqual(filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image-expected.checksum'], 'new-image-checksum')
self.assertEqual(filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image-expected.png'], 'new-image-png')
self.assertEqual(filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image-expected.txt'], 'new-image-txt')
def test_all_platforms(self):
rebaseliner, filesystem = self.make_rebaseliner(
"BUGX REBASELINE : failures/expected/image.html = IMAGE")
rebaseliner.run()
# See comment in test_one_platform for an explanation of the 12 written tests.
# Note that even though the rebaseline is marked for all platforms, each
# rebaseliner only ever does one.
self.assertEqual(len(filesystem.written_files), 12)
self.assertEqual(filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image-expected.checksum'], 'new-image-checksum')
self.assertEqual(filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image-expected.png'], 'new-image-png')
self.assertEqual(filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image-expected.txt'], 'new-image-txt')
def test_png_file_with_comment(self):
rebaseliner, filesystem = self.make_rebaseliner(
"BUGX REBASELINE MAC : failures/expected/image_checksum.html = IMAGE")
compile_success = rebaseliner._compile_rebaselining_tests()
self.assertTrue(compile_success)
self.assertEqual(set(['failures/expected/image_checksum.html']), rebaseliner._rebaselining_tests)
rebaseliner.run()
# There is one less file written than |test_one_platform| because we only
# write 2 expectations (the png and the txt file).
self.assertEqual(len(filesystem.written_files), 11)
self.assertEqual(filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.png'], 'tEXtchecksum\x000123456789')
self.assertEqual(filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.txt'], 'png-comment-txt')
self.assertFalse(filesystem.files.get('/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.checksum', None))
def test_png_file_with_comment_remove_old_checksum(self):
rebaseliner, filesystem = self.make_rebaseliner(
"BUGX REBASELINE MAC : failures/expected/image_checksum.html = IMAGE")
filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.png'] = 'old'
filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.checksum'] = 'old'
filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.txt'] = 'old'
compile_success = rebaseliner._compile_rebaselining_tests()
self.assertTrue(compile_success)
self.assertEqual(set(['failures/expected/image_checksum.html']), rebaseliner._rebaselining_tests)
rebaseliner.run()
# There is one more file written than |test_png_file_with_comment_remove_old_checksum|
# because we also delete the old checksum.
self.assertEqual(len(filesystem.written_files), 12)
self.assertEqual(filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.png'], 'tEXtchecksum\x000123456789')
self.assertEqual(filesystem.files['/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.txt'], 'png-comment-txt')
self.assertEqual(filesystem.files.get('/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.checksum', None), None)
def test_png_file_with_comment_as_duplicate(self):
rebaseliner, filesystem = self.make_rebaseliner(
"BUGX REBASELINE MAC : failures/expected/image_checksum.html = IMAGE")
filesystem.files['/test.checkout/LayoutTests/platform/test-mac-snowleopard/failures/expected/image_checksum-expected.png'] = 'tEXtchecksum\x000123456789'
filesystem.files['/test.checkout/LayoutTests/platform/test-mac-snowleopard/failures/expected/image_checksum-expected.txt'] = 'png-comment-txt'
compile_success = rebaseliner._compile_rebaselining_tests()
self.assertTrue(compile_success)
self.assertEqual(set(['failures/expected/image_checksum.html']), rebaseliner._rebaselining_tests)
rebaseliner.run()
self.assertEqual(filesystem.files.get('/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.png', None), None)
self.assertEqual(filesystem.files.get('/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.txt', None), None)
self.assertEqual(filesystem.files.get('/test.checkout/LayoutTests/platform/test-mac-leopard/failures/expected/image_checksum-expected.checksum', None), None)
def test_diff_baselines_txt(self):
rebaseliner, filesystem = self.make_rebaseliner("")
port = rebaseliner._port
output = port.expected_text(
port._filesystem.join(port.layout_tests_dir(), 'passes/text.html'))
self.assertFalse(rebaseliner._diff_baselines(output, output,
is_image=False))
def test_diff_baselines_png(self):
rebaseliner, filesystem = self.make_rebaseliner('')
port = rebaseliner._port
image = port.expected_image(
port._filesystem.join(port.layout_tests_dir(), 'passes/image.html'))
self.assertFalse(rebaseliner._diff_baselines(image, image,
is_image=True))
class TestRealMain(unittest.TestCase):
def setUp(self):
if not hasattr(self, '_orig_archive'):
self._orig_archive = rebaseline_chromium_webkit_tests.ARCHIVE_DIR_NAME_DICT
rebaseline_chromium_webkit_tests.ARCHIVE_DIR_NAME_DICT = test_archive(self._orig_archive)
def tearDown(self):
rebaseline_chromium_webkit_tests.ARCHIVE_DIR_NAME_DICT = self._orig_archive
def test_all_platforms(self):
expectations = "BUGX REBASELINE : failures/expected/image.html = IMAGE"
options = test_options()
host_port_obj, filesystem = test_host_port_and_filesystem(options, expectations)
url_fetcher = test_url_fetcher(filesystem)
zip_factory = test_zip_factory()
mock_scm = mocktool.MockSCM()
oc = outputcapture.OutputCapture()
oc.capture_output()
res = rebaseline_chromium_webkit_tests.real_main(options, options,
host_port_obj, host_port_obj, url_fetcher, zip_factory, mock_scm)
oc.restore_output()
# We expect to have written 36 files over the course of this rebaseline:
# *) 6*3 files in /__im_tmp/ for the archived members of the 6 ports
# *) 2*3 files in /test.checkout for actually differing baselines
# *) 1 file in /test.checkout for the updated test_expectations file
# *) 2*4 files in /tmp for the old/new baselines for the two actual ports
# *) 2 files in /tmp for the text diffs for the two ports
# *) 1 file in /tmp for the rebaseline results html file
self.assertEqual(res, 0)
self.assertEqual(len(filesystem.written_files), 36)
class TestHtmlGenerator(unittest.TestCase):
def make_generator(self, files, tests):
options = mocktool.MockOptions(configuration=None, html_directory='/tmp')
host_port = port.get('test', options, filesystem=port.unit_test_filesystem(files))
generator = rebaseline_chromium_webkit_tests.HtmlGenerator(host_port,
target_port=None, options=options, platforms=['test-mac-leopard'], rebaselining_tests=tests)
return generator, host_port
def test_generate_baseline_links(self):
files = {
"/tmp/foo-expected-mac-old.txt": "",
"/tmp/foo-expected-mac-new.txt": "",
"/tmp/foo-expected-mac-diff.txt": "",
}
tests = ["foo.txt"]
generator, host_port = self.make_generator(files, tests)
links = generator._generate_baseline_links("foo", ".txt", "mac")
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>'
self.assertEqual(links, expected_links)
if __name__ == '__main__':
unittest.main()