blob: debf456af7cbd346986ab44ed583a9c431250882 [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;
96static long libxmlMemoryAllocatedBase = 0;
97static int extraMemoryFromResolver = 0;
98
99static int
100fatalError(void) {
101 fprintf(stderr, "Exitting tests on fatal error\n");
102 exit(1);
103}
104
105/*
Daniel Veillarde84f2312005-07-02 07:31:28 +0000106 * that's needed to implement <resource>
107 */
108#define MAX_ENTITIES 20
Daniel Veillard24505b02005-07-28 23:49:35 +0000109static char *testEntitiesName[MAX_ENTITIES];
110static char *testEntitiesValue[MAX_ENTITIES];
111static int nb_entities = 0;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000112static void resetEntities(void) {
113 int i;
114
115 for (i = 0;i < nb_entities;i++) {
116 if (testEntitiesName[i] != NULL)
117 xmlFree(testEntitiesName[i]);
118 if (testEntitiesValue[i] != NULL)
119 xmlFree(testEntitiesValue[i]);
120 }
121 nb_entities = 0;
122}
123static int addEntity(char *name, char *content) {
124 if (nb_entities >= MAX_ENTITIES) {
125 fprintf(stderr, "Too many entities defined\n");
126 return(-1);
127 }
128 testEntitiesName[nb_entities] = name;
129 testEntitiesValue[nb_entities] = content;
130 nb_entities++;
131 return(0);
132}
133
134/*
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000135 * We need to trap calls to the resolver to not account memory for the catalog
136 * which is shared to the current running test. We also don't want to have
137 * network downloads modifying tests.
138 */
139static xmlParserInputPtr
140testExternalEntityLoader(const char *URL, const char *ID,
141 xmlParserCtxtPtr ctxt) {
142 xmlParserInputPtr ret;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000143 int i;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000144
Daniel Veillarde84f2312005-07-02 07:31:28 +0000145 for (i = 0;i < nb_entities;i++) {
146 if (!strcmp(testEntitiesName[i], URL)) {
147 ret = xmlNewStringInputStream(ctxt,
148 (const xmlChar *) testEntitiesValue[i]);
149 if (ret != NULL) {
150 ret->filename = (const char *)
151 xmlStrdup((xmlChar *)testEntitiesName[i]);
152 }
153 return(ret);
154 }
155 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000156 if (checkTestFile(URL)) {
157 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
158 } else {
159 int memused = xmlMemUsed();
160 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
161 extraMemoryFromResolver += xmlMemUsed() - memused;
162 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000163#if 0
Daniel Veillarde84f2312005-07-02 07:31:28 +0000164 if (ret == NULL) {
165 fprintf(stderr, "Failed to find resource %s\n", URL);
166 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000167#endif
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000168
169 return(ret);
170}
171
172/*
173 * Trapping the error messages at the generic level to grab the equivalent of
174 * stderr messages on CLI tools.
175 */
176static char testErrors[32769];
177static int testErrorsSize = 0;
178
Daniel Veillardc9352532005-07-04 14:25:34 +0000179static void test_log(const char *msg, ...) {
180 va_list args;
181 if (logfile != NULL) {
182 fprintf(logfile, "\n------------\n");
183 va_start(args, msg);
184 vfprintf(logfile, msg, args);
185 va_end(args);
186 fprintf(logfile, "%s", testErrors);
187 testErrorsSize = 0; testErrors[0] = 0;
188 }
189 if (verbose) {
190 va_start(args, msg);
191 vfprintf(stderr, msg, args);
192 va_end(args);
193 }
194}
195
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000196static void
197testErrorHandler(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
198 va_list args;
199 int res;
200
201 if (testErrorsSize >= 32768)
202 return;
203 va_start(args, msg);
204 res = vsnprintf(&testErrors[testErrorsSize],
205 32768 - testErrorsSize,
206 msg, args);
207 va_end(args);
208 if (testErrorsSize + res >= 32768) {
209 /* buffer is full */
210 testErrorsSize = 32768;
211 testErrors[testErrorsSize] = 0;
212 } else {
213 testErrorsSize += res;
214 }
215 testErrors[testErrorsSize] = 0;
216}
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000217
Daniel Veillard24505b02005-07-28 23:49:35 +0000218static xmlXPathContextPtr ctxtXPath;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000219
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000220static void
221initializeLibxml2(void) {
222 xmlGetWarningsDefaultValue = 0;
223 xmlPedanticParserDefault(0);
224
225 xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
226 xmlInitParser();
227 xmlSetExternalEntityLoader(testExternalEntityLoader);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000228 ctxtXPath = xmlXPathNewContext(NULL);
229 /* used as default nanemspace in xstc tests */
230 xmlXPathRegisterNs(ctxtXPath, BAD_CAST "ts", BAD_CAST "TestSuite");
231 xmlXPathRegisterNs(ctxtXPath, BAD_CAST "xlink",
232 BAD_CAST "http://www.w3.org/1999/xlink");
233 xmlSetGenericErrorFunc(NULL, testErrorHandler);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000234#ifdef LIBXML_SCHEMAS_ENABLED
235 xmlSchemaInitTypes();
236 xmlRelaxNGInitTypes();
237#endif
238 libxmlMemoryAllocatedBase = xmlMemUsed();
239}
240
241static xmlNodePtr
242getNext(xmlNodePtr cur, const char *xpath) {
243 xmlNodePtr ret = NULL;
244 xmlXPathObjectPtr res;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000245 xmlXPathCompExprPtr comp;
246
247 if ((cur == NULL) || (cur->doc == NULL) || (xpath == NULL))
248 return(NULL);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000249 ctxtXPath->doc = cur->doc;
250 ctxtXPath->node = cur;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000251 comp = xmlXPathCompile(BAD_CAST xpath);
252 if (comp == NULL) {
253 fprintf(stderr, "Failed to compile %s\n", xpath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000254 return(NULL);
255 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000256 res = xmlXPathCompiledEval(comp, ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000257 xmlXPathFreeCompExpr(comp);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000258 if (res == NULL)
259 return(NULL);
260 if ((res->type == XPATH_NODESET) &&
261 (res->nodesetval != NULL) &&
262 (res->nodesetval->nodeNr > 0) &&
263 (res->nodesetval->nodeTab != NULL))
264 ret = res->nodesetval->nodeTab[0];
265 xmlXPathFreeObject(res);
266 return(ret);
267}
268
269static xmlChar *
270getString(xmlNodePtr cur, const char *xpath) {
271 xmlChar *ret = NULL;
272 xmlXPathObjectPtr res;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000273 xmlXPathCompExprPtr comp;
274
275 if ((cur == NULL) || (cur->doc == NULL) || (xpath == NULL))
276 return(NULL);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000277 ctxtXPath->doc = cur->doc;
278 ctxtXPath->node = cur;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000279 comp = xmlXPathCompile(BAD_CAST xpath);
280 if (comp == NULL) {
281 fprintf(stderr, "Failed to compile %s\n", xpath);
282 return(NULL);
283 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000284 res = xmlXPathCompiledEval(comp, ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000285 xmlXPathFreeCompExpr(comp);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000286 if (res == NULL)
287 return(NULL);
288 if (res->type == XPATH_STRING) {
289 ret = res->stringval;
290 res->stringval = NULL;
291 }
292 xmlXPathFreeObject(res);
293 return(ret);
294}
295
296/************************************************************************
297 * *
298 * Test test/xsdtest/xsdtestsuite.xml *
299 * *
300 ************************************************************************/
301
302static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000303xsdIncorectTestCase(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000304 xmlNodePtr test;
305 xmlBufferPtr buf;
306 xmlRelaxNGParserCtxtPtr pctxt;
307 xmlRelaxNGPtr rng = NULL;
308 int ret = 0, memt;
309
310 cur = getNext(cur, "./incorrect[1]");
311 if (cur == NULL) {
312 return(0);
313 }
314
315 test = getNext(cur, "./*");
316 if (test == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000317 test_log("Failed to find test in correct line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000318 xmlGetLineNo(cur));
319 return(1);
320 }
321
322 memt = xmlMemUsed();
323 extraMemoryFromResolver = 0;
324 /*
325 * dump the schemas to a buffer, then reparse it and compile the schemas
326 */
327 buf = xmlBufferCreate();
328 if (buf == NULL) {
329 fprintf(stderr, "out of memory !\n");
330 fatalError();
331 }
332 xmlNodeDump(buf, test->doc, test, 0, 0);
333 pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
334 xmlRelaxNGSetParserErrors(pctxt,
335 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
336 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
337 pctxt);
338 rng = xmlRelaxNGParse(pctxt);
339 xmlRelaxNGFreeParserCtxt(pctxt);
340 if (rng != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000341 test_log("Failed to detect incorect RNG line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000342 xmlGetLineNo(test));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000343 ret = 1;
344 goto done;
345 }
346
347done:
348 if (buf != NULL)
349 xmlBufferFree(buf);
350 if (rng != NULL)
351 xmlRelaxNGFree(rng);
352 xmlResetLastError();
353 if ((memt != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000354 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000355 xmlGetLineNo(cur), xmlMemUsed() - memt);
356 nb_leaks++;
357 }
358 return(ret);
359}
360
Daniel Veillarde84f2312005-07-02 07:31:28 +0000361static void
362installResources(xmlNodePtr tst, const xmlChar *base) {
363 xmlNodePtr test;
364 xmlBufferPtr buf;
365 xmlChar *name, *content, *res;
Daniel Veillardc9352532005-07-04 14:25:34 +0000366
Daniel Veillarde84f2312005-07-02 07:31:28 +0000367 buf = xmlBufferCreate();
368 if (buf == NULL) {
369 fprintf(stderr, "out of memory !\n");
370 fatalError();
371 }
372 xmlNodeDump(buf, tst->doc, tst, 0, 0);
373
374 while (tst != NULL) {
375 test = getNext(tst, "./*");
376 if (test != NULL) {
377 xmlBufferEmpty(buf);
378 xmlNodeDump(buf, test->doc, test, 0, 0);
379 name = getString(tst, "string(@name)");
380 content = xmlStrdup(buf->content);
381 if ((name != NULL) && (content != NULL)) {
382 res = composeDir(base, name);
383 xmlFree(name);
384 addEntity((char *) res, (char *) content);
385 } else {
386 if (name != NULL) xmlFree(name);
387 if (content != NULL) xmlFree(content);
388 }
389 }
390 tst = getNext(tst, "following-sibling::resource[1]");
391 }
392 if (buf != NULL)
393 xmlBufferFree(buf);
394}
395
396static void
397installDirs(xmlNodePtr tst, const xmlChar *base) {
398 xmlNodePtr test;
399 xmlChar *name, *res;
400
401 name = getString(tst, "string(@name)");
402 if (name == NULL)
403 return;
404 res = composeDir(base, name);
405 xmlFree(name);
406 if (res == NULL) {
407 return;
408 }
409 /* Now process resources and subdir recursively */
410 test = getNext(tst, "./resource[1]");
411 if (test != NULL) {
412 installResources(test, res);
413 }
414 test = getNext(tst, "./dir[1]");
415 while (test != NULL) {
416 installDirs(test, res);
417 test = getNext(test, "following-sibling::dir[1]");
418 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000419 xmlFree(res);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000420}
421
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000422static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000423xsdTestCase(xmlNodePtr tst) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000424 xmlNodePtr test, tmp, cur;
425 xmlBufferPtr buf;
426 xmlDocPtr doc = NULL;
427 xmlRelaxNGParserCtxtPtr pctxt;
428 xmlRelaxNGValidCtxtPtr ctxt;
429 xmlRelaxNGPtr rng = NULL;
430 int ret = 0, mem, memt;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000431 xmlChar *dtd;
432
433 resetEntities();
Daniel Veillardc9352532005-07-04 14:25:34 +0000434 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000435
436 tmp = getNext(tst, "./dir[1]");
437 if (tmp != NULL) {
438 installDirs(tmp, NULL);
439 }
440 tmp = getNext(tst, "./resource[1]");
441 if (tmp != NULL) {
442 installResources(tmp, NULL);
443 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000444
445 cur = getNext(tst, "./correct[1]");
446 if (cur == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000447 return(xsdIncorectTestCase(tst));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000448 }
449
450 test = getNext(cur, "./*");
451 if (test == NULL) {
452 fprintf(stderr, "Failed to find test in correct line %ld\n",
453 xmlGetLineNo(cur));
454 return(1);
455 }
456
457 memt = xmlMemUsed();
458 extraMemoryFromResolver = 0;
459 /*
460 * dump the schemas to a buffer, then reparse it and compile the schemas
461 */
462 buf = xmlBufferCreate();
463 if (buf == NULL) {
464 fprintf(stderr, "out of memory !\n");
465 fatalError();
466 }
467 xmlNodeDump(buf, test->doc, test, 0, 0);
468 pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
469 xmlRelaxNGSetParserErrors(pctxt,
470 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
471 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
472 pctxt);
473 rng = xmlRelaxNGParse(pctxt);
474 xmlRelaxNGFreeParserCtxt(pctxt);
475 if (extraMemoryFromResolver)
476 memt = 0;
477
478 if (rng == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000479 test_log("Failed to parse RNGtest line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000480 xmlGetLineNo(test));
481 nb_errors++;
482 ret = 1;
483 goto done;
484 }
485 /*
486 * now scan all the siblings of correct to process the <valid> tests
487 */
488 tmp = getNext(cur, "following-sibling::valid[1]");
489 while (tmp != NULL) {
Daniel Veillarde84f2312005-07-02 07:31:28 +0000490 dtd = xmlGetProp(tmp, BAD_CAST "dtd");
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000491 test = getNext(tmp, "./*");
492 if (test == NULL) {
493 fprintf(stderr, "Failed to find test in <valid> line %ld\n",
494 xmlGetLineNo(tmp));
495
496 } else {
497 xmlBufferEmpty(buf);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000498 if (dtd != NULL)
499 xmlBufferAdd(buf, dtd, -1);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000500 xmlNodeDump(buf, test->doc, test, 0, 0);
501
502 /*
503 * We are ready to run the test
504 */
505 mem = xmlMemUsed();
506 extraMemoryFromResolver = 0;
507 doc = xmlReadMemory((const char *)buf->content, buf->use,
508 "test", NULL, 0);
509 if (doc == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000510 test_log("Failed to parse valid instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000511 xmlGetLineNo(tmp));
512 nb_errors++;
513 } else {
514 nb_tests++;
515 ctxt = xmlRelaxNGNewValidCtxt(rng);
516 xmlRelaxNGSetValidErrors(ctxt,
517 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
518 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
519 ctxt);
520 ret = xmlRelaxNGValidateDoc(ctxt, doc);
521 xmlRelaxNGFreeValidCtxt(ctxt);
522 if (ret > 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000523 test_log("Failed to validate valid instance line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000524 xmlGetLineNo(tmp));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000525 nb_errors++;
526 } else if (ret < 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000527 test_log("Internal error validating instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000528 xmlGetLineNo(tmp));
529 nb_errors++;
530 }
531 xmlFreeDoc(doc);
532 }
533 xmlResetLastError();
534 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000535 test_log("Validation of instance line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000536 xmlGetLineNo(tmp), xmlMemUsed() - mem);
537 xmlMemoryDump();
538 nb_leaks++;
539 }
540 }
Daniel Veillarde84f2312005-07-02 07:31:28 +0000541 if (dtd != NULL)
542 xmlFree(dtd);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000543 tmp = getNext(tmp, "following-sibling::valid[1]");
544 }
545 /*
546 * now scan all the siblings of correct to process the <invalid> tests
547 */
548 tmp = getNext(cur, "following-sibling::invalid[1]");
549 while (tmp != NULL) {
550 test = getNext(tmp, "./*");
551 if (test == NULL) {
552 fprintf(stderr, "Failed to find test in <invalid> line %ld\n",
553 xmlGetLineNo(tmp));
554
555 } else {
556 xmlBufferEmpty(buf);
557 xmlNodeDump(buf, test->doc, test, 0, 0);
558
559 /*
560 * We are ready to run the test
561 */
562 mem = xmlMemUsed();
563 extraMemoryFromResolver = 0;
564 doc = xmlReadMemory((const char *)buf->content, buf->use,
565 "test", NULL, 0);
566 if (doc == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000567 test_log("Failed to parse valid instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000568 xmlGetLineNo(tmp));
569 nb_errors++;
570 } else {
571 nb_tests++;
572 ctxt = xmlRelaxNGNewValidCtxt(rng);
573 xmlRelaxNGSetValidErrors(ctxt,
574 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
575 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
576 ctxt);
577 ret = xmlRelaxNGValidateDoc(ctxt, doc);
578 xmlRelaxNGFreeValidCtxt(ctxt);
579 if (ret == 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000580 test_log("Failed to detect invalid instance line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000581 xmlGetLineNo(tmp));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000582 nb_errors++;
583 } else if (ret < 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000584 test_log("Internal error validating instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000585 xmlGetLineNo(tmp));
586 nb_errors++;
587 }
588 xmlFreeDoc(doc);
589 }
590 xmlResetLastError();
591 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000592 test_log("Validation of instance line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000593 xmlGetLineNo(tmp), xmlMemUsed() - mem);
594 xmlMemoryDump();
595 nb_leaks++;
596 }
597 }
598 tmp = getNext(tmp, "following-sibling::invalid[1]");
599 }
600
601done:
602 if (buf != NULL)
603 xmlBufferFree(buf);
604 if (rng != NULL)
605 xmlRelaxNGFree(rng);
606 xmlResetLastError();
607 if ((memt != xmlMemUsed()) && (memt != 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000608 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000609 xmlGetLineNo(cur), xmlMemUsed() - memt);
610 nb_leaks++;
611 }
612 return(ret);
613}
614
615static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000616xsdTestSuite(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000617 if (verbose) {
618 xmlChar *doc = getString(cur, "string(documentation)");
619
620 if (doc != NULL) {
621 printf("Suite %s\n", doc);
622 xmlFree(doc);
623 }
624 }
625 cur = getNext(cur, "./testCase[1]");
626 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000627 xsdTestCase(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000628 cur = getNext(cur, "following-sibling::testCase[1]");
629 }
630
631 return(0);
632}
633
634static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000635xsdTest(void) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000636 xmlDocPtr doc;
637 xmlNodePtr cur;
638 const char *filename = "test/xsdtest/xsdtestsuite.xml";
639 int ret = 0;
640
641 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
642 if (doc == NULL) {
643 fprintf(stderr, "Failed to parse %s\n", filename);
644 return(-1);
645 }
646 printf("## XML Schemas datatypes test suite from James Clark\n");
647
648 cur = xmlDocGetRootElement(doc);
649 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
650 fprintf(stderr, "Unexpected format %s\n", filename);
651 ret = -1;
652 goto done;
653 }
654
655 cur = getNext(cur, "./testSuite[1]");
656 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
657 fprintf(stderr, "Unexpected format %s\n", filename);
658 ret = -1;
659 goto done;
660 }
661 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000662 xsdTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000663 cur = getNext(cur, "following-sibling::testSuite[1]");
664 }
665
666done:
667 if (doc != NULL)
668 xmlFreeDoc(doc);
669 return(ret);
670}
671
672static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000673rngTestSuite(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000674 if (verbose) {
675 xmlChar *doc = getString(cur, "string(documentation)");
676
677 if (doc != NULL) {
678 printf("Suite %s\n", doc);
679 xmlFree(doc);
680 } else {
681 doc = getString(cur, "string(section)");
682 if (doc != NULL) {
683 printf("Section %s\n", doc);
684 xmlFree(doc);
685 }
686 }
687 }
688 cur = getNext(cur, "./testSuite[1]");
689 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000690 xsdTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000691 cur = getNext(cur, "following-sibling::testSuite[1]");
692 }
693
694 return(0);
695}
696
697static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000698rngTest1(void) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000699 xmlDocPtr doc;
700 xmlNodePtr cur;
701 const char *filename = "test/relaxng/OASIS/spectest.xml";
702 int ret = 0;
703
704 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
705 if (doc == NULL) {
706 fprintf(stderr, "Failed to parse %s\n", filename);
707 return(-1);
708 }
Daniel Veillarde84f2312005-07-02 07:31:28 +0000709 printf("## Relax NG test suite from James Clark\n");
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000710
711 cur = xmlDocGetRootElement(doc);
712 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
713 fprintf(stderr, "Unexpected format %s\n", filename);
714 ret = -1;
715 goto done;
716 }
717
718 cur = getNext(cur, "./testSuite[1]");
719 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
720 fprintf(stderr, "Unexpected format %s\n", filename);
721 ret = -1;
722 goto done;
723 }
724 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000725 rngTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000726 cur = getNext(cur, "following-sibling::testSuite[1]");
727 }
728
729done:
730 if (doc != NULL)
731 xmlFreeDoc(doc);
732 return(ret);
733}
734
Daniel Veillarde84f2312005-07-02 07:31:28 +0000735static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000736rngTest2(void) {
Daniel Veillarde84f2312005-07-02 07:31:28 +0000737 xmlDocPtr doc;
738 xmlNodePtr cur;
739 const char *filename = "test/relaxng/testsuite.xml";
740 int ret = 0;
741
742 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
743 if (doc == NULL) {
744 fprintf(stderr, "Failed to parse %s\n", filename);
745 return(-1);
746 }
747 printf("## Relax NG test suite for libxml2\n");
748
749 cur = xmlDocGetRootElement(doc);
750 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
751 fprintf(stderr, "Unexpected format %s\n", filename);
752 ret = -1;
753 goto done;
754 }
755
756 cur = getNext(cur, "./testSuite[1]");
757 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
758 fprintf(stderr, "Unexpected format %s\n", filename);
759 ret = -1;
760 goto done;
761 }
762 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000763 xsdTestSuite(cur);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000764 cur = getNext(cur, "following-sibling::testSuite[1]");
765 }
766
767done:
768 if (doc != NULL)
769 xmlFreeDoc(doc);
770 return(ret);
771}
772
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000773/************************************************************************
774 * *
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000775 * Schemas test suites from W3C/NIST/MS/Sun *
776 * *
777 ************************************************************************/
778
779static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000780xstcTestInstance(xmlNodePtr cur, xmlSchemaPtr schemas,
Daniel Veillard6b6d6802005-07-03 21:00:34 +0000781 const xmlChar *spath, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000782 xmlChar *href = NULL;
783 xmlChar *path = NULL;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000784 xmlChar *validity = NULL;
785 xmlSchemaValidCtxtPtr ctxt = NULL;
786 xmlDocPtr doc = NULL;
787 int ret = 0, mem;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000788
Daniel Veillardde0e4982005-07-03 14:35:44 +0000789 xmlResetLastError();
Daniel Veillardc9352532005-07-04 14:25:34 +0000790 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000791 mem = xmlMemUsed();
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000792 href = getString(cur,
Daniel Veillardde0e4982005-07-03 14:35:44 +0000793 "string(ts:instanceDocument/@xlink:href)");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000794 if ((href == NULL) || (href[0] == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000795 test_log("testGroup line %ld misses href for schemaDocument\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000796 xmlGetLineNo(cur));
797 ret = -1;
798 goto done;
799 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000800 path = xmlBuildURI(href, BAD_CAST base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000801 if (path == NULL) {
802 fprintf(stderr,
803 "Failed to build path to schemas testGroup line %ld : %s\n",
804 xmlGetLineNo(cur), href);
805 ret = -1;
806 goto done;
807 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000808 if (checkTestFile((const char *) path) <= 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000809 test_log("schemas for testGroup line %ld is missing: %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000810 xmlGetLineNo(cur), path);
811 ret = -1;
812 goto done;
813 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000814 validity = getString(cur,
815 "string(ts:expected/@validity)");
816 if (validity == NULL) {
817 fprintf(stderr, "instanceDocument line %ld misses expected validity\n",
818 xmlGetLineNo(cur));
819 ret = -1;
820 goto done;
821 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000822 nb_tests++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000823 doc = xmlReadFile((const char *) path, NULL, XML_PARSE_NOENT);
824 if (doc == NULL) {
825 fprintf(stderr, "instance %s fails to parse\n", path);
826 ret = -1;
827 nb_errors++;
828 goto done;
829 }
830
831 ctxt = xmlSchemaNewValidCtxt(schemas);
832 xmlSchemaSetValidErrors(ctxt,
833 (xmlSchemaValidityErrorFunc) testErrorHandler,
834 (xmlSchemaValidityWarningFunc) testErrorHandler,
835 ctxt);
836 ret = xmlSchemaValidateDoc(ctxt, doc);
837
838 if (xmlStrEqual(validity, BAD_CAST "valid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000839 if (ret > 0) {
840 test_log("valid instance %s failed to validate against %s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000841 path, spath);
842 nb_errors++;
Daniel Veillardc9352532005-07-04 14:25:34 +0000843 } else if (ret < 0) {
844 test_log("valid instance %s got internal error validating %s\n",
845 path, spath);
846 nb_internals++;
847 nb_errors++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000848 }
849 } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
850 if (ret == 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000851 test_log("Failed to detect invalid instance %s against %s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000852 path, spath);
853 nb_errors++;
854 }
855 } else {
Daniel Veillardc9352532005-07-04 14:25:34 +0000856 test_log("instanceDocument line %ld has unexpected validity value%s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000857 xmlGetLineNo(cur), validity);
858 ret = -1;
859 goto done;
860 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000861
862done:
863 if (href != NULL) xmlFree(href);
864 if (path != NULL) xmlFree(path);
Daniel Veillardde0e4982005-07-03 14:35:44 +0000865 if (validity != NULL) xmlFree(validity);
866 if (ctxt != NULL) xmlSchemaFreeValidCtxt(ctxt);
867 if (doc != NULL) xmlFreeDoc(doc);
868 xmlResetLastError();
869 if (mem != xmlMemUsed()) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000870 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000871 xmlGetLineNo(cur), xmlMemUsed() - mem);
872 nb_leaks++;
873 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000874 return(ret);
875}
Daniel Veillardde0e4982005-07-03 14:35:44 +0000876
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000877static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000878xstcTestGroup(xmlNodePtr cur, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000879 xmlChar *href = NULL;
880 xmlChar *path = NULL;
881 xmlChar *validity = NULL;
882 xmlSchemaPtr schemas = NULL;
883 xmlSchemaParserCtxtPtr ctxt;
884 xmlNodePtr instance;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000885 int ret = 0, mem;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000886
Daniel Veillardde0e4982005-07-03 14:35:44 +0000887 xmlResetLastError();
Daniel Veillardc9352532005-07-04 14:25:34 +0000888 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000889 mem = xmlMemUsed();
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000890 href = getString(cur,
891 "string(ts:schemaTest/ts:schemaDocument/@xlink:href)");
892 if ((href == NULL) || (href[0] == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000893 test_log("testGroup line %ld misses href for schemaDocument\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000894 xmlGetLineNo(cur));
895 ret = -1;
896 goto done;
897 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000898 path = xmlBuildURI(href, BAD_CAST base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000899 if (path == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000900 test_log("Failed to build path to schemas testGroup line %ld : %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000901 xmlGetLineNo(cur), href);
902 ret = -1;
903 goto done;
904 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000905 if (checkTestFile((const char *) path) <= 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000906 test_log("schemas for testGroup line %ld is missing: %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000907 xmlGetLineNo(cur), path);
908 ret = -1;
909 goto done;
910 }
911 validity = getString(cur,
912 "string(ts:schemaTest/ts:expected/@validity)");
913 if (validity == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000914 test_log("testGroup line %ld misses expected validity\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000915 xmlGetLineNo(cur));
916 ret = -1;
917 goto done;
918 }
Daniel Veillardc9352532005-07-04 14:25:34 +0000919 nb_tests++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000920 if (xmlStrEqual(validity, BAD_CAST "valid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000921 nb_schematas++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000922 ctxt = xmlSchemaNewParserCtxt((const char *) path);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000923 xmlSchemaSetParserErrors(ctxt,
924 (xmlSchemaValidityErrorFunc) testErrorHandler,
925 (xmlSchemaValidityWarningFunc) testErrorHandler,
926 ctxt);
927 schemas = xmlSchemaParse(ctxt);
928 xmlSchemaFreeParserCtxt(ctxt);
929 if (schemas == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000930 test_log("valid schemas %s failed to parse\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000931 path);
Daniel Veillard90837782005-07-04 15:45:10 +0000932 ret = 1;
933 nb_errors++;
934 }
935 if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
936 test_log("valid schemas %s hit an unimplemented block\n",
937 path);
938 ret = 1;
939 nb_unimplemented++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000940 nb_errors++;
941 }
942 instance = getNext(cur, "./ts:instanceTest[1]");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000943 while (instance != NULL) {
Kasimier T. Buchcikdcac4fc2005-12-09 10:03:27 +0000944 if (schemas != NULL) {
945 xstcTestInstance(instance, schemas, path, base);
946 } else {
947 /*
948 * We'll automatically mark the instances as failed
949 * if the schema was broken.
950 */
951 nb_errors++;
952 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000953 instance = getNext(instance,
Kasimier T. Buchcikdcac4fc2005-12-09 10:03:27 +0000954 "following-sibling::ts:instanceTest[1]");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000955 }
956 } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000957 nb_schematas++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000958 ctxt = xmlSchemaNewParserCtxt((const char *) path);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000959 xmlSchemaSetParserErrors(ctxt,
960 (xmlSchemaValidityErrorFunc) testErrorHandler,
961 (xmlSchemaValidityWarningFunc) testErrorHandler,
962 ctxt);
963 schemas = xmlSchemaParse(ctxt);
964 xmlSchemaFreeParserCtxt(ctxt);
Daniel Veillard4ac5f9a2005-07-04 15:20:27 +0000965 if (schemas != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000966 test_log("Failed to detect error in schemas %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000967 path);
968 nb_errors++;
Daniel Veillard90837782005-07-04 15:45:10 +0000969 ret = 1;
970 }
971 if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
972 nb_unimplemented++;
973 test_log("invalid schemas %s hit an unimplemented block\n",
974 path);
975 ret = 1;
976 nb_errors++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000977 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000978 } else {
Daniel Veillardc9352532005-07-04 14:25:34 +0000979 test_log("testGroup line %ld misses unexpected validity value%s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000980 xmlGetLineNo(cur), validity);
981 ret = -1;
982 goto done;
983 }
984
985done:
986 if (href != NULL) xmlFree(href);
987 if (path != NULL) xmlFree(path);
988 if (validity != NULL) xmlFree(validity);
989 if (schemas != NULL) xmlSchemaFree(schemas);
Daniel Veillardde0e4982005-07-03 14:35:44 +0000990 xmlResetLastError();
991 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000992 test_log("Processing test line %ld %s leaked %d\n",
993 xmlGetLineNo(cur), path, xmlMemUsed() - mem);
Daniel Veillardde0e4982005-07-03 14:35:44 +0000994 nb_leaks++;
995 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000996 return(ret);
997}
998
999static int
Daniel Veillardc9352532005-07-04 14:25:34 +00001000xstcMetadata(const char *metadata, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001001 xmlDocPtr doc;
1002 xmlNodePtr cur;
1003 xmlChar *contributor;
1004 xmlChar *name;
Daniel Veillard6b6d6802005-07-03 21:00:34 +00001005 int ret = 0;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001006
1007 doc = xmlReadFile(metadata, NULL, XML_PARSE_NOENT);
1008 if (doc == NULL) {
1009 fprintf(stderr, "Failed to parse %s\n", metadata);
1010 return(-1);
1011 }
1012
1013 cur = xmlDocGetRootElement(doc);
1014 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSet"))) {
1015 fprintf(stderr, "Unexpected format %s\n", metadata);
1016 return(-1);
1017 }
1018 contributor = xmlGetProp(cur, BAD_CAST "contributor");
1019 if (contributor == NULL) {
1020 contributor = xmlStrdup(BAD_CAST "Unknown");
1021 }
1022 name = xmlGetProp(cur, BAD_CAST "name");
1023 if (name == NULL) {
1024 name = xmlStrdup(BAD_CAST "Unknown");
1025 }
1026 printf("## %s test suite for Schemas version %s\n", contributor, name);
1027 xmlFree(contributor);
1028 xmlFree(name);
1029
1030 cur = getNext(cur, "./ts:testGroup[1]");
1031 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testGroup"))) {
1032 fprintf(stderr, "Unexpected format %s\n", metadata);
1033 ret = -1;
1034 goto done;
1035 }
1036 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +00001037 xstcTestGroup(cur, base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001038 cur = getNext(cur, "following-sibling::ts:testGroup[1]");
1039 }
1040
1041done:
1042 xmlFreeDoc(doc);
1043 return(ret);
1044}
1045
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001046/************************************************************************
1047 * *
1048 * The driver for the tests *
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001049 * *
1050 ************************************************************************/
1051
1052int
1053main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1054 int res, ret = 0;
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001055 int old_errors, old_tests, old_leaks;
1056
Daniel Veillardc9352532005-07-04 14:25:34 +00001057 logfile = fopen(LOGFILE, "w");
1058 if (logfile == NULL) {
1059 fprintf(stderr,
1060 "Could not open the log file, running in verbose mode\n");
1061 verbose = 1;
1062 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001063 initializeLibxml2();
1064
1065 if ((argc >= 2) && (!strcmp(argv[1], "-v")))
1066 verbose = 1;
1067
1068
Daniel Veillarde84f2312005-07-02 07:31:28 +00001069 old_errors = nb_errors;
1070 old_tests = nb_tests;
1071 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001072 res = xsdTest();
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001073 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1074 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1075 else
1076 printf("Ran %d tests, %d errors, %d leaks\n",
1077 nb_tests - old_tests,
1078 nb_errors - old_errors,
1079 nb_leaks - old_leaks);
1080 old_errors = nb_errors;
1081 old_tests = nb_tests;
1082 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001083 res = rngTest1();
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001084 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1085 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1086 else
1087 printf("Ran %d tests, %d errors, %d leaks\n",
1088 nb_tests - old_tests,
1089 nb_errors - old_errors,
1090 nb_leaks - old_leaks);
1091 old_errors = nb_errors;
1092 old_tests = nb_tests;
1093 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001094 res = rngTest2();
Daniel Veillarde84f2312005-07-02 07:31:28 +00001095 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1096 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1097 else
1098 printf("Ran %d tests, %d errors, %d leaks\n",
1099 nb_tests - old_tests,
1100 nb_errors - old_errors,
1101 nb_leaks - old_leaks);
1102 old_errors = nb_errors;
1103 old_tests = nb_tests;
1104 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001105 nb_internals = 0;
1106 nb_schematas = 0;
1107 res = xstcMetadata(
Daniel Veillardde0e4982005-07-03 14:35:44 +00001108 "xstc/Tests/Metadata/NISTXMLSchemaDatatypes.testSet",
1109 "xstc/Tests/Metadata/");
1110 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Daniel Veillardc9352532005-07-04 14:25:34 +00001111 printf("Ran %d tests (%d schemata), no errors\n",
1112 nb_tests - old_tests, nb_schematas);
Daniel Veillardde0e4982005-07-03 14:35:44 +00001113 else
Daniel Veillardc9352532005-07-04 14:25:34 +00001114 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +00001115 nb_tests - old_tests,
Daniel Veillardc9352532005-07-04 14:25:34 +00001116 nb_schematas,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001117 nb_errors - old_errors,
Daniel Veillardc9352532005-07-04 14:25:34 +00001118 nb_internals,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001119 nb_leaks - old_leaks);
1120 old_errors = nb_errors;
1121 old_tests = nb_tests;
1122 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001123 nb_internals = 0;
1124 nb_schematas = 0;
1125 res = xstcMetadata(
Daniel Veillardde0e4982005-07-03 14:35:44 +00001126 "xstc/Tests/Metadata/SunXMLSchema1-0-20020116.testSet",
Daniel Veillardc9352532005-07-04 14:25:34 +00001127 "xstc/Tests/");
Daniel Veillardde0e4982005-07-03 14:35:44 +00001128 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Daniel Veillardc9352532005-07-04 14:25:34 +00001129 printf("Ran %d tests (%d schemata), no errors\n",
1130 nb_tests - old_tests, nb_schematas);
Daniel Veillardde0e4982005-07-03 14:35:44 +00001131 else
Daniel Veillardc9352532005-07-04 14:25:34 +00001132 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +00001133 nb_tests - old_tests,
Daniel Veillardc9352532005-07-04 14:25:34 +00001134 nb_schematas,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001135 nb_errors - old_errors,
Daniel Veillardc9352532005-07-04 14:25:34 +00001136 nb_internals,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001137 nb_leaks - old_leaks);
1138 old_errors = nb_errors;
1139 old_tests = nb_tests;
1140 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001141 nb_internals = 0;
1142 nb_schematas = 0;
1143 res = xstcMetadata(
Daniel Veillardde0e4982005-07-03 14:35:44 +00001144 "xstc/Tests/Metadata/MSXMLSchema1-0-20020116.testSet",
1145 "xstc/Tests/");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001146 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Daniel Veillardc9352532005-07-04 14:25:34 +00001147 printf("Ran %d tests (%d schemata), no errors\n",
1148 nb_tests - old_tests, nb_schematas);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001149 else
Daniel Veillardc9352532005-07-04 14:25:34 +00001150 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001151 nb_tests - old_tests,
Daniel Veillardc9352532005-07-04 14:25:34 +00001152 nb_schematas,
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001153 nb_errors - old_errors,
Daniel Veillardc9352532005-07-04 14:25:34 +00001154 nb_internals,
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001155 nb_leaks - old_leaks);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001156
1157 if ((nb_errors == 0) && (nb_leaks == 0)) {
1158 ret = 0;
1159 printf("Total %d tests, no errors\n",
1160 nb_tests);
1161 } else {
1162 ret = 1;
1163 printf("Total %d tests, %d errors, %d leaks\n",
1164 nb_tests, nb_errors, nb_leaks);
1165 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001166
1167 xmlXPathFreeContext(ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001168 xmlCleanupParser();
1169 xmlMemoryDump();
1170
Daniel Veillardc9352532005-07-04 14:25:34 +00001171 if (logfile != NULL)
1172 fclose(logfile);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001173 return(ret);
1174}
Daniel Veillard95175012005-07-03 16:09:51 +00001175#else /* !SCHEMAS */
1176int
1177main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1178 fprintf(stderr, "runsuite requires support for schemas and xpath in libxml2\n");
1179}
1180#endif