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