blob: 23b0706dcbd7a43936ff48103257a3a712759bfe [file] [log] [blame]
Daniel Veillardbb7ddb32002-02-17 21:26:33 +00001#!/usr/bin/python
2import sys
Daniel Veillard878eab02002-02-19 13:46:09 +00003import time
Daniel Veillardbb7ddb32002-02-17 21:26:33 +00004import 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
Daniel Veillardc7612992002-02-17 22:47:37 +000021error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000022def errorHandler(ctx, str):
23 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +000024 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000025
Daniel Veillard8f597c32003-10-06 08:19:27 +000026 error_nr = error_nr + 1
Daniel Veillardc7612992002-02-17 22:47:37 +000027 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
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000032
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()
Daniel Veillardfa49d872002-03-09 10:20:00 +000055 try:
56 doc = ctxt.doc()
57 except:
58 doc = None
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000059 if ctxt.wellFormed() != 1:
60 doc.freeDoc()
61 return None
62 return doc
63
64#
65# The conformance testing routines
66#
67
68def testNotWf(filename, id):
69 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +000070 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000071 global log
72
73 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +000074 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000075
76 ctxt = libxml2.createFileParserCtxt(filename)
77 if ctxt == None:
78 return -1
Daniel Veillard8f597c32003-10-06 08:19:27 +000079 ret = ctxt.parseDocument()
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000080
Daniel Veillardfa49d872002-03-09 10:20:00 +000081 try:
82 doc = ctxt.doc()
83 except:
84 doc = None
Daniel Veillard8f597c32003-10-06 08:19:27 +000085 if doc != None:
86 doc.freeDoc()
87 if ret == 0 or ctxt.wellFormed() != 0:
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000088 print "%s: error: Well Formedness error not detected" % (id)
89 log.write("%s: error: Well Formedness error not detected\n" % (id))
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000090 return 0
91 return 1
92
93def testNotWfEnt(filename, id):
94 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +000095 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000096 global log
97
98 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +000099 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000100
101 ctxt = libxml2.createFileParserCtxt(filename)
102 if ctxt == None:
103 return -1
104 ctxt.replaceEntities(1)
Daniel Veillard8f597c32003-10-06 08:19:27 +0000105 ret = ctxt.parseDocument()
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000106
Daniel Veillardfa49d872002-03-09 10:20:00 +0000107 try:
108 doc = ctxt.doc()
109 except:
110 doc = None
Daniel Veillard8f597c32003-10-06 08:19:27 +0000111 if doc != None:
112 doc.freeDoc()
113 if ret == 0 or ctxt.wellFormed() != 0:
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000114 print "%s: error: Well Formedness error not detected" % (id)
115 log.write("%s: error: Well Formedness error not detected\n" % (id))
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000116 return 0
117 return 1
118
119def testNotWfEntDtd(filename, id):
120 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +0000121 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000122 global log
123
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000124 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +0000125 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000126
127 ctxt = libxml2.createFileParserCtxt(filename)
128 if ctxt == None:
129 return -1
130 ctxt.replaceEntities(1)
131 ctxt.loadSubset(1)
Daniel Veillard8f597c32003-10-06 08:19:27 +0000132 ret = ctxt.parseDocument()
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000133
Daniel Veillardfa49d872002-03-09 10:20:00 +0000134 try:
135 doc = ctxt.doc()
136 except:
137 doc = None
Daniel Veillard8f597c32003-10-06 08:19:27 +0000138 if doc != None:
139 doc.freeDoc()
140 if ret == 0 or ctxt.wellFormed() != 0:
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000141 print "%s: error: Well Formedness error not detected" % (id)
142 log.write("%s: error: Well Formedness error not detected\n" % (id))
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000143 return 0
144 return 1
145
146def testWfEntDtd(filename, id):
147 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +0000148 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000149 global log
150
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000151 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +0000152 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000153
154 ctxt = libxml2.createFileParserCtxt(filename)
155 if ctxt == None:
156 return -1
157 ctxt.replaceEntities(1)
158 ctxt.loadSubset(1)
Daniel Veillard8f597c32003-10-06 08:19:27 +0000159 ret = ctxt.parseDocument()
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000160
Daniel Veillardfa49d872002-03-09 10:20:00 +0000161 try:
162 doc = ctxt.doc()
163 except:
164 doc = None
Daniel Veillard8f597c32003-10-06 08:19:27 +0000165 if doc == None or ret != 0 or ctxt.wellFormed() == 0:
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000166 print "%s: error: wrongly failed to parse the document" % (id)
167 log.write("%s: error: wrongly failed to parse the document\n" % (id))
Daniel Veillard8f597c32003-10-06 08:19:27 +0000168 if doc != None:
169 doc.freeDoc()
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000170 return 0
171 if error_nr != 0:
172 print "%s: warning: WF document generated an error msg" % (id)
173 log.write("%s: error: WF document generated an error msg\n" % (id))
174 doc.freeDoc()
175 return 2
176 doc.freeDoc()
177 return 1
178
Daniel Veillard55253e22002-02-18 14:32:39 +0000179def testError(filename, id):
180 global error_nr
181 global error_msg
182 global log
183
184 error_nr = 0
185 error_msg = ''
186
187 ctxt = libxml2.createFileParserCtxt(filename)
188 if ctxt == None:
189 return -1
190 ctxt.replaceEntities(1)
191 ctxt.loadSubset(1)
Daniel Veillard8f597c32003-10-06 08:19:27 +0000192 ret = ctxt.parseDocument()
Daniel Veillard55253e22002-02-18 14:32:39 +0000193
Daniel Veillardfa49d872002-03-09 10:20:00 +0000194 try:
195 doc = ctxt.doc()
196 except:
197 doc = None
Daniel Veillard8f597c32003-10-06 08:19:27 +0000198 if doc != None:
199 doc.freeDoc()
Daniel Veillard55253e22002-02-18 14:32:39 +0000200 if ctxt.wellFormed() == 0:
201 print "%s: warning: failed to parse the document but accepted" % (id)
202 log.write("%s: warning: failed to parse the document but accepte\n" % (id))
203 return 2
204 if error_nr != 0:
205 print "%s: warning: WF document generated an error msg" % (id)
206 log.write("%s: error: WF document generated an error msg\n" % (id))
Daniel Veillard55253e22002-02-18 14:32:39 +0000207 return 2
Daniel Veillard55253e22002-02-18 14:32:39 +0000208 return 1
209
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000210def testInvalid(filename, id):
211 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +0000212 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000213 global log
214
215 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +0000216 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000217
218 ctxt = libxml2.createFileParserCtxt(filename)
219 if ctxt == None:
220 return -1
221 ctxt.validate(1)
Daniel Veillard8f597c32003-10-06 08:19:27 +0000222 ret = ctxt.parseDocument()
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000223
Daniel Veillardfa49d872002-03-09 10:20:00 +0000224 try:
225 doc = ctxt.doc()
226 except:
227 doc = None
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000228 valid = ctxt.isValid()
229 if doc == None:
230 print "%s: error: wrongly failed to parse the document" % (id)
231 log.write("%s: error: wrongly failed to parse the document\n" % (id))
232 return 0
233 if valid == 1:
234 print "%s: error: Validity error not detected" % (id)
235 log.write("%s: error: Validity error not detected\n" % (id))
236 doc.freeDoc()
237 return 0
238 if error_nr == 0:
239 print "%s: warning: Validity error not reported" % (id)
240 log.write("%s: warning: Validity error not reported\n" % (id))
241 doc.freeDoc()
242 return 2
243
244 doc.freeDoc()
245 return 1
246
247def testValid(filename, id):
248 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +0000249 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000250
251 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +0000252 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000253
254 ctxt = libxml2.createFileParserCtxt(filename)
255 if ctxt == None:
256 return -1
257 ctxt.validate(1)
258 ctxt.parseDocument()
259
Daniel Veillardfa49d872002-03-09 10:20:00 +0000260 try:
261 doc = ctxt.doc()
262 except:
263 doc = None
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000264 valid = ctxt.isValid()
265 if doc == None:
266 print "%s: error: wrongly failed to parse the document" % (id)
267 log.write("%s: error: wrongly failed to parse the document\n" % (id))
268 return 0
269 if valid != 1:
270 print "%s: error: Validity check failed" % (id)
271 log.write("%s: error: Validity check failed\n" % (id))
272 doc.freeDoc()
273 return 0
274 if error_nr != 0 or valid != 1:
275 print "%s: warning: valid document reported an error" % (id)
276 log.write("%s: warning: valid document reported an error\n" % (id))
277 doc.freeDoc()
278 return 2
279 doc.freeDoc()
280 return 1
281
282test_nr = 0
283test_succeed = 0
284test_failed = 0
285test_error = 0
286def runTest(test):
287 global test_nr
288 global test_failed
289 global test_error
290 global test_succeed
Daniel Veillardc7612992002-02-17 22:47:37 +0000291 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000292 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":
Daniel Veillard55253e22002-02-18 14:32:39 +0000332 res = testError(URI, id)
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000333 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))
Daniel Veillardc7612992002-02-17 22:47:37 +0000348 content = string.strip(test.content)
349 while content[-1] == '\n':
350 content = content[0:-1]
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000351 if extra != None:
Daniel Veillardc7612992002-02-17 22:47:37 +0000352 log.write(" %s:%s:%s\n" % (type, extra, content))
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000353 else:
354 log.write(" %s:%s\n\n" % (type, content))
Daniel Veillardc7612992002-02-17 22:47:37 +0000355 if error_msg != '':
356 log.write(" ----\n%s ----\n" % (error_msg))
357 error_msg = ''
358 log.write("\n")
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000359
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
Daniel Veillard878eab02002-02-19 13:46:09 +0000390start = time.time()
391
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000392case = testsuite.children
393while case != None:
394 global test_nr
395 global test_succeed
396 global test_failed
397 global test_error
398
399 if case.name == 'TESTCASES':
400 old_test_nr = test_nr
401 old_test_succeed = test_succeed
402 old_test_failed = test_failed
403 old_test_error = test_error
404 runTestCases(case)
405 print " Ran %d tests: %d suceeded, %d failed and %d generated an error" % (
406 test_nr - old_test_nr, test_succeed - old_test_succeed,
407 test_failed - old_test_failed, test_error - old_test_error)
408 case = case.next
409
410conf.freeDoc()
411log.close()
412
Daniel Veillard878eab02002-02-19 13:46:09 +0000413print "Ran %d tests: %d suceeded, %d failed and %d generated an error in %.2f s." % (
414 test_nr, test_succeed, test_failed, test_error, time.time() - start)