diff options
Diffstat (limited to 'tests/qapi-schema/test-qapi.py')
-rwxr-xr-x[-rw-r--r--] | tests/qapi-schema/test-qapi.py | 123 |
1 files changed, 106 insertions, 17 deletions
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py index b0f770b9bd..42baa702b6 100644..100755 --- a/tests/qapi-schema/test-qapi.py +++ b/tests/qapi-schema/test-qapi.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python # # QAPI parser test harness # @@ -11,7 +12,14 @@ # from __future__ import print_function +import argparse +import difflib +import os import sys +if sys.version_info[0] < 3: + from cStringIO import StringIO +else: + from io import StringIO from qapi.common import QAPIError, QAPISchema, QAPISchemaVisitor @@ -87,21 +95,102 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor): print('%sif %s' % (' ' * indent, ifcond)) -try: - schema = QAPISchema(sys.argv[1]) -except QAPIError as err: - print(err, file=sys.stderr) - exit(1) - -schema.visit(QAPISchemaTestVisitor()) - -for doc in schema.docs: - if doc.symbol: - print('doc symbol=%s' % doc.symbol) +def test_frontend(fname): + schema = QAPISchema(fname) + schema.visit(QAPISchemaTestVisitor()) + + for doc in schema.docs: + if doc.symbol: + print('doc symbol=%s' % doc.symbol) + else: + print('doc freeform') + print(' body=\n%s' % doc.body.text) + for arg, section in doc.args.items(): + print(' arg=%s\n%s' % (arg, section.text)) + for section in doc.sections: + print(' section=%s\n%s' % (section.name, section.text)) + + +def test_and_diff(test_name, dir_name, update): + sys.stdout = StringIO() + try: + test_frontend(os.path.join(dir_name, test_name + '.json')) + except QAPIError as err: + if err.info.fname is None: + print("%s" % err, file=sys.stderr) + return 2 + errstr = str(err) + '\n' + if dir_name: + errstr = errstr.replace(dir_name + '/', '') + actual_err = errstr.splitlines(True) else: - print('doc freeform') - print(' body=\n%s' % doc.body.text) - for arg, section in doc.args.items(): - print(' arg=%s\n%s' % (arg, section.text)) - for section in doc.sections: - print(' section=%s\n%s' % (section.name, section.text)) + actual_err = [] + finally: + actual_out = sys.stdout.getvalue().splitlines(True) + sys.stdout.close() + sys.stdout = sys.__stdout__ + + mode = 'r+' if update else 'r' + try: + outfp = open(os.path.join(dir_name, test_name + '.out'), mode) + errfp = open(os.path.join(dir_name, test_name + '.err'), mode) + expected_out = outfp.readlines() + expected_err = errfp.readlines() + except IOError as err: + print("%s: can't open '%s': %s" + % (sys.argv[0], err.filename, err.strerror), + file=sys.stderr) + return 2 + + if actual_out == expected_out and actual_err == expected_err: + return 0 + + print("%s %s" % (test_name, 'UPDATE' if update else 'FAIL'), + file=sys.stderr) + out_diff = difflib.unified_diff(expected_out, actual_out, outfp.name) + err_diff = difflib.unified_diff(expected_err, actual_err, errfp.name) + sys.stdout.writelines(out_diff) + sys.stdout.writelines(err_diff) + + if not update: + return 1 + + try: + outfp.truncate(0) + outfp.seek(0) + outfp.writelines(actual_out) + errfp.truncate(0) + errfp.seek(0) + errfp.writelines(actual_err) + except IOError as err: + print("%s: can't write '%s': %s" + % (sys.argv[0], err.filename, err.strerror), + file=sys.stderr) + return 2 + + return 0 + + +def main(argv): + parser = argparse.ArgumentParser( + description='QAPI schema tester') + parser.add_argument('-d', '--dir', action='store', default='', + help="directory containing tests") + parser.add_argument('-u', '--update', action='store_true', + help="update expected test results") + parser.add_argument('tests', nargs='*', metavar='TEST', action='store') + args = parser.parse_args() + + status = 0 + for t in args.tests: + (dir_name, base_name) = os.path.split(t) + dir_name = dir_name or args.dir + test_name = os.path.splitext(base_name)[0] + status |= test_and_diff(test_name, dir_name, args.update) + + exit(status) + + +if __name__ == '__main__': + main(sys.argv) + exit(0) |