blob: feb68174033c1a040f6e08af9d4c75efff37e0a6 [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
48libxml2.setEntityLoader(resolver)
49
50#
51# handle a valid instance
52#
53def handle_valid(node, schema):
54 global log
55 global nb_instances_success
56 global nb_instances_failed
57
58 instance = ""
59 child = node.children
60 while child != None:
61 if child.type != 'text':
62 instance = instance + child.serialize()
63 child = child.next
64
65 try:
66 doc = libxml2.parseDoc(instance)
67 except:
68 doc = None
69
70 if doc == None:
71 log.write("\nFailed to parse correct instance:\n-----\n")
72 log.write(instance)
73 log.write("\n-----\n")
74 nb_instances_failed = nb_instances_failed + 1
75 return
76
77 try:
78 ctxt = schema.relaxNGNewValidCtxt()
79 ret = doc.relaxNGValidateDoc(ctxt)
80 except:
81 ret = -1
82 if ret != 0:
83 log.write("\nFailed to validate correct instance:\n-----\n")
84 log.write(instance)
85 log.write("\n-----\n")
86 nb_instances_failed = nb_instances_failed + 1
87 else:
88 nb_instances_success = nb_instances_success + 1
89
90#
91# handle an invalid instance
92#
93def handle_invalid(node, schema):
94 global log
95 global nb_instances_success
96 global nb_instances_failed
97
98 instance = ""
99 child = node.children
100 while child != None:
101 if child.type != 'text':
102 instance = instance + child.serialize()
103 child = child.next
104
105 try:
106 doc = libxml2.parseDoc(instance)
107 except:
108 doc = None
109
110 if doc == None:
111 log.write("\nStrange: failed to parse incorrect instance:\n-----\n")
112 log.write(instance)
113 log.write("\n-----\n")
114 return
115
116 try:
117 ctxt = schema.relaxNGNewValidCtxt()
118 ret = doc.relaxNGValidateDoc(ctxt)
119 except:
120 ret = -1
121 if ret == 0:
122 log.write("\nFailed to detect validation problem in instance:\n-----\n")
123 log.write(instance)
124 log.write("\n-----\n")
125 nb_instances_failed = nb_instances_failed + 1
126 else:
127 nb_instances_success = nb_instances_success + 1
128
129#
130# handle an incorrect test
131#
132def handle_correct(node):
133 global log
134 global nb_schemas_success
135 global nb_schemas_failed
136
137 schema = ""
138 child = node.children
139 while child != None:
140 if child.type != 'text':
141 schema = schema + child.serialize()
142 child = child.next
143
144 try:
145 rngp = libxml2.relaxNGNewMemParserCtxt(schema, len(schema))
146 rngs = rngp.relaxNGParse()
147 except:
148 rngs = None
149 if rngs == None:
150 log.write("\nFailed to compile correct schema:\n-----\n")
151 log.write(schema)
152 log.write("\n-----\n")
153 nb_schemas_failed = nb_schemas_failed + 1
154 else:
155 nb_schemas_success = nb_schemas_success + 1
156 return rngs
157
158def handle_incorrect(node):
159 global log
160 global nb_schemas_success
161 global nb_schemas_failed
162
163 schema = ""
164 child = node.children
165 while child != None:
166 if child.type != 'text':
167 schema = schema + child.serialize()
168 child = child.next
169
170 try:
171 rngp = libxml2.relaxNGNewMemParserCtxt(schema, len(schema))
172 rngs = rngp.relaxNGParse()
173 except:
174 rngs = None
175 if rngs != None:
176 log.write("\nFailed to detect schema error in:\n-----\n")
177 log.write(schema)
178 log.write("\n-----\n")
179 nb_schemas_failed = nb_schemas_failed + 1
180 else:
181# log.write("\nSuccess detecting schema error in:\n-----\n")
182# log.write(schema)
183# log.write("\n-----\n")
184 nb_schemas_success = nb_schemas_success + 1
185 return None
186
187#
188# resource handling: keep a dictionary of URL->string mappings
189#
190def handle_resource(node, dir):
191 global resources
192
193 try:
194 name = node.prop('name')
195 except:
196 name = None
197
198 if name == None or name == '':
199 log.write("resource has no name")
200 return;
201
202 if dir != None:
203# name = libxml2.buildURI(name, dir)
204 name = dir + '/' + name
205
206 res = ""
207 child = node.children
208 while child != None:
209 if child.type != 'text':
210 res = res + child.serialize()
211 child = child.next
212 resources[name] = res
213
214#
215# dir handling: pseudo directory resources
216#
217def handle_dir(node, dir):
218 try:
219 name = node.prop('name')
220 except:
221 name = None
222
223 if name == None or name == '':
224 log.write("resource has no name")
225 return;
226
227 if dir != None:
228# name = libxml2.buildURI(name, dir)
229 name = dir + '/' + name
230
231 dirs = node.xpathEval('dir')
232 for dir in dirs:
233 handle_dir(dir, name)
234 res = node.xpathEval('resource')
235 for r in res:
236 handle_resource(r, name)
237
238
239#
240# handle a testCase element
241#
242def handle_testCase(node):
243 global nb_schemas_tests
244 global nb_instances_tests
245 global resources
246
247 log.write("\n ============= test %d line %d ================\n" % (
248
249 nb_schemas_tests, node.lineNo()))
250 resources = {}
251
252 dirs = node.xpathEval('dir')
253 for dir in dirs:
254 handle_dir(dir, None)
255 res = node.xpathEval('resource')
256 for r in res:
257 handle_resource(r, None)
258
259 tsts = node.xpathEval('incorrect')
260 if tsts != []:
261 if len(tsts) != 1:
262 print "warning test line %d has more than one <incorrect> example" %(node.lineNo())
263 schema = handle_incorrect(tsts[0])
264 else:
265 tsts = node.xpathEval('correct')
266 if tsts != []:
267 if len(tsts) != 1:
268 print "warning test line %d has more than one <correct> example"% (node.lineNo())
269 schema = handle_correct(tsts[0])
270 else:
271 print "warning <testCase> line %d has no <correct> nor <incorrect> child" % (node.lineNo())
272
273 nb_schemas_tests = nb_schemas_tests + 1;
274
275 valids = node.xpathEval('valid')
276 invalids = node.xpathEval('invalid')
277 nb_instances_tests = nb_instances_tests + len(valids) + len(invalids)
278 if schema != None:
279 for valid in valids:
280 handle_valid(valid, schema)
281 for invalid in invalids:
282 handle_invalid(invalid, schema)
283
284
285#
286# handle a testSuite element
287#
288def handle_testSuite(node):
289 docs = node.xpathEval('documentation')
290 authors = node.xpathEval('author')
291 if docs != []:
292 msg = ""
293 for doc in docs:
294 msg = msg + doc.content + " "
295 if authors != []:
296 msg = msg + "written by "
297 for author in authors:
298 msg = msg + author.content + " "
299 print msg
300 sections = node.xpathEval('section')
301 if sections != []:
302 msg = ""
303 for section in sections:
304 msg = msg + section.content + " "
305 print "Tests for section %s" % (msg)
306 for test in node.xpathEval('testCase'):
307 handle_testCase(test)
308 for test in node.xpathEval('testSuite'):
309 handle_testSuite(test)
310
311
312#
313# Parse the conf file
314#
315testsuite = libxml2.parseFile(CONF)
316root = testsuite.getRootElement()
317if root.name != 'testSuite':
318 print "%s doesn't start with a testSuite element, aborting" % (CONF)
319 sys.exit(1)
320print "Running Relax NG testsuite"
321handle_testSuite(root)
322
323print "\nTOTAL:\nfound %d test schemas: %d success %d failures" % (
324 nb_schemas_tests, nb_schemas_success, nb_schemas_failed)
325print "found %d test instances: %d success %d failures" % (
326 nb_instances_tests, nb_instances_success, nb_instances_failed)