15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/python
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import sys
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import time
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import string
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import StringIO
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sys.path.insert(0, "python")
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import libxml2
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Memory debug specific
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)libxml2.debugMemory(1)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)debug = 0
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)quiet = 1
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# the testsuite description
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CONF=os.path.join(os.path.dirname(__file__), "test/relaxng/testsuite.xml")
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LOG="check-relaxng-test-suite2.log"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)log = open(LOG, "w")
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)nb_schemas_tests = 0
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)nb_schemas_success = 0
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)nb_schemas_failed = 0
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)nb_instances_tests = 0
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)nb_instances_success = 0
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)nb_instances_failed = 0
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)libxml2.lineNumbersDefault(1)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Resolver callback
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)resources = {}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def resolver(URL, ID, ctxt):
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global resources
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if resources.has_key(URL):
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(StringIO.StringIO(resources[URL]))
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    log.write("Resolver failure: asked %s\n" % (URL))
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    log.write("resources: %s\n" % (resources))
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return None
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Load the previous results
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#results = {}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#previous = {}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#try:
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#    res = libxml2.parseFile(RES)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#except:
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#    log.write("Could not parse %s" % (RES))
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# handle a valid instance
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def handle_valid(node, schema):
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global log
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global nb_instances_success
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global nb_instances_failed
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    instance = node.prop("dtd")
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if instance == None:
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        instance = ""
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    child = node.children
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while child != None:
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if child.type != 'text':
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    instance = instance + child.serialize()
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	child = child.next
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#    mem = libxml2.debugMemory(1);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    try:
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	doc = libxml2.parseDoc(instance)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    except:
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        doc = None
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if doc == None:
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        log.write("\nFailed to parse correct instance:\n-----\n")
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	log.write(instance)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        log.write("\n-----\n")
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	nb_instances_failed = nb_instances_failed + 1
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if debug:
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print "instance line %d" % (node.lineNo())
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    try:
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ctxt = schema.relaxNGNewValidCtxt()
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = doc.relaxNGValidateDoc(ctxt)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	del ctxt
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    except:
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret = -1
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    doc.freeDoc()
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#    if mem != libxml2.debugMemory(1):
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#	print "validating instance %d line %d leaks" % (
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#		  nb_instances_tests, node.lineNo())
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ret != 0:
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        log.write("\nFailed to validate correct instance:\n-----\n")
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	log.write(instance)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        log.write("\n-----\n")
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	nb_instances_failed = nb_instances_failed + 1
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	nb_instances_success = nb_instances_success + 1
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# handle an invalid instance
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def handle_invalid(node, schema):
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global log
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global nb_instances_success
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global nb_instances_failed
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    instance = node.prop("dtd")
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if instance == None:
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        instance = ""
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    child = node.children
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while child != None:
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if child.type != 'text':
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    instance = instance + child.serialize()
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	child = child.next
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#    mem = libxml2.debugMemory(1);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    try:
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	doc = libxml2.parseDoc(instance)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    except:
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        doc = None
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if doc == None:
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        log.write("\nStrange: failed to parse incorrect instance:\n-----\n")
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	log.write(instance)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        log.write("\n-----\n")
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if debug:
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print "instance line %d" % (node.lineNo())
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    try:
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ctxt = schema.relaxNGNewValidCtxt()
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = doc.relaxNGValidateDoc(ctxt)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	del ctxt
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    except:
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret = -1
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    doc.freeDoc()
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#    mem2 = libxml2.debugMemory(1)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#    if mem != mem2:
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#	print "validating instance %d line %d leaks %d bytes" % (
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#		  nb_instances_tests, node.lineNo(), mem2 - mem)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ret == 0:
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        log.write("\nFailed to detect validation problem in instance:\n-----\n")
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	log.write(instance)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        log.write("\n-----\n")
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	nb_instances_failed = nb_instances_failed + 1
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	nb_instances_success = nb_instances_success + 1
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# handle an incorrect test
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def handle_correct(node):
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global log
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global nb_schemas_success
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global nb_schemas_failed
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    schema = ""
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    child = node.children
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while child != None:
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if child.type != 'text':
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    schema = schema + child.serialize()
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	child = child.next
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    try:
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rngp = libxml2.relaxNGNewMemParserCtxt(schema, len(schema))
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rngs = rngp.relaxNGParse()
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    except:
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rngs = None
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if rngs == None:
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        log.write("\nFailed to compile correct schema:\n-----\n")
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	log.write(schema)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        log.write("\n-----\n")
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	nb_schemas_failed = nb_schemas_failed + 1
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	nb_schemas_success = nb_schemas_success + 1
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rngs
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def handle_incorrect(node):
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global log
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global nb_schemas_success
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global nb_schemas_failed
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    schema = ""
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    child = node.children
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while child != None:
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if child.type != 'text':
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    schema = schema + child.serialize()
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	child = child.next
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    try:
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rngp = libxml2.relaxNGNewMemParserCtxt(schema, len(schema))
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rngs = rngp.relaxNGParse()
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    except:
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rngs = None
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if rngs != None:
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        log.write("\nFailed to detect schema error in:\n-----\n")
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	log.write(schema)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        log.write("\n-----\n")
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	nb_schemas_failed = nb_schemas_failed + 1
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#	log.write("\nSuccess detecting schema error in:\n-----\n")
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#	log.write(schema)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#	log.write("\n-----\n")
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	nb_schemas_success = nb_schemas_success + 1
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return None
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# resource handling: keep a dictionary of URL->string mappings
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def handle_resource(node, dir):
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global resources
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    try:
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	name = node.prop('name')
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    except:
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name = None
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if name == None or name == '':
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        log.write("resource has no name")
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if dir != None:
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#        name = libxml2.buildURI(name, dir)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name = dir + '/' + name
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    res = ""
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    child = node.children
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while child != None:
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if child.type != 'text':
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    res = res + child.serialize()
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	child = child.next
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resources[name] = res
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# dir handling: pseudo directory resources
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def handle_dir(node, dir):
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    try:
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	name = node.prop('name')
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    except:
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name = None
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if name == None or name == '':
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        log.write("resource has no name")
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if dir != None:
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#        name = libxml2.buildURI(name, dir)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name = dir + '/' + name
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dirs = node.xpathEval('dir')
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for dir in dirs:
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        handle_dir(dir, name)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    res = node.xpathEval('resource')
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for r in res:
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        handle_resource(r, name)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# handle a testCase element
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def handle_testCase(node):
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global nb_schemas_tests
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global nb_instances_tests
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global resources
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sections = node.xpathEval('string(section)')
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    log.write("\n    ======== test %d line %d section %s ==========\n" % (
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              nb_schemas_tests, node.lineNo(), sections))
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resources = {}
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if debug:
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print "test %d line %d" % (nb_schemas_tests, node.lineNo())
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dirs = node.xpathEval('dir')
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for dir in dirs:
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        handle_dir(dir, None)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    res = node.xpathEval('resource')
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for r in res:
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        handle_resource(r, None)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tsts = node.xpathEval('incorrect')
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if tsts != []:
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if len(tsts) != 1:
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    print "warning test line %d has more than one <incorrect> example" %(node.lineNo())
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	schema = handle_incorrect(tsts[0])
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tsts = node.xpathEval('correct')
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if tsts != []:
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if len(tsts) != 1:
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		print "warning test line %d has more than one <correct> example"% (node.lineNo())
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    schema = handle_correct(tsts[0])
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else:
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    print "warning <testCase> line %d has no <correct> nor <incorrect> child" % (node.lineNo())
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nb_schemas_tests = nb_schemas_tests + 1;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    valids = node.xpathEval('valid')
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    invalids = node.xpathEval('invalid')
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nb_instances_tests = nb_instances_tests + len(valids) + len(invalids)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if schema != None:
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for valid in valids:
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    handle_valid(valid, schema)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for invalid in invalids:
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    handle_invalid(invalid, schema)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# handle a testSuite element
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def handle_testSuite(node, level = 0):
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global nb_schemas_tests, nb_schemas_success, nb_schemas_failed
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global nb_instances_tests, nb_instances_success, nb_instances_failed
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if level >= 1:
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	old_schemas_tests = nb_schemas_tests
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	old_schemas_success = nb_schemas_success
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	old_schemas_failed = nb_schemas_failed
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	old_instances_tests = nb_instances_tests
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	old_instances_success = nb_instances_success
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	old_instances_failed = nb_instances_failed
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    docs = node.xpathEval('documentation')
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    authors = node.xpathEval('author')
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if docs != []:
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        msg = ""
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for doc in docs:
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    msg = msg + doc.content + " "
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if authors != []:
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    msg = msg + "written by "
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for author in authors:
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        msg = msg + author.content + " "
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if quiet == 0:
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    print msg
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sections = node.xpathEval('section')
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if sections != [] and level <= 0:
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        msg = ""
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for section in sections:
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    msg = msg + section.content + " "
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if quiet == 0:
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    print "Tests for section %s" % (msg)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for test in node.xpathEval('testCase'):
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        handle_testCase(test)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for test in node.xpathEval('testSuite'):
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        handle_testSuite(test, level + 1)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if level >= 1 and sections != []:
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        msg = ""
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for section in sections:
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    msg = msg + section.content + " "
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print "Result of tests for section %s" % (msg)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if nb_schemas_tests != old_schemas_tests:
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    print "found %d test schemas: %d success %d failures" % (
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		  nb_schemas_tests - old_schemas_tests,
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		  nb_schemas_success - old_schemas_success,
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		  nb_schemas_failed - old_schemas_failed)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if nb_instances_tests != old_instances_tests:
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    print "found %d test instances: %d success %d failures" % (
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		  nb_instances_tests - old_instances_tests,
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		  nb_instances_success - old_instances_success,
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		  nb_instances_failed - old_instances_failed)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Parse the conf file
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)libxml2.substituteEntitiesDefault(1);
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)testsuite = libxml2.parseFile(CONF)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Error and warnng callbacks
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def callback(ctx, str):
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global log
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    log.write("%s%s" % (ctx, str))
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)libxml2.registerErrorHandler(callback, "")
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)libxml2.setEntityLoader(resolver)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)root = testsuite.getRootElement()
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if root.name != 'testSuite':
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print "%s doesn't start with a testSuite element, aborting" % (CONF)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sys.exit(1)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if quiet == 0:
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print "Running Relax NG testsuite"
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)handle_testSuite(root)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if quiet == 0:
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print "\nTOTAL:\n"
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if quiet == 0 or nb_schemas_failed != 0:
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print "found %d test schemas: %d success %d failures" % (
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      nb_schemas_tests, nb_schemas_success, nb_schemas_failed)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if quiet == 0 or nb_instances_failed != 0:
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print "found %d test instances: %d success %d failures" % (
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      nb_instances_tests, nb_instances_success, nb_instances_failed)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)testsuite.freeDoc()
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Memory debug specific
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)libxml2.relaxNGCleanupTypes()
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)libxml2.cleanupParser()
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if libxml2.debugMemory(1) == 0:
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if quiet == 0:
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	print "OK"
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)else:
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print "Memory leak %d bytes" % (libxml2.debugMemory(1))
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    libxml2.dumpMemory()
419