1 #!/usr/bin/env python 2 # Copyright (C) 2011 Google Inc. All rights reserved. 3 # 4 # Redistribution and use in source and binary forms, with or without 5 # modification, are permitted provided that the following conditions are 6 # met: 7 # 8 # * Redistributions of source code must retain the above copyright 9 # notice, this list of conditions and the following disclaimer. 10 # * Redistributions in binary form must reproduce the above 11 # copyright notice, this list of conditions and the following disclaimer 12 # in the documentation and/or other materials provided with the 13 # distribution. 14 # * Neither the name of Google Inc. nor the names of its 15 # contributors may be used to endorse or promote products derived from 16 # this software without specific prior written permission. 17 # 18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 """Unit tests for MockDRT.""" 31 32 import sys 33 import unittest 34 35 from webkitpy.common import newstringio 36 37 from webkitpy.layout_tests.port import mock_drt 38 from webkitpy.layout_tests.port import factory 39 from webkitpy.layout_tests.port import port_testcase 40 from webkitpy.layout_tests.port import test 41 42 from webkitpy.tool import mocktool 43 mock_options = mocktool.MockOptions(use_apache=True, 44 configuration='Release') 45 46 47 class MockDRTPortTest(port_testcase.PortTestCase): 48 def make_port(self, options=mock_options): 49 if sys.platform == 'win32': 50 # We use this because the 'win' port doesn't work yet. 51 return mock_drt.MockDRTPort(port_name='mock-chromium-win', options=options) 52 return mock_drt.MockDRTPort(options=options) 53 54 def test_default_worker_model(self): 55 # only overridding the default test; we don't care about this one. 56 pass 57 58 def test_port_name_in_constructor(self): 59 self.assertTrue(mock_drt.MockDRTPort(port_name='mock-test')) 60 61 def test_acquire_http_lock(self): 62 # Only checking that no exception is raised. 63 self.make_port().acquire_http_lock() 64 65 def test_release_http_lock(self): 66 # Only checking that no exception is raised. 67 self.make_port().release_http_lock() 68 69 def test_check_build(self): 70 port = self.make_port() 71 self.assertTrue(port.check_build(True)) 72 73 def test_check_sys_deps(self): 74 port = self.make_port() 75 self.assertTrue(port.check_sys_deps(True)) 76 77 def test_start_helper(self): 78 # Only checking that no exception is raised. 79 self.make_port().start_helper() 80 81 def test_start_http_server(self): 82 # Only checking that no exception is raised. 83 self.make_port().start_http_server() 84 85 def test_start_websocket_server(self): 86 # Only checking that no exception is raised. 87 self.make_port().start_websocket_server() 88 89 def test_stop_helper(self): 90 # Only checking that no exception is raised. 91 self.make_port().stop_helper() 92 93 def test_stop_http_server(self): 94 # Only checking that no exception is raised. 95 self.make_port().stop_http_server() 96 97 def test_stop_websocket_server(self): 98 # Only checking that no exception is raised. 99 self.make_port().stop_websocket_server() 100 101 102 class MockDRTTest(unittest.TestCase): 103 def to_path(self, port, test_name): 104 return port._filesystem.join(port.layout_tests_dir(), test_name) 105 106 def input_line(self, port, test_name, checksum=None): 107 url = port.filename_to_uri(self.to_path(port, test_name)) 108 # FIXME: we shouldn't have to work around platform-specific issues 109 # here. 110 if url.startswith('file:////'): 111 url = url[len('file:////') - 1:] 112 if url.startswith('file:///'): 113 url = url[len('file:///') - 1:] 114 115 if checksum: 116 return url + "'" + checksum + '\n' 117 return url + '\n' 118 119 def extra_args(self, pixel_tests): 120 if pixel_tests: 121 return ['--pixel-tests', '-'] 122 return ['-'] 123 124 def make_drt(self, options, args, filesystem, stdin, stdout, stderr): 125 return mock_drt.MockDRT(options, args, filesystem, stdin, stdout, stderr) 126 127 def make_input_output(self, port, test_name, pixel_tests, 128 expected_checksum, drt_output, drt_input=None): 129 path = self.to_path(port, test_name) 130 if pixel_tests: 131 if not expected_checksum: 132 expected_checksum = port.expected_checksum(path) 133 if not drt_input: 134 drt_input = self.input_line(port, test_name, expected_checksum) 135 text_output = port.expected_text(path) 136 137 if not drt_output: 138 drt_output = self.expected_output(port, test_name, pixel_tests, 139 text_output, expected_checksum) 140 return (drt_input, drt_output) 141 142 def expected_output(self, port, test_name, pixel_tests, text_output, expected_checksum): 143 if pixel_tests and expected_checksum: 144 return ['Content-Type: text/plain\n', 145 text_output, 146 '#EOF\n', 147 '\n', 148 'ActualHash: %s\n' % expected_checksum, 149 'ExpectedHash: %s\n' % expected_checksum, 150 '#EOF\n'] 151 else: 152 return ['Content-Type: text/plain\n', 153 text_output, 154 '#EOF\n', 155 '#EOF\n'] 156 157 def assertTest(self, test_name, pixel_tests, expected_checksum=None, 158 drt_output=None, filesystem=None): 159 platform = 'test' 160 filesystem = filesystem or test.unit_test_filesystem() 161 port = factory.get(platform, filesystem=filesystem) 162 drt_input, drt_output = self.make_input_output(port, test_name, 163 pixel_tests, expected_checksum, drt_output) 164 165 args = ['--platform', 'test'] + self.extra_args(pixel_tests) 166 stdin = newstringio.StringIO(drt_input) 167 stdout = newstringio.StringIO() 168 stderr = newstringio.StringIO() 169 options, args = mock_drt.parse_options(args) 170 171 drt = self.make_drt(options, args, filesystem, stdin, stdout, stderr) 172 res = drt.run() 173 174 self.assertEqual(res, 0) 175 176 # We use the StringIO.buflist here instead of getvalue() because 177 # the StringIO might be a mix of unicode/ascii and 8-bit strings. 178 self.assertEqual(stdout.buflist, drt_output) 179 self.assertEqual(stderr.getvalue(), '') 180 181 def test_main(self): 182 filesystem = test.unit_test_filesystem() 183 stdin = newstringio.StringIO() 184 stdout = newstringio.StringIO() 185 stderr = newstringio.StringIO() 186 res = mock_drt.main(['--platform', 'test'] + self.extra_args(False), 187 filesystem, stdin, stdout, stderr) 188 self.assertEqual(res, 0) 189 self.assertEqual(stdout.getvalue(), '') 190 self.assertEqual(stderr.getvalue(), '') 191 self.assertEqual(filesystem.written_files, {}) 192 193 def test_pixeltest_passes(self): 194 # This also tests that we handle HTTP: test URLs properly. 195 self.assertTest('http/tests/passes/text.html', True) 196 197 def test_pixeltest__fails(self): 198 self.assertTest('failures/expected/checksum.html', pixel_tests=True, 199 expected_checksum='wrong-checksum', 200 drt_output=['Content-Type: text/plain\n', 201 'checksum-txt', 202 '#EOF\n', 203 '\n', 204 'ActualHash: checksum-checksum\n', 205 'ExpectedHash: wrong-checksum\n', 206 'Content-Type: image/png\n', 207 'Content-Length: 13\n', 208 'checksum\x8a-png', 209 '#EOF\n']) 210 211 def test_textonly(self): 212 self.assertTest('passes/image.html', False) 213 214 def test_checksum_in_png(self): 215 self.assertTest('passes/checksum_in_image.html', True) 216 217 218 class MockChromiumDRTTest(MockDRTTest): 219 def extra_args(self, pixel_tests): 220 if pixel_tests: 221 return ['--pixel-tests=/tmp/png_result0.png'] 222 return [] 223 224 def make_drt(self, options, args, filesystem, stdin, stdout, stderr): 225 options.chromium = True 226 227 # We have to set these by hand because --platform test won't trigger 228 # the Chromium code paths. 229 options.pixel_path = '/tmp/png_result0.png' 230 options.pixel_tests = True 231 232 return mock_drt.MockChromiumDRT(options, args, filesystem, stdin, stdout, stderr) 233 234 def input_line(self, port, test_name, checksum=None): 235 url = port.filename_to_uri(self.to_path(port, test_name)) 236 if checksum: 237 return url + ' 6000 ' + checksum + '\n' 238 return url + ' 6000\n' 239 240 def expected_output(self, port, test_name, pixel_tests, text_output, expected_checksum): 241 url = port.filename_to_uri(self.to_path(port, test_name)) 242 if pixel_tests and expected_checksum: 243 return ['#URL:%s\n' % url, 244 '#MD5:%s\n' % expected_checksum, 245 text_output, 246 '\n', 247 '#EOF\n'] 248 else: 249 return ['#URL:%s\n' % url, 250 text_output, 251 '\n', 252 '#EOF\n'] 253 254 def test_pixeltest__fails(self): 255 filesystem = test.unit_test_filesystem() 256 self.assertTest('failures/expected/checksum.html', pixel_tests=True, 257 expected_checksum='wrong-checksum', 258 drt_output=['#URL:file:///test.checkout/LayoutTests/failures/expected/checksum.html\n', 259 '#MD5:checksum-checksum\n', 260 'checksum-txt', 261 '\n', 262 '#EOF\n'], 263 filesystem=filesystem) 264 self.assertEquals(filesystem.written_files, 265 {'/tmp/png_result0.png': 'checksum\x8a-png'}) 266 267 def test_chromium_parse_options(self): 268 options, args = mock_drt.parse_options(['--platform', 'chromium-mac', 269 '--pixel-tests=/tmp/png_result0.png']) 270 self.assertTrue(options.chromium) 271 self.assertTrue(options.pixel_tests) 272 self.assertEquals(options.pixel_path, '/tmp/png_result0.png') 273 274 275 if __name__ == '__main__': 276 unittest.main() 277