Annotation of embedaddon/libxml2/python/tests/input_callback.py, revision 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>