Skip to content

Commit 1b14f00

Browse files
committed
Add testdir argument and non-zero rc on fail
1 parent c40bcea commit 1b14f00

File tree

1 file changed

+49
-6
lines changed

1 file changed

+49
-6
lines changed

bin/jp-compliance

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,22 @@ _bname = os.path.basename
7373
class ComplianceTestRunner(object):
7474
TEST_DIR = _pjoin(_dname(_dname(_abs(__file__))), 'tests')
7575

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
7779
self.test_dir = test_dir
7880
self.tests = tests
7981
self.jp_executable = exe
82+
self.had_failures = False
8083

8184
def run_tests(self, stop_first_fail):
8285
for test_case in self._test_cases():
8386
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
8692

8793
def _should_run(self, test_case):
8894
if not self.tests:
@@ -151,16 +157,36 @@ class ComplianceTestRunner(object):
151157
sys.stdout.flush()
152158
return True
153159
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)
155164
# 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):
157166
self._show_failure_for_error(stderr, test_case)
158167
return False
159168
else:
160169
sys.stdout.write('.')
161170
sys.stdout.flush()
162171
return True
163172

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+
164190
def _show_failure(self, actual, test_case):
165191
test_case['actual'] = json.dumps(actual)
166192
test_case['result'] = json.dumps(test_case['result'])
@@ -174,6 +200,17 @@ class ComplianceTestRunner(object):
174200
).format(**test_case)
175201
sys.stdout.write(failure_message)
176202

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+
"\nFAIL {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+
177214
def _show_failure_for_error(self, stderr, test_case):
178215
test_case['stderr'] = stderr
179216
failure_message = (
@@ -218,6 +255,8 @@ def main():
218255
parser.add_argument('-t', '--tests', help=(
219256
'The compliance tests to run. If this value is not provided, '
220257
'then all compliance tests are run.'), type=test_spec, nargs='+')
258+
parser.add_argument('-d', '--test-dir',
259+
help='The directory containing compliance tests.')
221260
parser.add_argument('-l', '--list', action="store_true",
222261
help=('List the available compliance tests to run. '
223262
'These values can then be used with the '
@@ -226,7 +265,7 @@ def main():
226265
parser.add_argument('-s', '--stop-first-fail', action='store_true',
227266
help='Stop running tests after a single test fails.')
228267
args = parser.parse_args()
229-
runner = ComplianceTestRunner(args.exe, args.tests)
268+
runner = ComplianceTestRunner(args.exe, args.tests, args.test_dir)
230269
if args.list:
231270
display_available_tests(runner.get_compliance_test_files())
232271
else:
@@ -237,6 +276,10 @@ def main():
237276
sys.stderr.write("\n")
238277
return 1
239278
sys.stdout.write('\n')
279+
if runner.had_failures:
280+
sys.stdout.write('FAIL\n')
281+
return 1
282+
sys.stdout.write('OK\n')
240283
return 0
241284

242285

0 commit comments

Comments
 (0)