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