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;
43 #if defined(_WIN32) && !defined(__CYGWIN__)
45 #define vsnprintf _vsnprintf
47 #define snprintf _snprintf
51 /************************************************************************
53 * File name and path utilities *
55 ************************************************************************/
57 static int checkTestFile(const char *filename) {
60 if (stat(filename, &buf) == -1)
63 #if defined(_WIN32) && !defined(__CYGWIN__)
64 if (!(buf.st_mode & _S_IFREG))
67 if (!S_ISREG(buf.st_mode))
74 static xmlChar *composeDir(const xmlChar *dir, const xmlChar *path) {
77 if (dir == NULL) return(xmlStrdup(path));
78 if (path == NULL) return(NULL);
80 snprintf(buf, 500, "%s/%s", (const char *) dir, (const char *) path);
81 return(xmlStrdup((const xmlChar *) buf));
84 /************************************************************************
86 * Libxml2 specific routines *
88 ************************************************************************/
90 static int nb_tests = 0;
91 static int nb_errors = 0;
92 static int nb_internals = 0;
93 static int nb_schematas = 0;
94 static int nb_unimplemented = 0;
95 static int nb_leaks = 0;
96 static int extraMemoryFromResolver = 0;
100 fprintf(stderr, "Exitting tests on fatal error\n");
105 * that's needed to implement <resource>
107 #define MAX_ENTITIES 20
108 static char *testEntitiesName[MAX_ENTITIES];
109 static char *testEntitiesValue[MAX_ENTITIES];
110 static int nb_entities = 0;
111 static void resetEntities(void) {
114 for (i = 0;i < nb_entities;i++) {
115 if (testEntitiesName[i] != NULL)
116 xmlFree(testEntitiesName[i]);
117 if (testEntitiesValue[i] != NULL)
118 xmlFree(testEntitiesValue[i]);
122 static int addEntity(char *name, char *content) {
123 if (nb_entities >= MAX_ENTITIES) {
124 fprintf(stderr, "Too many entities defined\n");
127 testEntitiesName[nb_entities] = name;
128 testEntitiesValue[nb_entities] = content;
134 * We need to trap calls to the resolver to not account memory for the catalog
135 * which is shared to the current running test. We also don't want to have
136 * network downloads modifying tests.
138 static xmlParserInputPtr
139 testExternalEntityLoader(const char *URL, const char *ID,
140 xmlParserCtxtPtr ctxt) {
141 xmlParserInputPtr ret;
144 for (i = 0;i < nb_entities;i++) {
145 if (!strcmp(testEntitiesName[i], URL)) {
146 ret = xmlNewStringInputStream(ctxt,
147 (const xmlChar *) testEntitiesValue[i]);
149 ret->filename = (const char *)
150 xmlStrdup((xmlChar *)testEntitiesName[i]);
155 if (checkTestFile(URL)) {
156 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
158 int memused = xmlMemUsed();
159 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
160 extraMemoryFromResolver += xmlMemUsed() - memused;
164 fprintf(stderr, "Failed to find resource %s\n", URL);
172 * Trapping the error messages at the generic level to grab the equivalent of
173 * stderr messages on CLI tools.
175 static char testErrors[32769];
176 static int testErrorsSize = 0;
178 static void test_log(const char *msg, ...) {
180 if (logfile != NULL) {
181 fprintf(logfile, "\n------------\n");
183 vfprintf(logfile, msg, args);
185 fprintf(logfile, "%s", testErrors);
186 testErrorsSize = 0; testErrors[0] = 0;
190 vfprintf(stderr, msg, args);
196 testErrorHandler(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
200 if (testErrorsSize >= 32768)
203 res = vsnprintf(&testErrors[testErrorsSize],
204 32768 - testErrorsSize,
207 if (testErrorsSize + res >= 32768) {
209 testErrorsSize = 32768;
210 testErrors[testErrorsSize] = 0;
212 testErrorsSize += res;
214 testErrors[testErrorsSize] = 0;
217 static xmlXPathContextPtr ctxtXPath;
220 initializeLibxml2(void) {
221 xmlGetWarningsDefaultValue = 0;
222 xmlPedanticParserDefault(0);
224 xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
226 xmlSetExternalEntityLoader(testExternalEntityLoader);
227 ctxtXPath = xmlXPathNewContext(NULL);
229 * Deactivate the cache if created; otherwise we have to create/free it
230 * for every test, since it will confuse the memory leak detection.
231 * Note that normally this need not be done, since the cache is not
232 * created until set explicitely with xmlXPathContextSetCache();
233 * but for test purposes it is sometimes usefull to activate the
234 * cache by default for the whole library.
236 if (ctxtXPath->cache != NULL)
237 xmlXPathContextSetCache(ctxtXPath, 0, -1, 0);
238 /* used as default nanemspace in xstc tests */
239 xmlXPathRegisterNs(ctxtXPath, BAD_CAST "ts", BAD_CAST "TestSuite");
240 xmlXPathRegisterNs(ctxtXPath, BAD_CAST "xlink",
241 BAD_CAST "http://www.w3.org/1999/xlink");
242 xmlSetGenericErrorFunc(NULL, testErrorHandler);
243 #ifdef LIBXML_SCHEMAS_ENABLED
244 xmlSchemaInitTypes();
245 xmlRelaxNGInitTypes();
250 getNext(xmlNodePtr cur, const char *xpath) {
251 xmlNodePtr ret = NULL;
252 xmlXPathObjectPtr res;
253 xmlXPathCompExprPtr comp;
255 if ((cur == NULL) || (cur->doc == NULL) || (xpath == NULL))
257 ctxtXPath->doc = cur->doc;
258 ctxtXPath->node = cur;
259 comp = xmlXPathCompile(BAD_CAST xpath);
261 fprintf(stderr, "Failed to compile %s\n", xpath);
264 res = xmlXPathCompiledEval(comp, ctxtXPath);
265 xmlXPathFreeCompExpr(comp);
268 if ((res->type == XPATH_NODESET) &&
269 (res->nodesetval != NULL) &&
270 (res->nodesetval->nodeNr > 0) &&
271 (res->nodesetval->nodeTab != NULL))
272 ret = res->nodesetval->nodeTab[0];
273 xmlXPathFreeObject(res);
278 getString(xmlNodePtr cur, const char *xpath) {
280 xmlXPathObjectPtr res;
281 xmlXPathCompExprPtr comp;
283 if ((cur == NULL) || (cur->doc == NULL) || (xpath == NULL))
285 ctxtXPath->doc = cur->doc;
286 ctxtXPath->node = cur;
287 comp = xmlXPathCompile(BAD_CAST xpath);
289 fprintf(stderr, "Failed to compile %s\n", xpath);
292 res = xmlXPathCompiledEval(comp, ctxtXPath);
293 xmlXPathFreeCompExpr(comp);
296 if (res->type == XPATH_STRING) {
297 ret = res->stringval;
298 res->stringval = NULL;
300 xmlXPathFreeObject(res);
304 /************************************************************************
306 * Test test/xsdtest/xsdtestsuite.xml *
308 ************************************************************************/
311 xsdIncorectTestCase(xmlNodePtr cur) {
314 xmlRelaxNGParserCtxtPtr pctxt;
315 xmlRelaxNGPtr rng = NULL;
318 cur = getNext(cur, "./incorrect[1]");
323 test = getNext(cur, "./*");
325 test_log("Failed to find test in correct line %ld\n",
331 extraMemoryFromResolver = 0;
333 * dump the schemas to a buffer, then reparse it and compile the schemas
335 buf = xmlBufferCreate();
337 fprintf(stderr, "out of memory !\n");
340 xmlNodeDump(buf, test->doc, test, 0, 0);
341 pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
342 xmlRelaxNGSetParserErrors(pctxt,
343 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
344 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
346 rng = xmlRelaxNGParse(pctxt);
347 xmlRelaxNGFreeParserCtxt(pctxt);
349 test_log("Failed to detect incorect RNG line %ld\n",
361 if ((memt < xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
362 test_log("Validation of tests starting line %ld leaked %d\n",
363 xmlGetLineNo(cur), xmlMemUsed() - memt);
370 installResources(xmlNodePtr tst, const xmlChar *base) {
373 xmlChar *name, *content, *res;
375 buf = xmlBufferCreate();
377 fprintf(stderr, "out of memory !\n");
380 xmlNodeDump(buf, tst->doc, tst, 0, 0);
382 while (tst != NULL) {
383 test = getNext(tst, "./*");
386 xmlNodeDump(buf, test->doc, test, 0, 0);
387 name = getString(tst, "string(@name)");
388 content = xmlStrdup(buf->content);
389 if ((name != NULL) && (content != NULL)) {
390 res = composeDir(base, name);
392 addEntity((char *) res, (char *) content);
394 if (name != NULL) xmlFree(name);
395 if (content != NULL) xmlFree(content);
398 tst = getNext(tst, "following-sibling::resource[1]");
405 installDirs(xmlNodePtr tst, const xmlChar *base) {
409 name = getString(tst, "string(@name)");
412 res = composeDir(base, name);
417 /* Now process resources and subdir recursively */
418 test = getNext(tst, "./resource[1]");
420 installResources(test, res);
422 test = getNext(tst, "./dir[1]");
423 while (test != NULL) {
424 installDirs(test, res);
425 test = getNext(test, "following-sibling::dir[1]");
431 xsdTestCase(xmlNodePtr tst) {
432 xmlNodePtr test, tmp, cur;
434 xmlDocPtr doc = NULL;
435 xmlRelaxNGParserCtxtPtr pctxt;
436 xmlRelaxNGValidCtxtPtr ctxt;
437 xmlRelaxNGPtr rng = NULL;
438 int ret = 0, mem, memt;
442 testErrorsSize = 0; testErrors[0] = 0;
444 tmp = getNext(tst, "./dir[1]");
446 installDirs(tmp, NULL);
448 tmp = getNext(tst, "./resource[1]");
450 installResources(tmp, NULL);
453 cur = getNext(tst, "./correct[1]");
455 return(xsdIncorectTestCase(tst));
458 test = getNext(cur, "./*");
460 fprintf(stderr, "Failed to find test in correct line %ld\n",
466 extraMemoryFromResolver = 0;
468 * dump the schemas to a buffer, then reparse it and compile the schemas
470 buf = xmlBufferCreate();
472 fprintf(stderr, "out of memory !\n");
475 xmlNodeDump(buf, test->doc, test, 0, 0);
476 pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
477 xmlRelaxNGSetParserErrors(pctxt,
478 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
479 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
481 rng = xmlRelaxNGParse(pctxt);
482 xmlRelaxNGFreeParserCtxt(pctxt);
483 if (extraMemoryFromResolver)
487 test_log("Failed to parse RNGtest line %ld\n",
494 * now scan all the siblings of correct to process the <valid> tests
496 tmp = getNext(cur, "following-sibling::valid[1]");
497 while (tmp != NULL) {
498 dtd = xmlGetProp(tmp, BAD_CAST "dtd");
499 test = getNext(tmp, "./*");
501 fprintf(stderr, "Failed to find test in <valid> line %ld\n",
507 xmlBufferAdd(buf, dtd, -1);
508 xmlNodeDump(buf, test->doc, test, 0, 0);
511 * We are ready to run the test
514 extraMemoryFromResolver = 0;
515 doc = xmlReadMemory((const char *)buf->content, buf->use,
518 test_log("Failed to parse valid instance line %ld\n",
523 ctxt = xmlRelaxNGNewValidCtxt(rng);
524 xmlRelaxNGSetValidErrors(ctxt,
525 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
526 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
528 ret = xmlRelaxNGValidateDoc(ctxt, doc);
529 xmlRelaxNGFreeValidCtxt(ctxt);
531 test_log("Failed to validate valid instance line %ld\n",
534 } else if (ret < 0) {
535 test_log("Internal error validating instance line %ld\n",
542 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
543 test_log("Validation of instance line %ld leaked %d\n",
544 xmlGetLineNo(tmp), xmlMemUsed() - mem);
551 tmp = getNext(tmp, "following-sibling::valid[1]");
554 * now scan all the siblings of correct to process the <invalid> tests
556 tmp = getNext(cur, "following-sibling::invalid[1]");
557 while (tmp != NULL) {
558 test = getNext(tmp, "./*");
560 fprintf(stderr, "Failed to find test in <invalid> line %ld\n",
565 xmlNodeDump(buf, test->doc, test, 0, 0);
568 * We are ready to run the test
571 extraMemoryFromResolver = 0;
572 doc = xmlReadMemory((const char *)buf->content, buf->use,
575 test_log("Failed to parse valid instance line %ld\n",
580 ctxt = xmlRelaxNGNewValidCtxt(rng);
581 xmlRelaxNGSetValidErrors(ctxt,
582 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
583 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
585 ret = xmlRelaxNGValidateDoc(ctxt, doc);
586 xmlRelaxNGFreeValidCtxt(ctxt);
588 test_log("Failed to detect invalid instance line %ld\n",
591 } else if (ret < 0) {
592 test_log("Internal error validating instance line %ld\n",
599 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
600 test_log("Validation of instance line %ld leaked %d\n",
601 xmlGetLineNo(tmp), xmlMemUsed() - mem);
606 tmp = getNext(tmp, "following-sibling::invalid[1]");
615 if ((memt != xmlMemUsed()) && (memt != 0)) {
616 test_log("Validation of tests starting line %ld leaked %d\n",
617 xmlGetLineNo(cur), xmlMemUsed() - memt);
624 xsdTestSuite(xmlNodePtr cur) {
626 xmlChar *doc = getString(cur, "string(documentation)");
629 printf("Suite %s\n", doc);
633 cur = getNext(cur, "./testCase[1]");
634 while (cur != NULL) {
636 cur = getNext(cur, "following-sibling::testCase[1]");
646 const char *filename = "test/xsdtest/xsdtestsuite.xml";
649 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
651 fprintf(stderr, "Failed to parse %s\n", filename);
654 printf("## XML Schemas datatypes test suite from James Clark\n");
656 cur = xmlDocGetRootElement(doc);
657 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
658 fprintf(stderr, "Unexpected format %s\n", filename);
663 cur = getNext(cur, "./testSuite[1]");
664 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
665 fprintf(stderr, "Unexpected format %s\n", filename);
669 while (cur != NULL) {
671 cur = getNext(cur, "following-sibling::testSuite[1]");
681 rngTestSuite(xmlNodePtr cur) {
683 xmlChar *doc = getString(cur, "string(documentation)");
686 printf("Suite %s\n", doc);
689 doc = getString(cur, "string(section)");
691 printf("Section %s\n", doc);
696 cur = getNext(cur, "./testSuite[1]");
697 while (cur != NULL) {
699 cur = getNext(cur, "following-sibling::testSuite[1]");
709 const char *filename = "test/relaxng/OASIS/spectest.xml";
712 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
714 fprintf(stderr, "Failed to parse %s\n", filename);
717 printf("## Relax NG test suite from James Clark\n");
719 cur = xmlDocGetRootElement(doc);
720 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
721 fprintf(stderr, "Unexpected format %s\n", filename);
726 cur = getNext(cur, "./testSuite[1]");
727 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
728 fprintf(stderr, "Unexpected format %s\n", filename);
732 while (cur != NULL) {
734 cur = getNext(cur, "following-sibling::testSuite[1]");
747 const char *filename = "test/relaxng/testsuite.xml";
750 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
752 fprintf(stderr, "Failed to parse %s\n", filename);
755 printf("## Relax NG test suite for libxml2\n");
757 cur = xmlDocGetRootElement(doc);
758 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
759 fprintf(stderr, "Unexpected format %s\n", filename);
764 cur = getNext(cur, "./testSuite[1]");
765 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
766 fprintf(stderr, "Unexpected format %s\n", filename);
770 while (cur != NULL) {
772 cur = getNext(cur, "following-sibling::testSuite[1]");
781 /************************************************************************
783 * Schemas test suites from W3C/NIST/MS/Sun *
785 ************************************************************************/
788 xstcTestInstance(xmlNodePtr cur, xmlSchemaPtr schemas,
789 const xmlChar *spath, const char *base) {
790 xmlChar *href = NULL;
791 xmlChar *path = NULL;
792 xmlChar *validity = NULL;
793 xmlSchemaValidCtxtPtr ctxt = NULL;
794 xmlDocPtr doc = NULL;
798 testErrorsSize = 0; testErrors[0] = 0;
800 href = getString(cur,
801 "string(ts:instanceDocument/@xlink:href)");
802 if ((href == NULL) || (href[0] == 0)) {
803 test_log("testGroup line %ld misses href for schemaDocument\n",
808 path = xmlBuildURI(href, BAD_CAST base);
811 "Failed to build path to schemas testGroup line %ld : %s\n",
812 xmlGetLineNo(cur), href);
816 if (checkTestFile((const char *) path) <= 0) {
817 test_log("schemas for testGroup line %ld is missing: %s\n",
818 xmlGetLineNo(cur), path);
822 validity = getString(cur,
823 "string(ts:expected/@validity)");
824 if (validity == NULL) {
825 fprintf(stderr, "instanceDocument line %ld misses expected validity\n",
831 doc = xmlReadFile((const char *) path, NULL, XML_PARSE_NOENT);
833 fprintf(stderr, "instance %s fails to parse\n", path);
839 ctxt = xmlSchemaNewValidCtxt(schemas);
840 xmlSchemaSetValidErrors(ctxt,
841 (xmlSchemaValidityErrorFunc) testErrorHandler,
842 (xmlSchemaValidityWarningFunc) testErrorHandler,
844 ret = xmlSchemaValidateDoc(ctxt, doc);
846 if (xmlStrEqual(validity, BAD_CAST "valid")) {
848 test_log("valid instance %s failed to validate against %s\n",
851 } else if (ret < 0) {
852 test_log("valid instance %s got internal error validating %s\n",
857 } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
859 test_log("Failed to detect invalid instance %s against %s\n",
864 test_log("instanceDocument line %ld has unexpected validity value%s\n",
865 xmlGetLineNo(cur), validity);
871 if (href != NULL) xmlFree(href);
872 if (path != NULL) xmlFree(path);
873 if (validity != NULL) xmlFree(validity);
874 if (ctxt != NULL) xmlSchemaFreeValidCtxt(ctxt);
875 if (doc != NULL) xmlFreeDoc(doc);
877 if (mem != xmlMemUsed()) {
878 test_log("Validation of tests starting line %ld leaked %d\n",
879 xmlGetLineNo(cur), xmlMemUsed() - mem);
886 xstcTestGroup(xmlNodePtr cur, const char *base) {
887 xmlChar *href = NULL;
888 xmlChar *path = NULL;
889 xmlChar *validity = NULL;
890 xmlSchemaPtr schemas = NULL;
891 xmlSchemaParserCtxtPtr ctxt;
896 testErrorsSize = 0; testErrors[0] = 0;
898 href = getString(cur,
899 "string(ts:schemaTest/ts:schemaDocument/@xlink:href)");
900 if ((href == NULL) || (href[0] == 0)) {
901 test_log("testGroup line %ld misses href for schemaDocument\n",
906 path = xmlBuildURI(href, BAD_CAST base);
908 test_log("Failed to build path to schemas testGroup line %ld : %s\n",
909 xmlGetLineNo(cur), href);
913 if (checkTestFile((const char *) path) <= 0) {
914 test_log("schemas for testGroup line %ld is missing: %s\n",
915 xmlGetLineNo(cur), path);
919 validity = getString(cur,
920 "string(ts:schemaTest/ts:expected/@validity)");
921 if (validity == NULL) {
922 test_log("testGroup line %ld misses expected validity\n",
928 if (xmlStrEqual(validity, BAD_CAST "valid")) {
930 ctxt = xmlSchemaNewParserCtxt((const char *) path);
931 xmlSchemaSetParserErrors(ctxt,
932 (xmlSchemaValidityErrorFunc) testErrorHandler,
933 (xmlSchemaValidityWarningFunc) testErrorHandler,
935 schemas = xmlSchemaParse(ctxt);
936 xmlSchemaFreeParserCtxt(ctxt);
937 if (schemas == NULL) {
938 test_log("valid schemas %s failed to parse\n",
943 if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
944 test_log("valid schemas %s hit an unimplemented block\n",
950 instance = getNext(cur, "./ts:instanceTest[1]");
951 while (instance != NULL) {
952 if (schemas != NULL) {
953 xstcTestInstance(instance, schemas, path, base);
956 * We'll automatically mark the instances as failed
957 * if the schema was broken.
961 instance = getNext(instance,
962 "following-sibling::ts:instanceTest[1]");
964 } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
966 ctxt = xmlSchemaNewParserCtxt((const char *) path);
967 xmlSchemaSetParserErrors(ctxt,
968 (xmlSchemaValidityErrorFunc) testErrorHandler,
969 (xmlSchemaValidityWarningFunc) testErrorHandler,
971 schemas = xmlSchemaParse(ctxt);
972 xmlSchemaFreeParserCtxt(ctxt);
973 if (schemas != NULL) {
974 test_log("Failed to detect error in schemas %s\n",
979 if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
981 test_log("invalid schemas %s hit an unimplemented block\n",
987 test_log("testGroup line %ld misses unexpected validity value%s\n",
988 xmlGetLineNo(cur), validity);
994 if (href != NULL) xmlFree(href);
995 if (path != NULL) xmlFree(path);
996 if (validity != NULL) xmlFree(validity);
997 if (schemas != NULL) xmlSchemaFree(schemas);
999 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
1000 test_log("Processing test line %ld %s leaked %d\n",
1001 xmlGetLineNo(cur), path, xmlMemUsed() - mem);
1008 xstcMetadata(const char *metadata, const char *base) {
1011 xmlChar *contributor;
1015 doc = xmlReadFile(metadata, NULL, XML_PARSE_NOENT);
1017 fprintf(stderr, "Failed to parse %s\n", metadata);
1021 cur = xmlDocGetRootElement(doc);
1022 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSet"))) {
1023 fprintf(stderr, "Unexpected format %s\n", metadata);
1026 contributor = xmlGetProp(cur, BAD_CAST "contributor");
1027 if (contributor == NULL) {
1028 contributor = xmlStrdup(BAD_CAST "Unknown");
1030 name = xmlGetProp(cur, BAD_CAST "name");
1032 name = xmlStrdup(BAD_CAST "Unknown");
1034 printf("## %s test suite for Schemas version %s\n", contributor, name);
1035 xmlFree(contributor);
1038 cur = getNext(cur, "./ts:testGroup[1]");
1039 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testGroup"))) {
1040 fprintf(stderr, "Unexpected format %s\n", metadata);
1044 while (cur != NULL) {
1045 xstcTestGroup(cur, base);
1046 cur = getNext(cur, "following-sibling::ts:testGroup[1]");
1054 /************************************************************************
1056 * The driver for the tests *
1058 ************************************************************************/
1061 main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1063 int old_errors, old_tests, old_leaks;
1065 logfile = fopen(LOGFILE, "w");
1066 if (logfile == NULL) {
1068 "Could not open the log file, running in verbose mode\n");
1071 initializeLibxml2();
1073 if ((argc >= 2) && (!strcmp(argv[1], "-v")))
1077 old_errors = nb_errors;
1078 old_tests = nb_tests;
1079 old_leaks = nb_leaks;
1081 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1082 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1084 printf("Ran %d tests, %d errors, %d leaks\n",
1085 nb_tests - old_tests,
1086 nb_errors - old_errors,
1087 nb_leaks - old_leaks);
1088 old_errors = nb_errors;
1089 old_tests = nb_tests;
1090 old_leaks = nb_leaks;
1092 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1093 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1095 printf("Ran %d tests, %d errors, %d leaks\n",
1096 nb_tests - old_tests,
1097 nb_errors - old_errors,
1098 nb_leaks - old_leaks);
1099 old_errors = nb_errors;
1100 old_tests = nb_tests;
1101 old_leaks = nb_leaks;
1103 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1104 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1106 printf("Ran %d tests, %d errors, %d leaks\n",
1107 nb_tests - old_tests,
1108 nb_errors - old_errors,
1109 nb_leaks - old_leaks);
1110 old_errors = nb_errors;
1111 old_tests = nb_tests;
1112 old_leaks = nb_leaks;
1115 xstcMetadata("xstc/Tests/Metadata/NISTXMLSchemaDatatypes.testSet",
1116 "xstc/Tests/Metadata/");
1117 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1118 printf("Ran %d tests (%d schemata), no errors\n",
1119 nb_tests - old_tests, nb_schematas);
1121 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
1122 nb_tests - old_tests,
1124 nb_errors - old_errors,
1126 nb_leaks - old_leaks);
1127 old_errors = nb_errors;
1128 old_tests = nb_tests;
1129 old_leaks = nb_leaks;
1132 xstcMetadata("xstc/Tests/Metadata/SunXMLSchema1-0-20020116.testSet",
1134 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1135 printf("Ran %d tests (%d schemata), no errors\n",
1136 nb_tests - old_tests, nb_schematas);
1138 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
1139 nb_tests - old_tests,
1141 nb_errors - old_errors,
1143 nb_leaks - old_leaks);
1144 old_errors = nb_errors;
1145 old_tests = nb_tests;
1146 old_leaks = nb_leaks;
1149 xstcMetadata("xstc/Tests/Metadata/MSXMLSchema1-0-20020116.testSet",
1151 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1152 printf("Ran %d tests (%d schemata), no errors\n",
1153 nb_tests - old_tests, nb_schematas);
1155 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
1156 nb_tests - old_tests,
1158 nb_errors - old_errors,
1160 nb_leaks - old_leaks);
1162 if ((nb_errors == 0) && (nb_leaks == 0)) {
1164 printf("Total %d tests, no errors\n",
1168 printf("Total %d tests, %d errors, %d leaks\n",
1169 nb_tests, nb_errors, nb_leaks);
1171 xmlXPathFreeContext(ctxtXPath);
1175 if (logfile != NULL)
1179 #else /* !SCHEMAS */
1181 main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1182 fprintf(stderr, "runsuite requires support for schemas and xpath in libxml2\n");