| 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 |