blob: 9905feba078377741dd8bcddf31864cb6e0f3b3f [file] [log] [blame]
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001/*
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00002 * runsuite.c: C program to run libxml2 againts published testsuites
Daniel Veillardf2e066a2005-06-30 13:04:44 +00003 *
4 * See Copyright for the status of this software.
5 *
6 * daniel@veillard.com
7 */
8
Daniel Veillardf93a67e2005-10-28 16:37:05 +00009#ifdef HAVE_CONFIG_H
10#include "libxml.h"
11#else
12#include <stdio.h>
13#endif
14
Daniel Veillardc9352532005-07-04 14:25:34 +000015#if !defined(_WIN32) || defined(__CYGWIN__)
Daniel Veillardf2e066a2005-06-30 13:04:44 +000016#include <unistd.h>
Daniel Veillardc9352532005-07-04 14:25:34 +000017#endif
Daniel Veillardf2e066a2005-06-30 13:04:44 +000018#include <string.h>
Daniel Veillardf2e066a2005-06-30 13:04:44 +000019#include <sys/types.h>
20#include <sys/stat.h>
21#include <fcntl.h>
Daniel Veillardf2e066a2005-06-30 13:04:44 +000022
23#include <libxml/parser.h>
Daniel Veillarde84f2312005-07-02 07:31:28 +000024#include <libxml/parserInternals.h>
Daniel Veillardf2e066a2005-06-30 13:04:44 +000025#include <libxml/tree.h>
26#include <libxml/uri.h>
Daniel Veillard95175012005-07-03 16:09:51 +000027#if defined(LIBXML_SCHEMAS_ENABLED) && defined(LIBXML_XPATH_ENABLED)
Daniel Veillardf2e066a2005-06-30 13:04:44 +000028#include <libxml/xmlreader.h>
29
30#include <libxml/xpath.h>
31#include <libxml/xpathInternals.h>
32
33#include <libxml/relaxng.h>
34#include <libxml/xmlschemas.h>
35#include <libxml/xmlschemastypes.h>
36
Daniel Veillardc9352532005-07-04 14:25:34 +000037#define LOGFILE "runsuite.log"
Daniel Veillard24505b02005-07-28 23:49:35 +000038static FILE *logfile = NULL;
Kasimier T. Buchcikdcac4fc2005-12-09 10:03:27 +000039static int verbose = 0;
40
41
42
43#if defined(_WIN32) && !defined(__CYGWIN__)
44
45#define vsnprintf _vsnprintf
46
47#define snprintf _snprintf
48
Kasimier T. Buchcik87db1cf2005-07-05 10:40:52 +000049#endif
Daniel Veillardc9352532005-07-04 14:25:34 +000050
Daniel Veillardf2e066a2005-06-30 13:04:44 +000051/************************************************************************
52 * *
53 * File name and path utilities *
54 * *
55 ************************************************************************/
56
57static int checkTestFile(const char *filename) {
58 struct stat buf;
59
60 if (stat(filename, &buf) == -1)
61 return(0);
62
Daniel Veillardcfbb0dd2005-07-04 17:12:01 +000063#if defined(_WIN32) && !defined(__CYGWIN__)
64 if (!(buf.st_mode & _S_IFREG))
65 return(0);
66#else
Daniel Veillardf2e066a2005-06-30 13:04:44 +000067 if (!S_ISREG(buf.st_mode))
68 return(0);
Daniel Veillardcfbb0dd2005-07-04 17:12:01 +000069#endif
Daniel Veillardf2e066a2005-06-30 13:04:44 +000070
71 return(1);
72}
Daniel Veillardcfbb0dd2005-07-04 17:12:01 +000073
Daniel Veillarde84f2312005-07-02 07:31:28 +000074static xmlChar *composeDir(const xmlChar *dir, const xmlChar *path) {
75 char buf[500];
76
77 if (dir == NULL) return(xmlStrdup(path));
78 if (path == NULL) return(NULL);
79
80 snprintf(buf, 500, "%s/%s", (const char *) dir, (const char *) path);
81 return(xmlStrdup((const xmlChar *) buf));
82}
Daniel Veillardf2e066a2005-06-30 13:04:44 +000083
84/************************************************************************
85 * *
86 * Libxml2 specific routines *
87 * *
88 ************************************************************************/
89
90static int nb_tests = 0;
91static int nb_errors = 0;
Daniel Veillardc9352532005-07-04 14:25:34 +000092static int nb_internals = 0;
93static int nb_schematas = 0;
Daniel Veillard90837782005-07-04 15:45:10 +000094static int nb_unimplemented = 0;
Daniel Veillardf2e066a2005-06-30 13:04:44 +000095static int nb_leaks = 0;
Daniel Veillardf2e066a2005-06-30 13:04:44 +000096static int extraMemoryFromResolver = 0;
97
98static int
99fatalError(void) {
100 fprintf(stderr, "Exitting tests on fatal error\n");
101 exit(1);
102}
103
104/*
Daniel Veillarde84f2312005-07-02 07:31:28 +0000105 * that's needed to implement <resource>
106 */
107#define MAX_ENTITIES 20
Daniel Veillard24505b02005-07-28 23:49:35 +0000108static char *testEntitiesName[MAX_ENTITIES];
109static char *testEntitiesValue[MAX_ENTITIES];
110static int nb_entities = 0;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000111static void resetEntities(void) {
112 int i;
113
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]);
119 }
120 nb_entities = 0;
121}
122static int addEntity(char *name, char *content) {
123 if (nb_entities >= MAX_ENTITIES) {
124 fprintf(stderr, "Too many entities defined\n");
125 return(-1);
126 }
127 testEntitiesName[nb_entities] = name;
128 testEntitiesValue[nb_entities] = content;
129 nb_entities++;
130 return(0);
131}
132
133/*
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000134 * 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.
137 */
138static xmlParserInputPtr
139testExternalEntityLoader(const char *URL, const char *ID,
140 xmlParserCtxtPtr ctxt) {
141 xmlParserInputPtr ret;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000142 int i;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000143
Daniel Veillarde84f2312005-07-02 07:31:28 +0000144 for (i = 0;i < nb_entities;i++) {
145 if (!strcmp(testEntitiesName[i], URL)) {
146 ret = xmlNewStringInputStream(ctxt,
147 (const xmlChar *) testEntitiesValue[i]);
148 if (ret != NULL) {
149 ret->filename = (const char *)
150 xmlStrdup((xmlChar *)testEntitiesName[i]);
151 }
152 return(ret);
153 }
154 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000155 if (checkTestFile(URL)) {
156 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
157 } else {
158 int memused = xmlMemUsed();
159 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
160 extraMemoryFromResolver += xmlMemUsed() - memused;
161 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000162#if 0
Daniel Veillarde84f2312005-07-02 07:31:28 +0000163 if (ret == NULL) {
164 fprintf(stderr, "Failed to find resource %s\n", URL);
165 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000166#endif
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000167
168 return(ret);
169}
170
171/*
172 * Trapping the error messages at the generic level to grab the equivalent of
173 * stderr messages on CLI tools.
174 */
175static char testErrors[32769];
176static int testErrorsSize = 0;
177
Daniel Veillardc9352532005-07-04 14:25:34 +0000178static void test_log(const char *msg, ...) {
179 va_list args;
180 if (logfile != NULL) {
181 fprintf(logfile, "\n------------\n");
182 va_start(args, msg);
183 vfprintf(logfile, msg, args);
184 va_end(args);
185 fprintf(logfile, "%s", testErrors);
186 testErrorsSize = 0; testErrors[0] = 0;
187 }
188 if (verbose) {
189 va_start(args, msg);
190 vfprintf(stderr, msg, args);
191 va_end(args);
192 }
193}
194
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000195static void
196testErrorHandler(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
197 va_list args;
198 int res;
199
200 if (testErrorsSize >= 32768)
201 return;
202 va_start(args, msg);
203 res = vsnprintf(&testErrors[testErrorsSize],
204 32768 - testErrorsSize,
205 msg, args);
206 va_end(args);
207 if (testErrorsSize + res >= 32768) {
208 /* buffer is full */
209 testErrorsSize = 32768;
210 testErrors[testErrorsSize] = 0;
211 } else {
212 testErrorsSize += res;
213 }
214 testErrors[testErrorsSize] = 0;
215}
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000216
Daniel Veillard24505b02005-07-28 23:49:35 +0000217static xmlXPathContextPtr ctxtXPath;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000218
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000219static void
220initializeLibxml2(void) {
221 xmlGetWarningsDefaultValue = 0;
222 xmlPedanticParserDefault(0);
223
224 xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
225 xmlInitParser();
226 xmlSetExternalEntityLoader(testExternalEntityLoader);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000227 ctxtXPath = xmlXPathNewContext(NULL);
Kasimier T. Buchcika7248442006-05-29 16:15:36 +0000228 /*
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 xmlXPathContextSetObjectCache();
233 * but for test purposes it is sometimes usefull to activate the
234 * cache by default for the whole library.
235 */
236 if (ctxtXPath->objCache != NULL)
237 xmlXPathContextSetObjectCache(ctxtXPath, 0, -1, 0);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000238 /* 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);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000243#ifdef LIBXML_SCHEMAS_ENABLED
244 xmlSchemaInitTypes();
245 xmlRelaxNGInitTypes();
246#endif
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000247}
248
249static xmlNodePtr
250getNext(xmlNodePtr cur, const char *xpath) {
251 xmlNodePtr ret = NULL;
252 xmlXPathObjectPtr res;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000253 xmlXPathCompExprPtr comp;
254
255 if ((cur == NULL) || (cur->doc == NULL) || (xpath == NULL))
256 return(NULL);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000257 ctxtXPath->doc = cur->doc;
258 ctxtXPath->node = cur;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000259 comp = xmlXPathCompile(BAD_CAST xpath);
260 if (comp == NULL) {
261 fprintf(stderr, "Failed to compile %s\n", xpath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000262 return(NULL);
263 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000264 res = xmlXPathCompiledEval(comp, ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000265 xmlXPathFreeCompExpr(comp);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000266 if (res == NULL)
267 return(NULL);
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);
274 return(ret);
275}
276
277static xmlChar *
278getString(xmlNodePtr cur, const char *xpath) {
279 xmlChar *ret = NULL;
280 xmlXPathObjectPtr res;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000281 xmlXPathCompExprPtr comp;
282
283 if ((cur == NULL) || (cur->doc == NULL) || (xpath == NULL))
284 return(NULL);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000285 ctxtXPath->doc = cur->doc;
286 ctxtXPath->node = cur;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000287 comp = xmlXPathCompile(BAD_CAST xpath);
288 if (comp == NULL) {
289 fprintf(stderr, "Failed to compile %s\n", xpath);
290 return(NULL);
291 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000292 res = xmlXPathCompiledEval(comp, ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000293 xmlXPathFreeCompExpr(comp);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000294 if (res == NULL)
295 return(NULL);
296 if (res->type == XPATH_STRING) {
297 ret = res->stringval;
298 res->stringval = NULL;
299 }
300 xmlXPathFreeObject(res);
301 return(ret);
302}
303
304/************************************************************************
305 * *
306 * Test test/xsdtest/xsdtestsuite.xml *
307 * *
308 ************************************************************************/
309
310static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000311xsdIncorectTestCase(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000312 xmlNodePtr test;
313 xmlBufferPtr buf;
314 xmlRelaxNGParserCtxtPtr pctxt;
315 xmlRelaxNGPtr rng = NULL;
316 int ret = 0, memt;
317
318 cur = getNext(cur, "./incorrect[1]");
319 if (cur == NULL) {
320 return(0);
321 }
322
323 test = getNext(cur, "./*");
324 if (test == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000325 test_log("Failed to find test in correct line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000326 xmlGetLineNo(cur));
327 return(1);
328 }
329
330 memt = xmlMemUsed();
331 extraMemoryFromResolver = 0;
332 /*
333 * dump the schemas to a buffer, then reparse it and compile the schemas
334 */
335 buf = xmlBufferCreate();
336 if (buf == NULL) {
337 fprintf(stderr, "out of memory !\n");
338 fatalError();
339 }
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,
345 pctxt);
346 rng = xmlRelaxNGParse(pctxt);
347 xmlRelaxNGFreeParserCtxt(pctxt);
348 if (rng != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000349 test_log("Failed to detect incorect RNG line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000350 xmlGetLineNo(test));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000351 ret = 1;
352 goto done;
353 }
354
355done:
356 if (buf != NULL)
357 xmlBufferFree(buf);
358 if (rng != NULL)
359 xmlRelaxNGFree(rng);
360 xmlResetLastError();
361 if ((memt != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000362 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000363 xmlGetLineNo(cur), xmlMemUsed() - memt);
364 nb_leaks++;
365 }
366 return(ret);
367}
368
Daniel Veillarde84f2312005-07-02 07:31:28 +0000369static void
370installResources(xmlNodePtr tst, const xmlChar *base) {
371 xmlNodePtr test;
372 xmlBufferPtr buf;
373 xmlChar *name, *content, *res;
Daniel Veillardc9352532005-07-04 14:25:34 +0000374
Daniel Veillarde84f2312005-07-02 07:31:28 +0000375 buf = xmlBufferCreate();
376 if (buf == NULL) {
377 fprintf(stderr, "out of memory !\n");
378 fatalError();
379 }
380 xmlNodeDump(buf, tst->doc, tst, 0, 0);
381
382 while (tst != NULL) {
383 test = getNext(tst, "./*");
384 if (test != NULL) {
385 xmlBufferEmpty(buf);
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);
391 xmlFree(name);
392 addEntity((char *) res, (char *) content);
393 } else {
394 if (name != NULL) xmlFree(name);
395 if (content != NULL) xmlFree(content);
396 }
397 }
398 tst = getNext(tst, "following-sibling::resource[1]");
399 }
400 if (buf != NULL)
401 xmlBufferFree(buf);
402}
403
404static void
405installDirs(xmlNodePtr tst, const xmlChar *base) {
406 xmlNodePtr test;
407 xmlChar *name, *res;
408
409 name = getString(tst, "string(@name)");
410 if (name == NULL)
411 return;
412 res = composeDir(base, name);
413 xmlFree(name);
414 if (res == NULL) {
415 return;
416 }
417 /* Now process resources and subdir recursively */
418 test = getNext(tst, "./resource[1]");
419 if (test != NULL) {
420 installResources(test, res);
421 }
422 test = getNext(tst, "./dir[1]");
423 while (test != NULL) {
424 installDirs(test, res);
425 test = getNext(test, "following-sibling::dir[1]");
426 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000427 xmlFree(res);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000428}
429
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000430static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000431xsdTestCase(xmlNodePtr tst) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000432 xmlNodePtr test, tmp, cur;
433 xmlBufferPtr buf;
434 xmlDocPtr doc = NULL;
435 xmlRelaxNGParserCtxtPtr pctxt;
436 xmlRelaxNGValidCtxtPtr ctxt;
437 xmlRelaxNGPtr rng = NULL;
438 int ret = 0, mem, memt;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000439 xmlChar *dtd;
440
441 resetEntities();
Daniel Veillardc9352532005-07-04 14:25:34 +0000442 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000443
444 tmp = getNext(tst, "./dir[1]");
445 if (tmp != NULL) {
446 installDirs(tmp, NULL);
447 }
448 tmp = getNext(tst, "./resource[1]");
449 if (tmp != NULL) {
450 installResources(tmp, NULL);
451 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000452
453 cur = getNext(tst, "./correct[1]");
454 if (cur == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000455 return(xsdIncorectTestCase(tst));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000456 }
457
458 test = getNext(cur, "./*");
459 if (test == NULL) {
460 fprintf(stderr, "Failed to find test in correct line %ld\n",
461 xmlGetLineNo(cur));
462 return(1);
463 }
464
465 memt = xmlMemUsed();
466 extraMemoryFromResolver = 0;
467 /*
468 * dump the schemas to a buffer, then reparse it and compile the schemas
469 */
470 buf = xmlBufferCreate();
471 if (buf == NULL) {
472 fprintf(stderr, "out of memory !\n");
473 fatalError();
474 }
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,
480 pctxt);
481 rng = xmlRelaxNGParse(pctxt);
482 xmlRelaxNGFreeParserCtxt(pctxt);
483 if (extraMemoryFromResolver)
484 memt = 0;
485
486 if (rng == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000487 test_log("Failed to parse RNGtest line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000488 xmlGetLineNo(test));
489 nb_errors++;
490 ret = 1;
491 goto done;
492 }
493 /*
494 * now scan all the siblings of correct to process the <valid> tests
495 */
496 tmp = getNext(cur, "following-sibling::valid[1]");
497 while (tmp != NULL) {
Daniel Veillarde84f2312005-07-02 07:31:28 +0000498 dtd = xmlGetProp(tmp, BAD_CAST "dtd");
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000499 test = getNext(tmp, "./*");
500 if (test == NULL) {
501 fprintf(stderr, "Failed to find test in <valid> line %ld\n",
502 xmlGetLineNo(tmp));
503
504 } else {
505 xmlBufferEmpty(buf);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000506 if (dtd != NULL)
507 xmlBufferAdd(buf, dtd, -1);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000508 xmlNodeDump(buf, test->doc, test, 0, 0);
509
510 /*
511 * We are ready to run the test
512 */
513 mem = xmlMemUsed();
514 extraMemoryFromResolver = 0;
515 doc = xmlReadMemory((const char *)buf->content, buf->use,
516 "test", NULL, 0);
517 if (doc == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000518 test_log("Failed to parse valid instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000519 xmlGetLineNo(tmp));
520 nb_errors++;
521 } else {
522 nb_tests++;
523 ctxt = xmlRelaxNGNewValidCtxt(rng);
524 xmlRelaxNGSetValidErrors(ctxt,
525 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
526 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
527 ctxt);
528 ret = xmlRelaxNGValidateDoc(ctxt, doc);
529 xmlRelaxNGFreeValidCtxt(ctxt);
530 if (ret > 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000531 test_log("Failed to validate valid instance line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000532 xmlGetLineNo(tmp));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000533 nb_errors++;
534 } else if (ret < 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000535 test_log("Internal error validating instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000536 xmlGetLineNo(tmp));
537 nb_errors++;
538 }
539 xmlFreeDoc(doc);
540 }
541 xmlResetLastError();
542 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000543 test_log("Validation of instance line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000544 xmlGetLineNo(tmp), xmlMemUsed() - mem);
545 xmlMemoryDump();
546 nb_leaks++;
547 }
548 }
Daniel Veillarde84f2312005-07-02 07:31:28 +0000549 if (dtd != NULL)
550 xmlFree(dtd);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000551 tmp = getNext(tmp, "following-sibling::valid[1]");
552 }
553 /*
554 * now scan all the siblings of correct to process the <invalid> tests
555 */
556 tmp = getNext(cur, "following-sibling::invalid[1]");
557 while (tmp != NULL) {
558 test = getNext(tmp, "./*");
559 if (test == NULL) {
560 fprintf(stderr, "Failed to find test in <invalid> line %ld\n",
561 xmlGetLineNo(tmp));
562
563 } else {
564 xmlBufferEmpty(buf);
565 xmlNodeDump(buf, test->doc, test, 0, 0);
566
567 /*
568 * We are ready to run the test
569 */
570 mem = xmlMemUsed();
571 extraMemoryFromResolver = 0;
572 doc = xmlReadMemory((const char *)buf->content, buf->use,
573 "test", NULL, 0);
574 if (doc == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000575 test_log("Failed to parse valid instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000576 xmlGetLineNo(tmp));
577 nb_errors++;
578 } else {
579 nb_tests++;
580 ctxt = xmlRelaxNGNewValidCtxt(rng);
581 xmlRelaxNGSetValidErrors(ctxt,
582 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
583 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
584 ctxt);
585 ret = xmlRelaxNGValidateDoc(ctxt, doc);
586 xmlRelaxNGFreeValidCtxt(ctxt);
587 if (ret == 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000588 test_log("Failed to detect invalid instance line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000589 xmlGetLineNo(tmp));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000590 nb_errors++;
591 } else if (ret < 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000592 test_log("Internal error validating instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000593 xmlGetLineNo(tmp));
594 nb_errors++;
595 }
596 xmlFreeDoc(doc);
597 }
598 xmlResetLastError();
599 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000600 test_log("Validation of instance line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000601 xmlGetLineNo(tmp), xmlMemUsed() - mem);
602 xmlMemoryDump();
603 nb_leaks++;
604 }
605 }
606 tmp = getNext(tmp, "following-sibling::invalid[1]");
607 }
608
609done:
610 if (buf != NULL)
611 xmlBufferFree(buf);
612 if (rng != NULL)
613 xmlRelaxNGFree(rng);
614 xmlResetLastError();
615 if ((memt != xmlMemUsed()) && (memt != 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000616 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000617 xmlGetLineNo(cur), xmlMemUsed() - memt);
618 nb_leaks++;
619 }
620 return(ret);
621}
622
623static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000624xsdTestSuite(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000625 if (verbose) {
626 xmlChar *doc = getString(cur, "string(documentation)");
627
628 if (doc != NULL) {
629 printf("Suite %s\n", doc);
630 xmlFree(doc);
631 }
632 }
633 cur = getNext(cur, "./testCase[1]");
634 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000635 xsdTestCase(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000636 cur = getNext(cur, "following-sibling::testCase[1]");
637 }
638
639 return(0);
640}
641
642static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000643xsdTest(void) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000644 xmlDocPtr doc;
645 xmlNodePtr cur;
646 const char *filename = "test/xsdtest/xsdtestsuite.xml";
647 int ret = 0;
648
649 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
650 if (doc == NULL) {
651 fprintf(stderr, "Failed to parse %s\n", filename);
652 return(-1);
653 }
654 printf("## XML Schemas datatypes test suite from James Clark\n");
655
656 cur = xmlDocGetRootElement(doc);
657 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
658 fprintf(stderr, "Unexpected format %s\n", filename);
659 ret = -1;
660 goto done;
661 }
662
663 cur = getNext(cur, "./testSuite[1]");
664 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
665 fprintf(stderr, "Unexpected format %s\n", filename);
666 ret = -1;
667 goto done;
668 }
669 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000670 xsdTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000671 cur = getNext(cur, "following-sibling::testSuite[1]");
672 }
673
674done:
675 if (doc != NULL)
676 xmlFreeDoc(doc);
677 return(ret);
678}
679
680static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000681rngTestSuite(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000682 if (verbose) {
683 xmlChar *doc = getString(cur, "string(documentation)");
684
685 if (doc != NULL) {
686 printf("Suite %s\n", doc);
687 xmlFree(doc);
688 } else {
689 doc = getString(cur, "string(section)");
690 if (doc != NULL) {
691 printf("Section %s\n", doc);
692 xmlFree(doc);
693 }
694 }
695 }
696 cur = getNext(cur, "./testSuite[1]");
697 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000698 xsdTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000699 cur = getNext(cur, "following-sibling::testSuite[1]");
700 }
701
702 return(0);
703}
704
705static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000706rngTest1(void) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000707 xmlDocPtr doc;
708 xmlNodePtr cur;
709 const char *filename = "test/relaxng/OASIS/spectest.xml";
710 int ret = 0;
711
712 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
713 if (doc == NULL) {
714 fprintf(stderr, "Failed to parse %s\n", filename);
715 return(-1);
716 }
Daniel Veillarde84f2312005-07-02 07:31:28 +0000717 printf("## Relax NG test suite from James Clark\n");
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000718
719 cur = xmlDocGetRootElement(doc);
720 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
721 fprintf(stderr, "Unexpected format %s\n", filename);
722 ret = -1;
723 goto done;
724 }
725
726 cur = getNext(cur, "./testSuite[1]");
727 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
728 fprintf(stderr, "Unexpected format %s\n", filename);
729 ret = -1;
730 goto done;
731 }
732 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000733 rngTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000734 cur = getNext(cur, "following-sibling::testSuite[1]");
735 }
736
737done:
738 if (doc != NULL)
739 xmlFreeDoc(doc);
740 return(ret);
741}
742
Daniel Veillarde84f2312005-07-02 07:31:28 +0000743static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000744rngTest2(void) {
Daniel Veillarde84f2312005-07-02 07:31:28 +0000745 xmlDocPtr doc;
746 xmlNodePtr cur;
747 const char *filename = "test/relaxng/testsuite.xml";
748 int ret = 0;
749
750 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
751 if (doc == NULL) {
752 fprintf(stderr, "Failed to parse %s\n", filename);
753 return(-1);
754 }
755 printf("## Relax NG test suite for libxml2\n");
756
757 cur = xmlDocGetRootElement(doc);
758 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
759 fprintf(stderr, "Unexpected format %s\n", filename);
760 ret = -1;
761 goto done;
762 }
763
764 cur = getNext(cur, "./testSuite[1]");
765 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
766 fprintf(stderr, "Unexpected format %s\n", filename);
767 ret = -1;
768 goto done;
769 }
770 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000771 xsdTestSuite(cur);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000772 cur = getNext(cur, "following-sibling::testSuite[1]");
773 }
774
775done:
776 if (doc != NULL)
777 xmlFreeDoc(doc);
778 return(ret);
779}
780
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000781/************************************************************************
782 * *
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000783 * Schemas test suites from W3C/NIST/MS/Sun *
784 * *
785 ************************************************************************/
786
787static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000788xstcTestInstance(xmlNodePtr cur, xmlSchemaPtr schemas,
Daniel Veillard6b6d6802005-07-03 21:00:34 +0000789 const xmlChar *spath, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000790 xmlChar *href = NULL;
791 xmlChar *path = NULL;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000792 xmlChar *validity = NULL;
793 xmlSchemaValidCtxtPtr ctxt = NULL;
794 xmlDocPtr doc = NULL;
795 int ret = 0, mem;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000796
Daniel Veillardde0e4982005-07-03 14:35:44 +0000797 xmlResetLastError();
Daniel Veillardc9352532005-07-04 14:25:34 +0000798 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000799 mem = xmlMemUsed();
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000800 href = getString(cur,
Daniel Veillardde0e4982005-07-03 14:35:44 +0000801 "string(ts:instanceDocument/@xlink:href)");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000802 if ((href == NULL) || (href[0] == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000803 test_log("testGroup line %ld misses href for schemaDocument\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000804 xmlGetLineNo(cur));
805 ret = -1;
806 goto done;
807 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000808 path = xmlBuildURI(href, BAD_CAST base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000809 if (path == NULL) {
810 fprintf(stderr,
811 "Failed to build path to schemas testGroup line %ld : %s\n",
812 xmlGetLineNo(cur), href);
813 ret = -1;
814 goto done;
815 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000816 if (checkTestFile((const char *) path) <= 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000817 test_log("schemas for testGroup line %ld is missing: %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000818 xmlGetLineNo(cur), path);
819 ret = -1;
820 goto done;
821 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000822 validity = getString(cur,
823 "string(ts:expected/@validity)");
824 if (validity == NULL) {
825 fprintf(stderr, "instanceDocument line %ld misses expected validity\n",
826 xmlGetLineNo(cur));
827 ret = -1;
828 goto done;
829 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000830 nb_tests++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000831 doc = xmlReadFile((const char *) path, NULL, XML_PARSE_NOENT);
832 if (doc == NULL) {
833 fprintf(stderr, "instance %s fails to parse\n", path);
834 ret = -1;
835 nb_errors++;
836 goto done;
837 }
838
839 ctxt = xmlSchemaNewValidCtxt(schemas);
840 xmlSchemaSetValidErrors(ctxt,
841 (xmlSchemaValidityErrorFunc) testErrorHandler,
842 (xmlSchemaValidityWarningFunc) testErrorHandler,
843 ctxt);
844 ret = xmlSchemaValidateDoc(ctxt, doc);
845
846 if (xmlStrEqual(validity, BAD_CAST "valid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000847 if (ret > 0) {
848 test_log("valid instance %s failed to validate against %s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000849 path, spath);
850 nb_errors++;
Daniel Veillardc9352532005-07-04 14:25:34 +0000851 } else if (ret < 0) {
852 test_log("valid instance %s got internal error validating %s\n",
853 path, spath);
854 nb_internals++;
855 nb_errors++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000856 }
857 } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
858 if (ret == 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000859 test_log("Failed to detect invalid instance %s against %s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000860 path, spath);
861 nb_errors++;
862 }
863 } else {
Daniel Veillardc9352532005-07-04 14:25:34 +0000864 test_log("instanceDocument line %ld has unexpected validity value%s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000865 xmlGetLineNo(cur), validity);
866 ret = -1;
867 goto done;
868 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000869
870done:
871 if (href != NULL) xmlFree(href);
872 if (path != NULL) xmlFree(path);
Daniel Veillardde0e4982005-07-03 14:35:44 +0000873 if (validity != NULL) xmlFree(validity);
874 if (ctxt != NULL) xmlSchemaFreeValidCtxt(ctxt);
875 if (doc != NULL) xmlFreeDoc(doc);
876 xmlResetLastError();
877 if (mem != xmlMemUsed()) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000878 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000879 xmlGetLineNo(cur), xmlMemUsed() - mem);
880 nb_leaks++;
881 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000882 return(ret);
883}
Daniel Veillardde0e4982005-07-03 14:35:44 +0000884
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000885static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000886xstcTestGroup(xmlNodePtr cur, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000887 xmlChar *href = NULL;
888 xmlChar *path = NULL;
889 xmlChar *validity = NULL;
890 xmlSchemaPtr schemas = NULL;
891 xmlSchemaParserCtxtPtr ctxt;
892 xmlNodePtr instance;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000893 int ret = 0, mem;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000894
Daniel Veillardde0e4982005-07-03 14:35:44 +0000895 xmlResetLastError();
Daniel Veillardc9352532005-07-04 14:25:34 +0000896 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000897 mem = xmlMemUsed();
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000898 href = getString(cur,
899 "string(ts:schemaTest/ts:schemaDocument/@xlink:href)");
900 if ((href == NULL) || (href[0] == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000901 test_log("testGroup line %ld misses href for schemaDocument\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000902 xmlGetLineNo(cur));
903 ret = -1;
904 goto done;
905 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000906 path = xmlBuildURI(href, BAD_CAST base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000907 if (path == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000908 test_log("Failed to build path to schemas testGroup line %ld : %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000909 xmlGetLineNo(cur), href);
910 ret = -1;
911 goto done;
912 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000913 if (checkTestFile((const char *) path) <= 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000914 test_log("schemas for testGroup line %ld is missing: %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000915 xmlGetLineNo(cur), path);
916 ret = -1;
917 goto done;
918 }
919 validity = getString(cur,
920 "string(ts:schemaTest/ts:expected/@validity)");
921 if (validity == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000922 test_log("testGroup line %ld misses expected validity\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000923 xmlGetLineNo(cur));
924 ret = -1;
925 goto done;
926 }
Daniel Veillardc9352532005-07-04 14:25:34 +0000927 nb_tests++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000928 if (xmlStrEqual(validity, BAD_CAST "valid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000929 nb_schematas++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000930 ctxt = xmlSchemaNewParserCtxt((const char *) path);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000931 xmlSchemaSetParserErrors(ctxt,
932 (xmlSchemaValidityErrorFunc) testErrorHandler,
933 (xmlSchemaValidityWarningFunc) testErrorHandler,
934 ctxt);
935 schemas = xmlSchemaParse(ctxt);
936 xmlSchemaFreeParserCtxt(ctxt);
937 if (schemas == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000938 test_log("valid schemas %s failed to parse\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000939 path);
Daniel Veillard90837782005-07-04 15:45:10 +0000940 ret = 1;
941 nb_errors++;
942 }
943 if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
944 test_log("valid schemas %s hit an unimplemented block\n",
945 path);
946 ret = 1;
947 nb_unimplemented++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000948 nb_errors++;
949 }
950 instance = getNext(cur, "./ts:instanceTest[1]");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000951 while (instance != NULL) {
Kasimier T. Buchcikdcac4fc2005-12-09 10:03:27 +0000952 if (schemas != NULL) {
953 xstcTestInstance(instance, schemas, path, base);
954 } else {
955 /*
956 * We'll automatically mark the instances as failed
957 * if the schema was broken.
958 */
959 nb_errors++;
960 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000961 instance = getNext(instance,
Kasimier T. Buchcikdcac4fc2005-12-09 10:03:27 +0000962 "following-sibling::ts:instanceTest[1]");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000963 }
964 } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000965 nb_schematas++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000966 ctxt = xmlSchemaNewParserCtxt((const char *) path);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000967 xmlSchemaSetParserErrors(ctxt,
968 (xmlSchemaValidityErrorFunc) testErrorHandler,
969 (xmlSchemaValidityWarningFunc) testErrorHandler,
970 ctxt);
971 schemas = xmlSchemaParse(ctxt);
972 xmlSchemaFreeParserCtxt(ctxt);
Daniel Veillard4ac5f9a2005-07-04 15:20:27 +0000973 if (schemas != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000974 test_log("Failed to detect error in schemas %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000975 path);
976 nb_errors++;
Daniel Veillard90837782005-07-04 15:45:10 +0000977 ret = 1;
978 }
979 if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
980 nb_unimplemented++;
981 test_log("invalid schemas %s hit an unimplemented block\n",
982 path);
983 ret = 1;
984 nb_errors++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000985 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000986 } else {
Daniel Veillardc9352532005-07-04 14:25:34 +0000987 test_log("testGroup line %ld misses unexpected validity value%s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000988 xmlGetLineNo(cur), validity);
989 ret = -1;
990 goto done;
991 }
992
993done:
994 if (href != NULL) xmlFree(href);
995 if (path != NULL) xmlFree(path);
996 if (validity != NULL) xmlFree(validity);
997 if (schemas != NULL) xmlSchemaFree(schemas);
Daniel Veillardde0e4982005-07-03 14:35:44 +0000998 xmlResetLastError();
999 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +00001000 test_log("Processing test line %ld %s leaked %d\n",
1001 xmlGetLineNo(cur), path, xmlMemUsed() - mem);
Daniel Veillardde0e4982005-07-03 14:35:44 +00001002 nb_leaks++;
1003 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001004 return(ret);
1005}
1006
1007static int
Daniel Veillardc9352532005-07-04 14:25:34 +00001008xstcMetadata(const char *metadata, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001009 xmlDocPtr doc;
1010 xmlNodePtr cur;
1011 xmlChar *contributor;
1012 xmlChar *name;
Daniel Veillard6b6d6802005-07-03 21:00:34 +00001013 int ret = 0;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001014
1015 doc = xmlReadFile(metadata, NULL, XML_PARSE_NOENT);
1016 if (doc == NULL) {
1017 fprintf(stderr, "Failed to parse %s\n", metadata);
1018 return(-1);
1019 }
1020
1021 cur = xmlDocGetRootElement(doc);
1022 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSet"))) {
1023 fprintf(stderr, "Unexpected format %s\n", metadata);
1024 return(-1);
1025 }
1026 contributor = xmlGetProp(cur, BAD_CAST "contributor");
1027 if (contributor == NULL) {
1028 contributor = xmlStrdup(BAD_CAST "Unknown");
1029 }
1030 name = xmlGetProp(cur, BAD_CAST "name");
1031 if (name == NULL) {
1032 name = xmlStrdup(BAD_CAST "Unknown");
1033 }
1034 printf("## %s test suite for Schemas version %s\n", contributor, name);
1035 xmlFree(contributor);
1036 xmlFree(name);
1037
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);
1041 ret = -1;
1042 goto done;
1043 }
1044 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +00001045 xstcTestGroup(cur, base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001046 cur = getNext(cur, "following-sibling::ts:testGroup[1]");
1047 }
1048
1049done:
1050 xmlFreeDoc(doc);
1051 return(ret);
1052}
1053
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001054/************************************************************************
1055 * *
1056 * The driver for the tests *
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001057 * *
1058 ************************************************************************/
1059
1060int
1061main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001062 int ret = 0;
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001063 int old_errors, old_tests, old_leaks;
1064
Daniel Veillardc9352532005-07-04 14:25:34 +00001065 logfile = fopen(LOGFILE, "w");
1066 if (logfile == NULL) {
1067 fprintf(stderr,
1068 "Could not open the log file, running in verbose mode\n");
1069 verbose = 1;
1070 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001071 initializeLibxml2();
1072
1073 if ((argc >= 2) && (!strcmp(argv[1], "-v")))
1074 verbose = 1;
1075
1076
Daniel Veillarde84f2312005-07-02 07:31:28 +00001077 old_errors = nb_errors;
1078 old_tests = nb_tests;
1079 old_leaks = nb_leaks;
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001080 xsdTest();
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001081 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1082 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1083 else
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;
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001091 rngTest1();
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001092 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1093 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1094 else
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;
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001102 rngTest2();
Daniel Veillarde84f2312005-07-02 07:31:28 +00001103 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1104 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1105 else
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;
Daniel Veillardc9352532005-07-04 14:25:34 +00001113 nb_internals = 0;
1114 nb_schematas = 0;
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001115 xstcMetadata("xstc/Tests/Metadata/NISTXMLSchemaDatatypes.testSet",
Daniel Veillardde0e4982005-07-03 14:35:44 +00001116 "xstc/Tests/Metadata/");
1117 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Daniel Veillardc9352532005-07-04 14:25:34 +00001118 printf("Ran %d tests (%d schemata), no errors\n",
1119 nb_tests - old_tests, nb_schematas);
Daniel Veillardde0e4982005-07-03 14:35:44 +00001120 else
Daniel Veillardc9352532005-07-04 14:25:34 +00001121 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +00001122 nb_tests - old_tests,
Daniel Veillardc9352532005-07-04 14:25:34 +00001123 nb_schematas,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001124 nb_errors - old_errors,
Daniel Veillardc9352532005-07-04 14:25:34 +00001125 nb_internals,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001126 nb_leaks - old_leaks);
1127 old_errors = nb_errors;
1128 old_tests = nb_tests;
1129 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001130 nb_internals = 0;
1131 nb_schematas = 0;
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001132 xstcMetadata("xstc/Tests/Metadata/SunXMLSchema1-0-20020116.testSet",
Daniel Veillardc9352532005-07-04 14:25:34 +00001133 "xstc/Tests/");
Daniel Veillardde0e4982005-07-03 14:35:44 +00001134 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Daniel Veillardc9352532005-07-04 14:25:34 +00001135 printf("Ran %d tests (%d schemata), no errors\n",
1136 nb_tests - old_tests, nb_schematas);
Daniel Veillardde0e4982005-07-03 14:35:44 +00001137 else
Daniel Veillardc9352532005-07-04 14:25:34 +00001138 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +00001139 nb_tests - old_tests,
Daniel Veillardc9352532005-07-04 14:25:34 +00001140 nb_schematas,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001141 nb_errors - old_errors,
Daniel Veillardc9352532005-07-04 14:25:34 +00001142 nb_internals,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001143 nb_leaks - old_leaks);
1144 old_errors = nb_errors;
1145 old_tests = nb_tests;
1146 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001147 nb_internals = 0;
1148 nb_schematas = 0;
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001149 xstcMetadata("xstc/Tests/Metadata/MSXMLSchema1-0-20020116.testSet",
Daniel Veillardde0e4982005-07-03 14:35:44 +00001150 "xstc/Tests/");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001151 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Daniel Veillardc9352532005-07-04 14:25:34 +00001152 printf("Ran %d tests (%d schemata), no errors\n",
1153 nb_tests - old_tests, nb_schematas);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001154 else
Daniel Veillardc9352532005-07-04 14:25:34 +00001155 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001156 nb_tests - old_tests,
Daniel Veillardc9352532005-07-04 14:25:34 +00001157 nb_schematas,
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001158 nb_errors - old_errors,
Daniel Veillardc9352532005-07-04 14:25:34 +00001159 nb_internals,
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001160 nb_leaks - old_leaks);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001161
1162 if ((nb_errors == 0) && (nb_leaks == 0)) {
1163 ret = 0;
1164 printf("Total %d tests, no errors\n",
1165 nb_tests);
1166 } else {
1167 ret = 1;
1168 printf("Total %d tests, %d errors, %d leaks\n",
1169 nb_tests, nb_errors, nb_leaks);
1170 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001171 xmlXPathFreeContext(ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001172 xmlCleanupParser();
1173 xmlMemoryDump();
1174
Daniel Veillardc9352532005-07-04 14:25:34 +00001175 if (logfile != NULL)
1176 fclose(logfile);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001177 return(ret);
1178}
Daniel Veillard95175012005-07-03 16:09:51 +00001179#else /* !SCHEMAS */
1180int
1181main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1182 fprintf(stderr, "runsuite requires support for schemas and xpath in libxml2\n");
1183}
1184#endif