Annotation of embedaddon/libxml2/python/tests/input_callback.py, revision 1.1.1.1

1.1       misho       1: #!/usr/bin/python -u
                      2: #
                      3: # This tests custom input callbacks
                      4: #
                      5: import sys
                      6: import libxml2
                      7: try:
                      8:     import StringIO
                      9:     str_io = StringIO.StringIO
                     10: except:
                     11:     import io
                     12:     str_io = io.StringIO
                     13: 
                     14: # We implement a new scheme, py://strings/ that will reference this dictionary
                     15: pystrings = {
                     16:     'catalogs/catalog.xml' :
                     17: '''<?xml version="1.0" encoding="utf-8"?>
                     18: <!DOCTYPE catalog PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN" "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
                     19: <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
                     20:   <rewriteSystem systemIdStartString="http://example.com/dtds/" rewritePrefix="../dtds/"/>
                     21: </catalog>''',
                     22: 
                     23:     'xml/sample.xml' :
                     24: '''<?xml version="1.0" encoding="utf-8"?>
                     25: <!DOCTYPE root SYSTEM "http://example.com/dtds/sample.dtd">
                     26: <root>&sample.entity;</root>''',
                     27: 
                     28:     'dtds/sample.dtd' :
                     29: '''
                     30: <!ELEMENT root (#PCDATA)>
                     31: <!ENTITY sample.entity "replacement text">'''
                     32: }
                     33: 
                     34: prefix = "py://strings/"
                     35: startURL = prefix + "xml/sample.xml"
                     36: catURL = prefix + "catalogs/catalog.xml"
                     37: 
                     38: def my_input_cb(URI):
                     39:     if not(URI.startswith(prefix)):
                     40:         return None
                     41:     path = URI[len(prefix):]
                     42:     if path not in pystrings:
                     43:         return None
                     44:     return str_io(pystrings[path])
                     45: 
                     46: 
                     47: def run_test(desc, docpath, catalog, exp_status="verified", exp_err=[], test_callback=None,
                     48:         root_name="root", root_content="replacement text"):
                     49:     opts = libxml2.XML_PARSE_DTDLOAD | libxml2.XML_PARSE_NONET | libxml2.XML_PARSE_COMPACT
                     50:     actual_err = []
                     51: 
                     52:     def my_global_error_cb(ctx, msg):
                     53:         actual_err.append((-1, msg))
                     54:     def my_ctx_error_cb(arg, msg, severity, reserved):
                     55:         actual_err.append((severity, msg))
                     56: 
                     57:     libxml2.registerErrorHandler(my_global_error_cb, None)
                     58:     try:
                     59:         parser = libxml2.createURLParserCtxt(docpath, opts)
                     60:         parser.setErrorHandler(my_ctx_error_cb, None)
                     61:         if catalog is not None:
                     62:             parser.addLocalCatalog(catalog)
                     63:         if test_callback is not None:
                     64:             test_callback()
                     65:         parser.parseDocument()
                     66:         doc = parser.doc()
                     67:         actual_status = "loaded"
                     68:         e = doc.getRootElement()
                     69:         if e.name == root_name and e.content == root_content:
                     70:             actual_status = "verified"
                     71:         doc.freeDoc()
                     72:     except libxml2.parserError:
                     73:         actual_status = "not loaded"
                     74: 
                     75:     if actual_status != exp_status:
                     76:         print("Test '%s' failed: expect status '%s', actual '%s'" % (desc, exp_status, actual_status))
                     77:         sys.exit(1)
                     78:     elif actual_err != exp_err:
                     79:         print("Test '%s' failed" % desc)
                     80:         print("Expect errors:")
                     81:         for s,m in exp_err: print("  [%2d] '%s'" % (s,m))
                     82:         print("Actual errors:")
                     83:         for s,m in actual_err: print("  [%2d] '%s'" % (s,m))
                     84:         sys.exit(1)
                     85: 
                     86: 
                     87: # Check that we cannot read custom schema without custom callback
                     88: run_test(desc="Loading entity without custom callback",
                     89:         docpath=startURL, catalog=None,
                     90:         exp_status="not loaded", exp_err=[
                     91:             (-1, "I/O "),
                     92:             (-1, "warning : "),
                     93:             (-1, "failed to load external entity \"py://strings/xml/sample.xml\"\n")
                     94:             ])
                     95: 
                     96: # Register handler and try to load the same entity
                     97: libxml2.registerInputCallback(my_input_cb)
                     98: run_test(desc="Loading entity with custom callback",
                     99:         docpath=startURL, catalog=None,
                    100:         exp_status="loaded", exp_err=[
                    101:             (-1, "Attempt to load network entity http://example.com/dtds/sample.dtd"),
                    102:             ( 4, "Entity 'sample.entity' not defined\n")
                    103:             ])
                    104: 
                    105: # Register a catalog (also accessible via pystr://) and retry
                    106: run_test(desc="Loading entity with custom callback and catalog",
                    107:         docpath=startURL, catalog=catURL)
                    108: 
                    109: # Unregister custom callback when parser is already created
                    110: run_test(desc="Loading entity and unregistering callback",
                    111:         docpath=startURL, catalog=catURL,
                    112:         test_callback=lambda: libxml2.popInputCallbacks(),
                    113:         exp_status="loaded", exp_err=[
                    114:             ( 3, "failed to load external entity \"py://strings/dtds/sample.dtd\"\n"),
                    115:             ( 4, "Entity 'sample.entity' not defined\n")
                    116:             ])
                    117: 
                    118: # Try to load the document again
                    119: run_test(desc="Retry loading document after unregistering callback",
                    120:         docpath=startURL, catalog=catURL,
                    121:         exp_status="not loaded", exp_err=[
                    122:             (-1, "I/O "),
                    123:             (-1, "warning : "),
                    124:             (-1, "failed to load external entity \"py://strings/xml/sample.xml\"\n")
                    125:             ])
                    126: 
                    127: # But should be able to read standard I/O yet...
                    128: run_test(desc="Loading using standard i/o after unregistering callback",
                    129:         docpath="tst.xml", catalog=None,
                    130:         root_name='doc', root_content='bar')
                    131: 
                    132: # Now pop ALL input callbacks, should fail to load even standard I/O
                    133: try:
                    134:     while True:
                    135:         libxml2.popInputCallbacks()
                    136: except IndexError:
                    137:     pass
                    138: 
                    139: run_test(desc="Loading using standard i/o after unregistering all callbacks",
                    140:         docpath="tst.xml", catalog=None,
                    141:         exp_status="not loaded", exp_err=[
                    142:             (-1, "I/O "),
                    143:             (-1, "warning : "),
                    144:             (-1, "failed to load external entity \"tst.xml\"\n")
                    145:             ])
                    146: 
                    147: print("OK")
                    148: sys.exit(0);

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>