1#!/usr/bin/python 2import sys 3import time 4import os 5import string 6sys.path.insert(0, "python") 7import libxml2 8 9test_nr = 0 10test_succeed = 0 11test_failed = 0 12test_error = 0 13 14# 15# the testsuite description 16# 17CONF="xml-test-suite/xmlconf/xmlconf.xml" 18LOG="check-xml-test-suite.log" 19 20log = open(LOG, "w") 21 22# 23# Error and warning handlers 24# 25error_nr = 0 26error_msg = '' 27def 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 38libxml2.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# 54def 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 73def 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 98def 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 124def 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 151def 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 184def 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 215def 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 252def 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 287def 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 "Unknown 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 363def 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 376conf = loadNoentDoc(CONF) 377if conf == None: 378 print "Unable to load %s" % CONF 379 sys.exit(1) 380 381testsuite = conf.getRootElement() 382if testsuite.name != 'TESTSUITE': 383 print "Expecting TESTSUITE root element: aborting" 384 sys.exit(1) 385 386profile = testsuite.prop('PROFILE') 387if profile != None: 388 print profile 389 390start = time.time() 391 392case = testsuite.children 393while 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 succeeded, %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 405conf.freeDoc() 406log.close() 407 408print "Ran %d tests: %d succeeded, %d failed and %d generated an error in %.2f s." % ( 409 test_nr, test_succeed, test_failed, test_error, time.time() - start) 410