blob: aecd6ae71c90ef733a78add385e2277103895f51 [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 Veillardc9352532005-07-04 14:25:34 +00009#if !defined(_WIN32) || defined(__CYGWIN__)
Daniel Veillardf2e066a2005-06-30 13:04:44 +000010#include <unistd.h>
Daniel Veillardc9352532005-07-04 14:25:34 +000011#endif
Daniel Veillardf2e066a2005-06-30 13:04:44 +000012#include <string.h>
13#include <stdio.h>
Daniel Veillardf2e066a2005-06-30 13:04:44 +000014#include <sys/types.h>
15#include <sys/stat.h>
16#include <fcntl.h>
Daniel Veillardf2e066a2005-06-30 13:04:44 +000017
18#include <libxml/parser.h>
Daniel Veillarde84f2312005-07-02 07:31:28 +000019#include <libxml/parserInternals.h>
Daniel Veillardf2e066a2005-06-30 13:04:44 +000020#include <libxml/tree.h>
21#include <libxml/uri.h>
Daniel Veillard95175012005-07-03 16:09:51 +000022#if defined(LIBXML_SCHEMAS_ENABLED) && defined(LIBXML_XPATH_ENABLED)
Daniel Veillardf2e066a2005-06-30 13:04:44 +000023#include <libxml/xmlreader.h>
24
25#include <libxml/xpath.h>
26#include <libxml/xpathInternals.h>
27
28#include <libxml/relaxng.h>
29#include <libxml/xmlschemas.h>
30#include <libxml/xmlschemastypes.h>
31
Daniel Veillardc9352532005-07-04 14:25:34 +000032#define LOGFILE "runsuite.log"
Daniel Veillard24505b02005-07-28 23:49:35 +000033static FILE *logfile = NULL;
34static int verbose = 0;
Kasimier T. Buchcik87db1cf2005-07-05 10:40:52 +000035
36#if defined(_WIN32) && !defined(__CYGWIN__)
37#define vsnprintf _vsnprintf
38#define snprintf _snprintf
39#endif
Daniel Veillardc9352532005-07-04 14:25:34 +000040
Daniel Veillardf2e066a2005-06-30 13:04:44 +000041/************************************************************************
42 * *
43 * File name and path utilities *
44 * *
45 ************************************************************************/
46
47static int checkTestFile(const char *filename) {
48 struct stat buf;
49
50 if (stat(filename, &buf) == -1)
51 return(0);
52
Daniel Veillardcfbb0dd2005-07-04 17:12:01 +000053#if defined(_WIN32) && !defined(__CYGWIN__)
54 if (!(buf.st_mode & _S_IFREG))
55 return(0);
56#else
Daniel Veillardf2e066a2005-06-30 13:04:44 +000057 if (!S_ISREG(buf.st_mode))
58 return(0);
Daniel Veillardcfbb0dd2005-07-04 17:12:01 +000059#endif
Daniel Veillardf2e066a2005-06-30 13:04:44 +000060
61 return(1);
62}
Daniel Veillardcfbb0dd2005-07-04 17:12:01 +000063
Daniel Veillarde84f2312005-07-02 07:31:28 +000064static xmlChar *composeDir(const xmlChar *dir, const xmlChar *path) {
65 char buf[500];
66
67 if (dir == NULL) return(xmlStrdup(path));
68 if (path == NULL) return(NULL);
69
70 snprintf(buf, 500, "%s/%s", (const char *) dir, (const char *) path);
71 return(xmlStrdup((const xmlChar *) buf));
72}
Daniel Veillardf2e066a2005-06-30 13:04:44 +000073
74/************************************************************************
75 * *
76 * Libxml2 specific routines *
77 * *
78 ************************************************************************/
79
80static int nb_tests = 0;
81static int nb_errors = 0;
Daniel Veillardc9352532005-07-04 14:25:34 +000082static int nb_internals = 0;
83static int nb_schematas = 0;
Daniel Veillard90837782005-07-04 15:45:10 +000084static int nb_unimplemented = 0;
Daniel Veillardf2e066a2005-06-30 13:04:44 +000085static int nb_leaks = 0;
86static long libxmlMemoryAllocatedBase = 0;
87static int extraMemoryFromResolver = 0;
88
89static int
90fatalError(void) {
91 fprintf(stderr, "Exitting tests on fatal error\n");
92 exit(1);
93}
94
95/*
Daniel Veillarde84f2312005-07-02 07:31:28 +000096 * that's needed to implement <resource>
97 */
98#define MAX_ENTITIES 20
Daniel Veillard24505b02005-07-28 23:49:35 +000099static char *testEntitiesName[MAX_ENTITIES];
100static char *testEntitiesValue[MAX_ENTITIES];
101static int nb_entities = 0;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000102static void resetEntities(void) {
103 int i;
104
105 for (i = 0;i < nb_entities;i++) {
106 if (testEntitiesName[i] != NULL)
107 xmlFree(testEntitiesName[i]);
108 if (testEntitiesValue[i] != NULL)
109 xmlFree(testEntitiesValue[i]);
110 }
111 nb_entities = 0;
112}
113static int addEntity(char *name, char *content) {
114 if (nb_entities >= MAX_ENTITIES) {
115 fprintf(stderr, "Too many entities defined\n");
116 return(-1);
117 }
118 testEntitiesName[nb_entities] = name;
119 testEntitiesValue[nb_entities] = content;
120 nb_entities++;
121 return(0);
122}
123
124/*
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000125 * We need to trap calls to the resolver to not account memory for the catalog
126 * which is shared to the current running test. We also don't want to have
127 * network downloads modifying tests.
128 */
129static xmlParserInputPtr
130testExternalEntityLoader(const char *URL, const char *ID,
131 xmlParserCtxtPtr ctxt) {
132 xmlParserInputPtr ret;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000133 int i;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000134
Daniel Veillarde84f2312005-07-02 07:31:28 +0000135 for (i = 0;i < nb_entities;i++) {
136 if (!strcmp(testEntitiesName[i], URL)) {
137 ret = xmlNewStringInputStream(ctxt,
138 (const xmlChar *) testEntitiesValue[i]);
139 if (ret != NULL) {
140 ret->filename = (const char *)
141 xmlStrdup((xmlChar *)testEntitiesName[i]);
142 }
143 return(ret);
144 }
145 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000146 if (checkTestFile(URL)) {
147 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
148 } else {
149 int memused = xmlMemUsed();
150 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
151 extraMemoryFromResolver += xmlMemUsed() - memused;
152 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000153#if 0
Daniel Veillarde84f2312005-07-02 07:31:28 +0000154 if (ret == NULL) {
155 fprintf(stderr, "Failed to find resource %s\n", URL);
156 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000157#endif
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000158
159 return(ret);
160}
161
162/*
163 * Trapping the error messages at the generic level to grab the equivalent of
164 * stderr messages on CLI tools.
165 */
166static char testErrors[32769];
167static int testErrorsSize = 0;
168
Daniel Veillardc9352532005-07-04 14:25:34 +0000169static void test_log(const char *msg, ...) {
170 va_list args;
171 if (logfile != NULL) {
172 fprintf(logfile, "\n------------\n");
173 va_start(args, msg);
174 vfprintf(logfile, msg, args);
175 va_end(args);
176 fprintf(logfile, "%s", testErrors);
177 testErrorsSize = 0; testErrors[0] = 0;
178 }
179 if (verbose) {
180 va_start(args, msg);
181 vfprintf(stderr, msg, args);
182 va_end(args);
183 }
184}
185
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000186static void
187testErrorHandler(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
188 va_list args;
189 int res;
190
191 if (testErrorsSize >= 32768)
192 return;
193 va_start(args, msg);
194 res = vsnprintf(&testErrors[testErrorsSize],
195 32768 - testErrorsSize,
196 msg, args);
197 va_end(args);
198 if (testErrorsSize + res >= 32768) {
199 /* buffer is full */
200 testErrorsSize = 32768;
201 testErrors[testErrorsSize] = 0;
202 } else {
203 testErrorsSize += res;
204 }
205 testErrors[testErrorsSize] = 0;
206}
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000207
Daniel Veillard24505b02005-07-28 23:49:35 +0000208static xmlXPathContextPtr ctxtXPath;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000209
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000210static void
211initializeLibxml2(void) {
212 xmlGetWarningsDefaultValue = 0;
213 xmlPedanticParserDefault(0);
214
215 xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
216 xmlInitParser();
217 xmlSetExternalEntityLoader(testExternalEntityLoader);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000218 ctxtXPath = xmlXPathNewContext(NULL);
219 /* used as default nanemspace in xstc tests */
220 xmlXPathRegisterNs(ctxtXPath, BAD_CAST "ts", BAD_CAST "TestSuite");
221 xmlXPathRegisterNs(ctxtXPath, BAD_CAST "xlink",
222 BAD_CAST "http://www.w3.org/1999/xlink");
223 xmlSetGenericErrorFunc(NULL, testErrorHandler);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000224#ifdef LIBXML_SCHEMAS_ENABLED
225 xmlSchemaInitTypes();
226 xmlRelaxNGInitTypes();
227#endif
228 libxmlMemoryAllocatedBase = xmlMemUsed();
229}
230
231static xmlNodePtr
232getNext(xmlNodePtr cur, const char *xpath) {
233 xmlNodePtr ret = NULL;
234 xmlXPathObjectPtr res;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000235 xmlXPathCompExprPtr comp;
236
237 if ((cur == NULL) || (cur->doc == NULL) || (xpath == NULL))
238 return(NULL);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000239 ctxtXPath->doc = cur->doc;
240 ctxtXPath->node = cur;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000241 comp = xmlXPathCompile(BAD_CAST xpath);
242 if (comp == NULL) {
243 fprintf(stderr, "Failed to compile %s\n", xpath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000244 return(NULL);
245 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000246 res = xmlXPathCompiledEval(comp, ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000247 xmlXPathFreeCompExpr(comp);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000248 if (res == NULL)
249 return(NULL);
250 if ((res->type == XPATH_NODESET) &&
251 (res->nodesetval != NULL) &&
252 (res->nodesetval->nodeNr > 0) &&
253 (res->nodesetval->nodeTab != NULL))
254 ret = res->nodesetval->nodeTab[0];
255 xmlXPathFreeObject(res);
256 return(ret);
257}
258
259static xmlChar *
260getString(xmlNodePtr cur, const char *xpath) {
261 xmlChar *ret = NULL;
262 xmlXPathObjectPtr res;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000263 xmlXPathCompExprPtr comp;
264
265 if ((cur == NULL) || (cur->doc == NULL) || (xpath == NULL))
266 return(NULL);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000267 ctxtXPath->doc = cur->doc;
268 ctxtXPath->node = cur;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000269 comp = xmlXPathCompile(BAD_CAST xpath);
270 if (comp == NULL) {
271 fprintf(stderr, "Failed to compile %s\n", xpath);
272 return(NULL);
273 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000274 res = xmlXPathCompiledEval(comp, ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000275 xmlXPathFreeCompExpr(comp);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000276 if (res == NULL)
277 return(NULL);
278 if (res->type == XPATH_STRING) {
279 ret = res->stringval;
280 res->stringval = NULL;
281 }
282 xmlXPathFreeObject(res);
283 return(ret);
284}
285
286/************************************************************************
287 * *
288 * Test test/xsdtest/xsdtestsuite.xml *
289 * *
290 ************************************************************************/
291
292static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000293xsdIncorectTestCase(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000294 xmlNodePtr test;
295 xmlBufferPtr buf;
296 xmlRelaxNGParserCtxtPtr pctxt;
297 xmlRelaxNGPtr rng = NULL;
298 int ret = 0, memt;
299
300 cur = getNext(cur, "./incorrect[1]");
301 if (cur == NULL) {
302 return(0);
303 }
304
305 test = getNext(cur, "./*");
306 if (test == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000307 test_log("Failed to find test in correct line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000308 xmlGetLineNo(cur));
309 return(1);
310 }
311
312 memt = xmlMemUsed();
313 extraMemoryFromResolver = 0;
314 /*
315 * dump the schemas to a buffer, then reparse it and compile the schemas
316 */
317 buf = xmlBufferCreate();
318 if (buf == NULL) {
319 fprintf(stderr, "out of memory !\n");
320 fatalError();
321 }
322 xmlNodeDump(buf, test->doc, test, 0, 0);
323 pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
324 xmlRelaxNGSetParserErrors(pctxt,
325 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
326 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
327 pctxt);
328 rng = xmlRelaxNGParse(pctxt);
329 xmlRelaxNGFreeParserCtxt(pctxt);
330 if (rng != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000331 test_log("Failed to detect incorect RNG line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000332 xmlGetLineNo(test));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000333 ret = 1;
334 goto done;
335 }
336
337done:
338 if (buf != NULL)
339 xmlBufferFree(buf);
340 if (rng != NULL)
341 xmlRelaxNGFree(rng);
342 xmlResetLastError();
343 if ((memt != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000344 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000345 xmlGetLineNo(cur), xmlMemUsed() - memt);
346 nb_leaks++;
347 }
348 return(ret);
349}
350
Daniel Veillarde84f2312005-07-02 07:31:28 +0000351static void
352installResources(xmlNodePtr tst, const xmlChar *base) {
353 xmlNodePtr test;
354 xmlBufferPtr buf;
355 xmlChar *name, *content, *res;
Daniel Veillardc9352532005-07-04 14:25:34 +0000356
Daniel Veillarde84f2312005-07-02 07:31:28 +0000357 buf = xmlBufferCreate();
358 if (buf == NULL) {
359 fprintf(stderr, "out of memory !\n");
360 fatalError();
361 }
362 xmlNodeDump(buf, tst->doc, tst, 0, 0);
363
364 while (tst != NULL) {
365 test = getNext(tst, "./*");
366 if (test != NULL) {
367 xmlBufferEmpty(buf);
368 xmlNodeDump(buf, test->doc, test, 0, 0);
369 name = getString(tst, "string(@name)");
370 content = xmlStrdup(buf->content);
371 if ((name != NULL) && (content != NULL)) {
372 res = composeDir(base, name);
373 xmlFree(name);
374 addEntity((char *) res, (char *) content);
375 } else {
376 if (name != NULL) xmlFree(name);
377 if (content != NULL) xmlFree(content);
378 }
379 }
380 tst = getNext(tst, "following-sibling::resource[1]");
381 }
382 if (buf != NULL)
383 xmlBufferFree(buf);
384}
385
386static void
387installDirs(xmlNodePtr tst, const xmlChar *base) {
388 xmlNodePtr test;
389 xmlChar *name, *res;
390
391 name = getString(tst, "string(@name)");
392 if (name == NULL)
393 return;
394 res = composeDir(base, name);
395 xmlFree(name);
396 if (res == NULL) {
397 return;
398 }
399 /* Now process resources and subdir recursively */
400 test = getNext(tst, "./resource[1]");
401 if (test != NULL) {
402 installResources(test, res);
403 }
404 test = getNext(tst, "./dir[1]");
405 while (test != NULL) {
406 installDirs(test, res);
407 test = getNext(test, "following-sibling::dir[1]");
408 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000409 xmlFree(res);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000410}
411
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000412static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000413xsdTestCase(xmlNodePtr tst) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000414 xmlNodePtr test, tmp, cur;
415 xmlBufferPtr buf;
416 xmlDocPtr doc = NULL;
417 xmlRelaxNGParserCtxtPtr pctxt;
418 xmlRelaxNGValidCtxtPtr ctxt;
419 xmlRelaxNGPtr rng = NULL;
420 int ret = 0, mem, memt;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000421 xmlChar *dtd;
422
423 resetEntities();
Daniel Veillardc9352532005-07-04 14:25:34 +0000424 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000425
426 tmp = getNext(tst, "./dir[1]");
427 if (tmp != NULL) {
428 installDirs(tmp, NULL);
429 }
430 tmp = getNext(tst, "./resource[1]");
431 if (tmp != NULL) {
432 installResources(tmp, NULL);
433 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000434
435 cur = getNext(tst, "./correct[1]");
436 if (cur == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000437 return(xsdIncorectTestCase(tst));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000438 }
439
440 test = getNext(cur, "./*");
441 if (test == NULL) {
442 fprintf(stderr, "Failed to find test in correct line %ld\n",
443 xmlGetLineNo(cur));
444 return(1);
445 }
446
447 memt = xmlMemUsed();
448 extraMemoryFromResolver = 0;
449 /*
450 * dump the schemas to a buffer, then reparse it and compile the schemas
451 */
452 buf = xmlBufferCreate();
453 if (buf == NULL) {
454 fprintf(stderr, "out of memory !\n");
455 fatalError();
456 }
457 xmlNodeDump(buf, test->doc, test, 0, 0);
458 pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
459 xmlRelaxNGSetParserErrors(pctxt,
460 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
461 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
462 pctxt);
463 rng = xmlRelaxNGParse(pctxt);
464 xmlRelaxNGFreeParserCtxt(pctxt);
465 if (extraMemoryFromResolver)
466 memt = 0;
467
468 if (rng == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000469 test_log("Failed to parse RNGtest line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000470 xmlGetLineNo(test));
471 nb_errors++;
472 ret = 1;
473 goto done;
474 }
475 /*
476 * now scan all the siblings of correct to process the <valid> tests
477 */
478 tmp = getNext(cur, "following-sibling::valid[1]");
479 while (tmp != NULL) {
Daniel Veillarde84f2312005-07-02 07:31:28 +0000480 dtd = xmlGetProp(tmp, BAD_CAST "dtd");
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000481 test = getNext(tmp, "./*");
482 if (test == NULL) {
483 fprintf(stderr, "Failed to find test in <valid> line %ld\n",
484 xmlGetLineNo(tmp));
485
486 } else {
487 xmlBufferEmpty(buf);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000488 if (dtd != NULL)
489 xmlBufferAdd(buf, dtd, -1);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000490 xmlNodeDump(buf, test->doc, test, 0, 0);
491
492 /*
493 * We are ready to run the test
494 */
495 mem = xmlMemUsed();
496 extraMemoryFromResolver = 0;
497 doc = xmlReadMemory((const char *)buf->content, buf->use,
498 "test", NULL, 0);
499 if (doc == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000500 test_log("Failed to parse valid instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000501 xmlGetLineNo(tmp));
502 nb_errors++;
503 } else {
504 nb_tests++;
505 ctxt = xmlRelaxNGNewValidCtxt(rng);
506 xmlRelaxNGSetValidErrors(ctxt,
507 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
508 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
509 ctxt);
510 ret = xmlRelaxNGValidateDoc(ctxt, doc);
511 xmlRelaxNGFreeValidCtxt(ctxt);
512 if (ret > 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000513 test_log("Failed to validate valid instance line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000514 xmlGetLineNo(tmp));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000515 nb_errors++;
516 } else if (ret < 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000517 test_log("Internal error validating instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000518 xmlGetLineNo(tmp));
519 nb_errors++;
520 }
521 xmlFreeDoc(doc);
522 }
523 xmlResetLastError();
524 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000525 test_log("Validation of instance line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000526 xmlGetLineNo(tmp), xmlMemUsed() - mem);
527 xmlMemoryDump();
528 nb_leaks++;
529 }
530 }
Daniel Veillarde84f2312005-07-02 07:31:28 +0000531 if (dtd != NULL)
532 xmlFree(dtd);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000533 tmp = getNext(tmp, "following-sibling::valid[1]");
534 }
535 /*
536 * now scan all the siblings of correct to process the <invalid> tests
537 */
538 tmp = getNext(cur, "following-sibling::invalid[1]");
539 while (tmp != NULL) {
540 test = getNext(tmp, "./*");
541 if (test == NULL) {
542 fprintf(stderr, "Failed to find test in <invalid> line %ld\n",
543 xmlGetLineNo(tmp));
544
545 } else {
546 xmlBufferEmpty(buf);
547 xmlNodeDump(buf, test->doc, test, 0, 0);
548
549 /*
550 * We are ready to run the test
551 */
552 mem = xmlMemUsed();
553 extraMemoryFromResolver = 0;
554 doc = xmlReadMemory((const char *)buf->content, buf->use,
555 "test", NULL, 0);
556 if (doc == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000557 test_log("Failed to parse valid instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000558 xmlGetLineNo(tmp));
559 nb_errors++;
560 } else {
561 nb_tests++;
562 ctxt = xmlRelaxNGNewValidCtxt(rng);
563 xmlRelaxNGSetValidErrors(ctxt,
564 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
565 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
566 ctxt);
567 ret = xmlRelaxNGValidateDoc(ctxt, doc);
568 xmlRelaxNGFreeValidCtxt(ctxt);
569 if (ret == 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000570 test_log("Failed to detect invalid instance line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000571 xmlGetLineNo(tmp));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000572 nb_errors++;
573 } else if (ret < 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000574 test_log("Internal error validating instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000575 xmlGetLineNo(tmp));
576 nb_errors++;
577 }
578 xmlFreeDoc(doc);
579 }
580 xmlResetLastError();
581 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000582 test_log("Validation of instance line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000583 xmlGetLineNo(tmp), xmlMemUsed() - mem);
584 xmlMemoryDump();
585 nb_leaks++;
586 }
587 }
588 tmp = getNext(tmp, "following-sibling::invalid[1]");
589 }
590
591done:
592 if (buf != NULL)
593 xmlBufferFree(buf);
594 if (rng != NULL)
595 xmlRelaxNGFree(rng);
596 xmlResetLastError();
597 if ((memt != xmlMemUsed()) && (memt != 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000598 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000599 xmlGetLineNo(cur), xmlMemUsed() - memt);
600 nb_leaks++;
601 }
602 return(ret);
603}
604
605static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000606xsdTestSuite(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000607 if (verbose) {
608 xmlChar *doc = getString(cur, "string(documentation)");
609
610 if (doc != NULL) {
611 printf("Suite %s\n", doc);
612 xmlFree(doc);
613 }
614 }
615 cur = getNext(cur, "./testCase[1]");
616 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000617 xsdTestCase(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000618 cur = getNext(cur, "following-sibling::testCase[1]");
619 }
620
621 return(0);
622}
623
624static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000625xsdTest(void) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000626 xmlDocPtr doc;
627 xmlNodePtr cur;
628 const char *filename = "test/xsdtest/xsdtestsuite.xml";
629 int ret = 0;
630
631 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
632 if (doc == NULL) {
633 fprintf(stderr, "Failed to parse %s\n", filename);
634 return(-1);
635 }
636 printf("## XML Schemas datatypes test suite from James Clark\n");
637
638 cur = xmlDocGetRootElement(doc);
639 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
640 fprintf(stderr, "Unexpected format %s\n", filename);
641 ret = -1;
642 goto done;
643 }
644
645 cur = getNext(cur, "./testSuite[1]");
646 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
647 fprintf(stderr, "Unexpected format %s\n", filename);
648 ret = -1;
649 goto done;
650 }
651 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000652 xsdTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000653 cur = getNext(cur, "following-sibling::testSuite[1]");
654 }
655
656done:
657 if (doc != NULL)
658 xmlFreeDoc(doc);
659 return(ret);
660}
661
662static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000663rngTestSuite(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000664 if (verbose) {
665 xmlChar *doc = getString(cur, "string(documentation)");
666
667 if (doc != NULL) {
668 printf("Suite %s\n", doc);
669 xmlFree(doc);
670 } else {
671 doc = getString(cur, "string(section)");
672 if (doc != NULL) {
673 printf("Section %s\n", doc);
674 xmlFree(doc);
675 }
676 }
677 }
678 cur = getNext(cur, "./testSuite[1]");
679 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000680 xsdTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000681 cur = getNext(cur, "following-sibling::testSuite[1]");
682 }
683
684 return(0);
685}
686
687static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000688rngTest1(void) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000689 xmlDocPtr doc;
690 xmlNodePtr cur;
691 const char *filename = "test/relaxng/OASIS/spectest.xml";
692 int ret = 0;
693
694 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
695 if (doc == NULL) {
696 fprintf(stderr, "Failed to parse %s\n", filename);
697 return(-1);
698 }
Daniel Veillarde84f2312005-07-02 07:31:28 +0000699 printf("## Relax NG test suite from James Clark\n");
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000700
701 cur = xmlDocGetRootElement(doc);
702 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
703 fprintf(stderr, "Unexpected format %s\n", filename);
704 ret = -1;
705 goto done;
706 }
707
708 cur = getNext(cur, "./testSuite[1]");
709 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
710 fprintf(stderr, "Unexpected format %s\n", filename);
711 ret = -1;
712 goto done;
713 }
714 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000715 rngTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000716 cur = getNext(cur, "following-sibling::testSuite[1]");
717 }
718
719done:
720 if (doc != NULL)
721 xmlFreeDoc(doc);
722 return(ret);
723}
724
Daniel Veillarde84f2312005-07-02 07:31:28 +0000725static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000726rngTest2(void) {
Daniel Veillarde84f2312005-07-02 07:31:28 +0000727 xmlDocPtr doc;
728 xmlNodePtr cur;
729 const char *filename = "test/relaxng/testsuite.xml";
730 int ret = 0;
731
732 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
733 if (doc == NULL) {
734 fprintf(stderr, "Failed to parse %s\n", filename);
735 return(-1);
736 }
737 printf("## Relax NG test suite for libxml2\n");
738
739 cur = xmlDocGetRootElement(doc);
740 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
741 fprintf(stderr, "Unexpected format %s\n", filename);
742 ret = -1;
743 goto done;
744 }
745
746 cur = getNext(cur, "./testSuite[1]");
747 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
748 fprintf(stderr, "Unexpected format %s\n", filename);
749 ret = -1;
750 goto done;
751 }
752 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000753 xsdTestSuite(cur);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000754 cur = getNext(cur, "following-sibling::testSuite[1]");
755 }
756
757done:
758 if (doc != NULL)
759 xmlFreeDoc(doc);
760 return(ret);
761}
762
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000763/************************************************************************
764 * *
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000765 * Schemas test suites from W3C/NIST/MS/Sun *
766 * *
767 ************************************************************************/
768
769static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000770xstcTestInstance(xmlNodePtr cur, xmlSchemaPtr schemas,
Daniel Veillard6b6d6802005-07-03 21:00:34 +0000771 const xmlChar *spath, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000772 xmlChar *href = NULL;
773 xmlChar *path = NULL;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000774 xmlChar *validity = NULL;
775 xmlSchemaValidCtxtPtr ctxt = NULL;
776 xmlDocPtr doc = NULL;
777 int ret = 0, mem;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000778
Daniel Veillardde0e4982005-07-03 14:35:44 +0000779 xmlResetLastError();
Daniel Veillardc9352532005-07-04 14:25:34 +0000780 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000781 mem = xmlMemUsed();
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000782 href = getString(cur,
Daniel Veillardde0e4982005-07-03 14:35:44 +0000783 "string(ts:instanceDocument/@xlink:href)");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000784 if ((href == NULL) || (href[0] == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000785 test_log("testGroup line %ld misses href for schemaDocument\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000786 xmlGetLineNo(cur));
787 ret = -1;
788 goto done;
789 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000790 path = xmlBuildURI(href, BAD_CAST base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000791 if (path == NULL) {
792 fprintf(stderr,
793 "Failed to build path to schemas testGroup line %ld : %s\n",
794 xmlGetLineNo(cur), href);
795 ret = -1;
796 goto done;
797 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000798 if (checkTestFile((const char *) path) <= 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000799 test_log("schemas for testGroup line %ld is missing: %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000800 xmlGetLineNo(cur), path);
801 ret = -1;
802 goto done;
803 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000804 validity = getString(cur,
805 "string(ts:expected/@validity)");
806 if (validity == NULL) {
807 fprintf(stderr, "instanceDocument line %ld misses expected validity\n",
808 xmlGetLineNo(cur));
809 ret = -1;
810 goto done;
811 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000812 nb_tests++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000813 doc = xmlReadFile((const char *) path, NULL, XML_PARSE_NOENT);
814 if (doc == NULL) {
815 fprintf(stderr, "instance %s fails to parse\n", path);
816 ret = -1;
817 nb_errors++;
818 goto done;
819 }
820
821 ctxt = xmlSchemaNewValidCtxt(schemas);
822 xmlSchemaSetValidErrors(ctxt,
823 (xmlSchemaValidityErrorFunc) testErrorHandler,
824 (xmlSchemaValidityWarningFunc) testErrorHandler,
825 ctxt);
826 ret = xmlSchemaValidateDoc(ctxt, doc);
827
828 if (xmlStrEqual(validity, BAD_CAST "valid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000829 if (ret > 0) {
830 test_log("valid instance %s failed to validate against %s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000831 path, spath);
832 nb_errors++;
Daniel Veillardc9352532005-07-04 14:25:34 +0000833 } else if (ret < 0) {
834 test_log("valid instance %s got internal error validating %s\n",
835 path, spath);
836 nb_internals++;
837 nb_errors++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000838 }
839 } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
840 if (ret == 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000841 test_log("Failed to detect invalid instance %s against %s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000842 path, spath);
843 nb_errors++;
844 }
845 } else {
Daniel Veillardc9352532005-07-04 14:25:34 +0000846 test_log("instanceDocument line %ld has unexpected validity value%s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000847 xmlGetLineNo(cur), validity);
848 ret = -1;
849 goto done;
850 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000851
852done:
853 if (href != NULL) xmlFree(href);
854 if (path != NULL) xmlFree(path);
Daniel Veillardde0e4982005-07-03 14:35:44 +0000855 if (validity != NULL) xmlFree(validity);
856 if (ctxt != NULL) xmlSchemaFreeValidCtxt(ctxt);
857 if (doc != NULL) xmlFreeDoc(doc);
858 xmlResetLastError();
859 if (mem != xmlMemUsed()) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000860 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000861 xmlGetLineNo(cur), xmlMemUsed() - mem);
862 nb_leaks++;
863 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000864 return(ret);
865}
Daniel Veillardde0e4982005-07-03 14:35:44 +0000866
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000867static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000868xstcTestGroup(xmlNodePtr cur, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000869 xmlChar *href = NULL;
870 xmlChar *path = NULL;
871 xmlChar *validity = NULL;
872 xmlSchemaPtr schemas = NULL;
873 xmlSchemaParserCtxtPtr ctxt;
874 xmlNodePtr instance;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000875 int ret = 0, mem;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000876
Daniel Veillardde0e4982005-07-03 14:35:44 +0000877 xmlResetLastError();
Daniel Veillardc9352532005-07-04 14:25:34 +0000878 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000879 mem = xmlMemUsed();
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000880 href = getString(cur,
881 "string(ts:schemaTest/ts:schemaDocument/@xlink:href)");
882 if ((href == NULL) || (href[0] == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000883 test_log("testGroup line %ld misses href for schemaDocument\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000884 xmlGetLineNo(cur));
885 ret = -1;
886 goto done;
887 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000888 path = xmlBuildURI(href, BAD_CAST base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000889 if (path == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000890 test_log("Failed to build path to schemas testGroup line %ld : %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000891 xmlGetLineNo(cur), href);
892 ret = -1;
893 goto done;
894 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000895 if (checkTestFile((const char *) path) <= 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000896 test_log("schemas for testGroup line %ld is missing: %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000897 xmlGetLineNo(cur), path);
898 ret = -1;
899 goto done;
900 }
901 validity = getString(cur,
902 "string(ts:schemaTest/ts:expected/@validity)");
903 if (validity == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000904 test_log("testGroup line %ld misses expected validity\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000905 xmlGetLineNo(cur));
906 ret = -1;
907 goto done;
908 }
Daniel Veillardc9352532005-07-04 14:25:34 +0000909 nb_tests++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000910 if (xmlStrEqual(validity, BAD_CAST "valid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000911 nb_schematas++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000912 ctxt = xmlSchemaNewParserCtxt((const char *) path);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000913 xmlSchemaSetParserErrors(ctxt,
914 (xmlSchemaValidityErrorFunc) testErrorHandler,
915 (xmlSchemaValidityWarningFunc) testErrorHandler,
916 ctxt);
917 schemas = xmlSchemaParse(ctxt);
918 xmlSchemaFreeParserCtxt(ctxt);
919 if (schemas == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000920 test_log("valid schemas %s failed to parse\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000921 path);
Daniel Veillard90837782005-07-04 15:45:10 +0000922 ret = 1;
923 nb_errors++;
924 }
925 if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
926 test_log("valid schemas %s hit an unimplemented block\n",
927 path);
928 ret = 1;
929 nb_unimplemented++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000930 nb_errors++;
931 }
932 instance = getNext(cur, "./ts:instanceTest[1]");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000933 while (instance != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000934 xstcTestInstance(instance, schemas, path, base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000935 instance = getNext(instance,
936 "following-sibling::ts:instanceTest[1]");
937 }
938 } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000939 nb_schematas++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000940 ctxt = xmlSchemaNewParserCtxt((const char *) path);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000941 xmlSchemaSetParserErrors(ctxt,
942 (xmlSchemaValidityErrorFunc) testErrorHandler,
943 (xmlSchemaValidityWarningFunc) testErrorHandler,
944 ctxt);
945 schemas = xmlSchemaParse(ctxt);
946 xmlSchemaFreeParserCtxt(ctxt);
Daniel Veillard4ac5f9a2005-07-04 15:20:27 +0000947 if (schemas != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000948 test_log("Failed to detect error in schemas %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000949 path);
950 nb_errors++;
Daniel Veillard90837782005-07-04 15:45:10 +0000951 ret = 1;
952 }
953 if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
954 nb_unimplemented++;
955 test_log("invalid schemas %s hit an unimplemented block\n",
956 path);
957 ret = 1;
958 nb_errors++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000959 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000960 } else {
Daniel Veillardc9352532005-07-04 14:25:34 +0000961 test_log("testGroup line %ld misses unexpected validity value%s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000962 xmlGetLineNo(cur), validity);
963 ret = -1;
964 goto done;
965 }
966
967done:
968 if (href != NULL) xmlFree(href);
969 if (path != NULL) xmlFree(path);
970 if (validity != NULL) xmlFree(validity);
971 if (schemas != NULL) xmlSchemaFree(schemas);
Daniel Veillardde0e4982005-07-03 14:35:44 +0000972 xmlResetLastError();
973 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000974 test_log("Processing test line %ld %s leaked %d\n",
975 xmlGetLineNo(cur), path, xmlMemUsed() - mem);
Daniel Veillardde0e4982005-07-03 14:35:44 +0000976 nb_leaks++;
977 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000978 return(ret);
979}
980
981static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000982xstcMetadata(const char *metadata, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000983 xmlDocPtr doc;
984 xmlNodePtr cur;
985 xmlChar *contributor;
986 xmlChar *name;
Daniel Veillard6b6d6802005-07-03 21:00:34 +0000987 int ret = 0;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000988
989 doc = xmlReadFile(metadata, NULL, XML_PARSE_NOENT);
990 if (doc == NULL) {
991 fprintf(stderr, "Failed to parse %s\n", metadata);
992 return(-1);
993 }
994
995 cur = xmlDocGetRootElement(doc);
996 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSet"))) {
997 fprintf(stderr, "Unexpected format %s\n", metadata);
998 return(-1);
999 }
1000 contributor = xmlGetProp(cur, BAD_CAST "contributor");
1001 if (contributor == NULL) {
1002 contributor = xmlStrdup(BAD_CAST "Unknown");
1003 }
1004 name = xmlGetProp(cur, BAD_CAST "name");
1005 if (name == NULL) {
1006 name = xmlStrdup(BAD_CAST "Unknown");
1007 }
1008 printf("## %s test suite for Schemas version %s\n", contributor, name);
1009 xmlFree(contributor);
1010 xmlFree(name);
1011
1012 cur = getNext(cur, "./ts:testGroup[1]");
1013 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testGroup"))) {
1014 fprintf(stderr, "Unexpected format %s\n", metadata);
1015 ret = -1;
1016 goto done;
1017 }
1018 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +00001019 xstcTestGroup(cur, base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001020 cur = getNext(cur, "following-sibling::ts:testGroup[1]");
1021 }
1022
1023done:
1024 xmlFreeDoc(doc);
1025 return(ret);
1026}
1027
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001028/************************************************************************
1029 * *
1030 * The driver for the tests *
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001031 * *
1032 ************************************************************************/
1033
1034int
1035main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1036 int res, ret = 0;
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001037 int old_errors, old_tests, old_leaks;
1038
Daniel Veillardc9352532005-07-04 14:25:34 +00001039 logfile = fopen(LOGFILE, "w");
1040 if (logfile == NULL) {
1041 fprintf(stderr,
1042 "Could not open the log file, running in verbose mode\n");
1043 verbose = 1;
1044 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001045 initializeLibxml2();
1046
1047 if ((argc >= 2) && (!strcmp(argv[1], "-v")))
1048 verbose = 1;
1049
1050
Daniel Veillarde84f2312005-07-02 07:31:28 +00001051 old_errors = nb_errors;
1052 old_tests = nb_tests;
1053 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001054 res = xsdTest();
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001055 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1056 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1057 else
1058 printf("Ran %d tests, %d errors, %d leaks\n",
1059 nb_tests - old_tests,
1060 nb_errors - old_errors,
1061 nb_leaks - old_leaks);
1062 old_errors = nb_errors;
1063 old_tests = nb_tests;
1064 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001065 res = rngTest1();
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001066 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1067 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1068 else
1069 printf("Ran %d tests, %d errors, %d leaks\n",
1070 nb_tests - old_tests,
1071 nb_errors - old_errors,
1072 nb_leaks - old_leaks);
1073 old_errors = nb_errors;
1074 old_tests = nb_tests;
1075 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001076 res = rngTest2();
Daniel Veillarde84f2312005-07-02 07:31:28 +00001077 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1078 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1079 else
1080 printf("Ran %d tests, %d errors, %d leaks\n",
1081 nb_tests - old_tests,
1082 nb_errors - old_errors,
1083 nb_leaks - old_leaks);
1084 old_errors = nb_errors;
1085 old_tests = nb_tests;
1086 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001087 nb_internals = 0;
1088 nb_schematas = 0;
1089 res = xstcMetadata(
Daniel Veillardde0e4982005-07-03 14:35:44 +00001090 "xstc/Tests/Metadata/NISTXMLSchemaDatatypes.testSet",
1091 "xstc/Tests/Metadata/");
1092 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Daniel Veillardc9352532005-07-04 14:25:34 +00001093 printf("Ran %d tests (%d schemata), no errors\n",
1094 nb_tests - old_tests, nb_schematas);
Daniel Veillardde0e4982005-07-03 14:35:44 +00001095 else
Daniel Veillardc9352532005-07-04 14:25:34 +00001096 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +00001097 nb_tests - old_tests,
Daniel Veillardc9352532005-07-04 14:25:34 +00001098 nb_schematas,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001099 nb_errors - old_errors,
Daniel Veillardc9352532005-07-04 14:25:34 +00001100 nb_internals,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001101 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/SunXMLSchema1-0-20020116.testSet",
Daniel Veillardc9352532005-07-04 14:25:34 +00001109 "xstc/Tests/");
Daniel Veillardde0e4982005-07-03 14:35:44 +00001110 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/MSXMLSchema1-0-20020116.testSet",
1127 "xstc/Tests/");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +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 Veillard3fe1e8a2005-07-02 21:39:06 +00001131 else
Daniel Veillardc9352532005-07-04 14:25:34 +00001132 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001133 nb_tests - old_tests,
Daniel Veillardc9352532005-07-04 14:25:34 +00001134 nb_schematas,
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001135 nb_errors - old_errors,
Daniel Veillardc9352532005-07-04 14:25:34 +00001136 nb_internals,
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001137 nb_leaks - old_leaks);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001138
1139 if ((nb_errors == 0) && (nb_leaks == 0)) {
1140 ret = 0;
1141 printf("Total %d tests, no errors\n",
1142 nb_tests);
1143 } else {
1144 ret = 1;
1145 printf("Total %d tests, %d errors, %d leaks\n",
1146 nb_tests, nb_errors, nb_leaks);
1147 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001148
1149 xmlXPathFreeContext(ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001150 xmlCleanupParser();
1151 xmlMemoryDump();
1152
Daniel Veillardc9352532005-07-04 14:25:34 +00001153 if (logfile != NULL)
1154 fclose(logfile);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001155 return(ret);
1156}
Daniel Veillard95175012005-07-03 16:09:51 +00001157#else /* !SCHEMAS */
1158int
1159main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1160 fprintf(stderr, "runsuite requires support for schemas and xpath in libxml2\n");
1161}
1162#endif