410 lines
9.4 KiB
Python
Executable File
410 lines
9.4 KiB
Python
Executable File
#!/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)
|