1#!/usr/bin/python
2import sys
3import time
4import os
5import string
6sys.path.insert(0, "python")
7import libxml2
8
9#
10# the testsuite description
11#
12DIR="xinclude-test-suite"
13CONF="testdescr.xml"
14LOG="check-xinclude-test-suite.log"
15
16log = open(LOG, "w")
17
18os.chdir(DIR)
19
20test_nr = 0
21test_succeed = 0
22test_failed = 0
23test_error = 0
24#
25# Error and warning handlers
26#
27error_nr = 0
28error_msg = ''
29
30def 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
42libxml2.registerErrorHandler(errorHandler, None)
43
44def 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
55def 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    outputfile = None
86    diff = None
87    if type != 'error':
88	output = test.xpathEval('string(output)')
89	if output == 'No output file.':
90	    output = None
91	if output == '':
92	    output = None
93	if output != None:
94	    if basedir != None:
95		output = basedir + "/" + output
96	    if os.access(output, os.R_OK) == 0:
97		print "Result for %s missing: %s" % (id, output)
98		output = None
99	    else:
100		try:
101		    f = open(output)
102		    expected = f.read()
103		    outputfile = output
104		except:
105		    print "Result for %s unreadable: %s" % (id, output)
106
107    try:
108        # print "testing %s" % (URI)
109	doc = libxml2.parseFile(URI)
110    except:
111        doc = None
112    if doc != None:
113        res = doc.xincludeProcess()
114	if res >= 0 and expected != None:
115	    result = doc.serialize()
116	    if result != expected:
117	        print "Result for %s differs" % (id)
118		open("xinclude.res", "w").write(result)
119		diff = os.popen("diff %s xinclude.res" % outputfile).read()
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    if diff != None:
166        log.write("diff from test %s:\n" %(id))
167	log.write("   -----------\n%s\n   -----------\n" % (diff));
168
169    return 0
170
171
172def runTestCases(case):
173    creator = case.prop('creator')
174    if creator != None:
175	print "=>", creator
176    base = case.getBase(None)
177    basedir = case.prop('basedir')
178    if basedir != None:
179	base = libxml2.buildURI(basedir, base)
180    test = case.children
181    while test != None:
182        if test.name == 'testcase':
183	    runTest(test, base)
184	if test.name == 'testcases':
185	    runTestCases(test)
186        test = test.next
187
188conf = libxml2.parseFile(CONF)
189if conf == None:
190    print "Unable to load %s" % CONF
191    sys.exit(1)
192
193testsuite = conf.getRootElement()
194if testsuite.name != 'testsuite':
195    print "Expecting TESTSUITE root element: aborting"
196    sys.exit(1)
197
198profile = testsuite.prop('PROFILE')
199if profile != None:
200    print profile
201
202start = time.time()
203
204case = testsuite.children
205while case != None:
206    if case.name == 'testcases':
207	old_test_nr = test_nr
208	old_test_succeed = test_succeed
209	old_test_failed = test_failed
210	old_test_error = test_error
211        runTestCases(case)
212	print "   Ran %d tests: %d suceeded, %d failed and %d generated an error" % (
213	       test_nr - old_test_nr, test_succeed - old_test_succeed,
214	       test_failed - old_test_failed, test_error - old_test_error)
215    case = case.next
216
217conf.freeDoc()
218log.close()
219
220print "Ran %d tests: %d suceeded, %d failed and %d generated an error in %.2f s." % (
221      test_nr, test_succeed, test_failed, test_error, time.time() - start)
222