#!/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()
