blob: 2fbdc8402dfc02218e9a9ae4238dcfae4a634deb [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
Daniel Veillarda1a9d042003-03-18 16:53:17 +000013verbose = 1
Daniel Veillardeb7189f2003-02-27 20:11:13 +000014
15#
16# the testsuite description
17#
18CONF="test/xsdtest/xsdtestsuite.xml"
Daniel Veillarda1a9d042003-03-18 16:53:17 +000019LOG="check-xsddata-test-suite.log"
Daniel Veillardeb7189f2003-02-27 20:11:13 +000020
21log = open(LOG, "w")
22nb_schemas_tests = 0
23nb_schemas_success = 0
24nb_schemas_failed = 0
25nb_instances_tests = 0
26nb_instances_success = 0
27nb_instances_failed = 0
28
29libxml2.lineNumbersDefault(1)
30#
31# Error and warnng callbacks
32#
33def callback(ctx, str):
34 global log
35 log.write("%s%s" % (ctx, str))
36
37libxml2.registerErrorHandler(callback, "")
38
39#
40# Resolver callback
41#
42resources = {}
43def resolver(URL, ID, ctxt):
44 global resources
45
46 if resources.has_key(URL):
47 return(StringIO.StringIO(resources[URL]))
48 log.write("Resolver failure: asked %s\n" % (URL))
49 log.write("resources: %s\n" % (resources))
50 return None
51
52#
53# handle a valid instance
54#
55def handle_valid(node, schema):
56 global log
57 global nb_instances_success
58 global nb_instances_failed
59
Daniel Veillarda1a9d042003-03-18 16:53:17 +000060 instance = node.prop("dtd")
61 if instance == None:
62 instance = ""
Daniel Veillardeb7189f2003-02-27 20:11:13 +000063 child = node.children
64 while child != None:
65 if child.type != 'text':
66 instance = instance + child.serialize()
67 child = child.next
68
Daniel Veillarda1a9d042003-03-18 16:53:17 +000069 mem = libxml2.debugMemory(1);
Daniel Veillardeb7189f2003-02-27 20:11:13 +000070 try:
71 doc = libxml2.parseDoc(instance)
72 except:
73 doc = None
74
75 if doc == None:
76 log.write("\nFailed to parse correct instance:\n-----\n")
77 log.write(instance)
78 log.write("\n-----\n")
79 nb_instances_failed = nb_instances_failed + 1
80 return
81
Daniel Veillarda1a9d042003-03-18 16:53:17 +000082 if debug:
83 print "instance line %d" % (node.lineNo())
84
Daniel Veillardeb7189f2003-02-27 20:11:13 +000085 try:
86 ctxt = schema.relaxNGNewValidCtxt()
87 ret = doc.relaxNGValidateDoc(ctxt)
Daniel Veillarda1a9d042003-03-18 16:53:17 +000088 del ctxt
Daniel Veillardeb7189f2003-02-27 20:11:13 +000089 except:
90 ret = -1
Daniel Veillarda1a9d042003-03-18 16:53:17 +000091
92 doc.freeDoc()
93 if mem != libxml2.debugMemory(1):
94 print "validating instance %d line %d leaks" % (
95 nb_instances_tests, node.lineNo())
96
Daniel Veillardeb7189f2003-02-27 20:11:13 +000097 if ret != 0:
98 log.write("\nFailed to validate correct instance:\n-----\n")
99 log.write(instance)
100 log.write("\n-----\n")
101 nb_instances_failed = nb_instances_failed + 1
102 else:
103 nb_instances_success = nb_instances_success + 1
Daniel Veillardeb7189f2003-02-27 20:11:13 +0000104
105#
106# handle an invalid instance
107#
108def handle_invalid(node, schema):
109 global log
110 global nb_instances_success
111 global nb_instances_failed
112
Daniel Veillarda1a9d042003-03-18 16:53:17 +0000113 instance = node.prop("dtd")
114 if instance == None:
115 instance = ""
Daniel Veillardeb7189f2003-02-27 20:11:13 +0000116 child = node.children
117 while child != None:
118 if child.type != 'text':
119 instance = instance + child.serialize()
120 child = child.next
121
Daniel Veillarda1a9d042003-03-18 16:53:17 +0000122 mem = libxml2.debugMemory(1);
123
Daniel Veillardeb7189f2003-02-27 20:11:13 +0000124 try:
125 doc = libxml2.parseDoc(instance)
126 except:
127 doc = None
128
129 if doc == None:
130 log.write("\nStrange: failed to parse incorrect instance:\n-----\n")
131 log.write(instance)
132 log.write("\n-----\n")
133 return
134
Daniel Veillarda1a9d042003-03-18 16:53:17 +0000135 if debug:
136 print "instance line %d" % (node.lineNo())
137
Daniel Veillardeb7189f2003-02-27 20:11:13 +0000138 try:
139 ctxt = schema.relaxNGNewValidCtxt()
140 ret = doc.relaxNGValidateDoc(ctxt)
Daniel Veillarda1a9d042003-03-18 16:53:17 +0000141 del ctxt
142
Daniel Veillardeb7189f2003-02-27 20:11:13 +0000143 except:
144 ret = -1
Daniel Veillarda1a9d042003-03-18 16:53:17 +0000145
146 doc.freeDoc()
147 if mem != libxml2.debugMemory(1):
148 print "validating instance %d line %d leaks" % (
149 nb_instances_tests, node.lineNo())
150
Daniel Veillardeb7189f2003-02-27 20:11:13 +0000151 if ret == 0:
152 log.write("\nFailed to detect validation problem in instance:\n-----\n")
153 log.write(instance)
154 log.write("\n-----\n")
155 nb_instances_failed = nb_instances_failed + 1
156 else:
157 nb_instances_success = nb_instances_success + 1
Daniel Veillardeb7189f2003-02-27 20:11:13 +0000158
159#
160# handle an incorrect test
161#
162def handle_correct(node):
163 global log
164 global nb_schemas_success
165 global nb_schemas_failed
166
167 schema = ""
168 child = node.children
169 while child != None:
170 if child.type != 'text':
171 schema = schema + child.serialize()
172 child = child.next
173
174 try:
175 rngp = libxml2.relaxNGNewMemParserCtxt(schema, len(schema))
176 rngs = rngp.relaxNGParse()
177 except:
178 rngs = None
179 if rngs == None:
180 log.write("\nFailed to compile correct schema:\n-----\n")
181 log.write(schema)
182 log.write("\n-----\n")
183 nb_schemas_failed = nb_schemas_failed + 1
184 else:
185 nb_schemas_success = nb_schemas_success + 1
186 return rngs
187
188def handle_incorrect(node):
189 global log
190 global nb_schemas_success
191 global nb_schemas_failed
192
193 schema = ""
194 child = node.children
195 while child != None:
196 if child.type != 'text':
197 schema = schema + child.serialize()
198 child = child.next
199
200 try:
201 rngp = libxml2.relaxNGNewMemParserCtxt(schema, len(schema))
202 rngs = rngp.relaxNGParse()
203 except:
204 rngs = None
205 if rngs != None:
206 log.write("\nFailed to detect schema error in:\n-----\n")
207 log.write(schema)
208 log.write("\n-----\n")
209 nb_schemas_failed = nb_schemas_failed + 1
210 else:
211# log.write("\nSuccess detecting schema error in:\n-----\n")
212# log.write(schema)
213# log.write("\n-----\n")
214 nb_schemas_success = nb_schemas_success + 1
215 return None
216
217#
218# resource handling: keep a dictionary of URL->string mappings
219#
220def handle_resource(node, dir):
221 global resources
222
223 try:
224 name = node.prop('name')
225 except:
226 name = None
227
228 if name == None or name == '':
229 log.write("resource has no name")
230 return;
231
232 if dir != None:
233# name = libxml2.buildURI(name, dir)
234 name = dir + '/' + name
235
236 res = ""
237 child = node.children
238 while child != None:
239 if child.type != 'text':
240 res = res + child.serialize()
241 child = child.next
242 resources[name] = res
243
244#
245# dir handling: pseudo directory resources
246#
247def handle_dir(node, dir):
248 try:
249 name = node.prop('name')
250 except:
251 name = None
252
253 if name == None or name == '':
254 log.write("resource has no name")
255 return;
256
257 if dir != None:
258# name = libxml2.buildURI(name, dir)
259 name = dir + '/' + name
260
261 dirs = node.xpathEval('dir')
262 for dir in dirs:
263 handle_dir(dir, name)
264 res = node.xpathEval('resource')
265 for r in res:
266 handle_resource(r, name)
267
268#
269# handle a testCase element
270#
271def handle_testCase(node):
272 global nb_schemas_tests
273 global nb_instances_tests
274 global resources
275
276 sections = node.xpathEval('string(section)')
277 log.write("\n ======== test %d line %d section %s ==========\n" % (
278
279 nb_schemas_tests, node.lineNo(), sections))
280 resources = {}
281 if debug:
282 print "test %d line %d" % (nb_schemas_tests, node.lineNo())
283
284 dirs = node.xpathEval('dir')
285 for dir in dirs:
286 handle_dir(dir, None)
287 res = node.xpathEval('resource')
288 for r in res:
289 handle_resource(r, None)
290
291 tsts = node.xpathEval('incorrect')
292 if tsts != []:
293 if len(tsts) != 1:
294 print "warning test line %d has more than one <incorrect> example" %(node.lineNo())
295 schema = handle_incorrect(tsts[0])
296 else:
297 tsts = node.xpathEval('correct')
298 if tsts != []:
299 if len(tsts) != 1:
300 print "warning test line %d has more than one <correct> example"% (node.lineNo())
301 schema = handle_correct(tsts[0])
302 else:
303 print "warning <testCase> line %d has no <correct> nor <incorrect> child" % (node.lineNo())
304
305 nb_schemas_tests = nb_schemas_tests + 1;
306
307 valids = node.xpathEval('valid')
308 invalids = node.xpathEval('invalid')
309 nb_instances_tests = nb_instances_tests + len(valids) + len(invalids)
310 if schema != None:
311 for valid in valids:
312 handle_valid(valid, schema)
313 for invalid in invalids:
314 handle_invalid(invalid, schema)
315
316
317#
318# handle a testSuite element
319#
320def handle_testSuite(node, level = 0):
321 global nb_schemas_tests, nb_schemas_success, nb_schemas_failed
322 global nb_instances_tests, nb_instances_success, nb_instances_failed
Daniel Veillarda1a9d042003-03-18 16:53:17 +0000323 if verbose and level >= 0:
324 old_schemas_tests = nb_schemas_tests
325 old_schemas_success = nb_schemas_success
326 old_schemas_failed = nb_schemas_failed
327 old_instances_tests = nb_instances_tests
328 old_instances_success = nb_instances_success
329 old_instances_failed = nb_instances_failed
Daniel Veillardeb7189f2003-02-27 20:11:13 +0000330
331 docs = node.xpathEval('documentation')
332 authors = node.xpathEval('author')
333 if docs != []:
334 msg = ""
335 for doc in docs:
336 msg = msg + doc.content + " "
337 if authors != []:
338 msg = msg + "written by "
339 for author in authors:
340 msg = msg + author.content + " "
341 print msg
Daniel Veillarda1a9d042003-03-18 16:53:17 +0000342 sections = node.xpathEval('section')
Daniel Veillard798024a2003-03-19 10:36:09 +0000343 if verbose and sections != [] and level <= 0:
Daniel Veillarda1a9d042003-03-18 16:53:17 +0000344 msg = ""
345 for section in sections:
346 msg = msg + section.content + " "
347 print "Tests for section %s" % (msg)
Daniel Veillardeb7189f2003-02-27 20:11:13 +0000348 for test in node.xpathEval('testCase'):
349 handle_testCase(test)
350 for test in node.xpathEval('testSuite'):
351 handle_testSuite(test, level + 1)
352
Daniel Veillarda1a9d042003-03-18 16:53:17 +0000353
Daniel Veillard798024a2003-03-19 10:36:09 +0000354 if verbose and level >= 0 :
355 if sections != []:
356 msg = ""
357 for section in sections:
358 msg = msg + section.content + " "
359 print "Result of tests for section %s" % (msg)
360 elif docs != []:
361 msg = ""
362 for doc in docs:
363 msg = msg + doc.content + " "
364 print "Result of tests for %s" % (msg)
365
Daniel Veillarda1a9d042003-03-18 16:53:17 +0000366 if nb_schemas_tests != old_schemas_tests:
367 print "found %d test schemas: %d success %d failures" % (
368 nb_schemas_tests - old_schemas_tests,
369 nb_schemas_success - old_schemas_success,
370 nb_schemas_failed - old_schemas_failed)
371 if nb_instances_tests != old_instances_tests:
372 print "found %d test instances: %d success %d failures" % (
373 nb_instances_tests - old_instances_tests,
374 nb_instances_success - old_instances_success,
375 nb_instances_failed - old_instances_failed)
Daniel Veillardeb7189f2003-02-27 20:11:13 +0000376#
377# Parse the conf file
378#
379libxml2.substituteEntitiesDefault(1);
380testsuite = libxml2.parseFile(CONF)
Daniel Veillarda1a9d042003-03-18 16:53:17 +0000381
382#
383# Error and warnng callbacks
384#
385def callback(ctx, str):
386 global log
387 log.write("%s%s" % (ctx, str))
388
389libxml2.registerErrorHandler(callback, "")
390
Daniel Veillardeb7189f2003-02-27 20:11:13 +0000391libxml2.setEntityLoader(resolver)
392root = testsuite.getRootElement()
393if root.name != 'testSuite':
394 print "%s doesn't start with a testSuite element, aborting" % (CONF)
395 sys.exit(1)
396print "Running Relax NG testsuite"
397handle_testSuite(root)
398
399print "\nTOTAL:\nfound %d test schemas: %d success %d failures" % (
400 nb_schemas_tests, nb_schemas_success, nb_schemas_failed)
401print "found %d test instances: %d success %d failures" % (
402 nb_instances_tests, nb_instances_success, nb_instances_failed)
403
404testsuite.freeDoc()
405
406# Memory debug specific
407libxml2.relaxNGCleanupTypes()
408libxml2.cleanupParser()
409if libxml2.debugMemory(1) == 0:
410 print "OK"
411else:
412 print "Memory leak %d bytes" % (libxml2.debugMemory(1))
413 libxml2.dumpMemory()