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");