Move run-bindings-tests implementation to webkitpy/bindings/main.py
[WebKit-https.git] / Tools / Scripts / webkitpy / bindings / main.py
1 #!/usr/bin/python
2 # Copyright (C) 2011 Google Inc.  All rights reserved.
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions
6 # are met:
7 # 1. Redistributions of source code must retain the above copyright
8 #    notice, this list of conditions and the following disclaimer.
9 # 2. Redistributions in binary form must reproduce the above copyright
10 #    notice, this list of conditions and the following disclaimer in the
11 #    documentation and/or other materials provided with the distribution.
12 #
13 # THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 # PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 #
25
26 import os
27 import os.path
28 import shutil
29 import subprocess
30 import sys
31 import tempfile
32 from webkitpy.common.checkout.scm.detection import detect_scm_system
33
34
35 class BindingsTests:
36
37     def __init__(self, reset_results, generators):
38         self.reset_results = reset_results
39         self.generators = generators
40
41     def generate_from_idl(self, generator, idl_file, output_directory, supplemental_dependency_file):
42         cmd = ['perl', '-w',
43                '-IWebCore/bindings/scripts',
44                'WebCore/bindings/scripts/generate-bindings.pl',
45                # idl include directories (path relative to generate-bindings.pl)
46                '--include', '.',
47                '--defines', 'TESTING_%s' % generator,
48                '--generator', generator,
49                '--outputDir', output_directory,
50                '--supplementalDependencyFile', supplemental_dependency_file,
51                idl_file]
52
53         process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
54         exit_code = process.wait()
55         output = process.communicate()[0]
56         if output:
57             print output
58         return exit_code
59
60     def generate_supplemental_dependency(self, input_directory, supplemental_dependency_file):
61         idl_files_list = tempfile.mkstemp()
62         for input_file in os.listdir(input_directory):
63             (name, extension) = os.path.splitext(input_file)
64             if extension != '.idl':
65                 continue
66             os.write(idl_files_list[0], os.path.join(input_directory, input_file) + "\n")
67         os.close(idl_files_list[0])
68
69         cmd = ['perl', '-w',
70                '-IWebCore/bindings/scripts',
71                'WebCore/bindings/scripts/resolve-supplemental.pl',
72                '--idlFilesList', idl_files_list[1],
73                '--defines', '',
74                '--supplementalDependencyFile', supplemental_dependency_file]
75         process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
76         exit_code = process.wait()
77         output = process.communicate()[0]
78         if output:
79             print output
80
81         os.remove(idl_files_list[1])
82         return exit_code
83
84     def detect_changes(self, generator, work_directory, reference_directory):
85         changes_found = False
86         for output_file in os.listdir(work_directory):
87             cmd = ['diff',
88                    '-u',
89                    '-N',
90                    os.path.join(reference_directory, output_file),
91                    os.path.join(work_directory, output_file)]
92
93             process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
94             process.wait()
95             output = process.communicate()[0]
96             if output:
97                 print 'FAIL: (%s) %s' % (generator, output_file)
98                 print output
99                 changes_found = True
100             else:
101                 print 'PASS: (%s) %s' % (generator, output_file)
102
103         return changes_found
104
105     def run_tests(self, generator, input_directory, reference_directory, supplemental_dependency_file):
106         work_directory = reference_directory
107
108         passed = True
109         for input_file in os.listdir(input_directory):
110             (name, extension) = os.path.splitext(input_file)
111             if extension != '.idl':
112                 continue
113             # Generate output into the work directory (either the given one or a
114             # temp one if not reset_results is performed)
115             if not self.reset_results:
116                 work_directory = tempfile.mkdtemp()
117
118             if self.generate_from_idl(generator,
119                                       os.path.join(input_directory, input_file),
120                                       work_directory,
121                                       supplemental_dependency_file):
122                 passed = False
123
124             if self.reset_results:
125                 print "Reset results: (%s) %s" % (generator, input_file)
126                 continue
127
128             # Detect changes
129             if self.detect_changes(generator, work_directory, reference_directory):
130                 passed = False
131             shutil.rmtree(work_directory)
132
133         return passed
134
135     def main(self):
136         current_scm = detect_scm_system(os.curdir)
137         os.chdir(os.path.join(current_scm.checkout_root, 'Source'))
138
139         all_tests_passed = True
140
141         input_directory = os.path.join('WebCore', 'bindings', 'scripts', 'test')
142         supplemental_dependency_file = tempfile.mkstemp()[1]
143         if self.generate_supplemental_dependency(input_directory, supplemental_dependency_file):
144             print 'Failed to generate a supplemental dependency file.'
145             os.remove(supplemental_dependency_file)
146             return -1
147
148         for generator in self.generators:
149             input_directory = os.path.join('WebCore', 'bindings', 'scripts', 'test')
150             reference_directory = os.path.join('WebCore', 'bindings', 'scripts', 'test', generator)
151             if not self.run_tests(generator, input_directory, reference_directory, supplemental_dependency_file):
152                 all_tests_passed = False
153
154         os.remove(supplemental_dependency_file)
155         print ''
156         if all_tests_passed:
157             print 'All tests PASS!'
158             return 0
159         else:
160             print 'Some tests FAIL! (To update the reference files, execute "run-bindings-tests --reset-results")'
161             return -1