# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import optparse
import unittest

from webkitpy.common.net.buildbot import Build
from webkitpy.common.net.layout_test_results import LayoutTestResults
from webkitpy.common.system.executive_mock import MockExecutive
from webkitpy.common.system.output_capture import OutputCapture
from webkitpy.layout_tests.builder_list import BuilderList
from webkitpy.tool.commands.rebaseline import (
    AbstractParallelRebaselineCommand, CopyExistingBaselinesInternal,
    Rebaseline, RebaselineExpectations, RebaselineJson, RebaselineTest
)
from webkitpy.tool.mock_tool import MockWebKitPatch


# pylint: disable=protected-access
class BaseTestCase(unittest.TestCase):
    WEB_PREFIX = 'https://storage.googleapis.com/chromium-layout-test-archives/MOCK_Mac10_11/results/layout-test-results'

    command_constructor = None

    def setUp(self):
        self.tool = MockWebKitPatch()
        # Lint warns that command_constructor might not be set, but this is intentional; pylint: disable=not-callable
        self.command = self.command_constructor()
        self.command._tool = self.tool
        self.tool.builders = BuilderList({
            'MOCK Mac10.10 (dbg)': {'port_name': 'test-mac-mac10.10', 'specifiers': ['Mac10.10', 'Debug']},
            'MOCK Mac10.10': {'port_name': 'test-mac-mac10.10', 'specifiers': ['Mac10.10', 'Release']},
            'MOCK Mac10.11 (dbg)': {'port_name': 'test-mac-mac10.11', 'specifiers': ['Mac10.11', 'Debug']},
            'MOCK Mac10.11 ASAN': {'port_name': 'test-mac-mac10.11', 'specifiers': ['Mac10.11', 'Release']},
            'MOCK Mac10.11': {'port_name': 'test-mac-mac10.11', 'specifiers': ['Mac10.11', 'Release']},
            'MOCK Precise': {'port_name': 'test-linux-precise', 'specifiers': ['Precise', 'Release']},
            'MOCK Trusty': {'port_name': 'test-linux-trusty', 'specifiers': ['Trusty', 'Release']},
            'MOCK Win10': {'port_name': 'test-win-win10', 'specifiers': ['Win10', 'Release']},
            'MOCK Win7 (dbg)': {'port_name': 'test-win-win7', 'specifiers': ['Win7', 'Debug']},
            'MOCK Win7 (dbg)(1)': {'port_name': 'test-win-win7', 'specifiers': ['Win7', 'Debug']},
            'MOCK Win7 (dbg)(2)': {'port_name': 'test-win-win7', 'specifiers': ['Win7', 'Debug']},
            'MOCK Win7': {'port_name': 'test-win-win7', 'specifiers': ['Win7', 'Release']},
        })
        self.mac_port = self.tool.port_factory.get_from_builder_name('MOCK Mac10.11')

        self.mac_expectations_path = self.mac_port.path_to_generic_test_expectations_file()
        self.tool.filesystem.write_text_file(
            self.tool.filesystem.join(self.mac_port.layout_tests_dir(), 'VirtualTestSuites'), '[]')

        # In AbstractParallelRebaselineCommand._rebaseline_commands, a default port
        # object is gotten using self.tool.port_factory.get(), which is used to get
        # test paths -- and the layout tests directory may be different for the "test"
        # ports and real ports. Since only "test" ports are used in this class,
        # we can make the default port also a "test" port.
        self.original_port_factory_get = self.tool.port_factory.get
        test_port = self.tool.port_factory.get('test')

        def get_test_port(port_name=None, options=None, **kwargs):
            if not port_name:
                return test_port
            return self.original_port_factory_get(port_name, options, **kwargs)

        self.tool.port_factory.get = get_test_port

    def tearDown(self):
        self.tool.port_factory.get = self.original_port_factory_get

    def _expand(self, path):
        if self.tool.filesystem.isabs(path):
            return path
        return self.tool.filesystem.join(self.mac_port.layout_tests_dir(), path)

    def _read(self, path):
        return self.tool.filesystem.read_text_file(self._expand(path))

    def _write(self, path, contents):
        self.tool.filesystem.write_text_file(self._expand(path), contents)

    def _zero_out_test_expectations(self):
        for port_name in self.tool.port_factory.all_port_names():
            port = self.tool.port_factory.get(port_name)
            for path in port.expectations_files():
                self._write(path, '')
        self.tool.filesystem.written_files = {}

    def _setup_mock_build_data(self):
        for builder in ['MOCK Win7', 'MOCK Win7 (dbg)', 'MOCK Mac10.11']:
            self.tool.buildbot.set_results(Build(builder), LayoutTestResults({
                'tests': {
                    'userscripts': {
                        'first-test.html': {
                            'expected': 'PASS',
                            'actual': 'IMAGE+TEXT'
                        },
                        'second-test.html': {
                            'expected': 'FAIL',
                            'actual': 'IMAGE+TEXT'
                        }
                    }
                }
            }))


