Blame check-xml-test-suite.py

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