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

Side by Side Diff: Tools/Scripts/webkitpy/bindings/main.py

Issue 169743005: Faster run-bindings-tests (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Removed timings and fast is the only mode. Created 6 years, 10 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
OLDNEW
1 # Copyright (C) 2011 Google Inc. All rights reserved. 1 # Copyright (C) 2011 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 4 # modification, are permitted provided that the following conditions
5 # are met: 5 # are met:
6 # 1. Redistributions of source code must retain the above copyright 6 # 1. Redistributions of source code must retain the above copyright
7 # notice, this list of conditions and the following disclaimer. 7 # notice, this list of conditions and the following disclaimer.
8 # 2. Redistributions in binary form must reproduce the above copyright 8 # 2. Redistributions in binary form must reproduce the above copyright
9 # notice, this list of conditions and the following disclaimer in the 9 # notice, this list of conditions and the following disclaimer in the
10 # documentation and/or other materials provided with the distribution. 10 # documentation and/or other materials provided with the distribution.
11 # 11 #
12 # THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 12 # THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
13 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 13 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 14 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 15 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
16 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 16 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
17 # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 17 # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
18 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 18 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
19 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 19 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
20 # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20 # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 21 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 # 23 #
24 24
25 import fnmatch 25 import fnmatch
26 import os 26 import os
27 import cPickle as pickle
28 from shutil import rmtree 27 from shutil import rmtree
28 import sys
29 import tempfile 29 import tempfile
30 from webkitpy.common.checkout.scm.detection import detect_scm_system 30 from webkitpy.common.checkout.scm.detection import detect_scm_system
31 from webkitpy.common.system.executive import ScriptError 31 from webkitpy.common.system.executive import ScriptError
32 32
33 # Add Source path to PYTHONPATH to support function calls to bindings/scripts
34 # for compute_dependencies and idl_compiler
35 module_path = os.path.dirname(__file__)
36 source_path = os.path.normpath(os.path.join(module_path, os.pardir,
37 os.pardir, os.pardir, os.pardir,
38 'Source'))
39 sys.path.append(source_path)
40
41 from bindings.scripts.compute_dependencies import compute
42 from bindings.scripts.unstable.idl_compiler import compile_idl
43
44
33 PASS_MESSAGE = 'All tests PASS!' 45 PASS_MESSAGE = 'All tests PASS!'
34 FAIL_MESSAGE = """Some tests FAIL! 46 FAIL_MESSAGE = """Some tests FAIL!
35 To update the reference files, execute: 47 To update the reference files, execute:
36 run-bindings-tests --reset-results 48 run-bindings-tests --reset-results
37 49
38 If the failures are not due to your changes, test results may be out of sync; 50 If the failures are not due to your changes, test results may be out of sync;
39 please rebaseline them in a separate CL, after checking that tests fail in ToT. 51 please rebaseline them in a separate CL, after checking that tests fail in ToT.
40 In CL, please set: 52 In CL, please set:
41 NOTRY=true 53 NOTRY=true
42 TBR=(someone in Source/bindings/OWNERS or WATCHLISTS:bindings) 54 TBR=(someone in Source/bindings/OWNERS or WATCHLISTS:bindings)
43 """ 55 """
44 56
45 DEPENDENCY_IDL_FILES = set([ 57 DEPENDENCY_IDL_FILES = set([
46 'SupportTestPartialInterface.idl', 58 'SupportTestPartialInterface.idl',
47 'TestImplements.idl', 59 'TestImplements.idl',
48 'TestImplements2.idl', 60 'TestImplements2.idl',
49 'TestImplements3.idl', 61 'TestImplements3.idl',
50 'TestPartialInterface.idl', 62 'TestPartialInterface.idl',
51 'TestPartialInterfacePython.idl', 63 'TestPartialInterfacePython.idl',
52 'TestPartialInterfacePython2.idl', 64 'TestPartialInterfacePython2.idl',
53 ]) 65 ])
54 66
55 SKIP_PYTHON = 'TestSVG.idl' # Not implementing SVG-specific hacks in Python 67 SKIP_PYTHON = 'TestSVG.idl' # Not implementing SVG-specific hacks in Python
56 68
69 EXTENDED_ATTRIBUTES_FILE = 'bindings/IDLExtendedAttributes.txt'
70
57 all_input_directory = '.' # Relative to Source/ 71 all_input_directory = '.' # Relative to Source/
58 test_input_directory = os.path.join('bindings', 'tests', 'idls') 72 test_input_directory = os.path.join('bindings', 'tests', 'idls')
59 reference_directory = os.path.join('bindings', 'tests', 'results') 73 reference_directory = os.path.join('bindings', 'tests', 'results')
60 reference_event_names_filename = os.path.join(reference_directory, 'EventInterfa ces.in') 74 reference_event_names_filename = os.path.join(reference_directory, 'EventInterfa ces.in')
61 75
62 76
63 class ScopedTempFileProvider(object): 77 class ScopedTempFileProvider(object):
64 def __init__(self): 78 def __init__(self):
65 self.files = [] 79 self.files = []
66 self.directories = [] 80 self.directories = []
(...skipping 12 matching lines...) Expand all
79 def newtempdir(self): 93 def newtempdir(self):
80 path = tempfile.mkdtemp() 94 path = tempfile.mkdtemp()
81 self.directories.append(path) 95 self.directories.append(path)
82 return path 96 return path
83 97
84 provider = ScopedTempFileProvider() 98 provider = ScopedTempFileProvider()
85 99
86 100
87 class BindingsTests(object): 101 class BindingsTests(object):
88 def __init__(self, reset_results, test_python, verbose, executive): 102 def __init__(self, reset_results, test_python, verbose, executive):
103 self.interfaces_info = {} # in-memory interfaces
89 self.reset_results = reset_results 104 self.reset_results = reset_results
90 self.test_python = test_python 105 self.test_python = test_python
91 self.verbose = verbose 106 self.verbose = verbose
92 self.executive = executive 107 self.executive = executive
108 self.reader = None
93 _, self.interface_dependencies_filename = provider.newtempfile() 109 _, self.interface_dependencies_filename = provider.newtempfile()
94 _, self.interfaces_info_filename = provider.newtempfile() 110 _, self.interfaces_info_filename = provider.newtempfile()
95 # Generate output into the reference directory if resetting results, or 111 # Generate output into the reference directory if resetting results, or
96 # a temp directory if not. 112 # a temp directory if not.
97 if reset_results: 113 if reset_results:
98 self.output_directory = reference_directory 114 self.output_directory = reference_directory
99 else: 115 else:
100 self.output_directory = provider.newtempdir() 116 self.output_directory = provider.newtempdir()
101 self.output_directory_py = provider.newtempdir() 117 self.output_directory_py = provider.newtempdir()
102 self.event_names_filename = os.path.join(self.output_directory, 'EventIn terfaces.in') 118 self.event_names_filename = os.path.join(self.output_directory, 'EventIn terfaces.in')
103 119
104 def run_command(self, cmd): 120 def run_command(self, cmd):
105 output = self.executive.run_command(cmd) 121 output = self.executive.run_command(cmd)
106 if output: 122 if output:
107 print output 123 print output
108 124
109 def generate_from_idl_pl(self, idl_file): 125 def generate_from_idl_pl(self, idl_file):
110 cmd = ['perl', '-w', 126 cmd = ['perl', '-w',
111 '-Ibindings/scripts', 127 '-Ibindings/scripts',
112 '-Ibuild/scripts', 128 '-Ibuild/scripts',
113 '-Icore/scripts', 129 '-Icore/scripts',
114 '-I../../JSON/out/lib/perl5', 130 '-I../../JSON/out/lib/perl5',
115 'bindings/scripts/generate_bindings.pl', 131 'bindings/scripts/generate_bindings.pl',
116 # idl include directories (path relative to generate-bindings.pl) 132 # idl include directories (path relative to generate-bindings.pl)
117 '--include', '.', 133 '--include', '.',
118 '--outputDir', self.output_directory, 134 '--outputDir', self.output_directory,
119 '--interfaceDependenciesFile', self.interface_dependencies_filena me, 135 '--interfaceDependenciesFile', self.interface_dependencies_filena me,
120 '--idlAttributesFile', 'bindings/IDLExtendedAttributes.txt', 136 '--idlAttributesFile', EXTENDED_ATTRIBUTES_FILE,
121 idl_file] 137 idl_file]
122 try: 138 try:
123 self.run_command(cmd) 139 self.run_command(cmd)
124 except ScriptError, e: 140 except ScriptError, e:
125 print 'ERROR: generate_bindings.pl: ' + os.path.basename(idl_file) 141 print 'ERROR: generate_bindings.pl: ' + os.path.basename(idl_file)
126 print e.output 142 print e.output
127 return e.exit_code 143 return e.exit_code
128 return 0 144 return 0
129 145
130 def generate_from_idl_py(self, idl_file): 146 def generate_from_idl_py(self, idl_file):
131 cmd = ['python',
132 'bindings/scripts/unstable/idl_compiler.py',
133 '--output-dir', self.output_directory_py,
134 '--idl-attributes-file', 'bindings/IDLExtendedAttributes.txt',
135 '--interfaces-info-file', self.interfaces_info_filename,
136 idl_file]
137 try: 147 try:
138 self.run_command(cmd) 148 idl_file_fullpath = os.path.realpath(idl_file)
149 self.reader = compile_idl(idl_file_fullpath,
150 self.output_directory_py,
151 EXTENDED_ATTRIBUTES_FILE,
152 self.interfaces_info, self.reader)
139 except ScriptError, e: 153 except ScriptError, e:
140 print 'ERROR: idl_compiler.py: ' + os.path.basename(idl_file) 154 print 'ERROR: idl_compiler.py: ' + os.path.basename(idl_file)
141 print e.output 155 print e.output
142 return e.exit_code 156 return e.exit_code
157
143 return 0 158 return 0
144 159
145 def generate_interface_dependencies(self): 160 def generate_interface_dependencies(self):
146 def idl_paths(directory): 161 def idl_paths(directory):
147 return [os.path.join(directory, input_file) 162 return [os.path.join(directory, input_file)
148 for input_file in os.listdir(directory) 163 for input_file in os.listdir(directory)
149 if input_file.endswith('.idl')] 164 if input_file.endswith('.idl')]
150 165
151 def idl_paths_recursive(directory): 166 def idl_paths_recursive(directory):
152 idl_paths = [] 167 idl_paths = []
153 for dirpath, _, files in os.walk(directory): 168 for dirpath, _, files in os.walk(directory):
154 idl_paths.extend(os.path.join(dirpath, filename) 169 idl_paths.extend(os.path.join(dirpath, filename)
155 for filename in fnmatch.filter(files, '*.idl')) 170 for filename in fnmatch.filter(files, '*.idl'))
156 return idl_paths 171 return idl_paths
157 172
158 def write_list_file(idl_paths): 173 def write_list_file(idl_paths):
159 list_file, list_filename = provider.newtempfile() 174 list_file, list_filename = provider.newtempfile()
160 list_contents = ''.join(idl_path + '\n' 175 list_contents = ''.join(idl_path + '\n'
161 for idl_path in idl_paths) 176 for idl_path in idl_paths)
162 os.write(list_file, list_contents) 177 os.write(list_file, list_contents)
163 return list_filename 178 return list_filename
164 179
165 def compute_dependencies(idl_files_list_filename, 180 # Faster in-memory file list.
166 event_names_filename): 181 def list_idl_file(idl_paths):
182 idls = []
183 for idl_path in idl_paths:
184 idls.append(idl_path)
185 return idls
186
187 def compute_dependencies(idl_files_list, event_names_filename, pickle_na me):
167 # Dummy files, required by compute_dependencies but not checked 188 # Dummy files, required by compute_dependencies but not checked
168 _, window_constructors_file = provider.newtempfile() 189 _, window_constructors_file = provider.newtempfile()
169 _, workerglobalscope_constructors_file = provider.newtempfile() 190 _, workerglobalscope_constructors_file = provider.newtempfile()
170 _, sharedworkerglobalscope_constructors_file = provider.newtempfile( ) 191 _, sharedworkerglobalscope_constructors_file = provider.newtempfile( )
171 _, dedicatedworkerglobalscope_constructors_file = provider.newtempfi le() 192 _, dedicatedworkerglobalscope_constructors_file = provider.newtempfi le()
172 _, serviceworkersglobalscope_constructors_file = provider.newtempfil e() 193 _, serviceworkersglobalscope_constructors_file = provider.newtempfil e()
173 cmd = ['python',
174 'bindings/scripts/compute_dependencies.py',
175 '--idl-files-list', idl_files_list_filename,
176 '--interface-dependencies-file', self.interface_dependencies_ filename,
177 '--interfaces-info-file', self.interfaces_info_filename,
178 '--window-constructors-file', window_constructors_file,
179 '--workerglobalscope-constructors-file', workerglobalscope_co nstructors_file,
180 '--sharedworkerglobalscope-constructors-file', sharedworkergl obalscope_constructors_file,
181 '--dedicatedworkerglobalscope-constructors-file', dedicatedwo rkerglobalscope_constructors_file,
182 '--serviceworkerglobalscope-constructors-file', serviceworker sglobalscope_constructors_file,
183 '--event-names-file', event_names_filename,
184 '--write-file-only-if-changed', '0']
185 self.run_command(cmd)
186 194
187 test_idl_files_list_filename = write_list_file(idl_paths(test_input_dire ctory)) 195 return compute(idl_files_list,
188 all_idl_files_list_filename = write_list_file(idl_paths_recursive(all_in put_directory)) 196 self.interface_dependencies_filename,
197 window_constructors_file,
198 workerglobalscope_constructors_file,
199 sharedworkerglobalscope_constructors_file,
200 dedicatedworkerglobalscope_constructors_file,
201 serviceworkersglobalscope_constructors_file,
202 event_names_filename, False)
203
204 test_idl_files_list = list_idl_file(idl_paths(test_input_directory))
205 all_idl_files_list = list_idl_file(idl_paths_recursive(all_input_directo ry))
189 206
190 if self.reset_results and self.verbose: 207 if self.reset_results and self.verbose:
191 print 'Reset results: EventInterfaces.in' 208 print 'Reset results: EventInterfaces.in'
192 try: 209 try:
193 # We first compute dependencies for testing files only, 210 # We first compute dependencies for testing files only,
194 # so we can compare EventInterfaces.in. 211 # so we can compare EventInterfaces.in.
195 compute_dependencies(test_idl_files_list_filename, 212 compute_dependencies(test_idl_files_list, self.event_names_filename,
196 self.event_names_filename) 213 self.interfaces_info_filename)
197 214
198 # We then compute dependencies for all IDL files, as code generator 215 # We then compute dependencies for all IDL files, as code generator
199 # output depends on inheritance (both ancestor chain and inherited 216 # output depends on inheritance (both ancestor chain and inherited
200 # extended attributes), and some real interfaces are special-cased, 217 # extended attributes), and some real interfaces are special-cased,
201 # such as Node. 218 # such as Node.
202 # For example, when testing the behavior of interfaces that inherit 219 # For example, when testing the behavior of interfaces that inherit
203 # from Node, we also need to know that these inherit from 220 # from Node, we also need to know that these inherit from
204 # EventTarget, since this is also special-cased and Node inherits 221 # EventTarget, since this is also special-cased and Node inherits
205 # from EventTarget, but this inheritance information requires 222 # from EventTarget, but this inheritance information requires
206 # computing dependencies for the real Node.idl file. 223 # computing dependencies for the real Node.idl file.
207 # 224 #
208 # Don't overwrite the event names file generated for testing IDLs 225 # Don't overwrite the event names file generated for testing IDLs
209 _, dummy_event_names_filename = provider.newtempfile() 226 _, dummy_event_names_filename = provider.newtempfile()
210 compute_dependencies(all_idl_files_list_filename, 227 self.interfaces_info = compute_dependencies(all_idl_files_list,
211 dummy_event_names_filename) 228 dummy_event_names_filena me,
229 self.interfaces_info_fil ename)
212 except ScriptError, e: 230 except ScriptError, e:
213 print 'ERROR: compute_dependencies.py' 231 print 'ERROR: compute_dependencies.py'
214 print e.output 232 print e.output
215 return e.exit_code 233 return e.exit_code
216 return 0 234 return 0
217 235
218 def identical_file(self, reference_filename, output_filename): 236 def identical_file(self, reference_filename, output_filename):
219 reference_basename = os.path.basename(reference_filename) 237 reference_basename = os.path.basename(reference_filename)
220 cmd = ['diff', 238 cmd = ['diff',
221 '-u', 239 '-u',
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 321
304 all_tests_passed = self.run_tests() 322 all_tests_passed = self.run_tests()
305 if all_tests_passed: 323 if all_tests_passed:
306 if self.verbose: 324 if self.verbose:
307 print 325 print
308 print PASS_MESSAGE 326 print PASS_MESSAGE
309 return 0 327 return 0
310 print 328 print
311 print FAIL_MESSAGE 329 print FAIL_MESSAGE
312 return -1 330 return -1
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698