blob: 7c1320d5a653f49673c7a257098b70a76a56c23d [file] [log] [blame]
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +00001# Copyright (C) 2010 Google Inc. All rights reserved.
2#
3# Redistribution and use in source and binary forms, with or without
4# modification, are permitted provided that the following conditions are
5# met:
6#
7# * Redistributions of source code must retain the above copyright
8# notice, this list of conditions and the following disclaimer.
9# * Redistributions in binary form must reproduce the above
10# copyright notice, this list of conditions and the following disclaimer
11# in the documentation and/or other materials provided with the
12# distribution.
13# * Neither the name of Google Inc. nor the names of its
14# contributors may be used to endorse or promote products derived from
15# this software without specific prior written permission.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
Torne (Richard Coles)926b0012013-03-28 15:32:48 +000029import unittest2 as unittest
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +000030
31from webkitpy.common.system.outputcapture import OutputCapture
32from webkitpy.common.checkout.baselineoptimizer import BaselineOptimizer
33from webkitpy.common.net.buildbot.buildbot_mock import MockBuilder
34from webkitpy.common.system.executive_mock import MockExecutive2
35from webkitpy.thirdparty.mock import Mock
36from webkitpy.tool.commands.rebaseline import *
37from webkitpy.tool.mocktool import MockTool, MockOptions
38
39
40class _BaseTestCase(unittest.TestCase):
41 MOCK_WEB_RESULT = 'MOCK Web result, convert 404 to None=True'
42 WEB_PREFIX = 'http://example.com/f/builders/WebKit Mac10.7/results/layout-test-results'
43
44 command_constructor = None
45
46 def setUp(self):
47 self.tool = MockTool()
Torne (Richard Coles)926b0012013-03-28 15:32:48 +000048 self.command = self.command_constructor() # lint warns that command_constructor might not be set, but this is intentional; pylint: disable=E1102
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +000049 self.command.bind_to_tool(self.tool)
50 self.lion_port = self.tool.port_factory.get_from_builder_name("WebKit Mac10.7")
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010051 self.lion_expectations_path = self.lion_port.path_to_generic_test_expectations_file()
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +000052
53 # FIXME: we should override builders._exact_matches here to point to a set
54 # of test ports and restore the value in tearDown(), and that way the
55 # individual tests wouldn't have to worry about it.
56
57 def _expand(self, path):
58 if self.tool.filesystem.isabs(path):
59 return path
60 return self.tool.filesystem.join(self.lion_port.layout_tests_dir(), path)
61
62 def _read(self, path):
63 return self.tool.filesystem.read_text_file(self._expand(path))
64
65 def _write(self, path, contents):
66 self.tool.filesystem.write_text_file(self._expand(path), contents)
67
68 def _zero_out_test_expectations(self):
69 for port_name in self.tool.port_factory.all_port_names():
70 port = self.tool.port_factory.get(port_name)
71 for path in port.expectations_files():
72 self._write(path, '')
73 self.tool.filesystem.written_files = {}
74
75
76class TestRebaselineTest(_BaseTestCase):
77 command_constructor = RebaselineTest # AKA webkit-patch rebaseline-test-internal
78
79 def setUp(self):
80 super(TestRebaselineTest, self).setUp()
81 self.options = MockOptions(builder="WebKit Mac10.7", test="userscripts/another-test.html", suffixes="txt",
82 move_overwritten_baselines_to=None, results_directory=None)
83
84 def test_baseline_directory(self):
85 command = self.command
Torne (Richard Coles)926b0012013-03-28 15:32:48 +000086 self.assertMultiLineEqual(command._baseline_directory("WebKit Mac10.7"), "/mock-checkout/LayoutTests/platform/chromium-mac-lion")
87 self.assertMultiLineEqual(command._baseline_directory("WebKit Mac10.6"), "/mock-checkout/LayoutTests/platform/chromium-mac-snowleopard")
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +000088
89 def test_rebaseline_updates_expectations_file_noop(self):
90 self._zero_out_test_expectations()
91 self._write(self.lion_expectations_path, """Bug(B) [ Mac Linux XP Debug ] fast/dom/Window/window-postmessage-clone-really-deep-array.html [ Pass ]
92Bug(A) [ Debug ] : fast/css/large-list-of-rules-crash.html [ Failure ]
93""")
94 self._write("fast/dom/Window/window-postmessage-clone-really-deep-array.html", "Dummy test contents")
95 self._write("fast/css/large-list-of-rules-crash.html", "Dummy test contents")
96 self._write("userscripts/another-test.html", "Dummy test contents")
97
98 self.options.suffixes = "png,wav,txt"
99 self.command._rebaseline_test_and_update_expectations(self.options)
100
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000101 self.assertItemsEqual(self.tool.web.urls_fetched,
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000102 [self.WEB_PREFIX + '/userscripts/another-test-actual.png',
103 self.WEB_PREFIX + '/userscripts/another-test-actual.wav',
104 self.WEB_PREFIX + '/userscripts/another-test-actual.txt'])
105 new_expectations = self._read(self.lion_expectations_path)
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000106 self.assertMultiLineEqual(new_expectations, """Bug(B) [ Mac Linux XP Debug ] fast/dom/Window/window-postmessage-clone-really-deep-array.html [ Pass ]
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000107Bug(A) [ Debug ] : fast/css/large-list-of-rules-crash.html [ Failure ]
108""")
109
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000110 def test_rebaseline_test(self):
111 self.command._rebaseline_test("WebKit Linux", "userscripts/another-test.html", None, "txt", self.WEB_PREFIX)
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000112 self.assertItemsEqual(self.tool.web.urls_fetched, [self.WEB_PREFIX + '/userscripts/another-test-actual.txt'])
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000113
114 def test_rebaseline_test_with_results_directory(self):
Torne (Richard Coles)81a51572013-05-13 16:52:28 +0100115 self._write("userscripts/another-test.html", "test data")
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000116 self._write(self.lion_expectations_path, "Bug(x) [ Mac ] userscripts/another-test.html [ ImageOnlyFailure ]\nbug(z) [ Linux ] userscripts/another-test.html [ ImageOnlyFailure ]\n")
117 self.options.results_directory = '/tmp'
118 self.command._rebaseline_test_and_update_expectations(self.options)
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000119 self.assertItemsEqual(self.tool.web.urls_fetched, ['file:///tmp/userscripts/another-test-actual.txt'])
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000120
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100121 def test_rebaseline_reftest(self):
Torne (Richard Coles)81a51572013-05-13 16:52:28 +0100122 self._write("userscripts/another-test.html", "test data")
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100123 self._write("userscripts/another-test-expected.html", "generic result")
124 OutputCapture().assert_outputs(self, self.command._rebaseline_test_and_update_expectations, args=[self.options],
125 expected_logs="Cannot rebaseline reftest: userscripts/another-test.html\n")
Torne (Richard Coles)81a51572013-05-13 16:52:28 +0100126 self.assertDictEqual(self.command._scm_changes, {'add': [], 'remove-lines': []})
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100127
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000128 def test_rebaseline_test_and_print_scm_changes(self):
129 self.command._print_scm_changes = True
130 self.command._scm_changes = {'add': [], 'delete': []}
131 self.tool._scm.exists = lambda x: False
132
133 self.command._rebaseline_test("WebKit Linux", "userscripts/another-test.html", None, "txt", None)
134
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000135 self.assertDictEqual(self.command._scm_changes, {'add': ['/mock-checkout/LayoutTests/platform/chromium-linux/userscripts/another-test-expected.txt'], 'delete': []})
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000136
137 def test_rebaseline_and_copy_test(self):
138 self._write("userscripts/another-test-expected.txt", "generic result")
139
140 self.command._rebaseline_test("WebKit Mac10.7", "userscripts/another-test.html", ["chromium-mac-snowleopard"], "txt", None)
141
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000142 self.assertMultiLineEqual(self._read('platform/chromium-mac-lion/userscripts/another-test-expected.txt'), self.MOCK_WEB_RESULT)
143 self.assertMultiLineEqual(self._read('platform/chromium-mac-snowleopard/userscripts/another-test-expected.txt'), 'generic result')
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000144
145 def test_rebaseline_and_copy_test_no_existing_result(self):
146 self.command._rebaseline_test("WebKit Mac10.7", "userscripts/another-test.html", ["chromium-mac-snowleopard"], "txt", None)
147
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000148 self.assertMultiLineEqual(self._read('platform/chromium-mac-lion/userscripts/another-test-expected.txt'), self.MOCK_WEB_RESULT)
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000149 self.assertFalse(self.tool.filesystem.exists(self._expand('platform/chromium-mac-snowleopard/userscripts/another-test-expected.txt')))
150
151 def test_rebaseline_and_copy_test_with_lion_result(self):
152 self._write("platform/chromium-mac-lion/userscripts/another-test-expected.txt", "original lion result")
153
154 self.command._rebaseline_test("WebKit Mac10.7", "userscripts/another-test.html", ["chromium-mac-snowleopard"], "txt", self.WEB_PREFIX)
155
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000156 self.assertItemsEqual(self.tool.web.urls_fetched, [self.WEB_PREFIX + '/userscripts/another-test-actual.txt'])
157 self.assertMultiLineEqual(self._read("platform/chromium-mac-snowleopard/userscripts/another-test-expected.txt"), "original lion result")
158 self.assertMultiLineEqual(self._read("platform/chromium-mac-lion/userscripts/another-test-expected.txt"), self.MOCK_WEB_RESULT)
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000159
160 def test_rebaseline_and_copy_no_overwrite_test(self):
161 self._write("platform/chromium-mac-lion/userscripts/another-test-expected.txt", "original lion result")
162 self._write("platform/chromium-mac-snowleopard/userscripts/another-test-expected.txt", "original snowleopard result")
163
164 self.command._rebaseline_test("WebKit Mac10.7", "userscripts/another-test.html", ["chromium-mac-snowleopard"], "txt", None)
165
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000166 self.assertMultiLineEqual(self._read("platform/chromium-mac-snowleopard/userscripts/another-test-expected.txt"), "original snowleopard result")
167 self.assertMultiLineEqual(self._read("platform/chromium-mac-lion/userscripts/another-test-expected.txt"), self.MOCK_WEB_RESULT)
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000168
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100169 def test_rebaseline_test_internal_with_copying_overwritten_baseline_first(self):
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000170 self.tool.executive = MockExecutive2()
171
172 # FIXME: it's confusing that this is the test- port, and not the regular lion port. Really all of the tests should be using the test ports.
173 port = self.tool.port_factory.get('test-mac-snowleopard')
174 self._write(port._filesystem.join(port.layout_tests_dir(), 'platform/test-mac-snowleopard/failures/expected/image-expected.txt'), 'original snowleopard result')
175
176 old_exact_matches = builders._exact_matches
177 oc = OutputCapture()
178 try:
179 builders._exact_matches = {
180 "MOCK Leopard": {"port_name": "test-mac-leopard", "specifiers": set(["mock-specifier"])},
181 "MOCK SnowLeopard": {"port_name": "test-mac-snowleopard", "specifiers": set(["mock-specifier"])},
182 }
183
184 options = MockOptions(optimize=True, builder="MOCK SnowLeopard", suffixes="txt",
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100185 move_overwritten_baselines_to=None, verbose=True, test="failures/expected/image.html",
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000186 results_directory=None)
187
188 oc.capture_output()
189 self.command.execute(options, [], self.tool)
190 finally:
191 out, _, _ = oc.restore_output()
192 builders._exact_matches = old_exact_matches
193
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000194 self.assertMultiLineEqual(self._read(self.tool.filesystem.join(port.layout_tests_dir(), 'platform/test-mac-leopard/failures/expected/image-expected.txt')), 'original snowleopard result')
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100195 self.assertMultiLineEqual(out, '{"add": [], "remove-lines": [{"test": "failures/expected/image.html", "builder": "MOCK SnowLeopard"}]}\n')
196
197 def test_rebaseline_test_internal_with_copying_overwritten_baseline_first_to_multiple_locations(self):
198 self.tool.executive = MockExecutive2()
199
200 # FIXME: it's confusing that this is the test- port, and not the regular win port. Really all of the tests should be using the test ports.
201 port = self.tool.port_factory.get('test-win-win7')
202 self._write(port._filesystem.join(port.layout_tests_dir(), 'platform/test-win-win7/failures/expected/image-expected.txt'), 'original win7 result')
203
204 old_exact_matches = builders._exact_matches
205 oc = OutputCapture()
206 try:
207 builders._exact_matches = {
208 "MOCK Leopard": {"port_name": "test-mac-leopard", "specifiers": set(["mock-specifier"])},
209 "MOCK Linux": {"port_name": "test-linux-x86_64", "specifiers": set(["mock-specifier"])},
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100210 "MOCK Win7": {"port_name": "test-win-win7", "specifiers": set(["mock-specifier"])},
211 }
212
213 options = MockOptions(optimize=True, builder="MOCK Win7", suffixes="txt",
214 move_overwritten_baselines_to=None, verbose=True, test="failures/expected/image.html",
215 results_directory=None)
216
217 oc.capture_output()
218 self.command.execute(options, [], self.tool)
219 finally:
220 out, _, _ = oc.restore_output()
221 builders._exact_matches = old_exact_matches
222
223 self.assertMultiLineEqual(self._read(self.tool.filesystem.join(port.layout_tests_dir(), 'platform/test-linux-x86_64/failures/expected/image-expected.txt')), 'original win7 result')
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100224 self.assertFalse(self.tool.filesystem.exists(self.tool.filesystem.join(port.layout_tests_dir(), 'platform/chromium-mac-leopard/userscripts/another-test-expected.txt')))
225 self.assertMultiLineEqual(out, '{"add": [], "remove-lines": [{"test": "failures/expected/image.html", "builder": "MOCK Win7"}]}\n')
226
227 def test_rebaseline_test_internal_with_no_overwrite_existing_baseline(self):
228 self.tool.executive = MockExecutive2()
229
230 # FIXME: it's confusing that this is the test- port, and not the regular win port. Really all of the tests should be using the test ports.
231 port = self.tool.port_factory.get('test-win-win7')
232 self._write(port._filesystem.join(port.layout_tests_dir(), 'platform/test-win-win7/failures/expected/image-expected.txt'), 'original win7 result')
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100233
234 old_exact_matches = builders._exact_matches
235 oc = OutputCapture()
236 try:
237 builders._exact_matches = {
238 "MOCK Leopard": {"port_name": "test-mac-leopard", "specifiers": set(["mock-specifier"])},
239 "MOCK Linux": {"port_name": "test-linux-x86_64", "specifiers": set(["mock-specifier"])},
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100240 "MOCK Win7": {"port_name": "test-win-win7", "specifiers": set(["mock-specifier"])},
241 }
242
243 options = MockOptions(optimize=True, builder="MOCK Win7", suffixes="txt",
244 move_overwritten_baselines_to=None, verbose=True, test="failures/expected/image.html",
245 results_directory=None)
246
247 oc.capture_output()
248 self.command.execute(options, [], self.tool)
249 finally:
250 out, _, _ = oc.restore_output()
251 builders._exact_matches = old_exact_matches
252
253 self.assertMultiLineEqual(self._read(self.tool.filesystem.join(port.layout_tests_dir(), 'platform/test-linux-x86_64/failures/expected/image-expected.txt')), 'original win7 result')
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100254 self.assertMultiLineEqual(self._read(self.tool.filesystem.join(port.layout_tests_dir(), 'platform/test-win-win7/failures/expected/image-expected.txt')), 'MOCK Web result, convert 404 to None=True')
255 self.assertFalse(self.tool.filesystem.exists(self.tool.filesystem.join(port.layout_tests_dir(), 'platform/chromium-mac-leopard/userscripts/another-test-expected.txt')))
256 self.assertMultiLineEqual(out, '{"add": [], "remove-lines": [{"test": "failures/expected/image.html", "builder": "MOCK Win7"}]}\n')
257
258 def test_rebaseline_test_internal_with_port_that_lacks_buildbot(self):
259 self.tool.executive = MockExecutive2()
260
261 # FIXME: it's confusing that this is the test- port, and not the regular win port. Really all of the tests should be using the test ports.
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +0100262 port = self.tool.port_factory.get('test-win-win7')
263 self._write(port._filesystem.join(port.layout_tests_dir(), 'platform/test-win-win7/failures/expected/image-expected.txt'), 'original win7 result')
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100264
265 old_exact_matches = builders._exact_matches
266 oc = OutputCapture()
267 try:
268 builders._exact_matches = {
269 "MOCK XP": {"port_name": "test-win-xp"},
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +0100270 "MOCK Win7": {"port_name": "test-win-win7"},
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100271 }
272
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +0100273 options = MockOptions(optimize=True, builder="MOCK Win7", suffixes="txt",
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100274 move_overwritten_baselines_to=None, verbose=True, test="failures/expected/image.html",
275 results_directory=None)
276
277 oc.capture_output()
278 self.command.execute(options, [], self.tool)
279 finally:
280 out, _, _ = oc.restore_output()
281 builders._exact_matches = old_exact_matches
282
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +0100283 self.assertMultiLineEqual(self._read(self.tool.filesystem.join(port.layout_tests_dir(), 'platform/test-win-win7/failures/expected/image-expected.txt')), 'MOCK Web result, convert 404 to None=True')
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100284 self.assertFalse(self.tool.filesystem.exists(self.tool.filesystem.join(port.layout_tests_dir(), 'platform/test-win-xp/failures/expected/image-expected.txt')))
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +0100285 self.assertMultiLineEqual(out, '{"add": [], "remove-lines": [{"test": "failures/expected/image.html", "builder": "MOCK Win7"}]}\n')
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000286
287
288class TestRebaselineJson(_BaseTestCase):
289 command_constructor = RebaselineJson
290
291 def setUp(self):
292 super(TestRebaselineJson, self).setUp()
293 self.tool.executive = MockExecutive2()
294 self.old_exact_matches = builders._exact_matches
295 builders._exact_matches = {
296 "MOCK builder": {"port_name": "test-mac-snowleopard", "specifiers": set(["mock-specifier"]),
297 "move_overwritten_baselines_to": ["test-mac-leopard"]},
298 "MOCK builder (Debug)": {"port_name": "test-mac-snowleopard", "specifiers": set(["mock-specifier", "debug"])},
299 }
300
301 def tearDown(self):
302 builders._exact_matches = self.old_exact_matches
303 super(TestRebaselineJson, self).tearDown()
304
305 def test_rebaseline_all(self):
306 options = MockOptions(optimize=True, verbose=True, move_overwritten_baselines=False, results_directory=None)
Torne (Richard Coles)81a51572013-05-13 16:52:28 +0100307 self._write("user-scripts/another-test.html", "Dummy test contents")
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000308 self.command._rebaseline(options, {"user-scripts/another-test.html": {"MOCK builder": ["txt", "png"]}})
309
310 # Note that we have one run_in_parallel() call followed by a run_command()
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000311 self.assertEqual(self.tool.executive.calls,
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000312 [[['echo', 'rebaseline-test-internal', '--suffixes', 'txt,png', '--builder', 'MOCK builder', '--test', 'user-scripts/another-test.html', '--verbose']],
313 ['echo', '--verbose', 'optimize-baselines', '--suffixes', 'txt,png', 'user-scripts/another-test.html']])
314
315 def test_rebaseline_debug(self):
316 options = MockOptions(optimize=True, verbose=True, move_overwritten_baselines=False, results_directory=None)
Torne (Richard Coles)81a51572013-05-13 16:52:28 +0100317 self._write("user-scripts/another-test.html", "Dummy test contents")
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000318 self.command._rebaseline(options, {"user-scripts/another-test.html": {"MOCK builder (Debug)": ["txt", "png"]}})
319
320 # Note that we have one run_in_parallel() call followed by a run_command()
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000321 self.assertEqual(self.tool.executive.calls,
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000322 [[['echo', 'rebaseline-test-internal', '--suffixes', 'txt,png', '--builder', 'MOCK builder (Debug)', '--test', 'user-scripts/another-test.html', '--verbose']],
323 ['echo', '--verbose', 'optimize-baselines', '--suffixes', 'txt,png', 'user-scripts/another-test.html']])
324
325 def test_move_overwritten(self):
326 options = MockOptions(optimize=True, verbose=True, move_overwritten_baselines=True, results_directory=None)
Torne (Richard Coles)81a51572013-05-13 16:52:28 +0100327 self._write("user-scripts/another-test.html", "Dummy test contents")
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000328 self.command._rebaseline(options, {"user-scripts/another-test.html": {"MOCK builder": ["txt", "png"]}})
329
330 # Note that we have one run_in_parallel() call followed by a run_command()
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000331 self.assertEqual(self.tool.executive.calls,
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000332 [[['echo', 'rebaseline-test-internal', '--suffixes', 'txt,png', '--builder', 'MOCK builder', '--test', 'user-scripts/another-test.html', '--move-overwritten-baselines-to', 'test-mac-leopard', '--verbose']],
333 ['echo', '--verbose', 'optimize-baselines', '--suffixes', 'txt,png', 'user-scripts/another-test.html']])
334
335 def test_no_optimize(self):
336 options = MockOptions(optimize=False, verbose=True, move_overwritten_baselines=False, results_directory=None)
Torne (Richard Coles)81a51572013-05-13 16:52:28 +0100337 self._write("user-scripts/another-test.html", "Dummy test contents")
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000338 self.command._rebaseline(options, {"user-scripts/another-test.html": {"MOCK builder (Debug)": ["txt", "png"]}})
339
340 # Note that we have only one run_in_parallel() call
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000341 self.assertEqual(self.tool.executive.calls,
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000342 [[['echo', 'rebaseline-test-internal', '--suffixes', 'txt,png', '--builder', 'MOCK builder (Debug)', '--test', 'user-scripts/another-test.html', '--verbose']]])
343
344 def test_results_directory(self):
345 options = MockOptions(optimize=False, verbose=True, move_overwritten_baselines=False, results_directory='/tmp')
Torne (Richard Coles)81a51572013-05-13 16:52:28 +0100346 self._write("user-scripts/another-test.html", "Dummy test contents")
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000347 self.command._rebaseline(options, {"user-scripts/another-test.html": {"MOCK builder": ["txt", "png"]}})
348
349 # Note that we have only one run_in_parallel() call
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000350 self.assertEqual(self.tool.executive.calls,
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000351 [[['echo', 'rebaseline-test-internal', '--suffixes', 'txt,png', '--builder', 'MOCK builder', '--test', 'user-scripts/another-test.html', '--results-directory', '/tmp', '--verbose']]])
352
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100353class TestRebaselineJsonUpdatesExpectationsFiles(_BaseTestCase):
354 command_constructor = RebaselineJson
355
356 def setUp(self):
357 super(TestRebaselineJsonUpdatesExpectationsFiles, self).setUp()
358 self.tool.executive = MockExecutive2()
359
360 def mock_run_command(args,
361 cwd=None,
362 input=None,
363 error_handler=None,
364 return_exit_code=False,
365 return_stderr=True,
366 decode_output=False,
367 env=None):
368 return '{"add": [], "remove-lines": [{"test": "userscripts/another-test.html", "builder": "WebKit Mac10.7"}]}\n'
369 self.tool.executive.run_command = mock_run_command
370
371 def test_rebaseline_updates_expectations_file(self):
372 options = MockOptions(optimize=False, verbose=True, move_overwritten_baselines=False, results_directory=None)
373
374 self._write(self.lion_expectations_path, "Bug(x) [ Mac ] userscripts/another-test.html [ ImageOnlyFailure ]\nbug(z) [ Linux ] userscripts/another-test.html [ ImageOnlyFailure ]\n")
375 self._write("userscripts/another-test.html", "Dummy test contents")
376
377 self.command._rebaseline(options, {"userscripts/another-test.html": {"WebKit Mac10.7": ["txt", "png"]}})
378
379 new_expectations = self._read(self.lion_expectations_path)
380 self.assertMultiLineEqual(new_expectations, "Bug(x) [ MountainLion SnowLeopard ] userscripts/another-test.html [ ImageOnlyFailure ]\nbug(z) [ Linux ] userscripts/another-test.html [ ImageOnlyFailure ]\n")
381
382 def test_rebaseline_updates_expectations_file_all_platforms(self):
383 options = MockOptions(optimize=False, verbose=True, move_overwritten_baselines=False, results_directory=None)
384
385 self._write(self.lion_expectations_path, "Bug(x) userscripts/another-test.html [ ImageOnlyFailure ]\n")
386 self._write("userscripts/another-test.html", "Dummy test contents")
387
388 self.command._rebaseline(options, {"userscripts/another-test.html": {"WebKit Mac10.7": ["txt", "png"]}})
389
390 new_expectations = self._read(self.lion_expectations_path)
391 self.assertMultiLineEqual(new_expectations, "Bug(x) [ Linux MountainLion SnowLeopard Win ] userscripts/another-test.html [ ImageOnlyFailure ]\n")
392
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000393
394class TestRebaseline(_BaseTestCase):
395 # This command shares most of its logic with RebaselineJson, so these tests just test what is different.
396
397 command_constructor = Rebaseline # AKA webkit-patch rebaseline
398
399 def test_tests_to_update(self):
400 build = Mock()
401 OutputCapture().assert_outputs(self, self.command._tests_to_update, [build])
402
403 def test_rebaseline(self):
404 self.command._builders_to_pull_from = lambda: [MockBuilder('MOCK builder')]
405 self.command._tests_to_update = lambda builder: ['mock/path/to/test.html']
406
Torne (Richard Coles)81a51572013-05-13 16:52:28 +0100407 self._write("mock/path/to/test.html", "Dummy test contents")
408
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000409 self._zero_out_test_expectations()
410
411 old_exact_matches = builders._exact_matches
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000412 try:
413 builders._exact_matches = {
414 "MOCK builder": {"port_name": "test-mac-leopard", "specifiers": set(["mock-specifier"])},
415 }
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000416 self.command.execute(MockOptions(optimize=False, builders=None, suffixes="txt,png", verbose=True, move_overwritten_baselines=False), [], self.tool)
417 finally:
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000418 builders._exact_matches = old_exact_matches
419
420 calls = filter(lambda x: x != ['qmake', '-v'] and x[0] != 'perl', self.tool.executive.calls)
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000421 self.assertEqual(calls,
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000422 [[['echo', 'rebaseline-test-internal', '--suffixes', 'txt,png', '--builder', 'MOCK builder', '--test', 'mock/path/to/test.html', '--verbose']]])
423
Torne (Richard Coles)81a51572013-05-13 16:52:28 +0100424 def test_rebaseline_directory(self):
425 self.command._builders_to_pull_from = lambda: [MockBuilder('MOCK builder')]
426 self.command._tests_to_update = lambda builder: ['userscripts']
427
428 self._write("userscripts/first-test.html", "test data")
429 self._write("userscripts/second-test.html", "test data")
430
431 old_exact_matches = builders._exact_matches
432 try:
433 builders._exact_matches = {
434 "MOCK builder": {"port_name": "test-mac-leopard", "specifiers": set(["mock-specifier"])},
435 }
436 self.command.execute(MockOptions(optimize=False, builders=None, suffixes="txt,png", verbose=True, move_overwritten_baselines=False), [], self.tool)
437 finally:
438 builders._exact_matches = old_exact_matches
439
440 calls = filter(lambda x: x != ['qmake', '-v'] and x[0] != 'perl', self.tool.executive.calls)
441 self.assertEqual(calls,
442 [[['echo', 'rebaseline-test-internal', '--suffixes', 'txt,png', '--builder', 'MOCK builder', '--test', 'userscripts/first-test.html', '--verbose'],
443 ['echo', 'rebaseline-test-internal', '--suffixes', 'txt,png', '--builder', 'MOCK builder', '--test', 'userscripts/second-test.html', '--verbose']]])
444
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000445
446class TestRebaselineExpectations(_BaseTestCase):
447 command_constructor = RebaselineExpectations
448
449 def setUp(self):
450 super(TestRebaselineExpectations, self).setUp()
451 self.options = MockOptions(optimize=False, builders=None, suffixes=['txt'], verbose=False, platform=None,
452 move_overwritten_baselines=False, results_directory=None)
453
454 def test_rebaseline_expectations(self):
455 self._zero_out_test_expectations()
456
457 self.tool.executive = MockExecutive2()
458
Torne (Richard Coles)81a51572013-05-13 16:52:28 +0100459 self._write("userscripts/another-test.html", "Dummy test contents")
460 self._write("userscripts/images.svg", "Dummy test contents")
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000461 self.command._tests_to_rebaseline = lambda port: {'userscripts/another-test.html': set(['txt']), 'userscripts/images.svg': set(['png'])}
462 self.command.execute(self.options, [], self.tool)
463
464 # FIXME: change this to use the test- ports.
465 calls = filter(lambda x: x != ['qmake', '-v'], self.tool.executive.calls)
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000466 self.assertEqual(len(calls), 1)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100467 self.assertEqual(len(calls[0]), 14)
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000468
469 def test_rebaseline_expectations_noop(self):
470 self._zero_out_test_expectations()
471
472 oc = OutputCapture()
473 try:
474 oc.capture_output()
475 self.command.execute(self.options, [], self.tool)
476 finally:
477 _, _, logs = oc.restore_output()
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000478 self.assertEqual(self.tool.filesystem.written_files, {})
479 self.assertEqual(logs, 'Did not find any tests marked Rebaseline.\n')
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000480
481 def disabled_test_overrides_are_included_correctly(self):
482 # This tests that the any tests marked as REBASELINE in the overrides are found, but
483 # that the overrides do not get written into the main file.
484 self._zero_out_test_expectations()
485
486 self._write(self.lion_expectations_path, '')
487 self.lion_port.expectations_dict = lambda: {
488 self.lion_expectations_path: '',
489 'overrides': ('Bug(x) userscripts/another-test.html [ Failure Rebaseline ]\n'
490 'Bug(y) userscripts/test.html [ Crash ]\n')}
491 self._write('/userscripts/another-test.html', '')
492
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000493 self.assertDictEqual(self.command._tests_to_rebaseline(self.lion_port), {'userscripts/another-test.html': set(['png', 'txt', 'wav'])})
494 self.assertEqual(self._read(self.lion_expectations_path), '')
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000495
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100496 def test_rebaseline_without_other_expectations(self):
497 self._write("userscripts/another-test.html", "Dummy test contents")
498 self._write(self.lion_expectations_path, "Bug(x) userscripts/another-test.html [ Rebaseline ]\n")
499 self.assertDictEqual(self.command._tests_to_rebaseline(self.lion_port), {'userscripts/another-test.html': ('png', 'wav', 'txt')})
500
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000501
502class _FakeOptimizer(BaselineOptimizer):
503 def read_results_by_directory(self, baseline_name):
504 if baseline_name.endswith('txt'):
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100505 return {'LayoutTests/passes/text.html': '123456'}
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000506 return {}
507
508
509class TestAnalyzeBaselines(_BaseTestCase):
510 command_constructor = AnalyzeBaselines
511
512 def setUp(self):
513 super(TestAnalyzeBaselines, self).setUp()
514 self.port = self.tool.port_factory.get('test')
515 self.tool.port_factory.get = (lambda port_name=None, options=None: self.port)
516 self.lines = []
517 self.command._optimizer_class = _FakeOptimizer
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000518 self.command._write = (lambda msg: self.lines.append(msg)) # pylint bug warning about unnecessary lambda? pylint: disable=W0108
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000519
520 def test_default(self):
521 self.command.execute(MockOptions(suffixes='txt', missing=False, platform=None), ['passes/text.html'], self.tool)
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000522 self.assertEqual(self.lines,
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000523 ['passes/text-expected.txt:',
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100524 ' (generic): 123456'])
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000525
526 def test_missing_baselines(self):
527 self.command.execute(MockOptions(suffixes='png,txt', missing=True, platform=None), ['passes/text.html'], self.tool)
Torne (Richard Coles)926b0012013-03-28 15:32:48 +0000528 self.assertEqual(self.lines,
Torne (Richard Coles)5c87bf82012-11-14 11:46:17 +0000529 ['passes/text-expected.png: (no baselines found)',
530 'passes/text-expected.txt:',
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +0100531 ' (generic): 123456'])