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

Side by Side Diff: bindings/dart/scripts/dart_tests.py

Issue 540533002: Roll IDL to Dartium37 (r181268) (Closed) Base URL: https://dart.googlecode.com/svn/third_party/WebCore
Patch Set: Created 6 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 | « bindings/dart/scripts/dart_methods.py ('k') | bindings/dart/scripts/dart_types.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright (C) 2014 Google Inc. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions
5 # are met:
6 # 1. Redistributions of source code must retain the above copyright
7 # notice, this list of conditions and the following disclaimer.
8 # 2. Redistributions in binary form must reproduce the above copyright
9 # notice, this list of conditions and the following disclaimer in the
10 # documentation and/or other materials provided with the distribution.
11 #
12 # THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
13 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
16 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
17 # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
18 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
19 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
20 # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
23 #
24
25 import fnmatch
26 import os
27 import shutil
28 import sys
29 import tempfile
30
31 from webkitpy.common.checkout.scm.detection import detect_scm_system
32 from webkitpy.common.system import executive
33 from webkitpy.common.system.executive import ScriptError
34
35 # Add Source path to PYTHONPATH to support function calls to bindings/scripts
36 # for compute_dependencies and idl_compiler
37 module_path = os.path.dirname(__file__)
38 source_path = os.path.normpath(os.path.join(module_path, os.pardir,
39 os.pardir, os.pardir, os.pardir,
40 'Source'))
41 sys.path.append(source_path)
42
43 from bindings.scripts.compute_interfaces_info import compute_interfaces_info, in terfaces_info
44 from bindings.scripts.idl_compiler import IdlCompilerV8
45
46
47 PASS_MESSAGE = 'All tests PASS!'
48 FAIL_MESSAGE = """Some tests FAIL!
49 To update the reference files, execute:
50 run-bindings-tests --reset-results
51
52 If the failures are not due to your changes, test results may be out of sync;
53 please rebaseline them in a separate CL, after checking that tests fail in ToT.
54 In CL, please set:
55 NOTRY=true
56 TBR=(someone in Source/bindings/OWNERS or WATCHLISTS:bindings)
57 """
58
59 DEPENDENCY_IDL_FILES = set([
60 'SupportTestPartialInterface.idl',
61 'TestImplements.idl',
62 'TestImplements2.idl',
63 'TestImplements3.idl',
64 'TestPartialInterface.idl',
65 'TestPartialInterfacePython.idl',
66 'TestPartialInterfacePython2.idl',
67 ])
68
69
70 EXTENDED_ATTRIBUTES_FILE = 'bindings/IDLExtendedAttributes.txt'
71
72 all_input_directory = '.' # Relative to Source/
73 test_input_directory = os.path.join('bindings', 'tests', 'idls')
74 reference_directory = os.path.join('bindings', 'tests', 'results')
75
76
77 class ScopedTempFileProvider(object):
78 def __init__(self):
79 self.file_handles = []
80 self.file_paths = []
81 self.dir_paths = []
82
83 def __enter__(self):
84 return self
85
86 def __exit__(self, exc_type, exc_value, traceback):
87 for file_handle in self.file_handles:
88 os.close(file_handle)
89 for file_path in self.file_paths:
90 os.remove(file_path)
91 for dir_path in self.dir_paths:
92 # Temporary directories are used as output directories, so they
93 # contains unknown files (they aren't empty), hence use rmtree
94 shutil.rmtree(dir_path)
95
96 def new_temp_file(self):
97 file_handle, file_path = tempfile.mkstemp()
98 self.file_handles.append(file_handle)
99 self.file_paths.append(file_path)
100 return file_handle, file_path
101
102 def new_temp_dir(self):
103 dir_path = tempfile.mkdtemp()
104 self.dir_paths.append(dir_path)
105 return dir_path
106
107
108 class DartTests(object):
109 def __init__(self, reset_results, verbose, provider):
110 self.reset_results = reset_results
111 self.verbose = verbose
112 self.executive = executive.Executive()
113 self.provider = provider
114 self.idl_compiler = None
115 _, self.interfaces_info_filename = provider.new_temp_file()
116 # Generate output into the reference directory if resetting results, or
117 # a temp directory if not.
118 if reset_results:
119 self.output_directory = reference_directory
120 else:
121 self.output_directory = provider.new_temp_dir()
122
123 def run_command(self, cmd):
124 output = self.executive.run_command(cmd)
125 if output:
126 print output
127
128 def generate_from_idl(self, idl_file):
129 try:
130 idl_file_fullpath = os.path.realpath(idl_file)
131 self.idl_compiler.compile_file(idl_file_fullpath)
132 except ScriptError, e:
133 print 'ERROR: idl_compiler.py: ' + os.path.basename(idl_file)
134 print e.output
135 return e.exit_code
136
137 return 0
138
139 def generate_interface_dependencies(self):
140 def idl_paths(directory):
141 return [os.path.join(directory, input_file)
142 for input_file in os.listdir(directory)
143 if input_file.endswith('.idl')]
144
145 def idl_paths_recursive(directory):
146 idl_paths = []
147 for dirpath, _, files in os.walk(directory):
148 idl_paths.extend(os.path.join(dirpath, filename)
149 for filename in fnmatch.filter(files, '*.idl'))
150 return idl_paths
151
152 def write_list_file(idl_paths):
153 list_file, list_filename = self.provider.new_temp_file()
154 list_contents = ''.join(idl_path + '\n'
155 for idl_path in idl_paths)
156 os.write(list_file, list_contents)
157 return list_filename
158
159 # We compute interfaces info for *all* IDL files, not just test IDL
160 # files, as code generator output depends on inheritance (both ancestor
161 # chain and inherited extended attributes), and some real interfaces
162 # are special-cased, such as Node.
163 #
164 # For example, when testing the behavior of interfaces that inherit
165 # from Node, we also need to know that these inherit from EventTarget,
166 # since this is also special-cased and Node inherits from EventTarget,
167 # but this inheritance information requires computing dependencies for
168 # the real Node.idl file.
169 try:
170 compute_interfaces_info(idl_paths_recursive(all_input_directory))
171
172 except ScriptError, e:
173 print 'ERROR: compute_interfaces_info.py'
174 print e.output
175 return e.exit_code
176
177 return 0
178
179 def delete_cache_files(self):
180 # FIXME: Instead of deleting cache files, don't generate them.
181 cache_files = [os.path.join(self.output_directory, output_file)
182 for output_file in os.listdir(self.output_directory)
183 if (output_file in ('lextab.py', # PLY lex
184 'lextab.pyc',
185 'parsetab.pickle') or # PLY yacc
186 output_file.endswith('.cache'))] # Jinja
187 for cache_file in cache_files:
188 os.remove(cache_file)
189
190 def identical_file(self, reference_filename, output_filename):
191 reference_basename = os.path.basename(reference_filename)
192 cmd = ['diff',
193 '-u',
194 '-N',
195 reference_filename,
196 output_filename]
197 try:
198 self.run_command(cmd)
199 except ScriptError, e:
200 # run_command throws an exception on diff (b/c non-zero exit code)
201 print 'FAIL: %s' % reference_basename
202 print e.output
203 return False
204
205 if self.verbose:
206 print 'PASS: %s' % reference_basename
207 return True
208
209 def identical_output_files(self):
210 file_pairs = [(os.path.join(reference_directory, output_file),
211 os.path.join(self.output_directory, output_file))
212 for output_file in os.listdir(self.output_directory)]
213 return all([self.identical_file(reference_filename, output_filename)
214 for (reference_filename, output_filename) in file_pairs])
215
216 def no_excess_files(self):
217 generated_files = set(os.listdir(self.output_directory))
218 generated_files.add('.svn') # Subversion working copy directory
219 excess_files = [output_file
220 for output_file in os.listdir(reference_directory)
221 if output_file not in generated_files]
222 if excess_files:
223 print ('Excess reference files! '
224 '(probably cruft from renaming or deleting):\n' +
225 '\n'.join(excess_files))
226 return False
227 return True
228
229 def run_tests(self):
230 # Generate output, immediately dying on failure
231 if self.generate_interface_dependencies():
232 return False
233
234 self.idl_compiler = IdlCompilerV8(self.output_directory,
235 EXTENDED_ATTRIBUTES_FILE,
236 interfaces_info=interfaces_info,
237 only_if_changed=True)
238
239 for input_filename in os.listdir(test_input_directory):
240 if not input_filename.endswith('.idl'):
241 continue
242 if input_filename in DEPENDENCY_IDL_FILES:
243 # Dependencies aren't built (they are used by the dependent)
244 if self.verbose:
245 print 'DEPENDENCY: %s' % input_filename
246 continue
247
248 idl_path = os.path.join(test_input_directory, input_filename)
249 if self.generate_from_idl(idl_path):
250 return False
251 if self.reset_results and self.verbose:
252 print 'Reset results: %s' % input_filename
253
254 self.delete_cache_files()
255
256 # Detect all changes
257 passed = self.identical_output_files()
258 passed &= self.no_excess_files()
259 return passed
260
261 def main(self):
262 current_scm = detect_scm_system(os.curdir)
263 os.chdir(os.path.join(current_scm.checkout_root, 'Source'))
264
265 all_tests_passed = self.run_tests()
266 if all_tests_passed:
267 if self.verbose:
268 print
269 print PASS_MESSAGE
270 return 0
271 print
272 print FAIL_MESSAGE
273 return -1
274
275
276 def run_dart_tests(reset_results, verbose):
277 with ScopedTempFileProvider() as provider:
278 return DartTests(reset_results, verbose, provider).main()
OLDNEW
« no previous file with comments | « bindings/dart/scripts/dart_methods.py ('k') | bindings/dart/scripts/dart_types.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698