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