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 29import unittest 30 31from webkitpy.common.system.systemhost_mock import MockSystemHost 32 33from webkitpy.layout_tests.port import Port, Driver, DriverOutput 34from webkitpy.layout_tests.port.server_process_mock import MockServerProcess 35 36# FIXME: remove the dependency on TestWebKitPort 37from webkitpy.layout_tests.port.port_testcase import TestWebKitPort 38 39from webkitpy.tool.mocktool import MockOptions 40 41 42class DriverTest(unittest.TestCase): 43 def make_port(self): 44 port = Port(MockSystemHost(), 'test', MockOptions(configuration='Release')) 45 port._config.build_directory = lambda configuration: '/mock-checkout/out/' + configuration 46 return port 47 48 def _assert_wrapper(self, wrapper_string, expected_wrapper): 49 wrapper = Driver(self.make_port(), None, pixel_tests=False)._command_wrapper(wrapper_string) 50 self.assertEqual(wrapper, expected_wrapper) 51 52 def test_command_wrapper(self): 53 self._assert_wrapper(None, []) 54 self._assert_wrapper("valgrind", ["valgrind"]) 55 56 # Validate that shlex works as expected. 57 command_with_spaces = "valgrind --smc-check=\"check with spaces!\" --foo" 58 expected_parse = ["valgrind", "--smc-check=check with spaces!", "--foo"] 59 self._assert_wrapper(command_with_spaces, expected_parse) 60 61 def test_test_to_uri(self): 62 port = self.make_port() 63 driver = Driver(port, None, pixel_tests=False) 64 self.assertEqual(driver.test_to_uri('foo/bar.html'), 'file://%s/foo/bar.html' % port.layout_tests_dir()) 65 self.assertEqual(driver.test_to_uri('http/tests/foo.html'), 'http://127.0.0.1:8000/foo.html') 66 self.assertEqual(driver.test_to_uri('http/tests/https/bar.html'), 'https://127.0.0.1:8443/https/bar.html') 67 68 def test_uri_to_test(self): 69 port = self.make_port() 70 driver = Driver(port, None, pixel_tests=False) 71 self.assertEqual(driver.uri_to_test('file://%s/foo/bar.html' % port.layout_tests_dir()), 'foo/bar.html') 72 self.assertEqual(driver.uri_to_test('http://127.0.0.1:8000/foo.html'), 'http/tests/foo.html') 73 self.assertEqual(driver.uri_to_test('https://127.0.0.1:8443/https/bar.html'), 'http/tests/https/bar.html') 74 75 def test_read_block(self): 76 port = TestWebKitPort() 77 driver = Driver(port, 0, pixel_tests=False) 78 driver._server_process = MockServerProcess(lines=[ 79 'ActualHash: foobar', 80 'Content-Type: my_type', 81 'Content-Transfer-Encoding: none', 82 "#EOF", 83 ]) 84 content_block = driver._read_block(0) 85 self.assertEqual(content_block.content, '') 86 self.assertEqual(content_block.content_type, 'my_type') 87 self.assertEqual(content_block.encoding, 'none') 88 self.assertEqual(content_block.content_hash, 'foobar') 89 driver._server_process = None 90 91 def test_read_binary_block(self): 92 port = TestWebKitPort() 93 driver = Driver(port, 0, pixel_tests=True) 94 driver._server_process = MockServerProcess(lines=[ 95 'ActualHash: actual', 96 'ExpectedHash: expected', 97 'Content-Type: image/png', 98 'Content-Length: 9', 99 "12345678", 100 "#EOF", 101 ]) 102 content_block = driver._read_block(0) 103 self.assertEqual(content_block.content_type, 'image/png') 104 self.assertEqual(content_block.content_hash, 'actual') 105 self.assertEqual(content_block.content, '12345678\n') 106 self.assertEqual(content_block.decoded_content, '12345678\n') 107 driver._server_process = None 108 109 def test_read_base64_block(self): 110 port = TestWebKitPort() 111 driver = Driver(port, 0, pixel_tests=True) 112 driver._server_process = MockServerProcess(lines=[ 113 'ActualHash: actual', 114 'ExpectedHash: expected', 115 'Content-Type: image/png', 116 'Content-Transfer-Encoding: base64', 117 'Content-Length: 12', 118 'MTIzNDU2NzgK#EOF', 119 ]) 120 content_block = driver._read_block(0) 121 self.assertEqual(content_block.content_type, 'image/png') 122 self.assertEqual(content_block.content_hash, 'actual') 123 self.assertEqual(content_block.encoding, 'base64') 124 self.assertEqual(content_block.content, 'MTIzNDU2NzgK') 125 self.assertEqual(content_block.decoded_content, '12345678\n') 126 127 def test_no_timeout(self): 128 port = TestWebKitPort() 129 port._config.build_directory = lambda configuration: '/mock-checkout/out/' + configuration 130 driver = Driver(port, 0, pixel_tests=True, no_timeout=True) 131 self.assertEqual(driver.cmd_line(True, []), ['/mock-checkout/out/Release/content_shell', '--no-timeout', '--dump-render-tree', '-']) 132 133 def test_check_for_driver_crash(self): 134 port = TestWebKitPort() 135 driver = Driver(port, 0, pixel_tests=True) 136 137 class FakeServerProcess(object): 138 def __init__(self, crashed): 139 self.crashed = crashed 140 141 def pid(self): 142 return 1234 143 144 def name(self): 145 return 'FakeServerProcess' 146 147 def has_crashed(self): 148 return self.crashed 149 150 def stop(self, timeout=0.0): 151 pass 152 153 def assert_crash(driver, error_line, crashed, name, pid, unresponsive=False, leaked=False): 154 self.assertEqual(driver._check_for_driver_crash(error_line), crashed) 155 self.assertEqual(driver._crashed_process_name, name) 156 self.assertEqual(driver._crashed_pid, pid) 157 self.assertEqual(driver._subprocess_was_unresponsive, unresponsive) 158 self.assertEqual(driver._check_for_leak(error_line), leaked) 159 driver.stop() 160 161 driver._server_process = FakeServerProcess(False) 162 assert_crash(driver, '', False, None, None) 163 164 driver._crashed_process_name = None 165 driver._crashed_pid = None 166 driver._server_process = FakeServerProcess(False) 167 driver._subprocess_was_unresponsive = False 168 driver._leaked = False 169 assert_crash(driver, '#CRASHED\n', True, 'FakeServerProcess', 1234) 170 171 driver._crashed_process_name = None 172 driver._crashed_pid = None 173 driver._server_process = FakeServerProcess(False) 174 driver._subprocess_was_unresponsive = False 175 driver._leaked = False 176 assert_crash(driver, '#CRASHED - WebProcess\n', True, 'WebProcess', None) 177 178 driver._crashed_process_name = None 179 driver._crashed_pid = None 180 driver._server_process = FakeServerProcess(False) 181 driver._subprocess_was_unresponsive = False 182 driver._leaked = False 183 assert_crash(driver, '#CRASHED - WebProcess (pid 8675)\n', True, 'WebProcess', 8675) 184 185 driver._crashed_process_name = None 186 driver._crashed_pid = None 187 driver._server_process = FakeServerProcess(False) 188 driver._subprocess_was_unresponsive = False 189 driver._leaked = False 190 assert_crash(driver, '#PROCESS UNRESPONSIVE - WebProcess (pid 8675)\n', True, 'WebProcess', 8675, True) 191 192 driver._crashed_process_name = None 193 driver._crashed_pid = None 194 driver._server_process = FakeServerProcess(False) 195 driver._subprocess_was_unresponsive = False 196 driver._leaked = False 197 assert_crash(driver, '#CRASHED - renderer (pid 8675)\n', True, 'renderer', 8675) 198 199 driver._crashed_process_name = None 200 driver._crashed_pid = None 201 driver._server_process = FakeServerProcess(False) 202 driver._subprocess_was_unresponsive = False 203 driver._leaked = False 204 assert_crash(driver, '#LEAK - renderer pid 8675 ({"numberOfLiveDocuments":[2,3]})\n', False, None, None, False, True) 205 206 driver._crashed_process_name = None 207 driver._crashed_pid = None 208 driver._server_process = FakeServerProcess(True) 209 driver._subprocess_was_unresponsive = False 210 driver._leaked = False 211 assert_crash(driver, '', True, 'FakeServerProcess', 1234) 212 213 def test_creating_a_port_does_not_write_to_the_filesystem(self): 214 port = TestWebKitPort() 215 driver = Driver(port, 0, pixel_tests=True) 216 self.assertEqual(port._filesystem.written_files, {}) 217 self.assertEqual(port._filesystem.last_tmpdir, None) 218 219 def test_stop_cleans_up_properly(self): 220 port = TestWebKitPort() 221 port._server_process_constructor = MockServerProcess 222 driver = Driver(port, 0, pixel_tests=True) 223 driver.start(True, [], None) 224 last_tmpdir = port._filesystem.last_tmpdir 225 self.assertNotEquals(last_tmpdir, None) 226 driver.stop() 227 self.assertFalse(port._filesystem.isdir(last_tmpdir)) 228 229 def test_two_starts_cleans_up_properly(self): 230 port = TestWebKitPort() 231 port._server_process_constructor = MockServerProcess 232 driver = Driver(port, 0, pixel_tests=True) 233 driver.start(True, [], None) 234 last_tmpdir = port._filesystem.last_tmpdir 235 driver._start(True, []) 236 self.assertFalse(port._filesystem.isdir(last_tmpdir)) 237 238 def test_start_actually_starts(self): 239 port = TestWebKitPort() 240 port._server_process_constructor = MockServerProcess 241 driver = Driver(port, 0, pixel_tests=True) 242 driver.start(True, [], None) 243 self.assertTrue(driver._server_process.started) 244