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