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 32import sys 33import unittest 34 35from webkitpy.common import newstringio 36 37from webkitpy.layout_tests.port import mock_drt 38from webkitpy.layout_tests.port import factory 39from webkitpy.layout_tests.port import port_testcase 40from webkitpy.layout_tests.port import test 41 42from webkitpy.tool import mocktool 43mock_options = mocktool.MockOptions(use_apache=True, 44 configuration='Release') 45 46 47class 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 102class 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 218class 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 275if __name__ == '__main__': 276 unittest.main() 277