blob: 83546e48d155f2ba7cd8ffab7ebcb625bcc36347 [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
25 error_nr = error_nr + 1
Daniel Veillardc7612992002-02-17 22:47:37 +000026 if len(error_msg) < 300:
27 if len(error_msg) == 0 or error_msg[-1] == '\n':
28 error_msg = error_msg + " >>" + str
29 else:
30 error_msg = error_msg + str
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000031
32libxml2.registerErrorHandler(errorHandler, None)
33
34#warning_nr = 0
35#warning = ''
36#def warningHandler(ctx, str):
37# global warning_nr
38# global warning
39#
40# warning_nr = warning_nr + 1
41# warning = warning + str
42#
43#libxml2.registerWarningHandler(warningHandler, None)
44
45#
46# Used to load the XML testsuite description
47#
48def loadNoentDoc(filename):
49 ctxt = libxml2.createFileParserCtxt(filename)
50 if ctxt == None:
51 return None
52 ctxt.replaceEntities(1)
53 ctxt.parseDocument()
54 doc = ctxt.doc()
55 if ctxt.wellFormed() != 1:
56 doc.freeDoc()
57 return None
58 return doc
59
60#
61# The conformance testing routines
62#
63
64def testNotWf(filename, id):
65 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +000066 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000067 global log
68
69 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +000070 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000071
72 ctxt = libxml2.createFileParserCtxt(filename)
73 if ctxt == None:
74 return -1
75 ctxt.parseDocument()
76
77 doc = ctxt.doc()
78 if error_nr == 0 or ctxt.wellFormed() != 0:
79 print "%s: error: Well Formedness error not detected" % (id)
80 log.write("%s: error: Well Formedness error not detected\n" % (id))
81 doc.freeDoc()
82 return 0
83 return 1
84
85def testNotWfEnt(filename, id):
86 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +000087 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000088 global log
89
90 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +000091 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +000092
93 ctxt = libxml2.createFileParserCtxt(filename)
94 if ctxt == None:
95 return -1
96 ctxt.replaceEntities(1)
97 ctxt.parseDocument()
98
99 doc = ctxt.doc()
100 if error_nr == 0 or ctxt.wellFormed() != 0:
101 print "%s: error: Well Formedness error not detected" % (id)
102 log.write("%s: error: Well Formedness error not detected\n" % (id))
103 doc.freeDoc()
104 return 0
105 return 1
106
107def testNotWfEntDtd(filename, id):
108 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +0000109 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000110 global log
111
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000112 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +0000113 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000114
115 ctxt = libxml2.createFileParserCtxt(filename)
116 if ctxt == None:
117 return -1
118 ctxt.replaceEntities(1)
119 ctxt.loadSubset(1)
120 ctxt.parseDocument()
121
122 doc = ctxt.doc()
123 if error_nr == 0 or ctxt.wellFormed() != 0:
124 print "%s: error: Well Formedness error not detected" % (id)
125 log.write("%s: error: Well Formedness error not detected\n" % (id))
126 doc.freeDoc()
127 return 0
128 return 1
129
130def testWfEntDtd(filename, id):
131 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +0000132 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000133 global log
134
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000135 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +0000136 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000137
138 ctxt = libxml2.createFileParserCtxt(filename)
139 if ctxt == None:
140 return -1
141 ctxt.replaceEntities(1)
142 ctxt.loadSubset(1)
143 ctxt.parseDocument()
144
145 doc = ctxt.doc()
146 if ctxt.wellFormed() == 0:
147 print "%s: error: wrongly failed to parse the document" % (id)
148 log.write("%s: error: wrongly failed to parse the document\n" % (id))
149 return 0
150 if error_nr != 0:
151 print "%s: warning: WF document generated an error msg" % (id)
152 log.write("%s: error: WF document generated an error msg\n" % (id))
153 doc.freeDoc()
154 return 2
155 doc.freeDoc()
156 return 1
157
158def testInvalid(filename, id):
159 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +0000160 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000161 global log
162
163 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +0000164 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000165
166 ctxt = libxml2.createFileParserCtxt(filename)
167 if ctxt == None:
168 return -1
169 ctxt.validate(1)
170 ctxt.parseDocument()
171
172 doc = ctxt.doc()
173 valid = ctxt.isValid()
174 if doc == None:
175 print "%s: error: wrongly failed to parse the document" % (id)
176 log.write("%s: error: wrongly failed to parse the document\n" % (id))
177 return 0
178 if valid == 1:
179 print "%s: error: Validity error not detected" % (id)
180 log.write("%s: error: Validity error not detected\n" % (id))
181 doc.freeDoc()
182 return 0
183 if error_nr == 0:
184 print "%s: warning: Validity error not reported" % (id)
185 log.write("%s: warning: Validity error not reported\n" % (id))
186 doc.freeDoc()
187 return 2
188
189 doc.freeDoc()
190 return 1
191
192def testValid(filename, id):
193 global error_nr
Daniel Veillardc7612992002-02-17 22:47:37 +0000194 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000195
196 error_nr = 0
Daniel Veillardc7612992002-02-17 22:47:37 +0000197 error_msg = ''
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000198
199 ctxt = libxml2.createFileParserCtxt(filename)
200 if ctxt == None:
201 return -1
202 ctxt.validate(1)
203 ctxt.parseDocument()
204
205 doc = ctxt.doc()
206 valid = ctxt.isValid()
207 if doc == None:
208 print "%s: error: wrongly failed to parse the document" % (id)
209 log.write("%s: error: wrongly failed to parse the document\n" % (id))
210 return 0
211 if valid != 1:
212 print "%s: error: Validity check failed" % (id)
213 log.write("%s: error: Validity check failed\n" % (id))
214 doc.freeDoc()
215 return 0
216 if error_nr != 0 or valid != 1:
217 print "%s: warning: valid document reported an error" % (id)
218 log.write("%s: warning: valid document reported an error\n" % (id))
219 doc.freeDoc()
220 return 2
221 doc.freeDoc()
222 return 1
223
224test_nr = 0
225test_succeed = 0
226test_failed = 0
227test_error = 0
228def runTest(test):
229 global test_nr
230 global test_failed
231 global test_error
232 global test_succeed
Daniel Veillardc7612992002-02-17 22:47:37 +0000233 global error_msg
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000234 global log
235
236 uri = test.prop('URI')
237 id = test.prop('ID')
238 if uri == None:
239 print "Test without ID:", uri
240 return -1
241 if id == None:
242 print "Test without URI:", id
243 return -1
244 base = test.getBase(None)
245 URI = libxml2.buildURI(uri, base)
246 if os.access(URI, os.R_OK) == 0:
247 print "Test %s missing: base %s uri %s" % (URI, base, uri)
248 return -1
249 type = test.prop('TYPE')
250 if type == None:
251 print "Test %s missing TYPE" % (id)
252 return -1
253
254 extra = None
255 if type == "invalid":
256 res = testInvalid(URI, id)
257 elif type == "valid":
258 res = testValid(URI, id)
259 elif type == "not-wf":
260 extra = test.prop('ENTITIES')
261 # print URI
262 #if extra == None:
263 # res = testNotWfEntDtd(URI, id)
264 #elif extra == 'none':
265 # res = testNotWf(URI, id)
266 #elif extra == 'general':
267 # res = testNotWfEnt(URI, id)
268 #elif extra == 'both' or extra == 'parameter':
269 res = testNotWfEntDtd(URI, id)
270 #else:
271 # print "Unknow value %s for an ENTITIES test value" % (extra)
272 # return -1
273 elif type == "error":
274 res = testWfEntDtd(URI, id)
275 else:
276 # TODO skipped for now
277 return -1
278
279 test_nr = test_nr + 1
280 if res > 0:
281 test_succeed = test_succeed + 1
282 elif res == 0:
283 test_failed = test_failed + 1
284 elif res < 0:
285 test_error = test_error + 1
286
287 # Log the ontext
288 if res != 1:
289 log.write(" File: %s\n" % (URI))
Daniel Veillardc7612992002-02-17 22:47:37 +0000290 content = string.strip(test.content)
291 while content[-1] == '\n':
292 content = content[0:-1]
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000293 if extra != None:
Daniel Veillardc7612992002-02-17 22:47:37 +0000294 log.write(" %s:%s:%s\n" % (type, extra, content))
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000295 else:
296 log.write(" %s:%s\n\n" % (type, content))
Daniel Veillardc7612992002-02-17 22:47:37 +0000297 if error_msg != '':
298 log.write(" ----\n%s ----\n" % (error_msg))
299 error_msg = ''
300 log.write("\n")
Daniel Veillardbb7ddb32002-02-17 21:26:33 +0000301
302 return 0
303
304
305def runTestCases(case):
306 profile = case.prop('PROFILE')
307 if profile != None and \
308 string.find(profile, "IBM XML Conformance Test Suite - Production") < 0:
309 print "=>", profile
310 test = case.children
311 while test != None:
312 if test.name == 'TEST':
313 runTest(test)
314 if test.name == 'TESTCASES':
315 runTestCases(test)
316 test = test.next
317
318conf = loadNoentDoc(CONF)
319if conf == None:
320 print "Unable to load %s" % CONF
321 sys.exit(1)
322
323testsuite = conf.getRootElement()
324if testsuite.name != 'TESTSUITE':
325 print "Expecting TESTSUITE root element: aborting"
326 sys.exit(1)
327
328profile = testsuite.prop('PROFILE')
329if profile != None:
330 print profile
331
332case = testsuite.children
333while case != None:
334 global test_nr
335 global test_succeed
336 global test_failed
337 global test_error
338
339 if case.name == 'TESTCASES':
340 old_test_nr = test_nr
341 old_test_succeed = test_succeed
342 old_test_failed = test_failed
343 old_test_error = test_error
344 runTestCases(case)
345 print " Ran %d tests: %d suceeded, %d failed and %d generated an error" % (
346 test_nr - old_test_nr, test_succeed - old_test_succeed,
347 test_failed - old_test_failed, test_error - old_test_error)
348 case = case.next
349
350conf.freeDoc()
351log.close()
352
353print "Ran %d tests: %d suceeded, %d failed and %d generated an error" % (
354 test_nr, test_succeed, test_failed, test_error)