blob: 1929b70e502ed896b7042b6553a8f7a133e94da6 [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 Veillard55253e22002-02-18 14:32:39 +000026 if string.find(str, "error:") >= 0:
27 error_nr = error_nr + 1
Daniel Veillardc7612992002-02-17 22:47:37 +000028 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
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000033
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 doc = ctxt.doc()
57 if ctxt.wellFormed() != 1:
58 doc.freeDoc()
59 return None
60 return doc
61
62#
63# The conformance testing routines
64#
65
66def testNotWf(filename, id):
67 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +000068 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000069 global log
70
71 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +000072 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000073
74 ctxt = libxml2.createFileParserCtxt(filename)
75 if ctxt == None:
76 return -1
77 ctxt.parseDocument()
78
79 doc = ctxt.doc()
80 if error_nr == 0 or ctxt.wellFormed() != 0:
81 print "%s: error: Well Formedness error not detected" % (id)
82 log.write("%s: error: Well Formedness error not detected\n" % (id))
83 doc.freeDoc()
84 return 0
85 return 1
86
87def testNotWfEnt(filename, id):
88 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +000089 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000090 global log
91
92 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +000093 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000094
95 ctxt = libxml2.createFileParserCtxt(filename)
96 if ctxt == None:
97 return -1
98 ctxt.replaceEntities(1)
99 ctxt.parseDocument()
100
101 doc = ctxt.doc()
102 if error_nr == 0 or ctxt.wellFormed() != 0:
103 print "%s: error: Well Formedness error not detected" % (id)
104 log.write("%s: error: Well Formedness error not detected\n" % (id))
105 doc.freeDoc()
106 return 0
107 return 1
108
109def testNotWfEntDtd(filename, id):
110 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +0000111 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000112 global log
113
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000114 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +0000115 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000116
117 ctxt = libxml2.createFileParserCtxt(filename)
118 if ctxt == None:
119 return -1
120 ctxt.replaceEntities(1)
121 ctxt.loadSubset(1)
122 ctxt.parseDocument()
123
124 doc = ctxt.doc()
125 if error_nr == 0 or ctxt.wellFormed() != 0:
126 print "%s: error: Well Formedness error not detected" % (id)
127 log.write("%s: error: Well Formedness error not detected\n" % (id))
128 doc.freeDoc()
129 return 0
130 return 1
131
132def testWfEntDtd(filename, id):
133 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +0000134 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000135 global log
136
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000137 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +0000138 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000139
140 ctxt = libxml2.createFileParserCtxt(filename)
141 if ctxt == None:
142 return -1
143 ctxt.replaceEntities(1)
144 ctxt.loadSubset(1)
145 ctxt.parseDocument()
146
147 doc = ctxt.doc()
148 if ctxt.wellFormed() == 0:
149 print "%s: error: wrongly failed to parse the document" % (id)
150 log.write("%s: error: wrongly failed to parse the document\n" % (id))
151 return 0
152 if error_nr != 0:
153 print "%s: warning: WF document generated an error msg" % (id)
154 log.write("%s: error: WF document generated an error msg\n" % (id))
155 doc.freeDoc()
156 return 2
157 doc.freeDoc()
158 return 1
159
Daniel Veillard55253e22002-02-18 14:32:39 +0000160def testError(filename, id):
161 global error_nr
162 global error_msg
163 global log
164
165 error_nr = 0
166 error_msg = ''
167
168 ctxt = libxml2.createFileParserCtxt(filename)
169 if ctxt == None:
170 return -1
171 ctxt.replaceEntities(1)
172 ctxt.loadSubset(1)
173 ctxt.parseDocument()
174
175 doc = ctxt.doc()
176 if ctxt.wellFormed() == 0:
177 print "%s: warning: failed to parse the document but accepted" % (id)
178 log.write("%s: warning: failed to parse the document but accepte\n" % (id))
179 return 2
180 if error_nr != 0:
181 print "%s: warning: WF document generated an error msg" % (id)
182 log.write("%s: error: WF document generated an error msg\n" % (id))
183 doc.freeDoc()
184 return 2
185 doc.freeDoc()
186 return 1
187
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000188def testInvalid(filename, id):
189 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +0000190 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000191 global log
192
193 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +0000194 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000195
196 ctxt = libxml2.createFileParserCtxt(filename)
197 if ctxt == None:
198 return -1
199 ctxt.validate(1)
200 ctxt.parseDocument()
201
202 doc = ctxt.doc()
203 valid = ctxt.isValid()
204 if doc == None:
205 print "%s: error: wrongly failed to parse the document" % (id)
206 log.write("%s: error: wrongly failed to parse the document\n" % (id))
207 return 0
208 if valid == 1:
209 print "%s: error: Validity error not detected" % (id)
210 log.write("%s: error: Validity error not detected\n" % (id))
211 doc.freeDoc()
212 return 0
213 if error_nr == 0:
214 print "%s: warning: Validity error not reported" % (id)
215 log.write("%s: warning: Validity error not reported\n" % (id))
216 doc.freeDoc()
217 return 2
218
219 doc.freeDoc()
220 return 1
221
222def testValid(filename, id):
223 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +0000224 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000225
226 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +0000227 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000228
229 ctxt = libxml2.createFileParserCtxt(filename)
230 if ctxt == None:
231 return -1
232 ctxt.validate(1)
233 ctxt.parseDocument()
234
235 doc = ctxt.doc()
236 valid = ctxt.isValid()
237 if doc == None:
238 print "%s: error: wrongly failed to parse the document" % (id)
239 log.write("%s: error: wrongly failed to parse the document\n" % (id))
240 return 0
241 if valid != 1:
242 print "%s: error: Validity check failed" % (id)
243 log.write("%s: error: Validity check failed\n" % (id))
244 doc.freeDoc()
245 return 0
246 if error_nr != 0 or valid != 1:
247 print "%s: warning: valid document reported an error" % (id)
248 log.write("%s: warning: valid document reported an error\n" % (id))
249 doc.freeDoc()
250 return 2
251 doc.freeDoc()
252 return 1
253
254test_nr = 0
255test_succeed = 0
256test_failed = 0
257test_error = 0
258def runTest(test):
259 global test_nr
260 global test_failed
261 global test_error
262 global test_succeed
Daniel Veillardc7612992002-02-17 22:47:37 +0000263 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000264 global log
265
266 uri = test.prop('URI')
267 id = test.prop('ID')
268 if uri == None:
269 print "Test without ID:", uri
270 return -1
271 if id == None:
272 print "Test without URI:", id
273 return -1
274 base = test.getBase(None)
275 URI = libxml2.buildURI(uri, base)
276 if os.access(URI, os.R_OK) == 0:
277 print "Test %s missing: base %s uri %s" % (URI, base, uri)
278 return -1
279 type = test.prop('TYPE')
280 if type == None:
281 print "Test %s missing TYPE" % (id)
282 return -1
283
284 extra = None
285 if type == "invalid":
286 res = testInvalid(URI, id)
287 elif type == "valid":
288 res = testValid(URI, id)
289 elif type == "not-wf":
290 extra = test.prop('ENTITIES')
291 # print URI
292 #if extra == None:
293 # res = testNotWfEntDtd(URI, id)
294 #elif extra == 'none':
295 # res = testNotWf(URI, id)
296 #elif extra == 'general':
297 # res = testNotWfEnt(URI, id)
298 #elif extra == 'both' or extra == 'parameter':
299 res = testNotWfEntDtd(URI, id)
300 #else:
301 # print "Unknow value %s for an ENTITIES test value" % (extra)
302 # return -1
303 elif type == "error":
Daniel Veillard55253e22002-02-18 14:32:39 +0000304 res = testError(URI, id)
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000305 else:
306 # TODO skipped for now
307 return -1
308
309 test_nr = test_nr + 1
310 if res > 0:
311 test_succeed = test_succeed + 1
312 elif res == 0:
313 test_failed = test_failed + 1
314 elif res < 0:
315 test_error = test_error + 1
316
317 # Log the ontext
318 if res != 1:
319 log.write(" File: %s\n" % (URI))
Daniel Veillardc7612992002-02-17 22:47:37 +0000320 content = string.strip(test.content)
321 while content[-1] == '\n':
322 content = content[0:-1]
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000323 if extra != None:
Daniel Veillardc7612992002-02-17 22:47:37 +0000324 log.write(" %s:%s:%s\n" % (type, extra, content))
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000325 else:
326 log.write(" %s:%s\n\n" % (type, content))
Daniel Veillardc7612992002-02-17 22:47:37 +0000327 if error_msg != '':
328 log.write(" ----\n%s ----\n" % (error_msg))
329 error_msg = ''
330 log.write("\n")
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000331
332 return 0
333
334
335def runTestCases(case):
336 profile = case.prop('PROFILE')
337 if profile != None and \
338 string.find(profile, "IBM XML Conformance Test Suite - Production") < 0:
339 print "=>", profile
340 test = case.children
341 while test != None:
342 if test.name == 'TEST':
343 runTest(test)
344 if test.name == 'TESTCASES':
345 runTestCases(test)
346 test = test.next
347
348conf = loadNoentDoc(CONF)
349if conf == None:
350 print "Unable to load %s" % CONF
351 sys.exit(1)
352
353testsuite = conf.getRootElement()
354if testsuite.name != 'TESTSUITE':
355 print "Expecting TESTSUITE root element: aborting"
356 sys.exit(1)
357
358profile = testsuite.prop('PROFILE')
359if profile != None:
360 print profile
361
Daniel Veillard878eab02002-02-19 13:46:09 +0000362start = time.time()
363
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000364case = testsuite.children
365while case != None:
366 global test_nr
367 global test_succeed
368 global test_failed
369 global test_error
370
371 if case.name == 'TESTCASES':
372 old_test_nr = test_nr
373 old_test_succeed = test_succeed
374 old_test_failed = test_failed
375 old_test_error = test_error
376 runTestCases(case)
377 print " Ran %d tests: %d suceeded, %d failed and %d generated an error" % (
378 test_nr - old_test_nr, test_succeed - old_test_succeed,
379 test_failed - old_test_failed, test_error - old_test_error)
380 case = case.next
381
382conf.freeDoc()
383log.close()
384
Daniel Veillard878eab02002-02-19 13:46:09 +0000385print "Ran %d tests: %d suceeded, %d failed and %d generated an error in %.2f s." % (
386 test_nr, test_succeed, test_failed, test_error, time.time() - start)