@@ -73,16 +73,22 @@ _bname = os.path.basename
73
73
class ComplianceTestRunner (object ):
74
74
TEST_DIR = _pjoin (_dname (_dname (_abs (__file__ ))), 'tests' )
75
75
76
- def __init__ (self , exe = None , tests = None , test_dir = TEST_DIR ):
76
+ def __init__ (self , exe = None , tests = None , test_dir = None ):
77
+ if test_dir is None :
78
+ test_dir = self .TEST_DIR
77
79
self .test_dir = test_dir
78
80
self .tests = tests
79
81
self .jp_executable = exe
82
+ self .had_failures = False
80
83
81
84
def run_tests (self , stop_first_fail ):
82
85
for test_case in self ._test_cases ():
83
86
if self ._should_run (test_case ):
84
- if not self ._run_test (test_case ) and stop_first_fail :
85
- return
87
+ test_passed = self ._run_test (test_case )
88
+ if not test_passed :
89
+ self .had_failures = True
90
+ if stop_first_fail :
91
+ return
86
92
87
93
def _should_run (self , test_case ):
88
94
if not self .tests :
@@ -151,16 +157,36 @@ class ComplianceTestRunner(object):
151
157
sys .stdout .flush ()
152
158
return True
153
159
else :
154
- error_type = test_case ['error' ]
160
+ # This is a test case for errors.
161
+ if process .returncode == 0 :
162
+ self ._show_failure_for_zero_rc (stderr , process .returncode ,
163
+ test_case )
155
164
# For errors, we expect the error type on stderr.
156
- if error_type not in stderr :
165
+ if not self . _passes_error_test ( test_case [ 'error' ], stderr ) :
157
166
self ._show_failure_for_error (stderr , test_case )
158
167
return False
159
168
else :
160
169
sys .stdout .write ('.' )
161
170
sys .stdout .flush ()
162
171
return True
163
172
173
+ def _passes_error_test (self , error_type , stderr ):
174
+ # Each tool will have different error messages, so we don't
175
+ # want to be super strict about what's allowed.
176
+ #
177
+ # Simplest case, the error_type appears in stderr, case insensitive.
178
+ if error_type not in stderr .lower ():
179
+ return True
180
+ # Second case, all the parts of the error appear in stderr.
181
+ # Also case insensitive.
182
+ # An error_type will be '-' separated: invalid-type
183
+ # So a test can pass as long as "invalid" and "type" appear
184
+ # in stderr (case insensitive).
185
+ error_parts = error_type .split ('-' )
186
+ if all (p in stderr .lower () for p in error_parts ):
187
+ return True
188
+ return False
189
+
164
190
def _show_failure (self , actual , test_case ):
165
191
test_case ['actual' ] = json .dumps (actual )
166
192
test_case ['result' ] = json .dumps (test_case ['result' ])
@@ -174,6 +200,17 @@ class ComplianceTestRunner(object):
174
200
).format (** test_case )
175
201
sys .stdout .write (failure_message )
176
202
203
+ def _show_failure_for_zero_rc (self , stderr , return_code , test_case ):
204
+ test_case ['stderr' ] = stderr
205
+ test_case ['returncode' ] = return_code
206
+ failure_message = (
207
+ "\n FAIL {category},{group_number},{test_number}\n "
208
+ "The expression: {expression}\n "
209
+ "was suppose to have non zero for error error: {error}\n "
210
+ "but instead gave rc of: {returncode}, stderr: \n {stderr}\n "
211
+ ).format (** test_case )
212
+ sys .stdout .write (failure_message )
213
+
177
214
def _show_failure_for_error (self , stderr , test_case ):
178
215
test_case ['stderr' ] = stderr
179
216
failure_message = (
@@ -218,6 +255,8 @@ def main():
218
255
parser .add_argument ('-t' , '--tests' , help = (
219
256
'The compliance tests to run. If this value is not provided, '
220
257
'then all compliance tests are run.' ), type = test_spec , nargs = '+' )
258
+ parser .add_argument ('-d' , '--test-dir' ,
259
+ help = 'The directory containing compliance tests.' )
221
260
parser .add_argument ('-l' , '--list' , action = "store_true" ,
222
261
help = ('List the available compliance tests to run. '
223
262
'These values can then be used with the '
@@ -226,7 +265,7 @@ def main():
226
265
parser .add_argument ('-s' , '--stop-first-fail' , action = 'store_true' ,
227
266
help = 'Stop running tests after a single test fails.' )
228
267
args = parser .parse_args ()
229
- runner = ComplianceTestRunner (args .exe , args .tests )
268
+ runner = ComplianceTestRunner (args .exe , args .tests , args . test_dir )
230
269
if args .list :
231
270
display_available_tests (runner .get_compliance_test_files ())
232
271
else :
@@ -237,6 +276,10 @@ def main():
237
276
sys .stderr .write ("\n " )
238
277
return 1
239
278
sys .stdout .write ('\n ' )
279
+ if runner .had_failures :
280
+ sys .stdout .write ('FAIL\n ' )
281
+ return 1
282
+ sys .stdout .write ('OK\n ' )
240
283
return 0
241
284
242
285
0 commit comments