class TestCopyExistingBaselinesInternal(BaseTestCase):
    command_constructor = CopyExistingBaselinesInternal

    def setUp(self):
        super(TestCopyExistingBaselinesInternal, self).setUp()

    def options(self, **kwargs):
        options_dict = {
            'results_directory': None,
            'suffixes': 'txt',
            'verbose': False,
        }
        options_dict.update(kwargs)
        return optparse.Values(options_dict)

    def baseline_path(self, path_from_layout_test_dir):
        port = self.tool.port_factory.get()
        return self.tool.filesystem.join(port.layout_tests_dir(), path_from_layout_test_dir)

    # The tests in this class all depend on the fall-back path graph
    # that is set up in |TestPort.FALLBACK_PATHS|.

    def test_copy_baseline_mac_newer_to_older_version(self):
        # The test-mac-mac10.11 baseline is copied over to the test-mac-mac10.10
        # baseline directory because test-mac-mac10.10 is the "immediate
        # predecessor" in the fall-back graph.
        self._write(
            self.baseline_path('platform/test-mac-mac10.11/failures/expected/image-expected.txt'),
            'original test-mac-mac10.11 result')
        self.assertFalse(self.tool.filesystem.exists(
            self.baseline_path('platform/test-mac-mac10.10/failures/expected/image-expected.txt')))

        self.command.execute(self.options(builder='MOCK Mac10.11', test='failures/expected/image.html'), [], self.tool)

        self.assertEqual(
            self._read(self.baseline_path('platform/test-mac-mac10.11/failures/expected/image-expected.txt')),
            'original test-mac-mac10.11 result')
        self.assertEqual(
            self._read(self.baseline_path('platform/test-mac-mac10.10/failures/expected/image-expected.txt')),
            'original test-mac-mac10.11 result')

    def test_copy_baseline_win10_to_linux_trusty_and_win7(self):
        # The test-win-win10 baseline is copied over to the test-linux-trusty
        # and test-win-win7 baseline paths, since both of these are "immediate
        # predecessors".
        self._write(
            self.baseline_path('platform/test-win-win10/failures/expected/image-expected.txt'),
            'original test-win-win10 result')
        self.assertFalse(self.tool.filesystem.exists(
            self.baseline_path('platform/test-linux-trusty/failures/expected/image-expected.txt')))

        self.command.execute(self.options(builder='MOCK Win10', test='failures/expected/image.html'), [], self.tool)

        self.assertEqual(
            self._read(self.baseline_path('platform/test-win-win10/failures/expected/image-expected.txt')),
            'original test-win-win10 result')
        self.assertEqual(
            self._read(self.baseline_path('platform/test-linux-trusty/failures/expected/image-expected.txt')),
            'original test-win-win10 result')
        self.assertEqual(
            self._read(self.baseline_path('platform/test-linux-trusty/failures/expected/image-expected.txt')),
            'original test-win-win10 result')

    def test_no_copy_existing_baseline(self):
        # If a baseline exists already for an "immediate prdecessor" baseline
        # directory, (e.g. test-linux-trusty), then no "immediate successor"
        # baselines (e.g. test-win-win10) are copied over.
        self._write(
            self.baseline_path('platform/test-win-win10/failures/expected/image-expected.txt'),
            'original test-win-win10 result')
        self._write(
            self.baseline_path('platform/test-linux-trusty/failures/expected/image-expected.txt'),
            'original test-linux-trusty result')

        self.command.execute(self.options(builder='MOCK Win10', test='failures/expected/image.html'), [], self.tool)

        self.assertEqual(
            self._read(self.baseline_path('platform/test-win-win10/failures/expected/image-expected.txt')),
            'original test-win-win10 result')
        self.assertEqual(
            self._read(self.baseline_path('platform/test-linux-trusty/failures/expected/image-expected.txt')),
            'original test-linux-trusty result')

    def test_no_copy_skipped_test(self):
        # If a test is skipped on some platform, no baselines are copied over
        # to that directory. In this example, the test is skipped on linux,
        # so the test-win-win10 baseline is not copied over.
        port = self.tool.port_factory.get('test-win-win10')
        self._write(
            self.baseline_path('platform/test-win-win10/failures/expected/image-expected.txt'),
            'original test-win-win10 result')
        self._write(
            port.path_to_generic_test_expectations_file(),
            ('[ Win ] failures/expected/image.html [ Failure ]\n'
             '[ Linux ] failures/expected/image.html [ Skip ]\n'))

        self.command.execute(self.options(builder='MOCK Win10', test='failures/expected/image.html'), [], self.tool)

        self.assertFalse(
            self.tool.filesystem.exists(self.baseline_path('platform/test-linux-trusty/failures/expected/image-expected.txt')))

    def test_port_for_primary_baseline(self):
        self.assertEqual(self.command._port_for_primary_baseline('test-linux-trusty').name(), 'test-linux-trusty')
        self.assertEqual(self.command._port_for_primary_baseline('test-mac-mac10.11').name(), 'test-mac-mac10.11')

    def test_port_for_primary_baseline_not_found(self):
        with self.assertRaises(Exception):
            self.command._port_for_primary_baseline('test-foo-foo4.7')


