blob: 248367d45b6e72c46e998f5ad291e134bade294d [file] [log] [blame]
Daniel Veillardbb7ddb32002-02-17 21:26:33 +00001#!/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
Daniel Veillardc7612992002-02-17 22:47:37 +000020error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000021def errorHandler(ctx, str):
22 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +000023 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000024
Daniel Veillard55253e22002-02-18 14:32:39 +000025 if string.find(str, "error:") >= 0:
26 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()
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
Daniel Veillardc7612992002-02-17 22:47:37 +000067 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000068 global log
69
70 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +000071 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000072
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
Daniel Veillardc7612992002-02-17 22:47:37 +000088 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000089 global log
90
91 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +000092 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000093
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
Daniel Veillardc7612992002-02-17 22:47:37 +0000110 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000111 global log
112
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000113 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +0000114 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000115
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
Daniel Veillardc7612992002-02-17 22:47:37 +0000133 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000134 global log
135
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000136 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +0000137 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000138
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
Daniel Veillard55253e22002-02-18 14:32:39 +0000159def 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
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000187def testInvalid(filename, id):
188 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +0000189 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000190 global log
191
192 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +0000193 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000194
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
Daniel Veillardc7612992002-02-17 22:47:37 +0000223 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000224
225 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +0000226 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000227
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
Daniel Veillardc7612992002-02-17 22:47:37 +0000262 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000263 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":
Daniel Veillard55253e22002-02-18 14:32:39 +0000303 res = testError(URI, id)
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000304 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))
Daniel Veillardc7612992002-02-17 22:47:37 +0000319 content = string.strip(test.content)
320 while content[-1] == '\n':
321 content = content[0:-1]
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000322 if extra != None:
Daniel Veillardc7612992002-02-17 22:47:37 +0000323 log.write(" %s:%s:%s\n" % (type, extra, content))
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000324 else:
325 log.write(" %s:%s\n\n" % (type, content))
Daniel Veillardc7612992002-02-17 22:47:37 +0000326 if error_msg != '':
327 log.write(" ----\n%s ----\n" % (error_msg))
328 error_msg = ''
329 log.write("\n")
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000330
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)