1bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard#!/usr/bin/python
2bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillardimport sys
3878eab04c07a090c7b3aeb182993b579e0ea0195Daniel Veillardimport time
4bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillardimport os
5bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillardimport string
6cb40c222a4f92fb4519ec571547f2b8fcbe6a4edWilliam M. Bracksys.path.insert(0, "python")
7bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillardimport libxml2
8bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
91a99396b18b85d27c33f24b509fe03213ddce04cDaniel Veillardtest_nr = 0
101a99396b18b85d27c33f24b509fe03213ddce04cDaniel Veillardtest_succeed = 0
111a99396b18b85d27c33f24b509fe03213ddce04cDaniel Veillardtest_failed = 0
121a99396b18b85d27c33f24b509fe03213ddce04cDaniel Veillardtest_error = 0
131a99396b18b85d27c33f24b509fe03213ddce04cDaniel Veillard
14bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard#
15bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard# the testsuite description
16bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard#
17bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel VeillardCONF="xml-test-suite/xmlconf/xmlconf.xml"
18bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel VeillardLOG="check-xml-test-suite.log"
19bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
20bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillardlog = open(LOG, "w")
21bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
22bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard#
23bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard# Error and warning handlers
24bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard#
25bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillarderror_nr = 0
26c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillarderror_msg = ''
27bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillarddef errorHandler(ctx, str):
28bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    global error_nr
29c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard    global error_msg
30bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
318f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard    error_nr = error_nr + 1
32c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard    if len(error_msg) < 300:
33c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard        if len(error_msg) == 0 or error_msg[-1] == '\n':
34c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard	    error_msg = error_msg + "   >>" + str
35c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard	else:
36c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard	    error_msg = error_msg + str
37bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
38bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillardlibxml2.registerErrorHandler(errorHandler, None)
39bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
40bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard#warning_nr = 0
41bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard#warning = ''
42bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard#def warningHandler(ctx, str):
43bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard#    global warning_nr
44bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard#    global warning
45bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard#
46bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard#    warning_nr = warning_nr + 1
47bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard#    warning = warning + str
48bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard#
49bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard#libxml2.registerWarningHandler(warningHandler, None)
50bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
51bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard#
52bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard# Used to load the XML testsuite description
53bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard#
54bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillarddef loadNoentDoc(filename):
55bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    ctxt = libxml2.createFileParserCtxt(filename)
56bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if ctxt == None:
57bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        return None
58bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    ctxt.replaceEntities(1)
59bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    ctxt.parseDocument()
60fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard    try:
61fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard	doc = ctxt.doc()
62fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard    except:
63fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard        doc = None
64bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if ctxt.wellFormed() != 1:
65bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        doc.freeDoc()
66bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	return None
67bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    return doc
68bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
69bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard#
70bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard# The conformance testing routines
71bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard#
72bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
73bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillarddef testNotWf(filename, id):
74bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    global error_nr
75c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard    global error_msg
76bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    global log
77bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
78bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    error_nr = 0
79c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard    error_msg = ''
80bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
81bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    ctxt = libxml2.createFileParserCtxt(filename)
82bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if ctxt == None:
83bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        return -1
848f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard    ret = ctxt.parseDocument()
85bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
86fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard    try:
87fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard	doc = ctxt.doc()
88fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard    except:
89fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard        doc = None
908f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard    if doc != None:
918f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard	doc.freeDoc()
928f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard    if ret == 0 or ctxt.wellFormed() != 0:
93bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        print "%s: error: Well Formedness error not detected" % (id)
94bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	log.write("%s: error: Well Formedness error not detected\n" % (id))
95bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	return 0
96bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    return 1
97bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
98bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillarddef testNotWfEnt(filename, id):
99bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    global error_nr
100c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard    global error_msg
101bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    global log
102bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
103bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    error_nr = 0
104c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard    error_msg = ''
105bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
106bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    ctxt = libxml2.createFileParserCtxt(filename)
107bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if ctxt == None:
108bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        return -1
109bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    ctxt.replaceEntities(1)
1108f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard    ret = ctxt.parseDocument()
111bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
112fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard    try:
113fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard	doc = ctxt.doc()
114fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard    except:
115fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard        doc = None
1168f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard    if doc != None:
1178f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard	doc.freeDoc()
1188f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard    if ret == 0 or ctxt.wellFormed() != 0:
119bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        print "%s: error: Well Formedness error not detected" % (id)
120bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	log.write("%s: error: Well Formedness error not detected\n" % (id))
121bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	return 0
122bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    return 1
123bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
124bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillarddef testNotWfEntDtd(filename, id):
125bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    global error_nr
126c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard    global error_msg
127bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    global log
128bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
129bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    error_nr = 0
130c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard    error_msg = ''
131bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
132bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    ctxt = libxml2.createFileParserCtxt(filename)
133bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if ctxt == None:
134bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        return -1
135bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    ctxt.replaceEntities(1)
136bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    ctxt.loadSubset(1)
1378f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard    ret = ctxt.parseDocument()
138bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
139fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard    try:
140fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard	doc = ctxt.doc()
141fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard    except:
142fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard        doc = None
1438f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard    if doc != None:
1448f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard	doc.freeDoc()
1458f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard    if ret == 0 or ctxt.wellFormed() != 0:
146bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        print "%s: error: Well Formedness error not detected" % (id)
147bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	log.write("%s: error: Well Formedness error not detected\n" % (id))
148bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	return 0
149bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    return 1
150bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
151bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillarddef testWfEntDtd(filename, id):
152bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    global error_nr
153c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard    global error_msg
154bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    global log
155bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
156bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    error_nr = 0
157c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard    error_msg = ''
158bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
159bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    ctxt = libxml2.createFileParserCtxt(filename)
160bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if ctxt == None:
161bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        return -1
162bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    ctxt.replaceEntities(1)
163bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    ctxt.loadSubset(1)
1648f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard    ret = ctxt.parseDocument()
165bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
166fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard    try:
167fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard	doc = ctxt.doc()
168fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard    except:
169fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard        doc = None
1708f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard    if doc == None or ret != 0 or ctxt.wellFormed() == 0:
171bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        print "%s: error: wrongly failed to parse the document" % (id)
172bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	log.write("%s: error: wrongly failed to parse the document\n" % (id))
1738f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard	if doc != None:
1748f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard	    doc.freeDoc()
175bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	return 0
176bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if error_nr != 0:
177bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        print "%s: warning: WF document generated an error msg" % (id)
178bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	log.write("%s: error: WF document generated an error msg\n" % (id))
179bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	doc.freeDoc()
180bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	return 2
181bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    doc.freeDoc()
182bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    return 1
183bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
18455253e21f0f41f03afb4842f560a852658077a89Daniel Veillarddef testError(filename, id):
18555253e21f0f41f03afb4842f560a852658077a89Daniel Veillard    global error_nr
18655253e21f0f41f03afb4842f560a852658077a89Daniel Veillard    global error_msg
18755253e21f0f41f03afb4842f560a852658077a89Daniel Veillard    global log
18855253e21f0f41f03afb4842f560a852658077a89Daniel Veillard
18955253e21f0f41f03afb4842f560a852658077a89Daniel Veillard    error_nr = 0
19055253e21f0f41f03afb4842f560a852658077a89Daniel Veillard    error_msg = ''
19155253e21f0f41f03afb4842f560a852658077a89Daniel Veillard
19255253e21f0f41f03afb4842f560a852658077a89Daniel Veillard    ctxt = libxml2.createFileParserCtxt(filename)
19355253e21f0f41f03afb4842f560a852658077a89Daniel Veillard    if ctxt == None:
19455253e21f0f41f03afb4842f560a852658077a89Daniel Veillard        return -1
19555253e21f0f41f03afb4842f560a852658077a89Daniel Veillard    ctxt.replaceEntities(1)
19655253e21f0f41f03afb4842f560a852658077a89Daniel Veillard    ctxt.loadSubset(1)
1978f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard    ret = ctxt.parseDocument()
19855253e21f0f41f03afb4842f560a852658077a89Daniel Veillard
199fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard    try:
200fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard	doc = ctxt.doc()
201fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard    except:
202fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard        doc = None
2038f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard    if doc != None:
2048f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard	doc.freeDoc()
20555253e21f0f41f03afb4842f560a852658077a89Daniel Veillard    if ctxt.wellFormed() == 0:
20655253e21f0f41f03afb4842f560a852658077a89Daniel Veillard        print "%s: warning: failed to parse the document but accepted" % (id)
20755253e21f0f41f03afb4842f560a852658077a89Daniel Veillard	log.write("%s: warning: failed to parse the document but accepte\n" % (id))
20855253e21f0f41f03afb4842f560a852658077a89Daniel Veillard	return 2
20955253e21f0f41f03afb4842f560a852658077a89Daniel Veillard    if error_nr != 0:
21055253e21f0f41f03afb4842f560a852658077a89Daniel Veillard        print "%s: warning: WF document generated an error msg" % (id)
21155253e21f0f41f03afb4842f560a852658077a89Daniel Veillard	log.write("%s: error: WF document generated an error msg\n" % (id))
21255253e21f0f41f03afb4842f560a852658077a89Daniel Veillard	return 2
21355253e21f0f41f03afb4842f560a852658077a89Daniel Veillard    return 1
21455253e21f0f41f03afb4842f560a852658077a89Daniel Veillard
215bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillarddef testInvalid(filename, id):
216bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    global error_nr
217c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard    global error_msg
218bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    global log
219bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
220bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    error_nr = 0
221c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard    error_msg = ''
222bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
223bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    ctxt = libxml2.createFileParserCtxt(filename)
224bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if ctxt == None:
225bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        return -1
226bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    ctxt.validate(1)
2278f597c3bf515bc1dc962c7eefbe6eb6745b9d5a5Daniel Veillard    ret = ctxt.parseDocument()
228bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
229fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard    try:
230fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard	doc = ctxt.doc()
231fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard    except:
232fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard        doc = None
233bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    valid = ctxt.isValid()
234bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if doc == None:
235bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        print "%s: error: wrongly failed to parse the document" % (id)
236bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	log.write("%s: error: wrongly failed to parse the document\n" % (id))
237bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	return 0
238bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if valid == 1:
239bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        print "%s: error: Validity error not detected" % (id)
240bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	log.write("%s: error: Validity error not detected\n" % (id))
241bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	doc.freeDoc()
242bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	return 0
243bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if error_nr == 0:
244bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        print "%s: warning: Validity error not reported" % (id)
245bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	log.write("%s: warning: Validity error not reported\n" % (id))
246bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	doc.freeDoc()
247bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	return 2
248bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
249bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    doc.freeDoc()
250bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    return 1
251bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
252bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillarddef testValid(filename, id):
253bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    global error_nr
254c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard    global error_msg
255bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
256bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    error_nr = 0
257c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard    error_msg = ''
258bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
259bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    ctxt = libxml2.createFileParserCtxt(filename)
260bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if ctxt == None:
261bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        return -1
262bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    ctxt.validate(1)
263bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    ctxt.parseDocument()
264bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
265fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard    try:
266fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard	doc = ctxt.doc()
267fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard    except:
268fa49d87f92bdd6133f95e19b02bc214ade03099eDaniel Veillard        doc = None
269bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    valid = ctxt.isValid()
270bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if doc == None:
271bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        print "%s: error: wrongly failed to parse the document" % (id)
272bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	log.write("%s: error: wrongly failed to parse the document\n" % (id))
273bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	return 0
274bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if valid != 1:
275bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        print "%s: error: Validity check failed" % (id)
276bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	log.write("%s: error: Validity check failed\n" % (id))
277bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	doc.freeDoc()
278bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	return 0
279bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if error_nr != 0 or valid != 1:
280bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        print "%s: warning: valid document reported an error" % (id)
281bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	log.write("%s: warning: valid document reported an error\n" % (id))
282bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	doc.freeDoc()
283bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	return 2
284bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    doc.freeDoc()
285bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    return 1
286bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
287bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillarddef runTest(test):
288bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    global test_nr
289bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    global test_succeed
2901a99396b18b85d27c33f24b509fe03213ddce04cDaniel Veillard    global test_failed
291c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard    global error_msg
292bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    global log
293bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
294bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    uri = test.prop('URI')
295bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    id = test.prop('ID')
296bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if uri == None:
297bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        print "Test without ID:", uri
298bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	return -1
299bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if id == None:
300bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        print "Test without URI:", id
301bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	return -1
302bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    base = test.getBase(None)
303bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    URI = libxml2.buildURI(uri, base)
304bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if os.access(URI, os.R_OK) == 0:
305bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        print "Test %s missing: base %s uri %s" % (URI, base, uri)
306bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	return -1
307bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    type = test.prop('TYPE')
308bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if type == None:
309bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        print "Test %s missing TYPE" % (id)
310bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	return -1
311bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
312bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    extra = None
313bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if type == "invalid":
314bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        res = testInvalid(URI, id)
315bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    elif type == "valid":
316bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        res = testValid(URI, id)
317bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    elif type == "not-wf":
318bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        extra =  test.prop('ENTITIES')
319bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	# print URI
320bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	#if extra == None:
321bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	#    res = testNotWfEntDtd(URI, id)
322bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard 	#elif extra == 'none':
323bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	#    res = testNotWf(URI, id)
324bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	#elif extra == 'general':
325bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	#    res = testNotWfEnt(URI, id)
326bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	#elif extra == 'both' or extra == 'parameter':
327bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	res = testNotWfEntDtd(URI, id)
328bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	#else:
329bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	#    print "Unknow value %s for an ENTITIES test value" % (extra)
330bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	#    return -1
331bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    elif type == "error":
33255253e21f0f41f03afb4842f560a852658077a89Daniel Veillard	res = testError(URI, id)
333bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    else:
334bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        # TODO skipped for now
335bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	return -1
336bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
337bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    test_nr = test_nr + 1
338bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if res > 0:
339bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	test_succeed = test_succeed + 1
340bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    elif res == 0:
341bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	test_failed = test_failed + 1
342bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    elif res < 0:
343bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	test_error = test_error + 1
344bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
345bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    # Log the ontext
346bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if res != 1:
347bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	log.write("   File: %s\n" % (URI))
348c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard	content = string.strip(test.content)
349c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard	while content[-1] == '\n':
350c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard	    content = content[0:-1]
351bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	if extra != None:
352c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard	    log.write("   %s:%s:%s\n" % (type, extra, content))
353bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	else:
354bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	    log.write("   %s:%s\n\n" % (type, content))
355c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard	if error_msg != '':
356c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard	    log.write("   ----\n%s   ----\n" % (error_msg))
357c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard	    error_msg = ''
358c7612996ad1148c324dcd75ca732cf4c0cb68ae0Daniel Veillard	log.write("\n")
359bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
360bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    return 0
361bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
362bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
363bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillarddef runTestCases(case):
364bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    profile = case.prop('PROFILE')
365bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if profile != None and \
366bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard       string.find(profile, "IBM XML Conformance Test Suite - Production") < 0:
367bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	print "=>", profile
368bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    test = case.children
369bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    while test != None:
370bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        if test.name == 'TEST':
371bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	    runTest(test)
372bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	if test.name == 'TESTCASES':
373bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	    runTestCases(test)
374bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        test = test.next
375bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
376bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillardconf = loadNoentDoc(CONF)
377bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillardif conf == None:
378bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    print "Unable to load %s" % CONF
379bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    sys.exit(1)
380bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
381bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillardtestsuite = conf.getRootElement()
382bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillardif testsuite.name != 'TESTSUITE':
383bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    print "Expecting TESTSUITE root element: aborting"
384bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    sys.exit(1)
385bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
386bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillardprofile = testsuite.prop('PROFILE')
387bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillardif profile != None:
388bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    print profile
389bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
390878eab04c07a090c7b3aeb182993b579e0ea0195Daniel Veillardstart = time.time()
391878eab04c07a090c7b3aeb182993b579e0ea0195Daniel Veillard
392bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillardcase = testsuite.children
393bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillardwhile case != None:
394bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    if case.name == 'TESTCASES':
395bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	old_test_nr = test_nr
396bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	old_test_succeed = test_succeed
397bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	old_test_failed = test_failed
398bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	old_test_error = test_error
399bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard        runTestCases(case)
400bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	print "   Ran %d tests: %d suceeded, %d failed and %d generated an error" % (
401bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	       test_nr - old_test_nr, test_succeed - old_test_succeed,
402bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard	       test_failed - old_test_failed, test_error - old_test_error)
403bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard    case = case.next
404bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
405bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillardconf.freeDoc()
406bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillardlog.close()
407bb7ddb342917c61f9c95e97b9a0f16ada6d3cdc9Daniel Veillard
408878eab04c07a090c7b3aeb182993b579e0ea0195Daniel Veillardprint "Ran %d tests: %d suceeded, %d failed and %d generated an error in %.2f s." % (
409878eab04c07a090c7b3aeb182993b579e0ea0195Daniel Veillard      test_nr, test_succeed, test_failed, test_error, time.time() - start)
410