class TestRebaselineTest(BaseTestCase):
    command_constructor = RebaselineTest  # AKA webkit-patch rebaseline-test-internal

    def setUp(self):
        super(TestRebaselineTest, self).setUp()

    @staticmethod
    def options(**kwargs):
        return optparse.Values(dict({
            'builder': 'MOCK Mac10.11',
            'test': 'userscripts/another-test.html',
            'suffixes': 'txt',
            'results_directory': None,
            'build_number': None
        }, **kwargs))

    def test_baseline_directory(self):
        command = self.command
        self.assertMultiLineEqual(command._baseline_directory('MOCK Mac10.11'),
                                  '/test.checkout/LayoutTests/platform/test-mac-mac10.11')
        self.assertMultiLineEqual(command._baseline_directory('MOCK Mac10.10'),
                                  '/test.checkout/LayoutTests/platform/test-mac-mac10.10')
        self.assertMultiLineEqual(command._baseline_directory('MOCK Trusty'),
                                  '/test.checkout/LayoutTests/platform/test-linux-trusty')
        self.assertMultiLineEqual(command._baseline_directory('MOCK Precise'),
                                  '/test.checkout/LayoutTests/platform/test-linux-precise')

    def test_rebaseline_updates_expectations_file_noop(self):
        self._zero_out_test_expectations()
        self._write(
            self.mac_expectations_path,
            ('Bug(B) [ Mac Linux Win7 Debug ] fast/dom/Window/window-postmessage-clone-really-deep-array.html [ Pass ]\n'
             'Bug(A) [ Debug ] : fast/css/large-list-of-rules-crash.html [ Failure ]\n'))
        self._write('fast/dom/Window/window-postmessage-clone-really-deep-array.html', 'Dummy test contents')
        self._write('fast/css/large-list-of-rules-crash.html', 'Dummy test contents')
        self._write('userscripts/another-test.html', 'Dummy test contents')

        self.command._rebaseline_test_and_update_expectations(self.options(suffixes='png,wav,txt'))

        self.assertItemsEqual(self.tool.web.urls_fetched,
                              [self.WEB_PREFIX + '/userscripts/another-test-actual.png',
                               self.WEB_PREFIX + '/userscripts/another-test-actual.wav',
                               self.WEB_PREFIX + '/userscripts/another-test-actual.txt'])
        new_expectations = self._read(self.mac_expectations_path)
        self.assertMultiLineEqual(
            new_expectations,
            ('Bug(B) [ Mac Linux Win7 Debug ] fast/dom/Window/window-postmessage-clone-really-deep-array.html [ Pass ]\n'
             'Bug(A) [ Debug ] : fast/css/large-list-of-rules-crash.html [ Failure ]\n'))

    def test_rebaseline_test(self):
        self.command._rebaseline_test('MOCK Trusty', 'userscripts/another-test.html', 'txt', self.WEB_PREFIX)
        self.assertItemsEqual(self.tool.web.urls_fetched, [self.WEB_PREFIX + '/userscripts/another-test-actual.txt'])

    def test_rebaseline_test_with_results_directory(self):
        self._write('userscripts/another-test.html', 'test data')
        self._write(
            self.mac_expectations_path,
            ('Bug(x) [ Mac ] userscripts/another-test.html [ Failure ]\n'
             'bug(z) [ Linux ] userscripts/another-test.html [ Failure ]\n'))
        self.command._rebaseline_test_and_update_expectations(self.options(results_directory='/tmp'))
        self.assertItemsEqual(self.tool.web.urls_fetched, ['file:///tmp/userscripts/another-test-actual.txt'])

    def test_rebaseline_reftest(self):
        self._write('userscripts/another-test.html', 'test data')
        self._write('userscripts/another-test-expected.html', 'generic result')
        OutputCapture().assert_outputs(
            self, self.command._rebaseline_test_and_update_expectations, args=[self.options(suffixes='png')],
            expected_logs='Cannot rebaseline image result for reftest: userscripts/another-test.html\n')
        self.assertDictEqual(self.command.expectation_line_changes.to_dict(), {'remove-lines': []})

    def test_rebaseline_test_internal_with_port_that_lacks_buildbot(self):
        self.tool.executive = MockExecutive()

        port = self.tool.port_factory.get('test-win-win7')
        self._write(
            port.host.filesystem.join(
                port.layout_tests_dir(),
                'platform/test-win-win10/failures/expected/image-expected.txt'),
            'original win10 result')

        oc = OutputCapture()
        try:
            options = optparse.Values({
                'optimize': True,
                'builder': 'MOCK Win10',
                'suffixes': 'txt',
                'verbose': True,
                'test': 'failures/expected/image.html',
                'results_directory': None,
                'build_number': None
            })
            oc.capture_output()
            self.command.execute(options, [], self.tool)
        finally:
            out, _, _ = oc.restore_output()

        self.assertMultiLineEqual(
            self._read(self.tool.filesystem.join(
                port.layout_tests_dir(),
                'platform/test-win-win10/failures/expected/image-expected.txt')),
            'MOCK Web result, convert 404 to None=True')
        self.assertFalse(self.tool.filesystem.exists(self.tool.filesystem.join(
            port.layout_tests_dir(), 'platform/test-win-win7/failures/expected/image-expected.txt')))
        self.assertMultiLineEqual(
            out, '{"remove-lines": [{"test": "failures/expected/image.html", "builder": "MOCK Win10"}]}\n')


