#include "config.h" #include #include #include #include #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_FCNTL_H #include #endif #ifdef HAVE_SYS_MMAN_H #include /* seems needed for Solaris */ #ifndef MAP_FAIL #define MAP_FAIL ((void *) -1) #endif #endif #ifdef HAVE_SYS_STAT_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #include #define OASIS_TEST "conf/xmlconf.xml" #define TEST_OK 0 #define TEST_FAILED -1 #define TYPE_ERROR 0 #define TYPE_NOTWF 1 #define TYPE_INVALID 2 #define TYPE_VALID 3 static const char *types[] = { "error", "not-wf", "invalid", "valid", NULL }; static int verbose = 0; static int wfWarning = 0; static int wfError = 0; static int validWarning = 0; static int validError = 0; static int passed = 0; static int failed = 0; /************************************************************************ * * * Test ouput * * * ************************************************************************/ /** * xmlTestError: * @ctx: an XML parser context * @msg: the message to display/transmit * @...: extra parameters for the message display * * Display and format an error messages, gives file, line, position and * extra parameters. */ void xmlTestError(void *ctx, const char *msg, ...) { wfError++; } /** * xmlTestWarning: * @ctx: an XML parser context * @msg: the message to display/transmit * @...: extra parameters for the message display * * Display and format a warning messages, gives file, line, position and * extra parameters. */ void xmlTestWarning(void *ctx, const char *msg, ...) { wfWarning++; } /** * xmlTestValidityError: * @ctx: an XML parser context * @msg: the message to display/transmit * @...: extra parameters for the message display * * Display and format an validity error messages, gives file, * line, position and extra parameters. */ void xmlTestValidityError(void *ctx, const char *msg, ...) { validError++; } /** * xmlTestValidityWarning: * @ctx: an XML parser context * @msg: the message to display/transmit * @...: extra parameters for the message display * * Display and format a validity warning messages, gives file, line, * position and extra parameters. */ void xmlTestValidityWarning(void *ctx, const char *msg, ...) { validWarning++; } /************************************************************************ * * * The code running the tests * * * ************************************************************************/ int runOasisTest(const xmlChar *id, int type, const char *filename, const xmlChar *sections) { xmlDocPtr doc = NULL; int ret; xmlParserCtxtPtr ctxt; xmlSAXHandler silent, *old; if (verbose) { printf("Test: %s, type %s, URI %s", id, types[type], filename); if (sections != NULL) { printf(", sections %s\n", sections); } else printf("\n"); } wfWarning = 0; wfError = 0; validWarning = 0; validError = 0; ctxt = xmlCreateFileParserCtxt(filename); if (ctxt == NULL) { printf("Test: %s, cannot open %s\n", id, filename); return(-1); } memcpy(&silent, ctxt->sax, sizeof(silent)); old = ctxt->sax; silent.error = xmlTestError; silent.warning = xmlTestWarning; silent.fatalError = xmlTestError; ctxt->sax = &silent; ctxt->vctxt.error = xmlTestValidityError; ctxt->vctxt.warning = xmlTestValidityWarning; if ((type == TYPE_INVALID) || (type == TYPE_VALID)) { ctxt->validate = 1; /* Allocate the Node stack */ ctxt->vctxt.nodeTab = (xmlNodePtr *) xmlMalloc(4 * sizeof(xmlNodePtr)); ctxt->vctxt.nodeNr = 0; ctxt->vctxt.nodeMax = 4; ctxt->vctxt.node = NULL; } xmlParseDocument(ctxt); ret = ctxt->wellFormed; doc = ctxt->myDoc; ctxt->sax = old; xmlFreeParserCtxt(ctxt); if (!ret) { xmlFreeDoc(doc); doc = NULL; } /* * Analyze */ ret = 1; switch (type) { case TYPE_NOTWF: if (wfError == 0) { printf("test %s failed : didn't found WF error\n",filename); ret = 0; } else if (doc != NULL) { printf("test %s : WF error but return result\n",filename); } break; case TYPE_INVALID: if (wfError != 0) { printf( "test %s failed : found WF error in just invalid document\n",filename); ret = 0; } else if (validError == 0) { printf("test %s : didn't found vality errors \n",filename); ret = 0; } break; case TYPE_VALID: if (wfError != 0) { printf("test %s failed : found WF error while valid\n",filename); ret = 0; } else if (validError != 0) { printf( "test %s : found vality errors while document is valid\n",filename); ret = 0; } break; case TYPE_ERROR: break; } /* * free it. */ if (doc != NULL) xmlFreeDoc(doc); if ((verbose) && (ret == 1)) { printf("test %s Ok\n",filename); } if (ret == 1) passed++; else failed++; return(0); } /************************************************************************ * * * OASIS testsuite interface * * * ************************************************************************/ xmlDocPtr readOasisSuite(const char *filename) { int ret; xmlParserCtxtPtr ctxt; xmlSAXHandler silent, *old; xmlDocPtr doc; /* * strip blanks from the test result tree and read in the external * entities. */ xmlKeepBlanksDefault(0); xmlSubstituteEntitiesDefault(1); /* * Do a silent parsing */ ctxt = xmlCreateFileParserCtxt(filename); memcpy(&silent, ctxt->sax, sizeof(silent)); old = ctxt->sax; silent.error = NULL; silent.warning = NULL; silent.fatalError = NULL; xmlParseDocument(ctxt); ret = ctxt->wellFormed; doc = ctxt->myDoc; ctxt->sax = old; xmlFreeParserCtxt(ctxt); if (!ret) { xmlFreeDoc(doc); doc = NULL; } /* * switch back to decent defaults. */ xmlKeepBlanksDefault(1); xmlSubstituteEntitiesDefault(0); return(doc); } int analyzeTest(xmlDocPtr doc, xmlNodePtr test) { xmlChar *type; xmlChar *sections; xmlChar *id; xmlChar *URI; xmlChar *uri = NULL; int typ = -1; /* * Scan the infos */ id = xmlGetProp(test, (xmlChar *) "ID"); if (id == NULL) { fprintf(stderr, "Test without ID\n"); return(0); } type = xmlGetProp(test, (xmlChar *) "TYPE"); if (type == NULL) { fprintf(stderr, "Test %s without TYPE\n", id); xmlFree(id); return(0); } if (!xmlStrcmp(type, (const xmlChar *) "not-wf")) typ = TYPE_NOTWF; else if (!xmlStrcmp(type, (const xmlChar *) "error")) typ = TYPE_ERROR; else if (!xmlStrcmp(type, (const xmlChar *) "valid")) typ = TYPE_VALID; else if (!xmlStrcmp(type, (const xmlChar *) "invalid")) typ = TYPE_INVALID; else { fprintf(stderr, "Test %s : unknown TYPE %s\n", id, type); xmlFree(id); xmlFree(type); return(0); } URI = xmlGetProp(test, (xmlChar *) "URI"); if (URI == NULL) { fprintf(stderr, "Test %s without URI\n", id); xmlFree(id); xmlFree(type); return(0); } uri = xmlBuildURI(URI, doc->URL); sections = xmlGetProp(test, (xmlChar *) "SECTIONS"); /* * Launch the test */ if (uri != NULL) runOasisTest(id, typ, (const char *) uri, sections); else runOasisTest(id, typ, (const char *) URI, sections); /* * Cleanup */ if (sections != NULL) xmlFree(sections); xmlFree(id); xmlFree(type); xmlFree(URI); if (uri != NULL) xmlFree(uri); return(1); } int analyzeCases(xmlDocPtr doc, xmlNodePtr cases) { xmlChar *profile; int nbtests = 0; xmlNodePtr child; profile = xmlGetProp(cases, (xmlChar *) "PROFILE"); if (profile) { printf("\n Suite: %s\n\n", (char *) profile); } else { printf("\n Suite: unknown tests\n\n"); } child = cases->children; while (child != NULL) { if ((child->type == XML_ELEMENT_NODE) && (!xmlStrcmp(child->name, (const xmlChar *)"TEST"))) { nbtests += analyzeTest(doc, child); } child = child->next; } if (profile) { printf("\n Suite: %s : %d tests\n\n", (char *) profile, nbtests); xmlFree(profile); } else { printf("\n Suite: %d tests\n\n", nbtests); } return(nbtests); } int analyzeSuite(xmlDocPtr doc, xmlNodePtr suite) { xmlChar *profile; int nbtests = 0; xmlNodePtr child; if ((suite == NULL) || xmlStrcmp(suite->name, (const xmlChar *)"TESTSUITE")) { fprintf(stderr, "No TESTSUITE root\n"); return(-1); } profile = xmlGetProp(suite, (xmlChar *) "PROFILE"); if (profile) { printf("\n Testing: %s\n\n", (char *) profile); } else { printf("\n Testing: unknown test suite\n\n"); } child = suite->children; while (child != NULL) { if ((child->type == XML_ELEMENT_NODE) && (!xmlStrcmp(child->name, (const xmlChar *)"TESTCASES"))) { nbtests += analyzeCases(doc, child); } child = child->next; } if (profile) { printf("\n Testing: %s : %d tests\n", (char *) profile, nbtests); xmlFree(profile); } else { printf("\n Testing: test suite : %d tests\n", nbtests); } printf("\n Result: %d tests passed, %d tests failed\n", passed, failed); return(nbtests); } int main(int argc, char ** argv) { xmlDocPtr tree; tree = readOasisSuite(OASIS_TEST); if (tree == NULL) { fprintf(stderr, "failed to load %s\n", OASIS_TEST); return(-1); } analyzeSuite(tree, xmlDocGetRootElement(tree)); return(0); }