2 * runsuite.c: C program to run libxml2 againts published testsuites
4 * See Copyright for the status of this software.
15 #if !defined(_WIN32) || defined(__CYGWIN__)
19 #include <sys/types.h>
23 #include <libxml/parser.h>
24 #include <libxml/parserInternals.h>
25 #include <libxml/tree.h>
26 #include <libxml/uri.h>
27 #if defined(LIBXML_SCHEMAS_ENABLED) && defined(LIBXML_XPATH_ENABLED)
28 #include <libxml/xmlreader.h>
30 #include <libxml/xpath.h>
31 #include <libxml/xpathInternals.h>
33 #include <libxml/relaxng.h>
34 #include <libxml/xmlschemas.h>
35 #include <libxml/xmlschemastypes.h>
37 #define LOGFILE "runsuite.log"
38 static FILE *logfile = NULL;
39 static int verbose = 0;
41 #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
42 #define vsnprintf _vsnprintf
43 #define snprintf _snprintf
46 /************************************************************************
48 * File name and path utilities *
50 ************************************************************************/
52 static int checkTestFile(const char *filename) {
55 if (stat(filename, &buf) == -1)
58 #if defined(_WIN32) && !defined(__CYGWIN__)
59 if (!(buf.st_mode & _S_IFREG))
62 if (!S_ISREG(buf.st_mode))
69 static xmlChar *composeDir(const xmlChar *dir, const xmlChar *path) {
72 if (dir == NULL) return(xmlStrdup(path));
73 if (path == NULL) return(NULL);
75 snprintf(buf, 500, "%s/%s", (const char *) dir, (const char *) path);
76 return(xmlStrdup((const xmlChar *) buf));
79 /************************************************************************
81 * Libxml2 specific routines *
83 ************************************************************************/
85 static int nb_tests = 0;
86 static int nb_errors = 0;
87 static int nb_internals = 0;
88 static int nb_schematas = 0;
89 static int nb_unimplemented = 0;
90 static int nb_leaks = 0;
91 static int extraMemoryFromResolver = 0;
95 fprintf(stderr, "Exitting tests on fatal error\n");
100 * that's needed to implement <resource>
102 #define MAX_ENTITIES 20
103 static char *testEntitiesName[MAX_ENTITIES];
104 static char *testEntitiesValue[MAX_ENTITIES];
105 static int nb_entities = 0;
106 static void resetEntities(void) {
109 for (i = 0;i < nb_entities;i++) {
110 if (testEntitiesName[i] != NULL)
111 xmlFree(testEntitiesName[i]);
112 if (testEntitiesValue[i] != NULL)
113 xmlFree(testEntitiesValue[i]);
117 static int addEntity(char *name, char *content) {
118 if (nb_entities >= MAX_ENTITIES) {
119 fprintf(stderr, "Too many entities defined\n");
122 testEntitiesName[nb_entities] = name;
123 testEntitiesValue[nb_entities] = content;
129 * We need to trap calls to the resolver to not account memory for the catalog
130 * which is shared to the current running test. We also don't want to have
131 * network downloads modifying tests.
133 static xmlParserInputPtr
134 testExternalEntityLoader(const char *URL, const char *ID,
135 xmlParserCtxtPtr ctxt) {
136 xmlParserInputPtr ret;
139 for (i = 0;i < nb_entities;i++) {
140 if (!strcmp(testEntitiesName[i], URL)) {
141 ret = xmlNewStringInputStream(ctxt,
142 (const xmlChar *) testEntitiesValue[i]);
144 ret->filename = (const char *)
145 xmlStrdup((xmlChar *)testEntitiesName[i]);
150 if (checkTestFile(URL)) {
151 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
153 int memused = xmlMemUsed();
154 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
155 extraMemoryFromResolver += xmlMemUsed() - memused;
159 fprintf(stderr, "Failed to find resource %s\n", URL);
167 * Trapping the error messages at the generic level to grab the equivalent of
168 * stderr messages on CLI tools.
170 static char testErrors[32769];
171 static int testErrorsSize = 0;
173 static void test_log(const char *msg, ...) {
175 if (logfile != NULL) {
176 fprintf(logfile, "\n------------\n");
178 vfprintf(logfile, msg, args);
180 fprintf(logfile, "%s", testErrors);
181 testErrorsSize = 0; testErrors[0] = 0;
185 vfprintf(stderr, msg, args);
191 testErrorHandler(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
195 if (testErrorsSize >= 32768)
198 res = vsnprintf(&testErrors[testErrorsSize],
199 32768 - testErrorsSize,
202 if (testErrorsSize + res >= 32768) {
204 testErrorsSize = 32768;
205 testErrors[testErrorsSize] = 0;
207 testErrorsSize += res;
209 testErrors[testErrorsSize] = 0;
212 static xmlXPathContextPtr ctxtXPath;
215 initializeLibxml2(void) {
216 xmlGetWarningsDefaultValue = 0;
217 xmlPedanticParserDefault(0);
219 xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
221 xmlSetExternalEntityLoader(testExternalEntityLoader);
222 ctxtXPath = xmlXPathNewContext(NULL);
224 * Deactivate the cache if created; otherwise we have to create/free it
225 * for every test, since it will confuse the memory leak detection.
226 * Note that normally this need not be done, since the cache is not
227 * created until set explicitely with xmlXPathContextSetCache();
228 * but for test purposes it is sometimes usefull to activate the
229 * cache by default for the whole library.
231 if (ctxtXPath->cache != NULL)
232 xmlXPathContextSetCache(ctxtXPath, 0, -1, 0);
233 /* used as default nanemspace in xstc tests */
234 xmlXPathRegisterNs(ctxtXPath, BAD_CAST "ts", BAD_CAST "TestSuite");
235 xmlXPathRegisterNs(ctxtXPath, BAD_CAST "xlink",
236 BAD_CAST "http://www.w3.org/1999/xlink");
237 xmlSetGenericErrorFunc(NULL, testErrorHandler);
238 #ifdef LIBXML_SCHEMAS_ENABLED
239 xmlSchemaInitTypes();
240 xmlRelaxNGInitTypes();
245 getNext(xmlNodePtr cur, const char *xpath) {
246 xmlNodePtr ret = NULL;
247 xmlXPathObjectPtr res;
248 xmlXPathCompExprPtr comp;
250 if ((cur == NULL) || (cur->doc == NULL) || (xpath == NULL))
252 ctxtXPath->doc = cur->doc;
253 ctxtXPath->node = cur;
254 comp = xmlXPathCompile(BAD_CAST xpath);
256 fprintf(stderr, "Failed to compile %s\n", xpath);
259 res = xmlXPathCompiledEval(comp, ctxtXPath);
260 xmlXPathFreeCompExpr(comp);
263 if ((res->type == XPATH_NODESET) &&
264 (res->nodesetval != NULL) &&
265 (res->nodesetval->nodeNr > 0) &&
266 (res->nodesetval->nodeTab != NULL))
267 ret = res->nodesetval->nodeTab[0];
268 xmlXPathFreeObject(res);
273 getString(xmlNodePtr cur, const char *xpath) {
275 xmlXPathObjectPtr res;
276 xmlXPathCompExprPtr comp;
278 if ((cur == NULL) || (cur->doc == NULL) || (xpath == NULL))
280 ctxtXPath->doc = cur->doc;
281 ctxtXPath->node = cur;
282 comp = xmlXPathCompile(BAD_CAST xpath);
284 fprintf(stderr, "Failed to compile %s\n", xpath);
287 res = xmlXPathCompiledEval(comp, ctxtXPath);
288 xmlXPathFreeCompExpr(comp);
291 if (res->type == XPATH_STRING) {
292 ret = res->stringval;
293 res->stringval = NULL;
295 xmlXPathFreeObject(res);
299 /************************************************************************
301 * Test test/xsdtest/xsdtestsuite.xml *
303 ************************************************************************/
306 xsdIncorectTestCase(xmlNodePtr cur) {
309 xmlRelaxNGParserCtxtPtr pctxt;
310 xmlRelaxNGPtr rng = NULL;
313 cur = getNext(cur, "./incorrect[1]");
318 test = getNext(cur, "./*");
320 test_log("Failed to find test in correct line %ld\n",
326 extraMemoryFromResolver = 0;
328 * dump the schemas to a buffer, then reparse it and compile the schemas
330 buf = xmlBufferCreate();
332 fprintf(stderr, "out of memory !\n");
335 xmlNodeDump(buf, test->doc, test, 0, 0);
336 pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
337 xmlRelaxNGSetParserErrors(pctxt,
338 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
339 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
341 rng = xmlRelaxNGParse(pctxt);
342 xmlRelaxNGFreeParserCtxt(pctxt);
344 test_log("Failed to detect incorect RNG line %ld\n",
356 if ((memt < xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
357 test_log("Validation of tests starting line %ld leaked %d\n",
358 xmlGetLineNo(cur), xmlMemUsed() - memt);
365 installResources(xmlNodePtr tst, const xmlChar *base) {
368 xmlChar *name, *content, *res;
370 buf = xmlBufferCreate();
372 fprintf(stderr, "out of memory !\n");
375 xmlNodeDump(buf, tst->doc, tst, 0, 0);
377 while (tst != NULL) {
378 test = getNext(tst, "./*");
381 xmlNodeDump(buf, test->doc, test, 0, 0);
382 name = getString(tst, "string(@name)");
383 content = xmlStrdup(buf->content);
384 if ((name != NULL) && (content != NULL)) {
385 res = composeDir(base, name);
387 addEntity((char *) res, (char *) content);
389 if (name != NULL) xmlFree(name);
390 if (content != NULL) xmlFree(content);
393 tst = getNext(tst, "following-sibling::resource[1]");
400 installDirs(xmlNodePtr tst, const xmlChar *base) {
404 name = getString(tst, "string(@name)");
407 res = composeDir(base, name);
412 /* Now process resources and subdir recursively */
413 test = getNext(tst, "./resource[1]");
415 installResources(test, res);
417 test = getNext(tst, "./dir[1]");
418 while (test != NULL) {
419 installDirs(test, res);
420 test = getNext(test, "following-sibling::dir[1]");
426 xsdTestCase(xmlNodePtr tst) {
427 xmlNodePtr test, tmp, cur;
429 xmlDocPtr doc = NULL;
430 xmlRelaxNGParserCtxtPtr pctxt;
431 xmlRelaxNGValidCtxtPtr ctxt;
432 xmlRelaxNGPtr rng = NULL;
433 int ret = 0, mem, memt;
437 testErrorsSize = 0; testErrors[0] = 0;
439 tmp = getNext(tst, "./dir[1]");
441 installDirs(tmp, NULL);
443 tmp = getNext(tst, "./resource[1]");
445 installResources(tmp, NULL);
448 cur = getNext(tst, "./correct[1]");
450 return(xsdIncorectTestCase(tst));
453 test = getNext(cur, "./*");
455 fprintf(stderr, "Failed to find test in correct line %ld\n",
461 extraMemoryFromResolver = 0;
463 * dump the schemas to a buffer, then reparse it and compile the schemas
465 buf = xmlBufferCreate();
467 fprintf(stderr, "out of memory !\n");
470 xmlNodeDump(buf, test->doc, test, 0, 0);
471 pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
472 xmlRelaxNGSetParserErrors(pctxt,
473 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
474 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
476 rng = xmlRelaxNGParse(pctxt);
477 xmlRelaxNGFreeParserCtxt(pctxt);
478 if (extraMemoryFromResolver)
482 test_log("Failed to parse RNGtest line %ld\n",
489 * now scan all the siblings of correct to process the <valid> tests
491 tmp = getNext(cur, "following-sibling::valid[1]");
492 while (tmp != NULL) {
493 dtd = xmlGetProp(tmp, BAD_CAST "dtd");
494 test = getNext(tmp, "./*");
496 fprintf(stderr, "Failed to find test in <valid> line %ld\n",
502 xmlBufferAdd(buf, dtd, -1);
503 xmlNodeDump(buf, test->doc, test, 0, 0);
506 * We are ready to run the test
509 extraMemoryFromResolver = 0;
510 doc = xmlReadMemory((const char *)buf->content, buf->use,
513 test_log("Failed to parse valid instance line %ld\n",
518 ctxt = xmlRelaxNGNewValidCtxt(rng);
519 xmlRelaxNGSetValidErrors(ctxt,
520 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
521 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
523 ret = xmlRelaxNGValidateDoc(ctxt, doc);
524 xmlRelaxNGFreeValidCtxt(ctxt);
526 test_log("Failed to validate valid instance line %ld\n",
529 } else if (ret < 0) {
530 test_log("Internal error validating instance line %ld\n",
537 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
538 test_log("Validation of instance line %ld leaked %d\n",
539 xmlGetLineNo(tmp), xmlMemUsed() - mem);
546 tmp = getNext(tmp, "following-sibling::valid[1]");
549 * now scan all the siblings of correct to process the <invalid> tests
551 tmp = getNext(cur, "following-sibling::invalid[1]");
552 while (tmp != NULL) {
553 test = getNext(tmp, "./*");
555 fprintf(stderr, "Failed to find test in <invalid> line %ld\n",
560 xmlNodeDump(buf, test->doc, test, 0, 0);
563 * We are ready to run the test
566 extraMemoryFromResolver = 0;
567 doc = xmlReadMemory((const char *)buf->content, buf->use,
570 test_log("Failed to parse valid instance line %ld\n",
575 ctxt = xmlRelaxNGNewValidCtxt(rng);
576 xmlRelaxNGSetValidErrors(ctxt,
577 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
578 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
580 ret = xmlRelaxNGValidateDoc(ctxt, doc);
581 xmlRelaxNGFreeValidCtxt(ctxt);
583 test_log("Failed to detect invalid instance line %ld\n",
586 } else if (ret < 0) {
587 test_log("Internal error validating instance line %ld\n",
594 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
595 test_log("Validation of instance line %ld leaked %d\n",
596 xmlGetLineNo(tmp), xmlMemUsed() - mem);
601 tmp = getNext(tmp, "following-sibling::invalid[1]");
610 if ((memt != xmlMemUsed()) && (memt != 0)) {
611 test_log("Validation of tests starting line %ld leaked %d\n",
612 xmlGetLineNo(cur), xmlMemUsed() - memt);
619 xsdTestSuite(xmlNodePtr cur) {
621 xmlChar *doc = getString(cur, "string(documentation)");
624 printf("Suite %s\n", doc);
628 cur = getNext(cur, "./testCase[1]");
629 while (cur != NULL) {
631 cur = getNext(cur, "following-sibling::testCase[1]");
641 const char *filename = "test/xsdtest/xsdtestsuite.xml";
644 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
646 fprintf(stderr, "Failed to parse %s\n", filename);
649 printf("## XML Schemas datatypes test suite from James Clark\n");
651 cur = xmlDocGetRootElement(doc);
652 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
653 fprintf(stderr, "Unexpected format %s\n", filename);
658 cur = getNext(cur, "./testSuite[1]");
659 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
660 fprintf(stderr, "Unexpected format %s\n", filename);
664 while (cur != NULL) {
666 cur = getNext(cur, "following-sibling::testSuite[1]");
676 rngTestSuite(xmlNodePtr cur) {
678 xmlChar *doc = getString(cur, "string(documentation)");
681 printf("Suite %s\n", doc);
684 doc = getString(cur, "string(section)");
686 printf("Section %s\n", doc);
691 cur = getNext(cur, "./testSuite[1]");
692 while (cur != NULL) {
694 cur = getNext(cur, "following-sibling::testSuite[1]");
704 const char *filename = "test/relaxng/OASIS/spectest.xml";
707 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
709 fprintf(stderr, "Failed to parse %s\n", filename);
712 printf("## Relax NG test suite from James Clark\n");
714 cur = xmlDocGetRootElement(doc);
715 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
716 fprintf(stderr, "Unexpected format %s\n", filename);
721 cur = getNext(cur, "./testSuite[1]");
722 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
723 fprintf(stderr, "Unexpected format %s\n", filename);
727 while (cur != NULL) {
729 cur = getNext(cur, "following-sibling::testSuite[1]");
742 const char *filename = "test/relaxng/testsuite.xml";
745 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
747 fprintf(stderr, "Failed to parse %s\n", filename);
750 printf("## Relax NG test suite for libxml2\n");
752 cur = xmlDocGetRootElement(doc);
753 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
754 fprintf(stderr, "Unexpected format %s\n", filename);
759 cur = getNext(cur, "./testSuite[1]");
760 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
761 fprintf(stderr, "Unexpected format %s\n", filename);
765 while (cur != NULL) {
767 cur = getNext(cur, "following-sibling::testSuite[1]");
776 /************************************************************************
778 * Schemas test suites from W3C/NIST/MS/Sun *
780 ************************************************************************/
783 xstcTestInstance(xmlNodePtr cur, xmlSchemaPtr schemas,
784 const xmlChar *spath, const char *base) {
785 xmlChar *href = NULL;
786 xmlChar *path = NULL;
787 xmlChar *validity = NULL;
788 xmlSchemaValidCtxtPtr ctxt = NULL;
789 xmlDocPtr doc = NULL;
793 testErrorsSize = 0; testErrors[0] = 0;
795 href = getString(cur,
796 "string(ts:instanceDocument/@xlink:href)");
797 if ((href == NULL) || (href[0] == 0)) {
798 test_log("testGroup line %ld misses href for schemaDocument\n",
803 path = xmlBuildURI(href, BAD_CAST base);
806 "Failed to build path to schemas testGroup line %ld : %s\n",
807 xmlGetLineNo(cur), href);
811 if (checkTestFile((const char *) path) <= 0) {
812 test_log("schemas for testGroup line %ld is missing: %s\n",
813 xmlGetLineNo(cur), path);
817 validity = getString(cur,
818 "string(ts:expected/@validity)");
819 if (validity == NULL) {
820 fprintf(stderr, "instanceDocument line %ld misses expected validity\n",
826 doc = xmlReadFile((const char *) path, NULL, XML_PARSE_NOENT);
828 fprintf(stderr, "instance %s fails to parse\n", path);
834 ctxt = xmlSchemaNewValidCtxt(schemas);
835 xmlSchemaSetValidErrors(ctxt,
836 (xmlSchemaValidityErrorFunc) testErrorHandler,
837 (xmlSchemaValidityWarningFunc) testErrorHandler,
839 ret = xmlSchemaValidateDoc(ctxt, doc);
841 if (xmlStrEqual(validity, BAD_CAST "valid")) {
843 test_log("valid instance %s failed to validate against %s\n",
846 } else if (ret < 0) {
847 test_log("valid instance %s got internal error validating %s\n",
852 } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
854 test_log("Failed to detect invalid instance %s against %s\n",
859 test_log("instanceDocument line %ld has unexpected validity value%s\n",
860 xmlGetLineNo(cur), validity);
866 if (href != NULL) xmlFree(href);
867 if (path != NULL) xmlFree(path);
868 if (validity != NULL) xmlFree(validity);
869 if (ctxt != NULL) xmlSchemaFreeValidCtxt(ctxt);
870 if (doc != NULL) xmlFreeDoc(doc);
872 if (mem != xmlMemUsed()) {
873 test_log("Validation of tests starting line %ld leaked %d\n",
874 xmlGetLineNo(cur), xmlMemUsed() - mem);
881 xstcTestGroup(xmlNodePtr cur, const char *base) {
882 xmlChar *href = NULL;
883 xmlChar *path = NULL;
884 xmlChar *validity = NULL;
885 xmlSchemaPtr schemas = NULL;
886 xmlSchemaParserCtxtPtr ctxt;
891 testErrorsSize = 0; testErrors[0] = 0;
893 href = getString(cur,
894 "string(ts:schemaTest/ts:schemaDocument/@xlink:href)");
895 if ((href == NULL) || (href[0] == 0)) {
896 test_log("testGroup line %ld misses href for schemaDocument\n",
901 path = xmlBuildURI(href, BAD_CAST base);
903 test_log("Failed to build path to schemas testGroup line %ld : %s\n",
904 xmlGetLineNo(cur), href);
908 if (checkTestFile((const char *) path) <= 0) {
909 test_log("schemas for testGroup line %ld is missing: %s\n",
910 xmlGetLineNo(cur), path);
914 validity = getString(cur,
915 "string(ts:schemaTest/ts:expected/@validity)");
916 if (validity == NULL) {
917 test_log("testGroup line %ld misses expected validity\n",
923 if (xmlStrEqual(validity, BAD_CAST "valid")) {
925 ctxt = xmlSchemaNewParserCtxt((const char *) path);
926 xmlSchemaSetParserErrors(ctxt,
927 (xmlSchemaValidityErrorFunc) testErrorHandler,
928 (xmlSchemaValidityWarningFunc) testErrorHandler,
930 schemas = xmlSchemaParse(ctxt);
931 xmlSchemaFreeParserCtxt(ctxt);
932 if (schemas == NULL) {
933 test_log("valid schemas %s failed to parse\n",
938 if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
939 test_log("valid schemas %s hit an unimplemented block\n",
945 instance = getNext(cur, "./ts:instanceTest[1]");
946 while (instance != NULL) {
947 if (schemas != NULL) {
948 xstcTestInstance(instance, schemas, path, base);
951 * We'll automatically mark the instances as failed
952 * if the schema was broken.
956 instance = getNext(instance,
957 "following-sibling::ts:instanceTest[1]");
959 } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
961 ctxt = xmlSchemaNewParserCtxt((const char *) path);
962 xmlSchemaSetParserErrors(ctxt,
963 (xmlSchemaValidityErrorFunc) testErrorHandler,
964 (xmlSchemaValidityWarningFunc) testErrorHandler,
966 schemas = xmlSchemaParse(ctxt);
967 xmlSchemaFreeParserCtxt(ctxt);
968 if (schemas != NULL) {
969 test_log("Failed to detect error in schemas %s\n",
974 if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
976 test_log("invalid schemas %s hit an unimplemented block\n",
982 test_log("testGroup line %ld misses unexpected validity value%s\n",
983 xmlGetLineNo(cur), validity);
989 if (href != NULL) xmlFree(href);
990 if (path != NULL) xmlFree(path);
991 if (validity != NULL) xmlFree(validity);
992 if (schemas != NULL) xmlSchemaFree(schemas);
994 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
995 test_log("Processing test line %ld %s leaked %d\n",
996 xmlGetLineNo(cur), path, xmlMemUsed() - mem);
1003 xstcMetadata(const char *metadata, const char *base) {
1006 xmlChar *contributor;
1010 doc = xmlReadFile(metadata, NULL, XML_PARSE_NOENT);
1012 fprintf(stderr, "Failed to parse %s\n", metadata);
1016 cur = xmlDocGetRootElement(doc);
1017 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSet"))) {
1018 fprintf(stderr, "Unexpected format %s\n", metadata);
1021 contributor = xmlGetProp(cur, BAD_CAST "contributor");
1022 if (contributor == NULL) {
1023 contributor = xmlStrdup(BAD_CAST "Unknown");
1025 name = xmlGetProp(cur, BAD_CAST "name");
1027 name = xmlStrdup(BAD_CAST "Unknown");
1029 printf("## %s test suite for Schemas version %s\n", contributor, name);
1030 xmlFree(contributor);
1033 cur = getNext(cur, "./ts:testGroup[1]");
1034 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testGroup"))) {
1035 fprintf(stderr, "Unexpected format %s\n", metadata);
1039 while (cur != NULL) {
1040 xstcTestGroup(cur, base);
1041 cur = getNext(cur, "following-sibling::ts:testGroup[1]");
1049 /************************************************************************
1051 * The driver for the tests *
1053 ************************************************************************/
1056 main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1058 int old_errors, old_tests, old_leaks;
1060 logfile = fopen(LOGFILE, "w");
1061 if (logfile == NULL) {
1063 "Could not open the log file, running in verbose mode\n");
1066 initializeLibxml2();
1068 if ((argc >= 2) && (!strcmp(argv[1], "-v")))
1072 old_errors = nb_errors;
1073 old_tests = nb_tests;
1074 old_leaks = nb_leaks;
1076 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1077 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1079 printf("Ran %d tests, %d errors, %d leaks\n",
1080 nb_tests - old_tests,
1081 nb_errors - old_errors,
1082 nb_leaks - old_leaks);
1083 old_errors = nb_errors;
1084 old_tests = nb_tests;
1085 old_leaks = nb_leaks;
1087 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1088 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1090 printf("Ran %d tests, %d errors, %d leaks\n",
1091 nb_tests - old_tests,
1092 nb_errors - old_errors,
1093 nb_leaks - old_leaks);
1094 old_errors = nb_errors;
1095 old_tests = nb_tests;
1096 old_leaks = nb_leaks;
1098 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1099 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1101 printf("Ran %d tests, %d errors, %d leaks\n",
1102 nb_tests - old_tests,
1103 nb_errors - old_errors,
1104 nb_leaks - old_leaks);
1105 old_errors = nb_errors;
1106 old_tests = nb_tests;
1107 old_leaks = nb_leaks;
1110 xstcMetadata("xstc/Tests/Metadata/NISTXMLSchemaDatatypes.testSet",
1111 "xstc/Tests/Metadata/");
1112 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1113 printf("Ran %d tests (%d schemata), no errors\n",
1114 nb_tests - old_tests, nb_schematas);
1116 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
1117 nb_tests - old_tests,
1119 nb_errors - old_errors,
1121 nb_leaks - old_leaks);
1122 old_errors = nb_errors;
1123 old_tests = nb_tests;
1124 old_leaks = nb_leaks;
1127 xstcMetadata("xstc/Tests/Metadata/SunXMLSchema1-0-20020116.testSet",
1129 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1130 printf("Ran %d tests (%d schemata), no errors\n",
1131 nb_tests - old_tests, nb_schematas);
1133 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
1134 nb_tests - old_tests,
1136 nb_errors - old_errors,
1138 nb_leaks - old_leaks);
1139 old_errors = nb_errors;
1140 old_tests = nb_tests;
1141 old_leaks = nb_leaks;
1144 xstcMetadata("xstc/Tests/Metadata/MSXMLSchema1-0-20020116.testSet",
1146 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1147 printf("Ran %d tests (%d schemata), no errors\n",
1148 nb_tests - old_tests, nb_schematas);
1150 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
1151 nb_tests - old_tests,
1153 nb_errors - old_errors,
1155 nb_leaks - old_leaks);
1157 if ((nb_errors == 0) && (nb_leaks == 0)) {
1159 printf("Total %d tests, no errors\n",
1163 printf("Total %d tests, %d errors, %d leaks\n",
1164 nb_tests, nb_errors, nb_leaks);
1166 xmlXPathFreeContext(ctxtXPath);
1170 if (logfile != NULL)
1174 #else /* !SCHEMAS */
1176 main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1177 fprintf(stderr, "runsuite requires support for schemas and xpath in libxml2\n");