blob: b0c63e117bd1fbaeda492dd43492a475673a62f3 [file] [log] [blame]
Daniel Veillardeb7189f2003-02-27 20:11:13 +00001#!/usr/bin/python
2import sys
3import time
4import os
5import string
6import StringIO
7sys.path.append("python")
8import libxml2
9
10# Memory debug specific
11libxml2.debugMemory(1)
12debug = 0
13
14#
15# the testsuite description
16#
17CONF="test/xsdtest/xsdtestsuite.xml"
18LOG="check-xsdtype-test-suite.log"
19
20log = open(LOG, "w")
21nb_schemas_tests = 0
22nb_schemas_success = 0
23nb_schemas_failed = 0
24nb_instances_tests = 0
25nb_instances_success = 0
26nb_instances_failed = 0
27
28libxml2.lineNumbersDefault(1)
29#
30# Error and warnng callbacks
31#
32def callback(ctx, str):
33 global log
34 log.write("%s%s" % (ctx, str))
35
36libxml2.registerErrorHandler(callback, "")
37
38#
39# Resolver callback
40#
41resources = {}
42def resolver(URL, ID, ctxt):
43 global resources
44
45 if resources.has_key(URL):
46 return(StringIO.StringIO(resources[URL]))
47 log.write("Resolver failure: asked %s\n" % (URL))
48 log.write("resources: %s\n" % (resources))
49 return None
50
51#
52# handle a valid instance
53#
54def handle_valid(node, schema):
55 global log
56 global nb_instances_success
57 global nb_instances_failed
58
59 instance = ""
60 child = node.children
61 while child != None:
62 if child.type != 'text':
63 instance = instance + child.serialize()
64 child = child.next
65
66 try:
67 doc = libxml2.parseDoc(instance)
68 except:
69 doc = None
70
71 if doc == None:
72 log.write("\nFailed to parse correct instance:\n-----\n")
73 log.write(instance)
74 log.write("\n-----\n")
75 nb_instances_failed = nb_instances_failed + 1
76 return
77
78 try:
79 ctxt = schema.relaxNGNewValidCtxt()
80 ret = doc.relaxNGValidateDoc(ctxt)
81 except:
82 ret = -1
83 if ret != 0:
84 log.write("\nFailed to validate correct instance:\n-----\n")
85 log.write(instance)
86 log.write("\n-----\n")
87 nb_instances_failed = nb_instances_failed + 1
88 else:
89 nb_instances_success = nb_instances_success + 1
90 doc.freeDoc()
91
92#
93# handle an invalid instance
94#
95def handle_invalid(node, schema):
96 global log
97 global nb_instances_success
98 global nb_instances_failed
99
100 instance = ""
101 child = node.children
102 while child != None:
103 if child.type != 'text':
104 instance = instance + child.serialize()
105 child = child.next
106
107 try:
108 doc = libxml2.parseDoc(instance)
109 except:
110 doc = None
111
112 if doc == None:
113 log.write("\nStrange: failed to parse incorrect instance:\n-----\n")
114 log.write(instance)
115 log.write("\n-----\n")
116 return
117
118 try:
119 ctxt = schema.relaxNGNewValidCtxt()
120 ret = doc.relaxNGValidateDoc(ctxt)
121 except:
122 ret = -1
123 if ret == 0:
124 log.write("\nFailed to detect validation problem in instance:\n-----\n")
125 log.write(instance)
126 log.write("\n-----\n")
127 nb_instances_failed = nb_instances_failed + 1
128 else:
129 nb_instances_success = nb_instances_success + 1
130 doc.freeDoc()
131
132#
133# handle an incorrect test
134#
135def handle_correct(node):
136 global log
137 global nb_schemas_success
138 global nb_schemas_failed
139
140 schema = ""
141 child = node.children
142 while child != None:
143 if child.type != 'text':
144 schema = schema + child.serialize()
145 child = child.next
146
147 try:
148 rngp = libxml2.relaxNGNewMemParserCtxt(schema, len(schema))
149 rngs = rngp.relaxNGParse()
150 except:
151 rngs = None
152 if rngs == None:
153 log.write("\nFailed to compile correct schema:\n-----\n")
154 log.write(schema)
155 log.write("\n-----\n")
156 nb_schemas_failed = nb_schemas_failed + 1
157 else:
158 nb_schemas_success = nb_schemas_success + 1
159 return rngs
160
161def handle_incorrect(node):
162 global log
163 global nb_schemas_success
164 global nb_schemas_failed
165
166 schema = ""
167 child = node.children
168 while child != None:
169 if child.type != 'text':
170 schema = schema + child.serialize()
171 child = child.next
172
173 try:
174 rngp = libxml2.relaxNGNewMemParserCtxt(schema, len(schema))
175 rngs = rngp.relaxNGParse()
176 except:
177 rngs = None
178 if rngs != None:
179 log.write("\nFailed to detect schema error in:\n-----\n")
180 log.write(schema)
181 log.write("\n-----\n")
182 nb_schemas_failed = nb_schemas_failed + 1
183 else:
184# log.write("\nSuccess detecting schema error in:\n-----\n")
185# log.write(schema)
186# log.write("\n-----\n")
187 nb_schemas_success = nb_schemas_success + 1
188 return None
189
190#
191# resource handling: keep a dictionary of URL->string mappings
192#
193def handle_resource(node, dir):
194 global resources
195
196 try:
197 name = node.prop('name')
198 except:
199 name = None
200
201 if name == None or name == '':
202 log.write("resource has no name")
203 return;
204
205 if dir != None:
206# name = libxml2.buildURI(name, dir)
207 name = dir + '/' + name
208
209 res = ""
210 child = node.children
211 while child != None:
212 if child.type != 'text':
213 res = res + child.serialize()
214 child = child.next
215 resources[name] = res
216
217#
218# dir handling: pseudo directory resources
219#
220def handle_dir(node, dir):
221 try:
222 name = node.prop('name')
223 except:
224 name = None
225
226 if name == None or name == '':
227 log.write("resource has no name")
228 return;
229
230 if dir != None:
231# name = libxml2.buildURI(name, dir)
232 name = dir + '/' + name
233
234 dirs = node.xpathEval('dir')
235 for dir in dirs:
236 handle_dir(dir, name)
237 res = node.xpathEval('resource')
238 for r in res:
239 handle_resource(r, name)
240
241#
242# handle a testCase element
243#
244def handle_testCase(node):
245 global nb_schemas_tests
246 global nb_instances_tests
247 global resources
248
249 sections = node.xpathEval('string(section)')
250 log.write("\n ======== test %d line %d section %s ==========\n" % (
251
252 nb_schemas_tests, node.lineNo(), sections))
253 resources = {}
254 if debug:
255 print "test %d line %d" % (nb_schemas_tests, node.lineNo())
256
257 dirs = node.xpathEval('dir')
258 for dir in dirs:
259 handle_dir(dir, None)
260 res = node.xpathEval('resource')
261 for r in res:
262 handle_resource(r, None)
263
264 tsts = node.xpathEval('incorrect')
265 if tsts != []:
266 if len(tsts) != 1:
267 print "warning test line %d has more than one <incorrect> example" %(node.lineNo())
268 schema = handle_incorrect(tsts[0])
269 else:
270 tsts = node.xpathEval('correct')
271 if tsts != []:
272 if len(tsts) != 1:
273 print "warning test line %d has more than one <correct> example"% (node.lineNo())
274 schema = handle_correct(tsts[0])
275 else:
276 print "warning <testCase> line %d has no <correct> nor <incorrect> child" % (node.lineNo())
277
278 nb_schemas_tests = nb_schemas_tests + 1;
279
280 valids = node.xpathEval('valid')
281 invalids = node.xpathEval('invalid')
282 nb_instances_tests = nb_instances_tests + len(valids) + len(invalids)
283 if schema != None:
284 for valid in valids:
285 handle_valid(valid, schema)
286 for invalid in invalids:
287 handle_invalid(invalid, schema)
288
289
290#
291# handle a testSuite element
292#
293def handle_testSuite(node, level = 0):
294 global nb_schemas_tests, nb_schemas_success, nb_schemas_failed
295 global nb_instances_tests, nb_instances_success, nb_instances_failed
296 if level >= 1:
297 old_schemas_tests = nb_schemas_tests
298 old_schemas_success = nb_schemas_success
299 old_schemas_failed = nb_schemas_failed
300 old_instances_tests = nb_instances_tests
301 old_instances_success = nb_instances_success
302 old_instances_failed = nb_instances_failed
303
304 docs = node.xpathEval('documentation')
305 authors = node.xpathEval('author')
306 if docs != []:
307 msg = ""
308 for doc in docs:
309 msg = msg + doc.content + " "
310 if authors != []:
311 msg = msg + "written by "
312 for author in authors:
313 msg = msg + author.content + " "
314 print msg
315 sections = node.xpathEval('section')
316 if sections != [] and level <= 0:
317 msg = ""
318 for section in sections:
319 msg = msg + section.content + " "
320 print "Tests for section %s" % (msg)
321 for test in node.xpathEval('testCase'):
322 handle_testCase(test)
323 for test in node.xpathEval('testSuite'):
324 handle_testSuite(test, level + 1)
325
326
327 if level >= 1 and sections != []:
328 msg = ""
329 for section in sections:
330 msg = msg + section.content + " "
331 print "Result of tests for section %s" % (msg)
332 if nb_schemas_tests != old_schemas_tests:
333 print "found %d test schemas: %d success %d failures" % (
334 nb_schemas_tests - old_schemas_tests,
335 nb_schemas_success - old_schemas_success,
336 nb_schemas_failed - old_schemas_failed)
337 if nb_instances_tests != old_instances_tests:
338 print "found %d test instances: %d success %d failures" % (
339 nb_instances_tests - old_instances_tests,
340 nb_instances_success - old_instances_success,
341 nb_instances_failed - old_instances_failed)
342#
343# Parse the conf file
344#
345libxml2.substituteEntitiesDefault(1);
346testsuite = libxml2.parseFile(CONF)
347libxml2.setEntityLoader(resolver)
348root = testsuite.getRootElement()
349if root.name != 'testSuite':
350 print "%s doesn't start with a testSuite element, aborting" % (CONF)
351 sys.exit(1)
352print "Running Relax NG testsuite"
353handle_testSuite(root)
354
355print "\nTOTAL:\nfound %d test schemas: %d success %d failures" % (
356 nb_schemas_tests, nb_schemas_success, nb_schemas_failed)
357print "found %d test instances: %d success %d failures" % (
358 nb_instances_tests, nb_instances_success, nb_instances_failed)
359
360testsuite.freeDoc()
361
362# Memory debug specific
363libxml2.relaxNGCleanupTypes()
364libxml2.cleanupParser()
365if libxml2.debugMemory(1) == 0:
366 print "OK"
367else:
368 print "Memory leak %d bytes" % (libxml2.debugMemory(1))
369 libxml2.dumpMemory()