3 # Copyright © 2018 Intel Corporation
5 # Permission is hereby granted, free of charge, to any person obtaining a copy
6 # of this software and associated documentation files (the "Software"), to deal
7 # in the Software without restriction, including without limitation the rights
8 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 # copies of the Software, and to permit persons to whom the Software is
10 # furnished to do so, subject to the following conditions:
12 # The above copyright notice and this permission notice shall be included in
13 # all copies or substantial portions of the Software.
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 """Run glcpp tests with various line endings."""
25 from __future__
import print_function
36 parser
= argparse
.ArgumentParser()
37 parser
.add_argument('glcpp', help='Path to the he glcpp binary.')
38 parser
.add_argument('testdir', help='Path to tests and expected output.')
39 parser
.add_argument('--unix', action
='store_true', help='Run tests for Unix style newlines')
40 parser
.add_argument('--windows', action
='store_true', help='Run tests for Windows/Dos style newlines')
41 parser
.add_argument('--oldmac', action
='store_true', help='Run tests for Old Mac (pre-OSX) style newlines')
42 parser
.add_argument('--bizarro', action
='store_true', help='Run tests for Bizarro world style newlines')
43 parser
.add_argument('--valgrind', action
='store_true', help='Run with valgrind for errors')
44 return parser
.parse_args()
47 def parse_test_file(filename
, nl_format
):
48 """Check for any special arguments and return them as a list."""
49 # Disable "universal newlines" mode; we can't directly use `nl_format` as
50 # the `newline` argument, because the "bizarro" test uses something Python
52 with io
.open(filename
, newline
='') as f
:
53 for l
in f
.read().split(nl_format
):
54 if 'glcpp-args:' in l
:
55 return l
.split('glcpp-args:')[1].strip().split()
59 def test_output(glcpp
, filename
, expfile
, nl_format
='\n'):
60 """Test that the output of glcpp is what we expect."""
61 extra_args
= parse_test_file(filename
, nl_format
)
63 with
open(filename
, 'rb') as f
:
64 proc
= subprocess
.Popen(
66 stdout
=subprocess
.PIPE
,
67 stderr
=subprocess
.STDOUT
,
68 stdin
=subprocess
.PIPE
)
69 actual
, _
= proc
.communicate(f
.read())
70 actual
= actual
.decode('utf-8')
72 with
open(expfile
, 'r') as f
:
75 if actual
== expected
:
77 return (False, difflib
.unified_diff(actual
.splitlines(), expected
.splitlines()))
80 def _valgrind(glcpp
, filename
):
81 """Run valgrind and report any warnings."""
82 extra_args
= parse_test_file(filename
, nl_format
='\n')
85 fd
, tmpfile
= tempfile
.mkstemp()
87 with
open(filename
, 'rb') as f
:
88 proc
= subprocess
.Popen(
89 ['valgrind', '--error-exitcode=31', '--log-file', tmpfile
, glcpp
] + extra_args
,
90 stdout
=subprocess
.PIPE
,
91 stderr
=subprocess
.STDOUT
,
92 stdin
=subprocess
.PIPE
)
93 proc
.communicate(f
.read())
94 if proc
.returncode
!= 31:
96 with
open(tmpfile
, 'rb') as f
:
98 return (False, contents
)
104 """Test files with unix style (\n) new lines."""
108 print('============= Testing for Correctness (Unix) =============')
109 for filename
in os
.listdir(args
.testdir
):
110 if not filename
.endswith('.c'):
113 print( '{}:'.format(os
.path
.splitext(filename
)[0]), end
=' ')
116 testfile
= os
.path
.join(args
.testdir
, filename
)
117 valid
, diff
= test_output(args
.glcpp
, testfile
, testfile
+ '.expected')
124 print(l
, file=sys
.stderr
)
127 raise Exception('Could not find any tests.')
129 print('{}/{}'.format(passed
, total
), 'tests returned correct results')
130 return total
== passed
133 def _replace_test(args
, replace
):
134 """Test files with non-unix style line endings. Print your own header."""
138 for filename
in os
.listdir(args
.testdir
):
139 if not filename
.endswith('.c'):
142 print( '{}:'.format(os
.path
.splitext(filename
)[0]), end
=' ')
144 testfile
= os
.path
.join(args
.testdir
, filename
)
146 fd
, tmpfile
= tempfile
.mkstemp()
148 with io
.open(testfile
, 'rt') as f
:
150 with io
.open(tmpfile
, 'wt') as f
:
151 f
.write(contents
.replace('\n', replace
))
152 valid
, diff
= test_output(
153 args
.glcpp
, tmpfile
, testfile
+ '.expected', nl_format
=replace
)
163 print(l
, file=sys
.stderr
)
166 raise Exception('Could not find any tests.')
168 print('{}/{}'.format(passed
, total
), 'tests returned correct results')
169 return total
== passed
172 def test_windows(args
):
173 """Test files with windows/dos style (\r\n) new lines."""
174 print('============= Testing for Correctness (Windows) =============')
175 return _replace_test(args
, '\r\n')
178 def test_oldmac(args
):
179 """Test files with Old Mac style (\r) new lines."""
180 print('============= Testing for Correctness (Old Mac) =============')
181 return _replace_test(args
, '\r')
184 def test_bizarro(args
):
185 """Test files with Bizarro world style (\n\r) new lines."""
186 # This is allowed by the spec, but why?
187 print('============= Testing for Correctness (Bizarro) =============')
188 return _replace_test(args
, '\n\r')
191 def test_valgrind(args
):
195 print('============= Testing for Valgrind Warnings =============')
196 for filename
in os
.listdir(args
.testdir
):
197 if not filename
.endswith('.c'):
200 print( '{}:'.format(os
.path
.splitext(filename
)[0]), end
=' ')
202 valid
, log
= _valgrind(args
.glcpp
, os
.path
.join(args
.testdir
, filename
))
208 print(log
, file=sys
.stderr
)
211 raise Exception('Could not find any tests.')
213 print('{}/{}'.format(passed
, total
), 'tests returned correct results')
214 return total
== passed
222 success
= success
and test_unix(args
)
224 success
= success
and test_windows(args
)
226 success
= success
and test_oldmac(args
)
228 success
= success
and test_bizarro(args
)
230 success
= success
and test_valgrind(args
)
232 exit(0 if success
else 1)
235 if __name__
== '__main__':