Home | History | Annotate | Download | only in port
      1 # 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 
     29 import unittest
     30 import StringIO
     31 
     32 from webkitpy.common.system import logtesting
     33 from webkitpy.common.system import executive_mock
     34 from webkitpy.common.system import filesystem_mock
     35 from webkitpy.tool import mocktool
     36 from webkitpy.thirdparty.mock import Mock
     37 
     38 
     39 import chromium
     40 import chromium_linux
     41 import chromium_mac
     42 import chromium_win
     43 
     44 from webkitpy.layout_tests.port import port_testcase
     45 
     46 
     47 class ChromiumDriverTest(unittest.TestCase):
     48     def setUp(self):
     49         mock_port = Mock()
     50         mock_port.get_option = lambda option_name: ''
     51         self.driver = chromium.ChromiumDriver(mock_port, worker_number=0)
     52 
     53     def test_test_shell_command(self):
     54         expected_command = "test.html 2 checksum\n"
     55         self.assertEqual(self.driver._test_shell_command("test.html", 2, "checksum"), expected_command)
     56 
     57     def _assert_write_command_and_read_line(self, input=None, expected_line=None, expected_stdin=None, expected_crash=False):
     58         if not expected_stdin:
     59             if input:
     60                 expected_stdin = input
     61             else:
     62                 # We reset stdin, so we should expect stdin.getValue = ""
     63                 expected_stdin = ""
     64         self.driver._proc.stdin = StringIO.StringIO()
     65         line, did_crash = self.driver._write_command_and_read_line(input)
     66         self.assertEqual(self.driver._proc.stdin.getvalue(), expected_stdin)
     67         self.assertEqual(line, expected_line)
     68         self.assertEqual(did_crash, expected_crash)
     69 
     70     def test_write_command_and_read_line(self):
     71         self.driver._proc = Mock()
     72         # Set up to read 3 lines before we get an IOError
     73         self.driver._proc.stdout = StringIO.StringIO("first\nsecond\nthird\n")
     74 
     75         unicode_input = u"I \u2661 Unicode"
     76         utf8_input = unicode_input.encode("utf-8")
     77         # Test unicode input conversion to utf-8
     78         self._assert_write_command_and_read_line(input=unicode_input, expected_stdin=utf8_input, expected_line="first\n")
     79         # Test str() input.
     80         self._assert_write_command_and_read_line(input="foo", expected_line="second\n")
     81         # Test input=None
     82         self._assert_write_command_and_read_line(expected_line="third\n")
     83         # Test reading from a closed/empty stream.
     84         # reading from a StringIO does not raise IOError like a real file would, so raise IOError manually.
     85         def mock_readline():
     86             raise IOError
     87         self.driver._proc.stdout.readline = mock_readline
     88         self._assert_write_command_and_read_line(expected_crash=True)
     89 
     90     def test_stop(self):
     91         self.pid = None
     92         self.wait_called = False
     93         self.driver._proc = Mock()
     94         self.driver._proc.pid = 1
     95         self.driver._proc.stdin = StringIO.StringIO()
     96         self.driver._proc.stdout = StringIO.StringIO()
     97         self.driver._proc.stderr = StringIO.StringIO()
     98         self.driver._proc.poll = lambda: None
     99 
    100         def fake_wait():
    101             self.assertTrue(self.pid is not None)
    102             self.wait_called = True
    103 
    104         self.driver._proc.wait = fake_wait
    105 
    106         class FakeExecutive(object):
    107             def kill_process(other, pid):
    108                 self.pid = pid
    109                 self.driver._proc.poll = lambda: 2
    110 
    111         self.driver._port._executive = FakeExecutive()
    112         self.driver.KILL_TIMEOUT = 0.01
    113         self.driver.stop()
    114         self.assertTrue(self.wait_called)
    115         self.assertEquals(self.pid, 1)
    116 
    117 
    118 class ChromiumPortTest(port_testcase.PortTestCase):
    119     def port_maker(self, platform):
    120         return chromium.ChromiumPort
    121 
    122     def test_driver_cmd_line(self):
    123         # Override this test since ChromiumPort doesn't implement driver_cmd_line().
    124         pass
    125 
    126     def test_baseline_search_path(self):
    127         # Override this test since ChromiumPort doesn't implement baseline_search_path().
    128         pass
    129 
    130     class TestMacPort(chromium_mac.ChromiumMacPort):
    131         def __init__(self, options):
    132             chromium_mac.ChromiumMacPort.__init__(self,
    133                                                   options=options,
    134                                                   filesystem=filesystem_mock.MockFileSystem())
    135 
    136         def default_configuration(self):
    137             self.default_configuration_called = True
    138             return 'default'
    139 
    140     class TestLinuxPort(chromium_linux.ChromiumLinuxPort):
    141         def __init__(self, options):
    142             chromium_linux.ChromiumLinuxPort.__init__(self,
    143                                                       options=options,
    144                                                       filesystem=filesystem_mock.MockFileSystem())
    145 
    146         def default_configuration(self):
    147             self.default_configuration_called = True
    148             return 'default'
    149 
    150     class TestWinPort(chromium_win.ChromiumWinPort):
    151         def __init__(self, options):
    152             chromium_win.ChromiumWinPort.__init__(self,
    153                                                   options=options,
    154                                                   filesystem=filesystem_mock.MockFileSystem())
    155 
    156         def default_configuration(self):
    157             self.default_configuration_called = True
    158             return 'default'
    159 
    160     def test_path_to_image_diff(self):
    161         mock_options = mocktool.MockOptions()
    162         port = ChromiumPortTest.TestLinuxPort(options=mock_options)
    163         self.assertTrue(port._path_to_image_diff().endswith(
    164             '/out/default/ImageDiff'))
    165         port = ChromiumPortTest.TestMacPort(options=mock_options)
    166         self.assertTrue(port._path_to_image_diff().endswith(
    167             '/xcodebuild/default/ImageDiff'))
    168         port = ChromiumPortTest.TestWinPort(options=mock_options)
    169         self.assertTrue(port._path_to_image_diff().endswith(
    170             '/default/ImageDiff.exe'))
    171 
    172     def test_skipped_layout_tests(self):
    173         mock_options = mocktool.MockOptions()
    174         port = ChromiumPortTest.TestLinuxPort(options=mock_options)
    175 
    176         fake_test = port._filesystem.join(port.layout_tests_dir(), "fast/js/not-good.js")
    177 
    178         port.test_expectations = lambda: """BUG_TEST SKIP : fast/js/not-good.js = TEXT
    179 LINUX WIN : fast/js/very-good.js = TIMEOUT PASS"""
    180         port.test_expectations_overrides = lambda: ''
    181         port.tests = lambda paths: set()
    182         port.path_exists = lambda test: True
    183 
    184         skipped_tests = port.skipped_layout_tests(extra_test_files=[fake_test, ])
    185         self.assertTrue("fast/js/not-good.js" in skipped_tests)
    186 
    187     def test_default_configuration(self):
    188         mock_options = mocktool.MockOptions()
    189         port = ChromiumPortTest.TestLinuxPort(options=mock_options)
    190         self.assertEquals(mock_options.configuration, 'default')
    191         self.assertTrue(port.default_configuration_called)
    192 
    193         mock_options = mocktool.MockOptions(configuration=None)
    194         port = ChromiumPortTest.TestLinuxPort(mock_options)
    195         self.assertEquals(mock_options.configuration, 'default')
    196         self.assertTrue(port.default_configuration_called)
    197 
    198     def test_diff_image(self):
    199         class TestPort(ChromiumPortTest.TestLinuxPort):
    200             def _path_to_image_diff(self):
    201                 return "/path/to/image_diff"
    202 
    203         mock_options = mocktool.MockOptions()
    204         port = ChromiumPortTest.TestLinuxPort(mock_options)
    205 
    206         # Images are different.
    207         port._executive = executive_mock.MockExecutive2(exit_code=0)
    208         self.assertEquals(False, port.diff_image("EXPECTED", "ACTUAL"))
    209 
    210         # Images are the same.
    211         port._executive = executive_mock.MockExecutive2(exit_code=1)
    212         self.assertEquals(True, port.diff_image("EXPECTED", "ACTUAL"))
    213 
    214         # There was some error running image_diff.
    215         port._executive = executive_mock.MockExecutive2(exit_code=2)
    216         exception_raised = False
    217         try:
    218             port.diff_image("EXPECTED", "ACTUAL")
    219         except ValueError, e:
    220             exception_raised = True
    221         self.assertFalse(exception_raised)
    222 
    223 
    224 class ChromiumPortLoggingTest(logtesting.LoggingTestCase):
    225     def test_check_sys_deps(self):
    226         mock_options = mocktool.MockOptions()
    227         port = ChromiumPortTest.TestLinuxPort(options=mock_options)
    228 
    229         # Success
    230         port._executive = executive_mock.MockExecutive2(exit_code=0)
    231         self.assertTrue(port.check_sys_deps(needs_http=False))
    232 
    233         # Failure
    234         port._executive = executive_mock.MockExecutive2(exit_code=1,
    235             output='testing output failure')
    236         self.assertFalse(port.check_sys_deps(needs_http=False))
    237         self.assertLog([
    238             'ERROR: System dependencies check failed.\n',
    239             'ERROR: To override, invoke with --nocheck-sys-deps\n',
    240             'ERROR: \n',
    241             'ERROR: testing output failure\n'])
    242 
    243 if __name__ == '__main__':
    244     unittest.main()
    245