15abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# Copyright (C) 2010 Google Inc. All rights reserved.
25abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#
35abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# Redistribution and use in source and binary forms, with or without
45abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# modification, are permitted provided that the following conditions are
55abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# met:
65abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#
75abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#    * Redistributions of source code must retain the above copyright
85abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# notice, this list of conditions and the following disclaimer.
95abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#    * Redistributions in binary form must reproduce the above
105abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# copyright notice, this list of conditions and the following disclaimer
115abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# in the documentation and/or other materials provided with the
125abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# distribution.
135abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#    * Neither the name of Google Inc. nor the names of its
145abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# contributors may be used to endorse or promote products derived from
155abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# this software without specific prior written permission.
165abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#
175abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
185abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
195abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
205abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
215abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
225abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
235abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
245abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
255abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
265abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
275abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
285abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
295abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick"""Unit testing base class for Port implementations."""
305abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
3181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochimport sys
325abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickimport unittest
335abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
3481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch# Handle Python < 2.6 where multiprocessing isn't available.
3581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochtry:
3681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    import multiprocessing
3781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochexcept ImportError:
3881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    multiprocessing = None
3981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
40a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochfrom webkitpy.tool import mocktool
412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochmock_options = mocktool.MockOptions(use_apache=True,
42a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                                    configuration='Release')
435abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
444576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang# FIXME: This should be used for all ports, not just WebKit Mac. See
454576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang# https://bugs.webkit.org/show_bug.cgi?id=50043 .
465abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
475abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickclass PortTestCase(unittest.TestCase):
485abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    """Tests the WebKit port implementation."""
4981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    def port_maker(self, platform):
5081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        """Override to return the class object of the port to be tested,
5181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        or None if a valid port object cannot be constructed on the specified
5281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        platform."""
535abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        raise NotImplementedError()
545abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
5581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    def make_port(self, options=mock_options):
5681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        """This routine should be used for tests that should only be run
5781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        when we can create a full, valid port object."""
5881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        maker = self.port_maker(sys.platform)
5981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if not maker:
6081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return None
6181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return maker(options=options)
6381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
6481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    def test_default_worker_model(self):
6581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        port = self.make_port()
6681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if not port:
6781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return
6881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
6981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if multiprocessing:
7081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            self.assertEqual(port.default_worker_model(), 'processes')
7181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        else:
722bde8e466a4451c7319e3a072d118917957d6554Steve Block            self.assertEqual(port.default_worker_model(), 'threads')
7381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
744576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    def test_driver_cmd_line(self):
754576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        port = self.make_port()
764576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        if not port:
774576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            return
784576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        self.assertTrue(len(port.driver_cmd_line()))
794576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        options = mocktool.MockOptions(additional_drt_flag=['--foo=bar', '--foo=baz'])
812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        port = self.make_port(options=options)
822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        cmd_line = port.driver_cmd_line()
832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        self.assertTrue('--foo=bar' in cmd_line)
842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        self.assertTrue('--foo=baz' in cmd_line)
852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
86ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    def disabled_test_http_server(self):
875abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        port = self.make_port()
885abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        if not port:
895abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            return
905abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        port.start_http_server()
915abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        port.stop_http_server()
925abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
93ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    def disabled_test_image_diff(self):
945abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        port = self.make_port()
955abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        if not port:
965abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            return
975abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
985abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        if not port.check_image_diff():
99ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch            # The port hasn't been built - don't run the tests.
1005abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            return
1015abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
1025abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        dir = port.layout_tests_dir()
103ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        file1 = port._filesystem.join(dir, 'fast', 'css', 'button_center.png')
104ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        contents1 = port._filesystem.read_binary_file(file1)
105ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        file2 = port._filesystem.join(dir, 'fast', 'css',
106ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch                                      'remove-shorthand-expected.png')
107ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        contents2 = port._filesystem.read_binary_file(file2)
108ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        tmpfd, tmpfile = port._filesystem.open_binary_tempfile('')
109ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        tmpfd.close()
1105abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
111bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        self.assertFalse(port.diff_image(contents1, contents1))
112bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        self.assertTrue(port.diff_image(contents1, contents2))
1135abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
114bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        self.assertTrue(port.diff_image(contents1, contents2, tmpfile))
1155abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
116ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        port._filesystem.remove(tmpfile)
117ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
1182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    def test_diff_image__missing_both(self):
1192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        port = self.make_port()
1202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if not port:
1212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return
1222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        self.assertFalse(port.diff_image(None, None, None))
1232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        self.assertFalse(port.diff_image(None, '', None))
1242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        self.assertFalse(port.diff_image('', None, None))
1252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        self.assertFalse(port.diff_image('', '', None))
1262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    def test_diff_image__missing_actual(self):
1282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        port = self.make_port()
1292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if not port:
1302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return
1312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        self.assertTrue(port.diff_image(None, 'foo', None))
1322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        self.assertTrue(port.diff_image('', 'foo', None))
1332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    def test_diff_image__missing_expected(self):
1352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        port = self.make_port()
1362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if not port:
1372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return
1382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        self.assertTrue(port.diff_image('foo', None, None))
1392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        self.assertTrue(port.diff_image('foo', '', None))
1402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
142ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    def disabled_test_websocket_server(self):
1435abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        port = self.make_port()
1445abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        if not port:
1455abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            return
1465abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        port.start_websocket_server()
1475abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        port.stop_websocket_server()
1482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def test_test_configuration(self):
1502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        port = self.make_port()
1512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if not port:
1522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return
1532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self.assertTrue(port.test_configuration())
1542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    def test_all_test_configurations(self):
1562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        port = self.make_port()
1572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if not port:
1582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return
1592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        self.assertTrue(len(port.all_test_configurations()) > 0)
16081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
16181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    def test_baseline_search_path(self):
16281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        port = self.make_port()
16381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if not port:
16481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return
16581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        self.assertTrue(port.baseline_path() in port.baseline_search_path())
166