ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

runsuite.c
Go to the documentation of this file.
00001 /*
00002  * runsuite.c: C program to run libxml2 againts published testsuites 
00003  *
00004  * See Copyright for the status of this software.
00005  *
00006  * daniel@veillard.com
00007  */
00008 
00009 #ifdef HAVE_CONFIG_H
00010 #include "libxml.h"
00011 #else
00012 #include <stdio.h>
00013 #endif
00014 
00015 #if !defined(_WIN32) || defined(__CYGWIN__)
00016 #include <unistd.h>
00017 #endif
00018 #include <string.h>
00019 #include <sys/types.h>
00020 #include <sys/stat.h>
00021 #include <fcntl.h>
00022 
00023 #include <libxml/parser.h>
00024 #include <libxml/parserInternals.h>
00025 #include <libxml/tree.h>
00026 #include <libxml/uri.h>
00027 #if defined(LIBXML_SCHEMAS_ENABLED) && defined(LIBXML_XPATH_ENABLED)
00028 #include <libxml/xmlreader.h>
00029 
00030 #include <libxml/xpath.h>
00031 #include <libxml/xpathInternals.h>
00032 
00033 #include <libxml/relaxng.h>
00034 #include <libxml/xmlschemas.h>
00035 #include <libxml/xmlschemastypes.h>
00036 
00037 #define LOGFILE "runsuite.log"
00038 static FILE *logfile = NULL;
00039 static int verbose = 0;
00040 
00041 
00042 
00043 #if defined(_WIN32) && !defined(__CYGWIN__)
00044 
00045 #define vsnprintf _vsnprintf
00046 
00047 #define snprintf _snprintf
00048 
00049 #endif
00050 
00051 /************************************************************************
00052  *                                  *
00053  *      File name and path utilities                *
00054  *                                  *
00055  ************************************************************************/
00056 
00057 static int checkTestFile(const char *filename) {
00058     struct stat buf;
00059 
00060     if (stat(filename, &buf) == -1)
00061         return(0);
00062 
00063 #if defined(_WIN32) && !defined(__CYGWIN__)
00064     if (!(buf.st_mode & _S_IFREG))
00065         return(0);
00066 #else
00067     if (!S_ISREG(buf.st_mode))
00068         return(0);
00069 #endif
00070 
00071     return(1);
00072 }
00073 
00074 static xmlChar *composeDir(const xmlChar *dir, const xmlChar *path) {
00075     char buf[500];
00076 
00077     if (dir == NULL) return(xmlStrdup(path));
00078     if (path == NULL) return(NULL);
00079 
00080     snprintf(buf, 500, "%s/%s", (const char *) dir, (const char *) path);
00081     return(xmlStrdup((const xmlChar *) buf));
00082 }
00083 
00084 /************************************************************************
00085  *                                  *
00086  *      Libxml2 specific routines               *
00087  *                                  *
00088  ************************************************************************/
00089 
00090 static int nb_tests = 0;
00091 static int nb_errors = 0;
00092 static int nb_internals = 0;
00093 static int nb_schematas = 0;
00094 static int nb_unimplemented = 0;
00095 static int nb_leaks = 0;
00096 static int extraMemoryFromResolver = 0;
00097 
00098 static int
00099 fatalError(void) {
00100     fprintf(stderr, "Exitting tests on fatal error\n");
00101     exit(1);
00102 }
00103 
00104 /*
00105  * that's needed to implement <resource>
00106  */
00107 #define MAX_ENTITIES 20
00108 static char *testEntitiesName[MAX_ENTITIES];
00109 static char *testEntitiesValue[MAX_ENTITIES];
00110 static int nb_entities = 0;
00111 static void resetEntities(void) {
00112     int i;
00113 
00114     for (i = 0;i < nb_entities;i++) {
00115         if (testEntitiesName[i] != NULL)
00116         xmlFree(testEntitiesName[i]);
00117         if (testEntitiesValue[i] != NULL)
00118         xmlFree(testEntitiesValue[i]);
00119     }
00120     nb_entities = 0;
00121 }
00122 static int addEntity(char *name, char *content) {
00123     if (nb_entities >= MAX_ENTITIES) {
00124     fprintf(stderr, "Too many entities defined\n");
00125     return(-1);
00126     }
00127     testEntitiesName[nb_entities] = name;
00128     testEntitiesValue[nb_entities] = content;
00129     nb_entities++;
00130     return(0);
00131 }
00132 
00133 /*
00134  * We need to trap calls to the resolver to not account memory for the catalog
00135  * which is shared to the current running test. We also don't want to have
00136  * network downloads modifying tests.
00137  */
00138 static xmlParserInputPtr 
00139 testExternalEntityLoader(const char *URL, const char *ID,
00140              xmlParserCtxtPtr ctxt) {
00141     xmlParserInputPtr ret;
00142     int i;
00143 
00144     for (i = 0;i < nb_entities;i++) {
00145         if (!strcmp(testEntitiesName[i], URL)) {
00146         ret = xmlNewStringInputStream(ctxt,
00147                     (const xmlChar *) testEntitiesValue[i]);
00148         if (ret != NULL) {
00149             ret->filename = (const char *)
00150                         xmlStrdup((xmlChar *)testEntitiesName[i]);
00151         }
00152         return(ret);
00153     }
00154     }
00155     if (checkTestFile(URL)) {
00156     ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
00157     } else {
00158     int memused = xmlMemUsed();
00159     ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
00160     extraMemoryFromResolver += xmlMemUsed() - memused;
00161     }
00162 #if 0
00163     if (ret == NULL) {
00164         fprintf(stderr, "Failed to find resource %s\n", URL);
00165     }
00166 #endif
00167       
00168     return(ret);
00169 }
00170 
00171 /*
00172  * Trapping the error messages at the generic level to grab the equivalent of
00173  * stderr messages on CLI tools.
00174  */
00175 static char testErrors[32769];
00176 static int testErrorsSize = 0;
00177 
00178 static void test_log(const char *msg, ...) {
00179     va_list args;
00180     if (logfile != NULL) {
00181         fprintf(logfile, "\n------------\n");
00182     va_start(args, msg);
00183     vfprintf(logfile, msg, args);
00184     va_end(args);
00185     fprintf(logfile, "%s", testErrors);
00186     testErrorsSize = 0; testErrors[0] = 0;
00187     }
00188     if (verbose) {
00189     va_start(args, msg);
00190     vfprintf(stderr, msg, args);
00191     va_end(args);
00192     }
00193 }
00194 
00195 static void
00196 testErrorHandler(void *ctx  ATTRIBUTE_UNUSED, const char *msg, ...) {
00197     va_list args;
00198     int res;
00199 
00200     if (testErrorsSize >= 32768)
00201         return;
00202     va_start(args, msg);
00203     res = vsnprintf(&testErrors[testErrorsSize],
00204                     32768 - testErrorsSize,
00205             msg, args);
00206     va_end(args);
00207     if (testErrorsSize + res >= 32768) {
00208         /* buffer is full */
00209     testErrorsSize = 32768;
00210     testErrors[testErrorsSize] = 0;
00211     } else {
00212         testErrorsSize += res;
00213     }
00214     testErrors[testErrorsSize] = 0;
00215 }
00216 
00217 static xmlXPathContextPtr ctxtXPath;
00218 
00219 static void
00220 initializeLibxml2(void) {
00221     xmlGetWarningsDefaultValue = 0;
00222     xmlPedanticParserDefault(0);
00223 
00224     xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
00225     xmlInitParser();
00226     xmlSetExternalEntityLoader(testExternalEntityLoader);
00227     ctxtXPath = xmlXPathNewContext(NULL);
00228     /*
00229     * Deactivate the cache if created; otherwise we have to create/free it
00230     * for every test, since it will confuse the memory leak detection.
00231     * Note that normally this need not be done, since the cache is not
00232     * created until set explicitely with xmlXPathContextSetCache();
00233     * but for test purposes it is sometimes usefull to activate the
00234     * cache by default for the whole library.
00235     */
00236     if (ctxtXPath->cache != NULL)
00237     xmlXPathContextSetCache(ctxtXPath, 0, -1, 0);
00238     /* used as default nanemspace in xstc tests */
00239     xmlXPathRegisterNs(ctxtXPath, BAD_CAST "ts", BAD_CAST "TestSuite");
00240     xmlXPathRegisterNs(ctxtXPath, BAD_CAST "xlink",
00241                        BAD_CAST "http://www.w3.org/1999/xlink");
00242     xmlSetGenericErrorFunc(NULL, testErrorHandler);
00243 #ifdef LIBXML_SCHEMAS_ENABLED
00244     xmlSchemaInitTypes();
00245     xmlRelaxNGInitTypes();
00246 #endif
00247 }
00248 
00249 static xmlNodePtr
00250 getNext(xmlNodePtr cur, const char *xpath) {
00251     xmlNodePtr ret = NULL;
00252     xmlXPathObjectPtr res;
00253     xmlXPathCompExprPtr comp;
00254 
00255     if ((cur == NULL)  || (cur->doc == NULL) || (xpath == NULL))
00256         return(NULL);
00257     ctxtXPath->doc = cur->doc;
00258     ctxtXPath->node = cur;
00259     comp = xmlXPathCompile(BAD_CAST xpath);
00260     if (comp == NULL) {
00261         fprintf(stderr, "Failed to compile %s\n", xpath);
00262     return(NULL);
00263     }
00264     res = xmlXPathCompiledEval(comp, ctxtXPath);
00265     xmlXPathFreeCompExpr(comp);
00266     if (res == NULL)
00267         return(NULL);
00268     if ((res->type == XPATH_NODESET) &&
00269         (res->nodesetval != NULL) &&
00270     (res->nodesetval->nodeNr > 0) &&
00271     (res->nodesetval->nodeTab != NULL))
00272     ret = res->nodesetval->nodeTab[0];
00273     xmlXPathFreeObject(res);
00274     return(ret);
00275 }
00276 
00277 static xmlChar *
00278 getString(xmlNodePtr cur, const char *xpath) {
00279     xmlChar *ret = NULL;
00280     xmlXPathObjectPtr res;
00281     xmlXPathCompExprPtr comp;
00282 
00283     if ((cur == NULL)  || (cur->doc == NULL) || (xpath == NULL))
00284         return(NULL);
00285     ctxtXPath->doc = cur->doc;
00286     ctxtXPath->node = cur;
00287     comp = xmlXPathCompile(BAD_CAST xpath);
00288     if (comp == NULL) {
00289         fprintf(stderr, "Failed to compile %s\n", xpath);
00290     return(NULL);
00291     }
00292     res = xmlXPathCompiledEval(comp, ctxtXPath);
00293     xmlXPathFreeCompExpr(comp);
00294     if (res == NULL)
00295         return(NULL);
00296     if (res->type == XPATH_STRING) {
00297         ret = res->stringval;
00298     res->stringval = NULL;
00299     }
00300     xmlXPathFreeObject(res);
00301     return(ret);
00302 }
00303 
00304 /************************************************************************
00305  *                                  *
00306  *      Test test/xsdtest/xsdtestsuite.xml          *
00307  *                                  *
00308  ************************************************************************/
00309 
00310 static int
00311 xsdIncorectTestCase(xmlNodePtr cur) {
00312     xmlNodePtr test;
00313     xmlBufferPtr buf;
00314     xmlRelaxNGParserCtxtPtr pctxt;
00315     xmlRelaxNGPtr rng = NULL;
00316     int ret = 0, memt;
00317 
00318     cur = getNext(cur, "./incorrect[1]");
00319     if (cur == NULL) {
00320         return(0);
00321     }
00322 
00323     test = getNext(cur, "./*");
00324     if (test == NULL) {
00325         test_log("Failed to find test in correct line %ld\n",
00326             xmlGetLineNo(cur));
00327         return(1);
00328     }
00329 
00330     memt = xmlMemUsed();
00331     extraMemoryFromResolver = 0;
00332     /*
00333      * dump the schemas to a buffer, then reparse it and compile the schemas
00334      */
00335     buf = xmlBufferCreate();
00336     if (buf == NULL) {
00337         fprintf(stderr, "out of memory !\n");
00338     fatalError();
00339     }
00340     xmlNodeDump(buf, test->doc, test, 0, 0);
00341     pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
00342     xmlRelaxNGSetParserErrors(pctxt,
00343          (xmlRelaxNGValidityErrorFunc) testErrorHandler,
00344          (xmlRelaxNGValidityWarningFunc) testErrorHandler,
00345      pctxt);
00346     rng = xmlRelaxNGParse(pctxt);
00347     xmlRelaxNGFreeParserCtxt(pctxt);
00348     if (rng != NULL) {
00349     test_log("Failed to detect incorect RNG line %ld\n",
00350             xmlGetLineNo(test));
00351         ret = 1;
00352     goto done;
00353     }
00354 
00355 done:
00356     if (buf != NULL)
00357     xmlBufferFree(buf);
00358     if (rng != NULL)
00359         xmlRelaxNGFree(rng);
00360     xmlResetLastError();
00361     if ((memt < xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
00362     test_log("Validation of tests starting line %ld leaked %d\n",
00363         xmlGetLineNo(cur), xmlMemUsed() - memt);
00364     nb_leaks++;
00365     }
00366     return(ret);
00367 }
00368 
00369 static void
00370 installResources(xmlNodePtr tst, const xmlChar *base) {
00371     xmlNodePtr test;
00372     xmlBufferPtr buf;
00373     xmlChar *name, *content, *res;
00374 
00375     buf = xmlBufferCreate();
00376     if (buf == NULL) {
00377         fprintf(stderr, "out of memory !\n");
00378     fatalError();
00379     }
00380     xmlNodeDump(buf, tst->doc, tst, 0, 0);
00381 
00382     while (tst != NULL) {
00383     test = getNext(tst, "./*");
00384     if (test != NULL) {
00385         xmlBufferEmpty(buf);
00386         xmlNodeDump(buf, test->doc, test, 0, 0);
00387         name = getString(tst, "string(@name)");
00388         content = xmlStrdup(buf->content);
00389         if ((name != NULL) && (content != NULL)) {
00390             res = composeDir(base, name);
00391         xmlFree(name);
00392             addEntity((char *) res, (char *) content);
00393         } else {
00394             if (name != NULL) xmlFree(name);
00395             if (content != NULL) xmlFree(content);
00396         }
00397     }
00398     tst = getNext(tst, "following-sibling::resource[1]");
00399     }
00400     if (buf != NULL)
00401     xmlBufferFree(buf);
00402 }
00403 
00404 static void
00405 installDirs(xmlNodePtr tst, const xmlChar *base) {
00406     xmlNodePtr test;
00407     xmlChar *name, *res;
00408 
00409     name = getString(tst, "string(@name)");
00410     if (name == NULL)
00411         return;
00412     res = composeDir(base, name);
00413     xmlFree(name);
00414     if (res == NULL) {
00415     return;
00416     }
00417     /* Now process resources and subdir recursively */
00418     test = getNext(tst, "./resource[1]");
00419     if (test != NULL) {
00420         installResources(test, res);
00421     }
00422     test = getNext(tst, "./dir[1]");
00423     while (test != NULL) {
00424         installDirs(test, res);
00425     test = getNext(test, "following-sibling::dir[1]");
00426     }
00427     xmlFree(res);
00428 }
00429 
00430 static int 
00431 xsdTestCase(xmlNodePtr tst) {
00432     xmlNodePtr test, tmp, cur;
00433     xmlBufferPtr buf;
00434     xmlDocPtr doc = NULL;
00435     xmlRelaxNGParserCtxtPtr pctxt;
00436     xmlRelaxNGValidCtxtPtr ctxt;
00437     xmlRelaxNGPtr rng = NULL;
00438     int ret = 0, mem, memt;
00439     xmlChar *dtd;
00440 
00441     resetEntities();
00442     testErrorsSize = 0; testErrors[0] = 0;
00443 
00444     tmp = getNext(tst, "./dir[1]");
00445     if (tmp != NULL) {
00446         installDirs(tmp, NULL);
00447     }
00448     tmp = getNext(tst, "./resource[1]");
00449     if (tmp != NULL) {
00450         installResources(tmp, NULL);
00451     }
00452 
00453     cur = getNext(tst, "./correct[1]");
00454     if (cur == NULL) {
00455         return(xsdIncorectTestCase(tst));
00456     }
00457     
00458     test = getNext(cur, "./*");
00459     if (test == NULL) {
00460         fprintf(stderr, "Failed to find test in correct line %ld\n",
00461             xmlGetLineNo(cur));
00462         return(1);
00463     }
00464 
00465     memt = xmlMemUsed();
00466     extraMemoryFromResolver = 0;
00467     /*
00468      * dump the schemas to a buffer, then reparse it and compile the schemas
00469      */
00470     buf = xmlBufferCreate();
00471     if (buf == NULL) {
00472         fprintf(stderr, "out of memory !\n");
00473     fatalError();
00474     }
00475     xmlNodeDump(buf, test->doc, test, 0, 0);
00476     pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
00477     xmlRelaxNGSetParserErrors(pctxt,
00478          (xmlRelaxNGValidityErrorFunc) testErrorHandler,
00479          (xmlRelaxNGValidityWarningFunc) testErrorHandler,
00480      pctxt);
00481     rng = xmlRelaxNGParse(pctxt);
00482     xmlRelaxNGFreeParserCtxt(pctxt);
00483     if (extraMemoryFromResolver)
00484         memt = 0;
00485 
00486     if (rng == NULL) {
00487         test_log("Failed to parse RNGtest line %ld\n",
00488             xmlGetLineNo(test));
00489     nb_errors++;
00490         ret = 1;
00491     goto done;
00492     }
00493     /*
00494      * now scan all the siblings of correct to process the <valid> tests
00495      */
00496     tmp = getNext(cur, "following-sibling::valid[1]");
00497     while (tmp != NULL) {
00498     dtd = xmlGetProp(tmp, BAD_CAST "dtd");
00499     test = getNext(tmp, "./*");
00500     if (test == NULL) {
00501         fprintf(stderr, "Failed to find test in <valid> line %ld\n",
00502             xmlGetLineNo(tmp));
00503         
00504     } else {
00505         xmlBufferEmpty(buf);
00506         if (dtd != NULL)
00507         xmlBufferAdd(buf, dtd, -1);
00508         xmlNodeDump(buf, test->doc, test, 0, 0);
00509 
00510         /*
00511          * We are ready to run the test
00512          */
00513         mem = xmlMemUsed();
00514         extraMemoryFromResolver = 0;
00515             doc = xmlReadMemory((const char *)buf->content, buf->use,
00516                             "test", NULL, 0);
00517         if (doc == NULL) {
00518         test_log("Failed to parse valid instance line %ld\n",
00519             xmlGetLineNo(tmp));
00520         nb_errors++;
00521         } else {
00522         nb_tests++;
00523             ctxt = xmlRelaxNGNewValidCtxt(rng);
00524         xmlRelaxNGSetValidErrors(ctxt,
00525              (xmlRelaxNGValidityErrorFunc) testErrorHandler,
00526              (xmlRelaxNGValidityWarningFunc) testErrorHandler,
00527              ctxt);
00528         ret = xmlRelaxNGValidateDoc(ctxt, doc);
00529         xmlRelaxNGFreeValidCtxt(ctxt);
00530         if (ret > 0) {
00531             test_log("Failed to validate valid instance line %ld\n",
00532                 xmlGetLineNo(tmp));
00533             nb_errors++;
00534         } else if (ret < 0) {
00535             test_log("Internal error validating instance line %ld\n",
00536                 xmlGetLineNo(tmp));
00537             nb_errors++;
00538         }
00539         xmlFreeDoc(doc);
00540         }
00541         xmlResetLastError();
00542         if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
00543             test_log("Validation of instance line %ld leaked %d\n",
00544                 xmlGetLineNo(tmp), xmlMemUsed() - mem);
00545         xmlMemoryDump();
00546             nb_leaks++;
00547         }
00548     }
00549     if (dtd != NULL)
00550         xmlFree(dtd);
00551     tmp = getNext(tmp, "following-sibling::valid[1]");
00552     }
00553     /*
00554      * now scan all the siblings of correct to process the <invalid> tests
00555      */
00556     tmp = getNext(cur, "following-sibling::invalid[1]");
00557     while (tmp != NULL) {
00558     test = getNext(tmp, "./*");
00559     if (test == NULL) {
00560         fprintf(stderr, "Failed to find test in <invalid> line %ld\n",
00561             xmlGetLineNo(tmp));
00562         
00563     } else {
00564         xmlBufferEmpty(buf);
00565         xmlNodeDump(buf, test->doc, test, 0, 0);
00566 
00567         /*
00568          * We are ready to run the test
00569          */
00570         mem = xmlMemUsed();
00571         extraMemoryFromResolver = 0;
00572             doc = xmlReadMemory((const char *)buf->content, buf->use,
00573                             "test", NULL, 0);
00574         if (doc == NULL) {
00575         test_log("Failed to parse valid instance line %ld\n",
00576             xmlGetLineNo(tmp));
00577         nb_errors++;
00578         } else {
00579         nb_tests++;
00580             ctxt = xmlRelaxNGNewValidCtxt(rng);
00581         xmlRelaxNGSetValidErrors(ctxt,
00582              (xmlRelaxNGValidityErrorFunc) testErrorHandler,
00583              (xmlRelaxNGValidityWarningFunc) testErrorHandler,
00584              ctxt);
00585         ret = xmlRelaxNGValidateDoc(ctxt, doc);
00586         xmlRelaxNGFreeValidCtxt(ctxt);
00587         if (ret == 0) {
00588             test_log("Failed to detect invalid instance line %ld\n",
00589                 xmlGetLineNo(tmp));
00590             nb_errors++;
00591         } else if (ret < 0) {
00592             test_log("Internal error validating instance line %ld\n",
00593                 xmlGetLineNo(tmp));
00594             nb_errors++;
00595         }
00596         xmlFreeDoc(doc);
00597         }
00598         xmlResetLastError();
00599         if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
00600             test_log("Validation of instance line %ld leaked %d\n",
00601                 xmlGetLineNo(tmp), xmlMemUsed() - mem);
00602         xmlMemoryDump();
00603             nb_leaks++;
00604         }
00605     }
00606     tmp = getNext(tmp, "following-sibling::invalid[1]");
00607     }
00608 
00609 done:
00610     if (buf != NULL)
00611     xmlBufferFree(buf);
00612     if (rng != NULL)
00613         xmlRelaxNGFree(rng);
00614     xmlResetLastError();
00615     if ((memt != xmlMemUsed()) && (memt != 0)) {
00616     test_log("Validation of tests starting line %ld leaked %d\n",
00617         xmlGetLineNo(cur), xmlMemUsed() - memt);
00618     nb_leaks++;
00619     }
00620     return(ret);
00621 }
00622 
00623 static int 
00624 xsdTestSuite(xmlNodePtr cur) {
00625     if (verbose) {
00626     xmlChar *doc = getString(cur, "string(documentation)");
00627 
00628     if (doc != NULL) {
00629         printf("Suite %s\n", doc);
00630         xmlFree(doc);
00631     }
00632     }
00633     cur = getNext(cur, "./testCase[1]");
00634     while (cur != NULL) {
00635         xsdTestCase(cur);
00636     cur = getNext(cur, "following-sibling::testCase[1]");
00637     }
00638         
00639     return(0);
00640 }
00641 
00642 static int 
00643 xsdTest(void) {
00644     xmlDocPtr doc;
00645     xmlNodePtr cur;
00646     const char *filename = "test/xsdtest/xsdtestsuite.xml";
00647     int ret = 0;
00648 
00649     doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
00650     if (doc == NULL) {
00651         fprintf(stderr, "Failed to parse %s\n", filename);
00652     return(-1);
00653     }
00654     printf("## XML Schemas datatypes test suite from James Clark\n");
00655 
00656     cur = xmlDocGetRootElement(doc);
00657     if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
00658         fprintf(stderr, "Unexpected format %s\n", filename);
00659     ret = -1;
00660     goto done;
00661     }
00662 
00663     cur = getNext(cur, "./testSuite[1]");
00664     if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
00665         fprintf(stderr, "Unexpected format %s\n", filename);
00666     ret = -1;
00667     goto done;
00668     }
00669     while (cur != NULL) {
00670         xsdTestSuite(cur);
00671     cur = getNext(cur, "following-sibling::testSuite[1]");
00672     }
00673 
00674 done:
00675     if (doc != NULL)
00676     xmlFreeDoc(doc);
00677     return(ret);
00678 }
00679 
00680 static int 
00681 rngTestSuite(xmlNodePtr cur) {
00682     if (verbose) {
00683     xmlChar *doc = getString(cur, "string(documentation)");
00684 
00685     if (doc != NULL) {
00686         printf("Suite %s\n", doc);
00687         xmlFree(doc);
00688     } else {
00689         doc = getString(cur, "string(section)");
00690         if (doc != NULL) {
00691         printf("Section %s\n", doc);
00692         xmlFree(doc);
00693         }
00694     }
00695     }
00696     cur = getNext(cur, "./testSuite[1]");
00697     while (cur != NULL) {
00698         xsdTestSuite(cur);
00699     cur = getNext(cur, "following-sibling::testSuite[1]");
00700     }
00701         
00702     return(0);
00703 }
00704 
00705 static int 
00706 rngTest1(void) {
00707     xmlDocPtr doc;
00708     xmlNodePtr cur;
00709     const char *filename = "test/relaxng/OASIS/spectest.xml";
00710     int ret = 0;
00711 
00712     doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
00713     if (doc == NULL) {
00714         fprintf(stderr, "Failed to parse %s\n", filename);
00715     return(-1);
00716     }
00717     printf("## Relax NG test suite from James Clark\n");
00718 
00719     cur = xmlDocGetRootElement(doc);
00720     if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
00721         fprintf(stderr, "Unexpected format %s\n", filename);
00722     ret = -1;
00723     goto done;
00724     }
00725 
00726     cur = getNext(cur, "./testSuite[1]");
00727     if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
00728         fprintf(stderr, "Unexpected format %s\n", filename);
00729     ret = -1;
00730     goto done;
00731     }
00732     while (cur != NULL) {
00733         rngTestSuite(cur);
00734     cur = getNext(cur, "following-sibling::testSuite[1]");
00735     }
00736 
00737 done:
00738     if (doc != NULL)
00739     xmlFreeDoc(doc);
00740     return(ret);
00741 }
00742 
00743 static int 
00744 rngTest2(void) {
00745     xmlDocPtr doc;
00746     xmlNodePtr cur;
00747     const char *filename = "test/relaxng/testsuite.xml";
00748     int ret = 0;
00749 
00750     doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
00751     if (doc == NULL) {
00752         fprintf(stderr, "Failed to parse %s\n", filename);
00753     return(-1);
00754     }
00755     printf("## Relax NG test suite for libxml2\n");
00756 
00757     cur = xmlDocGetRootElement(doc);
00758     if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
00759         fprintf(stderr, "Unexpected format %s\n", filename);
00760     ret = -1;
00761     goto done;
00762     }
00763 
00764     cur = getNext(cur, "./testSuite[1]");
00765     if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
00766         fprintf(stderr, "Unexpected format %s\n", filename);
00767     ret = -1;
00768     goto done;
00769     }
00770     while (cur != NULL) {
00771         xsdTestSuite(cur);
00772     cur = getNext(cur, "following-sibling::testSuite[1]");
00773     }
00774 
00775 done:
00776     if (doc != NULL)
00777     xmlFreeDoc(doc);
00778     return(ret);
00779 }
00780 
00781 /************************************************************************
00782  *                                  *
00783  *      Schemas test suites from W3C/NIST/MS/Sun        *
00784  *                                  *
00785  ************************************************************************/
00786 
00787 static int
00788 xstcTestInstance(xmlNodePtr cur, xmlSchemaPtr schemas,
00789                  const xmlChar *spath, const char *base) {
00790     xmlChar *href = NULL;
00791     xmlChar *path = NULL;
00792     xmlChar *validity = NULL;
00793     xmlSchemaValidCtxtPtr ctxt = NULL;
00794     xmlDocPtr doc = NULL;
00795     int ret = 0, mem;
00796 
00797     xmlResetLastError();
00798     testErrorsSize = 0; testErrors[0] = 0;
00799     mem = xmlMemUsed();
00800     href = getString(cur,
00801                      "string(ts:instanceDocument/@xlink:href)");
00802     if ((href == NULL) || (href[0] == 0)) {
00803     test_log("testGroup line %ld misses href for schemaDocument\n",
00804             xmlGetLineNo(cur));
00805     ret = -1;
00806     goto done;
00807     }
00808     path = xmlBuildURI(href, BAD_CAST base);
00809     if (path == NULL) {
00810     fprintf(stderr,
00811             "Failed to build path to schemas testGroup line %ld : %s\n",
00812         xmlGetLineNo(cur), href);
00813     ret = -1;
00814     goto done;
00815     }
00816     if (checkTestFile((const char *) path) <= 0) {
00817     test_log("schemas for testGroup line %ld is missing: %s\n",
00818         xmlGetLineNo(cur), path);
00819     ret = -1;
00820     goto done;
00821     }
00822     validity = getString(cur,
00823                          "string(ts:expected/@validity)");
00824     if (validity == NULL) {
00825         fprintf(stderr, "instanceDocument line %ld misses expected validity\n",
00826             xmlGetLineNo(cur));
00827     ret = -1;
00828     goto done;
00829     }
00830     nb_tests++;
00831     doc = xmlReadFile((const char *) path, NULL, XML_PARSE_NOENT);
00832     if (doc == NULL) {
00833         fprintf(stderr, "instance %s fails to parse\n", path);
00834     ret = -1;
00835     nb_errors++;
00836     goto done;
00837     }
00838 
00839     ctxt = xmlSchemaNewValidCtxt(schemas);
00840     xmlSchemaSetValidErrors(ctxt,
00841          (xmlSchemaValidityErrorFunc) testErrorHandler,
00842          (xmlSchemaValidityWarningFunc) testErrorHandler,
00843      ctxt);
00844     ret = xmlSchemaValidateDoc(ctxt, doc);
00845 
00846     if (xmlStrEqual(validity, BAD_CAST "valid")) {
00847     if (ret > 0) {
00848         test_log("valid instance %s failed to validate against %s\n",
00849             path, spath);
00850         nb_errors++;
00851     } else if (ret < 0) {
00852         test_log("valid instance %s got internal error validating %s\n",
00853             path, spath);
00854         nb_internals++;
00855         nb_errors++;
00856     }
00857     } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
00858     if (ret == 0) {
00859         test_log("Failed to detect invalid instance %s against %s\n",
00860             path, spath);
00861         nb_errors++;
00862     }
00863     } else {
00864         test_log("instanceDocument line %ld has unexpected validity value%s\n",
00865             xmlGetLineNo(cur), validity);
00866     ret = -1;
00867     goto done;
00868     }
00869 
00870 done:
00871     if (href != NULL) xmlFree(href);
00872     if (path != NULL) xmlFree(path);
00873     if (validity != NULL) xmlFree(validity);
00874     if (ctxt != NULL) xmlSchemaFreeValidCtxt(ctxt);
00875     if (doc != NULL) xmlFreeDoc(doc);
00876     xmlResetLastError();
00877     if (mem != xmlMemUsed()) {
00878     test_log("Validation of tests starting line %ld leaked %d\n",
00879         xmlGetLineNo(cur), xmlMemUsed() - mem);
00880     nb_leaks++;
00881     }
00882     return(ret);
00883 }
00884 
00885 static int
00886 xstcTestGroup(xmlNodePtr cur, const char *base) {
00887     xmlChar *href = NULL;
00888     xmlChar *path = NULL;
00889     xmlChar *validity = NULL;
00890     xmlSchemaPtr schemas = NULL;
00891     xmlSchemaParserCtxtPtr ctxt;
00892     xmlNodePtr instance;
00893     int ret = 0, mem;
00894 
00895     xmlResetLastError();
00896     testErrorsSize = 0; testErrors[0] = 0;
00897     mem = xmlMemUsed();
00898     href = getString(cur,
00899                      "string(ts:schemaTest/ts:schemaDocument/@xlink:href)");
00900     if ((href == NULL) || (href[0] == 0)) {
00901         test_log("testGroup line %ld misses href for schemaDocument\n",
00902             xmlGetLineNo(cur));
00903     ret = -1;
00904     goto done;
00905     }
00906     path = xmlBuildURI(href, BAD_CAST base);
00907     if (path == NULL) {
00908     test_log("Failed to build path to schemas testGroup line %ld : %s\n",
00909         xmlGetLineNo(cur), href);
00910     ret = -1;
00911     goto done;
00912     }
00913     if (checkTestFile((const char *) path) <= 0) {
00914     test_log("schemas for testGroup line %ld is missing: %s\n",
00915         xmlGetLineNo(cur), path);
00916     ret = -1;
00917     goto done;
00918     }
00919     validity = getString(cur,
00920                          "string(ts:schemaTest/ts:expected/@validity)");
00921     if (validity == NULL) {
00922         test_log("testGroup line %ld misses expected validity\n",
00923             xmlGetLineNo(cur));
00924     ret = -1;
00925     goto done;
00926     }
00927     nb_tests++;
00928     if (xmlStrEqual(validity, BAD_CAST "valid")) {
00929         nb_schematas++;
00930     ctxt = xmlSchemaNewParserCtxt((const char *) path);
00931     xmlSchemaSetParserErrors(ctxt,
00932          (xmlSchemaValidityErrorFunc) testErrorHandler,
00933          (xmlSchemaValidityWarningFunc) testErrorHandler,
00934          ctxt);
00935     schemas = xmlSchemaParse(ctxt);
00936     xmlSchemaFreeParserCtxt(ctxt);
00937     if (schemas == NULL) {
00938         test_log("valid schemas %s failed to parse\n",
00939             path);
00940         ret = 1;
00941         nb_errors++;
00942     }
00943     if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
00944         test_log("valid schemas %s hit an unimplemented block\n",
00945             path);
00946         ret = 1;
00947         nb_unimplemented++;
00948         nb_errors++;
00949     }
00950     instance = getNext(cur, "./ts:instanceTest[1]");
00951     while (instance != NULL) {
00952         if (schemas != NULL) {
00953         xstcTestInstance(instance, schemas, path, base);        
00954         } else {
00955         /*
00956         * We'll automatically mark the instances as failed
00957         * if the schema was broken.
00958         */
00959         nb_errors++;
00960         }
00961         instance = getNext(instance,
00962         "following-sibling::ts:instanceTest[1]");
00963     }
00964     } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
00965         nb_schematas++;
00966     ctxt = xmlSchemaNewParserCtxt((const char *) path);
00967     xmlSchemaSetParserErrors(ctxt,
00968          (xmlSchemaValidityErrorFunc) testErrorHandler,
00969          (xmlSchemaValidityWarningFunc) testErrorHandler,
00970          ctxt);
00971     schemas = xmlSchemaParse(ctxt);
00972     xmlSchemaFreeParserCtxt(ctxt);
00973     if (schemas != NULL) {
00974         test_log("Failed to detect error in schemas %s\n",
00975             path);
00976         nb_errors++;
00977         ret = 1;
00978     }
00979     if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
00980         nb_unimplemented++;
00981         test_log("invalid schemas %s hit an unimplemented block\n",
00982             path);
00983         ret = 1;
00984         nb_errors++;
00985     }
00986     } else {
00987         test_log("testGroup line %ld misses unexpected validity value%s\n",
00988             xmlGetLineNo(cur), validity);
00989     ret = -1;
00990     goto done;
00991     }
00992 
00993 done:
00994     if (href != NULL) xmlFree(href);
00995     if (path != NULL) xmlFree(path);
00996     if (validity != NULL) xmlFree(validity);
00997     if (schemas != NULL) xmlSchemaFree(schemas);
00998     xmlResetLastError();
00999     if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
01000     test_log("Processing test line %ld %s leaked %d\n",
01001         xmlGetLineNo(cur), path, xmlMemUsed() - mem);
01002     nb_leaks++;
01003     }
01004     return(ret);
01005 }
01006 
01007 static int
01008 xstcMetadata(const char *metadata, const char *base) {
01009     xmlDocPtr doc;
01010     xmlNodePtr cur;
01011     xmlChar *contributor;
01012     xmlChar *name;
01013     int ret = 0;
01014 
01015     doc = xmlReadFile(metadata, NULL, XML_PARSE_NOENT);
01016     if (doc == NULL) {
01017         fprintf(stderr, "Failed to parse %s\n", metadata);
01018     return(-1);
01019     }
01020 
01021     cur = xmlDocGetRootElement(doc);
01022     if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSet"))) {
01023         fprintf(stderr, "Unexpected format %s\n", metadata);
01024     return(-1);
01025     }
01026     contributor = xmlGetProp(cur, BAD_CAST "contributor");
01027     if (contributor == NULL) {
01028         contributor = xmlStrdup(BAD_CAST "Unknown");
01029     }
01030     name = xmlGetProp(cur, BAD_CAST "name");
01031     if (name == NULL) {
01032         name = xmlStrdup(BAD_CAST "Unknown");
01033     }
01034     printf("## %s test suite for Schemas version %s\n", contributor, name);
01035     xmlFree(contributor);
01036     xmlFree(name);
01037 
01038     cur = getNext(cur, "./ts:testGroup[1]");
01039     if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testGroup"))) {
01040         fprintf(stderr, "Unexpected format %s\n", metadata);
01041     ret = -1;
01042     goto done;
01043     }
01044     while (cur != NULL) {
01045         xstcTestGroup(cur, base);
01046     cur = getNext(cur, "following-sibling::ts:testGroup[1]");
01047     }
01048 
01049 done:
01050     xmlFreeDoc(doc);
01051     return(ret);
01052 }
01053 
01054 /************************************************************************
01055  *                                  *
01056  *      The driver for the tests                *
01057  *                                  *
01058  ************************************************************************/
01059 
01060 int
01061 main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
01062     int ret = 0;
01063     int old_errors, old_tests, old_leaks;
01064 
01065     logfile = fopen(LOGFILE, "w");
01066     if (logfile == NULL) {
01067         fprintf(stderr,
01068             "Could not open the log file, running in verbose mode\n");
01069     verbose = 1;
01070     }
01071     initializeLibxml2();
01072 
01073     if ((argc >= 2) && (!strcmp(argv[1], "-v")))
01074         verbose = 1;
01075 
01076 
01077     old_errors = nb_errors;
01078     old_tests = nb_tests;
01079     old_leaks = nb_leaks;
01080     xsdTest();
01081     if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
01082     printf("Ran %d tests, no errors\n", nb_tests - old_tests);
01083     else
01084     printf("Ran %d tests, %d errors, %d leaks\n",
01085            nb_tests - old_tests,
01086            nb_errors - old_errors,
01087            nb_leaks - old_leaks);
01088     old_errors = nb_errors;
01089     old_tests = nb_tests;
01090     old_leaks = nb_leaks;
01091     rngTest1();
01092     if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
01093     printf("Ran %d tests, no errors\n", nb_tests - old_tests);
01094     else
01095     printf("Ran %d tests, %d errors, %d leaks\n",
01096            nb_tests - old_tests,
01097            nb_errors - old_errors,
01098            nb_leaks - old_leaks);
01099     old_errors = nb_errors;
01100     old_tests = nb_tests;
01101     old_leaks = nb_leaks;
01102     rngTest2();
01103     if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
01104     printf("Ran %d tests, no errors\n", nb_tests - old_tests);
01105     else
01106     printf("Ran %d tests, %d errors, %d leaks\n",
01107            nb_tests - old_tests,
01108            nb_errors - old_errors,
01109            nb_leaks - old_leaks);
01110     old_errors = nb_errors;
01111     old_tests = nb_tests;
01112     old_leaks = nb_leaks;
01113     nb_internals = 0;
01114     nb_schematas = 0;
01115     xstcMetadata("xstc/Tests/Metadata/NISTXMLSchemaDatatypes.testSet",
01116          "xstc/Tests/Metadata/");
01117     if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
01118     printf("Ran %d tests (%d schemata), no errors\n",
01119            nb_tests - old_tests, nb_schematas);
01120     else
01121     printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
01122            nb_tests - old_tests,
01123            nb_schematas,
01124            nb_errors - old_errors,
01125            nb_internals,
01126            nb_leaks - old_leaks);
01127     old_errors = nb_errors;
01128     old_tests = nb_tests;
01129     old_leaks = nb_leaks;
01130     nb_internals = 0;
01131     nb_schematas = 0;
01132     xstcMetadata("xstc/Tests/Metadata/SunXMLSchema1-0-20020116.testSet",
01133          "xstc/Tests/");
01134     if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
01135     printf("Ran %d tests (%d schemata), no errors\n",
01136            nb_tests - old_tests, nb_schematas);
01137     else
01138     printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
01139            nb_tests - old_tests,
01140            nb_schematas,
01141            nb_errors - old_errors,
01142            nb_internals,
01143            nb_leaks - old_leaks);
01144     old_errors = nb_errors;
01145     old_tests = nb_tests;
01146     old_leaks = nb_leaks;
01147     nb_internals = 0;
01148     nb_schematas = 0;
01149     xstcMetadata("xstc/Tests/Metadata/MSXMLSchema1-0-20020116.testSet",
01150          "xstc/Tests/");
01151     if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
01152     printf("Ran %d tests (%d schemata), no errors\n",
01153            nb_tests - old_tests, nb_schematas);
01154     else
01155     printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
01156            nb_tests - old_tests,
01157            nb_schematas,
01158            nb_errors - old_errors,
01159            nb_internals,
01160            nb_leaks - old_leaks);
01161 
01162     if ((nb_errors == 0) && (nb_leaks == 0)) {
01163         ret = 0;
01164     printf("Total %d tests, no errors\n",
01165            nb_tests);
01166     } else {
01167         ret = 1;
01168     printf("Total %d tests, %d errors, %d leaks\n",
01169            nb_tests, nb_errors, nb_leaks);
01170     }
01171     xmlXPathFreeContext(ctxtXPath);
01172     xmlCleanupParser();
01173     xmlMemoryDump();
01174 
01175     if (logfile != NULL)
01176         fclose(logfile);
01177     return(ret);
01178 }
01179 #else /* !SCHEMAS */
01180 int
01181 main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
01182     fprintf(stderr, "runsuite requires support for schemas and xpath in libxml2\n");
01183 }
01184 #endif

Generated on Sat May 26 2012 04:33:22 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.