af541f0c785cc803a03df05fd896de8ae6243ce8
[WebKit-https.git] / Tools / Scripts / webkitpy / bindings / main.py
1 # Copyright (C) 2011 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 os
26 import os.path
27 import shutil
28 import subprocess
29 import sys
30 import tempfile
31 from webkitpy.common.checkout.scm.detection import detect_scm_system
32 from webkitpy.common.system.executive import ScriptError
33
34
35 class BindingsTests:
36
37     def __init__(self, reset_results, generators, executive):
38         self.reset_results = reset_results
39         self.generators = generators
40         self.executive = executive
41
42     def generate_from_idl(self, generator, idl_file, output_directory, supplemental_dependency_file):
43         cmd = ['perl', '-w',
44                '-IWebCore/bindings/scripts',
45                'WebCore/bindings/scripts/generate-bindings.pl',
46                # idl include directories (path relative to generate-bindings.pl)
47                '--include', '.',
48                '--defines', 'TESTING_%s' % generator,
49                '--generator', generator,
50                '--outputDir', output_directory,
51                '--supplementalDependencyFile', supplemental_dependency_file,
52                idl_file]
53
54         exit_code = 0
55         try:
56             output = self.executive.run_command(cmd)
57             if output:
58                 print output
59         except ScriptError, e:
60             print e.output
61             exit_code = e.exit_code
62         return exit_code
63
64     def generate_supplemental_dependency(self, input_directory, supplemental_dependency_file):
65         idl_files_list = tempfile.mkstemp()
66         for input_file in os.listdir(input_directory):
67             (name, extension) = os.path.splitext(input_file)
68             if extension != '.idl':
69                 continue
70             os.write(idl_files_list[0], os.path.join(input_directory, input_file) + "\n")
71         os.close(idl_files_list[0])
72
73         cmd = ['perl', '-w',
74                '-IWebCore/bindings/scripts',
75                'WebCore/bindings/scripts/preprocess-idls.pl',
76                '--idlFilesList', idl_files_list[1],
77                '--defines', '',
78                '--supplementalDependencyFile', supplemental_dependency_file]
79
80         exit_code = 0
81         try:
82             output = self.executive.run_command(cmd)
83             if output:
84                 print output
85         except ScriptError, e:
86             print e.output
87             exit_code = e.exit_code
88         os.remove(idl_files_list[1])
89         return exit_code
90
91     def detect_changes(self, generator, work_directory, reference_directory):
92         changes_found = False
93         for output_file in os.listdir(work_directory):
94             cmd = ['diff',
95                    '-u',
96                    '-N',
97                    os.path.join(reference_directory, output_file),
98                    os.path.join(work_directory, output_file)]
99
100             exit_code = 0
101             try:
102                 output = self.executive.run_command(cmd)
103             except ScriptError, e:
104                 output = e.output
105                 exit_code = e.exit_code
106
107             if exit_code or output:
108                 print 'FAIL: (%s) %s' % (generator, output_file)
109                 print output
110                 changes_found = True
111             else:
112                 print 'PASS: (%s) %s' % (generator, output_file)
113         return changes_found
114
115     def run_tests(self, generator, input_directory, reference_directory, supplemental_dependency_file):
116         work_directory = reference_directory
117
118         passed = True
119         for input_file in os.listdir(input_directory):
120             (name, extension) = os.path.splitext(input_file)
121             if extension != '.idl':
122                 continue
123             # Generate output into the work directory (either the given one or a
124             # temp one if not reset_results is performed)
125             if not self.reset_results:
126                 work_directory = tempfile.mkdtemp()
127
128             if self.generate_from_idl(generator,
129                                       os.path.join(input_directory, input_file),
130                                       work_directory,
131                                       supplemental_dependency_file):
132                 passed = False
133
134             if self.reset_results:
135                 print "Reset results: (%s) %s" % (generator, input_file)
136                 continue
137
138             # Detect changes
139             if self.detect_changes(generator, work_directory, reference_directory):
140                 passed = False
141             shutil.rmtree(work_directory)
142
143         return passed
144
145     def main(self):
146         current_scm = detect_scm_system(os.curdir)
147         os.chdir(os.path.join(current_scm.checkout_root, 'Source'))
148
149         all_tests_passed = True
150
151         input_directory = os.path.join('WebCore', 'bindings', 'scripts', 'test')
152         supplemental_dependency_file = tempfile.mkstemp()[1]
153         if self.generate_supplemental_dependency(input_directory, supplemental_dependency_file):
154             print 'Failed to generate a supplemental dependency file.'
155             os.remove(supplemental_dependency_file)
156             return -1
157
158         for generator in self.generators:
159             input_directory = os.path.join('WebCore', 'bindings', 'scripts', 'test')
160             reference_directory = os.path.join('WebCore', 'bindings', 'scripts', 'test', generator)
161             if not self.run_tests(generator, input_directory, reference_directory, supplemental_dependency_file):
162                 all_tests_passed = False
163
164         os.remove(supplemental_dependency_file)
165         print ''
166         if all_tests_passed:
167             print 'All tests PASS!'
168             return 0
169         else:
170             print 'Some tests FAIL! (To update the reference files, execute "run-bindings-tests --reset-results")'
171             return -1