class TestAbstractParallelRebaselineCommand(BaseTestCase):
    command_constructor = AbstractParallelRebaselineCommand

    def test_builders_to_fetch_from(self):
        builders_to_fetch = self.command._builders_to_fetch_from(
            ['MOCK Win10', 'MOCK Win7 (dbg)(1)', 'MOCK Win7 (dbg)(2)', 'MOCK Win7'])
        self.assertEqual(builders_to_fetch, ['MOCK Win7', 'MOCK Win10'])

    def test_all_baseline_paths(self):
        test_prefix_list = {
            'passes/text.html': {
                Build('MOCK Win7'): ('txt', 'png'),
                Build('MOCK Win10'): ('txt',),
            }
        }
        # pylint: disable=protected-access
        baseline_paths = self.command._all_baseline_paths(test_prefix_list)
        self.assertEqual(baseline_paths, [
            '/test.checkout/LayoutTests/passes/text-expected.png',
            '/test.checkout/LayoutTests/passes/text-expected.txt',
            '/test.checkout/LayoutTests/platform/test-win-win10/passes/text-expected.txt',
            '/test.checkout/LayoutTests/platform/test-win-win7/passes/text-expected.png',
            '/test.checkout/LayoutTests/platform/test-win-win7/passes/text-expected.txt',
        ])

    def test_remove_all_pass_testharness_baselines(self):
        self.tool.filesystem.write_text_file(
            '/test.checkout/LayoutTests/passes/text-expected.txt',
            ('This is a testharness.js-based test.\n'
             'PASS: foo\n'
             'Harness: the test ran to completion.\n'))
        test_prefix_list = {
            'passes/text.html': {
                Build('MOCK Win7'): ('txt', 'png'),
                Build('MOCK Win10'): ('txt',),
            }
        }
        self.command._remove_all_pass_testharness_baselines(test_prefix_list)
        self.assertFalse(self.tool.filesystem.exists(
            '/test.checkout/LayoutTests/passes/text-expected.txt'))


class TestRebaselineJson(BaseTestCase):
    command_constructor = RebaselineJson

    def setUp(self):
        super(TestRebaselineJson, self).setUp()
        self.tool.executive = MockExecutive()

    def tearDown(self):
        super(TestRebaselineJson, self).tearDown()

    @staticmethod
    def options(**kwargs):
        return optparse.Values(dict({
            'optimize': True,
            'verbose': True,
            'results_directory': None
        }, **kwargs))

    def test_rebaseline_test_passes_on_all_builders(self):
        self._setup_mock_build_data()

        self.tool.buildbot.set_results(Build('MOCK Win7'), LayoutTestResults({
            'tests': {
                'userscripts': {
                    'first-test.html': {
                        'expected': 'NEEDSREBASELINE',
                        'actual': 'PASS'
                    }
                }
            }
        }))

        self._write(self.mac_expectations_path, 'Bug(x) userscripts/first-test.html [ Failure ]\n')
        self._write('userscripts/first-test.html', 'Dummy test contents')
        self.command.rebaseline(self.options(), {'userscripts/first-test.html': {Build('MOCK Win7'): ['txt', 'png']}})

        self.assertEqual(self.tool.executive.calls, [])

    def test_rebaseline_all(self):
        self._setup_mock_build_data()

        self._write('userscripts/first-test.html', 'Dummy test contents')
        self.command.rebaseline(self.options(), {'userscripts/first-test.html': {Build('MOCK Win7'): ['txt', 'png']}})

        # Note that we have one run_in_parallel() call followed by a run_command()
        self.assertEqual(
            self.tool.executive.calls,
            [
                [['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'txt,png',
                  '--builder', 'MOCK Win7', '--test', 'userscripts/first-test.html', '--verbose']],
                [['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'txt,png',
                  '--builder', 'MOCK Win7', '--test', 'userscripts/first-test.html', '--verbose']],
                [['python', 'echo', 'optimize-baselines', '--suffixes', 'txt,png',
                  'userscripts/first-test.html', '--verbose']]
            ])

    def test_rebaseline_debug(self):
        self._setup_mock_build_data()

        self._write('userscripts/first-test.html', 'Dummy test contents')
        self.command.rebaseline(self.options(), {'userscripts/first-test.html': {Build('MOCK Win7 (dbg)'): ['txt', 'png']}})

        # Note that we have one run_in_parallel() call followed by a run_command()
        self.assertEqual(
            self.tool.executive.calls,
            [
                [['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'txt,png',
                  '--builder', 'MOCK Win7 (dbg)', '--test', 'userscripts/first-test.html', '--verbose']],
                [['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'txt,png', '--builder',
                  'MOCK Win7 (dbg)', '--test', 'userscripts/first-test.html', '--verbose']],
                [['python', 'echo', 'optimize-baselines', '--suffixes', 'txt,png',
                  'userscripts/first-test.html', '--verbose']]
            ])

    def test_no_optimize(self):
        self._setup_mock_build_data()
        self._write('userscripts/first-test.html', 'Dummy test contents')
        self.command.rebaseline(
            self.options(optimize=False),
            {'userscripts/first-test.html': {Build('MOCK Win7'): ['txt', 'png']}})

        # Note that we have only one run_in_parallel() call
        self.assertEqual(
            self.tool.executive.calls,
            [
                [['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'txt,png',
                  '--builder', 'MOCK Win7', '--test', 'userscripts/first-test.html', '--verbose']],
                [['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'txt,png',
                  '--builder', 'MOCK Win7', '--test', 'userscripts/first-test.html', '--verbose']]
            ])

    def test_results_directory(self):
        self._setup_mock_build_data()
        self._write('userscripts/first-test.html', 'Dummy test contents')
        self.command.rebaseline(
            self.options(optimize=False, results_directory='/tmp'),
            {'userscripts/first-test.html': {Build('MOCK Win7'): ['txt', 'png']}})

        # Note that we have only one run_in_parallel() call
        self.assertEqual(
            self.tool.executive.calls,
            [
                [['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'txt,png',
                  '--builder', 'MOCK Win7', '--test', 'userscripts/first-test.html', '--verbose']],
                [['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'txt,png',
                  '--builder', 'MOCK Win7', '--test', 'userscripts/first-test.html', '--verbose', '--results-directory', '/tmp']]
            ])

    def test_unstaged_baselines(self):
        git = self.tool.git()
        git.unstaged_changes = lambda: {
            'third_party/WebKit/LayoutTests/x/foo-expected.txt': 'M',
            'third_party/WebKit/LayoutTests/x/foo-expected.something': '?',
            'third_party/WebKit/LayoutTests/x/foo-expected.png': '?',
            'third_party/WebKit/LayoutTests/x/foo.html': 'M',
            'docs/something.md': '?',
        }
        self.assertEqual(
            self.command.unstaged_baselines(),
            [
                '/mock-checkout/third_party/WebKit/LayoutTests/x/foo-expected.png',
                '/mock-checkout/third_party/WebKit/LayoutTests/x/foo-expected.txt',
            ])


