2 * runsuite.c: C program to run libxml2 againts published testsuites
4 * See Copyright for the status of this software.
12 #if !defined(_WIN32) || defined(__CYGWIN__)
16 #include <sys/types.h>
20 #include <libxml/parser.h>
21 #include <libxml/parserInternals.h>
22 #include <libxml/tree.h>
23 #include <libxml/uri.h>
24 #if defined(LIBXML_SCHEMAS_ENABLED) && defined(LIBXML_XPATH_ENABLED)
25 #include <libxml/xmlreader.h>
27 #include <libxml/xpath.h>
28 #include <libxml/xpathInternals.h>
30 #include <libxml/relaxng.h>
31 #include <libxml/xmlschemas.h>
32 #include <libxml/xmlschemastypes.h>
34 #define LOGFILE "runsuite.log"
35 static FILE *logfile
= NULL
;
36 static int verbose
= 0;
39 /************************************************************************
41 * File name and path utilities *
43 ************************************************************************/
45 static int checkTestFile(const char *filename
) {
48 if (stat(filename
, &buf
) == -1)
51 #if defined(_WIN32) && !defined(__CYGWIN__)
52 if (!(buf
.st_mode
& _S_IFREG
))
55 if (!S_ISREG(buf
.st_mode
))
62 static xmlChar
*composeDir(const xmlChar
*dir
, const xmlChar
*path
) {
65 if (dir
== NULL
) return(xmlStrdup(path
));
66 if (path
== NULL
) return(NULL
);
68 snprintf(buf
, 500, "%s/%s", (const char *) dir
, (const char *) path
);
69 return(xmlStrdup((const xmlChar
*) buf
));
72 /************************************************************************
74 * Libxml2 specific routines *
76 ************************************************************************/
78 static int nb_tests
= 0;
79 static int nb_errors
= 0;
80 static int nb_internals
= 0;
81 static int nb_schematas
= 0;
82 static int nb_unimplemented
= 0;
83 static int nb_leaks
= 0;
84 static int extraMemoryFromResolver
= 0;
88 fprintf(stderr
, "Exitting tests on fatal error\n");
93 * that's needed to implement <resource>
95 #define MAX_ENTITIES 20
96 static char *testEntitiesName
[MAX_ENTITIES
];
97 static char *testEntitiesValue
[MAX_ENTITIES
];
98 static int nb_entities
= 0;
99 static void resetEntities(void) {
102 for (i
= 0;i
< nb_entities
;i
++) {
103 if (testEntitiesName
[i
] != NULL
)
104 xmlFree(testEntitiesName
[i
]);
105 if (testEntitiesValue
[i
] != NULL
)
106 xmlFree(testEntitiesValue
[i
]);
110 static int addEntity(char *name
, char *content
) {
111 if (nb_entities
>= MAX_ENTITIES
) {
112 fprintf(stderr
, "Too many entities defined\n");
115 testEntitiesName
[nb_entities
] = name
;
116 testEntitiesValue
[nb_entities
] = content
;
122 * We need to trap calls to the resolver to not account memory for the catalog
123 * which is shared to the current running test. We also don't want to have
124 * network downloads modifying tests.
126 static xmlParserInputPtr
127 testExternalEntityLoader(const char *URL
, const char *ID
,
128 xmlParserCtxtPtr ctxt
) {
129 xmlParserInputPtr ret
;
132 for (i
= 0;i
< nb_entities
;i
++) {
133 if (!strcmp(testEntitiesName
[i
], URL
)) {
134 ret
= xmlNewStringInputStream(ctxt
,
135 (const xmlChar
*) testEntitiesValue
[i
]);
137 ret
->filename
= (const char *)
138 xmlStrdup((xmlChar
*)testEntitiesName
[i
]);
143 if (checkTestFile(URL
)) {
144 ret
= xmlNoNetExternalEntityLoader(URL
, ID
, ctxt
);
146 int memused
= xmlMemUsed();
147 ret
= xmlNoNetExternalEntityLoader(URL
, ID
, ctxt
);
148 extraMemoryFromResolver
+= xmlMemUsed() - memused
;
152 fprintf(stderr
, "Failed to find resource %s\n", URL
);
160 * Trapping the error messages at the generic level to grab the equivalent of
161 * stderr messages on CLI tools.
163 static char testErrors
[32769];
164 static int testErrorsSize
= 0;
166 static void test_log(const char *msg
, ...) {
168 if (logfile
!= NULL
) {
169 fprintf(logfile
, "\n------------\n");
171 vfprintf(logfile
, msg
, args
);
173 fprintf(logfile
, "%s", testErrors
);
174 testErrorsSize
= 0; testErrors
[0] = 0;
178 vfprintf(stderr
, msg
, args
);
184 testErrorHandler(void *ctx ATTRIBUTE_UNUSED
, const char *msg
, ...) {
188 if (testErrorsSize
>= 32768)
191 res
= vsnprintf(&testErrors
[testErrorsSize
],
192 32768 - testErrorsSize
,
195 if (testErrorsSize
+ res
>= 32768) {
197 testErrorsSize
= 32768;
198 testErrors
[testErrorsSize
] = 0;
200 testErrorsSize
+= res
;
202 testErrors
[testErrorsSize
] = 0;
205 static xmlXPathContextPtr ctxtXPath
;
208 initializeLibxml2(void) {
209 xmlGetWarningsDefaultValue
= 0;
210 xmlPedanticParserDefault(0);
212 xmlMemSetup(xmlMemFree
, xmlMemMalloc
, xmlMemRealloc
, xmlMemoryStrdup
);
214 xmlSetExternalEntityLoader(testExternalEntityLoader
);
215 ctxtXPath
= xmlXPathNewContext(NULL
);
217 * Deactivate the cache if created; otherwise we have to create/free it
218 * for every test, since it will confuse the memory leak detection.
219 * Note that normally this need not be done, since the cache is not
220 * created until set explicitely with xmlXPathContextSetCache();
221 * but for test purposes it is sometimes usefull to activate the
222 * cache by default for the whole library.
224 if (ctxtXPath
->cache
!= NULL
)
225 xmlXPathContextSetCache(ctxtXPath
, 0, -1, 0);
226 /* used as default nanemspace in xstc tests */
227 xmlXPathRegisterNs(ctxtXPath
, BAD_CAST
"ts", BAD_CAST
"TestSuite");
228 xmlXPathRegisterNs(ctxtXPath
, BAD_CAST
"xlink",
229 BAD_CAST
"http://www.w3.org/1999/xlink");
230 xmlSetGenericErrorFunc(NULL
, testErrorHandler
);
231 #ifdef LIBXML_SCHEMAS_ENABLED
232 xmlSchemaInitTypes();
233 xmlRelaxNGInitTypes();
238 getNext(xmlNodePtr cur
, const char *xpath
) {
239 xmlNodePtr ret
= NULL
;
240 xmlXPathObjectPtr res
;
241 xmlXPathCompExprPtr comp
;
243 if ((cur
== NULL
) || (cur
->doc
== NULL
) || (xpath
== NULL
))
245 ctxtXPath
->doc
= cur
->doc
;
246 ctxtXPath
->node
= cur
;
247 comp
= xmlXPathCompile(BAD_CAST xpath
);
249 fprintf(stderr
, "Failed to compile %s\n", xpath
);
252 res
= xmlXPathCompiledEval(comp
, ctxtXPath
);
253 xmlXPathFreeCompExpr(comp
);
256 if ((res
->type
== XPATH_NODESET
) &&
257 (res
->nodesetval
!= NULL
) &&
258 (res
->nodesetval
->nodeNr
> 0) &&
259 (res
->nodesetval
->nodeTab
!= NULL
))
260 ret
= res
->nodesetval
->nodeTab
[0];
261 xmlXPathFreeObject(res
);
266 getString(xmlNodePtr cur
, const char *xpath
) {
268 xmlXPathObjectPtr res
;
269 xmlXPathCompExprPtr comp
;
271 if ((cur
== NULL
) || (cur
->doc
== NULL
) || (xpath
== NULL
))
273 ctxtXPath
->doc
= cur
->doc
;
274 ctxtXPath
->node
= cur
;
275 comp
= xmlXPathCompile(BAD_CAST xpath
);
277 fprintf(stderr
, "Failed to compile %s\n", xpath
);
280 res
= xmlXPathCompiledEval(comp
, ctxtXPath
);
281 xmlXPathFreeCompExpr(comp
);
284 if (res
->type
== XPATH_STRING
) {
285 ret
= res
->stringval
;
286 res
->stringval
= NULL
;
288 xmlXPathFreeObject(res
);
292 /************************************************************************
294 * Test test/xsdtest/xsdtestsuite.xml *
296 ************************************************************************/
299 xsdIncorectTestCase(xmlNodePtr cur
) {
302 xmlRelaxNGParserCtxtPtr pctxt
;
303 xmlRelaxNGPtr rng
= NULL
;
306 cur
= getNext(cur
, "./incorrect[1]");
311 test
= getNext(cur
, "./*");
313 test_log("Failed to find test in correct line %ld\n",
319 extraMemoryFromResolver
= 0;
321 * dump the schemas to a buffer, then reparse it and compile the schemas
323 buf
= xmlBufferCreate();
325 fprintf(stderr
, "out of memory !\n");
328 xmlNodeDump(buf
, test
->doc
, test
, 0, 0);
329 pctxt
= xmlRelaxNGNewMemParserCtxt((const char *)buf
->content
, buf
->use
);
330 xmlRelaxNGSetParserErrors(pctxt
,
331 (xmlRelaxNGValidityErrorFunc
) testErrorHandler
,
332 (xmlRelaxNGValidityWarningFunc
) testErrorHandler
,
334 rng
= xmlRelaxNGParse(pctxt
);
335 xmlRelaxNGFreeParserCtxt(pctxt
);
337 test_log("Failed to detect incorect RNG line %ld\n",
349 if ((memt
< xmlMemUsed()) && (extraMemoryFromResolver
== 0)) {
350 test_log("Validation of tests starting line %ld leaked %d\n",
351 xmlGetLineNo(cur
), xmlMemUsed() - memt
);
358 installResources(xmlNodePtr tst
, const xmlChar
*base
) {
361 xmlChar
*name
, *content
, *res
;
363 buf
= xmlBufferCreate();
365 fprintf(stderr
, "out of memory !\n");
368 xmlNodeDump(buf
, tst
->doc
, tst
, 0, 0);
370 while (tst
!= NULL
) {
371 test
= getNext(tst
, "./*");
374 xmlNodeDump(buf
, test
->doc
, test
, 0, 0);
375 name
= getString(tst
, "string(@name)");
376 content
= xmlStrdup(buf
->content
);
377 if ((name
!= NULL
) && (content
!= NULL
)) {
378 res
= composeDir(base
, name
);
380 addEntity((char *) res
, (char *) content
);
382 if (name
!= NULL
) xmlFree(name
);
383 if (content
!= NULL
) xmlFree(content
);
386 tst
= getNext(tst
, "following-sibling::resource[1]");
393 installDirs(xmlNodePtr tst
, const xmlChar
*base
) {
397 name
= getString(tst
, "string(@name)");
400 res
= composeDir(base
, name
);
405 /* Now process resources and subdir recursively */
406 test
= getNext(tst
, "./resource[1]");
408 installResources(test
, res
);
410 test
= getNext(tst
, "./dir[1]");
411 while (test
!= NULL
) {
412 installDirs(test
, res
);
413 test
= getNext(test
, "following-sibling::dir[1]");
419 xsdTestCase(xmlNodePtr tst
) {
420 xmlNodePtr test
, tmp
, cur
;
422 xmlDocPtr doc
= NULL
;
423 xmlRelaxNGParserCtxtPtr pctxt
;
424 xmlRelaxNGValidCtxtPtr ctxt
;
425 xmlRelaxNGPtr rng
= NULL
;
426 int ret
= 0, mem
, memt
;
430 testErrorsSize
= 0; testErrors
[0] = 0;
432 tmp
= getNext(tst
, "./dir[1]");
434 installDirs(tmp
, NULL
);
436 tmp
= getNext(tst
, "./resource[1]");
438 installResources(tmp
, NULL
);
441 cur
= getNext(tst
, "./correct[1]");
443 return(xsdIncorectTestCase(tst
));
446 test
= getNext(cur
, "./*");
448 fprintf(stderr
, "Failed to find test in correct line %ld\n",
454 extraMemoryFromResolver
= 0;
456 * dump the schemas to a buffer, then reparse it and compile the schemas
458 buf
= xmlBufferCreate();
460 fprintf(stderr
, "out of memory !\n");
463 xmlNodeDump(buf
, test
->doc
, test
, 0, 0);
464 pctxt
= xmlRelaxNGNewMemParserCtxt((const char *)buf
->content
, buf
->use
);
465 xmlRelaxNGSetParserErrors(pctxt
,
466 (xmlRelaxNGValidityErrorFunc
) testErrorHandler
,
467 (xmlRelaxNGValidityWarningFunc
) testErrorHandler
,
469 rng
= xmlRelaxNGParse(pctxt
);
470 xmlRelaxNGFreeParserCtxt(pctxt
);
471 if (extraMemoryFromResolver
)
475 test_log("Failed to parse RNGtest line %ld\n",
482 * now scan all the siblings of correct to process the <valid> tests
484 tmp
= getNext(cur
, "following-sibling::valid[1]");
485 while (tmp
!= NULL
) {
486 dtd
= xmlGetProp(tmp
, BAD_CAST
"dtd");
487 test
= getNext(tmp
, "./*");
489 fprintf(stderr
, "Failed to find test in <valid> line %ld\n",
495 xmlBufferAdd(buf
, dtd
, -1);
496 xmlNodeDump(buf
, test
->doc
, test
, 0, 0);
499 * We are ready to run the test
502 extraMemoryFromResolver
= 0;
503 doc
= xmlReadMemory((const char *)buf
->content
, buf
->use
,
506 test_log("Failed to parse valid instance line %ld\n",
511 ctxt
= xmlRelaxNGNewValidCtxt(rng
);
512 xmlRelaxNGSetValidErrors(ctxt
,
513 (xmlRelaxNGValidityErrorFunc
) testErrorHandler
,
514 (xmlRelaxNGValidityWarningFunc
) testErrorHandler
,
516 ret
= xmlRelaxNGValidateDoc(ctxt
, doc
);
517 xmlRelaxNGFreeValidCtxt(ctxt
);
519 test_log("Failed to validate valid instance line %ld\n",
522 } else if (ret
< 0) {
523 test_log("Internal error validating instance line %ld\n",
530 if ((mem
!= xmlMemUsed()) && (extraMemoryFromResolver
== 0)) {
531 test_log("Validation of instance line %ld leaked %d\n",
532 xmlGetLineNo(tmp
), xmlMemUsed() - mem
);
539 tmp
= getNext(tmp
, "following-sibling::valid[1]");
542 * now scan all the siblings of correct to process the <invalid> tests
544 tmp
= getNext(cur
, "following-sibling::invalid[1]");
545 while (tmp
!= NULL
) {
546 test
= getNext(tmp
, "./*");
548 fprintf(stderr
, "Failed to find test in <invalid> line %ld\n",
553 xmlNodeDump(buf
, test
->doc
, test
, 0, 0);
556 * We are ready to run the test
559 extraMemoryFromResolver
= 0;
560 doc
= xmlReadMemory((const char *)buf
->content
, buf
->use
,
563 test_log("Failed to parse valid instance line %ld\n",
568 ctxt
= xmlRelaxNGNewValidCtxt(rng
);
569 xmlRelaxNGSetValidErrors(ctxt
,
570 (xmlRelaxNGValidityErrorFunc
) testErrorHandler
,
571 (xmlRelaxNGValidityWarningFunc
) testErrorHandler
,
573 ret
= xmlRelaxNGValidateDoc(ctxt
, doc
);
574 xmlRelaxNGFreeValidCtxt(ctxt
);
576 test_log("Failed to detect invalid instance line %ld\n",
579 } else if (ret
< 0) {
580 test_log("Internal error validating instance line %ld\n",
587 if ((mem
!= xmlMemUsed()) && (extraMemoryFromResolver
== 0)) {
588 test_log("Validation of instance line %ld leaked %d\n",
589 xmlGetLineNo(tmp
), xmlMemUsed() - mem
);
594 tmp
= getNext(tmp
, "following-sibling::invalid[1]");
603 if ((memt
!= xmlMemUsed()) && (memt
!= 0)) {
604 test_log("Validation of tests starting line %ld leaked %d\n",
605 xmlGetLineNo(cur
), xmlMemUsed() - memt
);
612 xsdTestSuite(xmlNodePtr cur
) {
614 xmlChar
*doc
= getString(cur
, "string(documentation)");
617 printf("Suite %s\n", doc
);
621 cur
= getNext(cur
, "./testCase[1]");
622 while (cur
!= NULL
) {
624 cur
= getNext(cur
, "following-sibling::testCase[1]");
634 const char *filename
= "test/xsdtest/xsdtestsuite.xml";
637 doc
= xmlReadFile(filename
, NULL
, XML_PARSE_NOENT
);
639 fprintf(stderr
, "Failed to parse %s\n", filename
);
642 printf("## XML Schemas datatypes test suite from James Clark\n");
644 cur
= xmlDocGetRootElement(doc
);
645 if ((cur
== NULL
) || (!xmlStrEqual(cur
->name
, BAD_CAST
"testSuite"))) {
646 fprintf(stderr
, "Unexpected format %s\n", filename
);
651 cur
= getNext(cur
, "./testSuite[1]");
652 if ((cur
== NULL
) || (!xmlStrEqual(cur
->name
, BAD_CAST
"testSuite"))) {
653 fprintf(stderr
, "Unexpected format %s\n", filename
);
657 while (cur
!= NULL
) {
659 cur
= getNext(cur
, "following-sibling::testSuite[1]");
669 rngTestSuite(xmlNodePtr cur
) {
671 xmlChar
*doc
= getString(cur
, "string(documentation)");
674 printf("Suite %s\n", doc
);
677 doc
= getString(cur
, "string(section)");
679 printf("Section %s\n", doc
);
684 cur
= getNext(cur
, "./testSuite[1]");
685 while (cur
!= NULL
) {
687 cur
= getNext(cur
, "following-sibling::testSuite[1]");
697 const char *filename
= "test/relaxng/OASIS/spectest.xml";
700 doc
= xmlReadFile(filename
, NULL
, XML_PARSE_NOENT
);
702 fprintf(stderr
, "Failed to parse %s\n", filename
);
705 printf("## Relax NG test suite from James Clark\n");
707 cur
= xmlDocGetRootElement(doc
);
708 if ((cur
== NULL
) || (!xmlStrEqual(cur
->name
, BAD_CAST
"testSuite"))) {
709 fprintf(stderr
, "Unexpected format %s\n", filename
);
714 cur
= getNext(cur
, "./testSuite[1]");
715 if ((cur
== NULL
) || (!xmlStrEqual(cur
->name
, BAD_CAST
"testSuite"))) {
716 fprintf(stderr
, "Unexpected format %s\n", filename
);
720 while (cur
!= NULL
) {
722 cur
= getNext(cur
, "following-sibling::testSuite[1]");
735 const char *filename
= "test/relaxng/testsuite.xml";
738 doc
= xmlReadFile(filename
, NULL
, XML_PARSE_NOENT
);
740 fprintf(stderr
, "Failed to parse %s\n", filename
);
743 printf("## Relax NG test suite for libxml2\n");
745 cur
= xmlDocGetRootElement(doc
);
746 if ((cur
== NULL
) || (!xmlStrEqual(cur
->name
, BAD_CAST
"testSuite"))) {
747 fprintf(stderr
, "Unexpected format %s\n", filename
);
752 cur
= getNext(cur
, "./testSuite[1]");
753 if ((cur
== NULL
) || (!xmlStrEqual(cur
->name
, BAD_CAST
"testSuite"))) {
754 fprintf(stderr
, "Unexpected format %s\n", filename
);
758 while (cur
!= NULL
) {
760 cur
= getNext(cur
, "following-sibling::testSuite[1]");
769 /************************************************************************
771 * Schemas test suites from W3C/NIST/MS/Sun *
773 ************************************************************************/
776 xstcTestInstance(xmlNodePtr cur
, xmlSchemaPtr schemas
,
777 const xmlChar
*spath
, const char *base
) {
778 xmlChar
*href
= NULL
;
779 xmlChar
*path
= NULL
;
780 xmlChar
*validity
= NULL
;
781 xmlSchemaValidCtxtPtr ctxt
= NULL
;
782 xmlDocPtr doc
= NULL
;
786 testErrorsSize
= 0; testErrors
[0] = 0;
788 href
= getString(cur
,
789 "string(ts:instanceDocument/@xlink:href)");
790 if ((href
== NULL
) || (href
[0] == 0)) {
791 test_log("testGroup line %ld misses href for schemaDocument\n",
796 path
= xmlBuildURI(href
, BAD_CAST base
);
799 "Failed to build path to schemas testGroup line %ld : %s\n",
800 xmlGetLineNo(cur
), href
);
804 if (checkTestFile((const char *) path
) <= 0) {
805 test_log("schemas for testGroup line %ld is missing: %s\n",
806 xmlGetLineNo(cur
), path
);
810 validity
= getString(cur
,
811 "string(ts:expected/@validity)");
812 if (validity
== NULL
) {
813 fprintf(stderr
, "instanceDocument line %ld misses expected validity\n",
819 doc
= xmlReadFile((const char *) path
, NULL
, XML_PARSE_NOENT
);
821 fprintf(stderr
, "instance %s fails to parse\n", path
);
827 ctxt
= xmlSchemaNewValidCtxt(schemas
);
828 xmlSchemaSetValidErrors(ctxt
,
829 (xmlSchemaValidityErrorFunc
) testErrorHandler
,
830 (xmlSchemaValidityWarningFunc
) testErrorHandler
,
832 ret
= xmlSchemaValidateDoc(ctxt
, doc
);
834 if (xmlStrEqual(validity
, BAD_CAST
"valid")) {
836 test_log("valid instance %s failed to validate against %s\n",
839 } else if (ret
< 0) {
840 test_log("valid instance %s got internal error validating %s\n",
845 } else if (xmlStrEqual(validity
, BAD_CAST
"invalid")) {
847 test_log("Failed to detect invalid instance %s against %s\n",
852 test_log("instanceDocument line %ld has unexpected validity value%s\n",
853 xmlGetLineNo(cur
), validity
);
859 if (href
!= NULL
) xmlFree(href
);
860 if (path
!= NULL
) xmlFree(path
);
861 if (validity
!= NULL
) xmlFree(validity
);
862 if (ctxt
!= NULL
) xmlSchemaFreeValidCtxt(ctxt
);
863 if (doc
!= NULL
) xmlFreeDoc(doc
);
865 if (mem
!= xmlMemUsed()) {
866 test_log("Validation of tests starting line %ld leaked %d\n",
867 xmlGetLineNo(cur
), xmlMemUsed() - mem
);
874 xstcTestGroup(xmlNodePtr cur
, const char *base
) {
875 xmlChar
*href
= NULL
;
876 xmlChar
*path
= NULL
;
877 xmlChar
*validity
= NULL
;
878 xmlSchemaPtr schemas
= NULL
;
879 xmlSchemaParserCtxtPtr ctxt
;
884 testErrorsSize
= 0; testErrors
[0] = 0;
886 href
= getString(cur
,
887 "string(ts:schemaTest/ts:schemaDocument/@xlink:href)");
888 if ((href
== NULL
) || (href
[0] == 0)) {
889 test_log("testGroup line %ld misses href for schemaDocument\n",
894 path
= xmlBuildURI(href
, BAD_CAST base
);
896 test_log("Failed to build path to schemas testGroup line %ld : %s\n",
897 xmlGetLineNo(cur
), href
);
901 if (checkTestFile((const char *) path
) <= 0) {
902 test_log("schemas for testGroup line %ld is missing: %s\n",
903 xmlGetLineNo(cur
), path
);
907 validity
= getString(cur
,
908 "string(ts:schemaTest/ts:expected/@validity)");
909 if (validity
== NULL
) {
910 test_log("testGroup line %ld misses expected validity\n",
916 if (xmlStrEqual(validity
, BAD_CAST
"valid")) {
918 ctxt
= xmlSchemaNewParserCtxt((const char *) path
);
919 xmlSchemaSetParserErrors(ctxt
,
920 (xmlSchemaValidityErrorFunc
) testErrorHandler
,
921 (xmlSchemaValidityWarningFunc
) testErrorHandler
,
923 schemas
= xmlSchemaParse(ctxt
);
924 xmlSchemaFreeParserCtxt(ctxt
);
925 if (schemas
== NULL
) {
926 test_log("valid schemas %s failed to parse\n",
931 if ((ret
== 0) && (strstr(testErrors
, "nimplemented") != NULL
)) {
932 test_log("valid schemas %s hit an unimplemented block\n",
938 instance
= getNext(cur
, "./ts:instanceTest[1]");
939 while (instance
!= NULL
) {
940 if (schemas
!= NULL
) {
941 xstcTestInstance(instance
, schemas
, path
, base
);
944 * We'll automatically mark the instances as failed
945 * if the schema was broken.
949 instance
= getNext(instance
,
950 "following-sibling::ts:instanceTest[1]");
952 } else if (xmlStrEqual(validity
, BAD_CAST
"invalid")) {
954 ctxt
= xmlSchemaNewParserCtxt((const char *) path
);
955 xmlSchemaSetParserErrors(ctxt
,
956 (xmlSchemaValidityErrorFunc
) testErrorHandler
,
957 (xmlSchemaValidityWarningFunc
) testErrorHandler
,
959 schemas
= xmlSchemaParse(ctxt
);
960 xmlSchemaFreeParserCtxt(ctxt
);
961 if (schemas
!= NULL
) {
962 test_log("Failed to detect error in schemas %s\n",
967 if ((ret
== 0) && (strstr(testErrors
, "nimplemented") != NULL
)) {
969 test_log("invalid schemas %s hit an unimplemented block\n",
975 test_log("testGroup line %ld misses unexpected validity value%s\n",
976 xmlGetLineNo(cur
), validity
);
982 if (href
!= NULL
) xmlFree(href
);
983 if (path
!= NULL
) xmlFree(path
);
984 if (validity
!= NULL
) xmlFree(validity
);
985 if (schemas
!= NULL
) xmlSchemaFree(schemas
);
987 if ((mem
!= xmlMemUsed()) && (extraMemoryFromResolver
== 0)) {
988 test_log("Processing test line %ld %s leaked %d\n",
989 xmlGetLineNo(cur
), path
, xmlMemUsed() - mem
);
996 xstcMetadata(const char *metadata
, const char *base
) {
999 xmlChar
*contributor
;
1003 doc
= xmlReadFile(metadata
, NULL
, XML_PARSE_NOENT
);
1005 fprintf(stderr
, "Failed to parse %s\n", metadata
);
1009 cur
= xmlDocGetRootElement(doc
);
1010 if ((cur
== NULL
) || (!xmlStrEqual(cur
->name
, BAD_CAST
"testSet"))) {
1011 fprintf(stderr
, "Unexpected format %s\n", metadata
);
1014 contributor
= xmlGetProp(cur
, BAD_CAST
"contributor");
1015 if (contributor
== NULL
) {
1016 contributor
= xmlStrdup(BAD_CAST
"Unknown");
1018 name
= xmlGetProp(cur
, BAD_CAST
"name");
1020 name
= xmlStrdup(BAD_CAST
"Unknown");
1022 printf("## %s test suite for Schemas version %s\n", contributor
, name
);
1023 xmlFree(contributor
);
1026 cur
= getNext(cur
, "./ts:testGroup[1]");
1027 if ((cur
== NULL
) || (!xmlStrEqual(cur
->name
, BAD_CAST
"testGroup"))) {
1028 fprintf(stderr
, "Unexpected format %s\n", metadata
);
1032 while (cur
!= NULL
) {
1033 xstcTestGroup(cur
, base
);
1034 cur
= getNext(cur
, "following-sibling::ts:testGroup[1]");
1042 /************************************************************************
1044 * The driver for the tests *
1046 ************************************************************************/
1049 main(int argc ATTRIBUTE_UNUSED
, char **argv ATTRIBUTE_UNUSED
) {
1051 int old_errors
, old_tests
, old_leaks
;
1053 logfile
= fopen(LOGFILE
, "w");
1054 if (logfile
== NULL
) {
1056 "Could not open the log file, running in verbose mode\n");
1059 initializeLibxml2();
1061 if ((argc
>= 2) && (!strcmp(argv
[1], "-v")))
1065 old_errors
= nb_errors
;
1066 old_tests
= nb_tests
;
1067 old_leaks
= nb_leaks
;
1069 if ((nb_errors
== old_errors
) && (nb_leaks
== old_leaks
))
1070 printf("Ran %d tests, no errors\n", nb_tests
- old_tests
);
1072 printf("Ran %d tests, %d errors, %d leaks\n",
1073 nb_tests
- old_tests
,
1074 nb_errors
- old_errors
,
1075 nb_leaks
- old_leaks
);
1076 old_errors
= nb_errors
;
1077 old_tests
= nb_tests
;
1078 old_leaks
= nb_leaks
;
1080 if ((nb_errors
== old_errors
) && (nb_leaks
== old_leaks
))
1081 printf("Ran %d tests, no errors\n", nb_tests
- old_tests
);
1083 printf("Ran %d tests, %d errors, %d leaks\n",
1084 nb_tests
- old_tests
,
1085 nb_errors
- old_errors
,
1086 nb_leaks
- old_leaks
);
1087 old_errors
= nb_errors
;
1088 old_tests
= nb_tests
;
1089 old_leaks
= nb_leaks
;
1091 if ((nb_errors
== old_errors
) && (nb_leaks
== old_leaks
))
1092 printf("Ran %d tests, no errors\n", nb_tests
- old_tests
);
1094 printf("Ran %d tests, %d errors, %d leaks\n",
1095 nb_tests
- old_tests
,
1096 nb_errors
- old_errors
,
1097 nb_leaks
- old_leaks
);
1098 old_errors
= nb_errors
;
1099 old_tests
= nb_tests
;
1100 old_leaks
= nb_leaks
;
1103 xstcMetadata("xstc/Tests/Metadata/NISTXMLSchemaDatatypes.testSet",
1104 "xstc/Tests/Metadata/");
1105 if ((nb_errors
== old_errors
) && (nb_leaks
== old_leaks
))
1106 printf("Ran %d tests (%d schemata), no errors\n",
1107 nb_tests
- old_tests
, nb_schematas
);
1109 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
1110 nb_tests
- old_tests
,
1112 nb_errors
- old_errors
,
1114 nb_leaks
- old_leaks
);
1115 old_errors
= nb_errors
;
1116 old_tests
= nb_tests
;
1117 old_leaks
= nb_leaks
;
1120 xstcMetadata("xstc/Tests/Metadata/SunXMLSchema1-0-20020116.testSet",
1122 if ((nb_errors
== old_errors
) && (nb_leaks
== old_leaks
))
1123 printf("Ran %d tests (%d schemata), no errors\n",
1124 nb_tests
- old_tests
, nb_schematas
);
1126 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
1127 nb_tests
- old_tests
,
1129 nb_errors
- old_errors
,
1131 nb_leaks
- old_leaks
);
1132 old_errors
= nb_errors
;
1133 old_tests
= nb_tests
;
1134 old_leaks
= nb_leaks
;
1137 xstcMetadata("xstc/Tests/Metadata/MSXMLSchema1-0-20020116.testSet",
1139 if ((nb_errors
== old_errors
) && (nb_leaks
== old_leaks
))
1140 printf("Ran %d tests (%d schemata), no errors\n",
1141 nb_tests
- old_tests
, nb_schematas
);
1143 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
1144 nb_tests
- old_tests
,
1146 nb_errors
- old_errors
,
1148 nb_leaks
- old_leaks
);
1150 if ((nb_errors
== 0) && (nb_leaks
== 0)) {
1152 printf("Total %d tests, no errors\n",
1156 printf("Total %d tests, %d errors, %d leaks\n",
1157 nb_tests
, nb_errors
, nb_leaks
);
1159 xmlXPathFreeContext(ctxtXPath
);
1163 if (logfile
!= NULL
)
1167 #else /* !SCHEMAS */
1169 main(int argc ATTRIBUTE_UNUSED
, char **argv ATTRIBUTE_UNUSED
) {
1170 fprintf(stderr
, "runsuite requires support for schemas and xpath in libxml2\n");