OLD | NEW |
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. |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 'TestPartialInterface.idl', | 65 'TestPartialInterface.idl', |
66 'TestPartialInterface2.idl', | 66 'TestPartialInterface2.idl', |
67 'TestPartialInterface3.idl', | 67 'TestPartialInterface3.idl', |
68 ]) | 68 ]) |
69 | 69 |
70 COMPONENT_DIRECTORY = frozenset(['core', 'modules']) | 70 COMPONENT_DIRECTORY = frozenset(['core', 'modules']) |
71 | 71 |
72 test_input_directory = os.path.join(source_path, 'bindings', 'tests', 'idls') | 72 test_input_directory = os.path.join(source_path, 'bindings', 'tests', 'idls') |
73 reference_directory = os.path.join(source_path, 'bindings', 'tests', 'results') | 73 reference_directory = os.path.join(source_path, 'bindings', 'tests', 'results') |
74 | 74 |
| 75 PLY_LEX_YACC_FILES = frozenset([ |
| 76 'lextab.py', # PLY lex |
| 77 'lextab.pyc', |
| 78 'parsetab.pickle', # PLY yacc |
| 79 ]) |
75 | 80 |
76 @contextmanager | 81 @contextmanager |
77 def TemporaryDirectory(): | 82 def TemporaryDirectory(): |
78 """Wrapper for tempfile.mkdtemp() so it's usable with 'with' statement. | 83 """Wrapper for tempfile.mkdtemp() so it's usable with 'with' statement. |
79 | 84 |
80 Simple backport of tempfile.TemporaryDirectory from Python 3.2. | 85 Simple backport of tempfile.TemporaryDirectory from Python 3.2. |
81 """ | 86 """ |
82 name = tempfile.mkdtemp() | 87 name = tempfile.mkdtemp() |
83 try: | 88 try: |
84 yield name | 89 yield name |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 # than using a single component. | 123 # than using a single component. |
119 for idl_filename in idl_paths_recursive(source_path): | 124 for idl_filename in idl_paths_recursive(source_path): |
120 compute_info_individual(idl_filename, 'tests') | 125 compute_info_individual(idl_filename, 'tests') |
121 info_individuals = [info_individual()] | 126 info_individuals = [info_individual()] |
122 compute_interfaces_info_overall(info_individuals) | 127 compute_interfaces_info_overall(info_individuals) |
123 | 128 |
124 | 129 |
125 def bindings_tests(output_directory, verbose): | 130 def bindings_tests(output_directory, verbose): |
126 executive = Executive() | 131 executive = Executive() |
127 | 132 |
| 133 def list_files(directory): |
| 134 files = [] |
| 135 for component in os.listdir(directory): |
| 136 if component not in COMPONENT_DIRECTORY: |
| 137 continue |
| 138 directory_with_component = os.path.join(directory, component) |
| 139 for filename in os.listdir(directory_with_component): |
| 140 files.append(os.path.join(directory_with_component, filename)) |
| 141 return files |
| 142 |
128 def diff(filename1, filename2): | 143 def diff(filename1, filename2): |
129 # Python's difflib module is too slow, especially on long output, so | 144 # Python's difflib module is too slow, especially on long output, so |
130 # run external diff(1) command | 145 # run external diff(1) command |
131 cmd = ['diff', | 146 cmd = ['diff', |
132 '-u', # unified format | 147 '-u', # unified format |
133 '-N', # treat absent files as empty | 148 '-N', # treat absent files as empty |
134 filename1, | 149 filename1, |
135 filename2] | 150 filename2] |
136 # Return output and don't raise exception, even though diff(1) has | 151 # Return output and don't raise exception, even though diff(1) has |
137 # non-zero exit if files differ. | 152 # non-zero exit if files differ. |
138 return executive.run_command(cmd, error_handler=lambda x: None) | 153 return executive.run_command(cmd, error_handler=lambda x: None) |
139 | 154 |
| 155 def is_cache_file(filename): |
| 156 if filename in PLY_LEX_YACC_FILES: |
| 157 return True |
| 158 if filename.endswith('.cache'): # Jinja |
| 159 return True |
| 160 return False |
| 161 |
140 def delete_cache_files(): | 162 def delete_cache_files(): |
141 # FIXME: Instead of deleting cache files, don't generate them. | 163 # FIXME: Instead of deleting cache files, don't generate them. |
142 cache_files = [os.path.join(output_directory, output_file) | 164 cache_files = [path for path in list_files(output_directory) |
143 for output_file in os.listdir(output_directory) | 165 if is_cache_file(os.path.basename(path))] |
144 if (output_file in ('lextab.py', # PLY lex | |
145 'lextab.pyc', | |
146 'parsetab.pickle') or # PLY yacc | |
147 output_file.endswith('.cache'))] # Jinja | |
148 for cache_file in cache_files: | 166 for cache_file in cache_files: |
149 os.remove(cache_file) | 167 os.remove(cache_file) |
150 | 168 |
151 def identical_file(reference_filename, output_filename): | 169 def identical_file(reference_filename, output_filename): |
152 reference_basename = os.path.basename(reference_filename) | 170 reference_basename = os.path.basename(reference_filename) |
153 | 171 |
154 if not os.path.isfile(reference_filename): | 172 if not os.path.isfile(reference_filename): |
155 print 'Missing reference file!' | 173 print 'Missing reference file!' |
156 print '(if adding new test, update reference files)' | 174 print '(if adding new test, update reference files)' |
157 print reference_basename | 175 print reference_basename |
158 print | 176 print |
159 return False | 177 return False |
160 | 178 |
161 if not filecmp.cmp(reference_filename, output_filename): | 179 if not filecmp.cmp(reference_filename, output_filename): |
162 # cmp is much faster than diff, and usual case is "no differance", | 180 # cmp is much faster than diff, and usual case is "no differance", |
163 # so only run diff if cmp detects a difference | 181 # so only run diff if cmp detects a difference |
164 print 'FAIL: %s' % reference_basename | 182 print 'FAIL: %s' % reference_basename |
165 print diff(reference_filename, output_filename) | 183 print diff(reference_filename, output_filename) |
166 return False | 184 return False |
167 | 185 |
168 if verbose: | 186 if verbose: |
169 print 'PASS: %s' % reference_basename | 187 print 'PASS: %s' % reference_basename |
170 return True | 188 return True |
171 | 189 |
172 def identical_output_files(): | 190 def identical_output_files(output_files): |
173 file_pairs = [(os.path.join(reference_directory, output_file), | 191 reference_files = [os.path.join(reference_directory, |
174 os.path.join(output_directory, output_file)) | 192 os.path.relpath(path, output_directory)) |
175 for output_file in os.listdir(output_directory)] | 193 for path in output_files] |
176 return all([identical_file(reference_filename, output_filename) | 194 return all([identical_file(reference_filename, output_filename) |
177 for (reference_filename, output_filename) in file_pairs]) | 195 for (reference_filename, output_filename) in zip(reference_f
iles, output_files)]) |
178 | 196 |
179 def no_excess_files(): | 197 def no_excess_files(output_files): |
180 generated_files = set(os.listdir(output_directory)) | 198 generated_files = set([os.path.relpath(path, output_directory) |
181 generated_files.add('.svn') # Subversion working copy directory | 199 for path in output_files]) |
182 excess_files = [output_file | 200 # Add subversion working copy directories in core and modules. |
183 for output_file in os.listdir(reference_directory) | 201 for component in COMPONENT_DIRECTORY: |
184 if output_file not in generated_files] | 202 generated_files.add(os.path.join(component, '.svn')) |
| 203 |
| 204 excess_files = [] |
| 205 for path in list_files(reference_directory): |
| 206 relpath = os.path.relpath(path, reference_directory) |
| 207 if relpath not in generated_files: |
| 208 excess_files.append(relpath) |
185 if excess_files: | 209 if excess_files: |
186 print ('Excess reference files! ' | 210 print ('Excess reference files! ' |
187 '(probably cruft from renaming or deleting):\n' + | 211 '(probably cruft from renaming or deleting):\n' + |
188 '\n'.join(excess_files)) | 212 '\n'.join(excess_files)) |
189 return False | 213 return False |
190 return True | 214 return True |
191 | 215 |
192 try: | 216 try: |
193 generate_interface_dependencies() | 217 generate_interface_dependencies() |
194 idl_compiler = IdlCompilerV8(output_directory, | 218 for component in COMPONENT_DIRECTORY: |
195 interfaces_info=interfaces_info, | 219 output_dir = os.path.join(output_directory, component) |
196 only_if_changed=True) | 220 if not os.path.exists(output_dir): |
197 dictionary_impl_compiler = IdlCompilerDictionaryImpl( | 221 os.makedirs(output_dir) |
198 output_directory, interfaces_info=interfaces_info, | |
199 only_if_changed=True) | |
200 | 222 |
201 idl_filenames = [] | 223 idl_compiler = IdlCompilerV8(output_dir, |
202 for component in COMPONENT_DIRECTORY: | 224 interfaces_info=interfaces_info, |
| 225 only_if_changed=True) |
| 226 dictionary_impl_compiler = IdlCompilerDictionaryImpl( |
| 227 output_dir, interfaces_info=interfaces_info, |
| 228 only_if_changed=True) |
| 229 |
| 230 idl_filenames = [] |
203 input_directory = os.path.join(test_input_directory, component) | 231 input_directory = os.path.join(test_input_directory, component) |
204 for filename in os.listdir(input_directory): | 232 for filename in os.listdir(input_directory): |
205 if (filename.endswith('.idl') and | 233 if (filename.endswith('.idl') and |
206 # Dependencies aren't built | 234 # Dependencies aren't built |
207 # (they are used by the dependent) | 235 # (they are used by the dependent) |
208 filename not in DEPENDENCY_IDL_FILES): | 236 filename not in DEPENDENCY_IDL_FILES): |
209 idl_filenames.append( | 237 idl_filenames.append( |
210 os.path.realpath( | 238 os.path.realpath( |
211 os.path.join(input_directory, filename))) | 239 os.path.join(input_directory, filename))) |
212 for idl_path in idl_filenames: | 240 for idl_path in idl_filenames: |
213 idl_basename = os.path.basename(idl_path) | 241 idl_basename = os.path.basename(idl_path) |
214 idl_compiler.compile_file(idl_path) | 242 idl_compiler.compile_file(idl_path) |
215 definition_name, _ = os.path.splitext(idl_basename) | 243 definition_name, _ = os.path.splitext(idl_basename) |
216 if (definition_name in interfaces_info and | 244 if (definition_name in interfaces_info and interfaces_info[defin
ition_name]['is_dictionary']): |
217 interfaces_info[definition_name]['is_dictionary']): | 245 dictionary_impl_compiler.compile_file(idl_path) |
218 dictionary_impl_compiler.compile_file(idl_path) | 246 if verbose: |
219 if verbose: | 247 print 'Compiled: %s' % idl_path |
220 print 'Compiled: %s' % idl_path | |
221 finally: | 248 finally: |
222 delete_cache_files() | 249 delete_cache_files() |
223 | 250 |
224 # Detect all changes | 251 # Detect all changes |
225 passed = identical_output_files() | 252 output_files = list_files(output_directory) |
226 passed &= no_excess_files() | 253 passed = identical_output_files(output_files) |
| 254 passed &= no_excess_files(output_files) |
227 | 255 |
228 if passed: | 256 if passed: |
229 if verbose: | 257 if verbose: |
230 print | 258 print |
231 print PASS_MESSAGE | 259 print PASS_MESSAGE |
232 return 0 | 260 return 0 |
233 print | 261 print |
234 print FAIL_MESSAGE | 262 print FAIL_MESSAGE |
235 return 1 | 263 return 1 |
236 | 264 |
237 | 265 |
238 def run_bindings_tests(reset_results, verbose): | 266 def run_bindings_tests(reset_results, verbose): |
239 # Generate output into the reference directory if resetting results, or | 267 # Generate output into the reference directory if resetting results, or |
240 # a temp directory if not. | 268 # a temp directory if not. |
241 if reset_results: | 269 if reset_results: |
242 print 'Resetting results' | 270 print 'Resetting results' |
243 return bindings_tests(reference_directory, verbose) | 271 return bindings_tests(reference_directory, verbose) |
244 with TemporaryDirectory() as temp_dir: | 272 with TemporaryDirectory() as temp_dir: |
245 return bindings_tests(temp_dir, verbose) | 273 return bindings_tests(temp_dir, verbose) |
OLD | NEW |