class TestRebaselineJsonUpdatesExpectationsFiles(BaseTestCase):
    command_constructor = RebaselineJson

    def setUp(self):
        super(TestRebaselineJsonUpdatesExpectationsFiles, self).setUp()
        self.tool.executive = MockExecutive()

        def mock_run_command(*args, **kwargs):  # pylint: disable=unused-argument
            return '{"add": [], "remove-lines": [{"test": "userscripts/first-test.html", "builder": "MOCK Mac10.11"}]}\n'
        self.tool.executive.run_command = mock_run_command

    @staticmethod
    def options():
        return optparse.Values({
            'optimize': False,
            'verbose': True,
            'results_directory': None
        })

    def test_rebaseline_updates_expectations_file(self):
        self._write(
            self.mac_expectations_path,
            ('Bug(x) [ Mac ] userscripts/first-test.html [ Failure ]\n'
             'bug(z) [ Linux ] userscripts/first-test.html [ Failure ]\n'))
        self._write('userscripts/first-test.html', 'Dummy test contents')
        self._setup_mock_build_data()

        self.command.rebaseline(
            self.options(),
            {'userscripts/first-test.html': {Build('MOCK Mac10.11'): ['txt', 'png']}})

        new_expectations = self._read(self.mac_expectations_path)
        self.assertMultiLineEqual(
            new_expectations,
            ('Bug(x) [ Mac10.10 ] userscripts/first-test.html [ Failure ]\n'
             'bug(z) [ Linux ] userscripts/first-test.html [ Failure ]\n'))

    def test_rebaseline_updates_expectations_file_all_platforms(self):
        self._write(self.mac_expectations_path, 'Bug(x) userscripts/first-test.html [ Failure ]\n')
        self._write('userscripts/first-test.html', 'Dummy test contents')
        self._setup_mock_build_data()
        self.command.rebaseline(
            self.options(),
            {'userscripts/first-test.html': {Build('MOCK Mac10.11'): ['txt', 'png']}})
        new_expectations = self._read(self.mac_expectations_path)
        self.assertMultiLineEqual(
            new_expectations, 'Bug(x) [ Linux Mac10.10 Win ] userscripts/first-test.html [ Failure ]\n')

    def test_rebaseline_handles_platform_skips(self):
        # This test is just like test_rebaseline_updates_expectations_file_all_platforms(),
        # except that if a particular port happens to SKIP a test in an overrides file,
        # we count that as passing, and do not think that we still need to rebaseline it.
        self._write(self.mac_expectations_path, 'Bug(x) userscripts/first-test.html [ Failure ]\n')
        self._write('NeverFixTests', 'Bug(y) [ Android ] userscripts [ WontFix ]\n')
        self._write('userscripts/first-test.html', 'Dummy test contents')
        self._setup_mock_build_data()

        self.command.rebaseline(
            self.options(),
            {'userscripts/first-test.html': {Build('MOCK Mac10.11'): ['txt', 'png']}})

        new_expectations = self._read(self.mac_expectations_path)
        self.assertMultiLineEqual(
            new_expectations, 'Bug(x) [ Linux Mac10.10 Win ] userscripts/first-test.html [ Failure ]\n')

    def test_rebaseline_handles_skips_in_file(self):
        # This test is like test_Rebaseline_handles_platform_skips, except that the
        # Skip is in the same (generic) file rather than a platform file. In this case,
        # the Skip line should be left unmodified. Note that the first line is now
        # qualified as "[Linux Mac Win]"; if it was unqualified, it would conflict with
        # the second line.
        self._write(self.mac_expectations_path,
                    ('Bug(x) [ Linux Mac Win ] userscripts/first-test.html [ Failure ]\n'
                     'Bug(y) [ Android ] userscripts/first-test.html [ Skip ]\n'))
        self._write('userscripts/first-test.html', 'Dummy test contents')
        self._setup_mock_build_data()

        self.command.rebaseline(
            self.options(),
            {'userscripts/first-test.html': {Build('MOCK Mac10.11'): ['txt', 'png']}})

        new_expectations = self._read(self.mac_expectations_path)
        self.assertMultiLineEqual(
            new_expectations,
            ('Bug(x) [ Linux Mac10.10 Win ] userscripts/first-test.html [ Failure ]\n'
             'Bug(y) [ Android ] userscripts/first-test.html [ Skip ]\n'))

    def test_rebaseline_handles_smoke_tests(self):
        # This test is just like test_rebaseline_handles_platform_skips, except that we check for
        # a test not being in the SmokeTests file, instead of using overrides files.
        # If a test is not part of the smoke tests, we count that as passing on ports that only
        # run smoke tests, and do not think that we still need to rebaseline it.
        self._write(self.mac_expectations_path, 'Bug(x) userscripts/first-test.html [ Failure ]\n')
        self._write('SmokeTests', 'fast/html/article-element.html')
        self._write('userscripts/first-test.html', 'Dummy test contents')
        self._setup_mock_build_data()

        self.command.rebaseline(
            self.options(),
            {'userscripts/first-test.html': {Build('MOCK Mac10.11'): ['txt', 'png']}})

        new_expectations = self._read(self.mac_expectations_path)
        self.assertMultiLineEqual(
            new_expectations, 'Bug(x) [ Linux Mac10.10 Win ] userscripts/first-test.html [ Failure ]\n')


