BRANCH release for 2.5.x critical patches
[baserock-morphs:libxml2.git] / check-xinclude-test-suite.py
1 #!/usr/bin/python
2 import sys
3 import time
4 import os
5 import string
6 sys.path.append("python")
7 import libxml2
8
9 #
10 # the testsuite description
11 #
12 DIR="xinclude-test-suite"
13 CONF="testdescr.xml"
14 LOG="check-xinclude-test-suite.log"
15
16 log = open(LOG, "w")
17
18 os.chdir(DIR)
19
20 test_nr = 0
21 test_succeed = 0
22 test_failed = 0
23 test_error = 0
24 #
25 # Error and warning handlers
26 #
27 error_nr = 0
28 error_msg = ''
29
30 def errorHandler(ctx, str):
31     global error_nr
32     global error_msg
33
34     if string.find(str, "error:") >= 0:
35         error_nr = error_nr + 1
36     if len(error_msg) < 300:
37         if len(error_msg) == 0 or error_msg[-1] == '\n':
38             error_msg = error_msg + "   >>" + str
39         else:
40             error_msg = error_msg + str
41
42 libxml2.registerErrorHandler(errorHandler, None)
43
44 def testXInclude(filename, id):
45     global error_nr
46     global error_msg
47     global log
48
49     error_nr = 0
50     error_msg = ''
51
52     print "testXInclude(%s, %s)" % (filename, id)
53     return 1
54
55 def runTest(test, basedir):
56     global test_nr
57     global test_failed
58     global test_error
59     global test_succeed
60     global error_msg
61     global log
62
63     fatal_error = 0
64     uri = test.prop('href')
65     id = test.prop('id')
66     type = test.prop('type')
67     if uri == None:
68         print "Test without ID:", uri
69         return -1
70     if id == None:
71         print "Test without URI:", id
72         return -1
73     if type == None:
74         print "Test without URI:", id
75         return -1
76     if basedir != None:
77         URI = basedir + "/" + uri
78     else:
79         URI = uri
80     if os.access(URI, os.R_OK) == 0:
81         print "Test %s missing: base %s uri %s" % (URI, basedir, uri)
82         return -1
83
84     expected = None
85     if type != 'error':
86         output = test.xpathEval('string(output)')
87         if output == 'No output file.':
88             output = None
89         if output == '':
90             output = None
91         if output != None:
92             if basedir != None:
93                 output = basedir + "/" + output
94             if os.access(output, os.R_OK) == 0:
95                 print "Result for %s missing: %s" % (id, output)
96                 output = None
97             else:
98                 try:
99                     f = open(output)
100                     expected = f.read()
101                 except:
102                     print "Result for %s unreadable: %s" % (id, output)
103
104     try:
105         # print "testing %s" % (URI)
106         doc = libxml2.parseFile(URI)
107     except:
108         doc = None
109     if doc != None:
110         res = doc.xincludeProcess()
111         if res >= 0 and expected != None:
112             result = doc.serialize()
113             if result != expected:
114                 print "Result for %s differs" % (id)
115                 print '----'
116                 print result
117                 print '----'
118                 print expected
119                 print '----'
120
121         doc.freeDoc()
122     else:
123         print "Failed to parse %s" % (URI)
124         res = -1
125
126     
127
128     test_nr = test_nr + 1
129     if type == 'success':
130         if res > 0:
131             test_succeed = test_succeed + 1
132         elif res == 0:
133             test_failed = test_failed + 1
134             print "Test %s: no substitution done ???" % (id)
135         elif res < 0:
136             test_error = test_error + 1
137             print "Test %s: failed valid XInclude processing" % (id)
138     elif type == 'error':
139         if res > 0:
140             test_error = test_error + 1
141             print "Test %s: failed to detect invalid XInclude processing" % (id)
142         elif res == 0:
143             test_failed = test_failed + 1
144             print "Test %s: Invalid but no substitution done" % (id)
145         elif res < 0:
146             test_succeed = test_succeed + 1
147     elif type == 'optional':
148         if res > 0:
149             test_succeed = test_succeed + 1
150         else:
151             print "Test %s: failed optional test" % (id)
152
153     # Log the ontext
154     if res != 1:
155         log.write("Test ID %s\n" % (id))
156         log.write("   File: %s\n" % (URI))
157         content = string.strip(test.content)
158         while content[-1] == '\n':
159             content = content[0:-1]
160         log.write("   %s:%s\n\n" % (type, content))
161         if error_msg != '':
162             log.write("   ----\n%s   ----\n" % (error_msg))
163             error_msg = ''
164         log.write("\n")
165
166     return 0
167             
168
169 def runTestCases(case):
170     creator = case.prop('creator')
171     if creator != None:
172         print "=>", creator
173     base = case.getBase(None)
174     basedir = case.prop('basedir')
175     if basedir != None:
176         base = libxml2.buildURI(basedir, base)
177     test = case.children
178     while test != None:
179         if test.name == 'testcase':
180             runTest(test, base)
181         if test.name == 'testcases':
182             runTestCases(test)
183         test = test.next
184         
185 conf = libxml2.parseFile(CONF)
186 if conf == None:
187     print "Unable to load %s" % CONF
188     sys.exit(1)
189
190 testsuite = conf.getRootElement()
191 if testsuite.name != 'testsuite':
192     print "Expecting TESTSUITE root element: aborting"
193     sys.exit(1)
194
195 profile = testsuite.prop('PROFILE')
196 if profile != None:
197     print profile
198
199 start = time.time()
200
201 case = testsuite.children
202 while case != None:
203     if case.name == 'testcases':
204         old_test_nr = test_nr
205         old_test_succeed = test_succeed
206         old_test_failed = test_failed
207         old_test_error = test_error
208         runTestCases(case)
209         print "   Ran %d tests: %d suceeded, %d failed and %d generated an error" % (
210                test_nr - old_test_nr, test_succeed - old_test_succeed,
211                test_failed - old_test_failed, test_error - old_test_error)
212     case = case.next
213
214 conf.freeDoc()
215 log.close()
216
217 print "Ran %d tests: %d suceeded, %d failed and %d generated an error in %.2f s." % (
218       test_nr, test_succeed, test_failed, test_error, time.time() - start)