mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2024-10-28 14:55:25 +03:00
8f597c3bf5
* check-xml-test-suite.py: fixing the script * parser.c: replace sequences of RAW && NXT(.) == '.' with memcmp calls, seems to not break conformance, slightly inflate the size of the gcc generated code though. Daniel
415 lines
9.5 KiB
Python
Executable File
415 lines
9.5 KiB
Python
Executable File
#!/usr/bin/python
|
|
import sys
|
|
import time
|
|
import os
|
|
import string
|
|
sys.path.append("python")
|
|
import libxml2
|
|
|
|
#
|
|
# 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
|
|
|
|
test_nr = 0
|
|
test_succeed = 0
|
|
test_failed = 0
|
|
test_error = 0
|
|
def runTest(test):
|
|
global test_nr
|
|
global test_failed
|
|
global test_error
|
|
global test_succeed
|
|
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:
|
|
global test_nr
|
|
global test_succeed
|
|
global test_failed
|
|
global test_error
|
|
|
|
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)
|