class TestRebaseline(BaseTestCase):
    # This command shares most of its logic with RebaselineJson, so these tests just test what is different.

    command_constructor = Rebaseline  # AKA webkit-patch rebaseline

    def test_rebaseline(self):
        self.command._builders_to_pull_from = lambda: ['MOCK Win7']

        self._write('userscripts/first-test.html', 'test data')

        self._zero_out_test_expectations()
        self._setup_mock_build_data()
        options = optparse.Values({
            'results_directory': False,
            'optimize': False,
            'builders': None,
            'suffixes': 'txt,png',
            'verbose': True
        })
        self.command.execute(options, ['userscripts/first-test.html'], self.tool)

        self.assertEqual(
            self.tool.executive.calls,
            [
                [['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'txt,png',
                  '--builder', 'MOCK Win7', '--test', 'userscripts/first-test.html', '--verbose']],
                [['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'txt,png',
                  '--builder', 'MOCK Win7', '--test', 'userscripts/first-test.html', '--verbose']]
            ])

    def test_rebaseline_directory(self):
        self.command._builders_to_pull_from = lambda: ['MOCK Win7']

        self._write('userscripts/first-test.html', 'test data')
        self._write('userscripts/second-test.html', 'test data')

        self._setup_mock_build_data()
        options = optparse.Values({
            'results_directory': False,
            'optimize': False,
            'builders': None,
            'suffixes': 'txt,png',
            'verbose': True
        })
        self.command.execute(options, ['userscripts'], self.tool)

        self.assertEqual(
            self.tool.executive.calls,
            [
                [
                    ['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'txt,png',
                     '--builder', 'MOCK Win7', '--test', 'userscripts/first-test.html', '--verbose'],
                    ['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'txt,png',
                     '--builder', 'MOCK Win7', '--test', 'userscripts/second-test.html', '--verbose']
                ],
                [
                    ['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'txt,png',
                     '--builder', 'MOCK Win7', '--test', 'userscripts/first-test.html', '--verbose'],
                    ['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'txt,png',
                     '--builder', 'MOCK Win7', '--test', 'userscripts/second-test.html', '--verbose']
                ]
            ])


