Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Side by Side Diff: Tools/Scripts/webkitpy/layout_tests/port/mock_drt.py

Issue 23889025: Make mock_drt functional and add optional secondary 'actual' directory. (Closed) Base URL: svn://svn.chromium.org/blink/trunk/
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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) )
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698