| #!/usr/bin/python | |
| import sys | |
| import time | |
| import os | |
| import string | |
| sys.path.insert(0, "python") | |
| import libxml2 | |
| test_nr = 0 | |
| test_succeed = 0 | |
| test_failed = 0 | |
| test_error = 0 | |
| # | |
| # the testsuite description | |
| # | |
| CONF="xml-test-suite/xmlconf/xmlconf.xml" | |
| LOG="check-xml-test-suite.log" | |
| log = open(LOG, "w") | |
| # | |
| # Error and warning handlers | |
| # | |
| error_nr = 0 | |
| error_msg = '' | |
| def errorHandler(ctx, str): | |
| global error_nr | |
| global error_msg | |
| error_nr = error_nr + 1 | |
| if len(error_msg) < 300: | |
| if len(error_msg) == 0 or error_msg[-1] == '\n': | |
| error_msg = error_msg + " >>" + str | |
| else: | |
| error_msg = error_msg + str | |
| libxml2.registerErrorHandler(errorHandler, None) | |
| #warning_nr = 0 | |
| #warning = '' | |
| #def warningHandler(ctx, str): | |
| # global warning_nr | |
| # global warning | |
| # | |
| # warning_nr = warning_nr + 1 | |
| # warning = warning + str | |
| # | |
| #libxml2.registerWarningHandler(warningHandler, None) | |
| # | |
| # Used to load the XML testsuite description | |
| # | |
| def loadNoentDoc(filename): | |
| ctxt = libxml2.createFileParserCtxt(filename) | |
| if ctxt == None: | |
| return None | |
| ctxt.replaceEntities(1) | |
| ctxt.parseDocument() | |
| try: | |
| doc = ctxt.doc() | |
| except: | |
| doc = None | |
| if ctxt.wellFormed() != 1: | |
| doc.freeDoc() | |
| return None | |
| return doc | |
| # | |
| # The conformance testing routines | |
| # | |
| def testNotWf(filename, id): | |
| global error_nr | |
| global error_msg | |
| global log | |
| error_nr = 0 | |
| error_msg = '' | |
| ctxt = libxml2.createFileParserCtxt(filename) | |
| if ctxt == None: | |
| return -1 | |
| ret = ctxt.parseDocument() | |
| try: | |
| doc = ctxt.doc() | |
| except: | |
| doc = None | |
| if doc != None: | |
| doc.freeDoc() | |
| if ret == 0 or ctxt.wellFormed() != 0: | |
| print "%s: error: Well Formedness error not detected" % (id) | |
| log.write("%s: error: Well Formedness error not detected\n" % (id)) | |
| return 0 | |
| return 1 | |
| def testNotWfEnt(filename, id): | |
| global error_nr | |
| global error_msg | |
| global log | |
| error_nr = 0 | |
| error_msg = '' | |
| ctxt = libxml2.createFileParserCtxt(filename) | |
| if ctxt == None: | |
| return -1 | |
| ctxt.replaceEntities(1) | |
| ret = ctxt.parseDocument() | |
| try: | |
| doc = ctxt.doc() | |
| except: | |
| doc = None | |
| if doc != None: | |
| doc.freeDoc() | |
| if ret == 0 or ctxt.wellFormed() != 0: | |
| print "%s: error: Well Formedness error not detected" % (id) | |
| log.write("%s: error: Well Formedness error not detected\n" % (id)) | |
| return 0 | |
| return 1 | |
| def testNotWfEntDtd(filename, id): | |
| global error_nr | |
| global error_msg | |
| global log | |
| error_nr = 0 | |
| error_msg = '' | |
| ctxt = libxml2.createFileParserCtxt(filename) | |
| if ctxt == None: | |
| return -1 | |
| ctxt.replaceEntities(1) | |
| ctxt.loadSubset(1) | |
| ret = ctxt.parseDocument() | |
| try: | |
| doc = ctxt.doc() | |
| except: | |
| doc = None | |
| if doc != None: | |
| doc.freeDoc() | |
| if ret == 0 or ctxt.wellFormed() != 0: | |
| print "%s: error: Well Formedness error not detected" % (id) | |
| log.write("%s: error: Well Formedness error not detected\n" % (id)) | |
| return 0 | |
| return 1 | |
| def testWfEntDtd(filename, id): | |
| global error_nr | |
| global error_msg | |
| global log | |
| error_nr = 0 | |
| error_msg = '' | |
| ctxt = libxml2.createFileParserCtxt(filename) | |
| if ctxt == None: | |
| return -1 | |
| ctxt.replaceEntities(1) | |
| ctxt.loadSubset(1) | |
| ret = ctxt.parseDocument() | |
| try: | |
| doc = ctxt.doc() | |
| except: | |
| doc = None | |
| if doc == None or ret != 0 or ctxt.wellFormed() == 0: | |
| print "%s: error: wrongly failed to parse the document" % (id) | |
| log.write("%s: error: wrongly failed to parse the document\n" % (id)) | |
| if doc != None: | |
| doc.freeDoc() | |
| return 0 | |
| if error_nr != 0: | |
| print "%s: warning: WF document generated an error msg" % (id) | |
| log.write("%s: error: WF document generated an error msg\n" % (id)) | |
| doc.freeDoc() | |
| return 2 | |
| doc.freeDoc() | |
| return 1 | |
| def testError(filename, id): | |
| global error_nr | |
| global error_msg | |
| global log | |
| error_nr = 0 | |
| error_msg = '' | |
| ctxt = libxml2.createFileParserCtxt(filename) | |
| if ctxt == None: | |
| return -1 | |
| ctxt.replaceEntities(1) | |
| ctxt.loadSubset(1) | |
| ret = ctxt.parseDocument() | |
| try: | |
| doc = ctxt.doc() | |
| except: | |
| doc = None | |
| if doc != None: | |
| doc.freeDoc() | |
| if ctxt.wellFormed() == 0: | |
| print "%s: warning: failed to parse the document but accepted" % (id) | |
| log.write("%s: warning: failed to parse the document but accepte\n" % (id)) | |
| return 2 | |
| if error_nr != 0: | |
| print "%s: warning: WF document generated an error msg" % (id) | |
| log.write("%s: error: WF document generated an error msg\n" % (id)) | |
| return 2 | |
| return 1 | |
| def testInvalid(filename, id): | |
| global error_nr | |
| global error_msg | |
| global log | |
| error_nr = 0 | |
| error_msg = '' | |
| ctxt = libxml2.createFileParserCtxt(filename) | |
| if ctxt == None: | |
| return -1 | |
| ctxt.validate(1) | |
| ret = ctxt.parseDocument() | |
| try: | |
| doc = ctxt.doc() | |
| except: | |
| doc = None | |
| valid = ctxt.isValid() | |
| if doc == None: | |
| print "%s: error: wrongly failed to parse the document" % (id) | |
| log.write("%s: error: wrongly failed to parse the document\n" % (id)) | |
| return 0 | |
| if valid == 1: | |
| print "%s: error: Validity error not detected" % (id) | |
| log.write("%s: error: Validity error not detected\n" % (id)) | |
| doc.freeDoc() | |
| return 0 | |
| if error_nr == 0: | |
| print "%s: warning: Validity error not reported" % (id) | |
| log.write("%s: warning: Validity error not reported\n" % (id)) | |
| doc.freeDoc() | |
| return 2 | |
| doc.freeDoc() | |
| return 1 | |
| def testValid(filename, id): | |
| global error_nr | |
| global error_msg | |
| error_nr = 0 | |
| error_msg = '' | |
| ctxt = libxml2.createFileParserCtxt(filename) | |
| if ctxt == None: | |
| return -1 | |
| ctxt.validate(1) | |
| ctxt.parseDocument() | |
| try: | |
| doc = ctxt.doc() | |
| except: | |
| doc = None | |
| valid = ctxt.isValid() | |
| if doc == None: | |
| print "%s: error: wrongly failed to parse the document" % (id) | |
| log.write("%s: error: wrongly failed to parse the document\n" % (id)) | |
| return 0 | |
| if valid != 1: | |
| print "%s: error: Validity check failed" % (id) | |
| log.write("%s: error: Validity check failed\n" % (id)) | |
| doc.freeDoc() | |
| return 0 | |
| if error_nr != 0 or valid != 1: | |
| print "%s: warning: valid document reported an error" % (id) | |
| log.write("%s: warning: valid document reported an error\n" % (id)) | |
| doc.freeDoc() | |
| return 2 | |
| doc.freeDoc() | |
| return 1 | |
| def runTest(test): | |
| global test_nr | |
| global test_succeed | |
| global test_failed | |
| global error_msg | |
| global log | |
| uri = test.prop('URI') | |
| id = test.prop('ID') | |
| if uri == None: | |
| print "Test without ID:", uri | |
| return -1 | |
| if id == None: | |
| print "Test without URI:", id | |
| return -1 | |
| base = test.getBase(None) | |
| URI = libxml2.buildURI(uri, base) | |
| if os.access(URI, os.R_OK) == 0: | |
| print "Test %s missing: base %s uri %s" % (URI, base, uri) | |
| return -1 | |
| type = test.prop('TYPE') | |
| if type == None: | |
| print "Test %s missing TYPE" % (id) | |
| return -1 | |
| extra = None | |
| if type == "invalid": | |
| res = testInvalid(URI, id) | |
| elif type == "valid": | |
| res = testValid(URI, id) | |
| elif type == "not-wf": | |
| extra = test.prop('ENTITIES') | |
| # print URI | |
| #if extra == None: | |
| # res = testNotWfEntDtd(URI, id) | |
| #elif extra == 'none': | |
| # res = testNotWf(URI, id) | |
| #elif extra == 'general': | |
| # res = testNotWfEnt(URI, id) | |
| #elif extra == 'both' or extra == 'parameter': | |
| res = testNotWfEntDtd(URI, id) | |
| #else: | |
| # print "Unknow value %s for an ENTITIES test value" % (extra) | |
| # return -1 | |
| elif type == "error": | |
| res = testError(URI, id) | |
| else: | |
| # TODO skipped for now | |
| return -1 | |
| test_nr = test_nr + 1 | |
| if res > 0: | |
| test_succeed = test_succeed + 1 | |
| elif res == 0: | |
| test_failed = test_failed + 1 | |
| elif res < 0: | |
| test_error = test_error + 1 | |
| # Log the ontext | |
| if res != 1: | |
| log.write(" File: %s\n" % (URI)) | |
| content = string.strip(test.content) | |
| while content[-1] == '\n': | |
| content = content[0:-1] | |
| if extra != None: | |
| log.write(" %s:%s:%s\n" % (type, extra, content)) | |
| else: | |
| log.write(" %s:%s\n\n" % (type, content)) | |
| if error_msg != '': | |
| log.write(" ----\n%s ----\n" % (error_msg)) | |
| error_msg = '' | |
| log.write("\n") | |
| return 0 | |
| def runTestCases(case): | |
| profile = case.prop('PROFILE') | |
| if profile != None and \ | |
| string.find(profile, "IBM XML Conformance Test Suite - Production") < 0: | |
| print "=>", profile | |
| test = case.children | |
| while test != None: | |
| if test.name == 'TEST': | |
| runTest(test) | |
| if test.name == 'TESTCASES': | |
| runTestCases(test) | |
| test = test.next | |
| conf = loadNoentDoc(CONF) | |
| if conf == None: | |
| print "Unable to load %s" % CONF | |
| sys.exit(1) | |
| testsuite = conf.getRootElement() | |
| if testsuite.name != 'TESTSUITE': | |
| print "Expecting TESTSUITE root element: aborting" | |
| sys.exit(1) | |
| profile = testsuite.prop('PROFILE') | |
| if profile != None: | |
| print profile | |
| start = time.time() | |
| case = testsuite.children | |
| while case != None: | |
| if case.name == 'TESTCASES': | |
| old_test_nr = test_nr | |
| old_test_succeed = test_succeed | |
| old_test_failed = test_failed | |
| old_test_error = test_error | |
| runTestCases(case) | |
| print " Ran %d tests: %d suceeded, %d failed and %d generated an error" % ( | |
| test_nr - old_test_nr, test_succeed - old_test_succeed, | |
| test_failed - old_test_failed, test_error - old_test_error) | |
| case = case.next | |
| conf.freeDoc() | |
| log.close() | |
| print "Ran %d tests: %d suceeded, %d failed and %d generated an error in %.2f s." % ( | |
| test_nr, test_succeed, test_failed, test_error, time.time() - start) |