class TestRebaselineExpectations(BaseTestCase):
    command_constructor = RebaselineExpectations

    def setUp(self):
        super(TestRebaselineExpectations, self).setUp()

    @staticmethod
    def options():
        return optparse.Values({
            'optimize': False,
            'builders': None,
            'suffixes': ['txt'],
            'verbose': False,
            'platform': None,
            'results_directory': None
        })

    def _write_test_file(self, port, path, contents):
        abs_path = self.tool.filesystem.join(port.layout_tests_dir(), path)
        self.tool.filesystem.write_text_file(abs_path, contents)

    def test_rebaseline_expectations(self):
        self._zero_out_test_expectations()

        self.tool.executive = MockExecutive()

        for builder in ['MOCK Mac10.10', 'MOCK Mac10.11']:
            self.tool.buildbot.set_results(Build(builder), LayoutTestResults({
                'tests': {
                    'userscripts': {
                        'another-test.html': {
                            'expected': 'PASS',
                            'actual': 'PASS TEXT'
                        },
                        'images.svg': {
                            'expected': 'FAIL',
                            'actual': 'IMAGE+TEXT'
                        }
                    }
                }
            }))

        self._write('userscripts/another-test.html', 'Dummy test contents')
        self._write('userscripts/images.svg', 'Dummy test contents')
        self.command._tests_to_rebaseline = lambda port: {
            'userscripts/another-test.html': set(['txt']),
            'userscripts/images.svg': set(['png']),
            'userscripts/not-actually-failing.html': set(['txt', 'png', 'wav']),
        }

        self.command.execute(self.options(), [], self.tool)

        self.assertEqual(self.tool.executive.calls, [
            [
                ['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'txt',
                 '--builder', 'MOCK Mac10.10', '--test', 'userscripts/another-test.html'],
                ['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'txt',
                 '--builder', 'MOCK Mac10.11', '--test', 'userscripts/another-test.html'],
                ['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'png',
                 '--builder', 'MOCK Mac10.10', '--test', 'userscripts/images.svg'],
                ['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'png',
                 '--builder', 'MOCK Mac10.11', '--test', 'userscripts/images.svg'],
            ],
            [
                ['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'txt',
                 '--builder', 'MOCK Mac10.10', '--test', 'userscripts/another-test.html'],
                ['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'txt',
                 '--builder', 'MOCK Mac10.11', '--test', 'userscripts/another-test.html'],
                ['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'png',
                 '--builder', 'MOCK Mac10.10', '--test', 'userscripts/images.svg'],
                ['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'png',
                 '--builder', 'MOCK Mac10.11', '--test', 'userscripts/images.svg'],
            ],
        ])

    def test_rebaseline_expectations_reftests(self):
        self._zero_out_test_expectations()

        self.tool.executive = MockExecutive()

        for builder in ['MOCK Mac10.10', 'MOCK Mac10.11']:
            self.tool.buildbot.set_results(Build(builder), LayoutTestResults({
                'tests': {
                    'userscripts': {
                        'reftest-text.html': {
                            'expected': 'PASS',
                            'actual': 'TEXT'
                        },
                        'reftest-image.html': {
                            'expected': 'FAIL',
                            'actual': 'IMAGE'
                        },
                        'reftest-image-text.html': {
                            'expected': 'FAIL',
                            'actual': 'IMAGE+TEXT'
                        }
                    }
                }
            }))

        self._write('userscripts/reftest-text.html', 'Dummy test contents')
        self._write('userscripts/reftest-text-expected.html', 'Dummy test contents')
        self._write('userscripts/reftest-text-expected.html', 'Dummy test contents')
        self.command._tests_to_rebaseline = lambda port: {
            'userscripts/reftest-text.html': set(['txt']),
            'userscripts/reftest-image.html': set(['png']),
            'userscripts/reftest-image-text.html': set(['png', 'txt']),
        }

        self.command.execute(self.options(), [], self.tool)

        self.assertEqual(self.tool.executive.calls, [
            [
                ['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'txt',
                 '--builder', 'MOCK Mac10.10', '--test', 'userscripts/reftest-text.html'],
                ['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'txt',
                 '--builder', 'MOCK Mac10.11', '--test', 'userscripts/reftest-text.html'],
            ],
            [
                ['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'txt',
                 '--builder', 'MOCK Mac10.10', '--test', 'userscripts/reftest-text.html'],
                ['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'txt',
                 '--builder', 'MOCK Mac10.11', '--test', 'userscripts/reftest-text.html'],
            ],
        ])

    def test_rebaseline_expectations_noop(self):
        self._zero_out_test_expectations()

        oc = OutputCapture()
        try:
            oc.capture_output()
            self.command.execute(self.options(), [], self.tool)
        finally:
            _, _, logs = oc.restore_output()
            self.assertEqual(self.tool.filesystem.written_files, {})
            self.assertEqual(logs, 'Did not find any tests marked Rebaseline.\n')

    def disabled_test_overrides_are_included_correctly(self):
        # TODO(qyearsley): Fix or remove this test method.
        # This tests that any tests marked as REBASELINE in the overrides are found, but
        # that the overrides do not get written into the main file.
        self._zero_out_test_expectations()

        self._write(self.mac_expectations_path, '')
        self.mac_port.expectations_dict = lambda: {
            self.mac_expectations_path: '',
            'overrides': ('Bug(x) userscripts/another-test.html [ Failure Rebaseline ]\n'
                          'Bug(y) userscripts/test.html [ Crash ]\n')}
        self._write('/userscripts/another-test.html', '')

        self.assertDictEqual(self.command._tests_to_rebaseline(self.mac_port),
                             {'userscripts/another-test.html': set(['png', 'txt', 'wav'])})
        self.assertEqual(self._read(self.mac_expectations_path), '')

    def test_rebaseline_without_other_expectations(self):
        self._write('userscripts/another-test.html', 'Dummy test contents')
        self._write(self.mac_expectations_path, 'Bug(x) userscripts/another-test.html [ Rebaseline ]\n')
        self.assertDictEqual(self.command._tests_to_rebaseline(self.mac_port),
                             {'userscripts/another-test.html': ('png', 'wav', 'txt')})

    def test_rebaseline_test_passes_everywhere(self):
        test_port = self.tool.port_factory.get('test')

        for builder in ['MOCK Mac10.10', 'MOCK Mac10.11']:
            self.tool.buildbot.set_results(Build(builder), LayoutTestResults({
                'tests': {
                    'fast': {
                        'dom': {
                            'prototype-taco.html': {
                                'expected': 'FAIL',
                                'actual': 'PASS',
                                'is_unexpected': True
                            }
                        }
                    }
                }
            }))

        self.tool.filesystem.write_text_file(test_port.path_to_generic_test_expectations_file(), """
Bug(foo) fast/dom/prototype-taco.html [ Rebaseline ]
""")

        self._write_test_file(test_port, 'fast/dom/prototype-taco.html', 'Dummy test contents')

        self.tool.executive = MockLineRemovingExecutive()

        self.tool.builders = BuilderList({
            'MOCK Mac10.10': {'port_name': 'test-mac-mac10.10', 'specifiers': ['Mac10.10', 'Release']},
            'MOCK Mac10.11': {'port_name': 'test-mac-mac10.11', 'specifiers': ['Mac10.11', 'Release']},
        })

        self.command.execute(self.options(), [], self.tool)
        self.assertEqual(self.tool.executive.calls, [])

        # The mac ports should both be removed since they're the only ones in the builder list.
        self.assertEqual(self.tool.filesystem.read_text_file(test_port.path_to_generic_test_expectations_file()), """
Bug(foo) [ Linux Win ] fast/dom/prototype-taco.html [ Rebaseline ]
""")

    def test_rebaseline_missing(self):
        self.tool.buildbot.set_results(Build('MOCK Mac10.10'), LayoutTestResults({
            'tests': {
                'fast': {
                    'dom': {
                        'missing-text.html': {
                            'expected': 'PASS',
                            'actual': 'MISSING',
                            'is_unexpected': True,
                            'is_missing_text': True
                        },
                        'missing-text-and-image.html': {
                            'expected': 'PASS',
                            'actual': 'MISSING',
                            'is_unexpected': True,
                            'is_missing_text': True,
                            'is_missing_image': True
                        },
                        'missing-image.html': {
                            'expected': 'PASS',
                            'actual': 'MISSING',
                            'is_unexpected': True,
                            'is_missing_image': True
                        }
                    }
                }
            }
        }))

        self._write('fast/dom/missing-text.html', 'Dummy test contents')
        self._write('fast/dom/missing-text-and-image.html', 'Dummy test contents')
        self._write('fast/dom/missing-image.html', 'Dummy test contents')

        self.command._tests_to_rebaseline = lambda port: {
            'fast/dom/missing-text.html': set(['txt', 'png']),
            'fast/dom/missing-text-and-image.html': set(['txt', 'png']),
            'fast/dom/missing-image.html': set(['txt', 'png']),
        }

        self.command.execute(self.options(), [], self.tool)

        self.assertEqual(self.tool.executive.calls, [
            [
                ['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'txt',
                 '--builder', 'MOCK Mac10.10', '--test', 'fast/dom/missing-text.html'],
                ['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'txt,png',
                 '--builder', 'MOCK Mac10.10', '--test', 'fast/dom/missing-text-and-image.html'],
                ['python', 'echo', 'copy-existing-baselines-internal', '--suffixes', 'png',
                 '--builder', 'MOCK Mac10.10', '--test', 'fast/dom/missing-image.html'],
            ],
            [
                ['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'txt',
                 '--builder', 'MOCK Mac10.10', '--test', 'fast/dom/missing-text.html'],
                ['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'txt,png',
                 '--builder', 'MOCK Mac10.10', '--test', 'fast/dom/missing-text-and-image.html'],
                ['python', 'echo', 'rebaseline-test-internal', '--suffixes', 'png',
                 '--builder', 'MOCK Mac10.10', '--test', 'fast/dom/missing-image.html'],
            ]
        ])


class MockLineRemovingExecutive(MockExecutive):

    def run_in_parallel(self, commands):
        assert len(commands)

        num_previous_calls = len(self.calls)
        command_outputs = []
        for cmd_line, cwd in commands:
            out = self.run_command(cmd_line, cwd=cwd)
            if 'rebaseline-test-internal' in cmd_line:
                out = '{"remove-lines": [{"test": "%s", "builder": "%s"}]}\n' % (cmd_line[8], cmd_line[6])
            command_outputs.append([0, out, ''])

        new_calls = self.calls[num_previous_calls:]
        self.calls = self.calls[:num_previous_calls]
        self.calls.append(new_calls)
        return command_outputs
