Home | History | Annotate | Download | only in libxml2
      1 #!/usr/bin/python
      2 import sys
      3 import time
      4 import os
      5 import string
      6 sys.path.insert(0, "python")
      7 import libxml2
      8 
      9 test_nr = 0
     10 test_succeed = 0
     11 test_failed = 0
     12 test_error = 0
     13 
     14 #
     15 # the testsuite description
     16 #
     17 CONF="xml-test-suite/xmlconf/xmlconf.xml"
     18 LOG="check-xml-test-suite.log"
     19 
     20 log = open(LOG, "w")
     21 
     22 #
     23 # Error and warning handlers
     24 #
     25 error_nr = 0
     26 error_msg = ''
     27 def errorHandler(ctx, str):
     28     global error_nr
     29     global error_msg
     30 
     31     error_nr = error_nr + 1
     32     if len(error_msg) < 300:
     33         if len(error_msg) == 0 or error_msg[-1] == '\n':
     34 	    error_msg = error_msg + "   >>" + str
     35 	else:
     36 	    error_msg = error_msg + str
     37 
     38 libxml2.registerErrorHandler(errorHandler, None)
     39 
     40 #warning_nr = 0
     41 #warning = ''
     42 #def warningHandler(ctx, str):
     43 #    global warning_nr
     44 #    global warning
     45 #
     46 #    warning_nr = warning_nr + 1
     47 #    warning = warning + str
     48 #
     49 #libxml2.registerWarningHandler(warningHandler, None)
     50 
     51 #
     52 # Used to load the XML testsuite description
     53 #
     54 def loadNoentDoc(filename):
     55     ctxt = libxml2.createFileParserCtxt(filename)
     56     if ctxt == None:
     57         return None
     58     ctxt.replaceEntities(1)
     59     ctxt.parseDocument()
     60     try:
     61 	doc = ctxt.doc()
     62     except:
     63         doc = None
     64     if ctxt.wellFormed() != 1:
     65         doc.freeDoc()
     66 	return None
     67     return doc
     68 
     69 #
     70 # The conformance testing routines
     71 #
     72 
     73 def testNotWf(filename, id):
     74     global error_nr
     75     global error_msg
     76     global log
     77 
     78     error_nr = 0
     79     error_msg = ''
     80 
     81     ctxt = libxml2.createFileParserCtxt(filename)
     82     if ctxt == None:
     83         return -1
     84     ret = ctxt.parseDocument()
     85 
     86     try:
     87 	doc = ctxt.doc()
     88     except:
     89         doc = None
     90     if doc != None:
     91 	doc.freeDoc()
     92     if ret == 0 or ctxt.wellFormed() != 0:
     93         print "%s: error: Well Formedness error not detected" % (id)
     94 	log.write("%s: error: Well Formedness error not detected\n" % (id))
     95 	return 0
     96     return 1
     97 
     98 def testNotWfEnt(filename, id):
     99     global error_nr
    100     global error_msg
    101     global log
    102 
    103     error_nr = 0
    104     error_msg = ''
    105 
    106     ctxt = libxml2.createFileParserCtxt(filename)
    107     if ctxt == None:
    108         return -1
    109     ctxt.replaceEntities(1)
    110     ret = ctxt.parseDocument()
    111 
    112     try:
    113 	doc = ctxt.doc()
    114     except:
    115         doc = None
    116     if doc != None:
    117 	doc.freeDoc()
    118     if ret == 0 or ctxt.wellFormed() != 0:
    119         print "%s: error: Well Formedness error not detected" % (id)
    120 	log.write("%s: error: Well Formedness error not detected\n" % (id))
    121 	return 0
    122     return 1
    123 
    124 def testNotWfEntDtd(filename, id):
    125     global error_nr
    126     global error_msg
    127     global log
    128 
    129     error_nr = 0
    130     error_msg = ''
    131 
    132     ctxt = libxml2.createFileParserCtxt(filename)
    133     if ctxt == None:
    134         return -1
    135     ctxt.replaceEntities(1)
    136     ctxt.loadSubset(1)
    137     ret = ctxt.parseDocument()
    138 
    139     try:
    140 	doc = ctxt.doc()
    141     except:
    142         doc = None
    143     if doc != None:
    144 	doc.freeDoc()
    145     if ret == 0 or ctxt.wellFormed() != 0:
    146         print "%s: error: Well Formedness error not detected" % (id)
    147 	log.write("%s: error: Well Formedness error not detected\n" % (id))
    148 	return 0
    149     return 1
    150 
    151 def testWfEntDtd(filename, id):
    152     global error_nr
    153     global error_msg
    154     global log
    155 
    156     error_nr = 0
    157     error_msg = ''
    158 
    159     ctxt = libxml2.createFileParserCtxt(filename)
    160     if ctxt == None:
    161         return -1
    162     ctxt.replaceEntities(1)
    163     ctxt.loadSubset(1)
    164     ret = ctxt.parseDocument()
    165 
    166     try:
    167 	doc = ctxt.doc()
    168     except:
    169         doc = None
    170     if doc == None or ret != 0 or ctxt.wellFormed() == 0:
    171         print "%s: error: wrongly failed to parse the document" % (id)
    172 	log.write("%s: error: wrongly failed to parse the document\n" % (id))
    173 	if doc != None:
    174 	    doc.freeDoc()
    175 	return 0
    176     if error_nr != 0:
    177         print "%s: warning: WF document generated an error msg" % (id)
    178 	log.write("%s: error: WF document generated an error msg\n" % (id))
    179 	doc.freeDoc()
    180 	return 2
    181     doc.freeDoc()
    182     return 1
    183 
    184 def testError(filename, id):
    185     global error_nr
    186     global error_msg
    187     global log
    188 
    189     error_nr = 0
    190     error_msg = ''
    191 
    192     ctxt = libxml2.createFileParserCtxt(filename)
    193     if ctxt == None:
    194         return -1
    195     ctxt.replaceEntities(1)
    196     ctxt.loadSubset(1)
    197     ret = ctxt.parseDocument()
    198 
    199     try:
    200 	doc = ctxt.doc()
    201     except:
    202         doc = None
    203     if doc != None:
    204 	doc.freeDoc()
    205     if ctxt.wellFormed() == 0:
    206         print "%s: warning: failed to parse the document but accepted" % (id)
    207 	log.write("%s: warning: failed to parse the document but accepte\n" % (id))
    208 	return 2
    209     if error_nr != 0:
    210         print "%s: warning: WF document generated an error msg" % (id)
    211 	log.write("%s: error: WF document generated an error msg\n" % (id))
    212 	return 2
    213     return 1
    214 
    215 def testInvalid(filename, id):
    216     global error_nr
    217     global error_msg
    218     global log
    219 
    220     error_nr = 0
    221     error_msg = ''
    222 
    223     ctxt = libxml2.createFileParserCtxt(filename)
    224     if ctxt == None:
    225         return -1
    226     ctxt.validate(1)
    227     ret = ctxt.parseDocument()
    228 
    229     try:
    230 	doc = ctxt.doc()
    231     except:
    232         doc = None
    233     valid = ctxt.isValid()
    234     if doc == None:
    235         print "%s: error: wrongly failed to parse the document" % (id)
    236 	log.write("%s: error: wrongly failed to parse the document\n" % (id))
    237 	return 0
    238     if valid == 1:
    239         print "%s: error: Validity error not detected" % (id)
    240 	log.write("%s: error: Validity error not detected\n" % (id))
    241 	doc.freeDoc()
    242 	return 0
    243     if error_nr == 0:
    244         print "%s: warning: Validity error not reported" % (id)
    245 	log.write("%s: warning: Validity error not reported\n" % (id))
    246 	doc.freeDoc()
    247 	return 2
    248         
    249     doc.freeDoc()
    250     return 1
    251 
    252 def testValid(filename, id):
    253     global error_nr
    254     global error_msg
    255 
    256     error_nr = 0
    257     error_msg = ''
    258 
    259     ctxt = libxml2.createFileParserCtxt(filename)
    260     if ctxt == None:
    261         return -1
    262     ctxt.validate(1)
    263     ctxt.parseDocument()
    264 
    265     try:
    266 	doc = ctxt.doc()
    267     except:
    268         doc = None
    269     valid = ctxt.isValid()
    270     if doc == None:
    271         print "%s: error: wrongly failed to parse the document" % (id)
    272 	log.write("%s: error: wrongly failed to parse the document\n" % (id))
    273 	return 0
    274     if valid != 1:
    275         print "%s: error: Validity check failed" % (id)
    276 	log.write("%s: error: Validity check failed\n" % (id))
    277 	doc.freeDoc()
    278 	return 0
    279     if error_nr != 0 or valid != 1:
    280         print "%s: warning: valid document reported an error" % (id)
    281 	log.write("%s: warning: valid document reported an error\n" % (id))
    282 	doc.freeDoc()
    283 	return 2
    284     doc.freeDoc()
    285     return 1
    286 
    287 def runTest(test):
    288     global test_nr
    289     global test_succeed
    290     global test_failed
    291     global error_msg
    292     global log
    293 
    294     uri = test.prop('URI')
    295     id = test.prop('ID')
    296     if uri == None:
    297         print "Test without ID:", uri
    298 	return -1
    299     if id == None:
    300         print "Test without URI:", id
    301 	return -1
    302     base = test.getBase(None)
    303     URI = libxml2.buildURI(uri, base)
    304     if os.access(URI, os.R_OK) == 0:
    305         print "Test %s missing: base %s uri %s" % (URI, base, uri)
    306 	return -1
    307     type = test.prop('TYPE')
    308     if type == None:
    309         print "Test %s missing TYPE" % (id)
    310 	return -1
    311 
    312     extra = None
    313     if type == "invalid":
    314         res = testInvalid(URI, id)
    315     elif type == "valid":
    316         res = testValid(URI, id)
    317     elif type == "not-wf":
    318         extra =  test.prop('ENTITIES')
    319 	# print URI
    320 	#if extra == None:
    321 	#    res = testNotWfEntDtd(URI, id)
    322  	#elif extra == 'none':
    323 	#    res = testNotWf(URI, id)
    324 	#elif extra == 'general':
    325 	#    res = testNotWfEnt(URI, id)
    326 	#elif extra == 'both' or extra == 'parameter':
    327 	res = testNotWfEntDtd(URI, id)
    328 	#else:
    329 	#    print "Unknow value %s for an ENTITIES test value" % (extra)
    330 	#    return -1
    331     elif type == "error":
    332 	res = testError(URI, id)
    333     else:
    334         # TODO skipped for now
    335 	return -1
    336 
    337     test_nr = test_nr + 1
    338     if res > 0:
    339 	test_succeed = test_succeed + 1
    340     elif res == 0:
    341 	test_failed = test_failed + 1
    342     elif res < 0:
    343 	test_error = test_error + 1
    344 
    345     # Log the ontext
    346     if res != 1:
    347 	log.write("   File: %s\n" % (URI))
    348 	content = string.strip(test.content)
    349 	while content[-1] == '\n':
    350 	    content = content[0:-1]
    351 	if extra != None:
    352 	    log.write("   %s:%s:%s\n" % (type, extra, content))
    353 	else:
    354 	    log.write("   %s:%s\n\n" % (type, content))
    355 	if error_msg != '':
    356 	    log.write("   ----\n%s   ----\n" % (error_msg))
    357 	    error_msg = ''
    358 	log.write("\n")
    359 
    360     return 0
    361 	    
    362 
    363 def runTestCases(case):
    364     profile = case.prop('PROFILE')
    365     if profile != None and \
    366        string.find(profile, "IBM XML Conformance Test Suite - Production") < 0:
    367 	print "=>", profile
    368     test = case.children
    369     while test != None:
    370         if test.name == 'TEST':
    371 	    runTest(test)
    372 	if test.name == 'TESTCASES':
    373 	    runTestCases(test)
    374         test = test.next
    375         
    376 conf = loadNoentDoc(CONF)
    377 if conf == None:
    378     print "Unable to load %s" % CONF
    379     sys.exit(1)
    380 
    381 testsuite = conf.getRootElement()
    382 if testsuite.name != 'TESTSUITE':
    383     print "Expecting TESTSUITE root element: aborting"
    384     sys.exit(1)
    385 
    386 profile = testsuite.prop('PROFILE')
    387 if profile != None:
    388     print profile
    389 
    390 start = time.time()
    391 
    392 case = testsuite.children
    393 while case != None:
    394     if case.name == 'TESTCASES':
    395 	old_test_nr = test_nr
    396 	old_test_succeed = test_succeed
    397 	old_test_failed = test_failed
    398 	old_test_error = test_error
    399         runTestCases(case)
    400 	print "   Ran %d tests: %d suceeded, %d failed and %d generated an error" % (
    401 	       test_nr - old_test_nr, test_succeed - old_test_succeed,
    402 	       test_failed - old_test_failed, test_error - old_test_error)
    403     case = case.next
    404 
    405 conf.freeDoc()
    406 log.close()
    407 
    408 print "Ran %d tests: %d suceeded, %d failed and %d generated an error in %.2f s." % (
    409       test_nr, test_succeed, test_failed, test_error, time.time() - start)
    410