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