blob: 4e9858a4915d297cd687d8c3088797a143aa4f7f [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);
228 /* used as default nanemspace in xstc tests */
229 xmlXPathRegisterNs(ctxtXPath, BAD_CAST "ts", BAD_CAST "TestSuite");
230 xmlXPathRegisterNs(ctxtXPath, BAD_CAST "xlink",
231 BAD_CAST "http://www.w3.org/1999/xlink");
232 xmlSetGenericErrorFunc(NULL, testErrorHandler);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000233#ifdef LIBXML_SCHEMAS_ENABLED
234 xmlSchemaInitTypes();
235 xmlRelaxNGInitTypes();
236#endif
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000237}
238
239static xmlNodePtr
240getNext(xmlNodePtr cur, const char *xpath) {
241 xmlNodePtr ret = NULL;
242 xmlXPathObjectPtr res;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000243 xmlXPathCompExprPtr comp;
244
245 if ((cur == NULL) || (cur->doc == NULL) || (xpath == NULL))
246 return(NULL);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000247 ctxtXPath->doc = cur->doc;
248 ctxtXPath->node = cur;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000249 comp = xmlXPathCompile(BAD_CAST xpath);
250 if (comp == NULL) {
251 fprintf(stderr, "Failed to compile %s\n", xpath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000252 return(NULL);
253 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000254 res = xmlXPathCompiledEval(comp, ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000255 xmlXPathFreeCompExpr(comp);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000256 if (res == NULL)
257 return(NULL);
258 if ((res->type == XPATH_NODESET) &&
259 (res->nodesetval != NULL) &&
260 (res->nodesetval->nodeNr > 0) &&
261 (res->nodesetval->nodeTab != NULL))
262 ret = res->nodesetval->nodeTab[0];
263 xmlXPathFreeObject(res);
264 return(ret);
265}
266
267static xmlChar *
268getString(xmlNodePtr cur, const char *xpath) {
269 xmlChar *ret = NULL;
270 xmlXPathObjectPtr res;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000271 xmlXPathCompExprPtr comp;
272
273 if ((cur == NULL) || (cur->doc == NULL) || (xpath == NULL))
274 return(NULL);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000275 ctxtXPath->doc = cur->doc;
276 ctxtXPath->node = cur;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000277 comp = xmlXPathCompile(BAD_CAST xpath);
278 if (comp == NULL) {
279 fprintf(stderr, "Failed to compile %s\n", xpath);
280 return(NULL);
281 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000282 res = xmlXPathCompiledEval(comp, ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000283 xmlXPathFreeCompExpr(comp);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000284 if (res == NULL)
285 return(NULL);
286 if (res->type == XPATH_STRING) {
287 ret = res->stringval;
288 res->stringval = NULL;
289 }
290 xmlXPathFreeObject(res);
291 return(ret);
292}
293
294/************************************************************************
295 * *
296 * Test test/xsdtest/xsdtestsuite.xml *
297 * *
298 ************************************************************************/
299
300static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000301xsdIncorectTestCase(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000302 xmlNodePtr test;
303 xmlBufferPtr buf;
304 xmlRelaxNGParserCtxtPtr pctxt;
305 xmlRelaxNGPtr rng = NULL;
306 int ret = 0, memt;
307
308 cur = getNext(cur, "./incorrect[1]");
309 if (cur == NULL) {
310 return(0);
311 }
312
313 test = getNext(cur, "./*");
314 if (test == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000315 test_log("Failed to find test in correct line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000316 xmlGetLineNo(cur));
317 return(1);
318 }
319
320 memt = xmlMemUsed();
321 extraMemoryFromResolver = 0;
322 /*
323 * dump the schemas to a buffer, then reparse it and compile the schemas
324 */
325 buf = xmlBufferCreate();
326 if (buf == NULL) {
327 fprintf(stderr, "out of memory !\n");
328 fatalError();
329 }
330 xmlNodeDump(buf, test->doc, test, 0, 0);
331 pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
332 xmlRelaxNGSetParserErrors(pctxt,
333 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
334 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
335 pctxt);
336 rng = xmlRelaxNGParse(pctxt);
337 xmlRelaxNGFreeParserCtxt(pctxt);
338 if (rng != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000339 test_log("Failed to detect incorect RNG line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000340 xmlGetLineNo(test));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000341 ret = 1;
342 goto done;
343 }
344
345done:
346 if (buf != NULL)
347 xmlBufferFree(buf);
348 if (rng != NULL)
349 xmlRelaxNGFree(rng);
350 xmlResetLastError();
351 if ((memt != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000352 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000353 xmlGetLineNo(cur), xmlMemUsed() - memt);
354 nb_leaks++;
355 }
356 return(ret);
357}
358
Daniel Veillarde84f2312005-07-02 07:31:28 +0000359static void
360installResources(xmlNodePtr tst, const xmlChar *base) {
361 xmlNodePtr test;
362 xmlBufferPtr buf;
363 xmlChar *name, *content, *res;
Daniel Veillardc9352532005-07-04 14:25:34 +0000364
Daniel Veillarde84f2312005-07-02 07:31:28 +0000365 buf = xmlBufferCreate();
366 if (buf == NULL) {
367 fprintf(stderr, "out of memory !\n");
368 fatalError();
369 }
370 xmlNodeDump(buf, tst->doc, tst, 0, 0);
371
372 while (tst != NULL) {
373 test = getNext(tst, "./*");
374 if (test != NULL) {
375 xmlBufferEmpty(buf);
376 xmlNodeDump(buf, test->doc, test, 0, 0);
377 name = getString(tst, "string(@name)");
378 content = xmlStrdup(buf->content);
379 if ((name != NULL) && (content != NULL)) {
380 res = composeDir(base, name);
381 xmlFree(name);
382 addEntity((char *) res, (char *) content);
383 } else {
384 if (name != NULL) xmlFree(name);
385 if (content != NULL) xmlFree(content);
386 }
387 }
388 tst = getNext(tst, "following-sibling::resource[1]");
389 }
390 if (buf != NULL)
391 xmlBufferFree(buf);
392}
393
394static void
395installDirs(xmlNodePtr tst, const xmlChar *base) {
396 xmlNodePtr test;
397 xmlChar *name, *res;
398
399 name = getString(tst, "string(@name)");
400 if (name == NULL)
401 return;
402 res = composeDir(base, name);
403 xmlFree(name);
404 if (res == NULL) {
405 return;
406 }
407 /* Now process resources and subdir recursively */
408 test = getNext(tst, "./resource[1]");
409 if (test != NULL) {
410 installResources(test, res);
411 }
412 test = getNext(tst, "./dir[1]");
413 while (test != NULL) {
414 installDirs(test, res);
415 test = getNext(test, "following-sibling::dir[1]");
416 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000417 xmlFree(res);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000418}
419
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000420static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000421xsdTestCase(xmlNodePtr tst) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000422 xmlNodePtr test, tmp, cur;
423 xmlBufferPtr buf;
424 xmlDocPtr doc = NULL;
425 xmlRelaxNGParserCtxtPtr pctxt;
426 xmlRelaxNGValidCtxtPtr ctxt;
427 xmlRelaxNGPtr rng = NULL;
428 int ret = 0, mem, memt;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000429 xmlChar *dtd;
430
431 resetEntities();
Daniel Veillardc9352532005-07-04 14:25:34 +0000432 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000433
434 tmp = getNext(tst, "./dir[1]");
435 if (tmp != NULL) {
436 installDirs(tmp, NULL);
437 }
438 tmp = getNext(tst, "./resource[1]");
439 if (tmp != NULL) {
440 installResources(tmp, NULL);
441 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000442
443 cur = getNext(tst, "./correct[1]");
444 if (cur == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000445 return(xsdIncorectTestCase(tst));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000446 }
447
448 test = getNext(cur, "./*");
449 if (test == NULL) {
450 fprintf(stderr, "Failed to find test in correct line %ld\n",
451 xmlGetLineNo(cur));
452 return(1);
453 }
454
455 memt = xmlMemUsed();
456 extraMemoryFromResolver = 0;
457 /*
458 * dump the schemas to a buffer, then reparse it and compile the schemas
459 */
460 buf = xmlBufferCreate();
461 if (buf == NULL) {
462 fprintf(stderr, "out of memory !\n");
463 fatalError();
464 }
465 xmlNodeDump(buf, test->doc, test, 0, 0);
466 pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
467 xmlRelaxNGSetParserErrors(pctxt,
468 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
469 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
470 pctxt);
471 rng = xmlRelaxNGParse(pctxt);
472 xmlRelaxNGFreeParserCtxt(pctxt);
473 if (extraMemoryFromResolver)
474 memt = 0;
475
476 if (rng == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000477 test_log("Failed to parse RNGtest line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000478 xmlGetLineNo(test));
479 nb_errors++;
480 ret = 1;
481 goto done;
482 }
483 /*
484 * now scan all the siblings of correct to process the <valid> tests
485 */
486 tmp = getNext(cur, "following-sibling::valid[1]");
487 while (tmp != NULL) {
Daniel Veillarde84f2312005-07-02 07:31:28 +0000488 dtd = xmlGetProp(tmp, BAD_CAST "dtd");
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000489 test = getNext(tmp, "./*");
490 if (test == NULL) {
491 fprintf(stderr, "Failed to find test in <valid> line %ld\n",
492 xmlGetLineNo(tmp));
493
494 } else {
495 xmlBufferEmpty(buf);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000496 if (dtd != NULL)
497 xmlBufferAdd(buf, dtd, -1);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000498 xmlNodeDump(buf, test->doc, test, 0, 0);
499
500 /*
501 * We are ready to run the test
502 */
503 mem = xmlMemUsed();
504 extraMemoryFromResolver = 0;
505 doc = xmlReadMemory((const char *)buf->content, buf->use,
506 "test", NULL, 0);
507 if (doc == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000508 test_log("Failed to parse valid instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000509 xmlGetLineNo(tmp));
510 nb_errors++;
511 } else {
512 nb_tests++;
513 ctxt = xmlRelaxNGNewValidCtxt(rng);
514 xmlRelaxNGSetValidErrors(ctxt,
515 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
516 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
517 ctxt);
518 ret = xmlRelaxNGValidateDoc(ctxt, doc);
519 xmlRelaxNGFreeValidCtxt(ctxt);
520 if (ret > 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000521 test_log("Failed to validate valid instance line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000522 xmlGetLineNo(tmp));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000523 nb_errors++;
524 } else if (ret < 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000525 test_log("Internal error validating instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000526 xmlGetLineNo(tmp));
527 nb_errors++;
528 }
529 xmlFreeDoc(doc);
530 }
531 xmlResetLastError();
532 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000533 test_log("Validation of instance line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000534 xmlGetLineNo(tmp), xmlMemUsed() - mem);
535 xmlMemoryDump();
536 nb_leaks++;
537 }
538 }
Daniel Veillarde84f2312005-07-02 07:31:28 +0000539 if (dtd != NULL)
540 xmlFree(dtd);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000541 tmp = getNext(tmp, "following-sibling::valid[1]");
542 }
543 /*
544 * now scan all the siblings of correct to process the <invalid> tests
545 */
546 tmp = getNext(cur, "following-sibling::invalid[1]");
547 while (tmp != NULL) {
548 test = getNext(tmp, "./*");
549 if (test == NULL) {
550 fprintf(stderr, "Failed to find test in <invalid> line %ld\n",
551 xmlGetLineNo(tmp));
552
553 } else {
554 xmlBufferEmpty(buf);
555 xmlNodeDump(buf, test->doc, test, 0, 0);
556
557 /*
558 * We are ready to run the test
559 */
560 mem = xmlMemUsed();
561 extraMemoryFromResolver = 0;
562 doc = xmlReadMemory((const char *)buf->content, buf->use,
563 "test", NULL, 0);
564 if (doc == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000565 test_log("Failed to parse valid instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000566 xmlGetLineNo(tmp));
567 nb_errors++;
568 } else {
569 nb_tests++;
570 ctxt = xmlRelaxNGNewValidCtxt(rng);
571 xmlRelaxNGSetValidErrors(ctxt,
572 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
573 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
574 ctxt);
575 ret = xmlRelaxNGValidateDoc(ctxt, doc);
576 xmlRelaxNGFreeValidCtxt(ctxt);
577 if (ret == 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000578 test_log("Failed to detect invalid instance line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000579 xmlGetLineNo(tmp));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000580 nb_errors++;
581 } else if (ret < 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000582 test_log("Internal error validating instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000583 xmlGetLineNo(tmp));
584 nb_errors++;
585 }
586 xmlFreeDoc(doc);
587 }
588 xmlResetLastError();
589 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000590 test_log("Validation of instance line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000591 xmlGetLineNo(tmp), xmlMemUsed() - mem);
592 xmlMemoryDump();
593 nb_leaks++;
594 }
595 }
596 tmp = getNext(tmp, "following-sibling::invalid[1]");
597 }
598
599done:
600 if (buf != NULL)
601 xmlBufferFree(buf);
602 if (rng != NULL)
603 xmlRelaxNGFree(rng);
604 xmlResetLastError();
605 if ((memt != xmlMemUsed()) && (memt != 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000606 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000607 xmlGetLineNo(cur), xmlMemUsed() - memt);
608 nb_leaks++;
609 }
610 return(ret);
611}
612
613static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000614xsdTestSuite(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000615 if (verbose) {
616 xmlChar *doc = getString(cur, "string(documentation)");
617
618 if (doc != NULL) {
619 printf("Suite %s\n", doc);
620 xmlFree(doc);
621 }
622 }
623 cur = getNext(cur, "./testCase[1]");
624 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000625 xsdTestCase(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000626 cur = getNext(cur, "following-sibling::testCase[1]");
627 }
628
629 return(0);
630}
631
632static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000633xsdTest(void) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000634 xmlDocPtr doc;
635 xmlNodePtr cur;
636 const char *filename = "test/xsdtest/xsdtestsuite.xml";
637 int ret = 0;
638
639 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
640 if (doc == NULL) {
641 fprintf(stderr, "Failed to parse %s\n", filename);
642 return(-1);
643 }
644 printf("## XML Schemas datatypes test suite from James Clark\n");
645
646 cur = xmlDocGetRootElement(doc);
647 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
648 fprintf(stderr, "Unexpected format %s\n", filename);
649 ret = -1;
650 goto done;
651 }
652
653 cur = getNext(cur, "./testSuite[1]");
654 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
655 fprintf(stderr, "Unexpected format %s\n", filename);
656 ret = -1;
657 goto done;
658 }
659 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000660 xsdTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000661 cur = getNext(cur, "following-sibling::testSuite[1]");
662 }
663
664done:
665 if (doc != NULL)
666 xmlFreeDoc(doc);
667 return(ret);
668}
669
670static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000671rngTestSuite(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000672 if (verbose) {
673 xmlChar *doc = getString(cur, "string(documentation)");
674
675 if (doc != NULL) {
676 printf("Suite %s\n", doc);
677 xmlFree(doc);
678 } else {
679 doc = getString(cur, "string(section)");
680 if (doc != NULL) {
681 printf("Section %s\n", doc);
682 xmlFree(doc);
683 }
684 }
685 }
686 cur = getNext(cur, "./testSuite[1]");
687 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000688 xsdTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000689 cur = getNext(cur, "following-sibling::testSuite[1]");
690 }
691
692 return(0);
693}
694
695static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000696rngTest1(void) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000697 xmlDocPtr doc;
698 xmlNodePtr cur;
699 const char *filename = "test/relaxng/OASIS/spectest.xml";
700 int ret = 0;
701
702 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
703 if (doc == NULL) {
704 fprintf(stderr, "Failed to parse %s\n", filename);
705 return(-1);
706 }
Daniel Veillarde84f2312005-07-02 07:31:28 +0000707 printf("## Relax NG test suite from James Clark\n");
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000708
709 cur = xmlDocGetRootElement(doc);
710 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
711 fprintf(stderr, "Unexpected format %s\n", filename);
712 ret = -1;
713 goto done;
714 }
715
716 cur = getNext(cur, "./testSuite[1]");
717 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
718 fprintf(stderr, "Unexpected format %s\n", filename);
719 ret = -1;
720 goto done;
721 }
722 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000723 rngTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000724 cur = getNext(cur, "following-sibling::testSuite[1]");
725 }
726
727done:
728 if (doc != NULL)
729 xmlFreeDoc(doc);
730 return(ret);
731}
732
Daniel Veillarde84f2312005-07-02 07:31:28 +0000733static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000734rngTest2(void) {
Daniel Veillarde84f2312005-07-02 07:31:28 +0000735 xmlDocPtr doc;
736 xmlNodePtr cur;
737 const char *filename = "test/relaxng/testsuite.xml";
738 int ret = 0;
739
740 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
741 if (doc == NULL) {
742 fprintf(stderr, "Failed to parse %s\n", filename);
743 return(-1);
744 }
745 printf("## Relax NG test suite for libxml2\n");
746
747 cur = xmlDocGetRootElement(doc);
748 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
749 fprintf(stderr, "Unexpected format %s\n", filename);
750 ret = -1;
751 goto done;
752 }
753
754 cur = getNext(cur, "./testSuite[1]");
755 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
756 fprintf(stderr, "Unexpected format %s\n", filename);
757 ret = -1;
758 goto done;
759 }
760 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000761 xsdTestSuite(cur);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000762 cur = getNext(cur, "following-sibling::testSuite[1]");
763 }
764
765done:
766 if (doc != NULL)
767 xmlFreeDoc(doc);
768 return(ret);
769}
770
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000771/************************************************************************
772 * *
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000773 * Schemas test suites from W3C/NIST/MS/Sun *
774 * *
775 ************************************************************************/
776
777static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000778xstcTestInstance(xmlNodePtr cur, xmlSchemaPtr schemas,
Daniel Veillard6b6d6802005-07-03 21:00:34 +0000779 const xmlChar *spath, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000780 xmlChar *href = NULL;
781 xmlChar *path = NULL;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000782 xmlChar *validity = NULL;
783 xmlSchemaValidCtxtPtr ctxt = NULL;
784 xmlDocPtr doc = NULL;
785 int ret = 0, mem;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000786
Daniel Veillardde0e4982005-07-03 14:35:44 +0000787 xmlResetLastError();
Daniel Veillardc9352532005-07-04 14:25:34 +0000788 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000789 mem = xmlMemUsed();
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000790 href = getString(cur,
Daniel Veillardde0e4982005-07-03 14:35:44 +0000791 "string(ts:instanceDocument/@xlink:href)");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000792 if ((href == NULL) || (href[0] == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000793 test_log("testGroup line %ld misses href for schemaDocument\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000794 xmlGetLineNo(cur));
795 ret = -1;
796 goto done;
797 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000798 path = xmlBuildURI(href, BAD_CAST base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000799 if (path == NULL) {
800 fprintf(stderr,
801 "Failed to build path to schemas testGroup line %ld : %s\n",
802 xmlGetLineNo(cur), href);
803 ret = -1;
804 goto done;
805 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000806 if (checkTestFile((const char *) path) <= 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000807 test_log("schemas for testGroup line %ld is missing: %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000808 xmlGetLineNo(cur), path);
809 ret = -1;
810 goto done;
811 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000812 validity = getString(cur,
813 "string(ts:expected/@validity)");
814 if (validity == NULL) {
815 fprintf(stderr, "instanceDocument line %ld misses expected validity\n",
816 xmlGetLineNo(cur));
817 ret = -1;
818 goto done;
819 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000820 nb_tests++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000821 doc = xmlReadFile((const char *) path, NULL, XML_PARSE_NOENT);
822 if (doc == NULL) {
823 fprintf(stderr, "instance %s fails to parse\n", path);
824 ret = -1;
825 nb_errors++;
826 goto done;
827 }
828
829 ctxt = xmlSchemaNewValidCtxt(schemas);
830 xmlSchemaSetValidErrors(ctxt,
831 (xmlSchemaValidityErrorFunc) testErrorHandler,
832 (xmlSchemaValidityWarningFunc) testErrorHandler,
833 ctxt);
834 ret = xmlSchemaValidateDoc(ctxt, doc);
835
836 if (xmlStrEqual(validity, BAD_CAST "valid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000837 if (ret > 0) {
838 test_log("valid instance %s failed to validate against %s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000839 path, spath);
840 nb_errors++;
Daniel Veillardc9352532005-07-04 14:25:34 +0000841 } else if (ret < 0) {
842 test_log("valid instance %s got internal error validating %s\n",
843 path, spath);
844 nb_internals++;
845 nb_errors++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000846 }
847 } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
848 if (ret == 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000849 test_log("Failed to detect invalid instance %s against %s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000850 path, spath);
851 nb_errors++;
852 }
853 } else {
Daniel Veillardc9352532005-07-04 14:25:34 +0000854 test_log("instanceDocument line %ld has unexpected validity value%s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000855 xmlGetLineNo(cur), validity);
856 ret = -1;
857 goto done;
858 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000859
860done:
861 if (href != NULL) xmlFree(href);
862 if (path != NULL) xmlFree(path);
Daniel Veillardde0e4982005-07-03 14:35:44 +0000863 if (validity != NULL) xmlFree(validity);
864 if (ctxt != NULL) xmlSchemaFreeValidCtxt(ctxt);
865 if (doc != NULL) xmlFreeDoc(doc);
866 xmlResetLastError();
867 if (mem != xmlMemUsed()) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000868 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000869 xmlGetLineNo(cur), xmlMemUsed() - mem);
870 nb_leaks++;
871 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000872 return(ret);
873}
Daniel Veillardde0e4982005-07-03 14:35:44 +0000874
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000875static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000876xstcTestGroup(xmlNodePtr cur, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000877 xmlChar *href = NULL;
878 xmlChar *path = NULL;
879 xmlChar *validity = NULL;
880 xmlSchemaPtr schemas = NULL;
881 xmlSchemaParserCtxtPtr ctxt;
882 xmlNodePtr instance;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000883 int ret = 0, mem;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000884
Daniel Veillardde0e4982005-07-03 14:35:44 +0000885 xmlResetLastError();
Daniel Veillardc9352532005-07-04 14:25:34 +0000886 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000887 mem = xmlMemUsed();
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000888 href = getString(cur,
889 "string(ts:schemaTest/ts:schemaDocument/@xlink:href)");
890 if ((href == NULL) || (href[0] == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000891 test_log("testGroup line %ld misses href for schemaDocument\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000892 xmlGetLineNo(cur));
893 ret = -1;
894 goto done;
895 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000896 path = xmlBuildURI(href, BAD_CAST base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000897 if (path == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000898 test_log("Failed to build path to schemas testGroup line %ld : %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000899 xmlGetLineNo(cur), href);
900 ret = -1;
901 goto done;
902 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000903 if (checkTestFile((const char *) path) <= 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000904 test_log("schemas for testGroup line %ld is missing: %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000905 xmlGetLineNo(cur), path);
906 ret = -1;
907 goto done;
908 }
909 validity = getString(cur,
910 "string(ts:schemaTest/ts:expected/@validity)");
911 if (validity == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000912 test_log("testGroup line %ld misses expected validity\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000913 xmlGetLineNo(cur));
914 ret = -1;
915 goto done;
916 }
Daniel Veillardc9352532005-07-04 14:25:34 +0000917 nb_tests++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000918 if (xmlStrEqual(validity, BAD_CAST "valid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000919 nb_schematas++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000920 ctxt = xmlSchemaNewParserCtxt((const char *) path);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000921 xmlSchemaSetParserErrors(ctxt,
922 (xmlSchemaValidityErrorFunc) testErrorHandler,
923 (xmlSchemaValidityWarningFunc) testErrorHandler,
924 ctxt);
925 schemas = xmlSchemaParse(ctxt);
926 xmlSchemaFreeParserCtxt(ctxt);
927 if (schemas == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000928 test_log("valid schemas %s failed to parse\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000929 path);
Daniel Veillard90837782005-07-04 15:45:10 +0000930 ret = 1;
931 nb_errors++;
932 }
933 if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
934 test_log("valid schemas %s hit an unimplemented block\n",
935 path);
936 ret = 1;
937 nb_unimplemented++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000938 nb_errors++;
939 }
940 instance = getNext(cur, "./ts:instanceTest[1]");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000941 while (instance != NULL) {
Kasimier T. Buchcikdcac4fc2005-12-09 10:03:27 +0000942 if (schemas != NULL) {
943 xstcTestInstance(instance, schemas, path, base);
944 } else {
945 /*
946 * We'll automatically mark the instances as failed
947 * if the schema was broken.
948 */
949 nb_errors++;
950 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000951 instance = getNext(instance,
Kasimier T. Buchcikdcac4fc2005-12-09 10:03:27 +0000952 "following-sibling::ts:instanceTest[1]");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000953 }
954 } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000955 nb_schematas++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000956 ctxt = xmlSchemaNewParserCtxt((const char *) path);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000957 xmlSchemaSetParserErrors(ctxt,
958 (xmlSchemaValidityErrorFunc) testErrorHandler,
959 (xmlSchemaValidityWarningFunc) testErrorHandler,
960 ctxt);
961 schemas = xmlSchemaParse(ctxt);
962 xmlSchemaFreeParserCtxt(ctxt);
Daniel Veillard4ac5f9a2005-07-04 15:20:27 +0000963 if (schemas != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000964 test_log("Failed to detect error in schemas %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000965 path);
966 nb_errors++;
Daniel Veillard90837782005-07-04 15:45:10 +0000967 ret = 1;
968 }
969 if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
970 nb_unimplemented++;
971 test_log("invalid schemas %s hit an unimplemented block\n",
972 path);
973 ret = 1;
974 nb_errors++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000975 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000976 } else {
Daniel Veillardc9352532005-07-04 14:25:34 +0000977 test_log("testGroup line %ld misses unexpected validity value%s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000978 xmlGetLineNo(cur), validity);
979 ret = -1;
980 goto done;
981 }
982
983done:
984 if (href != NULL) xmlFree(href);
985 if (path != NULL) xmlFree(path);
986 if (validity != NULL) xmlFree(validity);
987 if (schemas != NULL) xmlSchemaFree(schemas);
Daniel Veillardde0e4982005-07-03 14:35:44 +0000988 xmlResetLastError();
989 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000990 test_log("Processing test line %ld %s leaked %d\n",
991 xmlGetLineNo(cur), path, xmlMemUsed() - mem);
Daniel Veillardde0e4982005-07-03 14:35:44 +0000992 nb_leaks++;
993 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000994 return(ret);
995}
996
997static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000998xstcMetadata(const char *metadata, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000999 xmlDocPtr doc;
1000 xmlNodePtr cur;
1001 xmlChar *contributor;
1002 xmlChar *name;
Daniel Veillard6b6d6802005-07-03 21:00:34 +00001003 int ret = 0;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001004
1005 doc = xmlReadFile(metadata, NULL, XML_PARSE_NOENT);
1006 if (doc == NULL) {
1007 fprintf(stderr, "Failed to parse %s\n", metadata);
1008 return(-1);
1009 }
1010
1011 cur = xmlDocGetRootElement(doc);
1012 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSet"))) {
1013 fprintf(stderr, "Unexpected format %s\n", metadata);
1014 return(-1);
1015 }
1016 contributor = xmlGetProp(cur, BAD_CAST "contributor");
1017 if (contributor == NULL) {
1018 contributor = xmlStrdup(BAD_CAST "Unknown");
1019 }
1020 name = xmlGetProp(cur, BAD_CAST "name");
1021 if (name == NULL) {
1022 name = xmlStrdup(BAD_CAST "Unknown");
1023 }
1024 printf("## %s test suite for Schemas version %s\n", contributor, name);
1025 xmlFree(contributor);
1026 xmlFree(name);
1027
1028 cur = getNext(cur, "./ts:testGroup[1]");
1029 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testGroup"))) {
1030 fprintf(stderr, "Unexpected format %s\n", metadata);
1031 ret = -1;
1032 goto done;
1033 }
1034 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +00001035 xstcTestGroup(cur, base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001036 cur = getNext(cur, "following-sibling::ts:testGroup[1]");
1037 }
1038
1039done:
1040 xmlFreeDoc(doc);
1041 return(ret);
1042}
1043
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001044/************************************************************************
1045 * *
1046 * The driver for the tests *
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001047 * *
1048 ************************************************************************/
1049
1050int
1051main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001052 int ret = 0;
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001053 int old_errors, old_tests, old_leaks;
1054
Daniel Veillardc9352532005-07-04 14:25:34 +00001055 logfile = fopen(LOGFILE, "w");
1056 if (logfile == NULL) {
1057 fprintf(stderr,
1058 "Could not open the log file, running in verbose mode\n");
1059 verbose = 1;
1060 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001061 initializeLibxml2();
1062
1063 if ((argc >= 2) && (!strcmp(argv[1], "-v")))
1064 verbose = 1;
1065
1066
Daniel Veillarde84f2312005-07-02 07:31:28 +00001067 old_errors = nb_errors;
1068 old_tests = nb_tests;
1069 old_leaks = nb_leaks;
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001070 xsdTest();
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001071 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1072 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1073 else
1074 printf("Ran %d tests, %d errors, %d leaks\n",
1075 nb_tests - old_tests,
1076 nb_errors - old_errors,
1077 nb_leaks - old_leaks);
1078 old_errors = nb_errors;
1079 old_tests = nb_tests;
1080 old_leaks = nb_leaks;
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001081 rngTest1();
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001082 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1083 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1084 else
1085 printf("Ran %d tests, %d errors, %d leaks\n",
1086 nb_tests - old_tests,
1087 nb_errors - old_errors,
1088 nb_leaks - old_leaks);
1089 old_errors = nb_errors;
1090 old_tests = nb_tests;
1091 old_leaks = nb_leaks;
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001092 rngTest2();
Daniel Veillarde84f2312005-07-02 07:31:28 +00001093 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1094 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1095 else
1096 printf("Ran %d tests, %d errors, %d leaks\n",
1097 nb_tests - old_tests,
1098 nb_errors - old_errors,
1099 nb_leaks - old_leaks);
1100 old_errors = nb_errors;
1101 old_tests = nb_tests;
1102 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001103 nb_internals = 0;
1104 nb_schematas = 0;
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001105 xstcMetadata("xstc/Tests/Metadata/NISTXMLSchemaDatatypes.testSet",
Daniel Veillardde0e4982005-07-03 14:35:44 +00001106 "xstc/Tests/Metadata/");
1107 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Daniel Veillardc9352532005-07-04 14:25:34 +00001108 printf("Ran %d tests (%d schemata), no errors\n",
1109 nb_tests - old_tests, nb_schematas);
Daniel Veillardde0e4982005-07-03 14:35:44 +00001110 else
Daniel Veillardc9352532005-07-04 14:25:34 +00001111 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +00001112 nb_tests - old_tests,
Daniel Veillardc9352532005-07-04 14:25:34 +00001113 nb_schematas,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001114 nb_errors - old_errors,
Daniel Veillardc9352532005-07-04 14:25:34 +00001115 nb_internals,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001116 nb_leaks - old_leaks);
1117 old_errors = nb_errors;
1118 old_tests = nb_tests;
1119 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001120 nb_internals = 0;
1121 nb_schematas = 0;
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001122 xstcMetadata("xstc/Tests/Metadata/SunXMLSchema1-0-20020116.testSet",
Daniel Veillardc9352532005-07-04 14:25:34 +00001123 "xstc/Tests/");
Daniel Veillardde0e4982005-07-03 14:35:44 +00001124 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Daniel Veillardc9352532005-07-04 14:25:34 +00001125 printf("Ran %d tests (%d schemata), no errors\n",
1126 nb_tests - old_tests, nb_schematas);
Daniel Veillardde0e4982005-07-03 14:35:44 +00001127 else
Daniel Veillardc9352532005-07-04 14:25:34 +00001128 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +00001129 nb_tests - old_tests,
Daniel Veillardc9352532005-07-04 14:25:34 +00001130 nb_schematas,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001131 nb_errors - old_errors,
Daniel Veillardc9352532005-07-04 14:25:34 +00001132 nb_internals,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001133 nb_leaks - old_leaks);
1134 old_errors = nb_errors;
1135 old_tests = nb_tests;
1136 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001137 nb_internals = 0;
1138 nb_schematas = 0;
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001139 xstcMetadata("xstc/Tests/Metadata/MSXMLSchema1-0-20020116.testSet",
Daniel Veillardde0e4982005-07-03 14:35:44 +00001140 "xstc/Tests/");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001141 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Daniel Veillardc9352532005-07-04 14:25:34 +00001142 printf("Ran %d tests (%d schemata), no errors\n",
1143 nb_tests - old_tests, nb_schematas);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001144 else
Daniel Veillardc9352532005-07-04 14:25:34 +00001145 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001146 nb_tests - old_tests,
Daniel Veillardc9352532005-07-04 14:25:34 +00001147 nb_schematas,
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001148 nb_errors - old_errors,
Daniel Veillardc9352532005-07-04 14:25:34 +00001149 nb_internals,
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001150 nb_leaks - old_leaks);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001151
1152 if ((nb_errors == 0) && (nb_leaks == 0)) {
1153 ret = 0;
1154 printf("Total %d tests, no errors\n",
1155 nb_tests);
1156 } else {
1157 ret = 1;
1158 printf("Total %d tests, %d errors, %d leaks\n",
1159 nb_tests, nb_errors, nb_leaks);
1160 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001161
1162 xmlXPathFreeContext(ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001163 xmlCleanupParser();
1164 xmlMemoryDump();
1165
Daniel Veillardc9352532005-07-04 14:25:34 +00001166 if (logfile != NULL)
1167 fclose(logfile);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001168 return(ret);
1169}
Daniel Veillard95175012005-07-03 16:09:51 +00001170#else /* !SCHEMAS */
1171int
1172main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1173 fprintf(stderr, "runsuite requires support for schemas and xpath in libxml2\n");
1174}
1175#endif