Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (c) 2012 Google Inc. All rights reserved. | 1 # Copyright (c) 2012 Google Inc. All rights reserved. |
| 2 # | 2 # |
| 3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
| 4 # modification, are permitted provided that the following conditions are | 4 # modification, are permitted provided that the following conditions are |
| 5 # met: | 5 # met: |
| 6 # | 6 # |
| 7 # * Redistributions of source code must retain the above copyright | 7 # * Redistributions of source code must retain the above copyright |
| 8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
| 9 # * Redistributions in binary form must reproduce the above | 9 # * Redistributions in binary form must reproduce the above |
| 10 # copyright notice, this list of conditions and the following disclaimer | 10 # copyright notice, this list of conditions and the following disclaimer |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 34 return the output a real DRT would return for a given test, assuming that | 34 return the output a real DRT would return for a given test, assuming that |
| 35 test actually passes (except for reftests, which currently cause the | 35 test actually passes (except for reftests, which currently cause the |
| 36 MockDRT to crash). | 36 MockDRT to crash). |
| 37 """ | 37 """ |
| 38 | 38 |
| 39 import base64 | 39 import base64 |
| 40 import logging | 40 import logging |
| 41 import optparse | 41 import optparse |
| 42 import os | 42 import os |
| 43 import sys | 43 import sys |
| 44 import types | |
| 44 | 45 |
| 45 # Since we execute this script directly as part of the unit tests, we need to en sure | 46 # Since we execute this script directly as part of the unit tests, we need to en sure |
| 46 # that Tools/Scripts is in sys.path for the next imports to work correctly. | 47 # that Tools/Scripts is in sys.path for the next imports to work correctly. |
| 47 script_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os. path.abspath(__file__))))) | 48 script_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os. path.abspath(__file__))))) |
| 48 if script_dir not in sys.path: | 49 if script_dir not in sys.path: |
| 49 sys.path.append(script_dir) | 50 sys.path.append(script_dir) |
| 50 | 51 |
| 52 from webkitpy.common import read_checksum_from_png | |
| 51 from webkitpy.common.system.systemhost import SystemHost | 53 from webkitpy.common.system.systemhost import SystemHost |
| 52 from webkitpy.layout_tests.port.driver import DriverInput, DriverOutput | 54 from webkitpy.layout_tests.port.driver import DriverInput, DriverOutput |
| 53 from webkitpy.layout_tests.port.factory import PortFactory | 55 from webkitpy.layout_tests.port.factory import PortFactory |
| 54 | 56 |
| 55 _log = logging.getLogger(__name__) | 57 _log = logging.getLogger(__name__) |
| 56 | 58 |
| 57 | 59 |
| 58 class MockDRTPort(object): | 60 class MockDRTPort(object): |
| 59 port_name = 'mock' | 61 port_name = 'mock' |
| 60 | 62 |
| 61 @classmethod | 63 @classmethod |
| 62 def determine_full_port_name(cls, host, options, port_name): | 64 def determine_full_port_name(cls, host, options, port_name): |
| 63 return port_name | 65 return port_name |
| 64 | 66 |
| 65 def __init__(self, host, port_name, **kwargs): | 67 def __init__(self, host, port_name, **kwargs): |
| 66 self.__delegate = PortFactory(host).get(port_name.replace('mock-', ''), **kwargs) | 68 self.__delegate = PortFactory(host).get(port_name.replace('mock-', ''), **kwargs) |
| 69 self.__delegate_driver_class = self.__delegate._driver_class | |
| 70 self.__delegate._driver_class = types.MethodType(self._driver_class, sel f.__delegate) | |
|
Dirk Pranke
2013/09/13 18:05:45
I think I sort-of understand what this change is d
bungeman-skia
2013/09/13 18:46:16
This is basically why this wasn't working. What wa
Dirk Pranke
2013/09/13 19:08:29
Oh, that makes sense. I think at one point (before
| |
| 67 | 71 |
| 68 def __getattr__(self, name): | 72 def __getattr__(self, name): |
| 69 return getattr(self.__delegate, name) | 73 return getattr(self.__delegate, name) |
| 70 | 74 |
| 71 def check_build(self, needs_http): | 75 def check_build(self, needs_http): |
| 72 return True | 76 return True |
| 73 | 77 |
| 74 def check_sys_deps(self, needs_http): | 78 def check_sys_deps(self, needs_http): |
| 75 return True | 79 return True |
| 76 | 80 |
| 77 def _driver_class(self): | 81 def _driver_class(self, delegate): |
| 78 return self._mocked_driver_maker | 82 return self._mocked_driver_maker |
| 79 | 83 |
| 80 @staticmethod | 84 #@staticmethod |
|
Dirk Pranke
2013/09/13 19:08:29
Delete the commented-out line :).
bungeman-skia
2013/09/13 20:22:14
Done. Yep, figured out self could come back around
| |
| 81 def _mocked_driver_maker(port, worker_number, pixel_tests, no_timeout=False) : | 85 def _mocked_driver_maker(self, port, worker_number, pixel_tests, no_timeout= False): |
| 82 path_to_this_file = port.host.filesystem.abspath(__file__.replace('.pyc' , '.py')) | 86 path_to_this_file = self.host.filesystem.abspath(__file__.replace('.pyc' , '.py')) |
| 83 driver = port.__delegate._driver_class()(port, worker_number, pixel_test s, no_timeout) | 87 driver = self.__delegate_driver_class()(self, worker_number, pixel_tests , no_timeout) |
| 84 driver.cmd_line = port._overriding_cmd_line(driver.cmd_line, | 88 driver.cmd_line = self._overriding_cmd_line(driver.cmd_line, |
| 85 port.__delegate._path_to_dri ver(), | 89 self.__delegate._path_to_dri ver(), |
| 86 sys.executable, | 90 sys.executable, |
| 87 path_to_this_file, | 91 path_to_this_file, |
| 88 port.__delegate.name()) | 92 self.__delegate.name()) |
| 89 return driver | 93 return driver |
| 90 | 94 |
| 91 @staticmethod | 95 @staticmethod |
| 92 def _overriding_cmd_line(original_cmd_line, driver_path, python_exe, this_fi le, port_name): | 96 def _overriding_cmd_line(original_cmd_line, driver_path, python_exe, this_fi le, port_name): |
| 93 def new_cmd_line(pixel_tests, per_test_args): | 97 def new_cmd_line(pixel_tests, per_test_args): |
| 94 cmd_line = original_cmd_line(pixel_tests, per_test_args) | 98 cmd_line = original_cmd_line(pixel_tests, per_test_args) |
| 95 index = cmd_line.index(driver_path) | 99 index = cmd_line.index(driver_path) |
| 96 cmd_line[index:index + 1] = [python_exe, this_file, '--platform', po rt_name] | 100 cmd_line[index:index + 1] = [python_exe, this_file, '--platform', po rt_name] |
| 97 return cmd_line | 101 return cmd_line |
| 98 | 102 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 145 # module. First, Chromium and non-Chromium DRTs have a different argument | 149 # module. First, Chromium and non-Chromium DRTs have a different argument |
| 146 # syntax. Chromium uses --pixel-tests=<path>, and non-Chromium uses | 150 # syntax. Chromium uses --pixel-tests=<path>, and non-Chromium uses |
| 147 # --pixel-tests as a boolean flag. Second, we don't want to have to list | 151 # --pixel-tests as a boolean flag. Second, we don't want to have to list |
| 148 # every command line flag DRT accepts, but optparse complains about | 152 # every command line flag DRT accepts, but optparse complains about |
| 149 # unrecognized flags. At some point it might be good to share a common | 153 # unrecognized flags. At some point it might be good to share a common |
| 150 # DRT options class between this file and webkit.py and chromium.py | 154 # DRT options class between this file and webkit.py and chromium.py |
| 151 # just to get better type checking. | 155 # just to get better type checking. |
| 152 platform_index = argv.index('--platform') | 156 platform_index = argv.index('--platform') |
| 153 platform = argv[platform_index + 1] | 157 platform = argv[platform_index + 1] |
| 154 | 158 |
| 159 actual_directory = None | |
| 160 if '--actual-directory' in argv: | |
| 161 actual_directory_index = argv.index('--actual-directory') | |
| 162 actual_directory = argv[actual_directory_index + 1] | |
| 163 | |
| 155 pixel_tests = False | 164 pixel_tests = False |
| 156 pixel_path = None | 165 pixel_path = None |
| 157 test_shell = '--test-shell' in argv | 166 test_shell = '--test-shell' in argv |
| 158 if test_shell: | 167 if test_shell: |
| 159 for arg in argv: | 168 for arg in argv: |
| 160 if arg.startswith('--pixel-tests'): | 169 if arg.startswith('--pixel-tests'): |
| 161 pixel_tests = True | 170 pixel_tests = True |
| 162 pixel_path = arg[len('--pixel-tests='):] | 171 pixel_path = arg[len('--pixel-tests='):] |
| 163 else: | 172 else: |
| 164 pixel_tests = '--pixel-tests' in argv | 173 pixel_tests = '--pixel-tests' in argv |
| 165 options = optparse.Values({'test_shell': test_shell, 'platform': platform, ' pixel_tests': pixel_tests, 'pixel_path': pixel_path}) | 174 options = optparse.Values({'test_shell': test_shell, |
| 175 'platform': platform, | |
| 176 'pixel_tests': pixel_tests, | |
| 177 'pixel_path': pixel_path, | |
| 178 'actual_directory': actual_directory}) | |
| 166 return (options, argv) | 179 return (options, argv) |
| 167 | 180 |
| 168 | 181 |
| 169 class MockDRT(object): | 182 class MockDRT(object): |
| 170 def __init__(self, options, args, host, stdin, stdout, stderr): | 183 def __init__(self, options, args, host, stdin, stdout, stderr): |
| 171 self._options = options | 184 self._options = options |
| 172 self._args = args | 185 self._args = args |
| 173 self._host = host | 186 self._host = host |
| 174 self._stdout = stdout | 187 self._stdout = stdout |
| 175 self._stdin = stdin | 188 self._stdin = stdin |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 188 return 0 | 201 return 0 |
| 189 driver_input = self.input_from_line(line) | 202 driver_input = self.input_from_line(line) |
| 190 dirname, basename = self._port.split_test(driver_input.test_name) | 203 dirname, basename = self._port.split_test(driver_input.test_name) |
| 191 is_reftest = (self._port.reference_files(driver_input.test_name) or | 204 is_reftest = (self._port.reference_files(driver_input.test_name) or |
| 192 self._port.is_reference_html_file(self._port._filesyst em, dirname, basename)) | 205 self._port.is_reference_html_file(self._port._filesyst em, dirname, basename)) |
| 193 output = self.output_for_test(driver_input, is_reftest) | 206 output = self.output_for_test(driver_input, is_reftest) |
| 194 self.write_test_output(driver_input, output, is_reftest) | 207 self.write_test_output(driver_input, output, is_reftest) |
| 195 | 208 |
| 196 def input_from_line(self, line): | 209 def input_from_line(self, line): |
| 197 vals = line.strip().split("'") | 210 vals = line.strip().split("'") |
| 198 if len(vals) == 1: | 211 uri = vals[0] |
| 199 uri = vals[0] | 212 checksum = None |
| 200 checksum = None | 213 if len(vals) >= 3: |
| 201 else: | 214 checksum = vals[2] |
| 202 uri = vals[0] | |
| 203 checksum = vals[1] | |
| 204 if uri.startswith('http://') or uri.startswith('https://'): | 215 if uri.startswith('http://') or uri.startswith('https://'): |
| 205 test_name = self._driver.uri_to_test(uri) | 216 test_name = self._driver.uri_to_test(uri) |
| 206 else: | 217 else: |
| 207 test_name = self._port.relative_test_filename(uri) | 218 test_name = self._port.relative_test_filename(uri) |
| 208 | 219 |
| 209 return DriverInput(test_name, 0, checksum, self._options.pixel_tests) | 220 return DriverInput(test_name, 0, checksum, self._options.pixel_tests) |
| 210 | 221 |
| 211 def output_for_test(self, test_input, is_reftest): | 222 def output_for_test(self, test_input, is_reftest): |
| 212 port = self._port | 223 port = self._port |
| 213 actual_text = port.expected_text(test_input.test_name) | 224 actual_text = port.expected_text(test_input.test_name) |
| 214 actual_audio = port.expected_audio(test_input.test_name) | 225 actual_audio = port.expected_audio(test_input.test_name) |
| 215 actual_image = None | 226 actual_image = None |
| 216 actual_checksum = None | 227 actual_checksum = None |
| 217 if is_reftest: | 228 if is_reftest: |
| 218 # Make up some output for reftests. | 229 # Make up some output for reftests. |
| 219 actual_text = 'reference text\n' | 230 actual_text = 'reference text\n' |
| 220 actual_checksum = 'mock-checksum' | 231 actual_checksum = 'mock-checksum' |
| 221 actual_image = 'blank' | 232 actual_image = 'blank' |
| 222 if test_input.test_name.endswith('-mismatch.html'): | 233 if test_input.test_name.endswith('-mismatch.html'): |
| 223 actual_text = 'not reference text\n' | 234 actual_text = 'not reference text\n' |
| 224 actual_checksum = 'not-mock-checksum' | 235 actual_checksum = 'not-mock-checksum' |
| 225 actual_image = 'not blank' | 236 actual_image = 'not blank' |
| 226 elif self._options.pixel_tests and test_input.image_hash: | 237 elif self._options.pixel_tests and test_input.image_hash: |
| 227 actual_checksum = port.expected_checksum(test_input.test_name) | 238 actual_checksum = port.expected_checksum(test_input.test_name) |
| 228 actual_image = port.expected_image(test_input.test_name) | 239 actual_image = port.expected_image(test_input.test_name) |
| 229 | 240 |
| 241 if self._options.actual_directory: | |
|
Dirk Pranke
2013/09/13 18:05:45
What happens if the -actual.* files don't exist ?
bungeman-skia
2013/09/13 18:46:16
The idea was that if the -actual.* files don't exi
Dirk Pranke
2013/09/13 19:08:29
Makes sense. The only concern I have about the unn
| |
| 242 actual_path = port._filesystem.join(self._options.actual_directory, test_input.test_name) | |
| 243 root, _ = port._filesystem.splitext(actual_path) | |
| 244 text_path = root + '-actual.txt' | |
| 245 if port._filesystem.exists(text_path): | |
| 246 actual_text = port._filesystem.read_binary_file(text_path) | |
| 247 audio_path = root + '-actual.wav' | |
| 248 if port._filesystem.exists(audio_path): | |
| 249 actual_audio = port._filesystem.read_binary_file(audio_path) | |
| 250 image_path = root + '-actual.png' | |
| 251 if port._filesystem.exists(image_path): | |
| 252 actual_image = port._filesystem.read_binary_file(image_path) | |
| 253 with port._filesystem.open_binary_file_for_reading(image_path) a s filehandle: | |
| 254 actual_checksum = read_checksum_from_png.read_checksum(fileh andle) | |
| 255 | |
| 230 return DriverOutput(actual_text, actual_image, actual_checksum, actual_a udio) | 256 return DriverOutput(actual_text, actual_image, actual_checksum, actual_a udio) |
| 231 | 257 |
| 232 def write_test_output(self, test_input, output, is_reftest): | 258 def write_test_output(self, test_input, output, is_reftest): |
| 233 if output.audio: | 259 if output.audio: |
| 234 self._stdout.write('Content-Type: audio/wav\n') | 260 self._stdout.write('Content-Type: audio/wav\n') |
| 235 self._stdout.write('Content-Transfer-Encoding: base64\n') | 261 self._stdout.write('Content-Transfer-Encoding: base64\n') |
| 236 self._stdout.write(base64.b64encode(output.audio)) | 262 self._stdout.write(base64.b64encode(output.audio)) |
| 237 else: | 263 else: |
| 238 self._stdout.write('Content-Type: text/plain\n') | 264 self._stdout.write('Content-Type: text/plain\n') |
| 239 # FIXME: Note that we don't ensure there is a trailing newline! | 265 # FIXME: Note that we don't ensure there is a trailing newline! |
| 240 # This mirrors actual (Mac) DRT behavior but is a bug. | 266 # This mirrors actual (Mac) DRT behavior but is a bug. |
| 241 if output.text: | 267 if output.text: |
| 242 self._stdout.write(output.text) | 268 self._stdout.write(output.text) |
| 243 | 269 |
| 244 self._stdout.write('#EOF\n') | 270 self._stdout.write('#EOF\n') |
| 245 | 271 |
| 246 if self._options.pixel_tests and output.image_hash: | 272 if self._options.pixel_tests and output.image_hash or is_reftest: |
| 247 self._stdout.write('\n') | 273 self._stdout.write('\n') |
| 248 self._stdout.write('ActualHash: %s\n' % output.image_hash) | 274 self._stdout.write('ActualHash: %s\n' % output.image_hash) |
| 249 self._stdout.write('ExpectedHash: %s\n' % test_input.image_hash) | 275 self._stdout.write('ExpectedHash: %s\n' % test_input.image_hash) |
| 250 if output.image_hash != test_input.image_hash: | 276 if output.image_hash != test_input.image_hash: |
| 251 self._stdout.write('Content-Type: image/png\n') | 277 self._stdout.write('Content-Type: image/png\n') |
| 252 self._stdout.write('Content-Length: %s\n' % len(output.image)) | 278 self._stdout.write('Content-Length: %s\n' % len(output.image)) |
| 253 self._stdout.write(output.image) | 279 self._stdout.write(output.image) |
| 254 self._stdout.write('#EOF\n') | 280 self._stdout.write('#EOF\n') |
| 255 self._stdout.flush() | 281 self._stdout.flush() |
| 256 self._stderr.write('#EOF\n') | 282 self._stderr.write('#EOF\n') |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 291 if output.text and not output.text.endswith('\n'): | 317 if output.text and not output.text.endswith('\n'): |
| 292 self._stdout.write('\n') | 318 self._stdout.write('\n') |
| 293 self._stdout.write('#EOF\n') | 319 self._stdout.write('#EOF\n') |
| 294 self._stdout.flush() | 320 self._stdout.flush() |
| 295 | 321 |
| 296 | 322 |
| 297 if __name__ == '__main__': | 323 if __name__ == '__main__': |
| 298 # Note that the Mock in MockDRT refers to the fact that it is emulating a | 324 # Note that the Mock in MockDRT refers to the fact that it is emulating a |
| 299 # real DRT, and as such, it needs access to a real SystemHost, not a MockSys temHost. | 325 # real DRT, and as such, it needs access to a real SystemHost, not a MockSys temHost. |
| 300 sys.exit(main(sys.argv[1:], SystemHost(), sys.stdin, sys.stdout, sys.stderr) ) | 326 sys.exit(main(sys.argv[1:], SystemHost(), sys.stdin, sys.stdout, sys.stderr) ) |
| OLD | NEW |