blob: 280c0880e8ebe0b44f0c8028c3df8b70fe5fd082 [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;
39static int verbose = 0;
Kasimier T. Buchcik87db1cf2005-07-05 10:40:52 +000040
41#if defined(_WIN32) && !defined(__CYGWIN__)
42#define vsnprintf _vsnprintf
43#define snprintf _snprintf
44#endif
Daniel Veillardc9352532005-07-04 14:25:34 +000045
Daniel Veillardf2e066a2005-06-30 13:04:44 +000046/************************************************************************
47 * *
48 * File name and path utilities *
49 * *
50 ************************************************************************/
51
52static int checkTestFile(const char *filename) {
53 struct stat buf;
54
55 if (stat(filename, &buf) == -1)
56 return(0);
57
Daniel Veillardcfbb0dd2005-07-04 17:12:01 +000058#if defined(_WIN32) && !defined(__CYGWIN__)
59 if (!(buf.st_mode & _S_IFREG))
60 return(0);
61#else
Daniel Veillardf2e066a2005-06-30 13:04:44 +000062 if (!S_ISREG(buf.st_mode))
63 return(0);
Daniel Veillardcfbb0dd2005-07-04 17:12:01 +000064#endif
Daniel Veillardf2e066a2005-06-30 13:04:44 +000065
66 return(1);
67}
Daniel Veillardcfbb0dd2005-07-04 17:12:01 +000068
Daniel Veillarde84f2312005-07-02 07:31:28 +000069static xmlChar *composeDir(const xmlChar *dir, const xmlChar *path) {
70 char buf[500];
71
72 if (dir == NULL) return(xmlStrdup(path));
73 if (path == NULL) return(NULL);
74
75 snprintf(buf, 500, "%s/%s", (const char *) dir, (const char *) path);
76 return(xmlStrdup((const xmlChar *) buf));
77}
Daniel Veillardf2e066a2005-06-30 13:04:44 +000078
79/************************************************************************
80 * *
81 * Libxml2 specific routines *
82 * *
83 ************************************************************************/
84
85static int nb_tests = 0;
86static int nb_errors = 0;
Daniel Veillardc9352532005-07-04 14:25:34 +000087static int nb_internals = 0;
88static int nb_schematas = 0;
Daniel Veillard90837782005-07-04 15:45:10 +000089static int nb_unimplemented = 0;
Daniel Veillardf2e066a2005-06-30 13:04:44 +000090static int nb_leaks = 0;
91static long libxmlMemoryAllocatedBase = 0;
92static int extraMemoryFromResolver = 0;
93
94static int
95fatalError(void) {
96 fprintf(stderr, "Exitting tests on fatal error\n");
97 exit(1);
98}
99
100/*
Daniel Veillarde84f2312005-07-02 07:31:28 +0000101 * that's needed to implement <resource>
102 */
103#define MAX_ENTITIES 20
Daniel Veillard24505b02005-07-28 23:49:35 +0000104static char *testEntitiesName[MAX_ENTITIES];
105static char *testEntitiesValue[MAX_ENTITIES];
106static int nb_entities = 0;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000107static void resetEntities(void) {
108 int i;
109
110 for (i = 0;i < nb_entities;i++) {
111 if (testEntitiesName[i] != NULL)
112 xmlFree(testEntitiesName[i]);
113 if (testEntitiesValue[i] != NULL)
114 xmlFree(testEntitiesValue[i]);
115 }
116 nb_entities = 0;
117}
118static int addEntity(char *name, char *content) {
119 if (nb_entities >= MAX_ENTITIES) {
120 fprintf(stderr, "Too many entities defined\n");
121 return(-1);
122 }
123 testEntitiesName[nb_entities] = name;
124 testEntitiesValue[nb_entities] = content;
125 nb_entities++;
126 return(0);
127}
128
129/*
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000130 * We need to trap calls to the resolver to not account memory for the catalog
131 * which is shared to the current running test. We also don't want to have
132 * network downloads modifying tests.
133 */
134static xmlParserInputPtr
135testExternalEntityLoader(const char *URL, const char *ID,
136 xmlParserCtxtPtr ctxt) {
137 xmlParserInputPtr ret;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000138 int i;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000139
Daniel Veillarde84f2312005-07-02 07:31:28 +0000140 for (i = 0;i < nb_entities;i++) {
141 if (!strcmp(testEntitiesName[i], URL)) {
142 ret = xmlNewStringInputStream(ctxt,
143 (const xmlChar *) testEntitiesValue[i]);
144 if (ret != NULL) {
145 ret->filename = (const char *)
146 xmlStrdup((xmlChar *)testEntitiesName[i]);
147 }
148 return(ret);
149 }
150 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000151 if (checkTestFile(URL)) {
152 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
153 } else {
154 int memused = xmlMemUsed();
155 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
156 extraMemoryFromResolver += xmlMemUsed() - memused;
157 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000158#if 0
Daniel Veillarde84f2312005-07-02 07:31:28 +0000159 if (ret == NULL) {
160 fprintf(stderr, "Failed to find resource %s\n", URL);
161 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000162#endif
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000163
164 return(ret);
165}
166
167/*
168 * Trapping the error messages at the generic level to grab the equivalent of
169 * stderr messages on CLI tools.
170 */
171static char testErrors[32769];
172static int testErrorsSize = 0;
173
Daniel Veillardc9352532005-07-04 14:25:34 +0000174static void test_log(const char *msg, ...) {
175 va_list args;
176 if (logfile != NULL) {
177 fprintf(logfile, "\n------------\n");
178 va_start(args, msg);
179 vfprintf(logfile, msg, args);
180 va_end(args);
181 fprintf(logfile, "%s", testErrors);
182 testErrorsSize = 0; testErrors[0] = 0;
183 }
184 if (verbose) {
185 va_start(args, msg);
186 vfprintf(stderr, msg, args);
187 va_end(args);
188 }
189}
190
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000191static void
192testErrorHandler(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
193 va_list args;
194 int res;
195
196 if (testErrorsSize >= 32768)
197 return;
198 va_start(args, msg);
199 res = vsnprintf(&testErrors[testErrorsSize],
200 32768 - testErrorsSize,
201 msg, args);
202 va_end(args);
203 if (testErrorsSize + res >= 32768) {
204 /* buffer is full */
205 testErrorsSize = 32768;
206 testErrors[testErrorsSize] = 0;
207 } else {
208 testErrorsSize += res;
209 }
210 testErrors[testErrorsSize] = 0;
211}
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000212
Daniel Veillard24505b02005-07-28 23:49:35 +0000213static xmlXPathContextPtr ctxtXPath;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000214
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000215static void
216initializeLibxml2(void) {
217 xmlGetWarningsDefaultValue = 0;
218 xmlPedanticParserDefault(0);
219
220 xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
221 xmlInitParser();
222 xmlSetExternalEntityLoader(testExternalEntityLoader);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000223 ctxtXPath = xmlXPathNewContext(NULL);
224 /* used as default nanemspace in xstc tests */
225 xmlXPathRegisterNs(ctxtXPath, BAD_CAST "ts", BAD_CAST "TestSuite");
226 xmlXPathRegisterNs(ctxtXPath, BAD_CAST "xlink",
227 BAD_CAST "http://www.w3.org/1999/xlink");
228 xmlSetGenericErrorFunc(NULL, testErrorHandler);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000229#ifdef LIBXML_SCHEMAS_ENABLED
230 xmlSchemaInitTypes();
231 xmlRelaxNGInitTypes();
232#endif
233 libxmlMemoryAllocatedBase = xmlMemUsed();
234}
235
236static xmlNodePtr
237getNext(xmlNodePtr cur, const char *xpath) {
238 xmlNodePtr ret = NULL;
239 xmlXPathObjectPtr res;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000240 xmlXPathCompExprPtr comp;
241
242 if ((cur == NULL) || (cur->doc == NULL) || (xpath == NULL))
243 return(NULL);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000244 ctxtXPath->doc = cur->doc;
245 ctxtXPath->node = cur;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000246 comp = xmlXPathCompile(BAD_CAST xpath);
247 if (comp == NULL) {
248 fprintf(stderr, "Failed to compile %s\n", xpath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000249 return(NULL);
250 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000251 res = xmlXPathCompiledEval(comp, ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000252 xmlXPathFreeCompExpr(comp);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000253 if (res == NULL)
254 return(NULL);
255 if ((res->type == XPATH_NODESET) &&
256 (res->nodesetval != NULL) &&
257 (res->nodesetval->nodeNr > 0) &&
258 (res->nodesetval->nodeTab != NULL))
259 ret = res->nodesetval->nodeTab[0];
260 xmlXPathFreeObject(res);
261 return(ret);
262}
263
264static xmlChar *
265getString(xmlNodePtr cur, const char *xpath) {
266 xmlChar *ret = NULL;
267 xmlXPathObjectPtr res;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000268 xmlXPathCompExprPtr comp;
269
270 if ((cur == NULL) || (cur->doc == NULL) || (xpath == NULL))
271 return(NULL);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000272 ctxtXPath->doc = cur->doc;
273 ctxtXPath->node = cur;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000274 comp = xmlXPathCompile(BAD_CAST xpath);
275 if (comp == NULL) {
276 fprintf(stderr, "Failed to compile %s\n", xpath);
277 return(NULL);
278 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000279 res = xmlXPathCompiledEval(comp, ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000280 xmlXPathFreeCompExpr(comp);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000281 if (res == NULL)
282 return(NULL);
283 if (res->type == XPATH_STRING) {
284 ret = res->stringval;
285 res->stringval = NULL;
286 }
287 xmlXPathFreeObject(res);
288 return(ret);
289}
290
291/************************************************************************
292 * *
293 * Test test/xsdtest/xsdtestsuite.xml *
294 * *
295 ************************************************************************/
296
297static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000298xsdIncorectTestCase(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000299 xmlNodePtr test;
300 xmlBufferPtr buf;
301 xmlRelaxNGParserCtxtPtr pctxt;
302 xmlRelaxNGPtr rng = NULL;
303 int ret = 0, memt;
304
305 cur = getNext(cur, "./incorrect[1]");
306 if (cur == NULL) {
307 return(0);
308 }
309
310 test = getNext(cur, "./*");
311 if (test == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000312 test_log("Failed to find test in correct line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000313 xmlGetLineNo(cur));
314 return(1);
315 }
316
317 memt = xmlMemUsed();
318 extraMemoryFromResolver = 0;
319 /*
320 * dump the schemas to a buffer, then reparse it and compile the schemas
321 */
322 buf = xmlBufferCreate();
323 if (buf == NULL) {
324 fprintf(stderr, "out of memory !\n");
325 fatalError();
326 }
327 xmlNodeDump(buf, test->doc, test, 0, 0);
328 pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
329 xmlRelaxNGSetParserErrors(pctxt,
330 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
331 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
332 pctxt);
333 rng = xmlRelaxNGParse(pctxt);
334 xmlRelaxNGFreeParserCtxt(pctxt);
335 if (rng != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000336 test_log("Failed to detect incorect RNG line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000337 xmlGetLineNo(test));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000338 ret = 1;
339 goto done;
340 }
341
342done:
343 if (buf != NULL)
344 xmlBufferFree(buf);
345 if (rng != NULL)
346 xmlRelaxNGFree(rng);
347 xmlResetLastError();
348 if ((memt != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000349 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000350 xmlGetLineNo(cur), xmlMemUsed() - memt);
351 nb_leaks++;
352 }
353 return(ret);
354}
355
Daniel Veillarde84f2312005-07-02 07:31:28 +0000356static void
357installResources(xmlNodePtr tst, const xmlChar *base) {
358 xmlNodePtr test;
359 xmlBufferPtr buf;
360 xmlChar *name, *content, *res;
Daniel Veillardc9352532005-07-04 14:25:34 +0000361
Daniel Veillarde84f2312005-07-02 07:31:28 +0000362 buf = xmlBufferCreate();
363 if (buf == NULL) {
364 fprintf(stderr, "out of memory !\n");
365 fatalError();
366 }
367 xmlNodeDump(buf, tst->doc, tst, 0, 0);
368
369 while (tst != NULL) {
370 test = getNext(tst, "./*");
371 if (test != NULL) {
372 xmlBufferEmpty(buf);
373 xmlNodeDump(buf, test->doc, test, 0, 0);
374 name = getString(tst, "string(@name)");
375 content = xmlStrdup(buf->content);
376 if ((name != NULL) && (content != NULL)) {
377 res = composeDir(base, name);
378 xmlFree(name);
379 addEntity((char *) res, (char *) content);
380 } else {
381 if (name != NULL) xmlFree(name);
382 if (content != NULL) xmlFree(content);
383 }
384 }
385 tst = getNext(tst, "following-sibling::resource[1]");
386 }
387 if (buf != NULL)
388 xmlBufferFree(buf);
389}
390
391static void
392installDirs(xmlNodePtr tst, const xmlChar *base) {
393 xmlNodePtr test;
394 xmlChar *name, *res;
395
396 name = getString(tst, "string(@name)");
397 if (name == NULL)
398 return;
399 res = composeDir(base, name);
400 xmlFree(name);
401 if (res == NULL) {
402 return;
403 }
404 /* Now process resources and subdir recursively */
405 test = getNext(tst, "./resource[1]");
406 if (test != NULL) {
407 installResources(test, res);
408 }
409 test = getNext(tst, "./dir[1]");
410 while (test != NULL) {
411 installDirs(test, res);
412 test = getNext(test, "following-sibling::dir[1]");
413 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000414 xmlFree(res);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000415}
416
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000417static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000418xsdTestCase(xmlNodePtr tst) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000419 xmlNodePtr test, tmp, cur;
420 xmlBufferPtr buf;
421 xmlDocPtr doc = NULL;
422 xmlRelaxNGParserCtxtPtr pctxt;
423 xmlRelaxNGValidCtxtPtr ctxt;
424 xmlRelaxNGPtr rng = NULL;
425 int ret = 0, mem, memt;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000426 xmlChar *dtd;
427
428 resetEntities();
Daniel Veillardc9352532005-07-04 14:25:34 +0000429 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000430
431 tmp = getNext(tst, "./dir[1]");
432 if (tmp != NULL) {
433 installDirs(tmp, NULL);
434 }
435 tmp = getNext(tst, "./resource[1]");
436 if (tmp != NULL) {
437 installResources(tmp, NULL);
438 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000439
440 cur = getNext(tst, "./correct[1]");
441 if (cur == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000442 return(xsdIncorectTestCase(tst));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000443 }
444
445 test = getNext(cur, "./*");
446 if (test == NULL) {
447 fprintf(stderr, "Failed to find test in correct line %ld\n",
448 xmlGetLineNo(cur));
449 return(1);
450 }
451
452 memt = xmlMemUsed();
453 extraMemoryFromResolver = 0;
454 /*
455 * dump the schemas to a buffer, then reparse it and compile the schemas
456 */
457 buf = xmlBufferCreate();
458 if (buf == NULL) {
459 fprintf(stderr, "out of memory !\n");
460 fatalError();
461 }
462 xmlNodeDump(buf, test->doc, test, 0, 0);
463 pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
464 xmlRelaxNGSetParserErrors(pctxt,
465 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
466 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
467 pctxt);
468 rng = xmlRelaxNGParse(pctxt);
469 xmlRelaxNGFreeParserCtxt(pctxt);
470 if (extraMemoryFromResolver)
471 memt = 0;
472
473 if (rng == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000474 test_log("Failed to parse RNGtest line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000475 xmlGetLineNo(test));
476 nb_errors++;
477 ret = 1;
478 goto done;
479 }
480 /*
481 * now scan all the siblings of correct to process the <valid> tests
482 */
483 tmp = getNext(cur, "following-sibling::valid[1]");
484 while (tmp != NULL) {
Daniel Veillarde84f2312005-07-02 07:31:28 +0000485 dtd = xmlGetProp(tmp, BAD_CAST "dtd");
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000486 test = getNext(tmp, "./*");
487 if (test == NULL) {
488 fprintf(stderr, "Failed to find test in <valid> line %ld\n",
489 xmlGetLineNo(tmp));
490
491 } else {
492 xmlBufferEmpty(buf);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000493 if (dtd != NULL)
494 xmlBufferAdd(buf, dtd, -1);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000495 xmlNodeDump(buf, test->doc, test, 0, 0);
496
497 /*
498 * We are ready to run the test
499 */
500 mem = xmlMemUsed();
501 extraMemoryFromResolver = 0;
502 doc = xmlReadMemory((const char *)buf->content, buf->use,
503 "test", NULL, 0);
504 if (doc == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000505 test_log("Failed to parse valid instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000506 xmlGetLineNo(tmp));
507 nb_errors++;
508 } else {
509 nb_tests++;
510 ctxt = xmlRelaxNGNewValidCtxt(rng);
511 xmlRelaxNGSetValidErrors(ctxt,
512 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
513 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
514 ctxt);
515 ret = xmlRelaxNGValidateDoc(ctxt, doc);
516 xmlRelaxNGFreeValidCtxt(ctxt);
517 if (ret > 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000518 test_log("Failed to validate valid instance line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000519 xmlGetLineNo(tmp));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000520 nb_errors++;
521 } else if (ret < 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000522 test_log("Internal error validating instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000523 xmlGetLineNo(tmp));
524 nb_errors++;
525 }
526 xmlFreeDoc(doc);
527 }
528 xmlResetLastError();
529 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000530 test_log("Validation of instance line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000531 xmlGetLineNo(tmp), xmlMemUsed() - mem);
532 xmlMemoryDump();
533 nb_leaks++;
534 }
535 }
Daniel Veillarde84f2312005-07-02 07:31:28 +0000536 if (dtd != NULL)
537 xmlFree(dtd);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000538 tmp = getNext(tmp, "following-sibling::valid[1]");
539 }
540 /*
541 * now scan all the siblings of correct to process the <invalid> tests
542 */
543 tmp = getNext(cur, "following-sibling::invalid[1]");
544 while (tmp != NULL) {
545 test = getNext(tmp, "./*");
546 if (test == NULL) {
547 fprintf(stderr, "Failed to find test in <invalid> line %ld\n",
548 xmlGetLineNo(tmp));
549
550 } else {
551 xmlBufferEmpty(buf);
552 xmlNodeDump(buf, test->doc, test, 0, 0);
553
554 /*
555 * We are ready to run the test
556 */
557 mem = xmlMemUsed();
558 extraMemoryFromResolver = 0;
559 doc = xmlReadMemory((const char *)buf->content, buf->use,
560 "test", NULL, 0);
561 if (doc == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000562 test_log("Failed to parse valid instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000563 xmlGetLineNo(tmp));
564 nb_errors++;
565 } else {
566 nb_tests++;
567 ctxt = xmlRelaxNGNewValidCtxt(rng);
568 xmlRelaxNGSetValidErrors(ctxt,
569 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
570 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
571 ctxt);
572 ret = xmlRelaxNGValidateDoc(ctxt, doc);
573 xmlRelaxNGFreeValidCtxt(ctxt);
574 if (ret == 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000575 test_log("Failed to detect invalid instance line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000576 xmlGetLineNo(tmp));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000577 nb_errors++;
578 } else if (ret < 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000579 test_log("Internal error validating instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000580 xmlGetLineNo(tmp));
581 nb_errors++;
582 }
583 xmlFreeDoc(doc);
584 }
585 xmlResetLastError();
586 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000587 test_log("Validation of instance line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000588 xmlGetLineNo(tmp), xmlMemUsed() - mem);
589 xmlMemoryDump();
590 nb_leaks++;
591 }
592 }
593 tmp = getNext(tmp, "following-sibling::invalid[1]");
594 }
595
596done:
597 if (buf != NULL)
598 xmlBufferFree(buf);
599 if (rng != NULL)
600 xmlRelaxNGFree(rng);
601 xmlResetLastError();
602 if ((memt != xmlMemUsed()) && (memt != 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000603 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000604 xmlGetLineNo(cur), xmlMemUsed() - memt);
605 nb_leaks++;
606 }
607 return(ret);
608}
609
610static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000611xsdTestSuite(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000612 if (verbose) {
613 xmlChar *doc = getString(cur, "string(documentation)");
614
615 if (doc != NULL) {
616 printf("Suite %s\n", doc);
617 xmlFree(doc);
618 }
619 }
620 cur = getNext(cur, "./testCase[1]");
621 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000622 xsdTestCase(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000623 cur = getNext(cur, "following-sibling::testCase[1]");
624 }
625
626 return(0);
627}
628
629static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000630xsdTest(void) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000631 xmlDocPtr doc;
632 xmlNodePtr cur;
633 const char *filename = "test/xsdtest/xsdtestsuite.xml";
634 int ret = 0;
635
636 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
637 if (doc == NULL) {
638 fprintf(stderr, "Failed to parse %s\n", filename);
639 return(-1);
640 }
641 printf("## XML Schemas datatypes test suite from James Clark\n");
642
643 cur = xmlDocGetRootElement(doc);
644 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
645 fprintf(stderr, "Unexpected format %s\n", filename);
646 ret = -1;
647 goto done;
648 }
649
650 cur = getNext(cur, "./testSuite[1]");
651 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
652 fprintf(stderr, "Unexpected format %s\n", filename);
653 ret = -1;
654 goto done;
655 }
656 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000657 xsdTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000658 cur = getNext(cur, "following-sibling::testSuite[1]");
659 }
660
661done:
662 if (doc != NULL)
663 xmlFreeDoc(doc);
664 return(ret);
665}
666
667static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000668rngTestSuite(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000669 if (verbose) {
670 xmlChar *doc = getString(cur, "string(documentation)");
671
672 if (doc != NULL) {
673 printf("Suite %s\n", doc);
674 xmlFree(doc);
675 } else {
676 doc = getString(cur, "string(section)");
677 if (doc != NULL) {
678 printf("Section %s\n", doc);
679 xmlFree(doc);
680 }
681 }
682 }
683 cur = getNext(cur, "./testSuite[1]");
684 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000685 xsdTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000686 cur = getNext(cur, "following-sibling::testSuite[1]");
687 }
688
689 return(0);
690}
691
692static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000693rngTest1(void) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000694 xmlDocPtr doc;
695 xmlNodePtr cur;
696 const char *filename = "test/relaxng/OASIS/spectest.xml";
697 int ret = 0;
698
699 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
700 if (doc == NULL) {
701 fprintf(stderr, "Failed to parse %s\n", filename);
702 return(-1);
703 }
Daniel Veillarde84f2312005-07-02 07:31:28 +0000704 printf("## Relax NG test suite from James Clark\n");
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000705
706 cur = xmlDocGetRootElement(doc);
707 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
708 fprintf(stderr, "Unexpected format %s\n", filename);
709 ret = -1;
710 goto done;
711 }
712
713 cur = getNext(cur, "./testSuite[1]");
714 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
715 fprintf(stderr, "Unexpected format %s\n", filename);
716 ret = -1;
717 goto done;
718 }
719 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000720 rngTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000721 cur = getNext(cur, "following-sibling::testSuite[1]");
722 }
723
724done:
725 if (doc != NULL)
726 xmlFreeDoc(doc);
727 return(ret);
728}
729
Daniel Veillarde84f2312005-07-02 07:31:28 +0000730static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000731rngTest2(void) {
Daniel Veillarde84f2312005-07-02 07:31:28 +0000732 xmlDocPtr doc;
733 xmlNodePtr cur;
734 const char *filename = "test/relaxng/testsuite.xml";
735 int ret = 0;
736
737 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
738 if (doc == NULL) {
739 fprintf(stderr, "Failed to parse %s\n", filename);
740 return(-1);
741 }
742 printf("## Relax NG test suite for libxml2\n");
743
744 cur = xmlDocGetRootElement(doc);
745 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
746 fprintf(stderr, "Unexpected format %s\n", filename);
747 ret = -1;
748 goto done;
749 }
750
751 cur = getNext(cur, "./testSuite[1]");
752 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
753 fprintf(stderr, "Unexpected format %s\n", filename);
754 ret = -1;
755 goto done;
756 }
757 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000758 xsdTestSuite(cur);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000759 cur = getNext(cur, "following-sibling::testSuite[1]");
760 }
761
762done:
763 if (doc != NULL)
764 xmlFreeDoc(doc);
765 return(ret);
766}
767
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000768/************************************************************************
769 * *
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000770 * Schemas test suites from W3C/NIST/MS/Sun *
771 * *
772 ************************************************************************/
773
774static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000775xstcTestInstance(xmlNodePtr cur, xmlSchemaPtr schemas,
Daniel Veillard6b6d6802005-07-03 21:00:34 +0000776 const xmlChar *spath, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000777 xmlChar *href = NULL;
778 xmlChar *path = NULL;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000779 xmlChar *validity = NULL;
780 xmlSchemaValidCtxtPtr ctxt = NULL;
781 xmlDocPtr doc = NULL;
782 int ret = 0, mem;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000783
Daniel Veillardde0e4982005-07-03 14:35:44 +0000784 xmlResetLastError();
Daniel Veillardc9352532005-07-04 14:25:34 +0000785 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000786 mem = xmlMemUsed();
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000787 href = getString(cur,
Daniel Veillardde0e4982005-07-03 14:35:44 +0000788 "string(ts:instanceDocument/@xlink:href)");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000789 if ((href == NULL) || (href[0] == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000790 test_log("testGroup line %ld misses href for schemaDocument\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000791 xmlGetLineNo(cur));
792 ret = -1;
793 goto done;
794 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000795 path = xmlBuildURI(href, BAD_CAST base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000796 if (path == NULL) {
797 fprintf(stderr,
798 "Failed to build path to schemas testGroup line %ld : %s\n",
799 xmlGetLineNo(cur), href);
800 ret = -1;
801 goto done;
802 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000803 if (checkTestFile((const char *) path) <= 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000804 test_log("schemas for testGroup line %ld is missing: %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000805 xmlGetLineNo(cur), path);
806 ret = -1;
807 goto done;
808 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000809 validity = getString(cur,
810 "string(ts:expected/@validity)");
811 if (validity == NULL) {
812 fprintf(stderr, "instanceDocument line %ld misses expected validity\n",
813 xmlGetLineNo(cur));
814 ret = -1;
815 goto done;
816 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000817 nb_tests++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000818 doc = xmlReadFile((const char *) path, NULL, XML_PARSE_NOENT);
819 if (doc == NULL) {
820 fprintf(stderr, "instance %s fails to parse\n", path);
821 ret = -1;
822 nb_errors++;
823 goto done;
824 }
825
826 ctxt = xmlSchemaNewValidCtxt(schemas);
827 xmlSchemaSetValidErrors(ctxt,
828 (xmlSchemaValidityErrorFunc) testErrorHandler,
829 (xmlSchemaValidityWarningFunc) testErrorHandler,
830 ctxt);
831 ret = xmlSchemaValidateDoc(ctxt, doc);
832
833 if (xmlStrEqual(validity, BAD_CAST "valid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000834 if (ret > 0) {
835 test_log("valid instance %s failed to validate against %s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000836 path, spath);
837 nb_errors++;
Daniel Veillardc9352532005-07-04 14:25:34 +0000838 } else if (ret < 0) {
839 test_log("valid instance %s got internal error validating %s\n",
840 path, spath);
841 nb_internals++;
842 nb_errors++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000843 }
844 } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
845 if (ret == 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000846 test_log("Failed to detect invalid instance %s against %s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000847 path, spath);
848 nb_errors++;
849 }
850 } else {
Daniel Veillardc9352532005-07-04 14:25:34 +0000851 test_log("instanceDocument line %ld has unexpected validity value%s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000852 xmlGetLineNo(cur), validity);
853 ret = -1;
854 goto done;
855 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000856
857done:
858 if (href != NULL) xmlFree(href);
859 if (path != NULL) xmlFree(path);
Daniel Veillardde0e4982005-07-03 14:35:44 +0000860 if (validity != NULL) xmlFree(validity);
861 if (ctxt != NULL) xmlSchemaFreeValidCtxt(ctxt);
862 if (doc != NULL) xmlFreeDoc(doc);
863 xmlResetLastError();
864 if (mem != xmlMemUsed()) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000865 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000866 xmlGetLineNo(cur), xmlMemUsed() - mem);
867 nb_leaks++;
868 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000869 return(ret);
870}
Daniel Veillardde0e4982005-07-03 14:35:44 +0000871
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000872static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000873xstcTestGroup(xmlNodePtr cur, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000874 xmlChar *href = NULL;
875 xmlChar *path = NULL;
876 xmlChar *validity = NULL;
877 xmlSchemaPtr schemas = NULL;
878 xmlSchemaParserCtxtPtr ctxt;
879 xmlNodePtr instance;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000880 int ret = 0, mem;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000881
Daniel Veillardde0e4982005-07-03 14:35:44 +0000882 xmlResetLastError();
Daniel Veillardc9352532005-07-04 14:25:34 +0000883 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000884 mem = xmlMemUsed();
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000885 href = getString(cur,
886 "string(ts:schemaTest/ts:schemaDocument/@xlink:href)");
887 if ((href == NULL) || (href[0] == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000888 test_log("testGroup line %ld misses href for schemaDocument\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000889 xmlGetLineNo(cur));
890 ret = -1;
891 goto done;
892 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000893 path = xmlBuildURI(href, BAD_CAST base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000894 if (path == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000895 test_log("Failed to build path to schemas testGroup line %ld : %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000896 xmlGetLineNo(cur), href);
897 ret = -1;
898 goto done;
899 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000900 if (checkTestFile((const char *) path) <= 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000901 test_log("schemas for testGroup line %ld is missing: %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000902 xmlGetLineNo(cur), path);
903 ret = -1;
904 goto done;
905 }
906 validity = getString(cur,
907 "string(ts:schemaTest/ts:expected/@validity)");
908 if (validity == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000909 test_log("testGroup line %ld misses expected validity\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000910 xmlGetLineNo(cur));
911 ret = -1;
912 goto done;
913 }
Daniel Veillardc9352532005-07-04 14:25:34 +0000914 nb_tests++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000915 if (xmlStrEqual(validity, BAD_CAST "valid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000916 nb_schematas++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000917 ctxt = xmlSchemaNewParserCtxt((const char *) path);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000918 xmlSchemaSetParserErrors(ctxt,
919 (xmlSchemaValidityErrorFunc) testErrorHandler,
920 (xmlSchemaValidityWarningFunc) testErrorHandler,
921 ctxt);
922 schemas = xmlSchemaParse(ctxt);
923 xmlSchemaFreeParserCtxt(ctxt);
924 if (schemas == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000925 test_log("valid schemas %s failed to parse\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000926 path);
Daniel Veillard90837782005-07-04 15:45:10 +0000927 ret = 1;
928 nb_errors++;
929 }
930 if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
931 test_log("valid schemas %s hit an unimplemented block\n",
932 path);
933 ret = 1;
934 nb_unimplemented++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000935 nb_errors++;
936 }
937 instance = getNext(cur, "./ts:instanceTest[1]");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000938 while (instance != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000939 xstcTestInstance(instance, schemas, path, base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000940 instance = getNext(instance,
941 "following-sibling::ts:instanceTest[1]");
942 }
943 } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000944 nb_schematas++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000945 ctxt = xmlSchemaNewParserCtxt((const char *) path);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000946 xmlSchemaSetParserErrors(ctxt,
947 (xmlSchemaValidityErrorFunc) testErrorHandler,
948 (xmlSchemaValidityWarningFunc) testErrorHandler,
949 ctxt);
950 schemas = xmlSchemaParse(ctxt);
951 xmlSchemaFreeParserCtxt(ctxt);
Daniel Veillard4ac5f9a2005-07-04 15:20:27 +0000952 if (schemas != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000953 test_log("Failed to detect error in schemas %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000954 path);
955 nb_errors++;
Daniel Veillard90837782005-07-04 15:45:10 +0000956 ret = 1;
957 }
958 if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
959 nb_unimplemented++;
960 test_log("invalid schemas %s hit an unimplemented block\n",
961 path);
962 ret = 1;
963 nb_errors++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000964 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000965 } else {
Daniel Veillardc9352532005-07-04 14:25:34 +0000966 test_log("testGroup line %ld misses unexpected validity value%s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000967 xmlGetLineNo(cur), validity);
968 ret = -1;
969 goto done;
970 }
971
972done:
973 if (href != NULL) xmlFree(href);
974 if (path != NULL) xmlFree(path);
975 if (validity != NULL) xmlFree(validity);
976 if (schemas != NULL) xmlSchemaFree(schemas);
Daniel Veillardde0e4982005-07-03 14:35:44 +0000977 xmlResetLastError();
978 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000979 test_log("Processing test line %ld %s leaked %d\n",
980 xmlGetLineNo(cur), path, xmlMemUsed() - mem);
Daniel Veillardde0e4982005-07-03 14:35:44 +0000981 nb_leaks++;
982 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000983 return(ret);
984}
985
986static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000987xstcMetadata(const char *metadata, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000988 xmlDocPtr doc;
989 xmlNodePtr cur;
990 xmlChar *contributor;
991 xmlChar *name;
Daniel Veillard6b6d6802005-07-03 21:00:34 +0000992 int ret = 0;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000993
994 doc = xmlReadFile(metadata, NULL, XML_PARSE_NOENT);
995 if (doc == NULL) {
996 fprintf(stderr, "Failed to parse %s\n", metadata);
997 return(-1);
998 }
999
1000 cur = xmlDocGetRootElement(doc);
1001 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSet"))) {
1002 fprintf(stderr, "Unexpected format %s\n", metadata);
1003 return(-1);
1004 }
1005 contributor = xmlGetProp(cur, BAD_CAST "contributor");
1006 if (contributor == NULL) {
1007 contributor = xmlStrdup(BAD_CAST "Unknown");
1008 }
1009 name = xmlGetProp(cur, BAD_CAST "name");
1010 if (name == NULL) {
1011 name = xmlStrdup(BAD_CAST "Unknown");
1012 }
1013 printf("## %s test suite for Schemas version %s\n", contributor, name);
1014 xmlFree(contributor);
1015 xmlFree(name);
1016
1017 cur = getNext(cur, "./ts:testGroup[1]");
1018 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testGroup"))) {
1019 fprintf(stderr, "Unexpected format %s\n", metadata);
1020 ret = -1;
1021 goto done;
1022 }
1023 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +00001024 xstcTestGroup(cur, base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001025 cur = getNext(cur, "following-sibling::ts:testGroup[1]");
1026 }
1027
1028done:
1029 xmlFreeDoc(doc);
1030 return(ret);
1031}
1032
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001033/************************************************************************
1034 * *
1035 * The driver for the tests *
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001036 * *
1037 ************************************************************************/
1038
1039int
1040main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1041 int res, ret = 0;
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001042 int old_errors, old_tests, old_leaks;
1043
Daniel Veillardc9352532005-07-04 14:25:34 +00001044 logfile = fopen(LOGFILE, "w");
1045 if (logfile == NULL) {
1046 fprintf(stderr,
1047 "Could not open the log file, running in verbose mode\n");
1048 verbose = 1;
1049 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001050 initializeLibxml2();
1051
1052 if ((argc >= 2) && (!strcmp(argv[1], "-v")))
1053 verbose = 1;
1054
1055
Daniel Veillarde84f2312005-07-02 07:31:28 +00001056 old_errors = nb_errors;
1057 old_tests = nb_tests;
1058 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001059 res = xsdTest();
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001060 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1061 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1062 else
1063 printf("Ran %d tests, %d errors, %d leaks\n",
1064 nb_tests - old_tests,
1065 nb_errors - old_errors,
1066 nb_leaks - old_leaks);
1067 old_errors = nb_errors;
1068 old_tests = nb_tests;
1069 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001070 res = rngTest1();
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 Veillardc9352532005-07-04 14:25:34 +00001081 res = rngTest2();
Daniel Veillarde84f2312005-07-02 07:31:28 +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 Veillardc9352532005-07-04 14:25:34 +00001092 nb_internals = 0;
1093 nb_schematas = 0;
1094 res = xstcMetadata(
Daniel Veillardde0e4982005-07-03 14:35:44 +00001095 "xstc/Tests/Metadata/NISTXMLSchemaDatatypes.testSet",
1096 "xstc/Tests/Metadata/");
1097 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Daniel Veillardc9352532005-07-04 14:25:34 +00001098 printf("Ran %d tests (%d schemata), no errors\n",
1099 nb_tests - old_tests, nb_schematas);
Daniel Veillardde0e4982005-07-03 14:35:44 +00001100 else
Daniel Veillardc9352532005-07-04 14:25:34 +00001101 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +00001102 nb_tests - old_tests,
Daniel Veillardc9352532005-07-04 14:25:34 +00001103 nb_schematas,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001104 nb_errors - old_errors,
Daniel Veillardc9352532005-07-04 14:25:34 +00001105 nb_internals,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001106 nb_leaks - old_leaks);
1107 old_errors = nb_errors;
1108 old_tests = nb_tests;
1109 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001110 nb_internals = 0;
1111 nb_schematas = 0;
1112 res = xstcMetadata(
Daniel Veillardde0e4982005-07-03 14:35:44 +00001113 "xstc/Tests/Metadata/SunXMLSchema1-0-20020116.testSet",
Daniel Veillardc9352532005-07-04 14:25:34 +00001114 "xstc/Tests/");
Daniel Veillardde0e4982005-07-03 14:35:44 +00001115 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Daniel Veillardc9352532005-07-04 14:25:34 +00001116 printf("Ran %d tests (%d schemata), no errors\n",
1117 nb_tests - old_tests, nb_schematas);
Daniel Veillardde0e4982005-07-03 14:35:44 +00001118 else
Daniel Veillardc9352532005-07-04 14:25:34 +00001119 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +00001120 nb_tests - old_tests,
Daniel Veillardc9352532005-07-04 14:25:34 +00001121 nb_schematas,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001122 nb_errors - old_errors,
Daniel Veillardc9352532005-07-04 14:25:34 +00001123 nb_internals,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001124 nb_leaks - old_leaks);
1125 old_errors = nb_errors;
1126 old_tests = nb_tests;
1127 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001128 nb_internals = 0;
1129 nb_schematas = 0;
1130 res = xstcMetadata(
Daniel Veillardde0e4982005-07-03 14:35:44 +00001131 "xstc/Tests/Metadata/MSXMLSchema1-0-20020116.testSet",
1132 "xstc/Tests/");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001133 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Daniel Veillardc9352532005-07-04 14:25:34 +00001134 printf("Ran %d tests (%d schemata), no errors\n",
1135 nb_tests - old_tests, nb_schematas);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001136 else
Daniel Veillardc9352532005-07-04 14:25:34 +00001137 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001138 nb_tests - old_tests,
Daniel Veillardc9352532005-07-04 14:25:34 +00001139 nb_schematas,
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001140 nb_errors - old_errors,
Daniel Veillardc9352532005-07-04 14:25:34 +00001141 nb_internals,
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001142 nb_leaks - old_leaks);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001143
1144 if ((nb_errors == 0) && (nb_leaks == 0)) {
1145 ret = 0;
1146 printf("Total %d tests, no errors\n",
1147 nb_tests);
1148 } else {
1149 ret = 1;
1150 printf("Total %d tests, %d errors, %d leaks\n",
1151 nb_tests, nb_errors, nb_leaks);
1152 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001153
1154 xmlXPathFreeContext(ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001155 xmlCleanupParser();
1156 xmlMemoryDump();
1157
Daniel Veillardc9352532005-07-04 14:25:34 +00001158 if (logfile != NULL)
1159 fclose(logfile);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001160 return(ret);
1161}
Daniel Veillard95175012005-07-03 16:09:51 +00001162#else /* !SCHEMAS */
1163int
1164main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1165 fprintf(stderr, "runsuite requires support for schemas and xpath in libxml2\n");
1166}
1167#endif